Package org.springframework.ide.eclipse.quickfix.jdt.util

Source Code of org.springframework.ide.eclipse.quickfix.jdt.util.ProposalCalculatorUtil$AnnotationFinder

/*******************************************************************************
*  Copyright (c) 2012 VMware, 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:
*      VMware, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.quickfix.jdt.util;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.security.Principal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.IAnnotatable;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IPackageDeclaration;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.ArrayType;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.QualifiedType;
import org.eclipse.jdt.core.dom.SimpleType;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.WildcardType;
import org.eclipse.jdt.internal.core.SourceMethod;
import org.eclipse.jdt.internal.ui.text.correction.AssistContext;
import org.eclipse.jdt.ui.text.java.IInvocationContext;
import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext;
import org.springframework.ide.eclipse.beans.core.BeansCorePlugin;
import org.springframework.ide.eclipse.beans.core.autowire.internal.provider.AutowireDependencyProvider;
import org.springframework.ide.eclipse.beans.core.internal.model.BeansModelUtils;
import org.springframework.ide.eclipse.beans.core.internal.model.validation.rules.ValidationRuleUtils;
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.IBeansModel;
import org.springframework.ide.eclipse.beans.core.model.IBeansProject;
import org.springframework.ide.eclipse.core.SpringCore;
import org.springframework.ide.eclipse.core.java.JdtUtils;
import org.springframework.ide.eclipse.core.model.validation.ValidationProblem;
import org.springframework.ide.eclipse.core.model.validation.ValidationProblemAttribute;

/**
* @author Terry Denney
* @author Martin Lippert
*/
public class ProposalCalculatorUtil {

  public static boolean containsImport(ICompilationUnit cu, String importName) {
    String importPackageName = importName;
    int index = importName.lastIndexOf(".");
    if (index > 0) {
      importPackageName = importName.substring(0, index);
    }

    try {
      IPackageDeclaration[] packageDecls = cu.getPackageDeclarations();
      for (IPackageDeclaration packageDecl : packageDecls) {
        String packageName = packageDecl.getElementName();
        if (packageName.equals(importPackageName)) {
          return true;
        }

      }
      IImportDeclaration[] importDecls = cu.getImports();
      for (IImportDeclaration importDecl : importDecls) {
        String importElementName = importDecl.getElementName();
        index = importElementName.lastIndexOf(".");
        String importElementPackageName = importElementName;
        if (index > 0) {
          importElementPackageName = importElementName.substring(0, index);
        }
        if (importElementName.endsWith("*")) {
          if (importPackageName.equals(importElementPackageName)) {
            return true;
          }
        }
        else {
          if (importName.equals(importElementName)) {
            return true;
          }
        }
      }
    }
    catch (JavaModelException e) {
      SpringCore.log(e);
    }

    return false;
  }

  public static Set<Annotation> findAnnotations(String annotation, ASTNode node) {
    AnnotationFinder finder = new AnnotationFinder(annotation);
    node.accept(finder);
    return finder.getAnnotations();
  }

  public static Set<Annotation> findAnnotations(String annotation, int invocationOffset, ASTNode node) {
    AnnotationFinder finder = new AnnotationFinder(annotation, invocationOffset);
    node.accept(finder);
    return finder.getAnnotations();
  }

  public static boolean hasAnnotationInParameters(SourceMethod method, String annotationName) {
    try {
      if (method.getSource() != null) {
        return method.getSource().contains('@' + annotationName);
      }
      return false;
    }
    catch (JavaModelException e) {
      SpringCore.log(e);
      return false;
    }
  }

  public static boolean hasAnnotationOnType(ICompilationUnit cu, String annotationName) {
    try {
      IType[] allTypes = cu.getAllTypes();
      for (IType type : allTypes) {
        IAnnotation[] annotations = type.getAnnotations();
        for (IAnnotation annotation : annotations) {
          if (annotationName.equals(annotation.getElementName())) {
            return true;
          }
        }
      }
    }
    catch (JavaModelException e) {
      SpringCore.log(e);
    }
    return false;
  }

