1 /*
2  * Copyright (c) 1997, 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 import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader;
30 
31 import java.util.*;
32 
33 import javax.lang.model.element.ModuleElement;
34 import javax.lang.model.element.PackageElement;
35 import javax.lang.model.element.TypeElement;
36 
37 import com.sun.source.doctree.DocTree;
38 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
39 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
40 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
41 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
42 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
43 import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
44 import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
45 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
46 import jdk.javadoc.internal.doclets.toolkit.Content;
47 import jdk.javadoc.internal.doclets.toolkit.PackageSummaryWriter;
48 import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
49 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
50 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
51 
52 /**
53  * Class to generate file for each package contents in the right-hand
54  * frame. This will list all the Class Kinds in the package. A click on any
55  * class-kind will update the frame with the clicked class-kind page.
56  *
57  *  <p><b>This is NOT part of any supported API.
58  *  If you write code that depends on this, you do so at your own risk.
59  *  This code and its internal interfaces are subject to change or
60  *  deletion without notice.</b>
61  *
62  * @author Atul M Dambalkar
63  * @author Bhavesh Patel (Modified)
64  */
65 public class PackageWriterImpl extends HtmlDocletWriter
66     implements PackageSummaryWriter {
67 
68     /**
69      * The package being documented.
70      */
71     protected PackageElement packageElement;
72 
73     /**
74      * The HTML tree for main tag.
75      */
76     protected HtmlTree mainTree = HtmlTree.MAIN();
77 
78     /**
79      * The HTML tree for section tag.
80      */
81     protected HtmlTree sectionTree = HtmlTree.SECTION();
82 
83     private final Navigation navBar;
84 
85     /**
86      * Constructor to construct PackageWriter object and to generate
87      * "package-summary.html" file in the respective package directory.
88      * For example for package "java.lang" this will generate file
89      * "package-summary.html" file in the "java/lang" directory. It will also
90      * create "java/lang" directory in the current or the destination directory
91      * if it doesn't exist.
92      *
93      * @param configuration the configuration of the doclet.
94      * @param packageElement    PackageElement under consideration.
95      */
PackageWriterImpl(HtmlConfiguration configuration, PackageElement packageElement)96     public PackageWriterImpl(HtmlConfiguration configuration, PackageElement packageElement) {
97         super(configuration,
98                 configuration.docPaths.forPackage(packageElement)
99                 .resolve(DocPaths.PACKAGE_SUMMARY));
100         this.packageElement = packageElement;
101         this.navBar = new Navigation(packageElement, configuration, fixedNavDiv, PageMode.PACKAGE, path);
102     }
103 
104     /**
105      * {@inheritDoc}
106      */
107     @Override
getPackageHeader(String heading)108     public Content getPackageHeader(String heading) {
109         HtmlTree bodyTree = getBody(true, getWindowTitle(utils.getPackageName(packageElement)));
110         HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER))
111                 ? HtmlTree.HEADER()
112                 : bodyTree;
113         addTop(htmlTree);
114         Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement),
115                 contents.moduleLabel);
116         navBar.setNavLinkModule(linkContent);
117         navBar.setUserHeader(getUserHeaderFooter(true));
118         htmlTree.addContent(navBar.getContent(true));
119         if (configuration.allowTag(HtmlTag.HEADER)) {
120             bodyTree.addContent(htmlTree);
121         }
122         HtmlTree div = new HtmlTree(HtmlTag.DIV);
123         div.setStyle(HtmlStyle.header);
124         if (configuration.showModules) {
125             ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(packageElement);
126             Content classModuleLabel = HtmlTree.SPAN(HtmlStyle.moduleLabelInPackage, contents.moduleLabel);
127             Content moduleNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, classModuleLabel);
128             moduleNameDiv.addContent(Contents.SPACE);
129             moduleNameDiv.addContent(getModuleLink(mdle,
130                     new StringContent(mdle.getQualifiedName().toString())));
131             div.addContent(moduleNameDiv);
132         }
133         Content annotationContent = new HtmlTree(HtmlTag.P);
134         addAnnotationInfo(packageElement, annotationContent);
135         div.addContent(annotationContent);
136         Content tHeading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
137                 HtmlStyle.title, contents.packageLabel);
138         tHeading.addContent(Contents.SPACE);
139         Content packageHead = new StringContent(heading);
140         tHeading.addContent(packageHead);
141         div.addContent(tHeading);
142         if (configuration.allowTag(HtmlTag.MAIN)) {
143             mainTree.addContent(div);
144         } else {
145             bodyTree.addContent(div);
146         }
147         return bodyTree;
148     }
149 
150     /**
151      * {@inheritDoc}
152      */
153     @Override
getContentHeader()154     public Content getContentHeader() {
155         HtmlTree div = new HtmlTree(HtmlTag.DIV);
156         div.setStyle(HtmlStyle.contentContainer);
157         return div;
158     }
159 
160     /**
161      * Add the package deprecation information to the documentation tree.
162      *
163      * @param div the content tree to which the deprecation information will be added
164      */
addDeprecationInfo(Content div)165     public void addDeprecationInfo(Content div) {
166         List<? extends DocTree> deprs = utils.getBlockTags(packageElement, DocTree.Kind.DEPRECATED);
167         if (utils.isDeprecated(packageElement)) {
168             CommentHelper ch = utils.getCommentHelper(packageElement);
169             HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV);
170             deprDiv.setStyle(HtmlStyle.deprecationBlock);
171             Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(packageElement));
172             deprDiv.addContent(deprPhrase);
173             if (!deprs.isEmpty()) {
174                 List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0));
175                 if (!commentTags.isEmpty()) {
176                     addInlineDeprecatedComment(packageElement, deprs.get(0), deprDiv);
177                 }
178             }
179             div.addContent(deprDiv);
180         }
181     }
182 
183     /**
184      * {@inheritDoc}
185      */
186     @Override
getSummaryHeader()187     public Content getSummaryHeader() {
188         HtmlTree ul = new HtmlTree(HtmlTag.UL);
189         ul.setStyle(HtmlStyle.blockList);
190         return ul;
191     }
192 
193     /**
194      * {@inheritDoc}
195      */
196     @Override
addInterfaceSummary(SortedSet<TypeElement> interfaces, Content summaryContentTree)197     public void addInterfaceSummary(SortedSet<TypeElement> interfaces, Content summaryContentTree) {
198         TableHeader tableHeader= new TableHeader(contents.interfaceLabel, contents.descriptionLabel);
199         addClassesSummary(interfaces, resources.interfaceSummary, resources.interfaceTableSummary,
200                 tableHeader, summaryContentTree);
201     }
202 
203     /**
204      * {@inheritDoc}
205      */
206     @Override
addClassSummary(SortedSet<TypeElement> classes, Content summaryContentTree)207     public void addClassSummary(SortedSet<TypeElement> classes, Content summaryContentTree) {
208         TableHeader tableHeader= new TableHeader(contents.classLabel, contents.descriptionLabel);
209         addClassesSummary(classes, resources.classSummary, resources.classTableSummary,
210                 tableHeader, summaryContentTree);
211     }
212 
213     /**
214      * {@inheritDoc}
215      */
216     @Override
addEnumSummary(SortedSet<TypeElement> enums, Content summaryContentTree)217     public void addEnumSummary(SortedSet<TypeElement> enums, Content summaryContentTree) {
218         TableHeader tableHeader= new TableHeader(contents.enum_, contents.descriptionLabel);
219         addClassesSummary(enums, resources.enumSummary, resources.enumTableSummary,
220                 tableHeader, summaryContentTree);
221     }
222 
223     /**
224      * {@inheritDoc}
225      */
226     @Override
addExceptionSummary(SortedSet<TypeElement> exceptions, Content summaryContentTree)227     public void addExceptionSummary(SortedSet<TypeElement> exceptions, Content summaryContentTree) {
228         TableHeader tableHeader= new TableHeader(contents.exception, contents.descriptionLabel);
229         addClassesSummary(exceptions, resources.exceptionSummary, resources.exceptionTableSummary,
230                 tableHeader, summaryContentTree);
231     }
232 
233     /**
234      * {@inheritDoc}
235      */
236     @Override
addErrorSummary(SortedSet<TypeElement> errors, Content summaryContentTree)237     public void addErrorSummary(SortedSet<TypeElement> errors, Content summaryContentTree) {
238         TableHeader tableHeader= new TableHeader(contents.error, contents.descriptionLabel);
239         addClassesSummary(errors, resources.errorSummary, resources.errorTableSummary,
240                 tableHeader, summaryContentTree);
241     }
242 
243     /**
244      * {@inheritDoc}
245      */
246     @Override
addAnnotationTypeSummary(SortedSet<TypeElement> annoTypes, Content summaryContentTree)247     public void addAnnotationTypeSummary(SortedSet<TypeElement> annoTypes, Content summaryContentTree) {
248         TableHeader tableHeader= new TableHeader(contents.annotationType, contents.descriptionLabel);
249         addClassesSummary(annoTypes, resources.annotationTypeSummary, resources.annotationTypeTableSummary,
250                 tableHeader, summaryContentTree);
251     }
252 
addClassesSummary(SortedSet<TypeElement> classes, String label, String tableSummary, TableHeader tableHeader, Content summaryContentTree)253     public void addClassesSummary(SortedSet<TypeElement> classes, String label,
254             String tableSummary, TableHeader tableHeader, Content summaryContentTree) {
255         if(!classes.isEmpty()) {
256             Table table = new Table(configuration.htmlVersion, HtmlStyle.typeSummary)
257                     .setSummary(tableSummary)
258                     .setCaption(getTableCaption(new StringContent(label)))
259                     .setHeader(tableHeader)
260                     .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast);
261 
262             for (TypeElement klass : classes) {
263                 if (!utils.isCoreClass(klass) || !configuration.isGeneratedDoc(klass)) {
264                     continue;
265                 }
266                 Content classLink = getLink(new LinkInfoImpl(
267                         configuration, LinkInfoImpl.Kind.PACKAGE, klass));
268                 ContentBuilder description = new ContentBuilder();
269                 if (utils.isDeprecated(klass)) {
270                     description.addContent(getDeprecatedPhrase(klass));
271                     List<? extends DocTree> tags = utils.getDeprecatedTrees(klass);
272                     if (!tags.isEmpty()) {
273                         addSummaryDeprecatedComment(klass, tags.get(0), description);
274                     }
275                 } else {
276                     addSummaryComment(klass, description);
277                 }
278                 table.addRow(classLink, description);
279             }
280             Content li = HtmlTree.LI(HtmlStyle.blockList, table.toContent());
281             summaryContentTree.addContent(li);
282         }
283     }
284 
285     /**
286      * {@inheritDoc}
287      */
288     @Override
addPackageDescription(Content packageContentTree)289     public void addPackageDescription(Content packageContentTree) {
290         if (!utils.getBody(packageElement).isEmpty()) {
291             Content tree = configuration.allowTag(HtmlTag.SECTION) ? sectionTree : packageContentTree;
292             tree.addContent(links.createAnchor(SectionName.PACKAGE_DESCRIPTION));
293             addDeprecationInfo(tree);
294             addInlineComment(packageElement, tree);
295         }
296     }
297 
298     /**
299      * {@inheritDoc}
300      */
301     @Override
addPackageTags(Content packageContentTree)302     public void addPackageTags(Content packageContentTree) {
303         Content htmlTree = (configuration.allowTag(HtmlTag.SECTION))
304                 ? sectionTree
305                 : packageContentTree;
306         addTagsInfo(packageElement, htmlTree);
307         if (configuration.allowTag(HtmlTag.SECTION)) {
308             packageContentTree.addContent(sectionTree);
309         }
310     }
311 
312     /**
313      * {@inheritDoc}
314      */
315     @Override
addPackageContent(Content contentTree, Content packageContentTree)316     public void addPackageContent(Content contentTree, Content packageContentTree) {
317         if (configuration.allowTag(HtmlTag.MAIN)) {
318             mainTree.addContent(packageContentTree);
319             contentTree.addContent(mainTree);
320         } else {
321             contentTree.addContent(packageContentTree);
322         }
323     }
324 
325     /**
326      * {@inheritDoc}
327      */
328     @Override
addPackageFooter(Content contentTree)329     public void addPackageFooter(Content contentTree) {
330         Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
331                 ? HtmlTree.FOOTER()
332                 : contentTree;
333         navBar.setUserFooter(getUserHeaderFooter(false));
334         htmlTree.addContent(navBar.getContent(false));
335         addBottom(htmlTree);
336         if (configuration.allowTag(HtmlTag.FOOTER)) {
337             contentTree.addContent(htmlTree);
338         }
339     }
340 
341     /**
342      * {@inheritDoc}
343      */
344     @Override
printDocument(Content contentTree)345     public void printDocument(Content contentTree) throws DocFileIOException {
346         printHtmlDocument(configuration.metakeywords.getMetaKeywords(packageElement),
347                 true, contentTree);
348     }
349 }
350