OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [tools/] [gnu/] [classpath/] [tools/] [doclets/] [AbstractDoclet.java] - Rev 779

Compare with Previous | Blame | View Log

/* gnu.classpath.tools.doclets.AbstractDoclet
   Copyright (C) 2004 Free Software Foundation, Inc.
 
This file is part of GNU Classpath.
 
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
 
Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
 
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */
 
package gnu.classpath.tools.doclets;
 
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.ConstructorDoc;
import com.sun.javadoc.Doc;
import com.sun.javadoc.Doclet;
import com.sun.javadoc.ExecutableMemberDoc;
import com.sun.javadoc.FieldDoc;
import com.sun.javadoc.MethodDoc;
import com.sun.javadoc.PackageDoc;
import com.sun.javadoc.Parameter;
import com.sun.javadoc.RootDoc;
import com.sun.javadoc.Tag;
import com.sun.javadoc.Type;
 
import com.sun.tools.doclets.Taglet;
 
import gnu.classpath.tools.taglets.GnuExtendedTaglet;
import gnu.classpath.tools.taglets.AuthorTaglet;
import gnu.classpath.tools.taglets.CodeTaglet;
import gnu.classpath.tools.taglets.DeprecatedTaglet;
import gnu.classpath.tools.taglets.GenericTaglet;
import gnu.classpath.tools.taglets.SinceTaglet;
import gnu.classpath.tools.taglets.ValueTaglet;
import gnu.classpath.tools.taglets.VersionTaglet;
import gnu.classpath.tools.taglets.TagletContext;
 
import gnu.classpath.tools.IOToolkit;
import gnu.classpath.tools.FileSystemClassLoader;
 
import java.io.File;
import java.io.IOException;
 
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.InvocationTargetException;
 
import java.text.MessageFormat;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.SortedSet;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
 
/**
 *  An abstract Doclet implementation with helpers for common tasks
 *  performed by Doclets.
 */
public abstract class AbstractDoclet
{
   /**
    *  Mapping from tag type to Taglet for user Taglets specified on
    *  the command line.
    */
   protected Map tagletMap = new LinkedHashMap();
 
   /**
    *  Stores the package groups specified in the user
    *  options. Contains objects of type PackageGroup.
    */
   private List packageGroups = new LinkedList();
 
   /**
    *  The current classpath for loading taglet classes.
    */
   private String tagletPath;
 
   /**
    *  Keeps track of the tags mentioned by the user during option
    *  processiong so that an error can be emitted if a tag is
    *  mentioned more than once.
    */
   private List mentionedTags = new LinkedList();
 
   public static int optionLength(String option) {
      return instance.getOptionLength(option);
   }
 
   public static boolean validOptions(String[][] options) {
      return true;
   }
 
   private static AbstractDoclet instance;
 
   protected static void setInstance(AbstractDoclet instance)
   {
      AbstractDoclet.instance = instance;
   }
 
   protected abstract void run()
      throws DocletConfigurationException, IOException;
 
   public static boolean start(RootDoc rootDoc)
   {
      try {
 
         instance.startInstance(rootDoc);
         return true;
      }
      catch (DocletConfigurationException e) {
         instance.printError(e.getMessage());
         return false;
      }
      catch (Exception e) {
         e.printStackTrace();
         return false;
      }
   }
 
   protected RootDoc getRootDoc()
   {
      return this.rootDoc;
   }
 
   private RootDoc rootDoc;
 
   protected abstract InlineTagRenderer getInlineTagRenderer();
 
   private void startInstance(RootDoc rootDoc)
      throws DocletConfigurationException, IOException
   {
      this.rootDoc = rootDoc;
 
      // Set the default Taglet order
 
      registerTaglet(new VersionTaglet());
      registerTaglet(new AuthorTaglet());
      registerTaglet(new SinceTaglet(getInlineTagRenderer()));
      registerTaglet(new StandardTaglet("serial"));
      registerTaglet(new StandardTaglet("deprecated"));
      registerTaglet(new StandardTaglet("see"));
      registerTaglet(new StandardTaglet("param"));
      registerTaglet(new StandardTaglet("return"));
 
      registerTaglet(new ValueTaglet());
      registerTaglet(new CodeTaglet());
 
      // Process command line options
 
      for (int i=0, ilim=rootDoc.options().length; i<ilim; ++i) {
 
         String[] optionArr = rootDoc.options()[i];
         String _optionTag = optionArr[0];
 
         DocletOption option = (DocletOption)nameToOptionMap.get(_optionTag.toLowerCase());
 
         if (null != option) {
            option.set(optionArr);
         }
      }
 
      // Enable/disable standard taglets based on user input
 
      AuthorTaglet.setTagletEnabled(optionAuthor.getValue());
      VersionTaglet.setTagletEnabled(optionVersion.getValue());
      SinceTaglet.setTagletEnabled(!optionNoSince.getValue());
      DeprecatedTaglet.setTagletEnabled(!optionNoDeprecated.getValue());
 
      if (!getTargetDirectory().exists()) {
         if (!getTargetDirectory().mkdirs()) {
            throw new DocletConfigurationException("Cannot create target directory "
                                                   + getTargetDirectory());
         }
      }
 
      run();
   }
 
   public File getTargetDirectory()
   {
      return optionTargetDirectory.getValue();
   }
 
   private DocletOptionFile optionTargetDirectory =
     new DocletOptionFile("-d",
                          new File(System.getProperty("user.dir")));
 
   private DocletOptionFlag optionNoEmailWarn =
     new DocletOptionFlag("-noemailwarn");
 
   private DocletOptionFlag optionAuthor =
     new DocletOptionFlag("-author");
 
   private DocletOptionFlag optionVersion =
     new DocletOptionFlag("-version");
 
   private DocletOptionFlag optionNoSince =
     new DocletOptionFlag("-nosince");
 
   private DocletOptionFlag optionNoDeprecated =
     new DocletOptionFlag("-nodeprecated");
 
   private DocletOptionGroup optionGroup =
     new DocletOptionGroup("-group");
 
   private DocletOptionPackageWildcard optionNoQualifier =
     new DocletOptionPackageWildcard("-noqualifier", true);
 
   private DocletOptionFlag optionDocFilesSubDirs =
     new DocletOptionFlag("-docfilessubdirs");
 
   private DocletOptionColonSeparated optionExcludeDocFilesSubDir =
     new DocletOptionColonSeparated("-excludedocfilessubdir");
 
   private DocletOptionTagletPath optionTagletPath =
     new DocletOptionTagletPath("-tagletpath");
 
   private DocletOptionTag optionTaglet =
     new DocletOptionTag("-taglet");
 
   private DocletOptionTag optionTag =
     new DocletOptionTag("-tag");
 
   private class DocletOptionTaglet
      extends DocletOption
   {
      DocletOptionTaglet(String optionName)
      {
         super(optionName);
      }
 
      public int getLength()
      {
         return 2;
      }
 
      public boolean set(String[] optionArr)
      {
 
         boolean tagletLoaded = false;
 
         String useTagletPath = AbstractDoclet.this.tagletPath;
         if (null == useTagletPath) {
            useTagletPath = System.getProperty("java.class.path");
         }
 
         try {
            Class tagletClass;
            try {
               tagletClass
                  = new FileSystemClassLoader(useTagletPath).loadClass(optionArr[1]);
            }
            catch (ClassNotFoundException e) {
               // If not found on specified tagletpath, try default classloader
               tagletClass
                  = Class.forName(optionArr[1]);
            }
            Method registerTagletMethod
               = tagletClass.getDeclaredMethod("register", new Class[] { java.util.Map.class });
 
            if (!registerTagletMethod.getReturnType().equals(Void.TYPE)) {
               printError("Taglet class '" + optionArr[1] + "' found, but register method doesn't return void.");
            }
            else if (registerTagletMethod.getExceptionTypes().length > 0) {
               printError("Taglet class '" + optionArr[1] + "' found, but register method contains throws clause.");
            }
            else if ((registerTagletMethod.getModifiers() & (Modifier.STATIC | Modifier.PUBLIC | Modifier.ABSTRACT)) != (Modifier.STATIC | Modifier.PUBLIC)) {
               printError("Taglet class '" + optionArr[1] + "' found, but register method isn't public static, or is abstract..");
            }
            else {
               Map tempMap = new HashMap();
               registerTagletMethod.invoke(null, new Object[] { tempMap });
               tagletLoaded = true;
               String name = (String)tempMap.keySet().iterator().next();
               Taglet taglet = (Taglet)tempMap.get(name);
               tagletMap.put(name, taglet);
               mentionedTags.add(taglet);
            }
         }
         catch (NoSuchMethodException e) {
            printError("Taglet class '" + optionArr[1] + "' found, but doesn't contain the register method.");
         }
         catch (SecurityException e) {
            printError("Taglet class '" + optionArr[1] + "' cannot be loaded: " + e.getMessage());
         }
         catch (InvocationTargetException e) {
            printError("Taglet class '" + optionArr[1] + "' found, but register method throws exception: " + e.toString());
         }
         catch (IllegalAccessException e) {
            printError("Taglet class '" + optionArr[1] + "' found, but there was a problem when accessing the register method: " + e.toString());
         }
         catch (IllegalArgumentException e) {
            printError("Taglet class '" + optionArr[1] + "' found, but there was a problem when accessing the register method: " + e.toString());
         }
         catch (ClassNotFoundException e) {
            printError("Taglet class '" + optionArr[1] + "' cannot be found.");
         }
         return tagletLoaded;
      }
   }
 
   private class DocletOptionGroup
      extends DocletOption
   {
      DocletOptionGroup(String optionName)
      {
         super(optionName);
      }
 
      public int getLength()
      {
         return 3;
      }
 
      public boolean set(String[] optionArr)
      {
         try {
            PackageMatcher packageMatcher = new PackageMatcher();
 
            StringTokenizer tokenizer = new StringTokenizer(optionArr[2], ":");
            while (tokenizer.hasMoreTokens()) {
               String packageWildcard = tokenizer.nextToken();
               packageMatcher.addWildcard(packageWildcard);
            }
 
            SortedSet groupPackages = packageMatcher.filter(rootDoc.specifiedPackages());
 
            packageGroups.add(new PackageGroup(optionArr[1], groupPackages));
 
            return true;
         }
         catch (InvalidPackageWildcardException e) {
            return false;
         }
      }
   }
 
 
   private class DocletOptionTagletPath
      extends DocletOption
   {
      DocletOptionTagletPath(String optionName)
      {
         super(optionName);
      }
 
      public int getLength()
      {
         return 2;
      }
 
      public boolean set(String[] optionArr)
      {
         AbstractDoclet.this.tagletPath = optionArr[1];
         return true;
      }
   }
 