  public static boolean hasAnnotation(IAnnotatable element, String annotationName) {
    try {
      IAnnotation[] annotations = element.getAnnotations();
      for (IAnnotation annotation : annotations) {
        if (annotationName.equals(annotation.getElementName())) {
          return true;
        }
      }
    }
    catch (JavaModelException e) {
      SpringCore.log(e);
    }
    return false;
  }

  /**
   * @param declToMatch
   * @param problemType
   * @param cu
   * @param typeNameToMatch problem marker should match this typeName, set to
   * Null if it should match any types
   * @return
   */
  public static ValidationProblem findProblem(BodyDeclaration declToMatch, String problemType, ICompilationUnit cu,
      String typeNameToMatch) {
    IBeansModel model = BeansCorePlugin.getModel();
    IBeansProject springProject = model.getProject(cu.getJavaProject().getProject());
    Set<IBeansConfig> configs = springProject.getConfigs();
    for (IBeansConfig config : configs) {
      AutowireDependencyProvider provider = new AutowireDependencyProvider(config, config);
      provider.resolveAutowiredDependencies();
      List<ValidationProblem> problems = provider.getValidationProblems();
      for (ValidationProblem problem : problems) {
        ValidationProblemAttribute[] problemAttributes = problem.getAttributes();
        boolean matched = false;
        BodyDeclaration problemDecl = null;
        String typeName = null;

        for (ValidationProblemAttribute problemAttribute : problemAttributes) {

          if (AutowireDependencyProvider.AUTOWIRE_PROBLEM_TYPE.equals(problemAttribute.getKey())) {
            if (problemType.equals(problemAttribute.getValue())) {
              matched = true;
            }
          }
          else if ("JAVA_HANDLE".equals(problemAttribute.getKey())) {
            problemDecl = getBodyDeclaration(JavaCore.create((String) problemAttribute.getValue()));
          }
          else if (AutowireDependencyProvider.BEAN_TYPE.equals(problemAttribute.getKey())) {
            typeName = (String) problemAttribute.getValue();
          }
        }

        if (matched && problemDecl != null && problemDecl.equals(declToMatch)) {
          if (typeNameToMatch == null || (typeName != null && typeName.equals(typeNameToMatch))) {
            return problem;
          }
        }
      }
    }
    return null;
  }

  public static Set<String> getMatchingBeans(IInvocationContext context, ITypeBinding typeBinding) {
    IProject project = null;
    try {
      project = context.getCompilationUnit().getUnderlyingResource().getProject();
    }
    catch (JavaModelException e) {
      return new HashSet<String>();
    }

    String typeName = typeBinding.getQualifiedName();
    IBeansProject springProject = BeansCorePlugin.getModel().getProject(project);
    return getMatchingBeans(typeName, springProject, null);
  }

  public static Set<String> getMatchingBeans(IInvocationContext context, ITypeBinding typeBinding, String qualifier) {
    IProject project = null;
    try {
      project = context.getCompilationUnit().getUnderlyingResource().getProject();
    }
    catch (JavaModelException e) {
      return new HashSet<String>();
    }

    String typeName = typeBinding.getQualifiedName();
    IBeansProject springProject = BeansCorePlugin.getModel().getProject(project);
    return getMatchingBeans(typeName, springProject, qualifier);
  }

  public static Set<String> getMatchingBeans(JavaContentAssistInvocationContext context, ITypeBinding type) {
    IBeansProject springProject = BeansCorePlugin.getModel().getProject(context.getProject().getProject());
    String typeName = type.getQualifiedName();
    return getMatchingBeans(typeName, springProject, null);
  }

