diff --git a/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/impl/definition/AbstractMemberDefinition.java b/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/impl/definition/AbstractMemberDefinition.java index 602a50aa21..9d7ab40150 100644 --- a/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/impl/definition/AbstractMemberDefinition.java +++ b/cdi/plugins/org.jboss.tools.cdi.core/src/org/jboss/tools/cdi/internal/core/impl/definition/AbstractMemberDefinition.java @@ -1,13 +1,13 @@ -/******************************************************************************* - * Copyright (c) 2009 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 - ******************************************************************************/ +/******************************************************************************* + * Copyright (c) 2009 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.cdi.internal.core.impl.definition; import java.util.ArrayList; @@ -41,7 +41,7 @@ import org.jboss.tools.common.text.ITextSourceReference; /** - * + * * @author Viacheslav Kabanovich * */ @@ -49,11 +49,16 @@ public abstract class AbstractMemberDefinition implements IAnnotated { public static int FLAG_NO_ANNOTATIONS = 1; public static int FLAG_ALL_MEMBERS = 2; + private static final String SPRING_CONTROLLER = "org.springframework.stereotype.Controller"; + private static final String SPRING_REPOSITORY = "org.springframework.stereotype.Repository"; + private static final String SPRING_SERVICE = "org.springframework.stereotype.Service"; + private static final String SPRING_COMPONENT = "org.springframework.stereotype.Component"; + CDICoreNature project; - protected List annotations = new ArrayList(2); + protected List annotations = new ArrayList<>(2); protected IAnnotatable member; private IAnnotationMap annotationsByType = EmptyMap.instance; - + protected ITextSourceReference originalDefinition = null; public AbstractMemberDefinition() {} @@ -149,7 +154,7 @@ private void addAnnotation(AnnotationDeclaration a, IRootDefinitionContext conte } else { a = b; } - + if(a.getTypeName() != null) { annotationsByType = annotationsByType.put(a.getTypeName(), a); } @@ -165,7 +170,7 @@ public void annotationKindChanged(String typeName, IRootDefinitionContext contex } //Make sure that a is non-specific annotation. addAnnotation(new AnnotationDeclaration(a), context); - + } public void removeAnnotation(IAnnotationDeclaration a) { @@ -181,6 +186,7 @@ public void removeAnnotation(IAnnotationDeclaration a) { * (non-Javadoc) * @see org.jboss.tools.cdi.core.IAnnotated#getAnnotations() */ + @Override public List getAnnotations() { return annotations; } @@ -189,6 +195,7 @@ public List getAnnotations() { * (non-Javadoc) * @see org.jboss.tools.cdi.core.IAnnotated#getAnnotation(java.lang.String) */ + @Override public AnnotationDeclaration getAnnotation(String typeName) { return annotationsByType.get(typeName); } @@ -197,6 +204,7 @@ public AnnotationDeclaration getAnnotation(String typeName) { * (non-Javadoc) * @see org.jboss.tools.common.java.IAnnotated#getAnnotationPosition(java.lang.String) */ + @Override public IJavaSourceReference getAnnotationPosition(String annotationTypeName) { return getAnnotation(annotationTypeName); } @@ -205,12 +213,24 @@ public IJavaSourceReference getAnnotationPosition(String annotationTypeName) { * (non-Javadoc) * @see org.jboss.tools.cdi.core.IAnnotated#isAnnotationPresent(java.lang.String) */ + @Override public boolean isAnnotationPresent(String annotationTypeName) { return getAnnotation(annotationTypeName)!=null; } public AnnotationDeclaration getNamedAnnotation() { - return getAnnotation(CDIConstants.NAMED_QUALIFIER_TYPE_NAME); + AnnotationDeclaration ad = getAnnotation(CDIConstants.NAMED_QUALIFIER_TYPE_NAME); + // also support all Spring dependencies (note: these are not real CDI "beans" but often + // can be used in the same way, so offering support for this widely used alternative is useful) + if (ad != null) return ad; + ad = getAnnotation(SPRING_CONTROLLER); + if (ad != null) return ad; + ad = getAnnotation(SPRING_SERVICE); + if (ad != null) return ad; + ad = getAnnotation(SPRING_REPOSITORY); + if (ad != null) return ad; + ad = getAnnotation(SPRING_COMPONENT); + return ad; } public AnnotationDeclaration getTypedAnnotation() { @@ -246,17 +266,20 @@ interface IAnnotationMap { class EmptyMap implements IAnnotationMap { static EmptyMap instance = new EmptyMap(); - + private EmptyMap() {} + @Override public IAnnotationMap put(String type, AnnotationDeclaration d) { return new OneEntryMap(d); } + @Override public AnnotationDeclaration get(String type) { return null; } + @Override public IAnnotationMap remove(String type) { return this; } @@ -264,38 +287,41 @@ public IAnnotationMap remove(String type) { class OneEntryMap implements IAnnotationMap { AnnotationDeclaration d; - + public OneEntryMap(AnnotationDeclaration d) { this.d = d; } @Override - public IAnnotationMap put(String type, AnnotationDeclaration d) { + public IAnnotationMap put(String type, AnnotationDeclaration ad) { if(this.d.getTypeName().equals(type)) { - this.d = d; + this.d = ad; return this; } - return new TwoEntryMap(this.d, d); + return new TwoEntryMap(this.d, ad); } + @Override public AnnotationDeclaration get(String type) { return (d.getTypeName().equals(type)) ? d : null; } + @Override public IAnnotationMap remove(String type) { return (get(type) != null) ? EmptyMap.instance : this; - } + } } class TwoEntryMap implements IAnnotationMap { AnnotationDeclaration d1; AnnotationDeclaration d2; - + public TwoEntryMap(AnnotationDeclaration d1,AnnotationDeclaration d2) { this.d1 = d1; this.d2 = d2; } + @Override public IAnnotationMap put(String type, AnnotationDeclaration d) { AnnotationDeclaration dc = get(type); if(dc == d1) { @@ -312,30 +338,36 @@ public IAnnotationMap put(String type, AnnotationDeclaration d) { return map; } + @Override public AnnotationDeclaration get(String type) { return (d1.getTypeName().equals(type)) ? d1 : (d2.getTypeName().equals(type)) ? d2 : null; } + @Override public IAnnotationMap remove(String type) { AnnotationDeclaration d = get(type); return (d == d1) ? new OneEntryMap(d2) : (d == d2) ? new OneEntryMap(d1) : this; - } + } } class AnnotationMap implements IAnnotationMap { - Map annotationsByType = new HashMap(8); - + Map annotationsByType = new HashMap<>(8); + AnnotationMap() {} - + + @Override public IAnnotationMap put(String type, AnnotationDeclaration d) { - annotationsByType.put(type, d); + annotationsByType.put(type, d); + return this; } + @Override public AnnotationDeclaration get(String type) { return annotationsByType.get(type); } + @Override public IAnnotationMap remove(String type) { annotationsByType.remove(type); return this; diff --git a/jsf/plugins/org.jboss.tools.jsf/src/org/jboss/tools/jsf/jsf2/bean/model/impl/AbstractMemberDefinition.java b/jsf/plugins/org.jboss.tools.jsf/src/org/jboss/tools/jsf/jsf2/bean/model/impl/AbstractMemberDefinition.java index 49e7ffaead..29c9600fb1 100644 --- a/jsf/plugins/org.jboss.tools.jsf/src/org/jboss/tools/jsf/jsf2/bean/model/impl/AbstractMemberDefinition.java +++ b/jsf/plugins/org.jboss.tools.jsf/src/org/jboss/tools/jsf/jsf2/bean/model/impl/AbstractMemberDefinition.java @@ -1,13 +1,13 @@ -/******************************************************************************* - * Copyright (c) 2011 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 - ******************************************************************************/ +/******************************************************************************* + * Copyright (c) 2011 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.jsf.jsf2.bean.model.impl; import java.util.ArrayList; @@ -20,9 +20,12 @@ import org.eclipse.jdt.core.IAnnotatable; import org.eclipse.jdt.core.IAnnotation; import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IMember; +import org.eclipse.jdt.core.IMemberValuePair; import org.eclipse.jdt.core.IType; import org.jboss.tools.common.java.IAnnotated; import org.jboss.tools.common.java.IAnnotationDeclaration; +import org.jboss.tools.common.java.IAnnotationType; import org.jboss.tools.common.java.IJavaAnnotation; import org.jboss.tools.common.java.IJavaSourceReference; import org.jboss.tools.common.java.impl.AnnotationDeclaration; @@ -31,7 +34,7 @@ import org.jboss.tools.jsf.jsf2.bean.model.JSF2Constants; /** - * + * * @author Viacheslav Kabanovich * */ @@ -39,11 +42,14 @@ public abstract class AbstractMemberDefinition implements IAnnotated { public static int FLAG_NO_ANNOTATIONS = 1; public static int FLAG_ALL_MEMBERS = 2; + private static final String SPRING_CONTROLLER = "org.springframework.stereotype.Controller"; + private static final String SPRING_COMPONENT = "org.springframework.stereotype.Component"; + protected List annotations = new ArrayList(); protected IAnnotatable member; protected Map annotationsByType = new HashMap(); protected IResource resource; - + public AbstractMemberDefinition() {} protected void setAnnotatable(IAnnotatable member, IType contextType, DefinitionContext context, int flags) { @@ -96,27 +102,162 @@ public void removeAnnotation(IAnnotationDeclaration a) { } } + @Override public List getAnnotations() { return annotations; } + @Override public AnnotationDeclaration getAnnotation(String typeName) { return annotationsByType.get(typeName); } + @Override public IJavaSourceReference getAnnotationPosition(String annotationTypeName) { return getAnnotation(annotationTypeName); } + @Override public boolean isAnnotationPresent(String annotationTypeName) { - return getAnnotation(annotationTypeName)!=null; + boolean b = (getAnnotation(annotationTypeName) != null); + if (!b && JSF2Constants.MANAGED_BEAN_ANNOTATION_TYPE_NAME.equals(annotationTypeName)) { + // also support Spring @Controller and @Component dependency + b = (getAnnotation(SPRING_CONTROLLER) != null + || getAnnotation(SPRING_COMPONENT) != null); + /* OPTIONAL, with support for all Spring annotations (but see at getManagedBeanAnnotation() ): + b = (getAnnotation("org.springframework.stereotype.Controller") != null + || getAnnotation("org.springframework.stereotype.Service") != null + || getAnnotation("org.springframework.stereotype.Repository") != null + || getAnnotation("org.springframework.stereotype.Component") != null); + */ + } + return b; } public AnnotationDeclaration getManagedBeanAnnotation() { - return annotationsByType.get(JSF2Constants.MANAGED_BEAN_ANNOTATION_TYPE_NAME); + AnnotationDeclaration ad = annotationsByType.get(JSF2Constants.MANAGED_BEAN_ANNOTATION_TYPE_NAME); + if (ad != null) return ad; + // also support Spring @Controller and @Component dependency + ad = annotationsByType.get(SPRING_CONTROLLER); + if (ad == null) ad = annotationsByType.get(SPRING_COMPONENT); + /* OPTIONAL, with support for all Spring annotations + * (but other than @Controller or generic @Component does not make sense, + * you will/should NOT access a Service or Repository inside your JSF file.): + if (ad == null) ad = annotationsByType.get("org.springframework.stereotype.Service"); + if (ad == null) ad = annotationsByType.get("org.springframework.stereotype.Repository"); + */ + if (ad != null) { + // create wrapper to map "value" (used by Spring) to "name" (which is used by @ManageBean) + ad = new AnnotationDeclaration() { + private AnnotationDeclaration wrapped; + + AnnotationDeclaration init(AnnotationDeclaration wrappedAD) { + this.wrapped = wrappedAD; + return this; + } + + @Override + public Object getMemberValue(String name) { + Object val = wrapped.getMemberValue(name); + if (val == null && "name".equals(name)) { + val = wrapped.getMemberValue(null); + } + return val; + } + + @Override + public Object getMemberValue(String name, boolean resolve) { + Object result = null; + if (resolve) { + result = this.getMemberConstantValue(name); + } + if (result == null) { + result = this.getMemberValue(name); + } + return result; + } + + @Override + public void setDeclaration(IJavaAnnotation annotation) { + wrapped.setDeclaration(annotation); + } + + @Override + public IJavaAnnotation getDeclaration() { + return wrapped.getDeclaration(); + } + + @Override + public IResource getResource() { + return wrapped.getResource(); + } + + @Override + public IMemberValuePair[] getMemberValuePairs() { + return wrapped.getMemberValuePairs(); + } + + @Override + public Object getMemberConstantValue(String name) { + return wrapped.getMemberConstantValue(name); + } + + @Override + public Object getMemberDefaultValue(String name) { + return wrapped.getMemberDefaultValue(name); + } + + @Override + public IMember getParentMember() { + return wrapped.getParentMember(); + } + + @Override + public String getTypeName() { + return wrapped.getTypeName(); + } + + @Override + public IType getType() { + return wrapped.getType(); + } + + @Override + public int getLength() { + return wrapped.getLength(); + } + + @Override + public int getStartPosition() { + return wrapped.getStartPosition(); + } + + @Override + public IAnnotationType getAnnotation() { + return wrapped.getAnnotation(); + } + + @Override + public IAnnotation getJavaAnnotation() { + return wrapped.getJavaAnnotation(); + } + + @Override + public IMember getSourceMember() { + return wrapped.getSourceMember(); + } + + @Override + public IJavaElement getSourceElement() { + return wrapped.getSourceElement(); + } + }.init(ad); // class + } + + return ad; } public IResource getResource() { return resource; } -} \ No newline at end of file +}