   private class DocletOptionTag
      extends DocletOption
   {
      DocletOptionTag(String optionName)
      {
         super(optionName);
      }
 
      public int getLength()
      {
         return 2;
      }
 
      public boolean set(String[] optionArr)
      {
         String tagSpec = optionArr[1];
         boolean validTagSpec = false;
         int ndx1 = tagSpec.indexOf(':');
         if (ndx1 < 0) {
            Taglet taglet = (Taglet)tagletMap.get(tagSpec);
            if (null == taglet) {
               printError("There is no standard tag '" + tagSpec + "'.");
            }
            else {
               if (mentionedTags.contains(taglet)) {
                  printError("Tag '" + tagSpec + "' has been added or moved before.");
               }
               else {
                  mentionedTags.add(taglet);
 
                  // re-append taglet
                  tagletMap.remove(tagSpec);
                  tagletMap.put(tagSpec, taglet);
               }
            }
         }
         else {
            int ndx2 = tagSpec.indexOf(':', ndx1 + 1);
            if (ndx2 > ndx1 && ndx2 < tagSpec.length() - 1) {
               String tagName = tagSpec.substring(0, ndx1);
               String tagHead = null;
               if (tagSpec.charAt(ndx2 + 1) == '\"') {
                  if (tagSpec.charAt(tagSpec.length() - 1) == '\"') {
                     tagHead = tagSpec.substring(ndx2 + 2, tagSpec.length() - 1);
                     validTagSpec = true;
                  }
               }
               else {
                  tagHead = tagSpec.substring(ndx2 + 1);
                  validTagSpec = true;
               }
 
               boolean tagScopeOverview = false;
               boolean tagScopePackages = false;
               boolean tagScopeTypes = false;
               boolean tagScopeConstructors = false;
               boolean tagScopeMethods = false;
               boolean tagScopeFields = false;
               boolean tagDisabled = false;
 
            tag_option_loop:
               for (int n=ndx1+1; n<ndx2; ++n) {
                  switch (tagSpec.charAt(n)) {
                  case 'X':
                     tagDisabled = true;
                     break;
                  case 'a':
                     tagScopeOverview = true;
                     tagScopePackages = true;
                     tagScopeTypes = true;
                     tagScopeConstructors = true;
                     tagScopeMethods = true;
                     tagScopeFields = true;
                     break;
                  case 'o':
                     tagScopeOverview = true;
                     break;
                  case 'p':
                     tagScopePackages = true;
                     break;
                  case 't':
                     tagScopeTypes = true;
                     break;
                  case 'c':
                     tagScopeConstructors = true;
                     break;
                  case 'm':
                     tagScopeMethods = true;
                     break;
                  case 'f':
                     tagScopeFields = true;
                     break;
                  default:
                     validTagSpec = false;
                     break tag_option_loop;
                  }
               }
 
               if (validTagSpec) {
                  GenericTaglet taglet
                     = new GenericTaglet(tagName,
                                         tagHead,
                                         tagScopeOverview,
                                         tagScopePackages,
                                         tagScopeTypes,
                                         tagScopeConstructors,
                                         tagScopeMethods,
                                         tagScopeFields);
                  taglet.setTagletEnabled(!tagDisabled);
                  taglet.register(tagletMap);
                  mentionedTags.add(taglet);
               }
            }
         }
         if (!validTagSpec) {
            printError("Value for option -tag must be in format \"<tagname>:Xaoptcmf:<taghead>\".");
         }
         return validTagSpec;
      }
   }
 
   private DocletOption[] commonOptions =
      {
         optionTargetDirectory,
         optionAuthor,
         optionVersion,
         optionNoSince,
         optionNoDeprecated,
         optionGroup,
         optionDocFilesSubDirs,
         optionExcludeDocFilesSubDir,
         optionTagletPath,
         optionTaglet,
         optionTag,
      };
 
   private void registerOptions()
   {
      if (!optionsRegistered) {
         for (int i=0; i<commonOptions.length; ++i) {
            DocletOption option = commonOptions[i];
            registerOption(option);
         }
         DocletOption[] docletOptions = getOptions();
         for (int i=0; i<docletOptions.length; ++i) {
            DocletOption option = docletOptions[i];
            registerOption(option);
         }
         optionsRegistered = true;
      }
   }
 
   protected abstract DocletOption[] getOptions();
 
   private boolean optionsRegistered = false;
 
   private void registerOption(DocletOption option)
   {
      nameToOptionMap.put(option.getName(), option);
   }
 
   private Map nameToOptionMap = new HashMap();
 
   private int getOptionLength(String optionName)
   {
      registerOptions();
      DocletOption option = (DocletOption)nameToOptionMap.get(optionName.toLowerCase());
      if (null != option) {
         return option.getLength();
      }
      else {
         return -1;
      }
   }
 
