Package org.springframework.ide.eclipse.aop.ui.navigator

Source Code of org.springframework.ide.eclipse.aop.ui.navigator.AopReferenceModelNavigatorContentProvider

/*******************************************************************************
* Copyright (c) 2006, 2012 Spring IDE Developers
* 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:
*     Spring IDE Developers - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.aop.ui.navigator;

import java.util.ArrayList;
import java.util.Arrays;
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.core.resources.IResource;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.SourceField;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.navigator.ICommonContentExtensionSite;
import org.eclipse.ui.navigator.ICommonContentProvider;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.xml.core.internal.document.ElementImpl;
import org.springframework.ide.eclipse.aop.core.Activator;
import org.springframework.ide.eclipse.aop.core.internal.model.AopReferenceModel;
import org.springframework.ide.eclipse.aop.core.internal.model.builder.AopReferenceModelBuilderJob;
import org.springframework.ide.eclipse.aop.core.model.IAopModelChangedListener;
import org.springframework.ide.eclipse.aop.core.model.IAopReference;
import org.springframework.ide.eclipse.aop.core.model.IAopReference.ADVICE_TYPE;
import org.springframework.ide.eclipse.aop.core.model.IAspectDefinition;
import org.springframework.ide.eclipse.aop.core.util.AopReferenceModelUtils;
import org.springframework.ide.eclipse.aop.ui.navigator.model.AdviceDeclareParentAopSourceNode;
import org.springframework.ide.eclipse.aop.ui.navigator.model.BeanReferenceNode;
import org.springframework.ide.eclipse.aop.ui.navigator.model.ClassMethodReferenceNode;
import org.springframework.ide.eclipse.aop.ui.navigator.model.IReferenceNode;
import org.springframework.ide.eclipse.aop.ui.navigator.model.JavaElementReferenceNode;
import org.springframework.ide.eclipse.aop.ui.navigator.model.MethodBeanReferenceNode;
import org.springframework.ide.eclipse.aop.ui.navigator.model.MethodReference;
import org.springframework.ide.eclipse.beans.core.BeansCorePlugin;
import org.springframework.ide.eclipse.beans.core.BeansCoreUtils;
import org.springframework.ide.eclipse.beans.core.internal.model.BeansModelUtils;
import org.springframework.ide.eclipse.beans.core.model.IBean;
import org.springframework.ide.eclipse.beans.core.model.IBeansConfig;
import org.springframework.ide.eclipse.beans.core.model.IBeansProject;
import org.springframework.ide.eclipse.beans.ui.editor.util.BeansEditorUtils;
import org.springframework.ide.eclipse.core.io.ZipEntryStorage;
import org.springframework.ide.eclipse.core.java.Introspector;
import org.springframework.ide.eclipse.core.model.IModelChangeListener;
import org.springframework.ide.eclipse.core.model.IModelElement;
import org.springframework.ide.eclipse.core.model.ModelChangeEvent;
import org.springframework.ide.eclipse.core.model.ModelChangeEvent.Type;
import org.springframework.ide.eclipse.core.model.xml.XmlSourceLocation;
import org.springframework.ide.eclipse.ui.SpringUIUtils;

/**
* {@link ICommonContentProvider} that contributes elements from the {@link AopReferenceModel} created by
* {@link AopReferenceModelBuilderJob}.
* @author Christian Dupuis
* @author Torsten Juergeleit
* @since 2.0
*/
@SuppressWarnings("restriction")
public class AopReferenceModelNavigatorContentProvider implements ICommonContentProvider, IAopModelChangedListener,
    IModelChangeListener {

  private StructuredViewer viewer;

  public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
    if (viewer instanceof StructuredViewer) {
      this.viewer = (StructuredViewer) viewer;
    }
    else {
      this.viewer = null;
    }
  }

  public void dispose() {
    if (viewer != null && viewer.getInput() != null) {
      this.viewer = null;
    }
    Activator.getModel().unregisterAopModelChangedListener(this);
    BeansCorePlugin.getModel().removeChangeListener(this);
  }

  public Object[] getElements(Object inputElement) {
    if (inputElement instanceof IType) {
      return getChildren(inputElement);
    }
    else if (inputElement instanceof IMethod) {
      return getChildren(inputElement);
    }
    else if (inputElement instanceof IField) {
      return getChildren(inputElement);
    }
    else if (inputElement instanceof JavaElementReferenceNode) {
      return getChildren(((JavaElementReferenceNode) inputElement).getJavaElement());
    }
    else if (inputElement instanceof ElementImpl) {
      return getChildren(inputElement);
    }
    return IModelElement.NO_CHILDREN;
  }

  public Object[] getChildren(Object parentElement) {
    if (parentElement instanceof IReferenceNode) {
      return ((IReferenceNode) parentElement).getChildren();
    }
    else if (parentElement instanceof JavaElementReferenceNode
        && ((JavaElementReferenceNode) parentElement).isRoot()) {
      return getChildren(((JavaElementReferenceNode) parentElement).getJavaElement());
    }
    else if (parentElement instanceof IType) {
      IType type = (IType) parentElement;
      List<Object> me = new ArrayList<Object>();
      try {
        Set<IMethod> methods = Introspector.getAllMethods(type);
        for (IMethod method : methods) {
          if (Activator.getModel().isAdvice(method) || Activator.getModel().isAdvised(method)) {
            me.addAll(Arrays.asList(getChildren(method)));
          }
        }
      }
      catch (JavaModelException e) {
      }
      ClassMethodReferenceNode node = new ClassMethodReferenceNode(type, me);

      List<IAopReference> references = Activator.getModel().getAllReferences();

      // fields
      try {
        for (IField field : type.getFields()) {
          Object[] obj = getChildren(field);
          if (obj != null && obj.length > 0) {
            for (Object o : obj) {
              node.getDeclareParentReferences().add((IReferenceNode) o);
            }
          }
        }
      }
      catch (JavaModelException e) {
      }

      for (IAopReference reference : references) {
        if (reference.getAdviceType() == ADVICE_TYPE.DECLARE_PARENTS) {
          if (reference.getTarget().equals(type)) {
            node.getDeclaredOnReferences().add(reference);
          }
        }
      }
      // add bean references
      Set<IBeansConfig> configs = BeansCorePlugin.getModel().getConfigs(type.getFullyQualifiedName());
      Set<String> beans = new HashSet<String>();
      for (IBeansConfig config : configs) {
        List<IBean> pBeans = new ArrayList<IBean>();
        pBeans.addAll(config.getBeans());
        pBeans.addAll(BeansModelUtils.getInnerBeans(config));
        for (IBean b : pBeans) {
          if (type.getFullyQualifiedName().equals(BeansModelUtils.getBeanClass(b, config))) {
            beans.add(b.getElementID());
          }
        }
      }
      node.setBeans(beans);
      return new Object[] { node };
    }
    else if (parentElement instanceof IMethod) {
      IMethod method = (IMethod) parentElement;
      List<IAopReference> references = Activator.getModel().getAllReferences();
      List<IAopReference> foundSourceReferences = new ArrayList<IAopReference>();
      List<IAopReference> foundTargetReferences = new ArrayList<IAopReference>();
      for (IAopReference reference : references) {
        if (reference.getTarget().equals(method)) {
          foundTargetReferences.add(reference);
        }
        if (reference.getSource() != null && reference.getSource().equals(method)) {
          foundSourceReferences.add(reference);
        }
      }
      List<IReferenceNode> nodes = new ArrayList<IReferenceNode>();
      Map<IMember, MethodReference> refs = new HashMap<IMember, MethodReference>();
      for (IAopReference reference : foundSourceReferences) {
        if (refs.containsKey(reference.getSource())) {
          refs.get(reference.getSource()).getAspects().add(reference);
        }
        else {
          MethodReference r = new MethodReference();
          r.setMember(reference.getSource());
          r.getAspects().add(reference);
          refs.put(reference.getSource(), r);
        }
      }
      for (IAopReference reference : foundTargetReferences) {
        if (refs.containsKey(reference.getTarget())) {
          refs.get(reference.getTarget()).getAdvices().add(reference);
        }
        else {
          MethodReference r = new MethodReference();
          r.setMember(reference.getTarget());
          r.getAdvices().add(reference);
          refs.put(reference.getTarget(), r);
        }
      }
      for (Map.Entry<IMember, MethodReference> entry : refs.entrySet()) {
        nodes.add(new MethodBeanReferenceNode(entry.getKey(), entry.getValue().getAspects(), entry.getValue()
            .getAdvices()));
      }
      return nodes.toArray();
    }
    else if (parentElement instanceof IField && parentElement instanceof SourceField) {
      IField method = (IField) parentElement;
      List<IAopReference> references = Activator.getModel().getAllReferences();
      List<IAopReference> foundSourceReferences = new ArrayList<IAopReference>();
      for (IAopReference reference : references) {
        if (reference.getSource() != null && reference.getSource().equals(method)) {
          foundSourceReferences.add(reference);
        }
      }
      List<IReferenceNode> nodes = new ArrayList<IReferenceNode>();
      Map<IMember, List<IAopReference>> refs = new HashMap<IMember, List<IAopReference>>();
      for (IAopReference reference : foundSourceReferences) {
        if (refs.containsKey(reference.getSource())) {
          refs.get(reference.getSource()).add(reference);
        }
        else {
          List<IAopReference> f = new ArrayList<IAopReference>();
          f.add(reference);
          refs.put(reference.getSource(), f);
        }
      }
      for (Map.Entry<IMember, List<IAopReference>> entry : refs.entrySet()) {
        nodes.add(new AdviceDeclareParentAopSourceNode(entry.getValue()));
      }
      return nodes.toArray();
    }
    else if (parentElement instanceof ElementImpl) {
      ElementImpl element = (ElementImpl) parentElement;
      IStructuredDocument document = element.getStructuredDocument();
      List<IReferenceNode> nodes = new ArrayList<IReferenceNode>();

      IResource resource = SpringUIUtils.getFile(document);
      // check if resource is a Beans Config
      if (!BeansCoreUtils.isBeansConfig(resource, true) || document == null) {
        return nodes.toArray();
      }
      IBeansConfig beansConfig = BeansCorePlugin.getModel().getConfig((IFile) resource, true);
      int startLine = document.getLineOfOffset(element.getStartOffset()) + 1;
      int endLine = document.getLineOfOffset(element.getEndOffset()) + 1;
      String id = BeansEditorUtils.getAttribute(element, "id");

      nodes.addAll(getChildrenFromXmlLocation(resource, startLine, endLine, id, BeansModelUtils.getBeans(beansConfig)));

      return nodes.toArray();
    }
    return IModelElement.NO_CHILDREN;
  }

  private List<IReferenceNode> getChildrenFromXmlLocation(IResource resource, int startLine, int endLine, String id,
      Set<IBean> beans) {
    List<IReferenceNode> nodes = new ArrayList<IReferenceNode>();
    List<IAopReference> references = Activator.getModel().getAllReferencesForResource(resource);

    Map<IAspectDefinition, List<IAopReference>> foundSourceReferences = new HashMap<IAspectDefinition, List<IAopReference>>();
    Map<IAspectDefinition, List<IAopReference>> foundIntroductionSourceReferences = new HashMap<IAspectDefinition, List<IAopReference>>();
    Map<IBean, List<IAopReference>> foundTargetReferences = new HashMap<IBean, List<IAopReference>>();
    Map<IBean, List<IAopReference>> foundIntroductionTargetReferences = new HashMap<IBean, List<IAopReference>>();

    for (IAopReference reference : references) {
      if (reference.getDefinition().getAspectName().equals(id)
          || (reference.getDefinition().getAspectStartLineNumber() >= startLine
              && reference.getDefinition().getAspectStartLineNumber() <= endLine && resource
              .equals(reference.getDefinition().getResource()))) {
        if (reference.getAdviceType() == ADVICE_TYPE.DECLARE_PARENTS) {
          if (foundIntroductionSourceReferences.containsKey(reference.getDefinition())) {
            foundIntroductionSourceReferences.get(reference.getDefinition()).add(reference);
          }
          else {
            List<IAopReference> tmp = new ArrayList<IAopReference>();
            tmp.add(reference);
            foundIntroductionSourceReferences.put(reference.getDefinition(), tmp);
          }

        }
        else {
          if (foundSourceReferences.containsKey(reference.getDefinition())) {
            foundSourceReferences.get(reference.getDefinition()).add(reference);
          }
          else {
            List<IAopReference> tmp = new ArrayList<IAopReference>();
            tmp.add(reference);
            foundSourceReferences.put(reference.getDefinition(), tmp);
          }
        }
      }
      IBean targetBean = AopReferenceModelUtils.getBeanFromElementId(reference.getTargetBeanId());
      if (targetBean != null) {
        if (reference.getDefinition().getAspectName().equals(id)
            || (targetBean.getElementStartLine() >= startLine && targetBean.getElementEndLine() <= endLine && resource
                .equals(targetBean.getElementResource()))) {
          if (reference.getAdviceType() == ADVICE_TYPE.DECLARE_PARENTS) {
            if (foundIntroductionTargetReferences.containsKey(targetBean)) {
              foundIntroductionTargetReferences.get(targetBean).add(reference);
            }
            else {
              List<IAopReference> tmp = new ArrayList<IAopReference>();
              tmp.add(reference);
              foundIntroductionTargetReferences.put(targetBean, tmp);
            }
          }
          else {
            if (foundTargetReferences.containsKey(targetBean)) {
              foundTargetReferences.get(targetBean).add(reference);
            }
            else {
              List<IAopReference> tmp = new ArrayList<IAopReference>();
              tmp.add(reference);
              foundTargetReferences.put(targetBean, tmp);
            }
          }
        }
      }
    }

    // add normal beans
    Map<IBean, BeanReferenceNode> beansRefs = new HashMap<IBean, BeanReferenceNode>();
    for (IBean bean : beans) {
      if (bean.getElementStartLine() >= startLine && bean.getElementEndLine() <= endLine
          && BeansCorePlugin.getModel().getElement(bean.getElementID()) != null) {
        // Check model source location so that aop nodes are not added
        if (bean.getElementSourceLocation() instanceof XmlSourceLocation) {
          String namespace = ((XmlSourceLocation) bean.getElementSourceLocation()).getNamespaceURI();
          if (!namespace.equals("http://www.springframework.org/schema/aop")) {
            BeanReferenceNode rn = new BeanReferenceNode(bean.getElementID());
            nodes.add(rn);
            beansRefs.put(bean, rn);
          }
        }
        else {
          BeanReferenceNode rn = new BeanReferenceNode(bean.getElementID());
          nodes.add(rn);
          beansRefs.put(bean, rn);
        }
      }
    }
    // add found references
    if (foundTargetReferences.size() > 0) {
      for (Map.Entry<IBean, List<IAopReference>> entry : foundTargetReferences.entrySet()) {
        if (beansRefs.containsKey(entry.getKey())) {
          beansRefs.get(entry.getKey()).getAdviseReferences().addAll(entry.getValue());
        }
      }
    }
    if (foundIntroductionTargetReferences.size() > 0) {
      for (Map.Entry<IBean, List<IAopReference>> entry : foundIntroductionTargetReferences.entrySet()) {
        if (beansRefs.containsKey(entry.getKey())) {
          beansRefs.get(entry.getKey()).getDeclaredOnReferences().addAll(entry.getValue());
        }
      }
    }
    if (foundSourceReferences.size() > 0) {
      for (Map.Entry<IAspectDefinition, List<IAopReference>> entry : foundSourceReferences.entrySet()) {
        for (Map.Entry<IBean, BeanReferenceNode> n : beansRefs.entrySet()) {
          if (n.getKey().getElementStartLine() == entry.getKey().getAspectStartLineNumber()
              || entry.getKey().getAspectName().equals(n.getKey().getElementName())) {
            beansRefs.get(n.getKey()).getAspectReferences().addAll(entry.getValue());
          }
        }
      }
    }
    if (foundIntroductionSourceReferences.size() > 0) {
      for (Map.Entry<IAspectDefinition, List<IAopReference>> entry : foundIntroductionSourceReferences.entrySet()) {
        for (Map.Entry<IBean, BeanReferenceNode> n : beansRefs.entrySet()) {
          if (n.getKey().getElementStartLine() == entry.getKey().getAspectStartLineNumber()
              || entry.getKey().getAspectName().equals(n.getKey().getElementName())) {
            beansRefs.get(n.getKey()).getDeclareParentReferences().addAll(entry.getValue());
          }
        }
      }
    }
    return nodes;
  }

  public Object getParent(Object element) {
    if (element instanceof IModelElement) {
      return ((IModelElement) element).getElementParent();
    }
    else if (element instanceof IFile) {
      IBeansConfig config = BeansCorePlugin.getModel().getConfig((IFile) element);
      if (config != null) {
        return config.getElementParent();
      }
    }
    else if (element instanceof ZipEntryStorage) {
      IBeansConfig config = BeansCorePlugin.getModel().getConfig(((ZipEntryStorage) element).getFullName());
      if (config != null) {
        return config.getElementParent();
      }
    }
    return null;
  }

  public boolean hasChildren(Object element) {
    if (element instanceof IReferenceNode) {
      return ((IReferenceNode) element).hasChildren();
    }
    else if (element instanceof IType) {
      IType type = (IType) element;
      try {
        IMethod[] methods = type.getMethods();
        for (IMethod method : methods) {
          if (Activator.getModel().isAdvised(method) || Activator.getModel().isAdvice(method)) {
            return true;
          }
        }
      }
      catch (JavaModelException e) {
      }
    }
    else if (element instanceof IMethod) {
      IMethod method = (IMethod) element;
      List<IAopReference> references = Activator.getModel().getAllReferences();
      for (IAopReference reference : references) {
        if (reference.getTarget().equals(method)) {
          return true;
        }
        if (reference.getSource().equals(method)) {
          return true;
        }
      }
    }
    return false;
  }

  protected void refreshViewer(final Object element) {
    if (viewer instanceof TreeViewer) {
      Control ctrl = viewer.getControl();

      // Are we in the UI thread?
      if (ctrl.getDisplay().getThread() == Thread.currentThread()) {
        AopReferenceModelNavigator.refreshViewer((TreeViewer) viewer, AopReferenceModelNavigator
            .calculateRootElement(element), element);
      }
      else {
        ctrl.getDisplay().asyncExec(new Runnable() {
          public void run() {

            // Abort if this happens after disposes
            Control ctrl = viewer.getControl();
            if (ctrl == null || ctrl.isDisposed()) {
              return;
            }
            AopReferenceModelNavigator.refreshViewer((TreeViewer) viewer, AopReferenceModelNavigator
                .calculateRootElement(element), element);
          }
        });
      }
    }
  }

  public void init(ICommonContentExtensionSite config) {
    Activator.getModel().registerAopModelChangedListener(this);
    BeansCorePlugin.getModel().addChangeListener(this);
  }

  public void saveState(IMemento aMemento) {
  }

  public void restoreState(IMemento aMemento) {
  }

  public void changed() {
    Object obj = viewer.getInput();
    refreshViewer(obj);
  }

  public void elementChanged(ModelChangeEvent event) {
    if (event.getType() == Type.CHANGED && event.getSource() instanceof IBeansProject) {
      changed();
    }
  }
}
TOP

Related Classes of org.springframework.ide.eclipse.aop.ui.navigator.AopReferenceModelNavigatorContentProvider

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.