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

Tue, 09 Oct 2012 19:10:00 -0700

author
jjg
date
Tue, 09 Oct 2012 19:10:00 -0700
changeset 1357
c75be5bc5283
parent 995
62bc3775d5bb
child 1359
25e14ad23cef
permissions
-rw-r--r--

8000663: clean up langtools imports
Reviewed-by: darcy

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

mercurial