   protected List getKnownDirectSubclasses(ClassDoc classDoc)
   {
      List result = new LinkedList();
      if (!"java.lang.Object".equals(classDoc.qualifiedName())) {
         ClassDoc[] classes = rootDoc.classes();
         for (int i=0; i<classes.length; ++i) {
            if (classDoc == classes[i].superclass()) {
               result.add(classes[i]);
            }
         }
      }
      return result;
   }
 
   protected static class IndexKey
      implements Comparable
   {
      private String name;
      private String lowerName;
 
      public IndexKey(String name)
      {
         this.name = name;
         this.lowerName = name.toLowerCase();
      }
 
      public boolean equals(Object other)
      {
         return this.lowerName.equals(((IndexKey)other).lowerName);
      }
 
      public int hashCode()
      {
         return lowerName.hashCode();
      }
 
      public int compareTo(Object other)
      {
         return lowerName.compareTo(((IndexKey)other).lowerName);
      }
 
      public String getName()
      {
         return name;
      }
   }
 
   private Map categorizedIndex;
 
   protected Map getCategorizedIndex()
   {
      if (null == categorizedIndex) {
         categorizedIndex = new LinkedHashMap();
 
         Map indexMap = getIndexByName();
         LinkedList keys = new LinkedList(); //indexMap.keySet().size());
         keys.addAll(indexMap.keySet());
         Collections.sort(keys);
         Iterator it = keys.iterator(); //indexMap.keySet().iterator();
         char previousCategoryLetter = '\0';
         Character keyLetter = null;
         while (it.hasNext()) {
            IndexKey key = (IndexKey)it.next();
            char firstChar = Character.toUpperCase(key.getName().charAt(0));
            if (firstChar != previousCategoryLetter) {
               keyLetter = new Character(firstChar);
               previousCategoryLetter = firstChar;
               categorizedIndex.put(keyLetter, new LinkedList());
            }
            List letterList = (List)categorizedIndex.get(keyLetter);
            letterList.add(indexMap.get(key));
         }
      }
 
      return categorizedIndex;
   }
 
 
   private Map indexByName;
 
   protected Map getIndexByName()
   {
      if (null == indexByName) {
         // Create index
 
         // Collect index
 
         indexByName = new HashMap(); //TreeMap();
 
         // Add packages to index
 
         PackageDoc[] packages = rootDoc.specifiedPackages();
         for (int i=0, ilim=packages.length; i<ilim; ++i) {
            PackageDoc c = packages[i];
            if (c.name().length() > 0) {
               indexByName.put(new IndexKey(c.name()), c);
            }
         }
 
         // Add classes, fields and methods to index
 
         ClassDoc[] sumclasses = rootDoc.classes();
         for (int i=0, ilim=sumclasses.length; i<ilim; ++i) {
            ClassDoc c = sumclasses[i];
            if (null == c.containingClass()) {
               indexByName.put(new IndexKey(c.name() + " " + c.containingPackage().name()), c);
            }
            else {
               indexByName.put(new IndexKey(c.name().substring(c.containingClass().name().length() + 1)
                                            + " " + c.containingClass().name() + " " + c.containingPackage().name()), c);
            }
            FieldDoc[] fields = c.fields();
            for (int j=0, jlim=fields.length; j<jlim; ++j) {
               indexByName.put(new IndexKey(fields[j].name() + " " + fields[j].containingClass().name() + " " + fields[j].containingPackage().name()), fields[j]);
            }
            MethodDoc[] methods = c.methods();
            for (int j=0, jlim=methods.length; j<jlim; ++j) {
               MethodDoc method = methods[j];
               indexByName.put(new IndexKey(method.name() + method.signature() + " " + method.containingClass().name() + " " + method.containingPackage().name()), method);
            }
            ConstructorDoc[] constructors = c.constructors();
            for (int j=0, jlim=constructors.length; j<jlim; ++j) {
               ConstructorDoc constructor = constructors[j];
               indexByName.put(new IndexKey(constructor.name() + constructor.signature() + " " + constructor.containingClass().name() + " " + constructor.containingPackage().name()), constructor);
            }
         }
      }
      return indexByName;
   }
 
   private void registerTaglet(Taglet taglet)
   {
      tagletMap.put(taglet.getName(), taglet);
   }
 
   protected void printTaglets(Tag[] tags, TagletContext context, TagletPrinter output, boolean inline)
   {
      for (Iterator it = tagletMap.keySet().iterator(); it.hasNext(); ) {
         String tagName = (String)it.next();
         Object o = tagletMap.get(tagName);
         Taglet taglet = (Taglet)o;
         Doc doc = context.getDoc();
         if (inline == taglet.isInlineTag()
             && ((doc == null
                  && taglet.inOverview())
                 || (doc != null
                     && ((doc.isConstructor() && taglet.inConstructor())
                         || (doc.isField() && taglet.inField())
                         || (doc.isMethod() && taglet.inMethod())
                         || (doc instanceof PackageDoc && taglet.inPackage())
                         || ((doc.isClass() || doc.isInterface()) && taglet.inType()))))) {
 
            List tagsOfThisType = new LinkedList();
            for (int i=0; i<tags.length; ++i) {
               if (tags[i].name().substring(1).equals(tagName)) {
                  tagsOfThisType.add(tags[i]);
               }
            }
 
            Tag[] tagletTags = (Tag[])tagsOfThisType.toArray(new Tag[tagsOfThisType.size()]);
 
            String tagletString;
            if (taglet instanceof StandardTaglet) {
               tagletString = renderTag(tagName, tagletTags, context);
            }
            else if (taglet instanceof GnuExtendedTaglet) {
               tagletString = ((GnuExtendedTaglet)taglet).toString(tagletTags, context);
            }
            else {
               tagletString = taglet.toString(tagletTags);
            }
            if (null != tagletString) {
               output.printTagletString(tagletString);
            }
         }
      }
   }
 
