1 /*
   2  * Copyright (c) 1998, 2018, 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 jdk.javadoc.internal.doclets.formats.html;
  27 
  28 import jdk.javadoc.internal.doclets.formats.html.markup.Table;
  29 
  30 import java.text.MessageFormat;
  31 import java.util.ArrayList;
  32 import java.util.Collections;
  33 import java.util.HashMap;
  34 import java.util.List;
  35 import java.util.Map;
  36 import java.util.Set;
  37 import java.util.SortedSet;
  38 import java.util.TreeSet;
  39 
  40 import javax.lang.model.element.Element;
  41 import javax.lang.model.element.PackageElement;
  42 import javax.lang.model.element.TypeElement;
  43 import javax.tools.Diagnostic;
  44 
  45 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
  46 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
  47 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
  48 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
  49 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
  50 import jdk.javadoc.internal.doclets.formats.html.markup.Links;
  51 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
  52 import jdk.javadoc.internal.doclets.toolkit.Content;
  53 import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
  54 import jdk.javadoc.internal.doclets.toolkit.util.ClassUseMapper;
  55 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
  56 import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
  57 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
  58 
  59 
  60 /**
  61  * Generate class usage information.
  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  * @author Robert G. Field
  69  * @author Bhavesh Patel (Modified)
  70  */
  71 public class ClassUseWriter extends SubWriterHolderWriter {
  72 
  73     final TypeElement typeElement;
  74     Set<PackageElement> pkgToPackageAnnotations = null;
  75     final Map<PackageElement, List<Element>> pkgToClassTypeParameter;
  76     final Map<PackageElement, List<Element>> pkgToClassAnnotations;
  77     final Map<PackageElement, List<Element>> pkgToMethodTypeParameter;
  78     final Map<PackageElement, List<Element>> pkgToMethodArgTypeParameter;
  79     final Map<PackageElement, List<Element>> pkgToMethodReturnTypeParameter;
  80     final Map<PackageElement, List<Element>> pkgToMethodAnnotations;
  81     final Map<PackageElement, List<Element>> pkgToMethodParameterAnnotations;
  82     final Map<PackageElement, List<Element>> pkgToFieldTypeParameter;
  83     final Map<PackageElement, List<Element>> pkgToFieldAnnotations;
  84     final Map<PackageElement, List<Element>> pkgToSubclass;
  85     final Map<PackageElement, List<Element>> pkgToSubinterface;
  86     final Map<PackageElement, List<Element>> pkgToImplementingClass;
  87     final Map<PackageElement, List<Element>> pkgToField;
  88     final Map<PackageElement, List<Element>> pkgToMethodReturn;
  89     final Map<PackageElement, List<Element>> pkgToMethodArgs;
  90     final Map<PackageElement, List<Element>> pkgToMethodThrows;
  91     final Map<PackageElement, List<Element>> pkgToConstructorAnnotations;
  92     final Map<PackageElement, List<Element>> pkgToConstructorParameterAnnotations;
  93     final Map<PackageElement, List<Element>> pkgToConstructorArgs;
  94     final Map<PackageElement, List<Element>> pkgToConstructorArgTypeParameter;
  95     final Map<PackageElement, List<Element>> pkgToConstructorThrows;
  96     final SortedSet<PackageElement> pkgSet;
  97     final MethodWriterImpl methodSubWriter;
  98     final ConstructorWriterImpl constrSubWriter;
  99     final FieldWriterImpl fieldSubWriter;
 100     final NestedClassWriterImpl classSubWriter;
 101     // Summary for various use tables.
 102     final String classUseTableSummary;
 103     final String subclassUseTableSummary;
 104     final String subinterfaceUseTableSummary;
 105     final String fieldUseTableSummary;
 106     final String methodUseTableSummary;
 107     final String constructorUseTableSummary;
 108     final String packageUseTableSummary;
 109 
 110     /**
 111      * The HTML tree for main tag.
 112      */
 113     protected HtmlTree mainTree = HtmlTree.MAIN();
 114 
 115     /**
 116      * Constructor.
 117      *
 118      * @param filename the file to be generated.
 119      */
 120     public ClassUseWriter(HtmlConfiguration configuration,
 121                           ClassUseMapper mapper, DocPath filename,
 122                           TypeElement typeElement) {
 123         super(configuration, filename);
 124         this.typeElement = typeElement;
 125         if (mapper.classToPackageAnnotations.containsKey(typeElement)) {
 126             pkgToPackageAnnotations = new TreeSet<>(utils.makeClassUseComparator());
 127             pkgToPackageAnnotations.addAll(mapper.classToPackageAnnotations.get(typeElement));
 128         }
 129         configuration.currentTypeElement = typeElement;
 130         this.pkgSet = new TreeSet<>(utils.makePackageComparator());
 131         this.pkgToClassTypeParameter = pkgDivide(mapper.classToClassTypeParam);
 132         this.pkgToClassAnnotations = pkgDivide(mapper.classToClassAnnotations);
 133         this.pkgToMethodTypeParameter = pkgDivide(mapper.classToMethodTypeParam);
 134         this.pkgToMethodArgTypeParameter = pkgDivide(mapper.classToMethodArgTypeParam);
 135         this.pkgToFieldTypeParameter = pkgDivide(mapper.classToFieldTypeParam);
 136         this.pkgToFieldAnnotations = pkgDivide(mapper.annotationToField);
 137         this.pkgToMethodReturnTypeParameter = pkgDivide(mapper.classToMethodReturnTypeParam);
 138         this.pkgToMethodAnnotations = pkgDivide(mapper.classToMethodAnnotations);
 139         this.pkgToMethodParameterAnnotations = pkgDivide(mapper.classToMethodParamAnnotation);
 140         this.pkgToSubclass = pkgDivide(mapper.classToSubclass);
 141         this.pkgToSubinterface = pkgDivide(mapper.classToSubinterface);
 142         this.pkgToImplementingClass = pkgDivide(mapper.classToImplementingClass);
 143         this.pkgToField = pkgDivide(mapper.classToField);
 144         this.pkgToMethodReturn = pkgDivide(mapper.classToMethodReturn);
 145         this.pkgToMethodArgs = pkgDivide(mapper.classToMethodArgs);
 146         this.pkgToMethodThrows = pkgDivide(mapper.classToMethodThrows);
 147         this.pkgToConstructorAnnotations = pkgDivide(mapper.classToConstructorAnnotations);
 148         this.pkgToConstructorParameterAnnotations = pkgDivide(mapper.classToConstructorParamAnnotation);
 149         this.pkgToConstructorArgs = pkgDivide(mapper.classToConstructorArgs);
 150         this.pkgToConstructorArgTypeParameter = pkgDivide(mapper.classToConstructorArgTypeParam);
 151         this.pkgToConstructorThrows = pkgDivide(mapper.classToConstructorThrows);
 152         //tmp test
 153         if (pkgSet.size() > 0 &&
 154             mapper.classToPackage.containsKey(this.typeElement) &&
 155             !pkgSet.equals(mapper.classToPackage.get(this.typeElement))) {
 156             configuration.reporter.print(Diagnostic.Kind.WARNING,
 157                     "Internal error: package sets don't match: "
 158                     + pkgSet + " with: " + mapper.classToPackage.get(this.typeElement));
 159         }
 160 
 161         methodSubWriter = new MethodWriterImpl(this);
 162         constrSubWriter = new ConstructorWriterImpl(this);
 163         fieldSubWriter = new FieldWriterImpl(this);
 164         classSubWriter = new NestedClassWriterImpl(this);
 165 
 166         String useTableSummary = resources.getText("doclet.Use_Table_Summary");
 167         classUseTableSummary = MessageFormat.format(useTableSummary,
 168                 resources.getText("doclet.classes"));
 169         subclassUseTableSummary = MessageFormat.format(useTableSummary,
 170                 resources.getText("doclet.subclasses"));
 171         subinterfaceUseTableSummary = MessageFormat.format(useTableSummary,
 172                 resources.getText("doclet.subinterfaces"));
 173         fieldUseTableSummary = MessageFormat.format(useTableSummary,
 174                 resources.getText("doclet.fields"));
 175         methodUseTableSummary = MessageFormat.format(useTableSummary,
 176                 resources.getText("doclet.methods"));
 177         constructorUseTableSummary = MessageFormat.format(useTableSummary,
 178                 resources.getText("doclet.constructors"));
 179         packageUseTableSummary = MessageFormat.format(useTableSummary,
 180                 resources.getText("doclet.packages"));
 181     }
 182 
 183     /**
 184      * Write out class use pages.
 185      *
 186      * @param configuration the configuration for this doclet
 187      * @param classtree the class tree hierarchy
 188      * @throws DocFileIOException if there is an error while generating the documentation
 189      */
 190     public static void generate(HtmlConfiguration configuration, ClassTree classtree) throws DocFileIOException  {
 191         ClassUseMapper mapper = new ClassUseMapper(configuration, classtree);
 192         for (TypeElement aClass : configuration.getIncludedTypeElements()) {
 193             // If -nodeprecated option is set and the containing package is marked
 194             // as deprecated, do not generate the class-use page. We will still generate
 195             // the class-use page if the class is marked as deprecated but the containing
 196             // package is not since it could still be linked from that package-use page.
 197             if (!(configuration.nodeprecated &&
 198                   configuration.utils.isDeprecated(configuration.utils.containingPackage(aClass))))
 199                 ClassUseWriter.generate(configuration, mapper, aClass);
 200         }
 201         for (PackageElement pkg : configuration.packages) {
 202             // If -nodeprecated option is set and the package is marked
 203             // as deprecated, do not generate the package-use page.
 204             if (!(configuration.nodeprecated && configuration.utils.isDeprecated(pkg)))
 205                 PackageUseWriter.generate(configuration, mapper, pkg);
 206         }
 207     }
 208 
 209     private Map<PackageElement, List<Element>> pkgDivide(Map<TypeElement, ? extends List<? extends Element>> classMap) {
 210         Map<PackageElement, List<Element>> map = new HashMap<>();
 211         List<? extends Element> elements = (List<? extends Element>) classMap.get(typeElement);
 212         if (elements != null) {
 213             Collections.sort(elements, utils.makeClassUseComparator());
 214             for (Element e : elements) {
 215                 PackageElement pkg = utils.containingPackage(e);
 216                 pkgSet.add(pkg);
 217                 List<Element> inPkg = map.get(pkg);
 218                 if (inPkg == null) {
 219                     inPkg = new ArrayList<>();
 220                     map.put(pkg, inPkg);
 221                 }
 222                 inPkg.add(e);
 223             }
 224         }
 225         return map;
 226     }
 227 
 228     /**
 229      * Generate a class page.
 230      *
 231      * @throws DocFileIOException if there is a problem while generating the documentation
 232      */
 233     public static void generate(HtmlConfiguration configuration, ClassUseMapper mapper,
 234                                 TypeElement typeElement) throws DocFileIOException {
 235         ClassUseWriter clsgen;
 236         DocPath path = configuration.docPaths.forPackage(typeElement)
 237                               .resolve(DocPaths.CLASS_USE)
 238                               .resolve(configuration.docPaths.forName( typeElement));
 239         clsgen = new ClassUseWriter(configuration, mapper, path, typeElement);
 240         clsgen.generateClassUseFile();
 241     }
 242 
 243     /**
 244      * Generate the class use elements.
 245      *
 246      * @throws DocFileIOException if there is a problem while generating the documentation
 247      */
 248     protected void generateClassUseFile() throws DocFileIOException {
 249         HtmlTree body = getClassUseHeader();
 250         HtmlTree div = new HtmlTree(HtmlTag.DIV);
 251         div.setStyle(HtmlStyle.classUseContainer);
 252         if (pkgSet.size() > 0) {
 253             addClassUse(div);
 254         } else {
 255             div.addContent(contents.getContent("doclet.ClassUse_No.usage.of.0",
 256                     utils.getFullyQualifiedName(typeElement)));
 257         }
 258         if (configuration.allowTag(HtmlTag.MAIN)) {
 259             mainTree.addContent(div);
 260             body.addContent(mainTree);
 261         } else {
 262             body.addContent(div);
 263         }
 264         HtmlTree htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
 265                 ? HtmlTree.FOOTER()
 266                 : body;
 267         addNavLinks(false, htmlTree);
 268         addBottom(htmlTree);
 269         if (configuration.allowTag(HtmlTag.FOOTER)) {
 270             body.addContent(htmlTree);
 271         }
 272         printHtmlDocument(null, true, body);
 273     }
 274 
 275     /**
 276      * Add the class use documentation.
 277      *
 278      * @param contentTree the content tree to which the class use information will be added
 279      */
 280     protected void addClassUse(Content contentTree) {
 281         HtmlTree ul = new HtmlTree(HtmlTag.UL);
 282         ul.setStyle(HtmlStyle.blockList);
 283         if (configuration.packages.size() > 1) {
 284             addPackageList(ul);
 285             addPackageAnnotationList(ul);
 286         }
 287         addClassList(ul);
 288         contentTree.addContent(ul);
 289     }
 290 
 291     /**
 292      * Add the packages elements that use the given class.
 293      *
 294      * @param contentTree the content tree to which the packages elements will be added
 295      */
 296     protected void addPackageList(Content contentTree) {
 297         Content caption = getTableCaption(contents.getContent(
 298                 "doclet.ClassUse_Packages.that.use.0",
 299                 getLink(new LinkInfoImpl(configuration,
 300                         LinkInfoImpl.Kind.CLASS_USE_HEADER, typeElement))));
 301         Table table = new Table(configuration.htmlVersion, HtmlStyle.useSummary)
 302                 .setSummary(packageUseTableSummary)
 303                 .setCaption(caption)
 304                 .setHeader(getPackageTableHeader())
 305                 .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast);
 306         for (PackageElement pkg : pkgSet) {
 307             addPackageUse(pkg, table);
 308         }
 309         Content li = HtmlTree.LI(HtmlStyle.blockList, table.toContent());
 310         contentTree.addContent(li);
 311     }
 312 
 313     /**
 314      * Add the package annotation elements.
 315      *
 316      * @param contentTree the content tree to which the package annotation elements will be added
 317      */
 318     protected void addPackageAnnotationList(Content contentTree) {
 319         if (!utils.isAnnotationType(typeElement) ||
 320                 pkgToPackageAnnotations == null ||
 321                 pkgToPackageAnnotations.isEmpty()) {
 322             return;
 323         }
 324         Content caption = getTableCaption(contents.getContent(
 325                 "doclet.ClassUse_PackageAnnotation",
 326                 getLink(new LinkInfoImpl(configuration,
 327                         LinkInfoImpl.Kind.CLASS_USE_HEADER, typeElement))));
 328 
 329         Table table = new Table(configuration.htmlVersion, HtmlStyle.useSummary)
 330                 .setSummary(packageUseTableSummary)
 331                 .setCaption(caption)
 332                 .setHeader(getPackageTableHeader())
 333                 .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast);
 334         for (PackageElement pkg : pkgToPackageAnnotations) {
 335             Content summary = new ContentBuilder();
 336             addSummaryComment(pkg, summary);
 337             table.addRow(getPackageLink(pkg), summary);
 338         }
 339         Content li = HtmlTree.LI(HtmlStyle.blockList, table.toContent());
 340         contentTree.addContent(li);
 341     }
 342 
 343     /**
 344      * Add the class elements that use the given class.
 345      *
 346      * @param contentTree the content tree to which the class elements will be added
 347      */
 348     protected void addClassList(Content contentTree) {
 349         HtmlTree ul = new HtmlTree(HtmlTag.UL);
 350         ul.setStyle(HtmlStyle.blockList);
 351         for (PackageElement pkg : pkgSet) {
 352             Content markerAnchor = links.createAnchor(getPackageAnchorName(pkg));
 353             HtmlTree htmlTree = (configuration.allowTag(HtmlTag.SECTION))
 354                     ? HtmlTree.SECTION(markerAnchor)
 355                     : HtmlTree.LI(HtmlStyle.blockList, markerAnchor);
 356             Content link = contents.getContent("doclet.ClassUse_Uses.of.0.in.1",
 357                     getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER,
 358                             typeElement)),
 359                     getPackageLink(pkg, utils.getPackageName(pkg)));
 360             Content heading = HtmlTree.HEADING(HtmlConstants.SUMMARY_HEADING, link);
 361             htmlTree.addContent(heading);
 362             addClassUse(pkg, htmlTree);
 363             if (configuration.allowTag(HtmlTag.SECTION)) {
 364                 ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
 365             } else {
 366                 ul.addContent(htmlTree);
 367             }
 368         }
 369         Content li = HtmlTree.LI(HtmlStyle.blockList, ul);
 370         contentTree.addContent(li);
 371     }
 372 
 373     /**
 374      * Add the package use information.
 375      *
 376      * @param pkg the package that uses the given class
 377      * @param table the table to which the package use information will be added
 378      */
 379     protected void addPackageUse(PackageElement pkg, Table table) {
 380         Content pkgLink =
 381                 links.createLink(getPackageAnchorName(pkg), new StringContent(utils.getPackageName(pkg)));
 382         Content summary = new ContentBuilder();
 383         addSummaryComment(pkg, summary);
 384         table.addRow(pkgLink, summary);
 385     }
 386 
 387     /**
 388      * Add the class use information.
 389      *
 390      * @param pkg the package that uses the given class
 391      * @param contentTree the content tree to which the class use information will be added
 392      */
 393     protected void addClassUse(PackageElement pkg, Content contentTree) {
 394         Content classLink = getLink(new LinkInfoImpl(configuration,
 395             LinkInfoImpl.Kind.CLASS_USE_HEADER, typeElement));
 396         Content pkgLink = getPackageLink(pkg, utils.getPackageName(pkg));
 397         classSubWriter.addUseInfo(pkgToClassAnnotations.get(pkg),
 398                 configuration.getContent("doclet.ClassUse_Annotation", classLink,
 399                 pkgLink), classUseTableSummary, contentTree);
 400         classSubWriter.addUseInfo(pkgToClassTypeParameter.get(pkg),
 401                 configuration.getContent("doclet.ClassUse_TypeParameter", classLink,
 402                 pkgLink), classUseTableSummary, contentTree);
 403         classSubWriter.addUseInfo(pkgToSubclass.get(pkg),
 404                 configuration.getContent("doclet.ClassUse_Subclass", classLink,
 405                 pkgLink), subclassUseTableSummary, contentTree);
 406         classSubWriter.addUseInfo(pkgToSubinterface.get(pkg),
 407                 configuration.getContent("doclet.ClassUse_Subinterface", classLink,
 408                 pkgLink), subinterfaceUseTableSummary, contentTree);
 409         classSubWriter.addUseInfo(pkgToImplementingClass.get(pkg),
 410                 configuration.getContent("doclet.ClassUse_ImplementingClass", classLink,
 411                 pkgLink), classUseTableSummary, contentTree);
 412         fieldSubWriter.addUseInfo(pkgToField.get(pkg),
 413                 configuration.getContent("doclet.ClassUse_Field", classLink,
 414                 pkgLink), fieldUseTableSummary, contentTree);
 415         fieldSubWriter.addUseInfo(pkgToFieldAnnotations.get(pkg),
 416                 configuration.getContent("doclet.ClassUse_FieldAnnotations", classLink,
 417                 pkgLink), fieldUseTableSummary, contentTree);
 418         fieldSubWriter.addUseInfo(pkgToFieldTypeParameter.get(pkg),
 419                 configuration.getContent("doclet.ClassUse_FieldTypeParameter", classLink,
 420                 pkgLink), fieldUseTableSummary, contentTree);
 421         methodSubWriter.addUseInfo(pkgToMethodAnnotations.get(pkg),
 422                 configuration.getContent("doclet.ClassUse_MethodAnnotations", classLink,
 423                 pkgLink), methodUseTableSummary, contentTree);
 424         methodSubWriter.addUseInfo(pkgToMethodParameterAnnotations.get(pkg),
 425                 configuration.getContent("doclet.ClassUse_MethodParameterAnnotations", classLink,
 426                 pkgLink), methodUseTableSummary, contentTree);
 427         methodSubWriter.addUseInfo(pkgToMethodTypeParameter.get(pkg),
 428                 configuration.getContent("doclet.ClassUse_MethodTypeParameter", classLink,
 429                 pkgLink), methodUseTableSummary, contentTree);
 430         methodSubWriter.addUseInfo(pkgToMethodReturn.get(pkg),
 431                 configuration.getContent("doclet.ClassUse_MethodReturn", classLink,
 432                 pkgLink), methodUseTableSummary, contentTree);
 433         methodSubWriter.addUseInfo(pkgToMethodReturnTypeParameter.get(pkg),
 434                 configuration.getContent("doclet.ClassUse_MethodReturnTypeParameter", classLink,
 435                 pkgLink), methodUseTableSummary, contentTree);
 436         methodSubWriter.addUseInfo(pkgToMethodArgs.get(pkg),
 437                 configuration.getContent("doclet.ClassUse_MethodArgs", classLink,
 438                 pkgLink), methodUseTableSummary, contentTree);
 439         methodSubWriter.addUseInfo(pkgToMethodArgTypeParameter.get(pkg),
 440                 configuration.getContent("doclet.ClassUse_MethodArgsTypeParameters", classLink,
 441                 pkgLink), methodUseTableSummary, contentTree);
 442         methodSubWriter.addUseInfo(pkgToMethodThrows.get(pkg),
 443                 configuration.getContent("doclet.ClassUse_MethodThrows", classLink,
 444                 pkgLink), methodUseTableSummary, contentTree);
 445         constrSubWriter.addUseInfo(pkgToConstructorAnnotations.get(pkg),
 446                 configuration.getContent("doclet.ClassUse_ConstructorAnnotations", classLink,
 447                 pkgLink), constructorUseTableSummary, contentTree);
 448         constrSubWriter.addUseInfo(pkgToConstructorParameterAnnotations.get(pkg),
 449                 configuration.getContent("doclet.ClassUse_ConstructorParameterAnnotations", classLink,
 450                 pkgLink), constructorUseTableSummary, contentTree);
 451         constrSubWriter.addUseInfo(pkgToConstructorArgs.get(pkg),
 452                 configuration.getContent("doclet.ClassUse_ConstructorArgs", classLink,
 453                 pkgLink), constructorUseTableSummary, contentTree);
 454         constrSubWriter.addUseInfo(pkgToConstructorArgTypeParameter.get(pkg),
 455                 configuration.getContent("doclet.ClassUse_ConstructorArgsTypeParameters", classLink,
 456                 pkgLink), constructorUseTableSummary, contentTree);
 457         constrSubWriter.addUseInfo(pkgToConstructorThrows.get(pkg),
 458                 configuration.getContent("doclet.ClassUse_ConstructorThrows", classLink,
 459                 pkgLink), constructorUseTableSummary, contentTree);
 460     }
 461 
 462     /**
 463      * Get the header for the class use Listing.
 464      *
 465      * @return a content tree representing the class use header
 466      */
 467     protected HtmlTree getClassUseHeader() {
 468         String cltype = configuration.getText(utils.isInterface(typeElement)
 469                 ? "doclet.Interface"
 470                 : "doclet.Class");
 471         String clname = utils.getFullyQualifiedName(typeElement);
 472         String title = configuration.getText("doclet.Window_ClassUse_Header",
 473                 cltype, clname);
 474         HtmlTree bodyTree = getBody(true, getWindowTitle(title));
 475         HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER))
 476                 ? HtmlTree.HEADER()
 477                 : bodyTree;
 478         addTop(htmlTree);
 479         addNavLinks(true, htmlTree);
 480         if (configuration.allowTag(HtmlTag.HEADER)) {
 481             bodyTree.addContent(htmlTree);
 482         }
 483         ContentBuilder headContent = new ContentBuilder();
 484         headContent.addContent(contents.getContent("doclet.ClassUse_Title", cltype));
 485         headContent.addContent(new HtmlTree(HtmlTag.BR));
 486         headContent.addContent(clname);
 487         Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING,
 488                 true, HtmlStyle.title, headContent);
 489         Content div = HtmlTree.DIV(HtmlStyle.header, heading);
 490         if (configuration.allowTag(HtmlTag.MAIN)) {
 491             mainTree.addContent(div);
 492         } else {
 493             bodyTree.addContent(div);
 494         }
 495         return bodyTree;
 496     }
 497 
 498     /**
 499      * Get the module link.
 500      *
 501      * @return a content tree for the module link
 502      */
 503     @Override
 504     protected Content getNavLinkModule() {
 505         Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(typeElement),
 506                 contents.moduleLabel);
 507         Content li = HtmlTree.LI(linkContent);
 508         return li;
 509     }
 510 
 511     /**
 512      * Get this package link.
 513      *
 514      * @return a content tree for the package link
 515      */
 516     protected Content getNavLinkPackage() {
 517         Content linkContent =
 518                 links.createLink(DocPath.parent.resolve(DocPaths.PACKAGE_SUMMARY), contents.packageLabel);
 519         Content li = HtmlTree.LI(linkContent);
 520         return li;
 521     }
 522 
 523     /**
 524      * Get class page link.
 525      *
 526      * @return a content tree for the class page link
 527      */
 528     protected Content getNavLinkClass() {
 529         Content linkContent = getLink(new LinkInfoImpl(
 530                 configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, typeElement)
 531                 .label(configuration.getText("doclet.Class")));
 532         Content li = HtmlTree.LI(linkContent);
 533         return li;
 534     }
 535 
 536     /**
 537      * Get the use link.
 538      *
 539      * @return a content tree for the use link
 540      */
 541     protected Content getNavLinkClassUse() {
 542         Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.useLabel);
 543         return li;
 544     }
 545 
 546     /**
 547      * Get the tree link.
 548      *
 549      * @return a content tree for the tree link
 550      */
 551     protected Content getNavLinkTree() {
 552         Content linkContent = utils.isEnclosingPackageIncluded(typeElement)
 553                 ? links.createLink(DocPath.parent.resolve(DocPaths.PACKAGE_TREE), contents.treeLabel)
 554                 : links.createLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE), contents.treeLabel);
 555         Content li = HtmlTree.LI(linkContent);
 556         return li;
 557     }
 558 }