Package org.dozer.eclipse.plugin.sourcepage.hyperlink

Source Code of org.dozer.eclipse.plugin.sourcepage.hyperlink.DozerClassHyperlinkDetector

/**
* Copyright 2005-2013 Dozer Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dozer.eclipse.plugin.sourcepage.hyperlink;

import org.dozer.eclipse.plugin.sourcepage.util.DozerPluginUtils;
import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.wst.xml.core.internal.Logger;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.springframework.ide.eclipse.beans.core.internal.model.BeansMapEntry;
import org.springframework.ide.eclipse.beans.core.model.IBean;
import org.springframework.ide.eclipse.beans.ui.editor.hyperlink.JavaElementHyperlink;
import org.springframework.ide.eclipse.beans.ui.editor.util.BeansEditorUtils;
import org.springframework.ide.eclipse.core.StringUtils;
import org.springframework.ide.eclipse.core.java.Introspector;
import org.springframework.ide.eclipse.core.java.JdtUtils;
import org.springframework.ide.eclipse.core.model.ISourceModelElement;
import org.w3c.dom.Attr;
import org.w3c.dom.Node;

import java.util.Set;

public class DozerClassHyperlinkDetector extends AbstractHyperlinkDetector {

  @SuppressWarnings("restriction")
  public final IHyperlink[] detectHyperlinks(ITextViewer textViewer,
      IRegion region, boolean canShowMultipleHyperlinks) {
    if (region == null || textViewer == null) {
      return null;
    }

    IDocument document = textViewer.getDocument();
   
    Node currentNode = BeansEditorUtils.getNodeByOffset(document, region.getOffset());
    if (currentNode != null) {
      switch (currentNode.getNodeType()) {
      case Node.ELEMENT_NODE:
        // at first try to handle selected attribute value
        Attr currentAttr = BeansEditorUtils.getAttrByOffset(
            currentNode, region.getOffset());
        IDOMAttr attr = (IDOMAttr) currentAttr;
        if (currentAttr != null
            && region.getOffset() >= attr
                .getValueRegionStartOffset()) {
          if (isLinkableAttr(currentAttr)) {
            IRegion hyperlinkRegion = getHyperlinkRegion(currentAttr);
            IHyperlink hyperLink = createHyperlink(currentAttr
                .getName(), currentAttr.getNodeValue(),
                currentNode, currentNode.getParentNode(),
                document, textViewer, hyperlinkRegion, region);
            if (hyperLink != null) {
              return new IHyperlink[] { hyperLink };
            }
          }
        }
        break;

      case Node.TEXT_NODE:
        IRegion hyperlinkRegion = getHyperlinkRegion(currentNode);
        Node parentNode = currentNode.getParentNode();
        if (parentNode != null) {
          IHyperlink hyperLink = createHyperlink(parentNode
              .getNodeName(), currentNode.getNodeValue(),
              currentNode, parentNode, document, textViewer,
              hyperlinkRegion, region);
          if (hyperLink != null) {
            return new IHyperlink[] { hyperLink };
          }
        }
        break;
      }
    }
    return null;
  }

  public IHyperlink createHyperlink(String attrName, String target, Node node,
      Node parentNode, IDocument document, ITextViewer textViewer,
      IRegion hyperlinkRegion, IRegion cursor) {
    String nodeName = parentNode.getNodeName();
    IFile file = BeansEditorUtils.getFile(document);       
    IType type = JdtUtils.getJavaType(file.getProject(), target);
   
    if ("class-a".equals(nodeName) || "class-b".equals(nodeName) || "a-hint".equals(attrName) || "b-hint".equals(attrName) || "a-deep-index-hint".equals(attrName) || "b-deep-index-hint".equals(attrName)) {
      //make a simple hyperlink to the class
      if (type != null) {
        return new JavaElementHyperlink(hyperlinkRegion, type);
      }
    } else if ("set-method".equals(attrName) || "get-method".equals(attrName) || "map-set-method".equals(attrName) || "map-get-method".equals(attrName) ) {
      if ("field".equals(nodeName)) {
        String targetClassName = DozerPluginUtils.getMappingClassName(node);
       
        //get the first method that matches and make a hyperlink to that
        if (targetClassName != null) {
          IType targetClass = JdtUtils.getJavaType(file.getProject(), targetClassName);
          IMethod method = getMethodFromType(targetClass, target);
          if (method != null) {
            return new JavaElementHyperlink(hyperlinkRegion, method);
          }
        }
      }
    } else if ("a-hint".equals(attrName) || "b-hint".equals(attrName)) {
      //make a simple hyperlink to the class
      if (parentNode.getParentNode() != null && "mapping".equals(parentNode.getParentNode().getNodeName())) {
        if (type != null) {
          return new JavaElementHyperlink(hyperlinkRegion, type);
        }
      }   
    } else if ("custom-converter".equals(attrName)) {
      //make a simple hyperlink to the class
      if (type != null) {
        return new JavaElementHyperlink(hyperlinkRegion, type);
      }
    } else if ("custom-converter-id".equals(attrName)) {
      //search spring-bean that uses our mapping file and return the mapping
      //for the customconverter-id map-property
      ISourceModelElement modelElement = getModelElementForCustomConverter(BeansEditorUtils.getFile(document), target);
         
      if (modelElement != null) {
        return new SourceModelHyperlink(modelElement, hyperlinkRegion);
      }
    } else if ("a".equals(nodeName) || "b".equals(nodeName) ) {
      String targetClassName = DozerPluginUtils.getMappingClassName(node.getParentNode());
      String property = node.getNodeValue();
     
      if (targetClassName != null) {
        IType targetClass = JdtUtils.getJavaType(file.getProject(), targetClassName);
       
        try {
          //if we are doing indexed property mapping, we remove the []
          property = property.replaceAll("\\[\\]", "");
         
          IMethod method = Introspector.getReadableProperty(targetClass, property);
         
          if (method != null)
            return new JavaElementHyperlink(hyperlinkRegion, method);         
        } catch (Throwable e) {
          Logger.logException(e);
        }       
      }
    } else if ("bean-factory".equals(attrName)) {
      //make a simple hyperlink to the class
      if (type != null) {
        return new JavaElementHyperlink(hyperlinkRegion, type);
      }
    }
   
    return null;
  }
 
  /**
   * Get First Method by name
   *
   * @param type
   * @param methodName
   * @return
   */
  private IMethod getMethodFromType(IType type, String methodName) {
    try {
      Set<IMethod> methods = Introspector.getAllMethods(type);
      for (IMethod method : methods) {
        if (method.getElementName().equals(methodName)) {
          return method;
        }
      }
    } catch (Exception e) {}
   
    return null;
  }
 
  private ISourceModelElement getModelElementForCustomConverter(IFile file, String customConverterId) {
    IBean bean = DozerPluginUtils.getDozerBeanForMappingFile(file);
    BeansMapEntry modelElement = DozerPluginUtils.getCCIModelElementForMappingFile(bean, customConverterId);

    if (modelElement != null)
      return modelElement;

      //exact property not found, at least return bean
    return bean;
 

  public boolean isLinkableAttr(Attr attr) {
    String attrName = attr.getName();
    String ownerName = attr.getOwnerElement().getNodeName();
    String parentName = attr.getOwnerElement().getParentNode().getNodeName();
   
    if ("bean-factory".equals(attrName))
      return true;   
    else if ("field".equals(ownerName)) {
      if ("custom-converter".equals(attrName) || "custom-converter-id".equals(attrName))
        return true;
    } else if ("field".equals(parentName)) {
      if ("set-method".equals(attrName) || "get-method".equals(attrName) || "map-set-method".equals(attrName) || "map-get-method".equals(attrName))
        return true;
    }

     
    return false;
 
 
  @SuppressWarnings("restriction")
  protected final IRegion getHyperlinkRegion(Node node) {
    if (node != null) {
      switch (node.getNodeType()) {
      case Node.DOCUMENT_TYPE_NODE:
      case Node.TEXT_NODE:
        IDOMNode docNode = (IDOMNode) node;
        return new Region(docNode.getStartOffset(), docNode
            .getEndOffset()
            - docNode.getStartOffset());

      case Node.ELEMENT_NODE:
        IDOMElement element = (IDOMElement) node;
        int endOffset;
        if (element.hasEndTag() && element.isClosed()) {
          endOffset = element.getStartEndOffset();
        }
        else {
          endOffset = element.getEndOffset();
        }
        return new Region(element.getStartOffset(), endOffset
            - element.getStartOffset());

      case Node.ATTRIBUTE_NODE:
        IDOMAttr att = (IDOMAttr) node;
        // do not include quotes in attribute value region
        int regOffset = att.getValueRegionStartOffset();
        int regLength = att.getValueRegionText().length();
        String attValue = att.getValueRegionText();
        if (StringUtils.isQuoted(attValue)) {
          regOffset += 1;
          regLength = regLength - 2;
        }
        return new Region(regOffset, regLength);
      }
    }
    return null;
  }
 
}
TOP

Related Classes of org.dozer.eclipse.plugin.sourcepage.hyperlink.DozerClassHyperlinkDetector

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.