Uploaded image for project: 'Tools (JBoss Tools)'
  1. Tools (JBoss Tools)
  2. JBIDE-25748

Discovery of "foreign" bean types for JSF auto-complete

XMLWordPrintable

    • Icon: Feature Request Feature Request
    • Resolution: Unresolved
    • Icon: Major Major
    • 4.30.x
    • 4.5.2.Final
    • cdi, jsf
    • None

      Auto-complete in JSF supports @ManagedBean and @Named, fine.
      But it is also possible to use "foreign" beans, concretely Spring via @Controller.

      I manually implemented a "hack" (see also https://stackoverflow.com/questions/48933757/el-autocomplete-code-assist-with-eclipse-and-spring-beans/48933758#48933758) by simply extending a single classes method.

      For JSF only extend class org.jboss.tools.jsf.jsf2.bean.model.impl.AbstractMemberDefinition methods getManagedBeanAnnotation() and isAnnotationPresent():

      public boolean isAnnotationPresent(String annotationTypeName) {
          //TW: added Spring annotations
          boolean b = (getAnnotation(annotationTypeName) != null);
          if (!b  &&  JSF2Constants.MANAGED_BEAN_ANNOTATION_TYPE_NAME.equals(annotationTypeName)) {
              b = (getAnnotation("org.springframework.stereotype.Controller") != null);
              /* with support for all Spring annotations:
              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() {
          AnnotationDeclaration ad = annotationsByType.get(JSF2Constants.MANAGED_BEAN_ANNOTATION_TYPE_NAME);
          //TW: added Spring annotations
          if (ad != null)  return ad;
          ad = annotationsByType.get("org.springframework.stereotype.Controller");
          /* with support for all Spring annotations:
          if (ad == null)  ad = annotationsByType.get("org.springframework.stereotype.Service");
          if (ad == null)  ad = annotationsByType.get("org.springframework.stereotype.Repository");
          if (ad == null)  ad = annotationsByType.get("org.springframework.stereotype.Component");
          */
          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;
      }
      

      For CDI extend class org.jboss.tools.cdi.internal.core.impl.definition.AbstractMemberDefinition method getNamedAnnotation():

      public AnnotationDeclaration getNamedAnnotation() {
          AnnotationDeclaration ad = getAnnotation(CDIConstants.NAMED_QUALIFIER_TYPE_NAME);
          //TW: added Spring annotations
          if (ad != null)  return ad;
          ad = getAnnotation("org.springframework.stereotype.Controller");
          /* add additional Spring annotations, if desired:
          if (ad != null)  return ad;
          ad = getAnnotation("org.springframework.stereotype.Service");
          if (ad != null)  return ad;
          ad = getAnnotation("org.springframework.stereotype.Repository");
          if (ad != null)  return ad;
          ad = getAnnotation("org.springframework.stereotype.Component");
          */
          return ad;
      }
      

      Best would be to offer a preferences String, that allows to add arbitrary annotations - maybe even a project specific setting.

            jmaury@redhat.com Jeff MAURY
            thiesw Thies W. (Inactive)
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: