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

Wed, 18 Feb 2009 13:47:27 -0800

author
bpatel
date
Wed, 18 Feb 2009 13:47:27 -0800
changeset 222
d424ed561993
parent 184
905e151a185a
child 233
5240b1120530
permissions
-rw-r--r--

6802694: Javadoc doclet does not display deprecated information with -nocomment option for serialized form
Reviewed-by: jjg

     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 com.sun.tools.doclets.internal.toolkit.*;
    29 import com.sun.tools.doclets.internal.toolkit.util.*;
    30 import com.sun.tools.doclets.internal.toolkit.builders.*;
    31 import com.sun.javadoc.*;
    33 import java.util.*;
    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         dl();
   175         dt();
   176         preNoNewLine();
   177         writeAnnotationInfo(classDoc);
   178         print(modifiers);
   179         LinkInfoImpl linkInfo = new LinkInfoImpl(
   180             LinkInfoImpl.CONTEXT_CLASS_SIGNATURE, classDoc, false);
   181         //Let's not link to ourselves in the signature.
   182         linkInfo.linkToSelf = false;
   183         String name = classDoc.name() +
   184             getTypeParameterLinks(linkInfo);
   185         if (configuration().linksource) {
   186             printSrcLink(classDoc, name);
   187         } else {
   188             strong(name);
   189         }
   190         if (!isInterface) {
   191             Type superclass = Util.getFirstVisibleSuperClass(classDoc,
   192                 configuration());
   193             if (superclass != null) {
   194                 dt();
   195                 print("extends ");
   196                 printLink(new LinkInfoImpl(
   197                     LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
   198                     superclass));
   199             }
   200         }
   201         Type[] implIntfacs = classDoc.interfaceTypes();
   202         if (implIntfacs != null && implIntfacs.length > 0) {
   203             int counter = 0;
   204             for (int i = 0; i < implIntfacs.length; i++) {
   205                 ClassDoc classDoc = implIntfacs[i].asClassDoc();
   206                 if (! (classDoc.isPublic() ||
   207                     Util.isLinkable(classDoc, configuration()))) {
   208                     continue;
   209                 }
   210                 if (counter == 0) {
   211                     dt();
   212                     print(isInterface? "extends " : "implements ");
   213                 } else {
   214                     print(", ");
   215                 }
   216                 printLink(new LinkInfoImpl(
   217                     LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
   218                     implIntfacs[i]));
   219                 counter++;
   220             }
   221         }
   222         dlEnd();
   223         preEnd();
   224         p();
   225     }
   227     /**
   228      * {@inheritDoc}
   229      */
   230     public void writeClassDescription() {
   231         if(!configuration.nocomment) {
   232             // generate documentation for the class.
   233             if (classDoc.inlineTags().length > 0) {
   234                 printInlineComment(classDoc);
   235                 p();
   236             }
   237         }
   238     }
   240     /**
   241      * {@inheritDoc}
   242      */
   243     public void writeClassTagInfo() {
   244         if(!configuration.nocomment) {
   245             // Print Information about all the tags here
   246             printTags(classDoc);
   247             hr();
   248             p();
   249         } else {
   250             hr();
   251         }
   252     }
   254     /**
   255      * {@inheritDoc}
   256      */
   257     public void writeClassDeprecationInfo() {
   258         hr();
   259         Tag[] deprs = classDoc.tags("deprecated");
   260         if (Util.isDeprecated(classDoc)) {
   261             strongText("doclet.Deprecated");
   262             if (deprs.length > 0) {
   263                 Tag[] commentTags = deprs[0].inlineTags();
   264                 if (commentTags.length > 0) {
   265                     space();
   266                     printInlineDeprecatedComment(classDoc, deprs[0]);
   267                 }
   268             }
   269             p();
   270         }
   271     }
   273     /**
   274      * Generate the indent and get the line image for the class tree.
   275      * For user accessibility, the image includes the alt attribute
   276      * "extended by".  (This method is not intended for a class
   277      * implementing an interface, where "implemented by" would be required.)
   278      *
   279      * indent  integer indicating the number of spaces to indent
   280      */
   281     private void writeStep(int indent) {
   282         print(spaces(4 * indent - 2));
   283         print("<IMG SRC=\"" + relativepathNoSlash + "/resources/inherit.gif\" " +
   284               "ALT=\"" + configuration.getText("doclet.extended_by") + " \">");
   285     }
   287     /**
   288      * Print the class hierarchy tree for the given class.
   289      * @param type the class to print the hierarchy for.
   290      * @return return the amount that should be indented in
   291      * the next level of the tree.
   292      */
   293     private int writeTreeForClassHelper(Type type) {
   294         Type sup = Util.getFirstVisibleSuperClass(
   295             type instanceof ClassDoc ? (ClassDoc) type : type.asClassDoc(),
   296             configuration());
   297         int indent = 0;
   298         if (sup != null) {
   299             indent = writeTreeForClassHelper(sup);
   300             writeStep(indent);
   301         }
   303         if (type.equals(classDoc)) {
   304             String typeParameters = getTypeParameterLinks(
   305                 new LinkInfoImpl(
   306                     LinkInfoImpl.CONTEXT_TREE,
   307                     classDoc, false));
   308             if (configuration.shouldExcludeQualifier(
   309                     classDoc.containingPackage().name())) {
   310                 strong(type.asClassDoc().name() + typeParameters);
   311             } else {
   312                 strong(type.asClassDoc().qualifiedName() + typeParameters);
   313             }
   314         } else {
   315             print(getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS_TREE_PARENT,
   316                     type instanceof ClassDoc ? (ClassDoc) type : type,
   317                     configuration.getClassName(type.asClassDoc()), false)));
   318         }
   319         println();
   320         return indent + 1;
   321     }
   323     /**
   324      * Print the class hierarchy tree for this class only.
   325      */
   326     public void writeClassTree() {
   327         if (! classDoc.isClass()) {
   328             return;
   329         }
   330         pre();
   331         writeTreeForClassHelper(classDoc);
   332         preEnd();
   333     }
   335     /**
   336      * Write the type parameter information.
   337      */
   338     public void writeTypeParamInfo() {
   339         if (classDoc.typeParamTags().length > 0) {
   340             dl();
   341             dt();
   342             TagletOutput output = (new ParamTaglet()).getTagletOutput(classDoc,
   343                 getTagletWriterInstance(false));
   344             print(output.toString());
   345             dlEnd();
   346         }
   347     }
   349     /**
   350      * {@inheritDoc}
   351      */
   352     public void writeSubClassInfo() {
   353         if (classDoc.isClass()) {
   354             if (classDoc.qualifiedName().equals("java.lang.Object") ||
   355                 classDoc.qualifiedName().equals("org.omg.CORBA.Object")) {
   356                 return;    // Don't generate the list, too huge
   357             }
   358             List<ClassDoc> subclasses = classtree.subs(classDoc, false);
   359             if (subclasses.size() > 0) {
   360                 dl();
   361                 dt();
   362                 strongText("doclet.Subclasses");
   363                 writeClassLinks(LinkInfoImpl.CONTEXT_SUBCLASSES,
   364                     subclasses);
   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                 writeClassLinks(LinkInfoImpl.CONTEXT_SUBINTERFACES,
   380                     subInterfaces);
   381             }
   382         }
   383     }
   385     /**
   386      * If this is the interface which are the classes, that implement this?
   387      */
   388     public void writeInterfaceUsageInfo () {
   389         if (! classDoc.isInterface()) {
   390             return;
   391         }
   392         if (classDoc.qualifiedName().equals("java.lang.Cloneable") ||
   393             classDoc.qualifiedName().equals("java.io.Serializable")) {
   394             return;   // Don't generate the list, too big
   395         }
   396         List<ClassDoc> implcl = classtree.implementingclasses(classDoc);
   397         if (implcl.size() > 0) {
   398             dl();
   399             dt();
   400             strongText("doclet.Implementing_Classes");
   401             writeClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_CLASSES,
   402                 implcl);
   403         }
   404     }
   406     /**
   407      * {@inheritDoc}
   408      */
   409     public void writeImplementedInterfacesInfo() {
   410         //NOTE:  we really should be using ClassDoc.interfaceTypes() here, but
   411         //       it doesn't walk up the tree like we want it to.
   412         List<Type> interfaceArray = Util.getAllInterfaces(classDoc, configuration);
   413         if (classDoc.isClass() && interfaceArray.size() > 0) {
   414             dl();
   415             dt();
   416             strongText("doclet.All_Implemented_Interfaces");
   417             writeClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_INTERFACES,
   418                 interfaceArray);
   419         }
   420     }
   422     /**
   423      * {@inheritDoc}
   424      */
   425     public void writeSuperInterfacesInfo() {
   426         //NOTE:  we really should be using ClassDoc.interfaceTypes() here, but
   427         //       it doesn't walk up the tree like we want it to.
   428         List<Type> interfaceArray = Util.getAllInterfaces(classDoc, configuration);
   429         if (classDoc.isInterface() && interfaceArray.size() > 0) {
   430             dl();
   431             dt();
   432             strongText("doclet.All_Superinterfaces");
   433             writeClassLinks(LinkInfoImpl.CONTEXT_SUPER_INTERFACES,
   434                 interfaceArray);
   435         }
   436     }
   438     /**
   439      * Generate links to the given classes.
   440      */
   441     private void writeClassLinks(int context, List<?> list) {
   442         Object[] typeList = list.toArray();
   443         //Sort the list to be printed.
   444         print(' ');
   445         dd();
   446         for (int i = 0; i < list.size(); i++) {
   447             if (i > 0) {
   448                 print(", ");
   449             }
   450             if (typeList[i] instanceof ClassDoc) {
   451                 printLink(new LinkInfoImpl(context, (ClassDoc)(typeList[i])));
   453             } else {
   454                 printLink(new LinkInfoImpl(context, (Type)(typeList[i])));
   455             }
   456         }
   457         ddEnd();
   458         dlEnd();
   459     }
   461     protected void navLinkTree() {
   462         navCellStart();
   463         printHyperLink("package-tree.html", "",
   464             configuration.getText("doclet.Tree"), true, "NavBarFont1");
   465         navCellEnd();
   466     }
   468     protected void printSummaryDetailLinks() {
   469         try {
   470             tr();
   471             tdVAlignClass("top", "NavBarCell3");
   472             font("-2");
   473             print("  ");
   474             navSummaryLinks();
   475             fontEnd();
   476             tdEnd();
   477             tdVAlignClass("top", "NavBarCell3");
   478             font("-2");
   479             navDetailLinks();
   480             fontEnd();
   481             tdEnd();
   482             trEnd();
   483         } catch (Exception e) {
   484             e.printStackTrace();
   485             throw new DocletAbortException();
   486         }
   487     }
   489     protected void navSummaryLinks() throws Exception {
   490         printText("doclet.Summary");
   491         space();
   492         MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
   493             configuration.getBuilderFactory().getMemberSummaryBuilder(this);
   494         String[] navLinkLabels =  new String[] {
   495             "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
   496                 "doclet.navMethod"
   497         };
   498         for (int i = 0; i < navLinkLabels.length; i++ ) {
   499             if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
   500                 continue;
   501             }
   502             if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
   503                 continue;
   504             }
   505             AbstractMemberWriter writer =
   506                 ((AbstractMemberWriter) memberSummaryBuilder.
   507                     getMemberSummaryWriter(i));
   508             if (writer == null) {
   509                 printText(navLinkLabels[i]);
   510             } else {
   511                 writer.navSummaryLink(
   512                     memberSummaryBuilder.members(i),
   513                     memberSummaryBuilder.getVisibleMemberMap(i));
   514             }
   515             if (i < navLinkLabels.length-1) {
   516                 navGap();
   517             }
   518         }
   519     }
   521     /**
   522      * Method navDetailLinks
   523      *
   524      * @throws   Exception
   525      *
   526      */
   527     protected void navDetailLinks() throws Exception {
   528         printText("doclet.Detail");
   529         space();
   530         MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
   531             configuration.getBuilderFactory().getMemberSummaryBuilder(this);
   532         String[] navLinkLabels =  new String[] {
   533             "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
   534                 "doclet.navMethod"
   535         };
   536         for (int i = 1; i < navLinkLabels.length; i++ ) {
   537             AbstractMemberWriter writer =
   538                 ((AbstractMemberWriter) memberSummaryBuilder.
   539                     getMemberSummaryWriter(i));
   540             if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
   541                 continue;
   542             }
   543             if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
   544                 continue;
   545             }
   546             if (writer == null) {
   547                 printText(navLinkLabels[i]);
   548             } else {
   549                 writer.navDetailLink(memberSummaryBuilder.members(i));
   550             }
   551             if (i < navLinkLabels.length - 1) {
   552                 navGap();
   553             }
   554         }
   555     }
   557     protected void navGap() {
   558         space();
   559         print('|');
   560         space();
   561     }
   563     /**
   564      * If this is an inner class or interface, write the enclosing class or
   565      * interface.
   566      */
   567     public void writeNestedClassInfo() {
   568         ClassDoc outerClass = classDoc.containingClass();
   569         if (outerClass != null) {
   570             dl();
   571             dt();
   572             if (outerClass.isInterface()) {
   573                 strongText("doclet.Enclosing_Interface");
   574             } else {
   575                 strongText("doclet.Enclosing_Class");
   576             }
   577             dd();
   578             printLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS, outerClass,
   579                 false));
   580             ddEnd();
   581             dlEnd();
   582         }
   583     }
   585     /**
   586      * Return the classDoc being documented.
   587      *
   588      * @return the classDoc being documented.
   589      */
   590     public ClassDoc getClassDoc() {
   591         return classDoc;
   592     }
   594     /**
   595      * {@inheritDoc}
   596      */
   597     public void completeMemberSummaryBuild() {
   598         p();
   599     }
   600 }

mercurial