Author: xcoulon
Date: 2012-10-12 07:46:13 -0400 (Fri, 12 Oct 2012)
New Revision: 44472
Added:
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.core/src/org/jboss/tools/ws/jaxrs/core/jdt/RangeUtils.java
Modified:
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.core/src/org/jboss/tools/ws/jaxrs/core/jdt/JavaAnnotationLocator.java
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.core/src/org/jboss/tools/ws/jaxrs/core/jdt/JdtUtils.java
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.ui/src/org/jboss/tools/ws/jaxrs/ui/contentassist/PathParamAnnotationValueCompletionProposalComputer.java
trunk/ws/tests/org.jboss.tools.ws.jaxrs.core.test/src/org/jboss/tools/ws/jaxrs/core/jdt/JdtUtilsTestCase.java
Log:
Fixed - JBIDE-12806 - Annotations location in the JAX-RS Metamodel are not updated after
code changes
https://issues.jboss.org/browse/JBIDE-12806
Modified:
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.core/src/org/jboss/tools/ws/jaxrs/core/jdt/JavaAnnotationLocator.java
===================================================================
---
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.core/src/org/jboss/tools/ws/jaxrs/core/jdt/JavaAnnotationLocator.java 2012-10-12
10:03:46 UTC (rev 44471)
+++
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.core/src/org/jboss/tools/ws/jaxrs/core/jdt/JavaAnnotationLocator.java 2012-10-12
11:46:13 UTC (rev 44472)
@@ -12,13 +12,20 @@
import java.util.List;
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.ILocalVariable;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IAnnotationBinding;
+import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.jboss.tools.ws.jaxrs.core.internal.utils.Logger;
/**
* @author Xavier Coulon
@@ -27,9 +34,12 @@
public class JavaAnnotationLocator extends ASTVisitor {
private final int location;
+ private final IMethod parentMethod;
+
private Annotation locatedAnnotation;
- public JavaAnnotationLocator(final int location) {
+ public JavaAnnotationLocator(final IJavaElement parentElement, final int location) {
+ this.parentMethod = (parentElement.getElementType() == IJavaElement.METHOD) ? (IMethod)
parentElement : null;
this.location = location;
}
@@ -61,16 +71,6 @@
}
/**
- * @see
org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodDeclaration)
- */
- @Override
- public boolean visit(MethodDeclaration node) {
- visitExtendedModifiers((List<?>)
node.getStructuralProperty(MethodDeclaration.MODIFIERS2_PROPERTY));
- // visit children to look for SingleVariableDeclaration
- return true;
- }
-
- /**
* @see
org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeDeclaration)
*/
@Override
@@ -81,16 +81,74 @@
}
/**
+ * @see
org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodDeclaration)
+ */
+ @Override
+ public boolean visit(MethodDeclaration declaration) {
+ visitExtendedModifiers((List<?>)
declaration.getStructuralProperty(MethodDeclaration.MODIFIERS2_PROPERTY));
+ return this.locatedAnnotation == null;
+ }
+
+ /*
+ * (non-Javadoc)
* @see
org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SingleVariableDeclaration)
*/
@Override
- public boolean visit(SingleVariableDeclaration node) {
- visitExtendedModifiers((List<?>)
node.getStructuralProperty(SingleVariableDeclaration.MODIFIERS2_PROPERTY));
- // no need to visit furthermore
+ public boolean visit(SingleVariableDeclaration variableDeclaration) {
+ // skip if parentMethod is undefined or if annotation is already located
+ if (this.parentMethod == null || this.locatedAnnotation != null) {
+ return false;
+ }
+ try {
+ if (DOMUtils.nodeMatches(variableDeclaration, location)) {
+ final IVariableBinding variableDeclarationBinding =
variableDeclaration.resolveBinding();
+ final IAnnotationBinding[] annotationBindings =
variableDeclarationBinding.getAnnotations();
+ // retrieve the parameter index in the parent method
+ final ILocalVariable localVariable = getLocalVariable(variableDeclarationBinding);
+ if (localVariable != null) {
+ final IAnnotation[] variableAnnotations = localVariable.getAnnotations();
+ for (int j = 0; j < annotationBindings.length; j++) {
+ final IAnnotation javaAnnotation = variableAnnotations[j];
+ if (RangeUtils.matches(javaAnnotation.getSourceRange(), location)) {
+ final IAnnotationBinding javaAnnotationBinding = annotationBindings[j];
+ this.locatedAnnotation = BindingUtils.toAnnotation(javaAnnotationBinding,
javaAnnotation);
+ break;
+ }
+ }
+ }
+ // TODO : add support for thrown exceptions
+ }
+ } catch (JavaModelException e) {
+ Logger.error("Failed to analyse compilation unit method '" +
this.parentMethod.getElementName() + "'", e);
+ }
+
+ // no need to carry on from here
return false;
+
}
-
+
/**
+ * Returns the localVariable associated with the given variable declaration binding, or
null if it could not be found
+ * @param variableDeclarationBinding
+ * @return
+ * @throws JavaModelException
+ */
+ private ILocalVariable getLocalVariable(final IVariableBinding
variableDeclarationBinding)
+ throws JavaModelException {
+ int i = -1;
+ for (String paramName : parentMethod.getParameterNames()) {
+ i++;
+ if (paramName.equals(variableDeclarationBinding.getName())) {
+ break;
+ }
+ }
+ if(i>=0) {
+ return this.parentMethod.getParameters()[i];
+ }
+ return null;
+ }
+
+ /**
* Visits the modifiers.
*
* @param modifiers
@@ -103,7 +161,8 @@
if (DOMUtils.nodeMatches(annotation, location)) {
final IAnnotationBinding annotationBinding = annotation.resolveAnnotationBinding();
if (annotationBinding != null) {
- this.locatedAnnotation = BindingUtils.toAnnotation(annotationBinding);
+ final IAnnotation javaAnnotation = (IAnnotation)
annotationBinding.getJavaElement();
+ this.locatedAnnotation = BindingUtils.toAnnotation(annotationBinding,
javaAnnotation);
}
}
}
Modified:
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.core/src/org/jboss/tools/ws/jaxrs/core/jdt/JdtUtils.java
===================================================================
---
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.core/src/org/jboss/tools/ws/jaxrs/core/jdt/JdtUtils.java 2012-10-12
10:03:46 UTC (rev 44471)
+++
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.core/src/org/jboss/tools/ws/jaxrs/core/jdt/JdtUtils.java 2012-10-12
11:46:13 UTC (rev 44472)
@@ -376,7 +376,7 @@
final IJavaElement element = compilationUnit.getElementAt(location);
final ASTNode astChildNode = DOMUtils.getASTNodeByTypeAndLocation(ast,
element.getElementType(), location);
if (astChildNode != null) {
- final JavaAnnotationLocator annotationLocator = new JavaAnnotationLocator(location);
+ final JavaAnnotationLocator annotationLocator = new JavaAnnotationLocator(element,
location);
astChildNode.accept(annotationLocator);
return annotationLocator.getLocatedAnnotation();
}
Added:
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.core/src/org/jboss/tools/ws/jaxrs/core/jdt/RangeUtils.java
===================================================================
---
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.core/src/org/jboss/tools/ws/jaxrs/core/jdt/RangeUtils.java
(rev 0)
+++
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.core/src/org/jboss/tools/ws/jaxrs/core/jdt/RangeUtils.java 2012-10-12
11:46:13 UTC (rev 44472)
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc.
+ * Distributed under license by Red Hat, Inc. All rights reserved.
+ * This program is 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:
+ * Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.ws.jaxrs.core.jdt;
+
+import org.eclipse.jdt.core.ISourceRange;
+
+/**
+ * @author Xavier Coulon
+ *
+ */
+public class RangeUtils {
+
+ /**
+ * Private constructor for this utility class
+ */
+ public RangeUtils() {
+ }
+
+ /**
+ * Returns true if the source range matches the given position, false otherwise
+ * @param sourceRange
+ * @param position
+ * @return
+ */
+ public static boolean matches(final ISourceRange range, final int position) {
+ return range.getOffset() <= position && position <= (range.getOffset() +
range.getLength());
+ }
+
+}
Property changes on:
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.core/src/org/jboss/tools/ws/jaxrs/core/jdt/RangeUtils.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified:
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.ui/src/org/jboss/tools/ws/jaxrs/ui/contentassist/PathParamAnnotationValueCompletionProposalComputer.java
===================================================================
---
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.ui/src/org/jboss/tools/ws/jaxrs/ui/contentassist/PathParamAnnotationValueCompletionProposalComputer.java 2012-10-12
10:03:46 UTC (rev 44471)
+++
trunk/ws/plugins/org.jboss.tools.ws.jaxrs.ui/src/org/jboss/tools/ws/jaxrs/ui/contentassist/PathParamAnnotationValueCompletionProposalComputer.java 2012-10-12
11:46:13 UTC (rev 44472)
@@ -20,6 +20,7 @@
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.ui.text.IJavaPartitions;
@@ -75,40 +76,43 @@
if (metamodel == null) {
return Collections.emptyList();
}
-// final IJavaElement invocationElement =
javaContext.getCompilationUnit().getElementAt(
-// context.getInvocationOffset());
-//
-// // ICompilationUnit.getElementAt(int) method may return null
-// if (invocationElement != null && invocationElement.getElementType() ==
IJavaElement.METHOD) {
-// IJaxrsResourceMethod resourceMethod = metamodel.getElement(invocationElement,
-// IJaxrsResourceMethod.class);
-// // the java method must be associated with a JAX-RS Resource Method.
-// if (resourceMethod != null) {
-// for (JavaMethodParameter methodParameter :
resourceMethod.getJavaMethodParameters()) {
-// for (Annotation annotation : methodParameter.getAnnotations().values()) {
-// final ISourceRange range = annotation.getSourceRange();
-// if (annotation.getFullyQualifiedName().equals(PATH_PARAM.qualifiedName)
&& range != null
-// && context.getInvocationOffset() >= range.getOffset()
-// && context.getInvocationOffset() < (range.getOffset() +
range.getLength())) {
-// // completion proposal on @PathParam method
-// // annotation
-// return internalComputePathParamProposals(javaContext, resourceMethod);
-// }
-//
-// }
-// }
-// }
-// }
-
+ // final IJavaElement invocationElement =
javaContext.getCompilationUnit().getElementAt(
+ // context.getInvocationOffset());
+ //
+ // // ICompilationUnit.getElementAt(int) method may return null
+ // if (invocationElement != null && invocationElement.getElementType() ==
IJavaElement.METHOD) {
+ // IJaxrsResourceMethod resourceMethod = metamodel.getElement(invocationElement,
+ // IJaxrsResourceMethod.class);
+ // // the java method must be associated with a JAX-RS Resource Method.
+ // if (resourceMethod != null) {
+ // for (JavaMethodParameter methodParameter :
resourceMethod.getJavaMethodParameters()) {
+ // for (Annotation annotation : methodParameter.getAnnotations().values()) {
+ // final ISourceRange range = annotation.getSourceRange();
+ // if (annotation.getFullyQualifiedName().equals(PATH_PARAM.qualifiedName) &&
range != null
+ // && context.getInvocationOffset() >= range.getOffset()
+ // && context.getInvocationOffset() < (range.getOffset() +
range.getLength())) {
+ // // completion proposal on @PathParam method
+ // // annotation
+ // return internalComputePathParamProposals(javaContext, resourceMethod);
+ // }
+ //
+ // }
+ // }
+ // }
+ // }
+
final int invocationOffset = context.getInvocationOffset();
final ICompilationUnit compilationUnit = javaContext.getCompilationUnit();
final Annotation annotation = JdtUtils.resolveAnnotationAt(invocationOffset,
compilationUnit);
- if(annotation != null &&
annotation.getFullyQualifiedName().equals(PATH_PARAM.qualifiedName)) {
- final IJaxrsResourceMethod resourceMethod =
metamodel.getElement(annotation.getJavaParent(),
- IJaxrsResourceMethod.class);
- return internalComputePathParamProposals(javaContext, resourceMethod);
+ if (annotation != null &&
annotation.getFullyQualifiedName().equals(PATH_PARAM.qualifiedName)) {
+ final IJavaElement javaMethod =
annotation.getJavaAnnotation().getAncestor(IJavaElement.METHOD);
+ if (javaMethod != null) {
+ final IJaxrsResourceMethod resourceMethod = metamodel.getElement(javaMethod,
+ IJaxrsResourceMethod.class);
+ return internalComputePathParamProposals(javaContext, resourceMethod);
+ }
}
-
+
} catch (Exception e) {
Logger.error("Failed to compute completion proposal", e);
}
Modified:
trunk/ws/tests/org.jboss.tools.ws.jaxrs.core.test/src/org/jboss/tools/ws/jaxrs/core/jdt/JdtUtilsTestCase.java
===================================================================
---
trunk/ws/tests/org.jboss.tools.ws.jaxrs.core.test/src/org/jboss/tools/ws/jaxrs/core/jdt/JdtUtilsTestCase.java 2012-10-12
10:03:46 UTC (rev 44471)
+++
trunk/ws/tests/org.jboss.tools.ws.jaxrs.core.test/src/org/jboss/tools/ws/jaxrs/core/jdt/JdtUtilsTestCase.java 2012-10-12
11:46:13 UTC (rev 44472)
@@ -757,7 +757,7 @@
final Annotation foundAnnotation = JdtUtils.resolveAnnotationAt(offset,
method.getCompilationUnit());
// verification
assertThat(foundAnnotation, notNullValue());
- assertThat(foundAnnotation.getJavaAnnotation(), nullValue());
+ assertThat(foundAnnotation.getJavaAnnotation(), notNullValue());
}
@Test
@@ -772,8 +772,7 @@
final Annotation foundAnnotation = JdtUtils.resolveAnnotationAt(offset,
customerType.getCompilationUnit());
// verification
assertThat(foundAnnotation, notNullValue());
- // iannotation retrieved from this method is null and does not need to be evaluated
anyway.
- assertThat(foundAnnotation.getJavaAnnotation(), nullValue());
+ assertThat(foundAnnotation.getJavaAnnotation(), notNullValue());
}
@Test