  // public static Set<String> getMatchingBeans(String typeName, IBeansProject
  // springProject) {
  // Set<String> matchingBeans = new HashSet<String>();
  //
  // Class<?> clazz = null;
  // try {
  // clazz = ClassUtils.loadClass(typeName);
  //
  // Set<IBeansConfig> configs = springProject.getConfigs();
  // for (IBeansConfig config : configs) {
  // AutowireDependencyProvider provider = new
  // AutowireDependencyProvider(config, config);
  // provider.getBeansForType(clazz);
  // }
  // }
  // catch (ClassNotFoundException e) {
  // }
  //
  // return matchingBeans;
  // }

  public static Set<String> getMatchingBeans(String typeName, IBeansProject springProject, String qualifier) {
    Set<String> matchingBeans = new HashSet<String>();
    Class<?> clazz = null;
    ClassLoader classLoader = JdtUtils.getProjectClassLoaderSupport(springProject.getProject(),
        BeansCorePlugin.getClassLoader()).getProjectClassLoader();
    try {
      clazz = classLoader.loadClass(typeName);
    }
    catch (ClassNotFoundException e) {
      return matchingBeans;
    }

    Set<IBean> beans = BeansModelUtils.getBeans(springProject);
    for (IBean bean : beans) {
      String beanClassName = ValidationRuleUtils.getBeanClassName(bean);
      if (beanClassName != null) {
        try {
          Class<?> beanClass = classLoader.loadClass(beanClassName);
          if (clazz.isAssignableFrom(beanClass)) {
            if (qualifier == null || qualifier.equals(bean.getElementName())) {
              matchingBeans.add(bean.getElementName());
            }
          }
        }
        catch (ClassNotFoundException e) {
        }
      }
    }
    return matchingBeans;
  }

  // public static Set<String> getMatchingBeans(BodyDeclaration declToMatch,
  // ICompilationUnit cu, String typeName) {
  // System.err.println("getMatchingBeans: " + typeName);
  // Set<String> matchingBeans = new HashSet<String>();
  //
  // ValidationProblem problem = findProblem(declToMatch,
  // AutowireDependencyProvider.TOO_MANY_MATCHING_BEANS, cu,
  // typeName);
  // if (problem != null) {
  // ValidationProblemAttribute[] attributes = problem.getAttributes();
  // for (ValidationProblemAttribute attribute : attributes) {
  // if
  // (attribute.getKey().startsWith(AutowireDependencyProvider.MATCHING_BEAN_NAME))
  // {
  // matchingBeans.add((String) attribute.getValue());
  // }
  // }
  // }
  //
  // return matchingBeans;
  // }

  public static String getPathVariableName(SingleVariableDeclaration param) {
    Set<Annotation> annotations = ProposalCalculatorUtil.findAnnotations("PathVariable", param);
    for (Annotation annotation : annotations) {
      if (annotation.isMarkerAnnotation()) {
        return param.getName().getFullyQualifiedName();
      }
      else if (annotation.isSingleMemberAnnotation()) {
        Expression value = ((SingleMemberAnnotation) annotation).getValue();
        if (value instanceof StringLiteral) {
          return ((StringLiteral) value).getLiteralValue();
        }
      }
      else if (annotation.isNormalAnnotation()) {
        NormalAnnotation nAnnotation = (NormalAnnotation) annotation;
        @SuppressWarnings("unchecked")
        List<MemberValuePair> valuePairs = nAnnotation.values();
        for (MemberValuePair valuePair : valuePairs) {
          if ("value".equals(valuePair.getName().getIdentifier())) {
            Expression value = valuePair.getValue();
            if (value instanceof StringLiteral) {
              return ((StringLiteral) value).getLiteralValue();
            }
          }
        }
      }
    }

    return null;
  }

  @SuppressWarnings("unchecked")
  public static MemberValuePair getRequiredMemberValuePair(BodyDeclaration decl) {
    Set<Annotation> annotations = ProposalCalculatorUtil.findAnnotations("Autowired", decl);
    for (Annotation annotation : annotations) {
      if (annotation instanceof NormalAnnotation) {
        NormalAnnotation normalAnnotation = (NormalAnnotation) annotation;
        List<MemberValuePair> values = normalAnnotation.values();
        for (MemberValuePair valuePair : values) {
          if ("required".equals(valuePair.getName().toString())) {
            return valuePair;
          }
        }
      }
    }
    return null;
  }

