1 /*
2  * Copyright (c) 1998, 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.io.IOException;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.HashMap;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36 import java.util.SortedSet;
37 import java.util.TreeSet;
38 
39 import com.sun.javadoc.*;
40 import com.sun.tools.doclets.formats.html.markup.*;
41 import com.sun.tools.doclets.internal.toolkit.*;
42 import com.sun.tools.doclets.internal.toolkit.util.*;
43 
44 /**
45  * Generate class usage information.
46  *
47  *  <p><b>This is NOT part of any supported API.
48  *  If you write code that depends on this, you do so at your own risk.
49  *  This code and its internal interfaces are subject to change or
50  *  deletion without notice.</b>
51  *
52  * @author Robert G. Field
53  * @author Bhavesh Patel (Modified)
54  */
55 public class ClassUseWriter extends SubWriterHolderWriter {
56 
57     final ClassDoc classdoc;
58     Set<PackageDoc> pkgToPackageAnnotations = null;
59     final Map<String,List<ProgramElementDoc>> pkgToClassTypeParameter;
60     final Map<String,List<ProgramElementDoc>> pkgToClassAnnotations;
61     final Map<String,List<ProgramElementDoc>> pkgToMethodTypeParameter;
62     final Map<String,List<ProgramElementDoc>> pkgToMethodArgTypeParameter;
63     final Map<String,List<ProgramElementDoc>> pkgToMethodReturnTypeParameter;
64     final Map<String,List<ProgramElementDoc>> pkgToMethodAnnotations;
65     final Map<String,List<ProgramElementDoc>> pkgToMethodParameterAnnotations;
66     final Map<String,List<ProgramElementDoc>> pkgToFieldTypeParameter;
67     final Map<String,List<ProgramElementDoc>> pkgToFieldAnnotations;
68     final Map<String,List<ProgramElementDoc>> pkgToSubclass;
69     final Map<String,List<ProgramElementDoc>> pkgToSubinterface;
70     final Map<String,List<ProgramElementDoc>> pkgToImplementingClass;
71     final Map<String,List<ProgramElementDoc>> pkgToField;
72     final Map<String,List<ProgramElementDoc>> pkgToMethodReturn;
73     final Map<String,List<ProgramElementDoc>> pkgToMethodArgs;
74     final Map<String,List<ProgramElementDoc>> pkgToMethodThrows;
75     final Map<String,List<ProgramElementDoc>> pkgToConstructorAnnotations;
76     final Map<String,List<ProgramElementDoc>> pkgToConstructorParameterAnnotations;
77     final Map<String,List<ProgramElementDoc>> pkgToConstructorArgs;
78     final Map<String,List<ProgramElementDoc>> pkgToConstructorArgTypeParameter;
79     final Map<String,List<ProgramElementDoc>> pkgToConstructorThrows;
80     final SortedSet<PackageDoc> pkgSet;
81     final MethodWriterImpl methodSubWriter;
82     final ConstructorWriterImpl constrSubWriter;
83     final FieldWriterImpl fieldSubWriter;
84     final NestedClassWriterImpl classSubWriter;
85     // Summary for various use tables.
86     final String classUseTableSummary;
87     final String subclassUseTableSummary;
88     final String subinterfaceUseTableSummary;
89     final String fieldUseTableSummary;
90     final String methodUseTableSummary;
91     final String constructorUseTableSummary;
92 
93     /**
94      * Constructor.
95      *
96      * @param filename the file to be generated.
97      * @throws IOException
98      * @throws DocletAbortException
99      */
ClassUseWriter(ConfigurationImpl configuration, ClassUseMapper mapper, DocPath filename, ClassDoc classdoc)100     public ClassUseWriter(ConfigurationImpl configuration,
101                           ClassUseMapper mapper, DocPath filename,
102                           ClassDoc classdoc) throws IOException {
103         super(configuration, filename);
104         this.classdoc = classdoc;
105         if (mapper.classToPackageAnnotations.containsKey(classdoc.qualifiedName()))
106                 pkgToPackageAnnotations = new TreeSet<PackageDoc>(mapper.classToPackageAnnotations.get(classdoc.qualifiedName()));
107         configuration.currentcd = classdoc;
108         this.pkgSet = new TreeSet<PackageDoc>();
109         this.pkgToClassTypeParameter = pkgDivide(mapper.classToClassTypeParam);
110         this.pkgToClassAnnotations = pkgDivide(mapper.classToClassAnnotations);
111         this.pkgToMethodTypeParameter = pkgDivide(mapper.classToExecMemberDocTypeParam);
112         this.pkgToMethodArgTypeParameter = pkgDivide(mapper.classToExecMemberDocArgTypeParam);
113         this.pkgToFieldTypeParameter = pkgDivide(mapper.classToFieldDocTypeParam);
114         this.pkgToFieldAnnotations = pkgDivide(mapper.annotationToFieldDoc);
115         this.pkgToMethodReturnTypeParameter = pkgDivide(mapper.classToExecMemberDocReturnTypeParam);
116         this.pkgToMethodAnnotations = pkgDivide(mapper.classToExecMemberDocAnnotations);
117         this.pkgToMethodParameterAnnotations = pkgDivide(mapper.classToExecMemberDocParamAnnotation);
118         this.pkgToSubclass = pkgDivide(mapper.classToSubclass);
119         this.pkgToSubinterface = pkgDivide(mapper.classToSubinterface);
120         this.pkgToImplementingClass = pkgDivide(mapper.classToImplementingClass);
121         this.pkgToField = pkgDivide(mapper.classToField);
122         this.pkgToMethodReturn = pkgDivide(mapper.classToMethodReturn);
123         this.pkgToMethodArgs = pkgDivide(mapper.classToMethodArgs);
124         this.pkgToMethodThrows = pkgDivide(mapper.classToMethodThrows);
125         this.pkgToConstructorAnnotations = pkgDivide(mapper.classToConstructorAnnotations);
126         this.pkgToConstructorParameterAnnotations = pkgDivide(mapper.classToConstructorParamAnnotation);
127         this.pkgToConstructorArgs = pkgDivide(mapper.classToConstructorArgs);
128         this.pkgToConstructorArgTypeParameter = pkgDivide(mapper.classToConstructorDocArgTypeParam);
129         this.pkgToConstructorThrows = pkgDivide(mapper.classToConstructorThrows);
130         //tmp test
131         if (pkgSet.size() > 0 &&
132             mapper.classToPackage.containsKey(classdoc.qualifiedName()) &&
133             !pkgSet.equals(mapper.classToPackage.get(classdoc.qualifiedName()))) {
134             configuration.root.printWarning("Internal error: package sets don't match: " + pkgSet + " with: " +
135                                    mapper.classToPackage.get(classdoc.qualifiedName()));
136         }
137         methodSubWriter = new MethodWriterImpl(this);
138         constrSubWriter = new ConstructorWriterImpl(this);
139         fieldSubWriter = new FieldWriterImpl(this);
140         classSubWriter = new NestedClassWriterImpl(this);
141         classUseTableSummary = configuration.getText("doclet.Use_Table_Summary",
142                 configuration.getText("doclet.classes"));
143         subclassUseTableSummary = configuration.getText("doclet.Use_Table_Summary",
144                 configuration.getText("doclet.subclasses"));
145         subinterfaceUseTableSummary = configuration.getText("doclet.Use_Table_Summary",
146                 configuration.getText("doclet.subinterfaces"));
147         fieldUseTableSummary = configuration.getText("doclet.Use_Table_Summary",
148                 configuration.getText("doclet.fields"));
149         methodUseTableSummary = configuration.getText("doclet.Use_Table_Summary",
150                 configuration.getText("doclet.methods"));
151         constructorUseTableSummary = configuration.getText("doclet.Use_Table_Summary",
152                 configuration.getText("doclet.constructors"));
153     }
154 
155     /**
156      * Write out class use pages.
157      * @throws DocletAbortException
158      */
generate(ConfigurationImpl configuration, ClassTree classtree)159     public static void generate(ConfigurationImpl configuration,
160                                 ClassTree classtree)  {
161         ClassUseMapper mapper = new ClassUseMapper(configuration.root, classtree);
162         ClassDoc[] classes = configuration.root.classes();
163         for (int i = 0; i < classes.length; i++) {
164             // If -nodeprecated option is set and the containing package is marked
165             // as deprecated, do not generate the class-use page. We will still generate
166             // the class-use page if the class is marked as deprecated but the containing
167             // package is not since it could still be linked from that package-use page.
168             if (!(configuration.nodeprecated &&
169                     Util.isDeprecated(classes[i].containingPackage())))
170                 ClassUseWriter.generate(configuration, mapper, classes[i]);
171         }
172         PackageDoc[] pkgs = configuration.packages;
173         for (int i = 0; i < pkgs.length; i++) {
174             // If -nodeprecated option is set and the package is marked
175             // as deprecated, do not generate the package-use page.
176             if (!(configuration.nodeprecated && Util.isDeprecated(pkgs[i])))
177                 PackageUseWriter.generate(configuration, mapper, pkgs[i]);
178         }
179     }
180 
pkgDivide(Map<String,? extends List<? extends ProgramElementDoc>> classMap)181     private Map<String,List<ProgramElementDoc>> pkgDivide(Map<String,? extends List<? extends ProgramElementDoc>> classMap) {
182         Map<String,List<ProgramElementDoc>> map = new HashMap<String,List<ProgramElementDoc>>();
183         List<? extends ProgramElementDoc> list= classMap.get(classdoc.qualifiedName());
184         if (list != null) {
185             Collections.sort(list);
186             Iterator<? extends ProgramElementDoc> it = list.iterator();
187             while (it.hasNext()) {
188                 ProgramElementDoc doc = it.next();
189                 PackageDoc pkg = doc.containingPackage();
190                 pkgSet.add(pkg);
191                 List<ProgramElementDoc> inPkg = map.get(pkg.name());
192                 if (inPkg == null) {
193                     inPkg = new ArrayList<ProgramElementDoc>();
194                     map.put(pkg.name(), inPkg);
195                 }
196                 inPkg.add(doc);
197             }
198         }
199         return map;
200     }
201 
202     /**
203      * Generate a class page.
204      */
generate(ConfigurationImpl configuration, ClassUseMapper mapper, ClassDoc classdoc)205     public static void generate(ConfigurationImpl configuration,
206                                 ClassUseMapper mapper, ClassDoc classdoc) {
207         ClassUseWriter clsgen;
208         DocPath path = DocPath.forPackage(classdoc)
209                 .resolve(DocPaths.CLASS_USE)
210                 .resolve(DocPath.forName(classdoc));
211         try {
212             clsgen = new ClassUseWriter(configuration,
213                                         mapper, path,
214                                         classdoc);
215             clsgen.generateClassUseFile();
216             clsgen.close();
217         } catch (IOException exc) {
218             configuration.standardmessage.
219                 error("doclet.exception_encountered",
220                       exc.toString(), path.getPath());
221             throw new DocletAbortException(exc);
222         }
223     }
224 
225     /**
226      * Generate the class use list.
227      */
generateClassUseFile()228     protected void generateClassUseFile() throws IOException {
229         Content body = getClassUseHeader();
230         HtmlTree div = new HtmlTree(HtmlTag.DIV);
231         div.addStyle(HtmlStyle.classUseContainer);
232         if (pkgSet.size() > 0) {
233             addClassUse(div);
234         } else {
235             div.addContent(getResource("doclet.ClassUse_No.usage.of.0",
236                     classdoc.qualifiedName()));
237         }
238         body.addContent(div);
239         addNavLinks(false, body);
240         addBottom(body);
241         printHtmlDocument(null, true, body);
242     }
243 
244     /**
245      * Add the class use documentation.
246      *
247      * @param contentTree the content tree to which the class use information will be added
248      */
addClassUse(Content contentTree)249     protected void addClassUse(Content contentTree) throws IOException {
250         HtmlTree ul = new HtmlTree(HtmlTag.UL);
251         ul.addStyle(HtmlStyle.blockList);
252         if (configuration.packages.length > 1) {
253             addPackageList(ul);
254             addPackageAnnotationList(ul);
255         }
256         addClassList(ul);
257         contentTree.addContent(ul);
258     }
259 
260     /**
261      * Add the packages list that use the given class.
262      *
263      * @param contentTree the content tree to which the packages list will be added
264      */
addPackageList(Content contentTree)265     protected void addPackageList(Content contentTree) throws IOException {
266         Content table = HtmlTree.TABLE(HtmlStyle.useSummary, 0, 3, 0, useTableSummary,
267                 getTableCaption(configuration.getResource(
268                 "doclet.ClassUse_Packages.that.use.0",
269                 getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc
270                 )))));
271         table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
272         Content tbody = new HtmlTree(HtmlTag.TBODY);
273         Iterator<PackageDoc> it = pkgSet.iterator();
274         for (int i = 0; it.hasNext(); i++) {
275             PackageDoc pkg = it.next();
276             HtmlTree tr = new HtmlTree(HtmlTag.TR);
277             if (i % 2 == 0) {
278                 tr.addStyle(HtmlStyle.altColor);
279             } else {
280                 tr.addStyle(HtmlStyle.rowColor);
281             }
282             addPackageUse(pkg, tr);
283             tbody.addContent(tr);
284         }
285         table.addContent(tbody);
286         Content li = HtmlTree.LI(HtmlStyle.blockList, table);
287         contentTree.addContent(li);
288     }
289 
290     /**
291      * Add the package annotation list.
292      *
293      * @param contentTree the content tree to which the package annotation list will be added
294      */
addPackageAnnotationList(Content contentTree)295     protected void addPackageAnnotationList(Content contentTree) throws IOException {
296         if ((!classdoc.isAnnotationType()) ||
297                 pkgToPackageAnnotations == null ||
298                 pkgToPackageAnnotations.isEmpty()) {
299             return;
300         }
301         Content table = HtmlTree.TABLE(HtmlStyle.useSummary, 0, 3, 0, useTableSummary,
302                 getTableCaption(configuration.getResource(
303                 "doclet.ClassUse_PackageAnnotation",
304                 getLink(new LinkInfoImpl(configuration,
305                         LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc)))));
306         table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
307         Content tbody = new HtmlTree(HtmlTag.TBODY);
308         Iterator<PackageDoc> it = pkgToPackageAnnotations.iterator();
309         for (int i = 0; it.hasNext(); i++) {
310             PackageDoc pkg = it.next();
311             HtmlTree tr = new HtmlTree(HtmlTag.TR);
312             if (i % 2 == 0) {
313                 tr.addStyle(HtmlStyle.altColor);
314             } else {
315                 tr.addStyle(HtmlStyle.rowColor);
316             }
317             Content tdFirst = HtmlTree.TD(HtmlStyle.colFirst,
318                     getPackageLink(pkg, new StringContent(pkg.name())));
319             tr.addContent(tdFirst);
320             HtmlTree tdLast = new HtmlTree(HtmlTag.TD);
321             tdLast.addStyle(HtmlStyle.colLast);
322             addSummaryComment(pkg, tdLast);
323             tr.addContent(tdLast);
324             tbody.addContent(tr);
325         }
326         table.addContent(tbody);
327         Content li = HtmlTree.LI(HtmlStyle.blockList, table);
328         contentTree.addContent(li);
329     }
330 
331     /**
332      * Add the class list that use the given class.
333      *
334      * @param contentTree the content tree to which the class list will be added
335      */
addClassList(Content contentTree)336     protected void addClassList(Content contentTree) throws IOException {
337         HtmlTree ul = new HtmlTree(HtmlTag.UL);
338         ul.addStyle(HtmlStyle.blockList);
339         for (Iterator<PackageDoc> it = pkgSet.iterator(); it.hasNext();) {
340             PackageDoc pkg = it.next();
341             Content li = HtmlTree.LI(HtmlStyle.blockList, getMarkerAnchor(pkg.name()));
342             Content link = getResource("doclet.ClassUse_Uses.of.0.in.1",
343                     getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER,
344                     classdoc)),
345                     getPackageLink(pkg, Util.getPackageName(pkg)));
346             Content heading = HtmlTree.HEADING(HtmlConstants.SUMMARY_HEADING, link);
347             li.addContent(heading);
348             addClassUse(pkg, li);
349             ul.addContent(li);
350         }
351         Content li = HtmlTree.LI(HtmlStyle.blockList, ul);
352         contentTree.addContent(li);
353     }
354 
355     /**
356      * Add the package use information.
357      *
358      * @param pkg the package that uses the given class
359      * @param contentTree the content tree to which the package use information will be added
360      */
addPackageUse(PackageDoc pkg, Content contentTree)361     protected void addPackageUse(PackageDoc pkg, Content contentTree) throws IOException {
362         Content tdFirst = HtmlTree.TD(HtmlStyle.colFirst,
363                 getHyperLink(pkg.name(), new StringContent(Util.getPackageName(pkg))));
364         contentTree.addContent(tdFirst);
365         HtmlTree tdLast = new HtmlTree(HtmlTag.TD);
366         tdLast.addStyle(HtmlStyle.colLast);
367         addSummaryComment(pkg, tdLast);
368         contentTree.addContent(tdLast);
369     }
370 
371     /**
372      * Add the class use information.
373      *
374      * @param pkg the package that uses the given class
375      * @param contentTree the content tree to which the class use information will be added
376      */
addClassUse(PackageDoc pkg, Content contentTree)377     protected void addClassUse(PackageDoc pkg, Content contentTree) throws IOException {
378         Content classLink = getLink(new LinkInfoImpl(configuration,
379             LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc));
380         Content pkgLink = getPackageLink(pkg, Util.getPackageName(pkg));
381         classSubWriter.addUseInfo(pkgToClassAnnotations.get(pkg.name()),
382                 configuration.getResource("doclet.ClassUse_Annotation", classLink,
383                 pkgLink), classUseTableSummary, contentTree);
384         classSubWriter.addUseInfo(pkgToClassTypeParameter.get(pkg.name()),
385                 configuration.getResource("doclet.ClassUse_TypeParameter", classLink,
386                 pkgLink), classUseTableSummary, contentTree);
387         classSubWriter.addUseInfo(pkgToSubclass.get(pkg.name()),
388                 configuration.getResource("doclet.ClassUse_Subclass", classLink,
389                 pkgLink), subclassUseTableSummary, contentTree);
390         classSubWriter.addUseInfo(pkgToSubinterface.get(pkg.name()),
391                 configuration.getResource("doclet.ClassUse_Subinterface", classLink,
392                 pkgLink), subinterfaceUseTableSummary, contentTree);
393         classSubWriter.addUseInfo(pkgToImplementingClass.get(pkg.name()),
394                 configuration.getResource("doclet.ClassUse_ImplementingClass", classLink,
395                 pkgLink), classUseTableSummary, contentTree);
396         fieldSubWriter.addUseInfo(pkgToField.get(pkg.name()),
397                 configuration.getResource("doclet.ClassUse_Field", classLink,
398                 pkgLink), fieldUseTableSummary, contentTree);
399         fieldSubWriter.addUseInfo(pkgToFieldAnnotations.get(pkg.name()),
400                 configuration.getResource("doclet.ClassUse_FieldAnnotations", classLink,
401                 pkgLink), fieldUseTableSummary, contentTree);
402         fieldSubWriter.addUseInfo(pkgToFieldTypeParameter.get(pkg.name()),
403                 configuration.getResource("doclet.ClassUse_FieldTypeParameter", classLink,
404                 pkgLink), fieldUseTableSummary, contentTree);
405         methodSubWriter.addUseInfo(pkgToMethodAnnotations.get(pkg.name()),
406                 configuration.getResource("doclet.ClassUse_MethodAnnotations", classLink,
407                 pkgLink), methodUseTableSummary, contentTree);
408         methodSubWriter.addUseInfo(pkgToMethodParameterAnnotations.get(pkg.name()),
409                 configuration.getResource("doclet.ClassUse_MethodParameterAnnotations", classLink,
410                 pkgLink), methodUseTableSummary, contentTree);
411         methodSubWriter.addUseInfo(pkgToMethodTypeParameter.get(pkg.name()),
412                 configuration.getResource("doclet.ClassUse_MethodTypeParameter", classLink,
413                 pkgLink), methodUseTableSummary, contentTree);
414         methodSubWriter.addUseInfo(pkgToMethodReturn.get(pkg.name()),
415                 configuration.getResource("doclet.ClassUse_MethodReturn", classLink,
416                 pkgLink), methodUseTableSummary, contentTree);
417         methodSubWriter.addUseInfo(pkgToMethodReturnTypeParameter.get(pkg.name()),
418                 configuration.getResource("doclet.ClassUse_MethodReturnTypeParameter", classLink,
419                 pkgLink), methodUseTableSummary, contentTree);
420         methodSubWriter.addUseInfo(pkgToMethodArgs.get(pkg.name()),
421                 configuration.getResource("doclet.ClassUse_MethodArgs", classLink,
422                 pkgLink), methodUseTableSummary, contentTree);
423         methodSubWriter.addUseInfo(pkgToMethodArgTypeParameter.get(pkg.name()),
424                 configuration.getResource("doclet.ClassUse_MethodArgsTypeParameters", classLink,
425                 pkgLink), methodUseTableSummary, contentTree);
426         methodSubWriter.addUseInfo(pkgToMethodThrows.get(pkg.name()),
427                 configuration.getResource("doclet.ClassUse_MethodThrows", classLink,
428                 pkgLink), methodUseTableSummary, contentTree);
429         constrSubWriter.addUseInfo(pkgToConstructorAnnotations.get(pkg.name()),
430                 configuration.getResource("doclet.ClassUse_ConstructorAnnotations", classLink,
431                 pkgLink), constructorUseTableSummary, contentTree);
432         constrSubWriter.addUseInfo(pkgToConstructorParameterAnnotations.get(pkg.name()),
433                 configuration.getResource("doclet.ClassUse_ConstructorParameterAnnotations", classLink,
434                 pkgLink), constructorUseTableSummary, contentTree);
435         constrSubWriter.addUseInfo(pkgToConstructorArgs.get(pkg.name()),
436                 configuration.getResource("doclet.ClassUse_ConstructorArgs", classLink,
437                 pkgLink), constructorUseTableSummary, contentTree);
438         constrSubWriter.addUseInfo(pkgToConstructorArgTypeParameter.get(pkg.name()),
439                 configuration.getResource("doclet.ClassUse_ConstructorArgsTypeParameters", classLink,
440                 pkgLink), constructorUseTableSummary, contentTree);
441         constrSubWriter.addUseInfo(pkgToConstructorThrows.get(pkg.name()),
442                 configuration.getResource("doclet.ClassUse_ConstructorThrows", classLink,
443                 pkgLink), constructorUseTableSummary, contentTree);
444     }
445 
446     /**
447      * Get the header for the class use Listing.
448      *
449      * @return a content tree representing the class use header
450      */
getClassUseHeader()451     protected Content getClassUseHeader() {
452         String cltype = configuration.getText(classdoc.isInterface()?
453             "doclet.Interface":"doclet.Class");
454         String clname = classdoc.qualifiedName();
455         String title = configuration.getText("doclet.Window_ClassUse_Header",
456                 cltype, clname);
457         Content bodyTree = getBody(true, getWindowTitle(title));
458         addTop(bodyTree);
459         addNavLinks(true, bodyTree);
460         ContentBuilder headContent = new ContentBuilder();
461         headContent.addContent(getResource("doclet.ClassUse_Title", cltype));
462         headContent.addContent(new HtmlTree(HtmlTag.BR));
463         headContent.addContent(clname);
464         Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING,
465                 true, HtmlStyle.title, headContent);
466         Content div = HtmlTree.DIV(HtmlStyle.header, heading);
467         bodyTree.addContent(div);
468         return bodyTree;
469     }
470 
471     /**
472      * Get this package link.
473      *
474      * @return a content tree for the package link
475      */
getNavLinkPackage()476     protected Content getNavLinkPackage() {
477         Content linkContent =
478                 getHyperLink(DocPath.parent.resolve(DocPaths.PACKAGE_SUMMARY), packageLabel);
479         Content li = HtmlTree.LI(linkContent);
480         return li;
481     }
482 
483     /**
484      * Get class page link.
485      *
486      * @return a content tree for the class page link
487      */
getNavLinkClass()488     protected Content getNavLinkClass() {
489         Content linkContent = getLink(new LinkInfoImpl(
490                 configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc)
491                 .label(configuration.getText("doclet.Class")));
492         Content li = HtmlTree.LI(linkContent);
493         return li;
494     }
495 
496     /**
497      * Get the use link.
498      *
499      * @return a content tree for the use link
500      */
getNavLinkClassUse()501     protected Content getNavLinkClassUse() {
502         Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, useLabel);
503         return li;
504     }
505 
506     /**
507      * Get the tree link.
508      *
509      * @return a content tree for the tree link
510      */
getNavLinkTree()511     protected Content getNavLinkTree() {
512         Content linkContent = classdoc.containingPackage().isIncluded() ?
513             getHyperLink(DocPath.parent.resolve(DocPaths.PACKAGE_TREE), treeLabel) :
514             getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE), treeLabel);
515         Content li = HtmlTree.LI(linkContent);
516         return li;
517     }
518 }
519