Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   *
   * Copyright (c) 2007-2011 Oracle and/or its affiliates. All rights reserved.
   *
   * The contents of this file are subject to the terms of either the GNU
   * General Public License Version 2 only ("GPL") or the Common Development
   * and Distribution License("CDDL") (collectively, the "License").  You
   * may not use this file except in compliance with the License.  You can
  * obtain a copy of the License at
  * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
  * or packager/legal/LICENSE.txt.  See the License for the specific
  * language governing permissions and limitations under the License.
  *
  * When distributing the software, include this License Header Notice in each
  * file and include the License file at packager/legal/LICENSE.txt.
  *
  * GPL Classpath Exception:
  * Oracle designates this particular file as subject to the "Classpath"
  * exception as provided by Oracle in the GPL Version 2 section of the License
  * file that accompanied this code.
  *
  * Modifications:
  * If applicable, add the following below the License Header, with the fields
  * enclosed by brackets [] replaced by your own identifying information:
  * "Portions Copyright [year] [name of copyright owner]"
  *
  * Contributor(s):
  * If you wish your version of this file to be governed by only the CDDL or
  * only the GPL Version 2, indicate your decision by adding "[Contributor]
  * elects to include this software in this distribution under the [CDDL or GPL
  * Version 2] license."  If you don't indicate a single choice of license, a
  * recipient has the option to distribute your version of this file under
  * either the CDDL, the GPL Version 2 or to extend the choice of license to
  * its licensees as provided above.  However, if you add GPL Version 2 code
  * and therefore, elected the GPL Version 2 license, then the option applies
  * only if the new code is made subject to such option by the copyright
  * holder.
  */
 package com.sun.enterprise.tools.apt;
 
 
 
 import  javax.inject.Qualifier;
 import java.util.*;
 
 import static com.sun.hk2.component.InhabitantsFile.*;