  @SuppressWarnings("unchecked")
  public static String getTypeName(Type type) {
    StringBuilder result = new StringBuilder();

    if (type.isArrayType()) {
      result.append(getTypeName(((ArrayType) type).getElementType()));
      result.append("[]");
    }
    else if (type.isParameterizedType()) {
      ParameterizedType pType = (ParameterizedType) type;
      result.append(getTypeName(pType.getType()));
      List<Type> typeArguments = pType.typeArguments();
      for (int i = 0; i < typeArguments.size(); i++) {
        if (i > 0) {
          result.append(", ");
        }
        result.append(getTypeName(typeArguments.get(i)));
      }
    }
    else if (type.isPrimitiveType()) {
      result.append(((PrimitiveType) type).getPrimitiveTypeCode().toString());
    }
    else if (type.isQualifiedType()) {
      QualifiedType qType = (QualifiedType) type;
      Type qualifier = qType.getQualifier();
      if (qualifier != null) {
        result.append(getTypeName(qualifier));
        result.append(".");
      }
      result.append(qType.getName().getFullyQualifiedName());
    }
    else if (type.isSimpleType()) {
      result.append(((SimpleType) type).getName().getFullyQualifiedName());
    }
    else if (type.isWildcardType()) {
      WildcardType wType = (WildcardType) type;
      result.append("? ");
      if (wType.isUpperBound()) {
        result.append("extends ");
      }
      else {
        result.append("super ");
      }
      result.append(getTypeName(wType.getBound()));
    }

    return result.toString();
  }

  @SuppressWarnings("unchecked")
  public static List<UriTemplateVariable> getUriTemplatVariables(Annotation annotation) {
    if (annotation instanceof SingleMemberAnnotation) {
      SingleMemberAnnotation sAnnotation = (SingleMemberAnnotation) annotation;
      return getUriTemplateVariables(sAnnotation.getValue());
    }
    else if (annotation instanceof NormalAnnotation) {
      NormalAnnotation nAnnotation = (NormalAnnotation) annotation;
      List<MemberValuePair> pairs = nAnnotation.values();
      for (MemberValuePair pair : pairs) {
        if ("value".equals(pair.getName().getFullyQualifiedName())) {
          return getUriTemplateVariables(pair.getValue());
        }
      }
    }

    return new ArrayList<UriTemplateVariable>();
  }

  /**
   * @param annotation to be matched, or null if matches all annotations
   * @param node
   * @return true if there is a matching annotation on the node
   */
  public static boolean hasAnnotation(String annotation, ASTNode node) {
    AnnotationFinder finder = new AnnotationFinder(annotation);
    node.accept(finder);
    Set<Annotation> annotations = finder.getAnnotations();
    return !annotations.isEmpty();
  }

  public static boolean hasProblem(BodyDeclaration declToMatch, String problemType, ICompilationUnit cu) {
    return findProblem(declToMatch, problemType, cu, null) != null;
  }

  private static Class<?>[] KNOWN_REQUEST_MAPPING_PARAM_TYPE = new Class<?>[] { InputStream.class,
      OutputStream.class, Reader.class, Writer.class, Principal.class, Locale.class, HttpServletRequest.class,
      HttpServletResponse.class, HttpSession.class };

  public static boolean isKnownRequestMappingParamType(IProject project, ITypeBinding typeBinding) {
    String typeName = typeBinding.getQualifiedName();
    ClassLoader classLoader = JdtUtils.getProjectClassLoaderSupport(project, BeansCorePlugin.getClassLoader())
        .getProjectClassLoader();
    try {
      Class<?> clazz = classLoader.loadClass(typeName);

      for (Class<?> knownClass : KNOWN_REQUEST_MAPPING_PARAM_TYPE) {
        Class<?> loadedClass = classLoader.loadClass(knownClass.getCanonicalName());
        if (loadedClass.isAssignableFrom(clazz)) {
          return true;
        }
      }
    }
    catch (ClassNotFoundException e) {
    }

    return false;
  }

