Sat, 13 Apr 2013 18:48:29 -0700
8009686: Generated javadoc documentation should be able to display type annotation on an array
Reviewed-by: jjg
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 = new RawHtml(getLink(new LinkInfoImpl(configuration,
128 LinkInfoImpl.CONTEXT_CLASS, prev, "",
129 configuration.getText("doclet.Prev_Class"), 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 = new RawHtml(getLink(new LinkInfoImpl(configuration,
146 LinkInfoImpl.CONTEXT_CLASS, next, "",
147 configuration.getText("doclet.Next_Class"), 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.CONTEXT_CLASS_HEADER, classDoc, false);
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(new RawHtml(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.CONTEXT_CLASS_SIGNATURE, classDoc, false);
249 //Let's not link to ourselves in the signature.
250 linkInfo.linkToSelf = false;
251 Content className = new StringContent(classDoc.name());
252 Content parameterLinks = new RawHtml(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 = new RawHtml(getLink(new LinkInfoImpl(configuration,
268 LinkInfoImpl.CONTEXT_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 = new RawHtml(getLink(new LinkInfoImpl(configuration,
289 LinkInfoImpl.CONTEXT_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 String typeParameters = getTypeParameterLinks(
364 new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_TREE,
365 classDoc, false));
366 if (configuration.shouldExcludeQualifier(
367 classDoc.containingPackage().name())) {
368 li.addContent(type.asClassDoc().name());
369 li.addContent(new RawHtml(typeParameters));
370 } else {
371 li.addContent(type.asClassDoc().qualifiedName());
372 li.addContent(new RawHtml(typeParameters));
373 }
374 } else {
375 Content link = new RawHtml(getLink(new LinkInfoImpl(configuration,
376 LinkInfoImpl.CONTEXT_CLASS_TREE_PARENT,
377 type instanceof ClassDoc ? (ClassDoc) type : type,
378 configuration.getClassName(type.asClassDoc()), false)));
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 TagletOutput output = (new ParamTaglet()).getTagletOutput(classDoc,
400 getTagletWriterInstance(false));
401 Content typeParam = new RawHtml(output.toString());
402 Content dl = HtmlTree.DL(typeParam);
403 classInfoTree.addContent(dl);
404 }
405 }
407 /**
408 * {@inheritDoc}
409 */
410 public void addSubClassInfo(Content classInfoTree) {
411 if (classDoc.isClass()) {
412 if (classDoc.qualifiedName().equals("java.lang.Object") ||
413 classDoc.qualifiedName().equals("org.omg.CORBA.Object")) {
414 return; // Don't generate the list, too huge
415 }
416 List<ClassDoc> subclasses = classtree.subs(classDoc, false);
417 if (subclasses.size() > 0) {
418 Content label = getResource(
419 "doclet.Subclasses");
420 Content dt = HtmlTree.DT(label);
421 Content dl = HtmlTree.DL(dt);
422 dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_SUBCLASSES,
423 subclasses));
424 classInfoTree.addContent(dl);
425 }
426 }
427 }
429 /**
430 * {@inheritDoc}
431 */
432 public void addSubInterfacesInfo(Content classInfoTree) {
433 if (classDoc.isInterface()) {
434 List<ClassDoc> subInterfaces = classtree.allSubs(classDoc, false);
435 if (subInterfaces.size() > 0) {
436 Content label = getResource(
437 "doclet.Subinterfaces");
438 Content dt = HtmlTree.DT(label);
439 Content dl = HtmlTree.DL(dt);
440 dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_SUBINTERFACES,
441 subInterfaces));
442 classInfoTree.addContent(dl);
443 }
444 }
445 }
447 /**
448 * {@inheritDoc}
449 */
450 public void addInterfaceUsageInfo (Content classInfoTree) {
451 if (! classDoc.isInterface()) {
452 return;
453 }
454 if (classDoc.qualifiedName().equals("java.lang.Cloneable") ||
455 classDoc.qualifiedName().equals("java.io.Serializable")) {
456 return; // Don't generate the list, too big
457 }
458 List<ClassDoc> implcl = classtree.implementingclasses(classDoc);
459 if (implcl.size() > 0) {
460 Content label = getResource(
461 "doclet.Implementing_Classes");
462 Content dt = HtmlTree.DT(label);
463 Content dl = HtmlTree.DL(dt);
464 dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_CLASSES,
465 implcl));
466 classInfoTree.addContent(dl);
467 }
468 }
470 /**
471 * {@inheritDoc}
472 */
473 public void addImplementedInterfacesInfo(Content classInfoTree) {
474 //NOTE: we really should be using ClassDoc.interfaceTypes() here, but
475 // it doesn't walk up the tree like we want it to.
476 List<Type> interfaceArray = Util.getAllInterfaces(classDoc, configuration);
477 if (classDoc.isClass() && interfaceArray.size() > 0) {
478 Content label = getResource(
479 "doclet.All_Implemented_Interfaces");
480 Content dt = HtmlTree.DT(label);
481 Content dl = HtmlTree.DL(dt);
482 dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_INTERFACES,
483 interfaceArray));
484 classInfoTree.addContent(dl);
485 }
486 }
488 /**
489 * {@inheritDoc}
490 */
491 public void addSuperInterfacesInfo(Content classInfoTree) {
492 //NOTE: we really should be using ClassDoc.interfaceTypes() here, but
493 // it doesn't walk up the tree like we want it to.
494 List<Type> interfaceArray = Util.getAllInterfaces(classDoc, configuration);
495 if (classDoc.isInterface() && interfaceArray.size() > 0) {
496 Content label = getResource(
497 "doclet.All_Superinterfaces");
498 Content dt = HtmlTree.DT(label);
499 Content dl = HtmlTree.DL(dt);
500 dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_SUPER_INTERFACES,
501 interfaceArray));
502 classInfoTree.addContent(dl);
503 }
504 }
506 /**
507 * {@inheritDoc}
508 */
509 public void addNestedClassInfo(Content classInfoTree) {
510 ClassDoc outerClass = classDoc.containingClass();
511 if (outerClass != null) {
512 Content label;
513 if (outerClass.isInterface()) {
514 label = getResource(
515 "doclet.Enclosing_Interface");
516 } else {
517 label = getResource(
518 "doclet.Enclosing_Class");
519 }
520 Content dt = HtmlTree.DT(label);
521 Content dl = HtmlTree.DL(dt);
522 Content dd = new HtmlTree(HtmlTag.DD);
523 dd.addContent(new RawHtml(getLink(new LinkInfoImpl(configuration,
524 LinkInfoImpl.CONTEXT_CLASS, outerClass, false))));
525 dl.addContent(dd);
526 classInfoTree.addContent(dl);
527 }
528 }
530 /**
531 * {@inheritDoc}
532 */
533 public void addFunctionalInterfaceInfo (Content classInfoTree) {
534 if (classDoc.isFunctionalInterface()) {
535 Content dt = HtmlTree.DT(getResource("doclet.Functional_Interface"));
536 Content dl = HtmlTree.DL(dt);
537 Content dd = new HtmlTree(HtmlTag.DD);
538 dd.addContent(getResource("doclet.Functional_Interface_Message"));
539 dl.addContent(dd);
540 classInfoTree.addContent(dl);
541 }
542 }
544 /**
545 * {@inheritDoc}
546 */
547 public void addClassDeprecationInfo(Content classInfoTree) {
548 Content hr = new HtmlTree(HtmlTag.HR);
549 classInfoTree.addContent(hr);
550 Tag[] deprs = classDoc.tags("deprecated");
551 if (Util.isDeprecated(classDoc)) {
552 Content strong = HtmlTree.STRONG(deprecatedPhrase);
553 Content div = HtmlTree.DIV(HtmlStyle.block, strong);
554 if (deprs.length > 0) {
555 Tag[] commentTags = deprs[0].inlineTags();
556 if (commentTags.length > 0) {
557 div.addContent(getSpace());
558 addInlineDeprecatedComment(classDoc, deprs[0], div);
559 }
560 }
561 classInfoTree.addContent(div);
562 }
563 }
565 /**
566 * Get links to the given classes.
567 *
568 * @param context the id of the context where the link will be printed
569 * @param list the list of classes
570 * @return a content tree for the class list
571 */
572 private Content getClassLinks(int context, List<?> list) {
573 Object[] typeList = list.toArray();
574 Content dd = new HtmlTree(HtmlTag.DD);
575 for (int i = 0; i < list.size(); i++) {
576 if (i > 0) {
577 Content separator = new StringContent(", ");
578 dd.addContent(separator);
579 }
580 if (typeList[i] instanceof ClassDoc) {
581 Content link = new RawHtml(getLink(
582 new LinkInfoImpl(configuration, context, (ClassDoc)(typeList[i]))));
583 dd.addContent(link);
584 } else {
585 Content link = new RawHtml(getLink(
586 new LinkInfoImpl(configuration, context, (Type)(typeList[i]))));
587 dd.addContent(link);
588 }
589 }
590 return dd;
591 }
593 /**
594 * {@inheritDoc}
595 */
596 protected Content getNavLinkTree() {
597 Content treeLinkContent = getHyperLink(DocPaths.PACKAGE_TREE,
598 treeLabel, "", "");
599 Content li = HtmlTree.LI(treeLinkContent);
600 return li;
601 }
603 /**
604 * Add summary details to the navigation bar.
605 *
606 * @param subDiv the content tree to which the summary detail links will be added
607 */
608 protected void addSummaryDetailLinks(Content subDiv) {
609 try {
610 Content div = HtmlTree.DIV(getNavSummaryLinks());
611 div.addContent(getNavDetailLinks());
612 subDiv.addContent(div);
613 } catch (Exception e) {
614 e.printStackTrace();
615 throw new DocletAbortException();
616 }
617 }
619 /**
620 * Get summary links for navigation bar.
621 *
622 * @return the content tree for the navigation summary links
623 */
624 protected Content getNavSummaryLinks() throws Exception {
625 Content li = HtmlTree.LI(summaryLabel);
626 li.addContent(getSpace());
627 Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li);
628 MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
629 configuration.getBuilderFactory().getMemberSummaryBuilder(this);
630 String[] navLinkLabels = new String[] {
631 "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
632 "doclet.navMethod"
633 };
634 for (int i = 0; i < navLinkLabels.length; i++ ) {
635 Content liNav = new HtmlTree(HtmlTag.LI);
636 if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
637 continue;
638 }
639 if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
640 continue;
641 }
642 AbstractMemberWriter writer =
643 ((AbstractMemberWriter) memberSummaryBuilder.
644 getMemberSummaryWriter(i));
645 if (writer == null) {
646 liNav.addContent(getResource(navLinkLabels[i]));
647 } else {
648 writer.addNavSummaryLink(
649 memberSummaryBuilder.members(i),
650 memberSummaryBuilder.getVisibleMemberMap(i), liNav);
651 }
652 if (i < navLinkLabels.length-1) {
653 addNavGap(liNav);
654 }
655 ulNav.addContent(liNav);
656 }
657 return ulNav;
658 }
660 /**
661 * Get detail links for the navigation bar.
662 *
663 * @return the content tree for the detail links
664 */
665 protected Content getNavDetailLinks() throws Exception {
666 Content li = HtmlTree.LI(detailLabel);
667 li.addContent(getSpace());
668 Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li);
669 MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
670 configuration.getBuilderFactory().getMemberSummaryBuilder(this);
671 String[] navLinkLabels = new String[] {
672 "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
673 "doclet.navMethod"
674 };
675 for (int i = 1; i < navLinkLabels.length; i++ ) {
676 Content liNav = new HtmlTree(HtmlTag.LI);
677 AbstractMemberWriter writer =
678 ((AbstractMemberWriter) memberSummaryBuilder.
679 getMemberSummaryWriter(i));
680 if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
681 continue;
682 }
683 if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
684 continue;
685 }
686 if (writer == null) {
687 liNav.addContent(getResource(navLinkLabels[i]));
688 } else {
689 writer.addNavDetailLink(memberSummaryBuilder.members(i), liNav);
690 }
691 if (i < navLinkLabels.length - 1) {
692 addNavGap(liNav);
693 }
694 ulNav.addContent(liNav);
695 }
696 return ulNav;
697 }
699 /**
700 * Add gap between navigation bar elements.
701 *
702 * @param liNav the content tree to which the gap will be added
703 */
704 protected void addNavGap(Content liNav) {
705 liNav.addContent(getSpace());
706 liNav.addContent("|");
707 liNav.addContent(getSpace());
708 }
710 /**
711 * Return the classDoc being documented.
712 *
713 * @return the classDoc being documented.
714 */
715 public ClassDoc getClassDoc() {
716 return classDoc;
717 }
718 }