   protected void printInlineTaglet(Tag tag, TagletContext context, TagletPrinter output)
   {
      Taglet taglet = (Taglet)tagletMap.get(tag.name().substring(1));
      if (null != taglet) {
         String tagletString;
         if (taglet instanceof GnuExtendedTaglet) {
            tagletString = ((GnuExtendedTaglet)taglet).toString(tag, context);
         }
         else {
            tagletString = taglet.toString(tag);
         }
         if (null != tagletString) {
            output.printTagletString(tagletString);
         }
      }
      else {
         printWarning("Unknown tag: " + tag.name());
      }
   }
 
   protected void printMainTaglets(Tag[] tags, TagletContext context, TagletPrinter output)
   {
      printTaglets(tags, context, output, false);
   }
 
   /**
    *  @param usedClassToPackagesMap  ClassDoc to (PackageDoc to (UsageType to (Set of Doc)))
    */
   private void addUsedBy(Map usedClassToPackagesMap,
                          ClassDoc usedClass, UsageType usageType, Doc user, PackageDoc userPackage)
   {
      Map packageToUsageTypeMap = (Map)usedClassToPackagesMap.get(usedClass);
      if (null == packageToUsageTypeMap) {
         packageToUsageTypeMap = new HashMap();
         usedClassToPackagesMap.put(usedClass, packageToUsageTypeMap);
      }
 
      Map usageTypeToUsersMap = (Map)packageToUsageTypeMap.get(userPackage);
      if (null == usageTypeToUsersMap) {
         usageTypeToUsersMap = new TreeMap();
         packageToUsageTypeMap.put(userPackage, usageTypeToUsersMap);
      }
 
      Set userSet = (Set)usageTypeToUsersMap.get(usageType);
      if (null == userSet) {
         userSet = new TreeSet(); // FIXME: we need the collator from Main here
         usageTypeToUsersMap.put(usageType, userSet);
      }
      userSet.add(user);
   }
 
   /**
    *  Create the cross reference database.
    */
   private Map collectUsage() {
 
      Map _usedClassToPackagesMap = new HashMap();
 
      ClassDoc[] classes = rootDoc.classes();
      for (int i = 0, ilim = classes.length; i < ilim; ++ i) {
         ClassDoc clazz = classes[i];
 
         if (clazz.isInterface()) {
            // classes implementing
            InterfaceRelation relation
               = (InterfaceRelation)getInterfaceRelations().get(clazz);
            Iterator it = relation.implementingClasses.iterator();
            while (it.hasNext()) {
               ClassDoc implementor = (ClassDoc)it.next();
               addUsedBy(_usedClassToPackagesMap,
                         clazz, UsageType.CLASS_IMPLEMENTING, implementor, implementor.containingPackage());
            }
         }
         else {
            // classes derived from
            for (ClassDoc superclass = clazz.superclass(); superclass != null;
                 superclass = superclass.superclass()) {
               addUsedBy(_usedClassToPackagesMap,
                         superclass, UsageType.CLASS_DERIVED_FROM, clazz, clazz.containingPackage());
            }
         }
 
         FieldDoc[] fields = clazz.fields();
         for (int j = 0, jlim = fields.length; j < jlim; ++ j) {
            FieldDoc field = fields[j];
 
            // fields of type
            ClassDoc fieldType = field.type().asClassDoc();
            if (null != fieldType) {
               addUsedBy(_usedClassToPackagesMap,
                         fieldType, UsageType.FIELD_OF_TYPE,
                         field, clazz.containingPackage());
            }
         }
 
         MethodDoc[] methods = clazz.methods();
         for (int j = 0, jlim = methods.length; j < jlim; ++ j) {
            MethodDoc method = methods[j];
 
            // methods with return type
 
            ClassDoc returnType = method.returnType().asClassDoc();
            if (null != returnType) {
               addUsedBy(_usedClassToPackagesMap,
                         returnType, UsageType.METHOD_WITH_RETURN_TYPE,
                         method, clazz.containingPackage());
            }
            Parameter[] parameters = method.parameters();
            for (int k=0; k<parameters.length; ++k) {
 
               // methods with parameter type
 
               Parameter parameter = parameters[k];
               ClassDoc parameterType = parameter.type().asClassDoc();
               if (null != parameterType) {
                  addUsedBy(_usedClassToPackagesMap,
                            parameterType, UsageType.METHOD_WITH_PARAMETER_TYPE,
                            method, clazz.containingPackage());
               }
            }
 
            // methods which throw
 
            ClassDoc[] thrownExceptions = method.thrownExceptions();
            for (int k = 0, klim = thrownExceptions.length; k < klim; ++ k) {
               ClassDoc thrownException = thrownExceptions[k];
               addUsedBy(_usedClassToPackagesMap,
                         thrownException, UsageType.METHOD_WITH_THROWN_TYPE,
                         method, clazz.containingPackage());
            }
         }
 
         ConstructorDoc[] constructors = clazz.constructors();
         for (int j = 0, jlim = constructors.length; j < jlim; ++ j) {
 
            ConstructorDoc constructor = constructors[j];
 
            Parameter[] parameters = constructor.parameters();
            for (int k = 0, klim = parameters.length; k < klim; ++ k) {
 
               // constructors with parameter type
 
               Parameter parameter = parameters[k];
               ClassDoc parameterType = parameter.type().asClassDoc();
               if (null != parameterType) {
                  addUsedBy(_usedClassToPackagesMap,
                            parameterType, UsageType.CONSTRUCTOR_WITH_PARAMETER_TYPE,
                            constructor, clazz.containingPackage());
               }
            }
 
            // constructors which throw
 
            ClassDoc[] thrownExceptions = constructor.thrownExceptions();
            for (int k = 0, klim = thrownExceptions.length; k < klim; ++ k) {
               ClassDoc thrownException = thrownExceptions[k];
               addUsedBy(_usedClassToPackagesMap,
                         thrownException, UsageType.CONSTRUCTOR_WITH_THROWN_TYPE,
                         constructor, clazz.containingPackage());
            }
         }
      }
      return _usedClassToPackagesMap;
   }
 
