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

Sun, 24 Feb 2013 11:36:58 -0800

author
jjg
date
Sun, 24 Feb 2013 11:36:58 -0800
changeset 1606
ccbe7ffdd867
parent 1359
25e14ad23cef
child 2525
2eb010b6cb22
permissions
-rw-r--r--

7112427: The doclet needs to be able to generate JavaFX documentation.
Reviewed-by: jjg
Contributed-by: jan.valenta@oracle.com

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

mercurial