ClassWriterImpl.java revision 3824:376ee1fd40c3
1107120Sjulian/* 2107120Sjulian * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 3107120Sjulian * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4107120Sjulian * 5107120Sjulian * This code is free software; you can redistribute it and/or modify it 6107120Sjulian * under the terms of the GNU General Public License version 2 only, as 7107120Sjulian * published by the Free Software Foundation. Oracle designates this 8107120Sjulian * particular file as subject to the "Classpath" exception as provided 9107120Sjulian * by Oracle in the LICENSE file that accompanied this code. 10107120Sjulian * 11107120Sjulian * This code is distributed in the hope that it will be useful, but WITHOUT 12107120Sjulian * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13107120Sjulian * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14107120Sjulian * version 2 for more details (a copy is included in the LICENSE file that 15107120Sjulian * accompanied this code). 16107120Sjulian * 17107120Sjulian * You should have received a copy of the GNU General Public License version 18107120Sjulian * 2 along with this work; if not, write to the Free Software Foundation, 19107120Sjulian * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20107120Sjulian * 21107120Sjulian * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22107120Sjulian * or visit www.oracle.com if you need additional information or have any 23107120Sjulian * questions. 24107120Sjulian */ 25107120Sjulian 26107120Sjulianpackage jdk.javadoc.internal.doclets.formats.html; 27107120Sjulian 28121054Semaximport java.util.*; 29107120Sjulian 30107120Sjulianimport javax.lang.model.element.AnnotationMirror; 31107120Sjulianimport javax.lang.model.element.Element; 32107120Sjulianimport javax.lang.model.element.ModuleElement; 33107120Sjulianimport javax.lang.model.element.PackageElement; 34107120Sjulianimport javax.lang.model.element.TypeElement; 35107120Sjulianimport javax.lang.model.type.TypeMirror; 36107120Sjulianimport javax.lang.model.util.SimpleElementVisitor8; 37121054Semax 38107120Sjulianimport com.sun.source.doctree.DocTree; 39107120Sjulianimport jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants; 40107120Sjulianimport jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; 41107120Sjulianimport jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; 42107120Sjulianimport jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; 43107120Sjulianimport jdk.javadoc.internal.doclets.formats.html.markup.StringContent; 44107120Sjulianimport jdk.javadoc.internal.doclets.toolkit.ClassWriter; 45107120Sjulianimport jdk.javadoc.internal.doclets.toolkit.Content; 46107120Sjulianimport jdk.javadoc.internal.doclets.toolkit.builders.MemberSummaryBuilder; 47107120Sjulianimport jdk.javadoc.internal.doclets.toolkit.taglets.ParamTaglet; 48107120Sjulianimport jdk.javadoc.internal.doclets.toolkit.util.ClassTree; 49107120Sjulianimport jdk.javadoc.internal.doclets.toolkit.util.CommentHelper; 50107120Sjulianimport jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; 51107120Sjulianimport jdk.javadoc.internal.doclets.toolkit.util.DocPath; 52107120Sjulianimport jdk.javadoc.internal.doclets.toolkit.util.DocPaths; 53107120Sjulianimport jdk.javadoc.internal.doclets.toolkit.util.DocletConstants; 54107120Sjulianimport jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap; 55107120Sjulianimport jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap.Kind; 56107120Sjulian 57107120Sjulian/** 58107120Sjulian * Generate the Class Information Page. 59107120Sjulian * 60107120Sjulian * <p><b>This is NOT part of any supported API. 61107120Sjulian * If you write code that depends on this, you do so at your own risk. 62107120Sjulian * This code and its internal interfaces are subject to change or 63107120Sjulian * deletion without notice.</b> 64107120Sjulian * 65107120Sjulian * @see javax.lang.model.element.TypeElement 66107120Sjulian * @see java.util.Collections 67107120Sjulian * @see java.util.List 68107120Sjulian * @see java.util.ArrayList 69114879Sjulian * @see java.util.HashMap 70107120Sjulian * 71107120Sjulian * @author Atul M Dambalkar 72107120Sjulian * @author Robert Field 73107120Sjulian * @author Bhavesh Patel (Modified) 74107120Sjulian */ 75107120Sjulianpublic class ClassWriterImpl extends SubWriterHolderWriter implements ClassWriter { 76107120Sjulian 77107120Sjulian protected final TypeElement typeElement; 78107120Sjulian 79107120Sjulian protected final ClassTree classtree; 80107120Sjulian 81107120Sjulian protected final TypeElement prev; 82107120Sjulian 83107120Sjulian protected final TypeElement next; 84107120Sjulian 85107120Sjulian /** 86107120Sjulian * @param configuration the configuration data for the doclet 87107120Sjulian * @param typeElement the class being documented. 88107120Sjulian * @param prevClass the previous class that was documented. 89114879Sjulian * @param nextClass the next class being documented. 90107120Sjulian * @param classTree the class tree for the given class. 91107120Sjulian */ 92107120Sjulian public ClassWriterImpl(ConfigurationImpl configuration, TypeElement typeElement, 93107120Sjulian TypeElement prevClass, TypeElement nextClass, ClassTree classTree) { 94107120Sjulian super(configuration, DocPath.forClass(configuration.utils, typeElement)); 95107120Sjulian this.typeElement = typeElement; 96107120Sjulian configuration.currentTypeElement = typeElement; 97107120Sjulian this.classtree = classTree; 98107120Sjulian this.prev = prevClass; 99107120Sjulian this.next = nextClass; 100107120Sjulian } 101107120Sjulian 102107120Sjulian /** 103107120Sjulian * Get the module link. 104188130Semax * 105188130Semax * @return a content tree for the module link 106188130Semax */ 107188130Semax @Override 108107120Sjulian protected Content getNavLinkModule() { 109107120Sjulian Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(typeElement), 110107120Sjulian contents.moduleLabel); 111107120Sjulian Content li = HtmlTree.LI(linkContent); 112107120Sjulian return li; 113107120Sjulian } 114107120Sjulian 115107120Sjulian /** 116107120Sjulian * Get this package link. 117107120Sjulian * 118107120Sjulian * @return a content tree for the package link 119107120Sjulian */ 120107120Sjulian @Override 121107120Sjulian protected Content getNavLinkPackage() { 122107120Sjulian Content linkContent = getHyperLink(DocPaths.PACKAGE_SUMMARY, 123107120Sjulian contents.packageLabel); 124107120Sjulian Content li = HtmlTree.LI(linkContent); 125107120Sjulian return li; 126107120Sjulian } 127107120Sjulian 128107120Sjulian /** 129107120Sjulian * Get the class link. 130107120Sjulian * 131107120Sjulian * @return a content tree for the class link 132107120Sjulian */ 133107120Sjulian @Override 134107120Sjulian protected Content getNavLinkClass() { 135107120Sjulian Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.classLabel); 136107120Sjulian return li; 137107120Sjulian } 138107120Sjulian 139107120Sjulian /** 140107120Sjulian * Get the class use link. 141107120Sjulian * 142107120Sjulian * @return a content tree for the class use link 143107120Sjulian */ 144107120Sjulian @Override 145107120Sjulian protected Content getNavLinkClassUse() { 146107120Sjulian Content linkContent = getHyperLink(DocPaths.CLASS_USE.resolve(filename), contents.useLabel); 147107120Sjulian Content li = HtmlTree.LI(linkContent); 148107120Sjulian return li; 149107120Sjulian } 150107120Sjulian 151107120Sjulian /** 152107120Sjulian * Get link to previous class. 153107120Sjulian * 154107120Sjulian * @return a content tree for the previous class link 155107120Sjulian */ 156107120Sjulian @Override 157107120Sjulian public Content getNavLinkPrevious() { 158107120Sjulian Content li; 159107120Sjulian if (prev != null) { 160107120Sjulian Content prevLink = getLink(new LinkInfoImpl(configuration, 161107120Sjulian LinkInfoImpl.Kind.CLASS, prev) 162107120Sjulian .label(contents.prevClassLabel).strong(true)); 163122758Sharti li = HtmlTree.LI(prevLink); 164107120Sjulian } 165107120Sjulian else 166107120Sjulian li = HtmlTree.LI(contents.prevClassLabel); 167107120Sjulian return li; 168107120Sjulian } 169107120Sjulian 170107120Sjulian /** 171107120Sjulian * Get link to next class. 172107120Sjulian * 173107120Sjulian * @return a content tree for the next class link 174107120Sjulian */ 175107120Sjulian @Override 176107120Sjulian public Content getNavLinkNext() { 177107120Sjulian Content li; 178107120Sjulian if (next != null) { 179107120Sjulian Content nextLink = getLink(new LinkInfoImpl(configuration, 180107120Sjulian LinkInfoImpl.Kind.CLASS, next) 181107120Sjulian .label(contents.nextClassLabel).strong(true)); 182107120Sjulian li = HtmlTree.LI(nextLink); 183107120Sjulian } 184107120Sjulian else 185107120Sjulian li = HtmlTree.LI(contents.nextClassLabel); 186107120Sjulian return li; 187107120Sjulian } 188107120Sjulian 189107120Sjulian /** 190107120Sjulian * {@inheritDoc} 191107120Sjulian */ 192107120Sjulian @Override 193107120Sjulian public Content getHeader(String header) { 194107120Sjulian HtmlTree bodyTree = getBody(true, getWindowTitle(utils.getSimpleName(typeElement))); 195107120Sjulian HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER)) 196107120Sjulian ? HtmlTree.HEADER() 197107120Sjulian : bodyTree; 198107120Sjulian addTop(htmlTree); 199107120Sjulian addNavLinks(true, htmlTree); 200107120Sjulian if (configuration.allowTag(HtmlTag.HEADER)) { 201107120Sjulian bodyTree.addContent(htmlTree); 202107120Sjulian } 203107120Sjulian bodyTree.addContent(HtmlConstants.START_OF_CLASS_DATA); 204107120Sjulian HtmlTree div = new HtmlTree(HtmlTag.DIV); 205107120Sjulian div.addStyle(HtmlStyle.header); 206107120Sjulian if (configuration.showModules) { 207107120Sjulian ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(typeElement); 208107120Sjulian Content classModuleLabel = HtmlTree.SPAN(HtmlStyle.moduleLabelInClass, contents.moduleLabel); 209107120Sjulian Content moduleNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, classModuleLabel); 210107120Sjulian moduleNameDiv.addContent(Contents.SPACE); 211107120Sjulian moduleNameDiv.addContent(getModuleLink(mdle, 212107120Sjulian new StringContent(mdle.getQualifiedName().toString()))); 213107120Sjulian div.addContent(moduleNameDiv); 214107120Sjulian } 215107120Sjulian PackageElement pkg = utils.containingPackage(typeElement); 216107120Sjulian if (!pkg.isUnnamed()) { 217107120Sjulian Content classPackageLabel = HtmlTree.SPAN(HtmlStyle.packageLabelInClass, contents.packageLabel); 218107120Sjulian Content pkgNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, classPackageLabel); 219107120Sjulian pkgNameDiv.addContent(Contents.SPACE); 220107120Sjulian Content pkgNameContent = getPackageLink(pkg, 221107120Sjulian new StringContent(utils.getPackageName(pkg))); 222107120Sjulian pkgNameDiv.addContent(pkgNameContent); 223107120Sjulian div.addContent(pkgNameDiv); 224107120Sjulian } 225107120Sjulian LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, 226107120Sjulian LinkInfoImpl.Kind.CLASS_HEADER, typeElement); 227107120Sjulian //Let's not link to ourselves in the header. 228107120Sjulian linkInfo.linkToSelf = false; 229107120Sjulian Content headerContent = new StringContent(header); 230107120Sjulian Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING, true, 231107120Sjulian HtmlStyle.title, headerContent); 232107120Sjulian heading.addContent(getTypeParameterLinks(linkInfo)); 233107120Sjulian div.addContent(heading); 234107120Sjulian if (configuration.allowTag(HtmlTag.MAIN)) { 235107120Sjulian mainTree.addContent(div); 236107120Sjulian } else { 237107120Sjulian bodyTree.addContent(div); 238107120Sjulian } 239107120Sjulian return bodyTree; 240107120Sjulian } 241107120Sjulian 242107120Sjulian /** 243107120Sjulian * {@inheritDoc} 244107120Sjulian */ 245107120Sjulian @Override 246107120Sjulian public Content getClassContentHeader() { 247107120Sjulian return getContentHeader(); 248107120Sjulian } 249107120Sjulian 250107120Sjulian /** 251107120Sjulian * {@inheritDoc} 252107120Sjulian */ 253107120Sjulian @Override 254107120Sjulian public void addFooter(Content contentTree) { 255107120Sjulian contentTree.addContent(HtmlConstants.END_OF_CLASS_DATA); 256107120Sjulian Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER)) 257107120Sjulian ? HtmlTree.FOOTER() 258114879Sjulian : contentTree; 259107120Sjulian addNavLinks(false, htmlTree); 260244040Seadler addBottom(htmlTree); 261107120Sjulian if (configuration.allowTag(HtmlTag.FOOTER)) { 262107120Sjulian contentTree.addContent(htmlTree); 263114879Sjulian } 264114879Sjulian } 265107120Sjulian 266107120Sjulian /** 267107120Sjulian * {@inheritDoc} 268107120Sjulian */ 269 @Override 270 public void printDocument(Content contentTree) throws DocFileIOException { 271 printHtmlDocument(configuration.metakeywords.getMetaKeywords(typeElement), 272 true, contentTree); 273 } 274 275 /** 276 * {@inheritDoc} 277 */ 278 @Override 279 public Content getClassInfoTreeHeader() { 280 return getMemberTreeHeader(); 281 } 282 283 /** 284 * {@inheritDoc} 285 */ 286 @Override 287 public Content getClassInfo(Content classInfoTree) { 288 return getMemberTree(HtmlStyle.description, classInfoTree); 289 } 290 291 /** 292 * {@inheritDoc} 293 */ 294 @Override 295 public void addClassSignature(String modifiers, Content classInfoTree) { 296 classInfoTree.addContent(new HtmlTree(HtmlTag.BR)); 297 Content pre = new HtmlTree(HtmlTag.PRE); 298 addAnnotationInfo(typeElement, pre); 299 pre.addContent(modifiers); 300 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, 301 LinkInfoImpl.Kind.CLASS_SIGNATURE, typeElement); 302 //Let's not link to ourselves in the signature. 303 linkInfo.linkToSelf = false; 304 Content className = new StringContent(utils.getSimpleName(typeElement)); 305 Content parameterLinks = getTypeParameterLinks(linkInfo); 306 if (configuration.linksource) { 307 addSrcLink(typeElement, className, pre); 308 pre.addContent(parameterLinks); 309 } else { 310 Content span = HtmlTree.SPAN(HtmlStyle.typeNameLabel, className); 311 span.addContent(parameterLinks); 312 pre.addContent(span); 313 } 314 if (!utils.isInterface(typeElement)) { 315 TypeMirror superclass = utils.getFirstVisibleSuperClass(typeElement); 316 if (superclass != null) { 317 pre.addContent(DocletConstants.NL); 318 pre.addContent("extends "); 319 Content link = getLink(new LinkInfoImpl(configuration, 320 LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME, 321 superclass)); 322 pre.addContent(link); 323 } 324 } 325 List<? extends TypeMirror> interfaces = typeElement.getInterfaces(); 326 if (!interfaces.isEmpty()) { 327 boolean isFirst = true; 328 for (TypeMirror type : interfaces) { 329 TypeElement tDoc = utils.asTypeElement(type); 330 if (!(utils.isPublic(tDoc) || utils.isLinkable(tDoc))) { 331 continue; 332 } 333 if (isFirst) { 334 pre.addContent(DocletConstants.NL); 335 pre.addContent(utils.isInterface(typeElement) ? "extends " : "implements "); 336 isFirst = false; 337 } else { 338 pre.addContent(", "); 339 } 340 Content link = getLink(new LinkInfoImpl(configuration, 341 LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME, 342 type)); 343 pre.addContent(link); 344 } 345 } 346 classInfoTree.addContent(pre); 347 } 348 349 /** 350 * {@inheritDoc} 351 */ 352 @Override 353 public void addClassDescription(Content classInfoTree) { 354 if(!configuration.nocomment) { 355 // generate documentation for the class. 356 if (!utils.getFullBody(typeElement).isEmpty()) { 357 addInlineComment(typeElement, classInfoTree); 358 } 359 } 360 } 361 362 /** 363 * {@inheritDoc} 364 */ 365 @Override 366 public void addClassTagInfo(Content classInfoTree) { 367 if(!configuration.nocomment) { 368 // Print Information about all the tags here 369 addTagsInfo(typeElement, classInfoTree); 370 } 371 } 372 373 /** 374 * Get the class hierarchy tree for the given class. 375 * 376 * @param type the class to print the hierarchy for 377 * @return a content tree for class inheritence 378 */ 379 private Content getClassInheritenceTree(TypeMirror type) { 380 TypeMirror sup; 381 HtmlTree classTreeUl = new HtmlTree(HtmlTag.UL); 382 classTreeUl.addStyle(HtmlStyle.inheritance); 383 Content liTree = null; 384 do { 385 sup = utils.getFirstVisibleSuperClass(type); 386 if (sup != null) { 387 HtmlTree ul = new HtmlTree(HtmlTag.UL); 388 ul.addStyle(HtmlStyle.inheritance); 389 ul.addContent(getTreeForClassHelper(type)); 390 if (liTree != null) 391 ul.addContent(liTree); 392 Content li = HtmlTree.LI(ul); 393 liTree = li; 394 type = sup; 395 } else 396 classTreeUl.addContent(getTreeForClassHelper(type)); 397 } while (sup != null); 398 if (liTree != null) 399 classTreeUl.addContent(liTree); 400 return classTreeUl; 401 } 402 403 /** 404 * Get the class helper tree for the given class. 405 * 406 * @param type the class to print the helper for 407 * @return a content tree for class helper 408 */ 409 private Content getTreeForClassHelper(TypeMirror type) { 410 Content li = new HtmlTree(HtmlTag.LI); 411 if (type.equals(typeElement.asType())) { 412 Content typeParameters = getTypeParameterLinks( 413 new LinkInfoImpl(configuration, LinkInfoImpl.Kind.TREE, 414 typeElement)); 415 if (configuration.shouldExcludeQualifier(utils.containingPackage(typeElement).toString())) { 416 li.addContent(utils.asTypeElement(type).getSimpleName()); 417 li.addContent(typeParameters); 418 } else { 419 li.addContent(utils.asTypeElement(type).getQualifiedName()); 420 li.addContent(typeParameters); 421 } 422 } else { 423 Content link = getLink(new LinkInfoImpl(configuration, 424 LinkInfoImpl.Kind.CLASS_TREE_PARENT, type) 425 .label(configuration.getClassName(utils.asTypeElement(type)))); 426 li.addContent(link); 427 } 428 return li; 429 } 430 431 /** 432 * {@inheritDoc} 433 */ 434 @Override 435 public void addClassTree(Content classContentTree) { 436 if (!utils.isClass(typeElement)) { 437 return; 438 } 439 classContentTree.addContent(getClassInheritenceTree(typeElement.asType())); 440 } 441 442 /** 443 * {@inheritDoc} 444 */ 445 @Override 446 public void addTypeParamInfo(Content classInfoTree) { 447 if (!utils.getTypeParamTrees(typeElement).isEmpty()) { 448 Content typeParam = (new ParamTaglet()).getTagletOutput(typeElement, 449 getTagletWriterInstance(false)); 450 Content dl = HtmlTree.DL(typeParam); 451 classInfoTree.addContent(dl); 452 } 453 } 454 455 /** 456 * {@inheritDoc} 457 */ 458 @Override 459 public void addSubClassInfo(Content classInfoTree) { 460 if (utils.isClass(typeElement)) { 461 if (typeElement.getQualifiedName().toString().equals("java.lang.Object") || 462 typeElement.getQualifiedName().toString().equals("org.omg.CORBA.Object")) { 463 return; // Don't generate the list, too huge 464 } 465 Set<TypeElement> subclasses = classtree.directSubClasses(typeElement, false); 466 if (!subclasses.isEmpty()) { 467 Content label = contents.subclassesLabel; 468 Content dt = HtmlTree.DT(label); 469 Content dl = HtmlTree.DL(dt); 470 dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUBCLASSES, 471 subclasses)); 472 classInfoTree.addContent(dl); 473 } 474 } 475 } 476 477 /** 478 * {@inheritDoc} 479 */ 480 @Override 481 public void addSubInterfacesInfo(Content classInfoTree) { 482 if (utils.isInterface(typeElement)) { 483 Set<TypeElement> subInterfaces = classtree.allSubClasses(typeElement, false); 484 if (!subInterfaces.isEmpty()) { 485 Content label = contents.subinterfacesLabel; 486 Content dt = HtmlTree.DT(label); 487 Content dl = HtmlTree.DL(dt); 488 dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUBINTERFACES, 489 subInterfaces)); 490 classInfoTree.addContent(dl); 491 } 492 } 493 } 494 495 /** 496 * {@inheritDoc} 497 */ 498 @Override 499 public void addInterfaceUsageInfo (Content classInfoTree) { 500 if (!utils.isInterface(typeElement)) { 501 return; 502 } 503 if (typeElement.getQualifiedName().toString().equals("java.lang.Cloneable") || 504 typeElement.getQualifiedName().toString().equals("java.io.Serializable")) { 505 return; // Don't generate the list, too big 506 } 507 Set<TypeElement> implcl = classtree.implementingClasses(typeElement); 508 if (!implcl.isEmpty()) { 509 Content label = contents.implementingClassesLabel; 510 Content dt = HtmlTree.DT(label); 511 Content dl = HtmlTree.DL(dt); 512 dl.addContent(getClassLinks(LinkInfoImpl.Kind.IMPLEMENTED_CLASSES, 513 implcl)); 514 classInfoTree.addContent(dl); 515 } 516 } 517 518 /** 519 * {@inheritDoc} 520 */ 521 @Override 522 public void addImplementedInterfacesInfo(Content classInfoTree) { 523 SortedSet<TypeMirror> interfaces = new TreeSet<>(utils.makeTypeMirrorClassUseComparator()); 524 interfaces.addAll(utils.getAllInterfaces(typeElement)); 525 if (utils.isClass(typeElement) && !interfaces.isEmpty()) { 526 Content label = contents.allImplementedInterfacesLabel; 527 Content dt = HtmlTree.DT(label); 528 Content dl = HtmlTree.DL(dt); 529 dl.addContent(getClassLinks(LinkInfoImpl.Kind.IMPLEMENTED_INTERFACES, interfaces)); 530 classInfoTree.addContent(dl); 531 } 532 } 533 534 /** 535 * {@inheritDoc} 536 */ 537 @Override 538 public void addSuperInterfacesInfo(Content classInfoTree) { 539 SortedSet<TypeMirror> interfaces = 540 new TreeSet<>(utils.makeTypeMirrorIndexUseComparator()); 541 interfaces.addAll(utils.getAllInterfaces(typeElement)); 542 543 if (utils.isInterface(typeElement) && !interfaces.isEmpty()) { 544 Content label = contents.allSuperinterfacesLabel; 545 Content dt = HtmlTree.DT(label); 546 Content dl = HtmlTree.DL(dt); 547 dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUPER_INTERFACES, interfaces)); 548 classInfoTree.addContent(dl); 549 } 550 } 551 552 /** 553 * {@inheritDoc} 554 */ 555 @Override 556 public void addNestedClassInfo(final Content classInfoTree) { 557 Element outerClass = typeElement.getEnclosingElement(); 558 if (outerClass == null) 559 return; 560 new SimpleElementVisitor8<Void, Void>() { 561 @Override 562 public Void visitType(TypeElement e, Void p) { 563 Content label = utils.isInterface(e) 564 ? contents.enclosingInterfaceLabel 565 : contents.enclosingClassLabel; 566 Content dt = HtmlTree.DT(label); 567 Content dl = HtmlTree.DL(dt); 568 Content dd = new HtmlTree(HtmlTag.DD); 569 dd.addContent(getLink(new LinkInfoImpl(configuration, 570 LinkInfoImpl.Kind.CLASS, e))); 571 dl.addContent(dd); 572 classInfoTree.addContent(dl); 573 return null; 574 } 575 }.visit(outerClass); 576 } 577 578 /** 579 * {@inheritDoc} 580 */ 581 @Override 582 public void addFunctionalInterfaceInfo (Content classInfoTree) { 583 if (isFunctionalInterface()) { 584 Content dt = HtmlTree.DT(contents.functionalInterface); 585 Content dl = HtmlTree.DL(dt); 586 Content dd = new HtmlTree(HtmlTag.DD); 587 dd.addContent(contents.functionalInterfaceMessage); 588 dl.addContent(dd); 589 classInfoTree.addContent(dl); 590 } 591 } 592 593 public boolean isFunctionalInterface() { 594 List<? extends AnnotationMirror> annotationMirrors = ((Element) typeElement).getAnnotationMirrors(); 595 for (AnnotationMirror anno : annotationMirrors) { 596 if (utils.isFunctionalInterface(anno)) { 597 return true; 598 } 599 } 600 return false; 601 } 602 603 604 /** 605 * {@inheritDoc} 606 */ 607 @Override 608 public void addClassDeprecationInfo(Content classInfoTree) { 609 Content hr = new HtmlTree(HtmlTag.HR); 610 classInfoTree.addContent(hr); 611 List<? extends DocTree> deprs = utils.getBlockTags(typeElement, DocTree.Kind.DEPRECATED); 612 if (utils.isDeprecated(typeElement)) { 613 Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(typeElement)); 614 Content div = HtmlTree.DIV(HtmlStyle.block, deprLabel); 615 if (!deprs.isEmpty()) { 616 CommentHelper ch = utils.getCommentHelper(typeElement); 617 DocTree dt = deprs.get(0); 618 List<? extends DocTree> commentTags = ch.getBody(configuration, dt); 619 if (!commentTags.isEmpty()) { 620 div.addContent(Contents.SPACE); 621 addInlineDeprecatedComment(typeElement, deprs.get(0), div); 622 } 623 } 624 classInfoTree.addContent(div); 625 } 626 } 627 628 /** 629 * Get links to the given classes. 630 * 631 * @param context the id of the context where the link will be printed 632 * @param list the list of classes 633 * @return a content tree for the class list 634 */ 635 private Content getClassLinks(LinkInfoImpl.Kind context, Collection<?> list) { 636 Content dd = new HtmlTree(HtmlTag.DD); 637 boolean isFirst = true; 638 for (Object type : list) { 639 if (!isFirst) { 640 Content separator = new StringContent(", "); 641 dd.addContent(separator); 642 } else { 643 isFirst = false; 644 } 645 // TODO: should we simply split this method up to avoid instanceof ? 646 if (type instanceof TypeElement) { 647 Content link = getLink( 648 new LinkInfoImpl(configuration, context, (TypeElement)(type))); 649 dd.addContent(HtmlTree.CODE(link)); 650 } else { 651 Content link = getLink( 652 new LinkInfoImpl(configuration, context, ((TypeMirror)type))); 653 dd.addContent(HtmlTree.CODE(link)); 654 } 655 } 656 return dd; 657 } 658 659 /** 660 * {@inheritDoc} 661 */ 662 @Override 663 protected Content getNavLinkTree() { 664 Content treeLinkContent = getHyperLink(DocPaths.PACKAGE_TREE, 665 contents.treeLabel, "", ""); 666 Content li = HtmlTree.LI(treeLinkContent); 667 return li; 668 } 669 670 /** 671 * Add summary details to the navigation bar. 672 * 673 * @param subDiv the content tree to which the summary detail links will be added 674 */ 675 @Override 676 protected void addSummaryDetailLinks(Content subDiv) { 677 Content div = HtmlTree.DIV(getNavSummaryLinks()); 678 div.addContent(getNavDetailLinks()); 679 subDiv.addContent(div); 680 } 681 682 /** 683 * Get summary links for navigation bar. 684 * 685 * @return the content tree for the navigation summary links 686 */ 687 protected Content getNavSummaryLinks() { 688 Content li = HtmlTree.LI(contents.summaryLabel); 689 li.addContent(Contents.SPACE); 690 Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li); 691 MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder) 692 configuration.getBuilderFactory().getMemberSummaryBuilder(this); 693 for (VisibleMemberMap.Kind kind : VisibleMemberMap.Kind.summarySet) { 694 Content liNav = new HtmlTree(HtmlTag.LI); 695 if (kind == VisibleMemberMap.Kind.ENUM_CONSTANTS && !utils.isEnum(typeElement)) { 696 continue; 697 } 698 if (kind == VisibleMemberMap.Kind.CONSTRUCTORS && utils.isEnum(typeElement)) { 699 continue; 700 } 701 AbstractMemberWriter writer = 702 ((AbstractMemberWriter) memberSummaryBuilder.getMemberSummaryWriter(kind)); 703 if (writer == null) { 704 liNav.addContent(contents.getContent(VisibleMemberMap.Kind.getNavLinkLabels(kind))); 705 } else { 706 writer.addNavSummaryLink( 707 memberSummaryBuilder.members(kind), 708 memberSummaryBuilder.getVisibleMemberMap(kind), liNav); 709 } 710 if (kind != Kind.METHODS) { 711 addNavGap(liNav); 712 } 713 ulNav.addContent(liNav); 714 } 715 return ulNav; 716 } 717 718 /** 719 * Get detail links for the navigation bar. 720 * 721 * @return the content tree for the detail links 722 */ 723 protected Content getNavDetailLinks() { 724 Content li = HtmlTree.LI(contents.detailLabel); 725 li.addContent(Contents.SPACE); 726 Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li); 727 MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder) 728 configuration.getBuilderFactory().getMemberSummaryBuilder(this); 729 for (VisibleMemberMap.Kind kind : VisibleMemberMap.Kind.detailSet) { 730 Content liNav = new HtmlTree(HtmlTag.LI); 731 AbstractMemberWriter writer = 732 ((AbstractMemberWriter) memberSummaryBuilder. 733 getMemberSummaryWriter(kind)); 734 if (kind == VisibleMemberMap.Kind.ENUM_CONSTANTS && !utils.isEnum(typeElement)) { 735 continue; 736 } 737 if (kind == VisibleMemberMap.Kind.CONSTRUCTORS && utils.isEnum(typeElement)) { 738 continue; 739 } 740 if (writer == null) { 741 liNav.addContent(contents.getContent(VisibleMemberMap.Kind.getNavLinkLabels(kind))); 742 } else { 743 writer.addNavDetailLink(memberSummaryBuilder.members(kind), liNav); 744 } 745 if (kind != Kind.METHODS) { 746 addNavGap(liNav); 747 } 748 ulNav.addContent(liNav); 749 } 750 return ulNav; 751 } 752 753 /** 754 * Return the TypeElement being documented. 755 * 756 * @return the TypeElement being documented. 757 */ 758 @Override 759 public TypeElement getTypeElement() { 760 return typeElement; 761 } 762} 763