   private Map usedClassToPackagesMap = null;
 
   protected Map getUsageOfClass(ClassDoc classDoc)
   {
      if (null == this.usedClassToPackagesMap) {
         this.usedClassToPackagesMap = collectUsage();
      }
      return (Map)this.usedClassToPackagesMap.get(classDoc);
   }
 
   protected static class UsageType
      implements Comparable
   {
      public static final UsageType CLASS_DERIVED_FROM = new UsageType("class-derived-from");
      public static final UsageType CLASS_IMPLEMENTING = new UsageType("class-implementing");
      public static final UsageType FIELD_OF_TYPE = new UsageType("field-of-type");
      public static final UsageType METHOD_WITH_RETURN_TYPE = new UsageType("method-with-return-type");
      public static final UsageType METHOD_WITH_PARAMETER_TYPE = new UsageType("method-with-parameter-type");
      public static final UsageType METHOD_WITH_THROWN_TYPE = new UsageType("method-with-thrown-type");
      public static final UsageType CONSTRUCTOR_WITH_PARAMETER_TYPE = new UsageType("constructor-with-parameter-type");
      public static final UsageType CONSTRUCTOR_WITH_THROWN_TYPE = new UsageType("constructor-with-thrown-type");
      private String id;
 
      private UsageType(String id)
      {
         this.id = id;
      }
 
      public int compareTo(Object other)
      {
         return this.id.compareTo(((UsageType)other).id);
      }
 
      public String toString() {
         return "UsageType{id=" + id + "}";
      }
 
      public String getId() {
         return id;
      }
   }
 
   private ResourceBundle resources;
 
   protected String getString(String key)
   {
      if (null == resources) {
         Locale currentLocale = Locale.getDefault();
 
         resources
            = ResourceBundle.getBundle("htmldoclet.HtmlDoclet", currentLocale);
      }
 
      return resources.getString(key);
   }
 
   protected String format(String key, String value1)
   {
      return MessageFormat.format(getString(key), new Object[] { value1 });
   }
 
   protected List getPackageGroups()
   {
      return packageGroups;
   }
 
   protected void copyDocFiles(File sourceDir, File targetDir)
      throws IOException
   {
      File sourceDocFiles = new File(sourceDir, "doc-files");
      File targetDocFiles = new File(targetDir, "doc-files");
 
      if (sourceDocFiles.exists()) {
         IOToolkit.copyDirectory(sourceDocFiles,
                                 targetDocFiles,
                                 optionDocFilesSubDirs.getValue(),
                                 optionExcludeDocFilesSubDir.getComponents());
      }
   }
 
   private Set sourcePaths;
 
   /**
    *  Try to determine the source directory for the given package by
    *  looking at the path specified by -sourcepath, or the current
    *  directory if -sourcepath hasn't been specified.
    *
    *  @throws IOException if the source directory couldn't be
    *  located.
    *
    *  @return List of File
    */
   protected List getPackageSourceDirs(PackageDoc packageDoc)
      throws IOException
   {
      if (null == sourcePaths) {
         for (int i=0; i<rootDoc.options().length; ++i) {
            if ("-sourcepath".equals(rootDoc.options()[i][0])
                || "-s".equals(rootDoc.options()[i][0])) {
               sourcePaths = new LinkedHashSet();
               String sourcepathString = rootDoc.options()[i][1];
               StringTokenizer st = new StringTokenizer(sourcepathString, File.pathSeparator);
               while (st.hasMoreTokens()) {
                  sourcePaths.add(new File(st.nextToken()));
               }
            }
         }
         if (null == sourcePaths) {
            sourcePaths = new LinkedHashSet();
            sourcePaths.add(new File(System.getProperty("user.dir")));
         }
      }
 
      String packageSubDir = packageDoc.name().replace('.', File.separatorChar);
      Iterator it = sourcePaths.iterator();
      List result = new LinkedList();
      while (it.hasNext()) {
         File pathComponent = (File)it.next();
         File packageDir = new File(pathComponent, packageSubDir);
         if (packageDir.exists()) {
            result.add(packageDir);
         }
      }
      if (result.isEmpty()) {
         throw new IOException("Couldn't locate source directory for package " + packageDoc.name());
      }
      else {
         return result;
      }
   }
 
