home *** CD-ROM | disk | FTP | other *** search
/ Internet News 1999 October / INEWS_10_CD.ISO / pc / jdk / jdk1.2.2 / docs / tooldocs / javadoc / source / ClassTree.java < prev    next >
Encoding:
Java Source  |  1999-09-19  |  9.3 KB  |  291 lines

  1. /*
  2.  * @(#)ClassTree.java    1.11 98/09/21
  3.  *
  4.  * Copyright 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package com.sun.tools.doclets;
  16.  
  17. import com.sun.javadoc.*;
  18. import java.io.*;
  19. import java.lang.*;
  20. import java.util.*;
  21.  
  22. /**
  23.  * Build Class Hierarchy for all the Classes. This class builds the Class
  24.  * Tree and the Interface Tree separately.
  25.  *
  26.  * @see java.util.HashMap
  27.  * @see java.util.List
  28.  * @see com.sun.javadoc.Type
  29.  * @see com.sun.javadoc.ClassDoc
  30.  * @author Atul M Dambalkar
  31.  */
  32. public class ClassTree { 
  33.     
  34.     /**
  35.      * List of baseclasses. Contains only java.lang.Object. Can be used to get
  36.      * the mapped listing of sub-classes.
  37.      */
  38.     private List baseclasses = new ArrayList();
  39.  
  40.     /** 
  41.     * Mapping for each Class with their SubClasses 
  42.     */
  43.     private Map subclasses = new HashMap();
  44.  
  45.     /**
  46.      * List of base-interfaces. Contains list of all the interfaces who do not
  47.      * have super-interfaces. Can be used to get the mapped listing of
  48.      * sub-interfaces.
  49.      */
  50.     private List baseinterfaces = new ArrayList();
  51.  
  52.     /** 
  53.     * Mapping for each Interface with their SubInterfaces 
  54.     */
  55.     private Map subinterfaces = new HashMap();
  56.  
  57.     /** 
  58.     * Mapping for each Interface with classes who implement it.
  59.     */
  60.     private Map implementingclasses = new HashMap();
  61.  
  62.     /**
  63.      * Constructor. Build the Tree using the Root of this Javadoc run.
  64.      * 
  65.      * @param root Root of the Document.
  66.      * @param noDeprecated Don't add deprecated classes in the class tree, if
  67.      * true.
  68.      */
  69.     public ClassTree(RootDoc root, boolean noDeprecated) {
  70.         Configuration.message.notice("doclet.Building_Tree");
  71.         buildTree(root.classes(), noDeprecated);
  72.     } 
  73.  
  74.     /**
  75.      * Constructor. Build the tree for the given array of classes.
  76.      *
  77.      * @param classes Array of classes.
  78.      * @param noDeprecated Don't add deprecated classes in the class tree, if
  79.      * true.
  80.      */
  81.     public ClassTree(ClassDoc[] classes, boolean noDeprecated) {
  82.         buildTree(classes, noDeprecated);
  83.     }
  84.         
  85.     /**
  86.      * Generate mapping for the sub-classes for every class in this run. 
  87.      * Return the sub-class list for java.lang.Object which will be having 
  88.      * sub-class listing for itself and also for each sub-class itself will
  89.      * have their own sub-class lists. 
  90.      *
  91.      * @param classes all the classes in this run.
  92.      * @param noDeprecated Don't add deprecated classes in the class tree, if
  93.      * true.
  94.      */
  95.     private void buildTree(ClassDoc[] classes, boolean noDeprecated) {
  96.         for (int i = 0; i < classes.length; i++) {
  97.             if (noDeprecated && classes[i].tags("deprecated").length > 0) {
  98.                 continue;
  99.             }
  100.             if (classes[i].isClass()) {
  101.                 processClass(classes[i]);
  102.             } else {    // this is an interface.
  103.                 processInterface(classes[i]);
  104.                 List list  = (List)implementingclasses.get(classes[i]);
  105.                 if (list != null) {
  106.                     Collections.sort(list);
  107.                 }
  108.             }
  109.         }
  110.  
  111.         Collections.sort(baseinterfaces);
  112.         for (Iterator it = subinterfaces.values().iterator(); it.hasNext(); ) {
  113.             Collections.sort((List)it.next());
  114.         }
  115.         for (Iterator it = subclasses.values().iterator(); it.hasNext(); ) {
  116.             Collections.sort((List)it.next());
  117.         }
  118.     }
  119.  
  120.     /**
  121.      * For the class passed map it to it's own sub-class listing.
  122.      * For the Class passed, get the super class, 
  123.      * if superclass is non null, (it is not "java.lang.Object")
  124.      *    get the "value" from the hashmap for this key Class
  125.      *    if entry not found create one and get that.
  126.      *    add this Class as a sub class in the list 
  127.      *    Recurse till hits java.lang.Object Null SuperClass.
  128.      * 
  129.      * @param cd class for which sub-class mapping to be generated. 
  130.      */
  131.     private void processClass(ClassDoc cd) {
  132.         ClassDoc superclass = cd.superclass();      
  133.         if (superclass != null) {   
  134.             if (!add(subclasses, superclass, cd)) {
  135.                 return;
  136.             } else {
  137.                 processClass(superclass);      // Recurse
  138.             }
  139.         } else {     // cd is java.lang.Object, add it once to the list 
  140.             if (!baseclasses.contains(cd)) {
  141.                 baseclasses.add(cd);
  142.             }
  143.         } 
  144.         ClassDoc[] intfacs = cd.interfaces();
  145.         for (int i = 0; i < intfacs.length; i++) {
  146.             add(implementingclasses, intfacs[i], cd);    
  147.         }
  148.     }
  149.  
  150.     /**
  151.      * For the interface passed get the interfaces which it extends, and then
  152.      * put this interface in the sub-interface list of those interfaces. Do it
  153.      * recursively. If a interface doesn't have super-interface just attach
  154.      * that interface in the list of all the baseinterfaces.
  155.      *
  156.      * @param cd Interface under consideration.
  157.      */
  158.     private void processInterface(ClassDoc cd) {
  159.         ClassDoc[] intfacs = cd.interfaces();
  160.         if (intfacs.length > 0) {
  161.             for (int i = 0; i < intfacs.length; i++) {
  162.                 if (!add(subinterfaces, intfacs[i], cd)) {
  163.                     return;
  164.                 } else {
  165.                     processInterface(intfacs[i]);   // Recurse
  166.                 }
  167.             }
  168.         } else {   
  169.             // we need to add all the interfaces who do not have
  170.             // super-interfaces to baseinterfaces list to traverse them
  171.             if (!baseinterfaces.contains(cd)) {
  172.                 baseinterfaces.add(cd);
  173.             }
  174.         }
  175.     }
  176.  
  177.     /**
  178.      * Adjust the Class Tree. Add the class interface  in to it's super-class' 
  179.      * or super-interface's sub-interface list.
  180.      *
  181.      * @param map the entire map.
  182.      * @param superclass java.lang.Object or the super-interface.
  183.      * @param cd sub-interface to be mapped.
  184.      * @returns boolean true if class added, false if class already processed.
  185.      */
  186.     private boolean add(Map map, ClassDoc superclass, ClassDoc cd) {
  187.         List list = (List)map.get(superclass);
  188.         if (list == null) {
  189.             list = new ArrayList();
  190.             map.put(superclass, list); 
  191.         }     
  192.         if (list.contains(cd)) {
  193.             return false; 
  194.         } else {
  195.             list.add(cd);
  196.         }
  197.         return true;
  198.     }    
  199.  
  200.     /** 
  201.      * From the map return the list of sub-classes or sub-interfaces. If list
  202.      * is null create a new one and return it.
  203.      *
  204.      * @param map The entire map.
  205.      * @param cd class for which the sub-class list is requested.
  206.      * @returns List Sub-Class list for the class passed.
  207.      */
  208.     private List get(Map map, ClassDoc cd) {
  209.         List list = (List)map.get(cd);
  210.         if (list == null) {
  211.             return new ArrayList();
  212.         }
  213.         return list;
  214.     }
  215.  
  216.     /**
  217.      *  Return the sub-class list for the class passed.
  218.      *
  219.      * @param cd class whose sub-class list is required.
  220.      */ 
  221.     public List subclasses(ClassDoc cd) {
  222.         return get(subclasses, cd);
  223.     }
  224.  
  225.     /**
  226.      *  Return the sub-interface list for the interface passed.
  227.      *
  228.      * @param cd interface whose sub-interface list is required.
  229.      */ 
  230.     public List subinterfaces(ClassDoc cd) {
  231.         return get(subinterfaces, cd);
  232.     }
  233.  
  234.     /**
  235.      *  Return the list of classes which implement the interface passed.
  236.      *
  237.      * @param cd interface whose implementing-classes list is required.
  238.      */ 
  239.     public List implementingclasses(ClassDoc cd) {
  240.         return get(implementingclasses, cd);
  241.     }
  242.  
  243.     /**
  244.      *  Return the sub-class/interface list for the class/interface passed.
  245.      *
  246.      * @param cd class/interface whose sub-class/interface list is required.
  247.      */ 
  248.     public List subs(ClassDoc cd) {
  249.         return get(cd.isInterface()? subinterfaces: subclasses, cd);
  250.     }
  251.  
  252.     /**
  253.      * Return a list of all direct or indirect, sub-classes and subinterfaces
  254.      * of the ClassDoc argument.
  255.      * 
  256.      * @param cd ClassDoc whose sub-classes or sub-interfaces are requested.
  257.      */ 
  258.     public List allSubs(ClassDoc cd) {
  259.         List list = get(cd.isInterface()? subinterfaces: subclasses, cd);
  260.         for (int i = 0; i < list.size(); i++) {
  261.             cd = (ClassDoc)list.get(i);
  262.             List tlist = get(cd.isInterface()? subinterfaces: subclasses, cd);
  263.             for (int j = 0; j < tlist.size(); j++) {
  264.                 ClassDoc tcd = (ClassDoc)tlist.get(j); 
  265.                 if (!list.contains(tcd)) {
  266.                     list.add(tcd);
  267.                 }
  268.             }
  269.         }
  270.         Collections.sort(list);
  271.         return list; 
  272.     }
  273.  
  274.     /**
  275.      *  Return the base-classes list. This will have only one element namely
  276.      *  thw classdoc for java.lang.Object, since this is the base class for all
  277.      *  classes.
  278.      */ 
  279.     public List baseclasses() {
  280.         return baseclasses;
  281.     }
  282.  
  283.     /**
  284.      *  Return the list of base interfaces. This is the list of interfaces
  285.      *  which do not have super-interface.
  286.      */ 
  287.     public List baseinterfaces() {
  288.         return baseinterfaces;
  289.     }
  290. }
  291.