Tue, 25 Dec 2012 17:23:59 -0800
8004893: the javadoc/doclet needs to be updated to accommodate lambda changes
Reviewed-by: jjg
1 /*
2 * Copyright (c) 1997, 2012, 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.io.IOException;
29 import java.util.*;
31 import com.sun.javadoc.*;
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 (pkgname.length() > 0) {
169 Content pkgNameContent = new StringContent(pkgname);
170 Content pkgNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, pkgNameContent);
171 div.addContent(pkgNameDiv);
172 }
173 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
174 LinkInfoImpl.CONTEXT_CLASS_HEADER, classDoc, false);
175 //Let's not link to ourselves in the header.
176 linkInfo.linkToSelf = false;
177 Content headerContent = new StringContent(header);
178 Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING, true,
179 HtmlStyle.title, headerContent);
180 heading.addContent(new RawHtml(getTypeParameterLinks(linkInfo)));
181 div.addContent(heading);
182 bodyTree.addContent(div);
183 return bodyTree;
184 }
186 /**
187 * {@inheritDoc}
188 */
189 public Content getClassContentHeader() {
190 return getContentHeader();
191 }
193 /**
194 * {@inheritDoc}
195 */
196 public void addFooter(Content contentTree) {
197 contentTree.addContent(HtmlConstants.END_OF_CLASS_DATA);
198 addNavLinks(false, contentTree);
199 addBottom(contentTree);
200 }
202 /**
203 * {@inheritDoc}
204 */
205 public void printDocument(Content contentTree) throws IOException {
206 printHtmlDocument(configuration.metakeywords.getMetaKeywords(classDoc),
207 true, contentTree);
208 }
210 /**
211 * {@inheritDoc}
212 */
213 public Content getClassInfoTreeHeader() {
214 return getMemberTreeHeader();
215 }
217 /**
218 * {@inheritDoc}
219 */
220 public Content getClassInfo(Content classInfoTree) {
221 return getMemberTree(HtmlStyle.description, classInfoTree);
222 }
224 /**
225 * {@inheritDoc}
226 */
227 public void addClassSignature(String modifiers, Content classInfoTree) {
228 boolean isInterface = classDoc.isInterface();
229 classInfoTree.addContent(new HtmlTree(HtmlTag.BR));
230 Content pre = new HtmlTree(HtmlTag.PRE);
231 addAnnotationInfo(classDoc, pre);
232 pre.addContent(modifiers);
233 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
234 LinkInfoImpl.CONTEXT_CLASS_SIGNATURE, classDoc, false);
235 //Let's not link to ourselves in the signature.
236 linkInfo.linkToSelf = false;
237 Content className = new StringContent(classDoc.name());
238 Content parameterLinks = new RawHtml(getTypeParameterLinks(linkInfo));
239 if (configuration.linksource) {
240 addSrcLink(classDoc, className, pre);
241 pre.addContent(parameterLinks);
242 } else {
243 Content span = HtmlTree.SPAN(HtmlStyle.strong, className);
244 span.addContent(parameterLinks);
245 pre.addContent(span);
246 }
247 if (!isInterface) {
248 Type superclass = Util.getFirstVisibleSuperClass(classDoc,
249 configuration);
250 if (superclass != null) {
251 pre.addContent(DocletConstants.NL);
252 pre.addContent("extends ");
253 Content link = new RawHtml(getLink(new LinkInfoImpl(configuration,
254 LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
255 superclass)));
256 pre.addContent(link);
257 }
258 }
259 Type[] implIntfacs = classDoc.interfaceTypes();
260 if (implIntfacs != null && implIntfacs.length > 0) {
261 int counter = 0;
262 for (int i = 0; i < implIntfacs.length; i++) {
263 ClassDoc classDoc = implIntfacs[i].asClassDoc();
264 if (! (classDoc.isPublic() ||
265 Util.isLinkable(classDoc, configuration))) {
266 continue;
267 }
268 if (counter == 0) {
269 pre.addContent(DocletConstants.NL);
270 pre.addContent(isInterface? "extends " : "implements ");
271 } else {
272 pre.addContent(", ");
273 }
274 Content link = new RawHtml(getLink(new LinkInfoImpl(configuration,
275 LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
276 implIntfacs[i])));
277 pre.addContent(link);
278 counter++;
279 }
280 }
281 classInfoTree.addContent(pre);
282 }
284 /**
285 * {@inheritDoc}
286 */
287 public void addClassDescription(Content classInfoTree) {
288 if(!configuration.nocomment) {
289 // generate documentation for the class.
290 if (classDoc.inlineTags().length > 0) {
291 addInlineComment(classDoc, classInfoTree);
292 }
293 }
294 }
296 /**
297 * {@inheritDoc}
298 */
299 public void addClassTagInfo(Content classInfoTree) {
300 if(!configuration.nocomment) {
301 // Print Information about all the tags here
302 addTagsInfo(classDoc, classInfoTree);
303 }
304 }
306 /**
307 * Get the class hierarchy tree for the given class.
308 *
309 * @param type the class to print the hierarchy for
310 * @return a content tree for class inheritence
311 */
312 private Content getClassInheritenceTree(Type type) {
313 Type sup;
314 HtmlTree classTreeUl = new HtmlTree(HtmlTag.UL);
315 classTreeUl.addStyle(HtmlStyle.inheritance);
316 Content liTree = null;
317 do {
318 sup = Util.getFirstVisibleSuperClass(
319 type instanceof ClassDoc ? (ClassDoc) type : type.asClassDoc(),
320 configuration);
321 if (sup != null) {
322 HtmlTree ul = new HtmlTree(HtmlTag.UL);
323 ul.addStyle(HtmlStyle.inheritance);
324 ul.addContent(getTreeForClassHelper(type));
325 if (liTree != null)
326 ul.addContent(liTree);
327 Content li = HtmlTree.LI(ul);
328 liTree = li;
329 type = sup;
330 }
331 else
332 classTreeUl.addContent(getTreeForClassHelper(type));
333 }
334 while (sup != null);
335 if (liTree != null)
336 classTreeUl.addContent(liTree);
337 return classTreeUl;
338 }
340 /**
341 * Get the class helper tree for the given class.
342 *
343 * @param type the class to print the helper for
344 * @return a content tree for class helper
345 */
346 private Content getTreeForClassHelper(Type type) {
347 Content li = new HtmlTree(HtmlTag.LI);
348 if (type.equals(classDoc)) {
349 String typeParameters = getTypeParameterLinks(
350 new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_TREE,
351 classDoc, false));
352 if (configuration.shouldExcludeQualifier(
353 classDoc.containingPackage().name())) {
354 li.addContent(type.asClassDoc().name());
355 li.addContent(new RawHtml(typeParameters));
356 } else {
357 li.addContent(type.asClassDoc().qualifiedName());
358 li.addContent(new RawHtml(typeParameters));
359 }
360 } else {
361 Content link = new RawHtml(getLink(new LinkInfoImpl(configuration,
362 LinkInfoImpl.CONTEXT_CLASS_TREE_PARENT,
363 type instanceof ClassDoc ? (ClassDoc) type : type,
364 configuration.getClassName(type.asClassDoc()), false)));
365 li.addContent(link);
366 }
367 return li;
368 }
370 /**
371 * {@inheritDoc}
372 */
373 public void addClassTree(Content classContentTree) {
374 if (!classDoc.isClass()) {
375 return;
376 }
377 classContentTree.addContent(getClassInheritenceTree(classDoc));
378 }
380 /**
381 * {@inheritDoc}
382 */
383 public void addTypeParamInfo(Content classInfoTree) {
384 if (classDoc.typeParamTags().length > 0) {
385 TagletOutput output = (new ParamTaglet()).getTagletOutput(classDoc,
386 getTagletWriterInstance(false));
387 Content typeParam = new RawHtml(output.toString());
388 Content dl = HtmlTree.DL(typeParam);
389 classInfoTree.addContent(dl);
390 }
391 }
393 /**
394 * {@inheritDoc}
395 */
396 public void addSubClassInfo(Content classInfoTree) {
397 if (classDoc.isClass()) {
398 if (classDoc.qualifiedName().equals("java.lang.Object") ||
399 classDoc.qualifiedName().equals("org.omg.CORBA.Object")) {
400 return; // Don't generate the list, too huge
401 }
402 List<ClassDoc> subclasses = classtree.subs(classDoc, false);
403 if (subclasses.size() > 0) {
404 Content label = getResource(
405 "doclet.Subclasses");
406 Content dt = HtmlTree.DT(label);
407 Content dl = HtmlTree.DL(dt);
408 dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_SUBCLASSES,
409 subclasses));
410 classInfoTree.addContent(dl);
411 }
412 }
413 }
415 /**
416 * {@inheritDoc}
417 */
418 public void addSubInterfacesInfo(Content classInfoTree) {
419 if (classDoc.isInterface()) {
420 List<ClassDoc> subInterfaces = classtree.allSubs(classDoc, false);
421 if (subInterfaces.size() > 0) {
422 Content label = getResource(
423 "doclet.Subinterfaces");
424 Content dt = HtmlTree.DT(label);
425 Content dl = HtmlTree.DL(dt);
426 dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_SUBINTERFACES,
427 subInterfaces));
428 classInfoTree.addContent(dl);
429 }
430 }
431 }
433 /**
434 * {@inheritDoc}
435 */
436 public void addInterfaceUsageInfo (Content classInfoTree) {
437 if (! classDoc.isInterface()) {
438 return;
439 }
440 if (classDoc.qualifiedName().equals("java.lang.Cloneable") ||
441 classDoc.qualifiedName().equals("java.io.Serializable")) {
442 return; // Don't generate the list, too big
443 }
444 List<ClassDoc> implcl = classtree.implementingclasses(classDoc);
445 if (implcl.size() > 0) {
446 Content label = getResource(
447 "doclet.Implementing_Classes");
448 Content dt = HtmlTree.DT(label);
449 Content dl = HtmlTree.DL(dt);
450 dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_CLASSES,
451 implcl));
452 classInfoTree.addContent(dl);
453 }
454 }
456 /**
457 * {@inheritDoc}
458 */
459 public void addImplementedInterfacesInfo(Content classInfoTree) {
460 //NOTE: we really should be using ClassDoc.interfaceTypes() here, but
461 // it doesn't walk up the tree like we want it to.
462 List<Type> interfaceArray = Util.getAllInterfaces(classDoc, configuration);
463 if (classDoc.isClass() && interfaceArray.size() > 0) {
464 Content label = getResource(
465 "doclet.All_Implemented_Interfaces");
466 Content dt = HtmlTree.DT(label);
467 Content dl = HtmlTree.DL(dt);
468 dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_INTERFACES,
469 interfaceArray));
470 classInfoTree.addContent(dl);
471 }
472 }
474 /**
475 * {@inheritDoc}
476 */
477 public void addSuperInterfacesInfo(Content classInfoTree) {
478 //NOTE: we really should be using ClassDoc.interfaceTypes() here, but
479 // it doesn't walk up the tree like we want it to.
480 List<Type> interfaceArray = Util.getAllInterfaces(classDoc, configuration);
481 if (classDoc.isInterface() && interfaceArray.size() > 0) {
482 Content label = getResource(
483 "doclet.All_Superinterfaces");
484 Content dt = HtmlTree.DT(label);
485 Content dl = HtmlTree.DL(dt);
486 dl.addContent(getClassLinks(LinkInfoImpl.CONTEXT_SUPER_INTERFACES,
487 interfaceArray));
488 classInfoTree.addContent(dl);
489 }
490 }
492 /**
493 * {@inheritDoc}
494 */
495 public void addNestedClassInfo(Content classInfoTree) {
496 ClassDoc outerClass = classDoc.containingClass();
497 if (outerClass != null) {
498 Content label;
499 if (outerClass.isInterface()) {
500 label = getResource(
501 "doclet.Enclosing_Interface");
502 } else {
503 label = getResource(
504 "doclet.Enclosing_Class");
505 }
506 Content dt = HtmlTree.DT(label);
507 Content dl = HtmlTree.DL(dt);
508 Content dd = new HtmlTree(HtmlTag.DD);
509 dd.addContent(new RawHtml(getLink(new LinkInfoImpl(configuration,
510 LinkInfoImpl.CONTEXT_CLASS, outerClass, false))));
511 dl.addContent(dd);
512 classInfoTree.addContent(dl);
513 }
514 }
516 /**
517 * {@inheritDoc}
518 */
519 public void addFunctionalInterfaceInfo (Content classInfoTree) {
520 if (classDoc.isFunctionalInterface()) {
521 Content dt = HtmlTree.DT(getResource("doclet.Functional_Interface"));
522 Content dl = HtmlTree.DL(dt);
523 Content dd = new HtmlTree(HtmlTag.DD);
524 dd.addContent(getResource("doclet.Functional_Interface_Message"));
525 dl.addContent(dd);
526 classInfoTree.addContent(dl);
527 }
528 }
530 /**
531 * {@inheritDoc}
532 */
533 public void addClassDeprecationInfo(Content classInfoTree) {
534 Content hr = new HtmlTree(HtmlTag.HR);
535 classInfoTree.addContent(hr);
536 Tag[] deprs = classDoc.tags("deprecated");
537 if (Util.isDeprecated(classDoc)) {
538 Content strong = HtmlTree.STRONG(deprecatedPhrase);
539 Content div = HtmlTree.DIV(HtmlStyle.block, strong);
540 if (deprs.length > 0) {
541 Tag[] commentTags = deprs[0].inlineTags();
542 if (commentTags.length > 0) {
543 div.addContent(getSpace());
544 addInlineDeprecatedComment(classDoc, deprs[0], div);
545 }
546 }
547 classInfoTree.addContent(div);
548 }
549 }
551 /**
552 * Get links to the given classes.
553 *
554 * @param context the id of the context where the link will be printed
555 * @param list the list of classes
556 * @return a content tree for the class list
557 */
558 private Content getClassLinks(int context, List<?> list) {
559 Object[] typeList = list.toArray();
560 Content dd = new HtmlTree(HtmlTag.DD);
561 for (int i = 0; i < list.size(); i++) {
562 if (i > 0) {
563 Content separator = new StringContent(", ");
564 dd.addContent(separator);
565 }
566 if (typeList[i] instanceof ClassDoc) {
567 Content link = new RawHtml(getLink(
568 new LinkInfoImpl(configuration, context, (ClassDoc)(typeList[i]))));
569 dd.addContent(link);
570 } else {
571 Content link = new RawHtml(getLink(
572 new LinkInfoImpl(configuration, context, (Type)(typeList[i]))));
573 dd.addContent(link);
574 }
575 }
576 return dd;
577 }
579 /**
580 * {@inheritDoc}
581 */
582 protected Content getNavLinkTree() {
583 Content treeLinkContent = getHyperLink(DocPaths.PACKAGE_TREE,
584 treeLabel, "", "");
585 Content li = HtmlTree.LI(treeLinkContent);
586 return li;
587 }
589 /**
590 * Add summary details to the navigation bar.
591 *
592 * @param subDiv the content tree to which the summary detail links will be added
593 */
594 protected void addSummaryDetailLinks(Content subDiv) {
595 try {
596 Content div = HtmlTree.DIV(getNavSummaryLinks());
597 div.addContent(getNavDetailLinks());
598 subDiv.addContent(div);
599 } catch (Exception e) {
600 e.printStackTrace();
601 throw new DocletAbortException();
602 }
603 }
605 /**
606 * Get summary links for navigation bar.
607 *
608 * @return the content tree for the navigation summary links
609 */
610 protected Content getNavSummaryLinks() throws Exception {
611 Content li = HtmlTree.LI(summaryLabel);
612 li.addContent(getSpace());
613 Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li);
614 MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
615 configuration.getBuilderFactory().getMemberSummaryBuilder(this);
616 String[] navLinkLabels = new String[] {
617 "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
618 "doclet.navMethod"
619 };
620 for (int i = 0; i < navLinkLabels.length; i++ ) {
621 Content liNav = new HtmlTree(HtmlTag.LI);
622 if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
623 continue;
624 }
625 if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
626 continue;
627 }
628 AbstractMemberWriter writer =
629 ((AbstractMemberWriter) memberSummaryBuilder.
630 getMemberSummaryWriter(i));
631 if (writer == null) {
632 liNav.addContent(getResource(navLinkLabels[i]));
633 } else {
634 writer.addNavSummaryLink(
635 memberSummaryBuilder.members(i),
636 memberSummaryBuilder.getVisibleMemberMap(i), liNav);
637 }
638 if (i < navLinkLabels.length-1) {
639 addNavGap(liNav);
640 }
641 ulNav.addContent(liNav);
642 }
643 return ulNav;
644 }
646 /**
647 * Get detail links for the navigation bar.
648 *
649 * @return the content tree for the detail links
650 */
651 protected Content getNavDetailLinks() throws Exception {
652 Content li = HtmlTree.LI(detailLabel);
653 li.addContent(getSpace());
654 Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li);
655 MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
656 configuration.getBuilderFactory().getMemberSummaryBuilder(this);
657 String[] navLinkLabels = new String[] {
658 "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
659 "doclet.navMethod"
660 };
661 for (int i = 1; i < navLinkLabels.length; i++ ) {
662 Content liNav = new HtmlTree(HtmlTag.LI);
663 AbstractMemberWriter writer =
664 ((AbstractMemberWriter) memberSummaryBuilder.
665 getMemberSummaryWriter(i));
666 if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
667 continue;
668 }
669 if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
670 continue;
671 }
672 if (writer == null) {
673 liNav.addContent(getResource(navLinkLabels[i]));
674 } else {
675 writer.addNavDetailLink(memberSummaryBuilder.members(i), liNav);
676 }
677 if (i < navLinkLabels.length - 1) {
678 addNavGap(liNav);
679 }
680 ulNav.addContent(liNav);
681 }
682 return ulNav;
683 }
685 /**
686 * Add gap between navigation bar elements.
687 *
688 * @param liNav the content tree to which the gap will be added
689 */
690 protected void addNavGap(Content liNav) {
691 liNav.addContent(getSpace());
692 liNav.addContent("|");
693 liNav.addContent(getSpace());
694 }
696 /**
697 * Return the classDoc being documented.
698 *
699 * @return the classDoc being documented.
700 */
701 public ClassDoc getClassDoc() {
702 return classDoc;
703 }
704 }