   protected File getSourceFile(ClassDoc classDoc)
      throws IOException
   {
      List packageDirs = getPackageSourceDirs(classDoc.containingPackage());
      Iterator it = packageDirs.iterator();
      while (it.hasNext()) {
         File packageDir = (File)it.next();
         File sourceFile = new File(packageDir, getOuterClassDoc(classDoc).name() + ".java");
         if (sourceFile.exists()) {
            return sourceFile;
         }
      }
 
      throw new IOException("Couldn't locate source file for class " + classDoc.qualifiedTypeName());
   }
 
   protected void printError(String error)
   {
      if (null != rootDoc) {
         rootDoc.printError(error);
      }
      else {
         System.err.println("ERROR: "+error);
      }
   }
 
   protected void printWarning(String warning)
   {
      if (null != rootDoc) {
         rootDoc.printWarning(warning);
      }
      else {
         System.err.println("WARNING: "+warning);
      }
   }
 
   protected void printNotice(String notice)
   {
      if (null != rootDoc) {
         rootDoc.printNotice(notice);
      }
      else {
         System.err.println(notice);
      }
   }
 
   protected static ClassDoc getOuterClassDoc(ClassDoc classDoc)
   {
      while (null != classDoc.containingClass()) {
         classDoc = classDoc.containingClass();
      }
      return classDoc;
   }
 
   private SortedSet allPackages;
 
   protected Set getAllPackages()
   {
      if (null == this.allPackages) {
         allPackages = new TreeSet();
         PackageDoc[] specifiedPackages = rootDoc.specifiedPackages();
         for (int i=0; i<specifiedPackages.length; ++i) {
            allPackages.add(specifiedPackages[i]);
         }
         ClassDoc[] specifiedClasses = rootDoc.specifiedClasses();
         for (int i=0; i<specifiedClasses.length; ++i) {
            allPackages.add(specifiedClasses[i].containingPackage());
         }
      }
      return this.allPackages;
   }
 
   protected boolean omitPackageQualifier(PackageDoc packageDoc)
   {
      if (!optionNoQualifier.isSpecified()) {
         return false;
      }
      else {
         return optionNoQualifier.match(packageDoc);
      }
   }
 
   protected String possiblyQualifiedName(Type type)
   {
      if (null == type.asClassDoc()
          || !omitPackageQualifier(type.asClassDoc().containingPackage())) {
         return type.qualifiedTypeName();
      }
      else {
         return type.typeName();
      }
   }
 
   protected static class InterfaceRelation
   {
      public Set superInterfaces;
      public Set subInterfaces;
      public Set implementingClasses;
 
      public InterfaceRelation()
      {
         superInterfaces = new TreeSet();
         subInterfaces = new TreeSet();
         implementingClasses = new TreeSet();
      }
   }
 
   private void addAllInterfaces(ClassDoc classDoc, Set allInterfaces)
   {
      ClassDoc[] interfaces = classDoc.interfaces();
      for (int i=0; i<interfaces.length; ++i) {
         allInterfaces.add(interfaces[i]);
         addAllInterfaces(interfaces[i], allInterfaces);
      }
   }
 
   private Map allSubClasses;
 
   protected Map getAllSubClasses()
   {
      if (null == allSubClasses) {
         allSubClasses = new HashMap();
 
         ClassDoc[] classDocs = getRootDoc().classes();
         for (int i=0; i<classDocs.length; ++i) {
            if (!classDocs[i].isInterface()) {
               for (ClassDoc cd = classDocs[i].superclass();
                    null != cd;
                    cd = cd.superclass()) {
 
                  if (!cd.qualifiedTypeName().equals("java.lang.Object")) {
                     List subClasses = (List)allSubClasses.get(cd);
                     if (null == subClasses) {
                        subClasses = new LinkedList();
                        allSubClasses.put(cd, subClasses);
                     }
                     subClasses.add(classDocs[i]);
                  }
               }
            }
         }
      }
      return allSubClasses;
   }
 
   private Map interfaceRelations;
 
   private void addToInterfaces(ClassDoc classDoc, ClassDoc[] interfaces)
   {
      for (int i=0; i<interfaces.length; ++i) {
         InterfaceRelation interfaceRelation
            = (InterfaceRelation)interfaceRelations.get(interfaces[i]);
         if (null == interfaceRelation) {
            interfaceRelation = new InterfaceRelation();
            interfaceRelations.put(interfaces[i], interfaceRelation);
         }
         interfaceRelation.implementingClasses.add(classDoc);
         addToInterfaces(classDoc, interfaces[i].interfaces());
      }
   }
 
