src/share/classes/com/sun/tools/doclets/internal/toolkit/util/ClassUseMapper.java

Thu, 02 Oct 2008 19:58:40 -0700

author
xdono
date
Thu, 02 Oct 2008 19:58:40 -0700
changeset 117
24a47c3062fe
parent 74
5a9172b251dd
child 184
905e151a185a
permissions
-rw-r--r--

6754988: Update copyright year
Summary: Update for files that have been modified starting July 2008
Reviewed-by: ohair, tbell

     1 /*
     2  * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any questions.
    24  */
    26 package com.sun.tools.doclets.internal.toolkit.util;
    28 import com.sun.javadoc.*;
    29 import java.util.*;
    31 /**
    32  * Map all class uses for a given class.
    33  *
    34  * This code is not part of an API.
    35  * It is implementation that is subject to change.
    36  * Do not use it as an API
    37  *
    38  * @since 1.2
    39  * @author Robert G. Field
    40  */
    41 public class ClassUseMapper {
    43     private final ClassTree classtree;
    45     /**
    46      * Mapping of ClassDocs to set of PackageDoc used by that class.
    47      * Entries may be null.
    48      */
    49     public Map<String,Set<PackageDoc>> classToPackage = new HashMap<String,Set<PackageDoc>>();
    51     /**
    52      * Mapping of Annotations to set of PackageDoc that use the annotation.
    53      */
    54     public Map<String,List<PackageDoc>> classToPackageAnnotations = new HashMap<String,List<PackageDoc>>();
    56     /**
    57      * Mapping of ClassDocs to set of ClassDoc used by that class.
    58      * Entries may be null.
    59      */
    60     public Map<String,Set<ClassDoc>> classToClass = new HashMap<String,Set<ClassDoc>>();
    62     /**
    63      * Mapping of ClassDocs to list of ClassDoc which are direct or
    64      * indirect subclasses of that class.
    65      * Entries may be null.
    66      */
    67     public Map<String,List<ClassDoc>> classToSubclass = new HashMap<String,List<ClassDoc>>();
    69     /**
    70      * Mapping of ClassDocs to list of ClassDoc which are direct or
    71      * indirect subinterfaces of that interface.
    72      * Entries may be null.
    73      */
    74     public Map<String,List<ClassDoc>> classToSubinterface = new HashMap<String,List<ClassDoc>>();
    76     /**
    77      * Mapping of ClassDocs to list of ClassDoc which implement
    78      * this interface.
    79      * Entries may be null.
    80      */
    81     public Map<String,List<ClassDoc>> classToImplementingClass = new HashMap<String,List<ClassDoc>>();
    83     /**
    84      * Mapping of ClassDocs to list of FieldDoc declared as that class.
    85      * Entries may be null.
    86      */
    87     public Map<String,List<FieldDoc>> classToField = new HashMap<String,List<FieldDoc>>();
    89     /**
    90      * Mapping of ClassDocs to list of MethodDoc returning that class.
    91      * Entries may be null.
    92      */
    93     public Map<String,List<MethodDoc>> classToMethodReturn = new HashMap<String,List<MethodDoc>>();
    95     /**
    96      * Mapping of ClassDocs to list of MethodDoc having that class
    97      * as an arg.
    98      * Entries may be null.
    99      */
   100     public Map<String,List<ExecutableMemberDoc>> classToMethodArgs = new HashMap<String,List<ExecutableMemberDoc>>();
   102     /**
   103      * Mapping of ClassDocs to list of MethodDoc which throws that class.
   104      * Entries may be null.
   105      */
   106     public Map<String,List<ExecutableMemberDoc>> classToMethodThrows = new HashMap<String,List<ExecutableMemberDoc>>();
   108     /**
   109      * Mapping of ClassDocs to list of ConstructorDoc having that class
   110      * as an arg.
   111      * Entries may be null.
   112      */
   113     public Map<String,List<ExecutableMemberDoc>> classToConstructorArgs = new HashMap<String,List<ExecutableMemberDoc>>();
   115     /**
   116      * Mapping of ClassDocs to list of ConstructorDoc which throws that class.
   117      * Entries may be null.
   118      */
   119     public Map<String,List<ExecutableMemberDoc>> classToConstructorThrows = new HashMap<String,List<ExecutableMemberDoc>>();
   121     /**
   122      * The mapping of AnnotationTypeDocs to constructors that use them.
   123      */
   124     public Map<String,List<ConstructorDoc>> classToConstructorAnnotations = new HashMap<String,List<ConstructorDoc>>();
   126     /**
   127      * The mapping of AnnotationTypeDocs to Constructor parameters that use them.
   128      */
   129     public Map<String,List<ExecutableMemberDoc>> classToConstructorParamAnnotation = new HashMap<String,List<ExecutableMemberDoc>>();
   131     /**
   132      * The mapping of ClassDocs to Constructor arguments that use them as type parameters.
   133      */
   134     public Map<String,List<ExecutableMemberDoc>> classToConstructorDocArgTypeParam = new HashMap<String,List<ExecutableMemberDoc>>();
   136     /**
   137      * The mapping of ClassDocs to ClassDocs that use them as type parameters.
   138      */
   139     public Map<String,List<ClassDoc>> classToClassTypeParam = new HashMap<String,List<ClassDoc>>();
   141     /**
   142      * The mapping of AnnotationTypeDocs to ClassDocs that use them.
   143      */
   144     public Map<String,List<ClassDoc>> classToClassAnnotations = new HashMap<String,List<ClassDoc>>();
   146     /**
   147      * The mapping of ClassDocs to ExecutableMemberDocs that use them as type parameters.
   148      */
   149     public Map<String,List<MethodDoc>> classToExecMemberDocTypeParam = new HashMap<String,List<MethodDoc>>();
   151     /**
   152      * The mapping of ClassDocs to ExecutableMemberDocs arguments that use them as type parameters.
   153      */
   154     public Map<String,List<ExecutableMemberDoc>> classToExecMemberDocArgTypeParam = new HashMap<String,List<ExecutableMemberDoc>>();
   156     /**
   157      * The mapping of AnnotationTypeDocs to ExecutableMemberDocs that use them.
   158      */
   159     public Map<String,List<MethodDoc>> classToExecMemberDocAnnotations = new HashMap<String,List<MethodDoc>>();
   161     /**
   162      * The mapping of ClassDocs to ExecutableMemberDocs that have return type
   163      * with type parameters of that class.
   164      */
   165     public Map<String,List<MethodDoc>> classToExecMemberDocReturnTypeParam = new HashMap<String,List<MethodDoc>>();
   167     /**
   168      * The mapping of AnnotationTypeDocs to MethodDoc parameters that use them.
   169      */
   170     public Map<String,List<ExecutableMemberDoc>> classToExecMemberDocParamAnnotation = new HashMap<String,List<ExecutableMemberDoc>>();
   172     /**
   173      * The mapping of ClassDocs to FieldDocs that use them as type parameters.
   174      */
   175     public Map<String,List<FieldDoc>> classToFieldDocTypeParam = new HashMap<String,List<FieldDoc>>();
   177     /**
   178      * The mapping of AnnotationTypeDocs to FieldDocs that use them.
   179      */
   180     public Map<String,List<FieldDoc>> annotationToFieldDoc = new HashMap<String,List<FieldDoc>>();
   183     public ClassUseMapper(RootDoc root, ClassTree classtree) {
   184         this.classtree = classtree;
   186         // Map subclassing, subinterfacing implementing, ...
   187         for (Iterator it = classtree.baseclasses().iterator(); it.hasNext();) {
   188             subclasses((ClassDoc)it.next());
   189         }
   190         for (Iterator it = classtree.baseinterfaces().iterator(); it.hasNext();) {
   191             // does subinterfacing as side-effect
   192             implementingClasses((ClassDoc)it.next());
   193         }
   194         // Map methods, fields, constructors using a class.
   195         ClassDoc[] classes = root.classes();
   196         for (int i = 0; i < classes.length; i++) {
   197             PackageDoc pkg = classes[i].containingPackage();
   198             mapAnnotations(classToPackageAnnotations, pkg, pkg);
   199             ClassDoc cd = classes[i];
   200             mapTypeParameters(classToClassTypeParam, cd, cd);
   201             mapAnnotations(classToClassAnnotations, cd, cd);
   202             FieldDoc[] fields = cd.fields();
   203             for (int j = 0; j < fields.length; j++) {
   204                 FieldDoc fd = fields[j];
   205                 mapTypeParameters(classToFieldDocTypeParam, fd, fd);
   206                 mapAnnotations(annotationToFieldDoc, fd, fd);
   207                 if (! fd.type().isPrimitive()) {
   208                     add(classToField, fd.type().asClassDoc(), fd);
   209                 }
   210             }
   211             ConstructorDoc[] cons = cd.constructors();
   212             for (int j = 0; j < cons.length; j++) {
   213                 mapAnnotations(classToConstructorAnnotations, cons[j], cons[j]);
   214                 mapExecutable(cons[j]);
   215             }
   216             MethodDoc[] meths = cd.methods();
   217             for (int j = 0; j < meths.length; j++) {
   218                 MethodDoc md = meths[j];
   219                 mapExecutable(md);
   220                 mapTypeParameters(classToExecMemberDocTypeParam, md, md);
   221                 mapAnnotations(classToExecMemberDocAnnotations, md, md);
   222                 if (! (md.returnType().isPrimitive() || md.returnType() instanceof TypeVariable)) {
   223                     mapTypeParameters(classToExecMemberDocReturnTypeParam,
   224                         md.returnType(), md);
   225                     add(classToMethodReturn, md.returnType().asClassDoc(), md);
   226                 }
   227             }
   228         }
   229     }
   231     /**
   232      * Return all subclasses of a class AND fill-in classToSubclass map.
   233      */
   234     private Collection<ClassDoc> subclasses(ClassDoc cd) {
   235         Collection<ClassDoc> ret = classToSubclass.get(cd.qualifiedName());
   236         if (ret == null) {
   237             ret = new TreeSet<ClassDoc>();
   238             List<ClassDoc> subs = classtree.subclasses(cd);
   239             if (subs != null) {
   240                 ret.addAll(subs);
   241                 for (Iterator<ClassDoc> it = subs.iterator(); it.hasNext();) {
   242                     ret.addAll(subclasses(it.next()));
   243                 }
   244             }
   245             addAll(classToSubclass, cd, ret);
   246         }
   247         return ret;
   248     }
   250     /**
   251      * Return all subinterfaces of an interface AND fill-in classToSubinterface map.
   252      */
   253     private Collection<ClassDoc> subinterfaces(ClassDoc cd) {
   254         Collection<ClassDoc> ret = classToSubinterface.get(cd.qualifiedName());
   255         if (ret == null) {
   256             ret = new TreeSet<ClassDoc>();
   257             List<ClassDoc> subs = classtree.subinterfaces(cd);
   258             if (subs != null) {
   259                 ret.addAll(subs);
   260                 for (Iterator<ClassDoc> it = subs.iterator(); it.hasNext();) {
   261                     ret.addAll(subinterfaces(it.next()));
   262                 }
   263             }
   264             addAll(classToSubinterface, cd, ret);
   265         }
   266         return ret;
   267     }
   269     /**
   270      * Return all implementing classes of an interface (including
   271      * all subclasses of implementing classes and all classes
   272      * implementing subinterfaces) AND fill-in both classToImplementingClass
   273      * and classToSubinterface maps.
   274      */
   275     private Collection<ClassDoc> implementingClasses(ClassDoc cd) {
   276         Collection<ClassDoc> ret = classToImplementingClass.get(cd.qualifiedName());
   277         if (ret == null) {
   278             ret = new TreeSet<ClassDoc>();
   279             List<ClassDoc> impl = classtree.implementingclasses(cd);
   280             if (impl != null) {
   281                 ret.addAll(impl);
   282                 for (Iterator it = impl.iterator(); it.hasNext();) {
   283                     ret.addAll(subclasses((ClassDoc)it.next()));
   284                 }
   285             }
   286             for (Iterator it = subinterfaces(cd).iterator(); it.hasNext();) {
   287                 ret.addAll(implementingClasses((ClassDoc)it.next()));
   288             }
   289             addAll(classToImplementingClass, cd, ret);
   290         }
   291         return ret;
   292     }
   294     /**
   295      * Determine classes used by a method or constructor, so they can be
   296      * inverse mapped.
   297      */
   298     private void mapExecutable(ExecutableMemberDoc em) {
   299         Parameter[] params = em.parameters();
   300         boolean isConstructor = em.isConstructor();
   301         List<Type> classArgs = new ArrayList<Type>();
   302         for (int k = 0; k < params.length; k++) {
   303             Type pcd = params[k].type();
   304             // primitives don't get mapped, also avoid dups
   305             if ((! params[k].type().isPrimitive()) &&
   306                  ! classArgs.contains(pcd) &&
   307                  ! (pcd instanceof TypeVariable)) {
   308                 add(isConstructor? classToConstructorArgs :classToMethodArgs,
   309                         pcd.asClassDoc(), em);
   310                 classArgs.add(pcd);
   311                 mapTypeParameters(isConstructor?
   312                    classToConstructorDocArgTypeParam : classToExecMemberDocArgTypeParam,
   313                    pcd, em);
   314             }
   315             mapAnnotations(
   316                 isConstructor ?
   317                     classToConstructorParamAnnotation :
   318                     classToExecMemberDocParamAnnotation,
   319                 params[k], em);
   320         }
   321         ClassDoc[] thr = em.thrownExceptions();
   322         for (int k = 0; k < thr.length; k++) {
   323             add(isConstructor? classToConstructorThrows : classToMethodThrows,
   324                     thr[k], em);
   325         }
   326     }
   328     private <T> List<T> refList(Map<String,List<T>> map, ClassDoc cd) {
   329         List<T> list = map.get(cd.qualifiedName());
   330         if (list == null) {
   331             @SuppressWarnings("unchecked")
   332             List<T> l = new ArrayList();
   333             list = l;
   334             map.put(cd.qualifiedName(), list);
   335         }
   336         return list;
   337     }
   339     private Set<PackageDoc> packageSet(ClassDoc cd) {
   340         Set<PackageDoc> pkgSet = classToPackage.get(cd.qualifiedName());
   341         if (pkgSet == null) {
   342             pkgSet = new TreeSet<PackageDoc>();
   343             classToPackage.put(cd.qualifiedName(), pkgSet);
   344         }
   345         return pkgSet;
   346     }
   348     private Set<ClassDoc> classSet(ClassDoc cd) {
   349         Set<ClassDoc> clsSet = classToClass.get(cd.qualifiedName());
   350         if (clsSet == null) {
   351             @SuppressWarnings("unchecked")
   352             Set<ClassDoc> s = new TreeSet();
   353             clsSet = s;
   354             classToClass.put(cd.qualifiedName(), clsSet);
   355         }
   356         return clsSet;
   357     }
   359     private <T extends ProgramElementDoc> void add(Map<String,List<T>> map, ClassDoc cd, T ref) {
   360         // add to specified map
   361         refList(map, cd).add(ref);
   363         // add ref's package to package map and class map
   364         packageSet(cd).add(ref.containingPackage());
   366         classSet(cd).add(ref instanceof MemberDoc?
   367                 ((MemberDoc)ref).containingClass() :
   368                     (ClassDoc)ref);
   369     }
   371     private void addAll(Map<String,List<ClassDoc>> map, ClassDoc cd, Collection<ClassDoc> refs) {
   372         if (refs == null) {
   373             return;
   374         }
   375         // add to specified map
   376         refList(map, cd).addAll(refs);
   378         Set<PackageDoc> pkgSet = packageSet(cd);
   379         Set<ClassDoc> clsSet = classSet(cd);
   380         // add ref's package to package map and class map
   381         for (Iterator<ClassDoc> it = refs.iterator(); it.hasNext();) {
   382             ClassDoc cls = it.next();
   383             pkgSet.add(cls.containingPackage());
   384             clsSet.add(cls);
   386         }
   387     }
   389     /**
   390      * Map the ClassDocs to the ProgramElementDocs that use them as
   391      * type parameters.
   392      *
   393      * @param map the map the insert the information into.
   394      * @param doc the doc whose type parameters are being checked.
   395      * @param holder the holder that owns the type parameters.
   396      */
   397     private <T extends ProgramElementDoc> void mapTypeParameters(Map<String,List<T>> map, Object doc,
   398             T holder) {
   399         TypeVariable[] typeVariables;
   400         if (doc instanceof ClassDoc) {
   401             typeVariables = ((ClassDoc) doc).typeParameters();
   402         } else if (doc instanceof WildcardType) {
   403             Type[] extendsBounds = ((WildcardType) doc).extendsBounds();
   404             for (int k = 0; k < extendsBounds.length; k++) {
   405                 addTypeParameterToMap(map, extendsBounds[k], holder);
   406             }
   407             Type[] superBounds = ((WildcardType) doc).superBounds();
   408             for (int k = 0; k < superBounds.length; k++) {
   409                 addTypeParameterToMap(map, superBounds[k], holder);
   410             }
   411             return;
   412         } else if (doc instanceof ParameterizedType) {
   413             Type[] typeArguments = ((ParameterizedType) doc).typeArguments();
   414             for (int k = 0; k < typeArguments.length; k++) {
   415                 addTypeParameterToMap(map, typeArguments[k], holder);
   416             }
   417             return;
   418         } else if (doc instanceof ExecutableMemberDoc) {
   419             typeVariables = ((ExecutableMemberDoc) doc).typeParameters();
   420         } else if (doc instanceof FieldDoc) {
   421             Type fieldType = ((FieldDoc) doc).type();
   422             mapTypeParameters(map, fieldType, holder);
   423             return;
   424         } else {
   425             return;
   426         }
   427         for (int i = 0; i < typeVariables.length; i++) {
   428             Type[] bounds = typeVariables[i].bounds();
   429             for (int j = 0; j < bounds.length; j++) {
   430                 addTypeParameterToMap(map, bounds[j], holder);
   431             }
   432         }
   433     }
   435     /**
   436      * Map the AnnotationType to the ProgramElementDocs that use them as
   437      * type parameters.
   438      *
   439      * @param map the map the insert the information into.
   440      * @param doc the doc whose type parameters are being checked.
   441      * @param holder the holder that owns the type parameters.
   442      */
   443     private <T extends ProgramElementDoc> void mapAnnotations(Map<String,List<T>> map, Object doc,
   444             T holder) {
   445         AnnotationDesc[] annotations;
   446         boolean isPackage = false;
   447         if (doc instanceof ProgramElementDoc) {
   448             annotations = ((ProgramElementDoc) doc).annotations();
   449         } else if (doc instanceof PackageDoc) {
   450             annotations = ((PackageDoc) doc).annotations();
   451             isPackage = true;
   452         } else if (doc instanceof Parameter) {
   453             annotations = ((Parameter) doc).annotations();
   454         } else {
   455             throw new DocletAbortException();
   456         }
   457         for (int i = 0; i < annotations.length; i++) {
   458             AnnotationTypeDoc annotationDoc = annotations[i].annotationType();
   459             if (isPackage)
   460                 refList(map, annotationDoc).add(holder);
   461             else
   462                 add(map, annotationDoc, holder);
   463         }
   464     }
   467     /**
   468      * Map the AnnotationType to the ProgramElementDocs that use them as
   469      * type parameters.
   470      *
   471      * @param map the map the insert the information into.
   472      * @param doc the doc whose type parameters are being checked.
   473      * @param holder the holder that owns the type parameters.
   474      */
   475     private <T extends PackageDoc> void mapAnnotations(Map<String,List<T>> map, PackageDoc doc,
   476             T holder) {
   477         AnnotationDesc[] annotations;
   478         annotations = doc.annotations();
   479         for (int i = 0; i < annotations.length; i++) {
   480             AnnotationTypeDoc annotationDoc = annotations[i].annotationType();
   481             refList(map, annotationDoc).add(holder);
   482         }
   483     }
   485     private <T extends ProgramElementDoc> void addTypeParameterToMap(Map<String,List<T>> map, Type type,
   486             T holder) {
   487         if (type instanceof ClassDoc) {
   488             add(map, (ClassDoc) type, holder);
   489         } else if (type instanceof ParameterizedType) {
   490             add(map, ((ParameterizedType) type).asClassDoc(), holder);
   491         }
   492         mapTypeParameters(map, type, holder);
   493     }
   494 }

mercurial