Package org.springframework.ide.eclipse.config.ui.actions

Source Code of org.springframework.ide.eclipse.config.ui.actions.ToggleMarkOccurrencesAction$OccurrenceLocation

/*******************************************************************************
*  Copyright (c) 2012 - 2013 GoPivotal, Inc.
*  All rights reserved. This program and the accompanying materials
*  are made available under the terms of the Eclipse Public License v1.0
*  which accompanies this distribution, and is available at
*  http://www.eclipse.org/legal/epl-v10.html
*
*  Contributors:
*      GoPivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.config.ui.actions;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IAnnotationModelExtension;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.xml.core.internal.document.AttrImpl;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.springframework.ide.eclipse.beans.core.BeansCorePlugin;
import org.springframework.ide.eclipse.beans.core.internal.model.validation.BeansValidationContext;
import org.springframework.ide.eclipse.beans.core.model.IBeansConfig;
import org.springframework.ide.eclipse.beans.core.namespaces.ToolAnnotationUtils.ToolAnnotationData;
import org.springframework.ide.eclipse.beans.ui.editor.util.BeansEditorUtils;
import org.springframework.ide.eclipse.config.core.schemas.BeansSchemaConstants;
import org.springframework.ide.eclipse.config.ui.ConfigUiPlugin;
import org.springframework.ide.eclipse.config.ui.editors.AbstractConfigEditor;
import org.springframework.ide.eclipse.core.SpringCore;
import org.springframework.ide.eclipse.core.internal.model.SpringProject;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
* This action toggles the mark occurrences for bean references.
* @author Terry Denney
* @author Christian Dupuis
* @author Leo Dos Santos
*/
@SuppressWarnings("restriction")
public class ToggleMarkOccurrencesAction extends Action implements IPropertyChangeListener, KeyListener, MouseListener {

  public static class OccurrenceLocation {

    private final int offset;

    private final int length;

    public OccurrenceLocation(int offset, int length) {
      this.offset = offset;
      this.length = length;
    }

    public int getLength() {
      return length;
    }

    public int getOffset() {
      return offset;
    }
  }

  private final IPreferenceStore prefStore;

  private AbstractConfigEditor editor;

  private final Set<Annotation> annotations;

  public static String STS_MARK_OCCURRENCES = "stsMarkOccurrences"; //$NON-NLS-1$

  private final String MARK_PATH = "icons/mark_occurrences.gif"; //$NON-NLS-1$

  private final String MARK_DISABLED_PATH = "icons/mark_occurrences_disabled.gif"; //$NON-NLS-1$

  private static final String[] ATTRIBUTES_TO_CHECK = new String[] { BeansSchemaConstants.ATTR_ID,
      BeansSchemaConstants.ATTR_NAME, BeansSchemaConstants.ATTR_PARENT, BeansSchemaConstants.ATTR_REF,
      BeansSchemaConstants.ATTR_DEPENDS_ON, BeansSchemaConstants.ATTR_BEAN, BeansSchemaConstants.ATTR_LOCAL,
      BeansSchemaConstants.ATTR_KEY_REF, BeansSchemaConstants.ATTR_VALUE_REF };

  public ToggleMarkOccurrencesAction() {
    super(Messages.getString("ToggleMarkOccurrencesAction.ACTION_LABEL"), Action.AS_CHECK_BOX); //$NON-NLS-1$
    ImageDescriptor imageDesc = ConfigUiPlugin.imageDescriptorFromPlugin(ConfigUiPlugin.PLUGIN_ID, MARK_PATH);
    ImageDescriptor disabledDesc = ConfigUiPlugin.imageDescriptorFromPlugin(ConfigUiPlugin.PLUGIN_ID,
        MARK_DISABLED_PATH);
    setImageDescriptor(imageDesc);
    setDisabledImageDescriptor(disabledDesc);
    annotations = new HashSet<Annotation>();
    prefStore = ConfigUiPlugin.getDefault().getPreferenceStore();
    prefStore.addPropertyChangeListener(this);
    setChecked(prefStore.getBoolean(STS_MARK_OCCURRENCES));
  }