   protected Map getInterfaceRelations()
   {
      if (null == interfaceRelations) {
         interfaceRelations = new HashMap();
 
         ClassDoc[] classDocs = getRootDoc().classes();
         for (int i=0; i<classDocs.length; ++i) {
            if (classDocs[i].isInterface()) {
               InterfaceRelation relation = new InterfaceRelation();
               addAllInterfaces(classDocs[i], relation.superInterfaces);
               interfaceRelations.put(classDocs[i], relation);
            }
         }
 
         Iterator it = interfaceRelations.keySet().iterator();
         while (it.hasNext()) {
            ClassDoc interfaceDoc = (ClassDoc)it.next();
            InterfaceRelation relation
               = (InterfaceRelation)interfaceRelations.get(interfaceDoc);
            Iterator superIt = relation.superInterfaces.iterator();
            while (superIt.hasNext()) {
               ClassDoc superInterfaceDoc = (ClassDoc)superIt.next();
               InterfaceRelation superRelation
                  = (InterfaceRelation)interfaceRelations.get(superInterfaceDoc);
               if (null != superRelation) {
                  superRelation.subInterfaces.add(interfaceDoc);
               }
            }
         }
 
         for (int i=0; i<classDocs.length; ++i) {
            if (!classDocs[i].isInterface()) {
               for (ClassDoc cd = classDocs[i]; null != cd; cd = cd.superclass()) {
                  addToInterfaces(classDocs[i], cd.interfaces());
               }
            }
         }
      }
 
      return interfaceRelations;
   }
 
   private Map sortedMethodMap = new HashMap();
 
   protected MethodDoc[] getSortedMethods(ClassDoc classDoc)
   {
      MethodDoc[] result = (MethodDoc[])sortedMethodMap.get(classDoc);
      if (null == result) {
         MethodDoc[] methods = classDoc.methods();
         result = (MethodDoc[])methods.clone();
         Arrays.sort(result);
         return result;
      }
      return result;
   }
 
   private Map sortedConstructorMap = new HashMap();
 
   protected ConstructorDoc[] getSortedConstructors(ClassDoc classDoc)
   {
      ConstructorDoc[] result = (ConstructorDoc[])sortedConstructorMap.get(classDoc);
      if (null == result) {
         ConstructorDoc[] constructors = classDoc.constructors();
         result = (ConstructorDoc[])constructors.clone();
         Arrays.sort(result);
         return result;
      }
      return result;
   }
 
   private Map sortedFieldMap = new HashMap();
 
   protected FieldDoc[] getSortedFields(ClassDoc classDoc)
   {
      FieldDoc[] result = (FieldDoc[])sortedFieldMap.get(classDoc);
      if (null == result) {
         FieldDoc[] fields = classDoc.fields();
         result = (FieldDoc[])fields.clone();
         Arrays.sort(result);
         return result;
      }
      return result;
   }
 
   private Map sortedInnerClassMap = new HashMap();
 
   protected ClassDoc[] getSortedInnerClasses(ClassDoc classDoc)
   {
      ClassDoc[] result = (ClassDoc[])sortedInnerClassMap.get(classDoc);
      if (null == result) {
         ClassDoc[] innerClasses = classDoc.innerClasses();
         result = (ClassDoc[])innerClasses.clone();
         Arrays.sort(result);
         return result;
      }
      return result;
   }
 
   protected abstract String renderTag(String tagName, Tag[] tags, TagletContext context);
 
   protected abstract String getDocletVersion();
 
   protected SortedSet getThrownExceptions(ExecutableMemberDoc execMemberDoc)
   {
      SortedSet result = new TreeSet();
      ClassDoc[] thrownExceptions = execMemberDoc.thrownExceptions();
      for (int j=0; j<thrownExceptions.length; ++j) {
         result.add(thrownExceptions[j]);
      }
      return result;
   }
 
   protected boolean isUncheckedException(ClassDoc classDoc)
   {
      if (classDoc.isException()) {
         while (null != classDoc) {
            if (classDoc.qualifiedTypeName().equals("java.lang.RuntimeException")) {
               return true;
            }
            classDoc = classDoc.superclass();
         }
         return false;
      }
      else {
         return false;
      }
   }
 
   protected FieldDoc findField(ClassDoc classDoc, String fieldName)
   {
      for (ClassDoc cd = classDoc; cd != null; cd = cd.superclass()) {
         FieldDoc[] fields = cd.fields(false);
         for (int i=0; i<fields.length; ++i) {
            if (fields[i].name().equals(fieldName)) {
               return fields[i];
            }
         }
      }
      return null;
   }
 
   private Map implementedInterfacesCache = new HashMap();
 
   protected Set getImplementedInterfaces(ClassDoc classDoc)
   {
      Set result = (Set)implementedInterfacesCache.get(classDoc);
      if (null == result) {
         result = new TreeSet();
 
         for (ClassDoc cd = classDoc; cd != null; cd = cd.superclass()) {
            ClassDoc[] interfaces = cd.interfaces();
            for (int i=0; i<interfaces.length; ++i) {
               result.add(interfaces[i]);
               InterfaceRelation relation
                  = (InterfaceRelation)getInterfaceRelations().get(interfaces[i]);
               if (null != relation) {
                  result.addAll(relation.superInterfaces);
               }
            }
         }
 
         implementedInterfacesCache.put(classDoc, result);
      }
 
      return result;
   }
 
   protected boolean isSinglePackage()
   {
      return getAllPackages().size() <= 1;
   }
 
   protected PackageDoc getSinglePackage()
   {
      return (PackageDoc)getAllPackages().iterator().next();
   }
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.