ClassWriterImpl.java revision 3593:70c752a3447a
1/* 2 * Copyright (c) 1997, 2016, 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 26package jdk.javadoc.internal.doclets.formats.html; 27 28import java.io.IOException; 29import java.util.*; 30 31import javax.lang.model.element.AnnotationMirror; 32import javax.lang.model.element.Element; 33import javax.lang.model.element.ModuleElement; 34import javax.lang.model.element.PackageElement; 35import javax.lang.model.element.TypeElement; 36import javax.lang.model.type.TypeMirror; 37import javax.lang.model.util.SimpleElementVisitor8; 38 39import com.sun.source.doctree.DocTree; 40import com.sun.tools.javac.util.DefinedBy; 41import com.sun.tools.javac.util.DefinedBy.Api; 42import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants; 43import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; 44import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; 45import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; 46import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; 47import jdk.javadoc.internal.doclets.toolkit.ClassWriter; 48import jdk.javadoc.internal.doclets.toolkit.Content; 49import jdk.javadoc.internal.doclets.toolkit.builders.MemberSummaryBuilder; 50import jdk.javadoc.internal.doclets.toolkit.taglets.ParamTaglet; 51import jdk.javadoc.internal.doclets.toolkit.util.ClassTree; 52import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper; 53import jdk.javadoc.internal.doclets.toolkit.util.DocPath; 54import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; 55import jdk.javadoc.internal.doclets.toolkit.util.DocletAbortException; 56import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants; 57import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap; 58import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap.Kind; 59 60/** 61 * Generate the Class Information Page. 62 * 63 * <p><b>This is NOT part of any supported API. 64 * If you write code that depends on this, you do so at your own risk. 65 * This code and its internal interfaces are subject to change or 66 * deletion without notice.</b> 67 * 68 * @see javax.lang.model.element.TypeElement 69 * @see java.util.Collections 70 * @see java.util.List 71 * @see java.util.ArrayList 72 * @see java.util.HashMap 73 * 74 * @author Atul M Dambalkar 75 * @author Robert Field 76 * @author Bhavesh Patel (Modified) 77 */ 78public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWriter { 79 80 protected final TypeElement typeElement; 81 82 protected final ClassTree classtree; 83 84 protected final TypeElement prev; 85 86 protected final TypeElement next; 87 88 /** 89 * @param configuration the configuration data for the doclet 90 * @param typeElement the class being documented. 91 * @param prevClass the previous class that was documented. 92 * @param nextClass the next class being documented. 93 * @param classTree the class tree for the given class. 94 * @throws java.io.IOException 95 */ 96 public ClassWriterImpl(ConfigurationImpl configuration, TypeElement typeElement, 97 TypeElement prevClass, TypeElement nextClass, ClassTree classTree) 98 throws IOException { 99 super(configuration, DocPath.forClass(configuration.utils, typeElement)); 100 this.typeElement = typeElement; 101 configuration.currentTypeElement = typeElement; 102 this.classtree = classTree; 103 this.prev = prevClass; 104 this.next = nextClass; 105 } 106 107 /** 108 * Get the module link. 109 * 110 * @return a content tree for the module link 111 */ 112 @Override 113 protected Content getNavLinkModule() { 114 Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(typeElement), 115 contents.moduleLabel); 116 Content li = HtmlTree.LI(linkContent); 117 return li; 118 } 119 120 /** 121 * Get this package link. 122 * 123 * @return a content tree for the package link 124 */ 125 @Override 126 protected Content getNavLinkPackage() { 127 Content linkContent = getHyperLink(DocPaths.PACKAGE_SUMMARY, 128 contents.packageLabel); 129 Content li = HtmlTree.LI(linkContent); 130 return li; 131 } 132 133 /** 134 * Get the class link. 135 * 136 * @return a content tree for the class link 137 */ 138 @Override 139 protected Content getNavLinkClass() { 140 Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.classLabel); 141 return li; 142 } 143 144 /** 145 * Get the class use link. 146 * 147 * @return a content tree for the class use link 148 */ 149 @Override 150 protected Content getNavLinkClassUse() { 151 Content linkContent = getHyperLink(DocPaths.CLASS_USE.resolve(filename), contents.useLabel); 152 Content li = HtmlTree.LI(linkContent); 153 return li; 154 } 155 156 /** 157 * Get link to previous class. 158 * 159 * @return a content tree for the previous class link 160 */ 161 @Override 162 public Content getNavLinkPrevious() { 163 Content li; 164 if (prev != null) { 165 Content prevLink = getLink(new LinkInfoImpl(configuration, 166 LinkInfoImpl.Kind.CLASS, prev) 167 .label(contents.prevClassLabel).strong(true)); 168 li = HtmlTree.LI(prevLink); 169 } 170 else 171 li = HtmlTree.LI(contents.prevClassLabel); 172 return li; 173 } 174 175 /** 176 * Get link to next class. 177 * 178 * @return a content tree for the next class link 179 */ 180 @Override 181 public Content getNavLinkNext() { 182 Content li; 183 if (next != null) { 184 Content nextLink = getLink(new LinkInfoImpl(configuration, 185 LinkInfoImpl.Kind.CLASS, next) 186 .label(contents.nextClassLabel).strong(true)); 187 li = HtmlTree.LI(nextLink); 188 } 189 else 190 li = HtmlTree.LI(contents.nextClassLabel); 191 return li; 192 } 193 194 /** 195 * {@inheritDoc} 196 */ 197 @Override 198 public Content getHeader(String header) { 199 HtmlTree bodyTree = getBody(true, getWindowTitle(utils.getSimpleName(typeElement))); 200 HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER)) 201 ? HtmlTree.HEADER() 202 : bodyTree; 203 addTop(htmlTree); 204 addNavLinks(true, htmlTree); 205 if (configuration.allowTag(HtmlTag.HEADER)) { 206 bodyTree.addContent(htmlTree); 207 } 208 bodyTree.addContent(HtmlConstants.START_OF_CLASS_DATA); 209 HtmlTree div = new HtmlTree(HtmlTag.DIV); 210 div.addStyle(HtmlStyle.header); 211 ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(typeElement); 212 if (configuration.showModules) { 213 Content classModuleLabel = HtmlTree.SPAN(HtmlStyle.moduleLabelInClass, contents.moduleLabel); 214 Content moduleNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, classModuleLabel); 215 moduleNameDiv.addContent(Contents.SPACE); 216 moduleNameDiv.addContent(getModuleLink(mdle, 217 new StringContent(mdle.getQualifiedName().toString()))); 218 div.addContent(moduleNameDiv); 219 } 220 PackageElement pkg = utils.containingPackage(typeElement); 221 if (!pkg.isUnnamed()) { 222 Content classPackageLabel = HtmlTree.SPAN(HtmlStyle.packageLabelInClass, contents.packageLabel); 223 Content pkgNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, classPackageLabel); 224 pkgNameDiv.addContent(Contents.SPACE); 225 Content pkgNameContent = getPackageLink(pkg, 226 new StringContent(utils.getPackageName(pkg))); 227 pkgNameDiv.addContent(pkgNameContent); 228 div.addContent(pkgNameDiv); 229 } 230 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, 231 LinkInfoImpl.Kind.CLASS_HEADER, typeElement); 232 //Let's not link to ourselves in the header. 233 linkInfo.linkToSelf = false; 234 Content headerContent = new StringContent(header); 235 Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING, true, 236 HtmlStyle.title, headerContent); 237 heading.addContent(getTypeParameterLinks(linkInfo)); 238 div.addContent(heading); 239 if (configuration.allowTag(HtmlTag.MAIN)) { 240 mainTree.addContent(div); 241 } else { 242 bodyTree.addContent(div); 243 } 244 return bodyTree; 245 } 246 247 /** 248 * {@inheritDoc} 249 */ 250 @Override 251 public Content getClassContentHeader() { 252 return getContentHeader(); 253 } 254 255 /** 256 * {@inheritDoc} 257 */ 258 @Override 259 public void addFooter(Content contentTree) { 260 contentTree.addContent(HtmlConstants.END_OF_CLASS_DATA); 261 Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER)) 262 ? HtmlTree.FOOTER() 263 : contentTree; 264 addNavLinks(false, htmlTree); 265 addBottom(htmlTree); 266 if (configuration.allowTag(HtmlTag.FOOTER)) { 267 contentTree.addContent(htmlTree); 268 } 269 } 270 271 /** 272 * {@inheritDoc} 273 */ 274 @Override 275 public void printDocument(Content contentTree) throws IOException { 276 printHtmlDocument(configuration.metakeywords.getMetaKeywords(typeElement), 277 true, contentTree); 278 } 279 280 /** 281 * {@inheritDoc} 282 */ 283 @Override 284 public Content getClassInfoTreeHeader() { 285 return getMemberTreeHeader(); 286 } 287 288 /** 289 * {@inheritDoc} 290 */ 291 @Override 292 public Content getClassInfo(Content classInfoTree) { 293 return getMemberTree(HtmlStyle.description, classInfoTree); 294 } 295 296 /** 297 * {@inheritDoc} 298 */ 299 @Override 300 public void addClassSignature(String modifiers, Content classInfoTree) { 301 classInfoTree.addContent(new HtmlTree(HtmlTag.BR)); 302 Content pre = new HtmlTree(HtmlTag.PRE); 303 addAnnotationInfo(typeElement, pre); 304 pre.addContent(modifiers); 305 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, 306 LinkInfoImpl.Kind.CLASS_SIGNATURE, typeElement); 307 //Let's not link to ourselves in the signature. 308 linkInfo.linkToSelf = false; 309 Content className = new StringContent(utils.getSimpleName(typeElement)); 310 Content parameterLinks = getTypeParameterLinks(linkInfo); 311 if (configuration.linksource) { 312 addSrcLink(typeElement, className, pre); 313 pre.addContent(parameterLinks); 314 } else { 315 Content span = HtmlTree.SPAN(HtmlStyle.typeNameLabel, className); 316 span.addContent(parameterLinks); 317 pre.addContent(span); 318 } 319 if (!utils.isInterface(typeElement)) { 320 TypeMirror superclass = utils.getFirstVisibleSuperClass(typeElement); 321 if (superclass != null) { 322 pre.addContent(DocletConstants.NL); 323 pre.addContent("extends "); 324 Content link = getLink(new LinkInfoImpl(configuration, 325 LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME, 326 superclass)); 327 pre.addContent(link); 328 } 329 } 330 List<? extends TypeMirror> interfaces = typeElement.getInterfaces(); 331 if (!interfaces.isEmpty()) { 332 boolean isFirst = true; 333 for (TypeMirror type : interfaces) { 334 TypeElement tDoc = utils.asTypeElement(type); 335 if (!(utils.isPublic(tDoc) || utils.isLinkable(tDoc))) { 336 continue; 337 } 338 if (isFirst) { 339 pre.addContent(DocletConstants.NL); 340 pre.addContent(utils.isInterface(typeElement) ? "extends " : "implements "); 341 isFirst = false; 342 } else { 343 pre.addContent(", "); 344 } 345 Content link = getLink(new LinkInfoImpl(configuration, 346 LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME, 347 type)); 348 pre.addContent(link); 349 } 350 } 351 classInfoTree.addContent(pre); 352 } 353 354 /** 355 * {@inheritDoc} 356 */ 357 @Override 358 public void addClassDescription(Content classInfoTree) { 359 if(!configuration.nocomment) { 360 // generate documentation for the class. 361 if (!utils.getBody(typeElement).isEmpty()) { 362 addInlineComment(typeElement, classInfoTree); 363 } 364 } 365 } 366 367 /** 368 * {@inheritDoc} 369 */ 370 @Override 371 public void addClassTagInfo(Content classInfoTree) { 372 if(!configuration.nocomment) { 373 // Print Information about all the tags here 374 addTagsInfo(typeElement, classInfoTree); 375 } 376 } 377 378 /** 379 * Get the class hierarchy tree for the given class. 380 * 381 * @param type the class to print the hierarchy for 382 * @return a content tree for class inheritence 383 */ 384 private Content getClassInheritenceTree(TypeMirror type) { 385 TypeMirror sup; 386 HtmlTree classTreeUl = new HtmlTree(HtmlTag.UL); 387 classTreeUl.addStyle(HtmlStyle.inheritance); 388 Content liTree = null; 389 do { 390 sup = utils.getFirstVisibleSuperClass(type); 391 if (sup != null) { 392 HtmlTree ul = new HtmlTree(HtmlTag.UL); 393 ul.addStyle(HtmlStyle.inheritance); 394 ul.addContent(getTreeForClassHelper(type)); 395 if (liTree != null) 396 ul.addContent(liTree); 397 Content li = HtmlTree.LI(ul); 398 liTree = li; 399 type = sup; 400 } else 401 classTreeUl.addContent(getTreeForClassHelper(type)); 402 } while (sup != null); 403 if (liTree != null) 404 classTreeUl.addContent(liTree); 405 return classTreeUl; 406 } 407 408 /** 409 * Get the class helper tree for the given class. 410 * 411 * @param type the class to print the helper for 412 * @return a content tree for class helper 413 */ 414 private Content getTreeForClassHelper(TypeMirror type) { 415 Content li = new HtmlTree(HtmlTag.LI); 416 if (type.equals(typeElement.asType())) { 417 Content typeParameters = getTypeParameterLinks( 418 new LinkInfoImpl(configuration, LinkInfoImpl.Kind.TREE, 419 typeElement)); 420 if (configuration.shouldExcludeQualifier(utils.containingPackage(typeElement).toString())) { 421 li.addContent(utils.asTypeElement(type).getSimpleName()); 422 li.addContent(typeParameters); 423 } else { 424 li.addContent(utils.asTypeElement(type).getQualifiedName()); 425 li.addContent(typeParameters); 426 } 427 } else { 428 Content link = getLink(new LinkInfoImpl(configuration, 429 LinkInfoImpl.Kind.CLASS_TREE_PARENT, type) 430 .label(configuration.getClassName(utils.asTypeElement(type)))); 431 li.addContent(link); 432 } 433 return li; 434 } 435 436 /** 437 * {@inheritDoc} 438 */ 439 @Override 440 public void addClassTree(Content classContentTree) { 441 if (!utils.isClass(typeElement)) { 442 return; 443 } 444 classContentTree.addContent(getClassInheritenceTree(typeElement.asType())); 445 } 446 447 /** 448 * {@inheritDoc} 449 */ 450 @Override 451 public void addTypeParamInfo(Content classInfoTree) { 452 if (!utils.getTypeParamTrees(typeElement).isEmpty()) { 453 Content typeParam = (new ParamTaglet()).getTagletOutput(typeElement, 454 getTagletWriterInstance(false)); 455 Content dl = HtmlTree.DL(typeParam); 456 classInfoTree.addContent(dl); 457 } 458 } 459 460 /** 461 * {@inheritDoc} 462 */ 463 @Override 464 public void addSubClassInfo(Content classInfoTree) { 465 if (utils.isClass(typeElement)) { 466 if (typeElement.getQualifiedName().toString().equals("java.lang.Object") || 467 typeElement.getQualifiedName().toString().equals("org.omg.CORBA.Object")) { 468 return; // Don't generate the list, too huge 469 } 470 Set<TypeElement> subclasses = classtree.directSubClasses(typeElement, false); 471 if (!subclasses.isEmpty()) { 472 Content label = contents.subclassesLabel; 473 Content dt = HtmlTree.DT(label); 474 Content dl = HtmlTree.DL(dt); 475 dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUBCLASSES, 476 subclasses)); 477 classInfoTree.addContent(dl); 478 } 479 } 480 } 481 482 /** 483 * {@inheritDoc} 484 */ 485 @Override 486 public void addSubInterfacesInfo(Content classInfoTree) { 487 if (utils.isInterface(typeElement)) { 488 Set<TypeElement> subInterfaces = classtree.allSubClasses(typeElement, false); 489 if (!subInterfaces.isEmpty()) { 490 Content label = contents.subinterfacesLabel; 491 Content dt = HtmlTree.DT(label); 492 Content dl = HtmlTree.DL(dt); 493 dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUBINTERFACES, 494 subInterfaces)); 495 classInfoTree.addContent(dl); 496 } 497 } 498 } 499 500 /** 501 * {@inheritDoc} 502 */ 503 @Override 504 public void addInterfaceUsageInfo (Content classInfoTree) { 505 if (!utils.isInterface(typeElement)) { 506 return; 507 } 508 if (typeElement.getQualifiedName().toString().equals("java.lang.Cloneable") || 509 typeElement.getQualifiedName().toString().equals("java.io.Serializable")) { 510 return; // Don't generate the list, too big 511 } 512 Set<TypeElement> implcl = classtree.implementingClasses(typeElement); 513 if (!implcl.isEmpty()) { 514 Content label = contents.implementingClassesLabel; 515 Content dt = HtmlTree.DT(label); 516 Content dl = HtmlTree.DL(dt); 517 dl.addContent(getClassLinks(LinkInfoImpl.Kind.IMPLEMENTED_CLASSES, 518 implcl)); 519 classInfoTree.addContent(dl); 520 } 521 } 522 523 /** 524 * {@inheritDoc} 525 */ 526 @Override 527 public void addImplementedInterfacesInfo(Content classInfoTree) { 528 SortedSet<TypeMirror> interfaces = new TreeSet<>(utils.makeTypeMirrorClassUseComparator()); 529 interfaces.addAll(utils.getAllInterfaces(typeElement)); 530 if (utils.isClass(typeElement) && !interfaces.isEmpty()) { 531 Content label = contents.allImplementedInterfacesLabel; 532 Content dt = HtmlTree.DT(label); 533 Content dl = HtmlTree.DL(dt); 534 dl.addContent(getClassLinks(LinkInfoImpl.Kind.IMPLEMENTED_INTERFACES, interfaces)); 535 classInfoTree.addContent(dl); 536 } 537 } 538 539 /** 540 * {@inheritDoc} 541 */ 542 @Override 543 public void addSuperInterfacesInfo(Content classInfoTree) { 544 SortedSet<TypeMirror> interfaces = 545 new TreeSet<>(utils.makeTypeMirrorIndexUseComparator()); 546 interfaces.addAll(utils.getAllInterfaces(typeElement)); 547 548 if (utils.isInterface(typeElement) && !interfaces.isEmpty()) { 549 Content label = contents.allSuperinterfacesLabel; 550 Content dt = HtmlTree.DT(label); 551 Content dl = HtmlTree.DL(dt); 552 dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUPER_INTERFACES, interfaces)); 553 classInfoTree.addContent(dl); 554 } 555 } 556 557 /** 558 * {@inheritDoc} 559 */ 560 @Override 561 public void addNestedClassInfo(final Content classInfoTree) { 562 Element outerClass = typeElement.getEnclosingElement(); 563 if (outerClass == null) 564 return; 565 new SimpleElementVisitor8<Void, Void>() { 566 @Override @DefinedBy(Api.LANGUAGE_MODEL) 567 public Void visitType(TypeElement e, Void p) { 568 Content label = utils.isInterface(e) 569 ? contents.enclosingInterfaceLabel 570 : contents.enclosingClassLabel; 571 Content dt = HtmlTree.DT(label); 572 Content dl = HtmlTree.DL(dt); 573 Content dd = new HtmlTree(HtmlTag.DD); 574 dd.addContent(getLink(new LinkInfoImpl(configuration, 575 LinkInfoImpl.Kind.CLASS, e))); 576 dl.addContent(dd); 577 classInfoTree.addContent(dl); 578 return null; 579 } 580 }.visit(outerClass); 581 } 582 583 /** 584 * {@inheritDoc} 585 */ 586 @Override 587 public void addFunctionalInterfaceInfo (Content classInfoTree) { 588 if (isFunctionalInterface()) { 589 Content dt = HtmlTree.DT(contents.functionalInterface); 590 Content dl = HtmlTree.DL(dt); 591 Content dd = new HtmlTree(HtmlTag.DD); 592 dd.addContent(contents.functionalInterfaceMessage); 593 dl.addContent(dd); 594 classInfoTree.addContent(dl); 595 } 596 } 597 598 public boolean isFunctionalInterface() { 599 List<? extends AnnotationMirror> annotationMirrors = ((Element) typeElement).getAnnotationMirrors(); 600 for (AnnotationMirror anno : annotationMirrors) { 601 if (utils.isFunctionalInterface(anno)) { 602 return true; 603 } 604 } 605 return false; 606 } 607 608 609 /** 610 * {@inheritDoc} 611 */ 612 @Override 613 public void addClassDeprecationInfo(Content classInfoTree) { 614 Content hr = new HtmlTree(HtmlTag.HR); 615 classInfoTree.addContent(hr); 616 List<? extends DocTree> deprs = utils.getBlockTags(typeElement, DocTree.Kind.DEPRECATED); 617 if (utils.isDeprecated(typeElement)) { 618 Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, contents.deprecatedPhrase); 619 Content div = HtmlTree.DIV(HtmlStyle.block, deprLabel); 620 if (!deprs.isEmpty()) { 621 CommentHelper ch = utils.getCommentHelper(typeElement); 622 DocTree dt = deprs.get(0); 623 List<? extends DocTree> commentTags = ch.getBody(configuration, dt); 624 if (!commentTags.isEmpty()) { 625 div.addContent(Contents.SPACE); 626 addInlineDeprecatedComment(typeElement, deprs.get(0), div); 627 } 628 } 629 classInfoTree.addContent(div); 630 } 631 } 632 633 /** 634 * Get links to the given classes. 635 * 636 * @param context the id of the context where the link will be printed 637 * @param list the list of classes 638 * @return a content tree for the class list 639 */ 640 private Content getClassLinks(LinkInfoImpl.Kind context, Collection<?> list) { 641 Content dd = new HtmlTree(HtmlTag.DD); 642 boolean isFirst = true; 643 for (Object type : list) { 644 if (!isFirst) { 645 Content separator = new StringContent(", "); 646 dd.addContent(separator); 647 } else { 648 isFirst = false; 649 } 650 // TODO: should we simply split this method up to avoid instanceof ? 651 if (type instanceof TypeElement) { 652 Content link = getLink( 653 new LinkInfoImpl(configuration, context, (TypeElement)(type))); 654 dd.addContent(HtmlTree.CODE(link)); 655 } else { 656 Content link = getLink( 657 new LinkInfoImpl(configuration, context, ((TypeMirror)type))); 658 dd.addContent(HtmlTree.CODE(link)); 659 } 660 } 661 return dd; 662 } 663 664 /** 665 * {@inheritDoc} 666 */ 667 @Override 668 protected Content getNavLinkTree() { 669 Content treeLinkContent = getHyperLink(DocPaths.PACKAGE_TREE, 670 contents.treeLabel, "", ""); 671 Content li = HtmlTree.LI(treeLinkContent); 672 return li; 673 } 674 675 /** 676 * Add summary details to the navigation bar. 677 * 678 * @param subDiv the content tree to which the summary detail links will be added 679 */ 680 protected void addSummaryDetailLinks(Content subDiv) { 681 try { 682 Content div = HtmlTree.DIV(getNavSummaryLinks()); 683 div.addContent(getNavDetailLinks()); 684 subDiv.addContent(div); 685 } catch (Exception e) { 686 throw new DocletAbortException(e); 687 } 688 } 689 690 /** 691 * Get summary links for navigation bar. 692 * 693 * @return the content tree for the navigation summary links 694 */ 695 protected Content getNavSummaryLinks() throws Exception { 696 Content li = HtmlTree.LI(contents.summaryLabel); 697 li.addContent(Contents.SPACE); 698 Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li); 699 MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder) 700 configuration.getBuilderFactory().getMemberSummaryBuilder(this); 701 for (VisibleMemberMap.Kind kind : VisibleMemberMap.Kind.summarySet) { 702 Content liNav = new HtmlTree(HtmlTag.LI); 703 if (kind == VisibleMemberMap.Kind.ENUM_CONSTANTS && !utils.isEnum(typeElement)) { 704 continue; 705 } 706 if (kind == VisibleMemberMap.Kind.CONSTRUCTORS && utils.isEnum(typeElement)) { 707 continue; 708 } 709 AbstractMemberWriter writer = 710 ((AbstractMemberWriter) memberSummaryBuilder.getMemberSummaryWriter(kind)); 711 if (writer == null) { 712 liNav.addContent(contents.getContent(VisibleMemberMap.Kind.getNavLinkLabels(kind))); 713 } else { 714 writer.addNavSummaryLink( 715 memberSummaryBuilder.members(kind), 716 memberSummaryBuilder.getVisibleMemberMap(kind), liNav); 717 } 718 if (kind != Kind.METHODS) { 719 addNavGap(liNav); 720 } 721 ulNav.addContent(liNav); 722 } 723 return ulNav; 724 } 725 726 /** 727 * Get detail links for the navigation bar. 728 * 729 * @return the content tree for the detail links 730 * @throws java.lang.Exception 731 */ 732 protected Content getNavDetailLinks() throws Exception { 733 Content li = HtmlTree.LI(contents.detailLabel); 734 li.addContent(Contents.SPACE); 735 Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li); 736 MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder) 737 configuration.getBuilderFactory().getMemberSummaryBuilder(this); 738 for (VisibleMemberMap.Kind kind : VisibleMemberMap.Kind.detailSet) { 739 Content liNav = new HtmlTree(HtmlTag.LI); 740 AbstractMemberWriter writer = 741 ((AbstractMemberWriter) memberSummaryBuilder. 742 getMemberSummaryWriter(kind)); 743 if (kind == VisibleMemberMap.Kind.ENUM_CONSTANTS && !utils.isEnum(typeElement)) { 744 continue; 745 } 746 if (kind == VisibleMemberMap.Kind.CONSTRUCTORS && utils.isEnum(typeElement)) { 747 continue; 748 } 749 if (writer == null) { 750 liNav.addContent(contents.getContent(VisibleMemberMap.Kind.getNavLinkLabels(kind))); 751 } else { 752 writer.addNavDetailLink(memberSummaryBuilder.members(kind), liNav); 753 } 754 if (kind != Kind.METHODS) { 755 addNavGap(liNav); 756 } 757 ulNav.addContent(liNav); 758 } 759 return ulNav; 760 } 761 762 /** 763 * Return the TypeElement being documented. 764 * 765 * @return the TypeElement being documented. 766 */ 767 @Override 768 public TypeElement getTypeElement() { 769 return typeElement; 770 } 771} 772