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 */ 25 26 package com.sun.tools.doclets.formats.html; 27 28 import java.util.*; 29 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; 38 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 { 59 60 protected final ClassDoc classDoc; 61 62 protected final ClassTree classtree; 63 64 protected final ClassDoc prev; 65 66 protected final ClassDoc next; 67 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 } 85 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 } 97 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 } 107 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 } 118 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 } 136 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 } 154 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 } 199 200 /** 201 * {@inheritDoc} 202 */ 203 public Content getClassContentHeader() { 204 return getContentHeader(); 205 } 206 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 } 215 216 /** 217 * {@inheritDoc} 218 */ 219 public void printDocument(Content contentTree) throws IOException { 220 printHtmlDocument(configuration.metakeywords.getMetaKeywords(classDoc), 221 true, contentTree); 222 } 223 224 /** 225 * {@inheritDoc} 226 */ 227 public Content getClassInfoTreeHeader() { 228 return getMemberTreeHeader(); 229 } 230 231 /** 232 * {@inheritDoc} 233 */ 234 public Content getClassInfo(Content classInfoTree) { 235 return getMemberTree(HtmlStyle.description, classInfoTree); 236 } 237 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 } 297 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 } 309 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 } 319 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 } 353 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 } 383 384 /** 385 * {@inheritDoc} 386 */ 387 public void addClassTree(Content classContentTree) { 388 if (!classDoc.isClass()) { 389 return; 390 } 391 classContentTree.addContent(getClassInheritenceTree(classDoc)); 392 } 393 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 } 406 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 } 428 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 } 446 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 } 469 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 } 487 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 } 505 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 } 529 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 } 543 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 } 564 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 } 592 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 } 602 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 } 618 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 } 659 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 } 698 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 } 709 710 /** 711 * Return the classDoc being documented. 712 * 713 * @return the classDoc being documented. 714 */ 715 public ClassDoc getClassDoc() { 716 return classDoc; 717 } 718 }