src/share/classes/com/sun/tools/doclets/internal/toolkit/util/ClassTree.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.tools.doclets.internal.toolkit.*;
    29 import com.sun.javadoc.*;
    30 import java.util.*;
    32 /**
    33  * Build Class Hierarchy for all the Classes. This class builds the Class
    34  * Tree and the Interface Tree separately.
    35  *
    36  * This code is not part of an API.
    37  * It is implementation that is subject to change.
    38  * Do not use it as an API
    39  *
    40  * @see java.util.HashMap
    41  * @see java.util.List
    42  * @see com.sun.javadoc.Type
    43  * @see com.sun.javadoc.ClassDoc
    44  * @author Atul M Dambalkar
    45  */
    46 public class ClassTree {
    48     /**
    49      * List of baseclasses. Contains only java.lang.Object. Can be used to get
    50      * the mapped listing of sub-classes.
    51      */
    52     private List<ClassDoc> baseclasses = new ArrayList<ClassDoc>();
    54     /**
    55     * Mapping for each Class with their SubClasses
    56     */
    57     private Map<ClassDoc,List<ClassDoc>> subclasses = new HashMap<ClassDoc,List<ClassDoc>>();
    59     /**
    60      * List of base-interfaces. Contains list of all the interfaces who do not
    61      * have super-interfaces. Can be used to get the mapped listing of
    62      * sub-interfaces.
    63      */
    64     private List<ClassDoc> baseinterfaces = new ArrayList<ClassDoc>();
    66     /**
    67     * Mapping for each Interface with their SubInterfaces
    68     */
    69     private Map<ClassDoc,List<ClassDoc>> subinterfaces = new HashMap<ClassDoc,List<ClassDoc>>();
    71     private List<ClassDoc> baseEnums = new ArrayList<ClassDoc>();
    72     private Map<ClassDoc,List<ClassDoc>> subEnums = new HashMap<ClassDoc,List<ClassDoc>>();
    74     private List<ClassDoc> baseAnnotationTypes = new ArrayList<ClassDoc>();
    75     private Map<ClassDoc,List<ClassDoc>> subAnnotationTypes = new HashMap<ClassDoc,List<ClassDoc>>();
    77     /**
    78     * Mapping for each Interface with classes who implement it.
    79     */
    80     private Map<ClassDoc,List<ClassDoc>> implementingclasses = new HashMap<ClassDoc,List<ClassDoc>>();
    82     /**
    83      * Constructor. Build the Tree using the Root of this Javadoc run.
    84      *
    85      * @param configuration the configuration of the doclet.
    86      * @param noDeprecated Don't add deprecated classes in the class tree, if
    87      * true.
    88      */
    89     public ClassTree(Configuration configuration, boolean noDeprecated) {
    90         configuration.message.notice("doclet.Building_Tree");
    91         buildTree(configuration.root.classes(), configuration);
    92     }
    94     /**
    95      * Constructor. Build the Tree using the Root of this Javadoc run.
    96      *
    97      * @param root Root of the Document.
    98      * @param configuration The curren configuration of the doclet.
    99      */
   100     public ClassTree(RootDoc root, Configuration configuration) {
   101         buildTree(root.classes(), configuration);
   102     }
   104     /**
   105      * Constructor. Build the tree for the given array of classes.
   106      *
   107      * @param classes Array of classes.
   108      * @param configuration The curren configuration of the doclet.
   109      */
   110     public ClassTree(ClassDoc[] classes, Configuration configuration) {
   111         buildTree(classes, configuration);
   112     }
   114     /**
   115      * Generate mapping for the sub-classes for every class in this run.
   116      * Return the sub-class list for java.lang.Object which will be having
   117      * sub-class listing for itself and also for each sub-class itself will
   118      * have their own sub-class lists.
   119      *
   120      * @param classes all the classes in this run.
   121      * @param configuration the current configuration of the doclet.
   122      */
   123     private void buildTree(ClassDoc[] classes, Configuration configuration) {
   124         for (int i = 0; i < classes.length; i++) {
   125             if (configuration.nodeprecated &&
   126                     classes[i].tags("deprecated").length > 0) {
   127                 continue;
   128             }
   129             if (classes[i].isEnum()) {
   130                 processType(classes[i], configuration, baseEnums, subEnums);
   131             } else if (classes[i].isClass()) {
   132                 processType(classes[i], configuration, baseclasses, subclasses);
   133             } else if (classes[i].isInterface()) {
   134                 processInterface(classes[i]);
   135                 List<ClassDoc> list = implementingclasses.get(classes[i]);
   136                 if (list != null) {
   137                     Collections.sort(list);
   138                 }
   139             } else if (classes[i].isAnnotationType()) {
   140                 processType(classes[i], configuration, baseAnnotationTypes,
   141                     subAnnotationTypes);
   142             }
   143         }
   145         Collections.sort(baseinterfaces);
   146         for (Iterator<List<ClassDoc>> it = subinterfaces.values().iterator(); it.hasNext(); ) {
   147             Collections.sort(it.next());
   148         }
   149         for (Iterator<List<ClassDoc>> it = subclasses.values().iterator(); it.hasNext(); ) {
   150             Collections.sort(it.next());
   151         }
   152     }
   154     /**
   155      * For the class passed map it to it's own sub-class listing.
   156      * For the Class passed, get the super class,
   157      * if superclass is non null, (it is not "java.lang.Object")
   158      *    get the "value" from the hashmap for this key Class
   159      *    if entry not found create one and get that.
   160      *    add this Class as a sub class in the list
   161      *    Recurse till hits java.lang.Object Null SuperClass.
   162      *
   163      * @param cd class for which sub-class mapping to be generated.
   164      * @param configuration the current configurtation of the doclet.
   165      */
   166     private void processType(ClassDoc cd, Configuration configuration,
   167             List<ClassDoc> bases, Map<ClassDoc,List<ClassDoc>> subs) {
   168         ClassDoc superclass = Util.getFirstVisibleSuperClassCD(cd, configuration);
   169         if (superclass != null) {
   170             if (!add(subs, superclass, cd)) {
   171                 return;
   172             } else {
   173                 processType(superclass, configuration, bases, subs);
   174             }
   175         } else {     // cd is java.lang.Object, add it once to the list
   176             if (!bases.contains(cd)) {
   177                 bases.add(cd);
   178             }
   179         }
   180         List intfacs = Util.getAllInterfaces(cd, configuration);
   181         for (Iterator iter = intfacs.iterator(); iter.hasNext();) {
   182             add(implementingclasses, ((Type) iter.next()).asClassDoc(), cd);
   183         }
   184     }
   186     /**
   187      * For the interface passed get the interfaces which it extends, and then
   188      * put this interface in the sub-interface list of those interfaces. Do it
   189      * recursively. If a interface doesn't have super-interface just attach
   190      * that interface in the list of all the baseinterfaces.
   191      *
   192      * @param cd Interface under consideration.
   193      */
   194     private void processInterface(ClassDoc cd) {
   195         ClassDoc[] intfacs = cd.interfaces();
   196         if (intfacs.length > 0) {
   197             for (int i = 0; i < intfacs.length; i++) {
   198                 if (!add(subinterfaces, intfacs[i], cd)) {
   199                     return;
   200                 } else {
   201                     processInterface(intfacs[i]);   // Recurse
   202                 }
   203             }
   204         } else {
   205             // we need to add all the interfaces who do not have
   206             // super-interfaces to baseinterfaces list to traverse them
   207             if (!baseinterfaces.contains(cd)) {
   208                 baseinterfaces.add(cd);
   209             }
   210         }
   211     }
   213     /**
   214      * Adjust the Class Tree. Add the class interface  in to it's super-class'
   215      * or super-interface's sub-interface list.
   216      *
   217      * @param map the entire map.
   218      * @param superclass java.lang.Object or the super-interface.
   219      * @param cd sub-interface to be mapped.
   220      * @returns boolean true if class added, false if class already processed.
   221      */
   222     private boolean add(Map<ClassDoc,List<ClassDoc>> map, ClassDoc superclass, ClassDoc cd) {
   223         List<ClassDoc> list = map.get(superclass);
   224         if (list == null) {
   225             list = new ArrayList<ClassDoc>();
   226             map.put(superclass, list);
   227         }
   228         if (list.contains(cd)) {
   229             return false;
   230         } else {
   231             list.add(cd);
   232         }
   233         return true;
   234     }
   236     /**
   237      * From the map return the list of sub-classes or sub-interfaces. If list
   238      * is null create a new one and return it.
   239      *
   240      * @param map The entire map.
   241      * @param cd class for which the sub-class list is requested.
   242      * @returns List Sub-Class list for the class passed.
   243      */
   244     private List<ClassDoc> get(Map<ClassDoc,List<ClassDoc>> map, ClassDoc cd) {
   245         List<ClassDoc> list = map.get(cd);
   246         if (list == null) {
   247             return new ArrayList<ClassDoc>();
   248         }
   249         return list;
   250     }
   252     /**
   253      *  Return the sub-class list for the class passed.
   254      *
   255      * @param cd class whose sub-class list is required.
   256      */
   257     public List<ClassDoc> subclasses(ClassDoc cd) {
   258         return get(subclasses, cd);
   259     }
   261     /**
   262      *  Return the sub-interface list for the interface passed.
   263      *
   264      * @param cd interface whose sub-interface list is required.
   265      */
   266     public List<ClassDoc> subinterfaces(ClassDoc cd) {
   267         return get(subinterfaces, cd);
   268     }
   270     /**
   271      *  Return the list of classes which implement the interface passed.
   272      *
   273      * @param cd interface whose implementing-classes list is required.
   274      */
   275     public List<ClassDoc> implementingclasses(ClassDoc cd) {
   276         List<ClassDoc> result = get(implementingclasses, cd);
   277         List<ClassDoc> subinterfaces = allSubs(cd, false);
   279         //If class x implements a subinterface of cd, then it follows
   280         //that class x implements cd.
   281         Iterator implementingClassesIter, subInterfacesIter = subinterfaces.listIterator();
   282         ClassDoc c;
   283         while(subInterfacesIter.hasNext()){
   284             implementingClassesIter = implementingclasses((ClassDoc)
   285                     subInterfacesIter.next()).listIterator();
   286             while(implementingClassesIter.hasNext()){
   287                 c = (ClassDoc)implementingClassesIter.next();
   288                 if(! result.contains(c)){
   289                     result.add(c);
   290                 }
   291             }
   292         }
   293         Collections.sort(result);
   294         return result;
   295     }
   297     /**
   298      *  Return the sub-class/interface list for the class/interface passed.
   299      *
   300      * @param cd class/interface whose sub-class/interface list is required.
   301      * @param isEnum true if the subclasses should be forced to come from the
   302      * enum tree.
   303      */
   304     public List<ClassDoc> subs(ClassDoc cd, boolean isEnum) {
   305         if (isEnum) {
   306             return get(subEnums, cd);
   307         } else if (cd.isAnnotationType()) {
   308             return get(subAnnotationTypes, cd);
   309         } else if (cd.isInterface()) {
   310             return get(subinterfaces, cd);
   311         } else if (cd.isClass()) {
   312             return get(subclasses, cd);
   313         } else {
   314             return null;
   315         }
   317     }
   319     /**
   320      * Return a list of all direct or indirect, sub-classes and subinterfaces
   321      * of the ClassDoc argument.
   322      *
   323      * @param cd ClassDoc whose sub-classes or sub-interfaces are requested.
   324      * @param isEnum true if the subclasses should be forced to come from the
   325      * enum tree.
   326      */
   327     public List<ClassDoc> allSubs(ClassDoc cd, boolean isEnum) {
   328         List<ClassDoc> list = subs(cd, isEnum);
   329         for (int i = 0; i < list.size(); i++) {
   330             cd = list.get(i);
   331             List tlist = subs(cd, isEnum);
   332             for (int j = 0; j < tlist.size(); j++) {
   333                 ClassDoc tcd = (ClassDoc)tlist.get(j);
   334                 if (!list.contains(tcd)) {
   335                     list.add(tcd);
   336                 }
   337             }
   338         }
   339         Collections.sort(list);
   340         return list;
   341     }
   343     /**
   344      *  Return the base-classes list. This will have only one element namely
   345      *  thw classdoc for java.lang.Object, since this is the base class for all
   346      *  classes.
   347      */
   348     public List baseclasses() {
   349         return baseclasses;
   350     }
   352     /**
   353      *  Return the list of base interfaces. This is the list of interfaces
   354      *  which do not have super-interface.
   355      */
   356     public List baseinterfaces() {
   357         return baseinterfaces;
   358     }
   360     /**
   361      *  Return the list of base enums. This is the list of enums
   362      *  which do not have super-enums.
   363      */
   364     public List baseEnums() {
   365         return baseEnums;
   366     }
   368     /**
   369      *  Return the list of base annotation types. This is the list of
   370      *  annotation types which do not have super-annotation types.
   371      */
   372     public List baseAnnotationTypes() {
   373         return baseAnnotationTypes;
   374     }
   375 }

mercurial