  private static BodyDeclaration getBodyDeclaration(IJavaElement element) {
    try {
      if (element instanceof IMember) {
        IMember member = (IMember) element;
        ICompilationUnit compilationUnit = member.getCompilationUnit();
        ISourceRange sourceRange = member.getSourceRange();
        AssistContext assistContext = new AssistContext(compilationUnit, null, sourceRange.getOffset(),
            sourceRange.getLength());
        ASTNode node = assistContext.getCoveringNode();
        if (node instanceof BodyDeclaration) {
          return (BodyDeclaration) node;
        }
      }
    }
    catch (JavaModelException e) {
    }
    return null;
  }

  private static List<UriTemplateVariable> getUriTemplateVariables(Expression expression) {
    List<UriTemplateVariable> variables = new ArrayList<UriTemplateVariable>();

    if (expression instanceof StringLiteral) {
      StringLiteral literal = (StringLiteral) expression;
      String uriTemplate = literal.getLiteralValue();
      int offset = 1; // skip start quote

      while (uriTemplate.length() > 0) {
        int index = uriTemplate.indexOf("{");
        if (index < 0) {
          break;
        }

        uriTemplate = uriTemplate.substring(index + 1);
        offset += index + 1;

        index = uriTemplate.indexOf(":");
        if (index < 0) {
          index = uriTemplate.indexOf("}");
          if (index < 0) {
            break;
          }
        }

        variables.add(new UriTemplateVariable(uriTemplate.substring(0, index), offset, literal));
        uriTemplate = uriTemplate.substring(index + 1);
        offset += index + 1;
      }
    }

    return variables;
  }

  private static class AnnotationFinder extends ASTVisitor {

    Set<Annotation> annotations = new HashSet<Annotation>();

    private final String annotationToMatch;

    private final int invocationOffset;

    private boolean isTypeDecl;

    public AnnotationFinder(String annotationToMatch) {
      this.annotationToMatch = annotationToMatch;
      this.invocationOffset = -1;
    }

    public AnnotationFinder(String annotationToMatch, int invocationOffset) {
      this.annotationToMatch = annotationToMatch;
      this.invocationOffset = invocationOffset;

    }

    public Set<Annotation> getAnnotations() {
      return annotations;
    }

    @Override
    public boolean visit(FieldDeclaration node) {
      if (isTypeDecl) {
        return false;
      }
      return super.visit(node);
    }

    @Override
    public boolean visit(MarkerAnnotation node) {
      if (matches(node)) {
        annotations.add(node);
      }
      return false;
    }

    @Override
    public boolean visit(MethodDeclaration node) {
      if (isTypeDecl) {
        return false;
      }
      return super.visit(node);
    }

    @Override
    public boolean visit(NormalAnnotation node) {
      if (matches(node)) {
        annotations.add(node);
      }
      return false;
    }

    @Override
    public boolean visit(SingleMemberAnnotation node) {
      if (matches(node)) {
        annotations.add(node);
      }
      return false;
    }

    @Override
    public boolean visit(TypeDeclaration typeDecl) {
      isTypeDecl = true;
      return super.visit(typeDecl);
    }

    private boolean matches(Annotation annotation) {
      Name typeName = annotation.getTypeName();
      if (typeName != null) {
        if (invocationOffset >= 0) {
          int startPos = annotation.getStartPosition();
          if (startPos > invocationOffset || startPos + annotation.getLength() < invocationOffset) {
            return false;
          }
        }
        return annotationToMatch == null || typeName.toString().equals(annotationToMatch);
      }
      return false;
    }
  }

}
TOP

Related Classes of org.springframework.ide.eclipse.quickfix.jdt.util.ProposalCalculatorUtil$AnnotationFinder

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.