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

Wed, 27 Apr 2016 01:34:52 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:34:52 +0800
changeset 0
959103a6100f
child 2525
2eb010b6cb22
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/
changeset: 2573:53ca196be1ae
tag: jdk8u25-b17

     1 /*
     2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. 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.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.tools.doclets.formats.html;
    28 import java.util.*;
    30 import com.sun.javadoc.*;
    31 import com.sun.tools.javac.jvm.Profile;
    32 import com.sun.tools.javadoc.RootDocImpl;
    33 import com.sun.tools.doclets.formats.html.markup.*;
    34 import com.sun.tools.doclets.internal.toolkit.*;
    35 import com.sun.tools.doclets.internal.toolkit.builders.*;
    36 import com.sun.tools.doclets.internal.toolkit.taglets.*;
    37 import com.sun.tools.doclets.internal.toolkit.util.*;
    38 import java.io.IOException;
    40 /**
    41  * Generate the Class Information Page.
    42  *
    43  *  <p><b>This is NOT part of any supported API.
    44  *  If you write code that depends on this, you do so at your own risk.
    45  *  This code and its internal interfaces are subject to change or
    46  *  deletion without notice.</b>
    47  *
    48  * @see com.sun.javadoc.ClassDoc
    49  * @see java.util.Collections
    50  * @see java.util.List
    51  * @see java.util.ArrayList
    52  * @see java.util.HashMap
    53  *
    54  * @author Atul M Dambalkar
    55  * @author Robert Field
    56  * @author Bhavesh Patel (Modified)
    57  */
    58 public class ClassWriterImpl extends SubWriterHolderWriter
    59         implements ClassWriter {
    61     protected final ClassDoc classDoc;
    63     protected final ClassTree classtree;
    65     protected final ClassDoc prev;
    67     protected final ClassDoc next;
    69     /**
    70      * @param configuration the configuration data for the doclet
    71      * @param classDoc the class being documented.
    72      * @param prevClass the previous class that was documented.
    73      * @param nextClass the next class being documented.
    74      * @param classTree the class tree for the given class.
    75      */
    76     public ClassWriterImpl (ConfigurationImpl configuration, ClassDoc classDoc,
    77             ClassDoc prevClass, ClassDoc nextClass, ClassTree classTree)
    78             throws IOException {
    79         super(configuration, DocPath.forClass(classDoc));
    80         this.classDoc = classDoc;
    81         configuration.currentcd = classDoc;
    82         this.classtree = classTree;
    83         this.prev = prevClass;
    84         this.next = nextClass;
    85     }
    87     /**
    88      * Get this package link.
    89      *
    90      * @return a content tree for the package link
    91      */
    92     protected Content getNavLinkPackage() {
    93         Content linkContent = getHyperLink(DocPaths.PACKAGE_SUMMARY,
    94                 packageLabel);
    95         Content li = HtmlTree.LI(linkContent);
    96         return li;
    97     }
    99     /**
   100      * Get the class link.
   101      *
   102      * @return a content tree for the class link
   103      */
   104     protected Content getNavLinkClass() {
   105         Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, classLabel);
   106         return li;
   107     }
   109     /**
   110      * Get the class use link.
   111      *
   112      * @return a content tree for the class use link
   113      */
   114     protected Content getNavLinkClassUse() {
   115         Content linkContent = getHyperLink(DocPaths.CLASS_USE.resolve(filename), useLabel);
   116         Content li = HtmlTree.LI(linkContent);
   117         return li;
   118     }
   120     /**
   121      * Get link to previous class.
   122      *
   123      * @return a content tree for the previous class link
   124      */
   125     public Content getNavLinkPrevious() {
   126         Content li;
   127         if (prev != null) {
   128             Content prevLink = getLink(new LinkInfoImpl(configuration,
   129                     LinkInfoImpl.Kind.CLASS, prev)
   130                     .label(prevclassLabel).strong(true));
   131             li = HtmlTree.LI(prevLink);
   132         }
   133         else
   134             li = HtmlTree.LI(prevclassLabel);
   135         return li;
   136     }
   138     /**
   139      * Get link to next class.
   140      *
   141      * @return a content tree for the next class link
   142      */
   143     public Content getNavLinkNext() {
   144         Content li;
   145         if (next != null) {
   146             Content nextLink = getLink(new LinkInfoImpl(configuration,
   147                     LinkInfoImpl.Kind.CLASS, next)
   148                     .label(nextclassLabel).strong(true));
   149             li = HtmlTree.LI(nextLink);
   150         }
   151         else
   152             li = HtmlTree.LI(nextclassLabel);
   153         return li;
   154     }
   156     /**
   157      * {@inheritDoc}
   158      */
   159     public Content getHeader(String header) {
   160         String pkgname = (classDoc.containingPackage() != null)?
   161             classDoc.containingPackage().name(): "";
   162         String clname = classDoc.name();
   163         Content bodyTree = getBody(true, getWindowTitle(clname));
   164         addTop(bodyTree);
   165         addNavLinks(true, bodyTree);
   166         bodyTree.addContent(HtmlConstants.START_OF_CLASS_DATA);
   167         HtmlTree div = new HtmlTree(HtmlTag.DIV);
   168         div.addStyle(HtmlStyle.header);
   169         if (configuration.showProfiles) {
   170             String sep = "";
   171             int profile = configuration.profiles.getProfile(getTypeNameForProfile(classDoc));
   172             if (profile > 0) {
   173                 Content profNameContent = new StringContent();
   174                 for (int i = profile; i < configuration.profiles.getProfileCount(); i++) {
   175                     profNameContent.addContent(sep);
   176                     profNameContent.addContent(Profile.lookup(i).name);
   177                     sep = ", ";
   178                 }
   179                 Content profileNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, profNameContent);
   180                 div.addContent(profileNameDiv);
   181             }
   182         }
   183         if (pkgname.length() > 0) {
   184             Content pkgNameContent = new StringContent(pkgname);
   185             Content pkgNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, pkgNameContent);
   186             div.addContent(pkgNameDiv);
   187         }
   188         LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
   189                 LinkInfoImpl.Kind.CLASS_HEADER, classDoc);
   190         //Let's not link to ourselves in the header.
   191         linkInfo.linkToSelf = false;
   192         Content headerContent = new StringContent(header);
   193         Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING, true,
   194                 HtmlStyle.title, headerContent);
   195         heading.addContent(getTypeParameterLinks(linkInfo));
   196         div.addContent(heading);
   197         bodyTree.addContent(div);
   198         return bodyTree;
   199     }
   201     /**
   202      * {@inheritDoc}
   203      */
   204     public Content getClassContentHeader() {
   205         return getContentHeader();
   206     }
   208     /**
   209      * {@inheritDoc}
   210      */
   211     public void addFooter(Content contentTree) {
   212         contentTree.addContent(HtmlConstants.END_OF_CLASS_DATA);
   213         addNavLinks(false, contentTree);
   214         addBottom(contentTree);
   215     }
   217     /**
   218      * {@inheritDoc}
   219      */
   220     public void printDocument(Content contentTree) throws IOException {
   221         printHtmlDocument(configuration.metakeywords.getMetaKeywords(classDoc),
   222                 true, contentTree);
   223     }
   225     /**
   226      * {@inheritDoc}
   227      */
   228     public Content getClassInfoTreeHeader() {
   229         return getMemberTreeHeader();
   230     }
   232     /**
   233      * {@inheritDoc}
   234      */
   235     public Content getClassInfo(Content classInfoTree) {
   236         return getMemberTree(HtmlStyle.description, classInfoTree);
   237     }
   239     /**
   240      * {@inheritDoc}
   241      */
   242     public void addClassSignature(String modifiers, Content classInfoTree) {
   243         boolean isInterface = classDoc.isInterface();
   244         classInfoTree.addContent(new HtmlTree(HtmlTag.BR));
   245         Content pre = new HtmlTree(HtmlTag.PRE);
   246         addAnnotationInfo(classDoc, pre);
   247         pre.addContent(modifiers);
   248         LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
   249                 LinkInfoImpl.Kind.CLASS_SIGNATURE, classDoc);
   250         //Let's not link to ourselves in the signature.
   251         linkInfo.linkToSelf = false;
   252         Content className = new StringContent(classDoc.name());
   253         Content parameterLinks = getTypeParameterLinks(linkInfo);
   254         if (configuration.linksource) {
   255             addSrcLink(classDoc, className, pre);
   256             pre.addContent(parameterLinks);
   257         } else {
   258             Content span = HtmlTree.SPAN(HtmlStyle.typeNameLabel, className);
   259             span.addContent(parameterLinks);
   260             pre.addContent(span);
   261         }
   262         if (!isInterface) {
   263             Type superclass = Util.getFirstVisibleSuperClass(classDoc,
   264                     configuration);
   265             if (superclass != null) {
   266                 pre.addContent(DocletConstants.NL);
   267                 pre.addContent("extends ");
   268                 Content link = getLink(new LinkInfoImpl(configuration,
   269                         LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME,
   270                         superclass));
   271                 pre.addContent(link);
   272             }
   273         }
   274         Type[] implIntfacs = classDoc.interfaceTypes();
   275         if (implIntfacs != null && implIntfacs.length > 0) {
   276             int counter = 0;
   277             for (int i = 0; i < implIntfacs.length; i++) {
   278                 ClassDoc classDoc = implIntfacs[i].asClassDoc();
   279                 if (! (classDoc.isPublic() ||
   280                         Util.isLinkable(classDoc, configuration))) {
   281                     continue;
   282                 }
   283                 if (counter == 0) {
   284                     pre.addContent(DocletConstants.NL);
   285                     pre.addContent(isInterface? "extends " : "implements ");
   286                 } else {
   287                     pre.addContent(", ");
   288                 }
   289                 Content link = getLink(new LinkInfoImpl(configuration,
   290                         LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME,
   291                         implIntfacs[i]));
   292                 pre.addContent(link);
   293                 counter++;
   294             }
   295         }
   296         classInfoTree.addContent(pre);
   297     }
   299     /**
   300      * {@inheritDoc}
   301      */
   302     public void addClassDescription(Content classInfoTree) {
   303         if(!configuration.nocomment) {
   304             // generate documentation for the class.
   305             if (classDoc.inlineTags().length > 0) {
   306                 addInlineComment(classDoc, classInfoTree);
   307             }
   308         }
   309     }
   311     /**
   312      * {@inheritDoc}
   313      */
   314     public void addClassTagInfo(Content classInfoTree) {
   315         if(!configuration.nocomment) {
   316             // Print Information about all the tags here
   317             addTagsInfo(classDoc, classInfoTree);
   318         }
   319     }
   321     /**
   322      * Get the class hierarchy tree for the given class.
   323      *
   324      * @param type the class to print the hierarchy for
   325      * @return a content tree for class inheritence
   326      */
   327     private Content getClassInheritenceTree(Type type) {
   328         Type sup;
   329         HtmlTree classTreeUl = new HtmlTree(HtmlTag.UL);
   330         classTreeUl.addStyle(HtmlStyle.inheritance);
   331         Content liTree = null;
   332         do {
   333             sup = Util.getFirstVisibleSuperClass(
   334                     type instanceof ClassDoc ? (ClassDoc) type : type.asClassDoc(),
   335                     configuration);
   336             if (sup != null) {
   337                 HtmlTree ul = new HtmlTree(HtmlTag.UL);
   338                 ul.addStyle(HtmlStyle.inheritance);
   339                 ul.addContent(getTreeForClassHelper(type));
   340                 if (liTree != null)
   341                     ul.addContent(liTree);
   342                 Content li = HtmlTree.LI(ul);
   343                 liTree = li;
   344                 type = sup;
   345             }
   346             else
   347                 classTreeUl.addContent(getTreeForClassHelper(type));
   348         }
   349         while (sup != null);
   350         if (liTree != null)
   351             classTreeUl.addContent(liTree);
   352         return classTreeUl;
   353     }
   355     /**
   356      * Get the class helper tree for the given class.
   357      *
   358      * @param type the class to print the helper for
   359      * @return a content tree for class helper
   360      */
   361     private Content getTreeForClassHelper(Type type) {
   362         Content li = new HtmlTree(HtmlTag.LI);
   363         if (type.equals(classDoc)) {
   364             Content typeParameters = getTypeParameterLinks(
   365                     new LinkInfoImpl(configuration, LinkInfoImpl.Kind.TREE,
   366                     classDoc));
   367             if (configuration.shouldExcludeQualifier(
   368                     classDoc.containingPackage().name())) {
   369                 li.addContent(type.asClassDoc().name());
   370                 li.addContent(typeParameters);
   371             } else {
   372                 li.addContent(type.asClassDoc().qualifiedName());
   373                 li.addContent(typeParameters);
   374             }
   375         } else {
   376             Content link = getLink(new LinkInfoImpl(configuration,
   377                     LinkInfoImpl.Kind.CLASS_TREE_PARENT, type)
   378                     .label(configuration.getClassName(type.asClassDoc())));
   379             li.addContent(link);
   380         }
   381         return li;
   382     }
   384     /**
   385      * {@inheritDoc}
   386      */
   387     public void addClassTree(Content classContentTree) {
   388         if (!classDoc.isClass()) {
   389             return;
   390         }
   391         classContentTree.addContent(getClassInheritenceTree(classDoc));
   392     }
   394     /**
   395      * {@inheritDoc}
   396      */
   397     public void addTypeParamInfo(Content classInfoTree) {
   398         if (classDoc.typeParamTags().length > 0) {
   399             Content typeParam = (new ParamTaglet()).getTagletOutput(classDoc,
   400                     getTagletWriterInstance(false));
   401             Content dl = HtmlTree.DL(typeParam);
   402             classInfoTree.addContent(dl);
   403         }
   404     }
   406     /**
   407      * {@inheritDoc}
   408      */
   409     public void addSubClassInfo(Content classInfoTree) {
   410         if (classDoc.isClass()) {
   411             if (classDoc.qualifiedName().equals("java.lang.Object") ||
   412                     classDoc.qualifiedName().equals("org.omg.CORBA.Object")) {
   413                 return;    // Don't generate the list, too huge
   414             }
   415             List<ClassDoc> subclasses = classtree.subs(classDoc, false);
   416             if (subclasses.size() > 0) {
   417                 Content label = getResource(
   418                         "doclet.Subclasses");
   419                 Content dt = HtmlTree.DT(label);
   420                 Content dl = HtmlTree.DL(dt);
   421                 dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUBCLASSES,
   422                         subclasses));
   423                 classInfoTree.addContent(dl);
   424             }
   425         }
   426     }
   428     /**
   429      * {@inheritDoc}
   430      */
   431     public void addSubInterfacesInfo(Content classInfoTree) {
   432         if (classDoc.isInterface()) {
   433             List<ClassDoc> subInterfaces = classtree.allSubs(classDoc, false);
   434             if (subInterfaces.size() > 0) {
   435                 Content label = getResource(
   436                         "doclet.Subinterfaces");
   437                 Content dt = HtmlTree.DT(label);
   438                 Content dl = HtmlTree.DL(dt);
   439                 dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUBINTERFACES,
   440                         subInterfaces));
   441                 classInfoTree.addContent(dl);
   442             }
   443         }
   444     }
   446     /**
   447      * {@inheritDoc}
   448      */
   449     public void addInterfaceUsageInfo (Content classInfoTree) {
   450         if (! classDoc.isInterface()) {
   451             return;
   452         }
   453         if (classDoc.qualifiedName().equals("java.lang.Cloneable") ||
   454                 classDoc.qualifiedName().equals("java.io.Serializable")) {
   455             return;   // Don't generate the list, too big
   456         }
   457         List<ClassDoc> implcl = classtree.implementingclasses(classDoc);
   458         if (implcl.size() > 0) {
   459             Content label = getResource(
   460                     "doclet.Implementing_Classes");
   461             Content dt = HtmlTree.DT(label);
   462             Content dl = HtmlTree.DL(dt);
   463             dl.addContent(getClassLinks(LinkInfoImpl.Kind.IMPLEMENTED_CLASSES,
   464                     implcl));
   465             classInfoTree.addContent(dl);
   466         }
   467     }
   469     /**
   470      * {@inheritDoc}
   471      */
   472     public void addImplementedInterfacesInfo(Content classInfoTree) {
   473         //NOTE:  we really should be using ClassDoc.interfaceTypes() here, but
   474         //       it doesn't walk up the tree like we want it to.
   475         List<Type> interfaceArray = Util.getAllInterfaces(classDoc, configuration);
   476         if (classDoc.isClass() && interfaceArray.size() > 0) {
   477             Content label = getResource(
   478                     "doclet.All_Implemented_Interfaces");
   479             Content dt = HtmlTree.DT(label);
   480             Content dl = HtmlTree.DL(dt);
   481             dl.addContent(getClassLinks(LinkInfoImpl.Kind.IMPLEMENTED_INTERFACES,
   482                     interfaceArray));
   483             classInfoTree.addContent(dl);
   484         }
   485     }
   487     /**
   488      * {@inheritDoc}
   489      */
   490     public void addSuperInterfacesInfo(Content classInfoTree) {
   491         //NOTE:  we really should be using ClassDoc.interfaceTypes() here, but
   492         //       it doesn't walk up the tree like we want it to.
   493         List<Type> interfaceArray = Util.getAllInterfaces(classDoc, configuration);
   494         if (classDoc.isInterface() && interfaceArray.size() > 0) {
   495             Content label = getResource(
   496                     "doclet.All_Superinterfaces");
   497             Content dt = HtmlTree.DT(label);
   498             Content dl = HtmlTree.DL(dt);
   499             dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUPER_INTERFACES,
   500                     interfaceArray));
   501             classInfoTree.addContent(dl);
   502         }
   503     }
   505     /**
   506      * {@inheritDoc}
   507      */
   508     public void addNestedClassInfo(Content classInfoTree) {
   509         ClassDoc outerClass = classDoc.containingClass();
   510         if (outerClass != null) {
   511             Content label;
   512             if (outerClass.isInterface()) {
   513                 label = getResource(
   514                         "doclet.Enclosing_Interface");
   515             } else {
   516                 label = getResource(
   517                         "doclet.Enclosing_Class");
   518             }
   519             Content dt = HtmlTree.DT(label);
   520             Content dl = HtmlTree.DL(dt);
   521             Content dd = new HtmlTree(HtmlTag.DD);
   522             dd.addContent(getLink(new LinkInfoImpl(configuration,
   523                     LinkInfoImpl.Kind.CLASS, outerClass)));
   524             dl.addContent(dd);
   525             classInfoTree.addContent(dl);
   526         }
   527     }
   529     /**
   530      * {@inheritDoc}
   531      */
   532     public void addFunctionalInterfaceInfo (Content classInfoTree) {
   533         if (isFunctionalInterface()) {
   534             Content dt = HtmlTree.DT(getResource("doclet.Functional_Interface"));
   535             Content dl = HtmlTree.DL(dt);
   536             Content dd = new HtmlTree(HtmlTag.DD);
   537             dd.addContent(getResource("doclet.Functional_Interface_Message"));
   538             dl.addContent(dd);
   539             classInfoTree.addContent(dl);
   540         }
   541     }
   543     public boolean isFunctionalInterface() {
   544         if (configuration.root instanceof RootDocImpl) {
   545             RootDocImpl root = (RootDocImpl) configuration.root;
   546             AnnotationDesc[] annotationDescList = classDoc.annotations();
   547             for (AnnotationDesc annoDesc : annotationDescList) {
   548                 if (root.isFunctionalInterface(annoDesc)) {
   549                     return true;
   550                 }
   551             }
   552         }
   553         return false;
   554     }
   556     /**
   557      * {@inheritDoc}
   558      */
   559     public void addClassDeprecationInfo(Content classInfoTree) {
   560         Content hr = new HtmlTree(HtmlTag.HR);
   561         classInfoTree.addContent(hr);
   562         Tag[] deprs = classDoc.tags("deprecated");
   563         if (Util.isDeprecated(classDoc)) {
   564             Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, deprecatedPhrase);
   565             Content div = HtmlTree.DIV(HtmlStyle.block, deprLabel);
   566             if (deprs.length > 0) {
   567                 Tag[] commentTags = deprs[0].inlineTags();
   568                 if (commentTags.length > 0) {
   569                     div.addContent(getSpace());
   570                     addInlineDeprecatedComment(classDoc, deprs[0], div);
   571                 }
   572             }
   573             classInfoTree.addContent(div);
   574         }
   575     }
   577     /**
   578      * Get links to the given classes.
   579      *
   580      * @param context the id of the context where the link will be printed
   581      * @param list the list of classes
   582      * @return a content tree for the class list
   583      */
   584     private Content getClassLinks(LinkInfoImpl.Kind context, List<?> list) {
   585         Object[] typeList = list.toArray();
   586         Content dd = new HtmlTree(HtmlTag.DD);
   587         for (int i = 0; i < list.size(); i++) {
   588             if (i > 0) {
   589                 Content separator = new StringContent(", ");
   590                 dd.addContent(separator);
   591             }
   592             if (typeList[i] instanceof ClassDoc) {
   593                 Content link = getLink(
   594                         new LinkInfoImpl(configuration, context, (ClassDoc)(typeList[i])));
   595                 dd.addContent(link);
   596             } else {
   597                 Content link = getLink(
   598                         new LinkInfoImpl(configuration, context, (Type)(typeList[i])));
   599                 dd.addContent(link);
   600             }
   601         }
   602         return dd;
   603     }
   605     /**
   606      * {@inheritDoc}
   607      */
   608     protected Content getNavLinkTree() {
   609         Content treeLinkContent = getHyperLink(DocPaths.PACKAGE_TREE,
   610                 treeLabel, "", "");
   611         Content li = HtmlTree.LI(treeLinkContent);
   612         return li;
   613     }
   615     /**
   616      * Add summary details to the navigation bar.
   617      *
   618      * @param subDiv the content tree to which the summary detail links will be added
   619      */
   620     protected void addSummaryDetailLinks(Content subDiv) {
   621         try {
   622             Content div = HtmlTree.DIV(getNavSummaryLinks());
   623             div.addContent(getNavDetailLinks());
   624             subDiv.addContent(div);
   625         } catch (Exception e) {
   626             e.printStackTrace();
   627             throw new DocletAbortException(e);
   628         }
   629     }
   631     /**
   632      * Get summary links for navigation bar.
   633      *
   634      * @return the content tree for the navigation summary links
   635      */
   636     protected Content getNavSummaryLinks() throws Exception {
   637         Content li = HtmlTree.LI(summaryLabel);
   638         li.addContent(getSpace());
   639         Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li);
   640         MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
   641                 configuration.getBuilderFactory().getMemberSummaryBuilder(this);
   642         String[] navLinkLabels =  new String[] {
   643             "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
   644             "doclet.navMethod"
   645         };
   646         for (int i = 0; i < navLinkLabels.length; i++ ) {
   647             Content liNav = new HtmlTree(HtmlTag.LI);
   648             if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
   649                 continue;
   650             }
   651             if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
   652                 continue;
   653             }
   654             AbstractMemberWriter writer =
   655                 ((AbstractMemberWriter) memberSummaryBuilder.
   656                 getMemberSummaryWriter(i));
   657             if (writer == null) {
   658                 liNav.addContent(getResource(navLinkLabels[i]));
   659             } else {
   660                 writer.addNavSummaryLink(
   661                         memberSummaryBuilder.members(i),
   662                         memberSummaryBuilder.getVisibleMemberMap(i), liNav);
   663             }
   664             if (i < navLinkLabels.length-1) {
   665                 addNavGap(liNav);
   666             }
   667             ulNav.addContent(liNav);
   668         }
   669         return ulNav;
   670     }
   672     /**
   673      * Get detail links for the navigation bar.
   674      *
   675      * @return the content tree for the detail links
   676      */
   677     protected Content getNavDetailLinks() throws Exception {
   678         Content li = HtmlTree.LI(detailLabel);
   679         li.addContent(getSpace());
   680         Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li);
   681         MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
   682                 configuration.getBuilderFactory().getMemberSummaryBuilder(this);
   683         String[] navLinkLabels =  new String[] {
   684             "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
   685             "doclet.navMethod"
   686         };
   687         for (int i = 1; i < navLinkLabels.length; i++ ) {
   688             Content liNav = new HtmlTree(HtmlTag.LI);
   689             AbstractMemberWriter writer =
   690                     ((AbstractMemberWriter) memberSummaryBuilder.
   691                     getMemberSummaryWriter(i));
   692             if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
   693                 continue;
   694             }
   695             if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
   696                 continue;
   697             }
   698             if (writer == null) {
   699                 liNav.addContent(getResource(navLinkLabels[i]));
   700             } else {
   701                 writer.addNavDetailLink(memberSummaryBuilder.members(i), liNav);
   702             }
   703             if (i < navLinkLabels.length - 1) {
   704                 addNavGap(liNav);
   705             }
   706             ulNav.addContent(liNav);
   707         }
   708         return ulNav;
   709     }
   711     /**
   712      * Add gap between navigation bar elements.
   713      *
   714      * @param liNav the content tree to which the gap will be added
   715      */
   716     protected void addNavGap(Content liNav) {
   717         liNav.addContent(getSpace());
   718         liNav.addContent("|");
   719         liNav.addContent(getSpace());
   720     }
   722     /**
   723      * Return the classDoc being documented.
   724      *
   725      * @return the classDoc being documented.
   726      */
   727     public ClassDoc getClassDoc() {
   728         return classDoc;
   729     }
   730 }

mercurial