Author: akazakov
Date: 2010-06-02 14:52:36 -0400 (Wed, 02 Jun 2010)
New Revision: 22494
Modified:
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/CDIConstants.java
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/CDIUtil.java
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/IBeanManager.java
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/preferences/CDIPreferenceInitializer.java
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/impl/CDIProject.java
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/validation/CDICoreValidator.java
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/validation/messages.properties
trunk/cdi/plugins/org.jboss.tools.cdi.ui/src/org/jboss/tools/cdi/ui/preferences/CDIConfigurationBlock.java
trunk/cdi/tests/org.jboss.tools.cdi.core.test/src/org/jboss/tools/cdi/core/test/tck/ResolutionByTypeTest.java
Log:
https://jira.jboss.org/jira/browse/JBIDE-2708 Added new CDI validation rule: Array-valued
or annotation-valued member of a qualifier type is not annotated @Nonbinding
Modified:
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/CDIConstants.java
===================================================================
---
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/CDIConstants.java 2010-06-02
18:08:10 UTC (rev 22493)
+++
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/CDIConstants.java 2010-06-02
18:52:36 UTC (rev 22494)
@@ -41,6 +41,8 @@
public String SPECIALIZES_ANNOTATION_TYPE_NAME =
"javax.enterprise.inject.Specializes";
+ public String NON_BINDING_ANNOTATION_TYPE_NAME
="javax.enterprise.util.Nonbinding";
+
public String STATEFUL_ANNOTATION_TYPE_NAME = "javax.ejb.Stateful";
public String STATELESS_ANNOTATION_TYPE_NAME = "javax.ejb.Stateless";
public String SINGLETON_ANNOTATION_TYPE_NAME = "javax.ejb.Singleton";
Modified:
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/CDIUtil.java
===================================================================
---
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/CDIUtil.java 2010-06-02
18:08:10 UTC (rev 22493)
+++
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/CDIUtil.java 2010-06-02
18:52:36 UTC (rev 22494)
@@ -20,11 +20,13 @@
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IAnnotatable;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.ILocalVariable;
import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.JavaModelException;
@@ -615,4 +617,70 @@
}
return null;
}
+
+ /**
+ * Returns true if the member annotated @NonBinding.
+ *
+ * @param sourceType the type where the member is declared
+ * @param member
+ * @return
+ */
+ public static boolean hasNonBindingAnnotationDeclaration(IType sourceType, IAnnotatable
member) {
+ return hasAnnotationDeclaration(sourceType, member,
CDIConstants.NON_BINDING_ANNOTATION_TYPE_NAME);
+ }
+
+ /**
+ * Returns true if the member has the given annotation.
+ *
+ * @param sourceType the type where the member is declared
+ * @param member
+ * @param annotationTypeName
+ * @return
+ */
+ public static boolean hasAnnotationDeclaration(IType sourceType, IAnnotatable member,
String annotationTypeName) {
+ try {
+ IAnnotation[] annotations = member.getAnnotations();
+ String simpleAnnotationTypeName = annotationTypeName;
+ int lastDot = annotationTypeName.lastIndexOf('.');
+ if(lastDot>-1) {
+ simpleAnnotationTypeName = simpleAnnotationTypeName.substring(lastDot + 1);
+ }
+ for (IAnnotation annotation : annotations) {
+ if(annotationTypeName.equals(annotation.getElementName())) {
+ return true;
+ }
+ if(simpleAnnotationTypeName.equals(annotation.getElementName())) {
+ String fullAnnotationclassName = EclipseJavaUtil.resolveType(sourceType,
simpleAnnotationTypeName);
+ if(fullAnnotationclassName!=null) {
+ IType annotationType =
sourceType.getJavaProject().findType(fullAnnotationclassName);
+ if(annotationType!=null &&
annotationType.getFullyQualifiedName().equals(annotationTypeName)) {
+ return true;
+ }
+ }
+ }
+ }
+ } catch (JavaModelException e) {
+ CDICorePlugin.getDefault().logError(e);
+ }
+ return false;
+ }
+
+ /**
+ * Converts ISourceRange to ITextSourceReference
+ *
+ * @param range
+ * @return
+ */
+ public static ITextSourceReference convertToSourceReference(final ISourceRange range) {
+ return new ITextSourceReference() {
+
+ public int getStartPosition() {
+ return range.getOffset();
+ }
+
+ public int getLength() {
+ return range.getLength();
+ }
+ };
+ }
}
\ No newline at end of file
Modified:
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/IBeanManager.java
===================================================================
---
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/IBeanManager.java 2010-06-02
18:08:10 UTC (rev 22493)
+++
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/IBeanManager.java 2010-06-02
18:52:36 UTC (rev 22494)
@@ -152,11 +152,11 @@
Set<IBean> getBeans(IPath path);
/**
- * Returns all the available qualifier types.
+ * Returns all the available qualifiers.
*
- * @return all the available qualifier types.
+ * @return all the available qualifiers.
*/
- Set<IType> getQualifierTypes();
+ IQualifier[] getQualifiers();
/**
* Returns all the available stereotypes.
@@ -203,6 +203,14 @@
IQualifier getQualifier(String qualifiedName);
/**
+ * Returns the qualifier by resource path.
+ *
+ * @param resource path
+ * @return the qualifier by resource path
+ */
+ IQualifier getQualifier(IPath path);
+
+ /**
* Returns scope model element for fully qualified name of scope annotation
* type
*
Modified:
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/preferences/CDIPreferenceInitializer.java
===================================================================
---
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/preferences/CDIPreferenceInitializer.java 2010-06-02
18:08:10 UTC (rev 22493)
+++
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/core/preferences/CDIPreferenceInitializer.java 2010-06-02
18:52:36 UTC (rev 22494)
@@ -38,5 +38,6 @@
defaultPreferences.put(CDIPreferences.INTERCEPTOR_OR_DECORATOR_IS_ALTERNATIVE,
CDIPreferences.WARNING);
defaultPreferences.put(CDIPreferences.INTERCEPTOR_ANNOTATED_SPECIALIZES,
CDIPreferences.WARNING);
defaultPreferences.put(CDIPreferences.DECORATOR_ANNOTATED_SPECIALIZES,
CDIPreferences.WARNING);
+ defaultPreferences.put(CDIPreferences.MISSING_NONBINDING_IN_QUALIFIER_TYPE_MEMBER,
CDIPreferences.WARNING);
}
}
\ No newline at end of file
Modified:
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/impl/CDIProject.java
===================================================================
---
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/impl/CDIProject.java 2010-06-02
18:08:10 UTC (rev 22493)
+++
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/impl/CDIProject.java 2010-06-02
18:52:36 UTC (rev 22494)
@@ -66,6 +66,7 @@
private Map<IPath, StereotypeElement> stereotypesByPath = new HashMap<IPath,
StereotypeElement>();
private Map<String, InterceptorBindingElement> interceptorBindings = new
HashMap<String, InterceptorBindingElement>();
private Map<String, QualifierElement> qualifiers = new HashMap<String,
QualifierElement>();
+ private Map<IPath, QualifierElement> qualifiersByPath = new HashMap<IPath,
QualifierElement>();
private Map<String, ScopeElement> scopes = new HashMap<String,
ScopeElement>();
private Set<IBean> allBeans = new HashSet<IBean>();
@@ -486,6 +487,21 @@
/*
* (non-Javadoc)
+ * @see org.jboss.tools.cdi.core.IBeanManager#getQualifiers()
+ */
+ public IQualifier[] getQualifiers() {
+ IQualifier[] result = new IQualifier[qualifiers.size()];
+ synchronized (qualifiers) {
+ int i=0;
+ for (IQualifier q: qualifiers.values()) {
+ result[i++] = q;
+ }
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
* @see org.jboss.tools.cdi.core.IBeanManager#getStereotypes()
*/
public IStereotype[] getStereotypes() {
@@ -670,6 +686,10 @@
return qualifiers.get(qualifiedName);
}
+ public QualifierElement getQualifier(IPath path) {
+ return qualifiersByPath.get(path);
+ }
+
public ScopeElement getScope(String qualifiedName) {
return scopes.get(qualifiedName);
}
@@ -685,6 +705,7 @@
stereotypesByPath.clear();
interceptorBindings.clear();
qualifiers.clear();
+ qualifiersByPath.clear();
scopes.clear();
List<AnnotationDefinition> ds = n.getDefinitions().getAllAnnotations();
for (AnnotationDefinition d: ds) {
@@ -703,6 +724,9 @@
QualifierElement s = new QualifierElement();
initAnnotationElement(s, d);
qualifiers.put(d.getQualifiedName(), s);
+ if(d.getResource() != null && d.getResource().getFullPath() != null) {
+ qualifiersByPath.put(d.getResource().getFullPath(), s);
+ }
} else if(d.getKind() == AnnotationDefinition.SCOPE) {
ScopeElement s = new ScopeElement();
initAnnotationElement(s, d);
Modified:
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/validation/CDICoreValidator.java
===================================================================
---
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/validation/CDICoreValidator.java 2010-06-02
18:08:10 UTC (rev 22493)
+++
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/validation/CDICoreValidator.java 2010-06-02
18:52:36 UTC (rev 22494)
@@ -56,6 +56,7 @@
import org.jboss.tools.cdi.core.IProducer;
import org.jboss.tools.cdi.core.IProducerField;
import org.jboss.tools.cdi.core.IProducerMethod;
+import org.jboss.tools.cdi.core.IQualifier;
import org.jboss.tools.cdi.core.IQualifierDeclaration;
import org.jboss.tools.cdi.core.IScope;
import org.jboss.tools.cdi.core.IScopeDeclaration;
@@ -66,6 +67,7 @@
import org.jboss.tools.cdi.core.preferences.CDIPreferences;
import org.jboss.tools.cdi.internal.core.impl.Parameter;
import org.jboss.tools.cdi.internal.core.impl.SessionBean;
+import org.jboss.tools.common.model.util.EclipseJavaUtil;
import org.jboss.tools.common.text.ITextSourceReference;
import org.jboss.tools.jst.web.kb.IKbProject;
import org.jboss.tools.jst.web.kb.KbProjectFactory;
@@ -127,12 +129,6 @@
List<IProject> projects = new ArrayList<IProject>();
projects.add(project);
- // IProject[] array = set.getAllProjects();
- // for (int i = 0; i < array.length; i++) {
- // if(array[i].isAccessible()) {
- // projects.add(array[i]);
- // }
- // }
return new ValidatingProjectSet(project, projects, rootContext);
}
@@ -254,11 +250,15 @@
validateBean(bean);
}
- IStereotype[] stereoTypes = cdiProject.getStereotypes();
- for (IStereotype type : stereoTypes) {
- validateStereotype(type);
+ IStereotype[] stereotypes = cdiProject.getStereotypes();
+ for (IStereotype stereotype : stereotypes) {
+ validateStereotype(stereotype);
}
+ IQualifier[] qualifiers = cdiProject.getQualifiers();
+ for (IQualifier qualifier : qualifiers) {
+ validateQualifier(qualifier);
+ }
return OK_STATUS;
}
@@ -278,6 +278,9 @@
}
IStereotype stereotype = cdiProject.getStereotype(file.getFullPath());
validateStereotype(stereotype);
+
+ IQualifier qualifier = cdiProject.getQualifier(file.getFullPath());
+ validateQualifier(qualifier);
}
/**
@@ -309,6 +312,13 @@
validationContext.addLinkedCoreResource(beanPath,
stereotype.getResource().getFullPath(), false);
}
}
+ Set<IQualifierDeclaration> qualifierDeclarations =
bean.getQualifierDeclarations();
+ for (IQualifierDeclaration qualifierDeclaration : qualifierDeclarations) {
+ IQualifier qualifier = qualifierDeclaration.getQualifier();
+ if (!qualifier.getSourceType().isReadOnly()) {
+ validationContext.addLinkedCoreResource(beanPath,
qualifier.getResource().getFullPath(), false);
+ }
+ }
// validate
validateTyped(bean);
@@ -1357,4 +1367,57 @@
}
}
}
+
+ /**
+ * Validates a qualifier.
+ *
+ * @param qualifier
+ */
+ private void validateQualifier(IQualifier qualifier) {
+ if(qualifier==null) {
+ return;
+ }
+ IResource resource = qualifier.getResource();
+ if (resource == null || !resource.getName().toLowerCase().endsWith(".java"))
{
+ // validate sources only
+ return;
+ }
+ /*
+ * 5.2.5. Qualifier annotations with members
+ * - array-valued or annotation-valued member of a qualifier type is not annotated
@Nonbinding (Non-Portable behavior)
+ */
+ IType type = qualifier.getSourceType();
+ try {
+ IMethod[] methods = type.getMethods();
+ for (IMethod method : methods) {
+ String returnTypeSignature = method.getReturnType();
+ int kind = Signature.getTypeSignatureKind(returnTypeSignature);
+ if(kind == Signature.ARRAY_TYPE_SIGNATURE) {
+ if(!CDIUtil.hasNonBindingAnnotationDeclaration(type, method)) {
+ ITextSourceReference reference =
CDIUtil.convertToSourceReference(method.getNameRange());
+ addError(CDIValidationMessages.MISSING_NONBINDING_FOR_ARRAY_VALUE_IN_QUALIFIER_TYPE_MEMBER,
CDIPreferences.MISSING_NONBINDING_IN_QUALIFIER_TYPE_MEMBER, reference,
qualifier.getResource());
+ }
+ } else if(kind == Signature.CLASS_TYPE_SIGNATURE) {
+ String typeName = Signature.getSignatureSimpleName(returnTypeSignature);
+ String packageName = Signature.getSignatureQualifier(returnTypeSignature);
+ if(packageName.length()>0) {
+ typeName = packageName + "." + typeName;
+ } else {
+ typeName = EclipseJavaUtil.resolveType(type, typeName);
+ }
+ if(typeName!=null) {
+ IType memberType = type.getJavaProject().findType(typeName);
+ if(memberType!=null && memberType.isAnnotation()) {
+ if(!CDIUtil.hasNonBindingAnnotationDeclaration(type, method)) {
+ ITextSourceReference reference =
CDIUtil.convertToSourceReference(method.getNameRange());
+ addError(CDIValidationMessages.MISSING_NONBINDING_FOR_ANNOTATION_VALUE_IN_QUALIFIER_TYPE_MEMBER,
CDIPreferences.MISSING_NONBINDING_IN_QUALIFIER_TYPE_MEMBER, reference,
qualifier.getResource());
+ }
+ }
+ }
+ }
+ }
+ } catch (JavaModelException e) {
+ CDICorePlugin.getDefault().logError(e);
+ }
+ }
}
\ No newline at end of file
Modified:
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/validation/messages.properties
===================================================================
---
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/validation/messages.properties 2010-06-02
18:08:10 UTC (rev 22493)
+++
trunk/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/validation/messages.properties 2010-06-02
18:52:36 UTC (rev 22494)
@@ -88,6 +88,6 @@
ILLEGAL_QUALIFIER_IN_STEREOTYPE=Stereotype declares any qualifier annotation other than
@Named
#Messages for Progress Monitor
-SEARCHING_RESOURCES=project "{0}"; searching resources for validation.
-VALIDATING_RESOURCE=project "{0}"; resource "{1}"
-VALIDATING_PROJECT=project "{0}"
\ No newline at end of file
+SEARCHING_RESOURCES=project "{0}"; searching resources for validation (CDI
Validator).
+VALIDATING_RESOURCE=project "{0}"; resource "{1}" (CDI Validator)
+VALIDATING_PROJECT=project "{0}" (CDI Validator)
\ No newline at end of file
Modified:
trunk/cdi/plugins/org.jboss.tools.cdi.ui/src/org/jboss/tools/cdi/ui/preferences/CDIConfigurationBlock.java
===================================================================
---
trunk/cdi/plugins/org.jboss.tools.cdi.ui/src/org/jboss/tools/cdi/ui/preferences/CDIConfigurationBlock.java 2010-06-02
18:08:10 UTC (rev 22493)
+++
trunk/cdi/plugins/org.jboss.tools.cdi.ui/src/org/jboss/tools/cdi/ui/preferences/CDIConfigurationBlock.java 2010-06-02
18:52:36 UTC (rev 22494)
@@ -50,7 +50,7 @@
// {CDIPreferences.PRODUCER_FIELD_TYPE_DOES_NOT_MATCH_JAVA_EE_OBJECT,
CDIPreferencesMessages.CDIValidatorConfigurationBlock_pb_producerFieldTypeDoesNotMatchJavaEeObject_label},
{CDIPreferences.INJECTION_TYPE_IS_VARIABLE,
CDIPreferencesMessages.CDIValidatorConfigurationBlock_pb_injectionTypeIsVariable_label},
{CDIPreferences.STEREOTYPE_IS_ANNOTATED_TYPED,
CDIPreferencesMessages.CDIValidatorConfigurationBlock_pb_stereotypeIsAnnotatedTyped_label},
-// {CDIPreferences.MISSING_NONBINDING_IN_QUALIFIER_TYPE_MEMBER,
CDIPreferencesMessages.CDIValidatorConfigurationBlock_pb_missingNonbindingInQualifierTypeMember_label},
+ {CDIPreferences.MISSING_NONBINDING_IN_QUALIFIER_TYPE_MEMBER,
CDIPreferencesMessages.CDIValidatorConfigurationBlock_pb_missingNonbindingInQualifierTypeMember_label},
// {CDIPreferences.MISSING_NONBINDING_IN_INTERCEPTOR_BINDING_TYPE_MEMBER,
CDIPreferencesMessages.CDIValidatorConfigurationBlock_pb_missingNonbindingInInterceptorBindingTypeMember_label},
},
CDICorePlugin.PLUGIN_ID
Modified:
trunk/cdi/tests/org.jboss.tools.cdi.core.test/src/org/jboss/tools/cdi/core/test/tck/ResolutionByTypeTest.java
===================================================================
---
trunk/cdi/tests/org.jboss.tools.cdi.core.test/src/org/jboss/tools/cdi/core/test/tck/ResolutionByTypeTest.java 2010-06-02
18:08:10 UTC (rev 22493)
+++
trunk/cdi/tests/org.jboss.tools.cdi.core.test/src/org/jboss/tools/cdi/core/test/tck/ResolutionByTypeTest.java 2010-06-02
18:52:36 UTC (rev 22494)
@@ -35,4 +35,6 @@
Set<IBean> beans = cdiProject.getBeans(true, type, new
IQualifierDeclaration[]{expensiveQualifier, whitefishQualifier});
assertContainsBeanClasses(beans, new
String[]{"org.jboss.jsr299.tck.tests.lookup.typesafe.resolution.RoundWhitefish",
"org.jboss.jsr299.tck.tests.lookup.typesafe.resolution.Halibut"});
}
+
+ // TODO continue implementing the tests
}
\ No newline at end of file