  private Set<OccurrenceLocation> findBeanReference(String beanName, BeansValidationContext context)
      throws BadLocationException {
    Set<OccurrenceLocation> result = new HashSet<OccurrenceLocation>();
    IDOMDocument document = editor.getDomDocument();
    if (document != null) {
      NodeList nodes = document.getDocumentElement().getChildNodes();
      for (int i = 0; i < nodes.getLength(); i++) {
        result.addAll(findBeanReference(beanName, nodes.item(i), context));
      }
    }
    return result;
  }

  private Set<OccurrenceLocation> findBeanReference(String beanName, Node node, BeansValidationContext context)
      throws BadLocationException {
    Set<OccurrenceLocation> result = new HashSet<OccurrenceLocation>();

    NamedNodeMap attributes = node.getAttributes();
    if (attributes != null) {
      for (int i = 0; i < attributes.getLength(); i++) {
        AttrImpl attribute = (AttrImpl) attributes.item(i);
        result.addAll(findBeanReferences(beanName, attribute, node, context));
      }
    }

    NodeList nodes = node.getChildNodes();
    if (nodes != null && nodes.getLength() > 0) {
      for (int i = 0; i < nodes.getLength(); i++) {
        Node child = nodes.item(i);
        if (child.getNodeType() == Node.ELEMENT_NODE) {
          result.addAll(findBeanReference(beanName, child, context));
        }
      }
    }

    return result;
  }

  private Set<OccurrenceLocation> findBeanReferences(String beanName, AttrImpl attribute, Node node,
      BeansValidationContext context) {
    Set<OccurrenceLocation> result = new HashSet<OccurrenceLocation>();

    String attrName = attribute.getName();
    if (attrName != null) {
      boolean found = false;

      for (String attributeName : ATTRIBUTES_TO_CHECK) {
        if (attributeName.equals(attrName)) {
          found = true;
          break;
        }
      }

      if (context != null) {
        for (ToolAnnotationData annotationData : context.getToolAnnotation(node, attribute.getLocalName())) {
          if ("ref".equals(annotationData.getKind())) { //$NON-NLS-1$
            found = true;
          }
        }
      }

      if (found) {
        if (beanName.equals(attribute.getValue())) {
          try {
            int offset = attribute.getValueRegionStartOffset();
            int length = beanName.length();

            // check if the value starts with quote
            if (editor.getTextViewer().getDocument().getChar(offset) == '"') {
              offset++;
            }
            result.add(new OccurrenceLocation(offset, length));
          }
          catch (BadLocationException e) {
          }
        }
      }
    }
    return result;

  }

