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

  1. /*
  2.  * @(#)ClassUseMapper.java    1.2 98/06/30
  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.standard;
  16.  
  17. import com.sun.javadoc.*;
  18. import com.sun.tools.doclets.ClassTree;
  19. import com.sun.tools.doclets.DocletAbortException;
  20. import java.util.*;
  21.  
  22. /**
  23.  * @since JDK1.2
  24.  * @author Robert G. Field
  25.  */
  26. public class ClassUseMapper {
  27.  
  28.     private final ClassTree classtree;
  29.  
  30.     /**
  31.      * Mapping of ClassDocs to set of PackageDoc used by that class.
  32.      * Entries may be null.
  33.      */
  34.     public Map classToPackage = new HashMap();
  35.  
  36.     /**
  37.      * Mapping of ClassDocs to set of ClassDoc used by that class.
  38.      * Entries may be null.
  39.      */
  40.     public Map classToClass = new HashMap();
  41.  
  42.     /**
  43.      * Mapping of ClassDocs to list of ClassDoc which are direct or 
  44.      * indirect subclasses of that class.
  45.      * Entries may be null.
  46.      */
  47.     public Map classToSubclass = new HashMap();
  48.  
  49.     /**
  50.      * Mapping of ClassDocs to list of ClassDoc which are direct or 
  51.      * indirect subinterfaces of that interface.
  52.      * Entries may be null.
  53.      */
  54.     public Map classToSubinterface = new HashMap();
  55.  
  56.     /**
  57.      * Mapping of ClassDocs to list of ClassDoc which implement
  58.      * this interface.
  59.      * Entries may be null.
  60.      */
  61.     public Map classToImplementingClass = new HashMap();
  62.  
  63.     /**
  64.      * Mapping of ClassDocs to list of FieldDoc declared as that class.
  65.      * Entries may be null.
  66.      */
  67.     public Map classToField = new HashMap();
  68.  
  69.     /**
  70.      * Mapping of ClassDocs to list of MethodDoc returning that class.
  71.      * Entries may be null.
  72.      */
  73.     public Map classToMethodReturn = new HashMap();
  74.  
  75.     /**
  76.      * Mapping of ClassDocs to list of MethodDoc having that class
  77.      * as an arg.
  78.      * Entries may be null.
  79.      */
  80.     public Map classToMethodArgs = new HashMap();
  81.  
  82.     /**
  83.      * Mapping of ClassDocs to list of MethodDoc which throws that class.
  84.      * Entries may be null.
  85.      */
  86.     public Map classToMethodThrows = new HashMap();
  87.  
  88.     /**
  89.      * Mapping of ClassDocs to list of ConstructorDoc having that class
  90.      * as an arg.
  91.      * Entries may be null.
  92.      */
  93.     public Map classToConstructorArgs = new HashMap();
  94.  
  95.     /**
  96.      * Mapping of ClassDocs to list of ConstructorDoc which throws that class.
  97.      * Entries may be null.
  98.      */
  99.     public Map classToConstructorThrows = new HashMap();
  100.  
  101.  
  102.     /**
  103.      * Write out class use pages.
  104.      */
  105.     public static void generate(RootDoc root, 
  106.                        ClassTree classtree) throws DocletAbortException {
  107.         ClassUseMapper mapper = new ClassUseMapper(root, classtree);
  108.         ClassDoc[] classes = root.classes();
  109.         for (int i = 0; i < classes.length; i++) {
  110.             ClassUseWriter.generate(mapper, classes[i]);
  111.         }
  112.         PackageDoc[] pkgs = Standard.configuration().packages;
  113.         for (int i = 0; i < pkgs.length; i++) {
  114.             PackageUseWriter.generate(mapper, pkgs[i]);
  115.         }
  116.     }
  117.  
  118.     private ClassUseMapper(RootDoc root, ClassTree classtree) {
  119.         this.classtree = classtree;
  120.  
  121.         // Map subclassing, subinterfacing implementing, ...
  122.         for (Iterator it = classtree.baseclasses().iterator(); it.hasNext();) {
  123.         subclasses((ClassDoc)it.next());
  124.     }
  125.         for (Iterator it = classtree.baseinterfaces().iterator(); it.hasNext();) {
  126.         // does subinterfacing as side-effect
  127.         implementingClasses((ClassDoc)it.next());
  128.     }
  129.     // Map methods, fields, constructors using a class.
  130.         ClassDoc[] classes = root.classes();
  131.         for (int i = 0; i < classes.length; i++) {
  132.             ClassDoc cd = classes[i];
  133.             FieldDoc[] fields = cd.fields();
  134.             for (int j = 0; j < fields.length; j++) {
  135.                 FieldDoc fd = fields[j];
  136.                 ClassDoc tcd = fd.type().asClassDoc();
  137.                 if (tcd != null) {
  138.                     add(classToField, tcd, fd);
  139.                 }
  140.             }
  141.             ConstructorDoc[] cons = cd.constructors();
  142.             for (int j = 0; j < cons.length; j++) {
  143.                 mapExecutable(cons[j]);
  144.             }
  145.             MethodDoc[] meths = cd.methods();
  146.             for (int j = 0; j < meths.length; j++) {
  147.                 MethodDoc md = meths[j];
  148.                 mapExecutable(md);
  149.                 ClassDoc tcd = md.returnType().asClassDoc();
  150.                 if (tcd != null) {
  151.                     add(classToMethodReturn, tcd, md);
  152.                 }
  153.             }
  154.         }
  155.     }
  156.  
  157.     /**
  158.      * Return all subclasses of a class AND fill-in classToSubclass map.
  159.      */
  160.     private Collection subclasses(ClassDoc cd) {
  161.         Collection ret = (Collection)classToSubclass.get(cd);
  162.     if (ret == null) {
  163.         ret = new TreeSet();
  164.         List subs = classtree.subclasses(cd);
  165.         if (subs != null) {
  166.             ret.addAll(subs);
  167.         for (Iterator it = subs.iterator(); it.hasNext();) {
  168.             ret.addAll(subclasses((ClassDoc)it.next()));
  169.         }
  170.         }
  171.         addAll(classToSubclass, cd, ret);
  172.     }
  173.     return ret;
  174.     }
  175.         
  176.     /**
  177.      * Return all subinterfaces of an interface AND fill-in classToSubinterface map.
  178.      */
  179.     private Collection subinterfaces(ClassDoc cd) {
  180.         Collection ret = (Collection)classToSubinterface.get(cd);
  181.     if (ret == null) {
  182.         ret = new TreeSet();
  183.         List subs = classtree.subinterfaces(cd);
  184.         if (subs != null) {
  185.             ret.addAll(subs);
  186.         for (Iterator it = subs.iterator(); it.hasNext();) {
  187.             ret.addAll(subinterfaces((ClassDoc)it.next()));
  188.         }
  189.         }
  190.         addAll(classToSubinterface, cd, ret);
  191.     }
  192.     return ret;
  193.     }
  194.         
  195.     /**
  196.      * Return all implementing classes of an interface (including
  197.      * all subclasses of implementing classes and all classes 
  198.      * implementing subinterfaces) AND fill-in both classToImplementingClass 
  199.      * and classToSubinterface maps.
  200.      */
  201.     private Collection implementingClasses(ClassDoc cd) {
  202.         Collection ret = (List)classToImplementingClass.get(cd);
  203.     if (ret == null) {
  204.         ret = new TreeSet();
  205.         List impl = classtree.implementingclasses(cd);
  206.         if (impl != null) {
  207.             ret.addAll(impl);
  208.             for (Iterator it = impl.iterator(); it.hasNext();) {
  209.             ret.addAll(subclasses((ClassDoc)it.next()));
  210.         }
  211.         }
  212.         for (Iterator it = subinterfaces(cd).iterator(); it.hasNext();) {
  213.             ret.addAll(implementingClasses((ClassDoc)it.next()));
  214.         }
  215.         addAll(classToImplementingClass, cd, ret);
  216.     }
  217.     return ret;
  218.     }
  219.         
  220.     /**
  221.      * Determine classes used by a method or constructor, so they can be
  222.      * inverse mapped.
  223.      */
  224.     private void mapExecutable(ExecutableMemberDoc em) {
  225.         Parameter[] params = em.parameters();
  226.         boolean isConstructor = em.isConstructor();
  227.         List classArgs = new ArrayList();
  228.         for (int k = 0; k < params.length; k++) {
  229.             ClassDoc pcd = params[k].type().asClassDoc();
  230.             // primitives don't get mapped, also avoid dups
  231.             if (pcd != null && !classArgs.contains(pcd)) {
  232.                 add(isConstructor? classToConstructorArgs :classToMethodArgs,
  233.                     pcd, em);
  234.                 classArgs.add(pcd);
  235.             }
  236.         }
  237.         ClassDoc[] thr = em.thrownExceptions();
  238.         for (int k = 0; k < thr.length; k++) {
  239.             add(isConstructor? classToConstructorThrows : classToMethodThrows, 
  240.                 thr[k], em);
  241.         }        
  242.     }
  243.  
  244.     private List refList(Map map, ClassDoc cd) {
  245.         List list = (List)map.get(cd);
  246.         if (list == null) {
  247.             list = new ArrayList();
  248.             map.put(cd, list);
  249.         }
  250.         return list;
  251.     }
  252.  
  253.     private Set packageSet(ClassDoc cd) {
  254.     Set pkgSet = (Set)classToPackage.get(cd);
  255.         if (pkgSet == null) {
  256.             pkgSet = new TreeSet();
  257.             classToPackage.put(cd, pkgSet);
  258.         }
  259.         return pkgSet;
  260.     }
  261.  
  262.     private Set classSet(ClassDoc cd) {
  263.     Set clsSet = (Set)classToClass.get(cd);
  264.         if (clsSet == null) {
  265.             clsSet = new TreeSet();
  266.             classToClass.put(cd, clsSet);
  267.         }
  268.         return clsSet;
  269.     }
  270.  
  271.     private void add(Map map, ClassDoc cd, ProgramElementDoc ref) {
  272.      // add to specified map
  273.         refList(map, cd).add(ref);
  274.  
  275.     // add ref's package to package map and class map
  276.     packageSet(cd).add(ref.containingPackage());
  277.         classSet(cd).add(ref instanceof MemberDoc? 
  278.                          ((MemberDoc)ref).containingClass() :
  279.                          ref);
  280.     }
  281.  
  282.     private void addAll(Map map, ClassDoc cd, Collection refs) {
  283.         if (refs == null) {
  284.         return;
  285.     }
  286.     // add to specified map
  287.         refList(map, cd).addAll(refs);
  288.  
  289.     Set pkgSet = packageSet(cd);
  290.     Set clsSet = classSet(cd);
  291.     // add ref's package to package map and class map
  292.     for (Iterator it = refs.iterator(); it.hasNext();) {
  293.             ProgramElementDoc pedoc = (ProgramElementDoc)it.next();
  294.         pkgSet.add(pedoc.containingPackage());
  295.             clsSet.add(pedoc instanceof MemberDoc? 
  296.                        ((MemberDoc)pedoc).containingClass() :
  297.                        pedoc);
  298.     }
  299.     }
  300. }
  301.