src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java

Sun, 11 Apr 2010 23:24:24 -0700

author
yhuang
date
Sun, 11 Apr 2010 23:24:24 -0700
changeset 539
06e06ec0d6f2
parent 233
5240b1120530
child 554
9d9f26857129
permissions
-rw-r--r--

6875904: Java 7 message synchronization 1
Reviewed-by: ogino, faryad

     1 /*
     2  * Copyright 1997-2005 Sun Microsystems, Inc.  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.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any questions.
    24  */
    26 package com.sun.tools.doclets.formats.html;
    28 import java.util.*;
    30 import com.sun.javadoc.*;
    31 import com.sun.tools.doclets.internal.toolkit.*;
    32 import com.sun.tools.doclets.internal.toolkit.util.*;
    33 import com.sun.tools.doclets.internal.toolkit.builders.*;
    34 import com.sun.tools.doclets.internal.toolkit.taglets.*;
    36 /**
    37  * Generate the Class Information Page.
    38  * @see com.sun.javadoc.ClassDoc
    39  * @see java.util.Collections
    40  * @see java.util.List
    41  * @see java.util.ArrayList
    42  * @see java.util.HashMap
    43  *
    44  * @author Atul M Dambalkar
    45  * @author Robert Field
    46  */
    47 public class ClassWriterImpl extends SubWriterHolderWriter
    48         implements ClassWriter {
    50     protected ClassDoc classDoc;
    52     protected ClassTree classtree;
    54     protected ClassDoc prev;
    56     protected ClassDoc next;
    58     /**
    59      * @param classDoc the class being documented.
    60      * @param prevClass the previous class that was documented.
    61      * @param nextClass the next class being documented.
    62      * @param classTree the class tree for the given class.
    63      */
    64     public ClassWriterImpl (ClassDoc classDoc,
    65             ClassDoc prevClass, ClassDoc nextClass, ClassTree classTree)
    66     throws Exception {
    67         super(ConfigurationImpl.getInstance(),
    68               DirectoryManager.getDirectoryPath(classDoc.containingPackage()),
    69               classDoc.name() + ".html",
    70               DirectoryManager.getRelativePath(classDoc.containingPackage().name()));
    71         this.classDoc = classDoc;
    72         configuration.currentcd = classDoc;
    73         this.classtree = classTree;
    74         this.prev = prevClass;
    75         this.next = nextClass;
    76     }
    78     /**
    79      * Print this package link
    80      */
    81     protected void navLinkPackage() {
    82         navCellStart();
    83         printHyperLink("package-summary.html", "",
    84             configuration.getText("doclet.Package"), true, "NavBarFont1");
    85         navCellEnd();
    86     }
    88     /**
    89      * Print class page indicator
    90      */
    91     protected void navLinkClass() {
    92         navCellRevStart();
    93         fontStyle("NavBarFont1Rev");
    94         strongText("doclet.Class");
    95         fontEnd();
    96         navCellEnd();
    97     }
    99     /**
   100      * Print class use link
   101      */
   102     protected void navLinkClassUse() {
   103         navCellStart();
   104         printHyperLink("class-use/" + filename, "",
   105                        configuration.getText("doclet.navClassUse"), true, "NavBarFont1");
   106         navCellEnd();
   107     }
   109     /**
   110      * Print previous package link
   111      */
   112     protected void navLinkPrevious() {
   113         if (prev == null) {
   114             printText("doclet.Prev_Class");
   115         } else {
   116             printLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS, prev, "",
   117                 configuration.getText("doclet.Prev_Class"), true));
   118         }
   119     }
   121     /**
   122      * Print next package link
   123      */
   124     protected void navLinkNext() {
   125         if (next == null) {
   126             printText("doclet.Next_Class");
   127         } else {
   128             printLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS, next, "",
   129                 configuration.getText("doclet.Next_Class"), true));
   130         }
   131     }
   133     /**
   134      * {@inheritDoc}
   135      */
   136     public void writeHeader(String header) {
   137         String pkgname = (classDoc.containingPackage() != null)?
   138             classDoc.containingPackage().name(): "";
   139         String clname = classDoc.name();
   140         printHtmlHeader(clname,
   141             configuration.metakeywords.getMetaKeywords(classDoc), true);
   142         printTop();
   143         navLinks(true);
   144         hr();
   145         println("<!-- ======== START OF CLASS DATA ======== -->");
   146         h2();
   147         if (pkgname.length() > 0) {
   148             font("-1"); print(pkgname); fontEnd(); br();
   149         }
   150         LinkInfoImpl linkInfo = new LinkInfoImpl( LinkInfoImpl.CONTEXT_CLASS_HEADER,
   151             classDoc, false);
   152         //Let's not link to ourselves in the header.
   153         linkInfo.linkToSelf = false;
   154         print(header + getTypeParameterLinks(linkInfo));
   155         h2End();
   156     }
   158     /**
   159      * {@inheritDoc}
   160      */
   161     public void writeFooter() {
   162         println("<!-- ========= END OF CLASS DATA ========= -->");
   163         hr();
   164         navLinks(false);
   165         printBottom();
   166         printBodyHtmlEnd();
   167     }
   169     /**
   170      * {@inheritDoc}
   171      */
   172     public void writeClassSignature(String modifiers) {
   173         boolean isInterface = classDoc.isInterface();
   174         preNoNewLine();
   175         writeAnnotationInfo(classDoc);
   176         print(modifiers);
   177         LinkInfoImpl linkInfo = new LinkInfoImpl(
   178             LinkInfoImpl.CONTEXT_CLASS_SIGNATURE, classDoc, false);
   179         //Let's not link to ourselves in the signature.
   180         linkInfo.linkToSelf = false;
   181         String name = classDoc.name() +
   182             getTypeParameterLinks(linkInfo);
   183         if (configuration().linksource) {
   184             printSrcLink(classDoc, name);
   185         } else {
   186             strong(name);
   187         }
   188         if (!isInterface) {
   189             Type superclass = Util.getFirstVisibleSuperClass(classDoc,
   190                 configuration());
   191             if (superclass != null) {
   192                 println();
   193                 print("extends ");
   194                 printLink(new LinkInfoImpl(
   195                     LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
   196                     superclass));
   197             }
   198         }
   199         Type[] implIntfacs = classDoc.interfaceTypes();
   200         if (implIntfacs != null && implIntfacs.length > 0) {
   201             int counter = 0;
   202             for (int i = 0; i < implIntfacs.length; i++) {
   203                 ClassDoc classDoc = implIntfacs[i].asClassDoc();
   204                 if (! (classDoc.isPublic() ||
   205                     Util.isLinkable(classDoc, configuration()))) {
   206                     continue;
   207                 }
   208                 if (counter == 0) {
   209                     println();
   210                     print(isInterface? "extends " : "implements ");
   211                 } else {
   212                     print(", ");
   213                 }
   214                 printLink(new LinkInfoImpl(
   215                     LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
   216                     implIntfacs[i]));
   217                 counter++;
   218             }
   219         }
   220         preEnd();
   221         p();
   222     }
   224     /**
   225      * {@inheritDoc}
   226      */
   227     public void writeClassDescription() {
   228         if(!configuration.nocomment) {
   229             // generate documentation for the class.
   230             if (classDoc.inlineTags().length > 0) {
   231                 printInlineComment(classDoc);
   232                 p();
   233             }
   234         }
   235     }
   237     /**
   238      * {@inheritDoc}
   239      */
   240     public void writeClassTagInfo() {
   241         if(!configuration.nocomment) {
   242             // Print Information about all the tags here
   243             printTags(classDoc);
   244             hr();
   245             p();
   246         } else {
   247             hr();
   248         }
   249     }
   251     /**
   252      * {@inheritDoc}
   253      */
   254     public void writeClassDeprecationInfo() {
   255         hr();
   256         Tag[] deprs = classDoc.tags("deprecated");
   257         if (Util.isDeprecated(classDoc)) {
   258             strongText("doclet.Deprecated");
   259             if (deprs.length > 0) {
   260                 Tag[] commentTags = deprs[0].inlineTags();
   261                 if (commentTags.length > 0) {
   262                     space();
   263                     printInlineDeprecatedComment(classDoc, deprs[0]);
   264                 }
   265             }
   266             p();
   267         }
   268     }
   270     /**
   271      * Generate the indent and get the line image for the class tree.
   272      * For user accessibility, the image includes the alt attribute
   273      * "extended by".  (This method is not intended for a class
   274      * implementing an interface, where "implemented by" would be required.)
   275      *
   276      * indent  integer indicating the number of spaces to indent
   277      */
   278     private void writeStep(int indent) {
   279         print(spaces(4 * indent - 2));
   280         print("<IMG SRC=\"" + relativepathNoSlash + "/resources/inherit.gif\" " +
   281               "ALT=\"" + configuration.getText("doclet.extended_by") + " \">");
   282     }
   284     /**
   285      * Print the class hierarchy tree for the given class.
   286      * @param type the class to print the hierarchy for.
   287      * @return return the amount that should be indented in
   288      * the next level of the tree.
   289      */
   290     private int writeTreeForClassHelper(Type type) {
   291         Type sup = Util.getFirstVisibleSuperClass(
   292             type instanceof ClassDoc ? (ClassDoc) type : type.asClassDoc(),
   293             configuration());
   294         int indent = 0;
   295         if (sup != null) {
   296             indent = writeTreeForClassHelper(sup);
   297             writeStep(indent);
   298         }
   300         if (type.equals(classDoc)) {
   301             String typeParameters = getTypeParameterLinks(
   302                 new LinkInfoImpl(
   303                     LinkInfoImpl.CONTEXT_TREE,
   304                     classDoc, false));
   305             if (configuration.shouldExcludeQualifier(
   306                     classDoc.containingPackage().name())) {
   307                 strong(type.asClassDoc().name() + typeParameters);
   308             } else {
   309                 strong(type.asClassDoc().qualifiedName() + typeParameters);
   310             }
   311         } else {
   312             print(getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS_TREE_PARENT,
   313                     type instanceof ClassDoc ? (ClassDoc) type : type,
   314                     configuration.getClassName(type.asClassDoc()), false)));
   315         }
   316         println();
   317         return indent + 1;
   318     }
   320     /**
   321      * Print the class hierarchy tree for this class only.
   322      */
   323     public void writeClassTree() {
   324         if (! classDoc.isClass()) {
   325             return;
   326         }
   327         pre();
   328         writeTreeForClassHelper(classDoc);
   329         preEnd();
   330     }
   332     /**
   333      * Write the type parameter information.
   334      */
   335     public void writeTypeParamInfo() {
   336         if (classDoc.typeParamTags().length > 0) {
   337             dl();
   338             dt();
   339             TagletOutput output = (new ParamTaglet()).getTagletOutput(classDoc,
   340                 getTagletWriterInstance(false));
   341             print(output.toString());
   342             dtEnd();
   343             dlEnd();
   344         }
   345     }
   347     /**
   348      * {@inheritDoc}
   349      */
   350     public void writeSubClassInfo() {
   351         if (classDoc.isClass()) {
   352             if (classDoc.qualifiedName().equals("java.lang.Object") ||
   353                 classDoc.qualifiedName().equals("org.omg.CORBA.Object")) {
   354                 return;    // Don't generate the list, too huge
   355             }
   356             List<ClassDoc> subclasses = classtree.subs(classDoc, false);
   357             if (subclasses.size() > 0) {
   358                 dl();
   359                 dt();
   360                 strongText("doclet.Subclasses");
   361                 dtEnd();
   362                 writeClassLinks(LinkInfoImpl.CONTEXT_SUBCLASSES,
   363                     subclasses);
   364                 dlEnd();
   365             }
   366         }
   367     }
   369     /**
   370      * {@inheritDoc}
   371      */
   372     public void writeSubInterfacesInfo() {
   373         if (classDoc.isInterface()) {
   374             List<ClassDoc> subInterfaces = classtree.allSubs(classDoc, false);
   375             if (subInterfaces.size() > 0) {
   376                 dl();
   377                 dt();
   378                 strongText("doclet.Subinterfaces");
   379                 dtEnd();
   380                 writeClassLinks(LinkInfoImpl.CONTEXT_SUBINTERFACES,
   381                     subInterfaces);
   382                 dlEnd();
   383             }
   384         }
   385     }
   387     /**
   388      * If this is the interface which are the classes, that implement this?
   389      */
   390     public void writeInterfaceUsageInfo () {
   391         if (! classDoc.isInterface()) {
   392             return;
   393         }
   394         if (classDoc.qualifiedName().equals("java.lang.Cloneable") ||
   395             classDoc.qualifiedName().equals("java.io.Serializable")) {
   396             return;   // Don't generate the list, too big
   397         }
   398         List<ClassDoc> implcl = classtree.implementingclasses(classDoc);
   399         if (implcl.size() > 0) {
   400             dl();
   401             dt();
   402             strongText("doclet.Implementing_Classes");
   403             dtEnd();
   404             writeClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_CLASSES,
   405                 implcl);
   406             dlEnd();
   407         }
   408     }
   410     /**
   411      * {@inheritDoc}
   412      */
   413     public void writeImplementedInterfacesInfo() {
   414         //NOTE:  we really should be using ClassDoc.interfaceTypes() here, but
   415         //       it doesn't walk up the tree like we want it to.
   416         List<Type> interfaceArray = Util.getAllInterfaces(classDoc, configuration);
   417         if (classDoc.isClass() && interfaceArray.size() > 0) {
   418             dl();
   419             dt();
   420             strongText("doclet.All_Implemented_Interfaces");
   421             dtEnd();
   422             writeClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_INTERFACES,
   423                 interfaceArray);
   424             dlEnd();
   425         }
   426     }
   428     /**
   429      * {@inheritDoc}
   430      */
   431     public void writeSuperInterfacesInfo() {
   432         //NOTE:  we really should be using ClassDoc.interfaceTypes() here, but
   433         //       it doesn't walk up the tree like we want it to.
   434         List<Type> interfaceArray = Util.getAllInterfaces(classDoc, configuration);
   435         if (classDoc.isInterface() && interfaceArray.size() > 0) {
   436             dl();
   437             dt();
   438             strongText("doclet.All_Superinterfaces");
   439             dtEnd();
   440             writeClassLinks(LinkInfoImpl.CONTEXT_SUPER_INTERFACES,
   441                 interfaceArray);
   442             dlEnd();
   443         }
   444     }
   446     /**
   447      * Generate links to the given classes.
   448      */
   449     private void writeClassLinks(int context, List<?> list) {
   450         Object[] typeList = list.toArray();
   451         //Sort the list to be printed.
   452         print(' ');
   453         dd();
   454         for (int i = 0; i < list.size(); i++) {
   455             if (i > 0) {
   456                 print(", ");
   457             }
   458             if (typeList[i] instanceof ClassDoc) {
   459                 printLink(new LinkInfoImpl(context, (ClassDoc)(typeList[i])));
   461             } else {
   462                 printLink(new LinkInfoImpl(context, (Type)(typeList[i])));
   463             }
   464         }
   465         ddEnd();
   466     }
   468     protected void navLinkTree() {
   469         navCellStart();
   470         printHyperLink("package-tree.html", "",
   471             configuration.getText("doclet.Tree"), true, "NavBarFont1");
   472         navCellEnd();
   473     }
   475     protected void printSummaryDetailLinks() {
   476         try {
   477             tr();
   478             tdVAlignClass("top", "NavBarCell3");
   479             font("-2");
   480             print("  ");
   481             navSummaryLinks();
   482             fontEnd();
   483             tdEnd();
   484             tdVAlignClass("top", "NavBarCell3");
   485             font("-2");
   486             navDetailLinks();
   487             fontEnd();
   488             tdEnd();
   489             trEnd();
   490         } catch (Exception e) {
   491             e.printStackTrace();
   492             throw new DocletAbortException();
   493         }
   494     }
   496     protected void navSummaryLinks() throws Exception {
   497         printText("doclet.Summary");
   498         space();
   499         MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
   500             configuration.getBuilderFactory().getMemberSummaryBuilder(this);
   501         String[] navLinkLabels =  new String[] {
   502             "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
   503                 "doclet.navMethod"
   504         };
   505         for (int i = 0; i < navLinkLabels.length; i++ ) {
   506             if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
   507                 continue;
   508             }
   509             if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
   510                 continue;
   511             }
   512             AbstractMemberWriter writer =
   513                 ((AbstractMemberWriter) memberSummaryBuilder.
   514                     getMemberSummaryWriter(i));
   515             if (writer == null) {
   516                 printText(navLinkLabels[i]);
   517             } else {
   518                 writer.navSummaryLink(
   519                     memberSummaryBuilder.members(i),
   520                     memberSummaryBuilder.getVisibleMemberMap(i));
   521             }
   522             if (i < navLinkLabels.length-1) {
   523                 navGap();
   524             }
   525         }
   526     }
   528     /**
   529      * Method navDetailLinks
   530      *
   531      * @throws   Exception
   532      *
   533      */
   534     protected void navDetailLinks() throws Exception {
   535         printText("doclet.Detail");
   536         space();
   537         MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
   538             configuration.getBuilderFactory().getMemberSummaryBuilder(this);
   539         String[] navLinkLabels =  new String[] {
   540             "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
   541                 "doclet.navMethod"
   542         };
   543         for (int i = 1; i < navLinkLabels.length; i++ ) {
   544             AbstractMemberWriter writer =
   545                 ((AbstractMemberWriter) memberSummaryBuilder.
   546                     getMemberSummaryWriter(i));
   547             if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
   548                 continue;
   549             }
   550             if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
   551                 continue;
   552             }
   553             if (writer == null) {
   554                 printText(navLinkLabels[i]);
   555             } else {
   556                 writer.navDetailLink(memberSummaryBuilder.members(i));
   557             }
   558             if (i < navLinkLabels.length - 1) {
   559                 navGap();
   560             }
   561         }
   562     }
   564     protected void navGap() {
   565         space();
   566         print('|');
   567         space();
   568     }
   570     /**
   571      * If this is an inner class or interface, write the enclosing class or
   572      * interface.
   573      */
   574     public void writeNestedClassInfo() {
   575         ClassDoc outerClass = classDoc.containingClass();
   576         if (outerClass != null) {
   577             dl();
   578             dt();
   579             if (outerClass.isInterface()) {
   580                 strongText("doclet.Enclosing_Interface");
   581             } else {
   582                 strongText("doclet.Enclosing_Class");
   583             }
   584             dtEnd();
   585             dd();
   586             printLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS, outerClass,
   587                 false));
   588             ddEnd();
   589             dlEnd();
   590         }
   591     }
   593     /**
   594      * Return the classDoc being documented.
   595      *
   596      * @return the classDoc being documented.
   597      */
   598     public ClassDoc getClassDoc() {
   599         return classDoc;
   600     }
   602     /**
   603      * {@inheritDoc}
   604      */
   605     public void completeMemberSummaryBuild() {
   606         p();
   607     }
   608 }

mercurial