Generates /META-INF/inhabitants/*

Author(s):
Kohsuke Kawaguchi
 
     private final AnnotationProcessorEnvironment env;
     private final boolean debug;
     private final DescriptorList list;
 
 
         this. = env;
          = env.getOptions().containsKey("-Adebug");
         env.addListener(this);
 
         this. = list;
     }
 
 
     public void process() {
         // env.getTypeDeclarations() only contain types that are newly introduced in the round
         DeclarationVisitor scanner = DeclarationVisitors.getDeclarationScanner(
             new ListClassVisitor(),
             .);
         for (TypeDeclaration typeDecl : .getTypeDeclarations())
             typeDecl.accept(scanner);
     }

    
Defer the output till the very end, because otherwise we'll end up writing files multiple times, which APT doesn't like. But APT also doesn't like us creating files after the rounds are completed, so we need a hack to figure out where the output directory is, and use that.
 
    public void roundComplete(RoundCompleteEvent event) {
        if(!event.getRoundState().finalRound())
            return;
        .write();
    }
    private class ListClassVisitor extends SimpleDeclarationVisitor {
        
Contract indices found in various methods of this class gets accumulated here.
        private final LinkedHashSet<Stringindices = new LinkedHashSet<String>();

        
Qualifiers gets accumulated here
        private final LinkedHashSet<Stringqualifiers = new LinkedHashSet<String>();

        
InterfaceTypes whose contracts are already checked.
        private final Set<InterfaceDeclarationcheckedInterfaces = new HashSet<InterfaceDeclaration>();
        private AnnotationMirror find(Declaration dClass<? extends AnnotationannType) {
            for(AnnotationMirror am : d.getAnnotationMirrors()) {
                if(am.getAnnotationType().getDeclaration().getQualifiedName().equals(annType.getName()))
                    return am;
            }
            return null;
        }
        public void visitClassDeclaration(ClassDeclaration d) {
            if () {
                .getMessager().printNotice("Visiting " + d.getQualifiedName());
            }
            // check if this class has annotation that has InhabitantAnnotation meta-annotation.
            InhabitantAnnotation ia=null;
            AnnotationMirror a=null;
            for (AnnotationMirror am : d.getAnnotationMirrors()) {
                ia = am.getAnnotationType().getDeclaration().getAnnotation(InhabitantAnnotation.class);
                if(ia!=null) {
                    a = am;
                    break;
                }
            }
            if(ia==null) {
                // doesn't have any component annotation.
                // in case annotations are removed from them, update the descriptors
                for (InhabitantsDescriptor id : ..values())
                    id.remove(d.getQualifiedName());
                return;
            }
            if () {
                .getMessager().printWarning("Found component annotation " + a + " on "+d.getQualifiedName());
            }
            
            // update the descriptor
            InhabitantsDescriptor descriptor = .get(ia.value());
            descriptor.put(d.getQualifiedName(),getInhabitantDeclaration(a,d));
        }
        public void visitInterfaceDeclaration(InterfaceDeclaration d) {
            if () {
                .getMessager().printNotice("Visiting " + d.getQualifiedName());
            }
            // check if this class has annotation that has InhabitantAnnotation meta-annotation.
            InhabitantAnnotation ia=null;
            AnnotationMirror a=null;
            for (AnnotationMirror am : d.getAnnotationMirrors()) {
                ia = am.getAnnotationType().getDeclaration().getAnnotation(InhabitantAnnotation.class);
                if(ia!=null) {
                    a = am;
                    if () {
                        .getMessager().printWarning("Found component annotation " + a + " on "+d.getQualifiedName());
                    }
                    String service=null;
                    ServiceProvider sp = a.getAnnotationType().getDeclaration().getAnnotation(ServiceProvider.class);
                    if (sp!=null) {
                        try {
                            sp.value();
                        } catch (MirroredTypeException e) {
                            service = ((DeclaredType)e.getTypeMirror()).getDeclaration().getQualifiedName();
                        }
                    }
                    InhabitantsDescriptor descriptor = .get(ia.value());
                    if (service!=null) {
                        processGenericImpl(servicedescriptorda);
                    }
                }
            }
        }
        public void processGenericImpl(String serviceInhabitantsDescriptor descriptorTypeDeclaration dAnnotationMirror a) {
                List<Stringnames = getIndexValues(a);
                String contract=null;
                ContractProvided cp = a.getAnnotationType().getDeclaration().getAnnotation(ContractProvided.class);
                if (cp!=null) {
                    try {
                        cp.value();
                    } catch (MirroredTypeException e) {
                        contract = ((DeclaredType)e.getTypeMirror()).getDeclaration().getQualifiedName();
                    }
                }
                String qualifiedName = d.getQualifiedName();
                
                 StringBuilder buf = new StringBuilder();
                 buf.append(.).append('=').append(service);
                 if (null == names) {
                   buf.append(",").append().append("=").append(contract);
                 } else {
                   for (String name : names) {
                     buf.append(",").append().append("=").append(contract).append(":").append(name);
                   }
                 }
                 buf.append(",").append().append("=").append(qualifiedName);
                 for (AnnotationTypeElementDeclaration ated : a.getAnnotationType().getDeclaration().getMethods()) {
                     for (AnnotationMirror am : ated.getAnnotationMirrors()) {
                         if (am.getAnnotationType().getDeclaration().getSimpleName().equals(InhabitantMetadata.class.getSimpleName())) {
                             for (Map.Entry<AnnotationTypeElementDeclarationAnnotationValueentry : a.getElementValues().entrySet()) {
                                 if (entry.getKey().getSimpleName().equals(ated.getSimpleName())) {
                                     buf.append(",").append(ated.getSimpleName()).append("=").append(entry.getValue().toString());
                                 }
                             }
                         }
                     }
                 }
                 descriptor.put(contract+":"+namesbuf.toString());
/*                // we should support gettting the @ContractProvided from the ServiceProvider
                for (AnnotationMirror am : a.getAnnotationType().getDeclaration().getAnnotationMirrors()) {
                    if (am.getAnnotationType().getDeclaration().getSimpleName().equals(ContractProvided.class.getSimpleName())) {
                        for (Map.Entry<AnnotationTypeElementDeclaration, AnnotationValue> entry : am.getElementValues().entrySet()) {
                            contract = entry.getValue().toString();
                        }
                    }
                }
                */
        }        

        
Visits a method declaration. The implementation simply invokes visitExecutableDeclaration.

