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

Tue, 14 May 2013 10:14:52 -0700

author
jjg
date
Tue, 14 May 2013 10:14:52 -0700
changeset 1738
6ea964c78845
parent 1736
74cd21f2c2fe
child 1744
76a691e3e961
permissions
-rw-r--r--

8011651: simplify LinkInfoImpl API
Reviewed-by: darcy

     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.doclets.formats.html.markup.*;
    33 import com.sun.tools.doclets.internal.toolkit.*;
    34 import com.sun.tools.doclets.internal.toolkit.builders.*;
    35 import com.sun.tools.doclets.internal.toolkit.taglets.*;
    36 import com.sun.tools.doclets.internal.toolkit.util.*;
    37 import java.io.IOException;
    39 /**
    40  * Generate the Class Information Page.
    41  *
    42  *  <p><b>This is NOT part of any supported API.
    43  *  If you write code that depends on this, you do so at your own risk.
    44  *  This code and its internal interfaces are subject to change or
    45  *  deletion without notice.</b>
    46  *
    47  * @see com.sun.javadoc.ClassDoc
    48  * @see java.util.Collections
    49  * @see java.util.List
    50  * @see java.util.ArrayList
    51  * @see java.util.HashMap
    52  *
    53  * @author Atul M Dambalkar
    54  * @author Robert Field
    55  * @author Bhavesh Patel (Modified)
    56  */
    57 public class ClassWriterImpl extends SubWriterHolderWriter
    58         implements ClassWriter {
    60     protected final ClassDoc classDoc;
    62     protected final ClassTree classtree;
    64     protected final ClassDoc prev;
    66     protected final ClassDoc next;
    68     /**
    69      * @param configuration the configuration data for the doclet
    70      * @param classDoc the class being documented.
    71      * @param prevClass the previous class that was documented.
    72      * @param nextClass the next class being documented.
    73      * @param classTree the class tree for the given class.
    74      */
    75     public ClassWriterImpl (ConfigurationImpl configuration, ClassDoc classDoc,
    76             ClassDoc prevClass, ClassDoc nextClass, ClassTree classTree)
    77             throws IOException {
    78         super(configuration, DocPath.forClass(classDoc));
    79         this.classDoc = classDoc;
    80         configuration.currentcd = classDoc;
    81         this.classtree = classTree;
    82         this.prev = prevClass;
    83         this.next = nextClass;
    84     }
    86     /**
    87      * Get this package link.
    88      *
    89      * @return a content tree for the package link
    90      */
    91     protected Content getNavLinkPackage() {
    92         Content linkContent = getHyperLink(DocPaths.PACKAGE_SUMMARY,
    93                 packageLabel);
    94         Content li = HtmlTree.LI(linkContent);
    95         return li;
    96     }
    98     /**
    99      * Get the class link.
   100      *
   101      * @return a content tree for the class link
   102      */
   103     protected Content getNavLinkClass() {
   104         Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, classLabel);
   105         return li;
   106     }
   108     /**
   109      * Get the class use link.
   110      *
   111      * @return a content tree for the class use link
   112      */
   113     protected Content getNavLinkClassUse() {
   114         Content linkContent = getHyperLink(DocPaths.CLASS_USE.resolve(filename), useLabel);
   115         Content li = HtmlTree.LI(linkContent);
   116         return li;
   117     }
   119     /**
   120      * Get link to previous class.
   121      *
   122      * @return a content tree for the previous class link
   123      */
   124     public Content getNavLinkPrevious() {
   125         Content li;
   126         if (prev != null) {
   127             Content prevLink = getLink(new LinkInfoImpl(configuration,
   128                     LinkInfoImpl.Kind.CLASS, prev)
   129                     .label(configuration.getText("doclet.Prev_Class")).strong(true));
   130             li = HtmlTree.LI(prevLink);
   131         }
   132         else
   133             li = HtmlTree.LI(prevclassLabel);
   134         return li;
   135     }
   137     /**
   138      * Get link to next class.
   139      *
   140      * @return a content tree for the next class link
   141      */
   142     public Content getNavLinkNext() {
   143         Content li;
   144         if (next != null) {
   145             Content nextLink = getLink(new LinkInfoImpl(configuration,
   146                     LinkInfoImpl.Kind.CLASS, next)
   147                     .label(configuration.getText("doclet.Next_Class")).strong(true));
   148             li = HtmlTree.LI(nextLink);
   149         }
   150         else
   151             li = HtmlTree.LI(nextclassLabel);
   152         return li;
   153     }
   155     /**
   156      * {@inheritDoc}
   157      */
   158     public Content getHeader(String header) {
   159         String pkgname = (classDoc.containingPackage() != null)?
   160             classDoc.containingPackage().name(): "";
   161         String clname = classDoc.name();
   162         Content bodyTree = getBody(true, getWindowTitle(clname));
   163         addTop(bodyTree);
   164         addNavLinks(true, bodyTree);
   165         bodyTree.addContent(HtmlConstants.START_OF_CLASS_DATA);
   166         HtmlTree div = new HtmlTree(HtmlTag.DIV);
   167         div.addStyle(HtmlStyle.header);
   168         if (configuration.showProfiles) {
   169             String sep = "";
   170             int profile = configuration.profiles.getProfile(getTypeNameForProfile(classDoc));
   171             if (profile > 0) {
   172                 Content profNameContent = new StringContent();
   173                 for (int i = profile; i < configuration.profiles.getProfileCount(); i++) {
   174                     profNameContent.addContent(sep);
   175                     profNameContent.addContent(Profile.lookup(i).name);
   176                     sep = ", ";
   177                 }
   178                 Content profileNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, profNameContent);
   179                 div.addContent(profileNameDiv);
   180             }
   181         }
   182         if (pkgname.length() > 0) {
   183             Content pkgNameContent = new StringContent(pkgname);
   184             Content pkgNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, pkgNameContent);
   185             div.addContent(pkgNameDiv);
   186         }
   187         LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
   188                 LinkInfoImpl.Kind.CLASS_HEADER, classDoc);
   189         //Let's not link to ourselves in the header.
   190         linkInfo.linkToSelf = false;
   191         Content headerContent = new StringContent(header);
   192         Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING, true,
   193                 HtmlStyle.title, headerContent);
   194         heading.addContent(getTypeParameterLinks(linkInfo));
   195         div.addContent(heading);
   196         bodyTree.addContent(div);
   197         return bodyTree;
   198     }
   200     /**
   201      * {@inheritDoc}
   202      */
   203     public Content getClassContentHeader() {
   204         return getContentHeader();
   205     }
   207     /**
   208      * {@inheritDoc}
   209      */
   210     public void addFooter(Content contentTree) {
   211         contentTree.addContent(HtmlConstants.END_OF_CLASS_DATA);
   212         addNavLinks(false, contentTree);
   213         addBottom(contentTree);
   214     }
   216     /**
   217      * {@inheritDoc}
   218      */
   219     public void printDocument(Content contentTree) throws IOException {
   220         printHtmlDocument(configuration.metakeywords.getMetaKeywords(classDoc),
   221                 true, contentTree);
   222     }
   224     /**
   225      * {@inheritDoc}
   226      */
   227     public Content getClassInfoTreeHeader() {
   228         return getMemberTreeHeader();
   229     }
   231     /**
   232      * {@inheritDoc}
   233      */
   234     public Content getClassInfo(Content classInfoTree) {
   235         return getMemberTree(HtmlStyle.description, classInfoTree);
   236     }
   238     /**
   239      * {@inheritDoc}
   240      */
   241     public void addClassSignature(String modifiers, Content classInfoTree) {
   242         boolean isInterface = classDoc.isInterface();
   243         classInfoTree.addContent(new HtmlTree(HtmlTag.BR));
   244         Content pre = new HtmlTree(HtmlTag.PRE);
   245         addAnnotationInfo(classDoc, pre);
   246         pre.addContent(modifiers);
   247         LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
   248                 LinkInfoImpl.Kind.CLASS_SIGNATURE, classDoc);
   249         //Let's not link to ourselves in the signature.
   250         linkInfo.linkToSelf = false;
   251         Content className = new StringContent(classDoc.name());
   252         Content parameterLinks = getTypeParameterLinks(linkInfo);
   253         if (configuration.linksource) {
   254             addSrcLink(classDoc, className, pre);
   255             pre.addContent(parameterLinks);
   256         } else {
   257             Content span = HtmlTree.SPAN(HtmlStyle.strong, className);
   258             span.addContent(parameterLinks);
   259             pre.addContent(span);
   260         }
   261         if (!isInterface) {
   262             Type superclass = Util.getFirstVisibleSuperClass(classDoc,
   263                     configuration);
   264             if (superclass != null) {
   265                 pre.addContent(DocletConstants.NL);
   266                 pre.addContent("extends ");
   267                 Content link = getLink(new LinkInfoImpl(configuration,
   268                         LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME,
   269                         superclass));
   270                 pre.addContent(link);
   271             }
   272         }
   273         Type[] implIntfacs = classDoc.interfaceTypes();
   274         if (implIntfacs != null && implIntfacs.length > 0) {
   275             int counter = 0;
   276             for (int i = 0; i < implIntfacs.length; i++) {
   277                 ClassDoc classDoc = implIntfacs[i].asClassDoc();
   278                 if (! (classDoc.isPublic() ||
   279                         Util.isLinkable(classDoc, configuration))) {
   280                     continue;
   281                 }
   282                 if (counter == 0) {
   283                     pre.addContent(DocletConstants.NL);
   284                     pre.addContent(isInterface? "extends " : "implements ");
   285                 } else {
   286                     pre.addContent(", ");
   287                 }
   288                 Content link = getLink(new LinkInfoImpl(configuration,
   289                         LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME,
   290                         implIntfacs[i]));
   291                 pre.addContent(link);
   292                 counter++;
   293             }
   294         }
   295         classInfoTree.addContent(pre);
   296     }
   298     /**
   299      * {@inheritDoc}
   300      */
   301     public void addClassDescription(Content classInfoTree) {
   302         if(!configuration.nocomment) {
   303             // generate documentation for the class.
   304             if (classDoc.inlineTags().length > 0) {
   305                 addInlineComment(classDoc, classInfoTree);
   306             }
   307         }
   308     }
   310     /**
   311      * {@inheritDoc}
   312      */
   313     public void addClassTagInfo(Content classInfoTree) {
   314         if(!configuration.nocomment) {
   315             // Print Information about all the tags here
   316             addTagsInfo(classDoc, classInfoTree);
   317         }
   318     }
   320     /**
   321      * Get the class hierarchy tree for the given class.
   322      *
   323      * @param type the class to print the hierarchy for
   324      * @return a content tree for class inheritence
   325      */
   326     private Content getClassInheritenceTree(Type type) {
   327         Type sup;
   328         HtmlTree classTreeUl = new HtmlTree(HtmlTag.UL);
   329         classTreeUl.addStyle(HtmlStyle.inheritance);
   330         Content liTree = null;
   331         do {
   332             sup = Util.getFirstVisibleSuperClass(
   333                     type instanceof ClassDoc ? (ClassDoc) type : type.asClassDoc(),
   334                     configuration);
   335             if (sup != null) {
   336                 HtmlTree ul = new HtmlTree(HtmlTag.UL);
   337                 ul.addStyle(HtmlStyle.inheritance);
   338                 ul.addContent(getTreeForClassHelper(type));
   339                 if (liTree != null)
   340                     ul.addContent(liTree);
   341                 Content li = HtmlTree.LI(ul);
   342                 liTree = li;
   343                 type = sup;
   344             }
   345             else
   346                 classTreeUl.addContent(getTreeForClassHelper(type));
   347         }
   348         while (sup != null);
   349         if (liTree != null)
   350             classTreeUl.addContent(liTree);
   351         return classTreeUl;
   352     }
   354     /**
   355      * Get the class helper tree for the given class.
   356      *
   357      * @param type the class to print the helper for
   358      * @return a content tree for class helper
   359      */
   360     private Content getTreeForClassHelper(Type type) {
   361         Content li = new HtmlTree(HtmlTag.LI);
   362         if (type.equals(classDoc)) {
   363             Content typeParameters = getTypeParameterLinks(
   364                     new LinkInfoImpl(configuration, LinkInfoImpl.Kind.TREE,
   365                     classDoc));
   366             if (configuration.shouldExcludeQualifier(
   367                     classDoc.containingPackage().name())) {
   368                 li.addContent(type.asClassDoc().name());
   369                 li.addContent(typeParameters);
   370             } else {
   371                 li.addContent(type.asClassDoc().qualifiedName());
   372                 li.addContent(typeParameters);
   373             }
   374         } else {
   375             Content link = getLink(new LinkInfoImpl(configuration,
   376                     LinkInfoImpl.Kind.CLASS_TREE_PARENT, type)
   377                     .label(configuration.getClassName(type.asClassDoc())));
   378             li.addContent(link);
   379         }
   380         return li;
   381     }
   383     /**
   384      * {@inheritDoc}
   385      */
   386     public void addClassTree(Content classContentTree) {
   387         if (!classDoc.isClass()) {
   388             return;
   389         }
   390         classContentTree.addContent(getClassInheritenceTree(classDoc));
   391     }
   393     /**
   394      * {@inheritDoc}
   395      */
   396     public void addTypeParamInfo(Content classInfoTree) {
   397         if (classDoc.typeParamTags().length > 0) {
   398             TagletOutput output = (new ParamTaglet()).getTagletOutput(classDoc,
   399                     getTagletWriterInstance(false));
   400             Content typeParam = new RawHtml(output.toString());
   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 (classDoc.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     /**
   544      * {@inheritDoc}
   545      */
   546     public void addClassDeprecationInfo(Content classInfoTree) {
   547         Content hr = new HtmlTree(HtmlTag.HR);
   548         classInfoTree.addContent(hr);
   549         Tag[] deprs = classDoc.tags("deprecated");
   550         if (Util.isDeprecated(classDoc)) {
   551             Content strong = HtmlTree.STRONG(deprecatedPhrase);
   552             Content div = HtmlTree.DIV(HtmlStyle.block, strong);
   553             if (deprs.length > 0) {
   554                 Tag[] commentTags = deprs[0].inlineTags();
   555                 if (commentTags.length > 0) {
   556                     div.addContent(getSpace());
   557                     addInlineDeprecatedComment(classDoc, deprs[0], div);
   558                 }
   559             }
   560             classInfoTree.addContent(div);
   561         }
   562     }
   564     /**
   565      * Get links to the given classes.
   566      *
   567      * @param context the id of the context where the link will be printed
   568      * @param list the list of classes
   569      * @return a content tree for the class list
   570      */
   571     private Content getClassLinks(LinkInfoImpl.Kind context, List<?> list) {
   572         Object[] typeList = list.toArray();
   573         Content dd = new HtmlTree(HtmlTag.DD);
   574         for (int i = 0; i < list.size(); i++) {
   575             if (i > 0) {
   576                 Content separator = new StringContent(", ");
   577                 dd.addContent(separator);
   578             }
   579             if (typeList[i] instanceof ClassDoc) {
   580                 Content link = getLink(
   581                         new LinkInfoImpl(configuration, context, (ClassDoc)(typeList[i])));
   582                 dd.addContent(link);
   583             } else {
   584                 Content link = getLink(
   585                         new LinkInfoImpl(configuration, context, (Type)(typeList[i])));
   586                 dd.addContent(link);
   587             }
   588         }
   589         return dd;
   590     }
   592     /**
   593      * {@inheritDoc}
   594      */
   595     protected Content getNavLinkTree() {
   596         Content treeLinkContent = getHyperLink(DocPaths.PACKAGE_TREE,
   597                 treeLabel, "", "");
   598         Content li = HtmlTree.LI(treeLinkContent);
   599         return li;
   600     }
   602     /**
   603      * Add summary details to the navigation bar.
   604      *
   605      * @param subDiv the content tree to which the summary detail links will be added
   606      */
   607     protected void addSummaryDetailLinks(Content subDiv) {
   608         try {
   609             Content div = HtmlTree.DIV(getNavSummaryLinks());
   610             div.addContent(getNavDetailLinks());
   611             subDiv.addContent(div);
   612         } catch (Exception e) {
   613             e.printStackTrace();
   614             throw new DocletAbortException();
   615         }
   616     }
   618     /**
   619      * Get summary links for navigation bar.
   620      *
   621      * @return the content tree for the navigation summary links
   622      */
   623     protected Content getNavSummaryLinks() throws Exception {
   624         Content li = HtmlTree.LI(summaryLabel);
   625         li.addContent(getSpace());
   626         Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li);
   627         MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
   628                 configuration.getBuilderFactory().getMemberSummaryBuilder(this);
   629         String[] navLinkLabels =  new String[] {
   630             "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
   631             "doclet.navMethod"
   632         };
   633         for (int i = 0; i < navLinkLabels.length; i++ ) {
   634             Content liNav = new HtmlTree(HtmlTag.LI);
   635             if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
   636                 continue;
   637             }
   638             if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
   639                 continue;
   640             }
   641             AbstractMemberWriter writer =
   642                 ((AbstractMemberWriter) memberSummaryBuilder.
   643                 getMemberSummaryWriter(i));
   644             if (writer == null) {
   645                 liNav.addContent(getResource(navLinkLabels[i]));
   646             } else {
   647                 writer.addNavSummaryLink(
   648                         memberSummaryBuilder.members(i),
   649                         memberSummaryBuilder.getVisibleMemberMap(i), liNav);
   650             }
   651             if (i < navLinkLabels.length-1) {
   652                 addNavGap(liNav);
   653             }
   654             ulNav.addContent(liNav);
   655         }
   656         return ulNav;
   657     }
   659     /**
   660      * Get detail links for the navigation bar.
   661      *
   662      * @return the content tree for the detail links
   663      */
   664     protected Content getNavDetailLinks() throws Exception {
   665         Content li = HtmlTree.LI(detailLabel);
   666         li.addContent(getSpace());
   667         Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li);
   668         MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
   669                 configuration.getBuilderFactory().getMemberSummaryBuilder(this);
   670         String[] navLinkLabels =  new String[] {
   671             "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
   672             "doclet.navMethod"
   673         };
   674         for (int i = 1; i < navLinkLabels.length; i++ ) {
   675             Content liNav = new HtmlTree(HtmlTag.LI);
   676             AbstractMemberWriter writer =
   677                     ((AbstractMemberWriter) memberSummaryBuilder.
   678                     getMemberSummaryWriter(i));
   679             if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
   680                 continue;
   681             }
   682             if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
   683                 continue;
   684             }
   685             if (writer == null) {
   686                 liNav.addContent(getResource(navLinkLabels[i]));
   687             } else {
   688                 writer.addNavDetailLink(memberSummaryBuilder.members(i), liNav);
   689             }
   690             if (i < navLinkLabels.length - 1) {
   691                 addNavGap(liNav);
   692             }
   693             ulNav.addContent(liNav);
   694         }
   695         return ulNav;
   696     }
   698     /**
   699      * Add gap between navigation bar elements.
   700      *
   701      * @param liNav the content tree to which the gap will be added
   702      */
   703     protected void addNavGap(Content liNav) {
   704         liNav.addContent(getSpace());
   705         liNav.addContent("|");
   706         liNav.addContent(getSpace());
   707     }
   709     /**
   710      * Return the classDoc being documented.
   711      *
   712      * @return the classDoc being documented.
   713      */
   714     public ClassDoc getClassDoc() {
   715         return classDoc;
   716     }
   717 }

mercurial