Package org.springframework.ide.eclipse.beans.ui.editor.hyperlink.tool

Source Code of org.springframework.ide.eclipse.beans.ui.editor.hyperlink.tool.ToolAnnotationBasedHyperlinkDetector

/*******************************************************************************
* Copyright (c) 2008 - 2013 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.beans.ui.editor.hyperlink.tool;

import java.util.Iterator;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.springframework.ide.eclipse.beans.core.model.IBean;
import org.springframework.ide.eclipse.beans.core.namespaces.ToolAnnotationUtils;
import org.springframework.ide.eclipse.beans.core.namespaces.ToolAnnotationUtils.ToolAnnotationData;
import org.springframework.ide.eclipse.beans.ui.editor.hyperlink.AbstractAnnotationBasedHyperlinkDetector;
import org.springframework.ide.eclipse.beans.ui.editor.hyperlink.ExternalBeanHyperlink;
import org.springframework.ide.eclipse.beans.ui.editor.hyperlink.HyperlinkUtils;
import org.springframework.ide.eclipse.beans.ui.editor.hyperlink.IAnnotationBasedHyperlinkDetector;
import org.springframework.ide.eclipse.beans.ui.editor.hyperlink.JavaElementHyperlink;
import org.springframework.ide.eclipse.beans.ui.editor.hyperlink.NodeElementHyperlink;
import org.springframework.ide.eclipse.beans.ui.editor.util.BeansEditorUtils;
import org.springframework.ide.eclipse.core.java.Introspector;
import org.springframework.ide.eclipse.core.java.Introspector.Public;
import org.springframework.ide.eclipse.core.java.Introspector.Static;
import org.springframework.ide.eclipse.core.java.JdtUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.Node;

/**
* {@link IAnnotationBasedHyperlinkDetector} that reads out the tool annotations and offers bean reference and java
* hyperlinks.
* @author Christian Dupuis
* @since 2.0.3
*/
public class ToolAnnotationBasedHyperlinkDetector extends AbstractAnnotationBasedHyperlinkDetector {

  private static final String REF_ATTRIBUTE = "ref";

  @Override
  public IHyperlink createHyperlink(String name, String target, Node node, Node parentNode, IDocument document,
      ITextViewer textViewer, IRegion hyperlinkRegion, IRegion cursor, Node annotation) {

    IFile file = BeansEditorUtils.getFile(document);
    ToolAnnotationData annotationData = ToolAnnotationUtils.getToolAnnotationData(annotation);

    if (REF_ATTRIBUTE.equals(annotationData.getKind())) {
      Node bean = BeansEditorUtils.getFirstReferenceableNodeById(node.getOwnerDocument(), target, file);
      if (bean != null) {
        IRegion region = getHyperlinkRegion(bean);
        return new NodeElementHyperlink(hyperlinkRegion, region, textViewer);
      }
      else {
        // assume this is an external reference
        Iterator<?> beans = BeansEditorUtils.getBeansFromConfigSets(file).iterator();
        while (beans.hasNext()) {
          IBean modelBean = (IBean) beans.next();
          if (modelBean.getElementName().equals(target)) {
            return new ExternalBeanHyperlink(modelBean, hyperlinkRegion);
          }
        }
      }
    }
    else if (Class.class.getName().equals(annotationData.getExpectedType())) {
      IHyperlink[] detectedHyperlinks = HyperlinkUtils.getXmlJavaHyperlinks(textViewer, hyperlinkRegion);
     
      // only return hyperlink if no xml Java hyperlink will be created to avoid duplicates
      if (detectedHyperlinks == null || detectedHyperlinks.length == 0) {
        if (file != null && file.exists()) {
          IType type = JdtUtils.getJavaType(file.getProject(), target);
          if (type != null) {
            return new JavaElementHyperlink(hyperlinkRegion, type);
          }
        }
      }
    }
    if (annotationData.getExpectedMethodType() != null) {
      String className = evaluateXPathExpression(annotationData.getExpectedMethodType(), node);
      return createMethodHyperlink(target, hyperlinkRegion, file, className);
    }
    else if (annotationData.getExpectedMethodRef() != null) {
      String typeName = evaluateXPathExpression(annotationData.getExpectedMethodRef(), node);
      String className = BeansEditorUtils.getClassNameForBean(file, node.getOwnerDocument(), typeName);
      return createMethodHyperlink(target, hyperlinkRegion, file, className);
    }
    return null;
  }

  private IHyperlink createMethodHyperlink(String target, IRegion hyperlinkRegion, IFile file, String className) {
    if (file != null && file.exists()) {
      IType type = JdtUtils.getJavaType(file.getProject(), className);
      try {
        IMethod method = Introspector.findMethod(type, target, -1, Public.DONT_CARE, Static.DONT_CARE);
        if (method != null) {
          return new JavaElementHyperlink(hyperlinkRegion, method);
        }
      }
      catch (JavaModelException e) {
        // ignore this here
      }
    }
    return null;
  }

  @Override
  public boolean isLinkableAttr(Attr attr, Node annotation) {
    if (ToolAnnotationUtils.ANNOTATION_ELEMENT.equals(annotation.getLocalName())
        && ToolAnnotationUtils.TOOL_NAMESPACE_URI.equals(annotation.getNamespaceURI())) {
      ToolAnnotationData annotationData = ToolAnnotationUtils.getToolAnnotationData(annotation);
      return annotationData != null
          && (REF_ATTRIBUTE.equals(annotationData.getKind())
              || Class.class.getName().equals(annotationData.getExpectedType())
              || annotationData.getExpectedMethodRef() != null || annotationData.getExpectedMethodType() != null);
    }
    return false;
  }

  protected String evaluateXPathExpression(String xpath, Node node) {
    XPathFactory factory = XPathFactory.newInstance();
    XPath path = factory.newXPath();
    try {
      return path.evaluate(xpath, node);
    }
    catch (XPathExpressionException e) {
      return null;
    }
  }

}
TOP

Related Classes of org.springframework.ide.eclipse.beans.ui.editor.hyperlink.tool.ToolAnnotationBasedHyperlinkDetector

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.