Parameters:
d the declaration to visit
        public void visitMethodDeclaration(MethodDeclaration d) {
            if () {
                .getMessager().printWarning("Visiting " + d.getSimpleName());
            }
            for (AnnotationMirror am : d.getAnnotationMirrors()) {
                Multiple multiple = am.getAnnotationType().getDeclaration().getAnnotation(Multiple.class);
                if (multiple!=null) {
                    Collection<AnnotationTypeElementDeclarationmembers = am.getAnnotationType().getDeclaration().getMethods();
                    AnnotationTypeElementDeclaration valueMember=null;
                    for (AnnotationTypeElementDeclaration aMember : members) {
                        if (aMember.getSimpleName().endsWith("value")) {
                            valueMember = aMember;
                            break;
                        }
                    }
                    if (valueMember==nullreturn;
                    AnnotationValue valueVal = am.getElementValues().get(valueMember);
                    Object annotationValue = valueVal.getValue();
                    if (annotationValue instanceof Collection) {
                        Collection<AnnotationValuevalues = (Collection<AnnotationValue>) annotationValue;
                        for (AnnotationValue aVal : values) {
                            AnnotationMirror aValMirror = (AnnotationMirroraVal.getValue();
                            // check if the annotation contained in the multiple declaration is itself annotated
                            // with InhabitantAnnotation
                            InhabitantAnnotation ia = aValMirror.getAnnotationType().getDeclaration().getAnnotation(InhabitantAnnotation.class);
                            if (ia!=null) {
                                generateInhabitantEntry(daValMirroria);
                            }
                        }
                    } else {
                        ..println("Ignoring " + am + " which is annotated with @Multiple, yet it's value() method is not collection");                        
                    }
                }
                InhabitantAnnotation ia = am.getAnnotationType().getDeclaration().getAnnotation(InhabitantAnnotation.class);
                if (ia!=null) {
                    generateInhabitantEntry(damia);
                }
            }
        }
            InhabitantsDescriptor descriptor = .get(ia.value());
            String service=null;
            if (sp!=null) {
                try {
                    sp.value();
                } catch (MirroredTypeException e) {
                    service = ((DeclaredType)e.getTypeMirror()).getDeclaration().getQualifiedName();
                }
            }
/*            String service=null;
            // I cannot use a.getAnnotationType().getDeclaration().getAnnotation() because the value() is a class
            // which cannot be loaded by the classloader at compile time.
            for (AnnotationMirror am : a.getAnnotationType().getDeclaration().getAnnotationMirrors()) {
                if (am.getAnnotationType().getDeclaration().getSimpleName().equals(ServiceProvider.class.getSimpleName())) {
                    for (Map.Entry<AnnotationTypeElementDeclaration, AnnotationValue> entry : am.getElementValues().entrySet()) {
                        service = entry.getValue()toString();
                        service = ((DeclaredType)entry.).getDeclaration().getQualifiedName()
                    }
                }
            }
            */
            if (service!=null) {
                List<Stringnames = getIndexValues(a);
                String contract=null;
                ContractProvided cp = a.getAnnotationType().getDeclaration().getAnnotation(ContractProvided.class);
                if (cp!=null) {
                    try {
                        cp.value();
                    } catch (MirroredTypeException e) {
                        contract = ((DeclaredType)e.getTypeMirror()).getDeclaration().getQualifiedName();
                    }
                }
                /*String contract="";
                // we should support getting the @ContractProvided from the ServiceProvider
                for (AnnotationMirror am : a.getAnnotationType().getDeclaration().getAnnotationMirrors()) {
                    if (am.getAnnotationType().getDeclaration().getSimpleName().equals(ContractProvided.class.getSimpleName())) {
                        for (Map.Entry<AnnotationTypeElementDeclaration, AnnotationValue> entry : am.getElementValues().entrySet()) {
                            contract = entry.getValue().toString();
                        }
                    }
                } */
                StringBuilder buf = new StringBuilder();
                buf.append(.).append('=').append(service);
                if (null == names) {
                  buf.append(",").append().append("=").append(contract);
                } else {
                  for (String name : names) {
                    buf.append(",").append().append("=").append(contract).append(":").append(name);
                  }
                }
                buf.append(",").append().append("=").append(d.getDeclaringType().getQualifiedName());
                buf.append(",").append("method-name").append('=').append(d.getSimpleName());
                for (AnnotationTypeElementDeclaration ated : a.getAnnotationType().getDeclaration().getMethods()) {
                    for (AnnotationMirror am : ated.getAnnotationMirrors()) {
                        if (am.getAnnotationType().getDeclaration().getSimpleName().equals(InhabitantMetadata.class.getSimpleName())) {
                            for (Map.Entry<AnnotationTypeElementDeclarationAnnotationValueentry : a.getElementValues().entrySet()) {
                                if (entry.getKey().getSimpleName().equals(ated.getSimpleName())) {
                                    buf.append(",").append(ated.getSimpleName()).append("=").append(entry.getValue().toString());
                                }
                            }
                        }
                    }
                }
                descriptor.put(contract+":"+namesbuf.toString());
            } else {
                descriptor.put(d.getDeclaringType().getQualifiedName(),
                        getInhabitantDeclaration(a, (ClassDeclarationd.getDeclaringType()));
            }
        }

        
Computes the metadata line for the given class declaration.

Parameters:
a The annotation which is meta-annotated with InhabitantAnnotation. Used to extract the index.
            .clear();
            .clear();
            .clear();
            // check for Contract supertypes.
            List<Stringnames = getIndexValues(a);
            for (TypeDeclaration t : ContractFinder.find(d)) {
                enforceContractLevelScope(t,d);
                if (null != names) {
                  for (String name : names) {
                    addIndex(t.getQualifiedName(), name);
                  }
                } else {
                  addIndex(t.getQualifiedName(), null);
                }
            }
            // check for contract annotations
            for(AnnotationMirror am : d.getAnnotationMirrors()) {
                AnnotationTypeDeclaration atd = am.getAnnotationType().getDeclaration();
                Contract c = atd.getAnnotation(Contract.class);
                if (c!=null) {
                    // this is a contract annotation
                    enforceContractLevelScope(atd,d);
                    names = getIndexValues(am);
                    if (null != names) {
                      for (String name : names) {
                        addIndex(atd.getQualifiedName(), name);
                      }
                    } else {
                      addIndex(atd.getQualifiedName(), null);
                    }
                }
                // check for meta-annotations
                for(AnnotationMirror mam : atd.getAnnotationMirrors()) {
                    AnnotationTypeDeclaration matd = mam.getAnnotationType().getDeclaration();
                    Contract mc = matd.getAnnotation(Contract.class);
                    if (mc!=null) {
                        // meta-contract annotation
                        names = getIndexValues(mam);
                        if (null != names) {
                          for (String name : names) {
                            addIndex(matd.getQualifiedName(), name);
                          }
                        } else {
                          addIndex(matd.getQualifiedName(), null);
                        }
                    }
                }
                // check for JSR330 Qualifier
                Qualifier qualifier = atd.getAnnotation(Qualifier.class);
                if (qualifier!=null) {
                    .add(atd.getQualifiedName());
                }
            }
            StringBuilder buf = new StringBuilder();
            buf.append(.).append('=').append(getClassName(d));
            for (String contract : ) {
                addMetadata(bufcontract);
            }
            for (String qualifier : ) {
                addMetadata(bufqualifier);
            }
            findInhabitantMetadata(dbuf);
            // TODO: should be deprecated and replaced with InhabitantMetadata
            String metadata = getStringValue(a,"metadata");
            if (metadata!=null && metadata.length()>0) {
                buf.append(',').append(metadata);
            }
            return buf.toString();
        }

        
Returns the fully qualified class name. The difference between this and TypeDeclaration.getQualifiedName() is that this method returns the same format as Class.getName(). Notably, separator for nested classes is '$', not '.'
        private String getClassName(TypeDeclaration d) {
            if (d.getDeclaringType()!=null) {
                return getClassName(d.getDeclaringType())+'$'+d.getSimpleName();
            } else {
                return d.getQualifiedName();
            }
        }        
        private void addMetadata(StringBuilder bufString keyString value) {
            buf.append(',').append(key).append('=').append(value);
        }
        private String quote(String s) {
            StringBuilder buf = new StringBuilder();
            buf.append('"');
            forint i=0; i<s.length(); i++ ) {
                char ch=s.charAt(i);
                switch(ch) {
                case '\\':
                    buf.append("\\\\");
                    break;
                case '"':
                    buf.append("\\\"");
                    break;
                default:
                    buf.append(ch);
                }
            }
            buf.append('"');
            return buf.toString();
        }

        