  private Set<OccurrenceLocation> findLocations(IndexedRegion region, int offset) {
    if (region instanceof IDOMNode) {
      IDOMNode node = (IDOMNode) region;
      IFile file = editor.getResourceFile();

      BeansValidationContext context = null;
      IBeansConfig config = BeansCorePlugin.getModel().getConfig(file);
      if (config != null) {
        context = new BeansValidationContext(config,
            new SpringProject(SpringCore.getModel(), file.getProject()));
      }

      String beanName = getBeanName(node, offset, context);
      if (beanName != null) {
        try {
          return findBeanReference(beanName, context);
        }
        catch (BadLocationException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }
    }
    return new HashSet<OccurrenceLocation>();
  }

  private String getBeanName(IDOMNode node, int offset, BeansValidationContext context) {
    NamedNodeMap attributes = node.getAttributes();
    if (attributes != null) {
      for (int i = 0; i < attributes.getLength(); i++) {
        AttrImpl attribute = (AttrImpl) attributes.item(i);

        if (attribute != null && attribute.getStartOffset() <= offset && attribute.getEndOffset() >= offset) {
          if (context != null) {
            List<ToolAnnotationData> toolAnnotations = context.getToolAnnotation(node,
                attribute.getLocalName());
            for (ToolAnnotationData toolAnnotation : toolAnnotations) {
              if ("ref".equals(toolAnnotation.getKind())) { //$NON-NLS-1$
                return attribute.getNodeValue();
              }
            }
          }

          for (String attributeName : ATTRIBUTES_TO_CHECK) {
            if (attributeName.equals(attribute.getNodeName())) {
              return attribute.getNodeValue();
            }
          }
        }
      }
    }
    return null;
  }

  public void keyPressed(KeyEvent e) {
  }

  public void keyReleased(KeyEvent e) {
    selectionChanged();
  }

  public void mouseDoubleClick(MouseEvent e) {
  }

  public void mouseDown(MouseEvent e) {
    selectionChanged();
  }

  public void mouseUp(MouseEvent e) {
  }

  public void propertyChange(PropertyChangeEvent event) {
    String property = event.getProperty();
    if (STS_MARK_OCCURRENCES.equals(property)) {
      setChecked(prefStore.getBoolean(STS_MARK_OCCURRENCES));
    }
  }

  @Override
  public void run() {
    prefStore.setValue(STS_MARK_OCCURRENCES, isChecked());
    selectionChanged();
  }

  private void selectionChanged() {
    if (editor != null) {
      if (prefStore.getBoolean(STS_MARK_OCCURRENCES)) {
        ISelection selection = editor.getTextViewer().getSelection();
        if (selection instanceof ITextSelection) {
          ITextSelection textSelection = (ITextSelection) selection;
          int offset = textSelection.getOffset();
          IndexedRegion node = BeansEditorUtils.getNodeAt(editor.getTextViewer(), offset);

          Set<OccurrenceLocation> locations = findLocations(node, offset);
          updateAnnotations(locations);
        }
      }
      else if (annotations.size() > 0) {
        updateAnnotations(new HashSet<OccurrenceLocation>());
        annotations.clear();
      }
    }
  }

  public void selectionChanged(SelectionChangedEvent event) {
    selectionChanged();
  }

  public void setActiveEditor(AbstractConfigEditor targetEditor) {
    if (this.editor != null && this.editor.getTextViewer() != null
        && this.editor.getTextViewer().getTextWidget() != null) {
      StyledText textWidget = this.editor.getTextViewer().getTextWidget();
      textWidget.removeMouseListener(this);
      textWidget.removeKeyListener(this);
      updateAnnotations(new HashSet<OccurrenceLocation>());
    }
    this.editor = targetEditor;
    setChecked(prefStore.getBoolean(STS_MARK_OCCURRENCES));
    if (this.editor != null && this.editor.getTextViewer() != null
        && this.editor.getTextViewer().getTextWidget() != null) {
      StyledText textWidget = this.editor.getTextViewer().getTextWidget();
      textWidget.addMouseListener(this);
      textWidget.addKeyListener(this);
    }
    selectionChanged();
  }

  private void updateAnnotations(Set<OccurrenceLocation> locations) {
    IAnnotationModel annotationModel = editor.getSourcePage().getDocumentProvider()
        .getAnnotationModel(editor.getEditorInput());
    if (annotationModel == null) {
      return;
    }

    Map<Annotation, Position> newAnnotations = new HashMap<Annotation, Position>();
    for (OccurrenceLocation location : locations) {
      Annotation annotation = new Annotation("org.eclipse.jdt.ui.occurrences", false, ""); //$NON-NLS-1$ //$NON-NLS-2$
      Position position = new Position(location.getOffset(), location.getLength());
      newAnnotations.put(annotation, position);
    }

    if (annotationModel instanceof IAnnotationModelExtension) {
      ((IAnnotationModelExtension) annotationModel).replaceAnnotations(
          annotations.toArray(new Annotation[annotations.size()]), newAnnotations);
    }
    else {
      for (Annotation annotation : annotations) {
        annotationModel.removeAnnotation(annotation);
      }

      for (Annotation annotation : newAnnotations.keySet()) {
        annotationModel.addAnnotation(annotation, newAnnotations.get(annotation));
      }
    }

    annotations.clear();
    annotations.addAll(newAnnotations.keySet());
  }

}
TOP

Related Classes of org.springframework.ide.eclipse.config.ui.actions.ToggleMarkOccurrencesAction$OccurrenceLocation

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.