Locates all InhabitantMetadata to add to the metadata.
        private void findInhabitantMetadata(ClassDeclaration dStringBuilder buf) {
          MultiMap<StringStringmd = .process(d);
          for (Map.Entry<StringList<String>> e : md.entrySet()) {
            HashSet<Stringprocessed = new HashSet<String>();
            for (String val : e.getValue()) {
              if (processed.add(val)) {
                processed.add(val);
                buf.append(',').append(e.getKey()).append('=').append(val);
              }
            }
          }
        }

        
Finds the value of the annotation element annotated with Index.
        private List<StringgetIndexValues(AnnotationMirror a) {
            ArrayList<Stringresult = new ArrayList<String>();
            
            AnnotationTypeDeclaration decl = a.getAnnotationType().getDeclaration();
            for (AnnotationTypeElementDeclaration e : decl.getMethods()) {
                if (e.getAnnotation(Index.class)!=null) {
                    AnnotationValue v = a.getElementValues().get(e);
                    if (null != v) {
                      if (Collection.class.isInstance(v.getValue())) {
                        for (Object val : (Collection<?>)v.getValue()) {
                          if (null != val) {
                            if (AnnotationValue.class.isInstance(val)) {
                              Object av = AnnotationValue.class.cast(val).getValue();
                              if (ClassType.class.isInstance(av)) {
                                result.add(getClassName(ClassType.class.cast(av).getDeclaration()));
                              } else {
                                result.add(av.toString());
                              }
                            } else {
                              result.add(val.toString());
                            }
                          }
                        }
                      } else {
                        result.add(v.getValue().toString());
                      }
                    } else { // defaulted
                      result.add(e.getDefaultValue().getValue().toString());
                    }
                }
            }
            
            return result.isEmpty() ? null : result;
        }

        
Given a use of annotation like @abc(def="ghi",jkl="mno") and a property name 'def', obtain the value of the annotation (in this example "ghi")
        private String getStringValue(AnnotationMirror aString name) {
            AnnotationTypeDeclaration decl = a.getAnnotationType().getDeclaration();
            for (AnnotationTypeElementDeclaration e : decl.getMethods()) {
                if (e.getSimpleName().equals(name)) {
                    AnnotationValue v = a.getElementValues().get(e);
                    if (v!=null) { // explicitly given
                        return v.getValue().toString();
                    } else { // defaulted
                        return e.getDefaultValue().getValue().toString();
                    }
                }
            }
            return null;
        }
        private void addIndex(String primaryString secondary) {
            if (secondary==null || secondary.length()==0) {
                .add(primary);    // unnamed
            } else {
                .add(primary+':'+secondary); // named
            }
        }

        
Records the contract<->service relationship.

Parameters:
ctrct The contract type declaration. Null in case of ContractProvided.
impl Implementation class.
        private void enforceContractLevelScope(TypeDeclaration ctrctClassDeclaration impl) {
            // if @Scoped is on the contract, that means we are forcing a certain scope type.
            Scoped s = ctrct.getAnnotation(Scoped.class);
            if (s==null) {
                return;
            }
            try {
                s.value();
                throw new AssertionError();
            } catch (MirroredTypeException e) {
                TypeMirror forcedScope = e.getTypeMirror();
                s = impl.getAnnotation(Scoped.class);
                if(s!=null) {
                    try {
                        s.value();
                        throw new AssertionError();
                    } catch (MirroredTypeException f) {
                        if(forcedScope.equals(f.getTypeMirror()))
                            return// forced scope and the actual scope are consistent
                    }
                }
                .getMessager().printError(impl.getPosition(),"@Scoped("+forcedScope+") is required because of the contract "+ctrct.getQualifiedName());
            }
        }
    }
New to GrepCode? Check out our FAQ X