1 /*
2  * Copyright (c) 2001, 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.Modifier;
34 import javax.lang.model.element.PackageElement;
35 import javax.lang.model.element.TypeElement;
36 import javax.lang.model.element.VariableElement;
37 
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.ConstantsSummaryWriter;
47 import jdk.javadoc.internal.doclets.toolkit.Content;
48 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
49 import jdk.javadoc.internal.doclets.toolkit.util.DocLink;
50 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
51 
52 
53 /**
54  * Write the Constants Summary Page in HTML format.
55  *
56  *  <p><b>This is NOT part of any supported API.
57  *  If you write code that depends on this, you do so at your own risk.
58  *  This code and its internal interfaces are subject to change or
59  *  deletion without notice.</b>
60  *
61  * @author Jamie Ho
62  * @author Bhavesh Patel (Modified)
63  */
64 public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements ConstantsSummaryWriter {
65 
66     /**
67      * The configuration used in this run of the standard doclet.
68      */
69     HtmlConfiguration configuration;
70 
71     /**
72      * The current class being documented.
73      */
74     private TypeElement currentTypeElement;
75 
76     private final String constantsTableSummary;
77 
78     private final TableHeader constantsTableHeader;
79 
80     /**
81      * The HTML tree for main tag.
82      */
83     private final HtmlTree mainTree = HtmlTree.MAIN();
84 
85     /**
86      * The HTML tree for constant values summary.
87      */
88     private HtmlTree summaryTree;
89 
90     private final Navigation navBar;
91 
92     /**
93      * Construct a ConstantsSummaryWriter.
94      * @param configuration the configuration used in this run
95      *        of the standard doclet.
96      */
ConstantsSummaryWriterImpl(HtmlConfiguration configuration)97     public ConstantsSummaryWriterImpl(HtmlConfiguration configuration) {
98         super(configuration, DocPaths.CONSTANT_VALUES);
99         this.configuration = configuration;
100         constantsTableSummary = resources.getText("doclet.Constants_Table_Summary",
101                 resources.getText("doclet.Constants_Summary"));
102         constantsTableHeader = new TableHeader(
103                 contents.modifierAndTypeLabel, contents.constantFieldLabel, contents.valueLabel);
104         this.navBar = new Navigation(null, configuration, fixedNavDiv, PageMode.CONSTANTVALUES, path);
105     }
106 
107     /**
108      * {@inheritDoc}
109      */
110     @Override
getHeader()111     public Content getHeader() {
112         String label = resources.getText("doclet.Constants_Summary");
113         HtmlTree bodyTree = getBody(true, getWindowTitle(label));
114         HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER))
115                 ? HtmlTree.HEADER()
116                 : bodyTree;
117         addTop(htmlTree);
118         navBar.setUserHeader(getUserHeaderFooter(true));
119         htmlTree.addContent(navBar.getContent(true));
120         if (configuration.allowTag(HtmlTag.HEADER)) {
121             bodyTree.addContent(htmlTree);
122         }
123         return bodyTree;
124     }
125 
126     /**
127      * {@inheritDoc}
128      */
129     @Override
getContentsHeader()130     public Content getContentsHeader() {
131         return new HtmlTree(HtmlTag.UL);
132     }
133 
134     /**
135      * {@inheritDoc}
136      */
137     @Override
addLinkToPackageContent(PackageElement pkg, Set<PackageElement> printedPackageHeaders, Content contentListTree)138     public void addLinkToPackageContent(PackageElement pkg,
139             Set<PackageElement> printedPackageHeaders, Content contentListTree) {
140         //add link to summary
141         Content link;
142         if (pkg.isUnnamed()) {
143             link = links.createLink(SectionName.UNNAMED_PACKAGE_ANCHOR,
144                     contents.defaultPackageLabel, "", "");
145         } else {
146             String parsedPackageName = utils.parsePackageName(pkg);
147             Content packageNameContent = getPackageLabel(parsedPackageName);
148             packageNameContent.addContent(".*");
149             link = links.createLink(DocLink.fragment(parsedPackageName),
150                     packageNameContent, "", "");
151             PackageElement abbrevPkg = configuration.workArounds.getAbbreviatedPackageElement(pkg);
152             printedPackageHeaders.add(abbrevPkg);
153         }
154         contentListTree.addContent(HtmlTree.LI(link));
155     }
156 
157     /**
158      * {@inheritDoc}
159      */
160     @Override
addContentsList(Content contentTree, Content contentListTree)161     public void addContentsList(Content contentTree, Content contentListTree) {
162         Content titleContent = contents.constantsSummaryTitle;
163         Content pHeading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
164                 HtmlStyle.title, titleContent);
165         Content div = HtmlTree.DIV(HtmlStyle.header, pHeading);
166         Content headingContent = contents.contentsHeading;
167         Content heading = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING, true,
168                 headingContent);
169         if (configuration.allowTag(HtmlTag.SECTION)) {
170             HtmlTree section = HtmlTree.SECTION(heading);
171             section.addContent(contentListTree);
172             div.addContent(section);
173             mainTree.addContent(div);
174         } else {
175             div.addContent(heading);
176             div.addContent(contentListTree);
177             contentTree.addContent(div);
178         }
179     }
180 
181     /**
182      * {@inheritDoc}
183      */
184     @Override
getConstantSummaries()185     public Content getConstantSummaries() {
186         HtmlTree summariesDiv = new HtmlTree(HtmlTag.DIV);
187         summariesDiv.setStyle(HtmlStyle.constantValuesContainer);
188         return summariesDiv;
189     }
190 
191     /**
192      * {@inheritDoc}
193      */
194     @Override
addPackageName(PackageElement pkg, Content summariesTree, boolean first)195     public void addPackageName(PackageElement pkg, Content summariesTree, boolean first) {
196         Content pkgNameContent;
197         if (!first && configuration.allowTag(HtmlTag.SECTION)) {
198             summariesTree.addContent(summaryTree);
199         }
200         if (pkg.isUnnamed()) {
201             summariesTree.addContent(links.createAnchor(SectionName.UNNAMED_PACKAGE_ANCHOR));
202             pkgNameContent = contents.defaultPackageLabel;
203         } else {
204             String parsedPackageName = utils.parsePackageName(pkg);
205             summariesTree.addContent(links.createAnchor(parsedPackageName));
206             pkgNameContent = getPackageLabel(parsedPackageName);
207         }
208         Content headingContent = new StringContent(".*");
209         Content heading = HtmlTree.HEADING(HtmlConstants.PACKAGE_HEADING, true,
210                 pkgNameContent);
211         heading.addContent(headingContent);
212         if (configuration.allowTag(HtmlTag.SECTION)) {
213             summaryTree = HtmlTree.SECTION(heading);
214         } else {
215             summariesTree.addContent(heading);
216         }
217     }
218 
219     /**
220      * {@inheritDoc}
221      */
222     @Override
getClassConstantHeader()223     public Content getClassConstantHeader() {
224         HtmlTree ul = new HtmlTree(HtmlTag.UL);
225         ul.setStyle(HtmlStyle.blockList);
226         return ul;
227     }
228 
229     /**
230      * {@inheritDoc}
231      */
232     @Override
addClassConstant(Content summariesTree, Content classConstantTree)233     public void addClassConstant(Content summariesTree, Content classConstantTree) {
234         if (configuration.allowTag(HtmlTag.SECTION)) {
235             summaryTree.addContent(classConstantTree);
236         } else {
237             summariesTree.addContent(classConstantTree);
238         }
239     }
240 
241     /**
242      * {@inheritDoc}
243      */
244     @Override
addConstantMembers(TypeElement typeElement, Collection<VariableElement> fields, Content classConstantTree)245     public void addConstantMembers(TypeElement typeElement, Collection<VariableElement> fields,
246             Content classConstantTree) {
247         currentTypeElement = typeElement;
248 
249         //generate links backward only to public classes.
250         Content classlink = (utils.isPublic(typeElement) || utils.isProtected(typeElement)) ?
251             getLink(new LinkInfoImpl(configuration,
252                     LinkInfoImpl.Kind.CONSTANT_SUMMARY, typeElement)) :
253             new StringContent(utils.getFullyQualifiedName(typeElement));
254 
255         PackageElement enclosingPackage  = utils.containingPackage(typeElement);
256         Content caption = new ContentBuilder();
257         if (!enclosingPackage.isUnnamed()) {
258             caption.addContent(enclosingPackage.getQualifiedName());
259             caption.addContent(".");
260         }
261         caption.addContent(classlink);
262 
263         Table table = new Table(configuration.htmlVersion, HtmlStyle.constantsSummary)
264                 .setSummary(constantsTableSummary)
265                 .setCaption(caption)
266                 .setHeader(constantsTableHeader)
267                 .setRowScopeColumn(1)
268                 .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colSecond, HtmlStyle.colLast);
269 
270         for (VariableElement field : fields) {
271             table.addRow(getTypeColumn(field), getNameColumn(field), getValue(field));
272         }
273         Content li = HtmlTree.LI(HtmlStyle.blockList, table.toContent());
274         classConstantTree.addContent(li);
275     }
276 
277     /**
278      * Get the type column for the constant summary table row.
279      *
280      * @param member the field to be documented.
281      * @return the type column of the constant table row
282      */
getTypeColumn(VariableElement member)283     private Content getTypeColumn(VariableElement member) {
284         Content anchor = links.createAnchor(
285                 currentTypeElement.getQualifiedName() + "." + member.getSimpleName());
286         Content typeContent = new ContentBuilder();
287         typeContent.addContent(anchor);
288         Content code = new HtmlTree(HtmlTag.CODE);
289         for (Modifier mod : member.getModifiers()) {
290             Content modifier = new StringContent(mod.toString());
291             code.addContent(modifier);
292             code.addContent(Contents.SPACE);
293         }
294         Content type = getLink(new LinkInfoImpl(configuration,
295                 LinkInfoImpl.Kind.CONSTANT_SUMMARY, member.asType()));
296         code.addContent(type);
297         typeContent.addContent(code);
298         return typeContent;
299     }
300 
301     /**
302      * Get the name column for the constant summary table row.
303      *
304      * @param member the field to be documented.
305      * @return the name column of the constant table row
306      */
getNameColumn(VariableElement member)307     private Content getNameColumn(VariableElement member) {
308         Content nameContent = getDocLink(LinkInfoImpl.Kind.CONSTANT_SUMMARY,
309                 member, member.getSimpleName(), false);
310         return HtmlTree.CODE(nameContent);
311     }
312 
313     /**
314      * Get the value column for the constant summary table row.
315      *
316      * @param member the field to be documented.
317      * @return the value column of the constant table row
318      */
getValue(VariableElement member)319     private Content getValue(VariableElement member) {
320         String value = utils.constantValueExpresion(member);
321         Content valueContent = new StringContent(value);
322         return HtmlTree.CODE(valueContent);
323     }
324 
325     /**
326      * {@inheritDoc}
327      */
328     @Override
addConstantSummaries(Content contentTree, Content summariesTree)329     public void addConstantSummaries(Content contentTree, Content summariesTree) {
330         if (configuration.allowTag(HtmlTag.SECTION) && summaryTree != null) {
331             summariesTree.addContent(summaryTree);
332         }
333         if (configuration.allowTag(HtmlTag.MAIN)) {
334             mainTree.addContent(summariesTree);
335             contentTree.addContent(mainTree);
336         } else {
337             contentTree.addContent(summariesTree);
338         }
339     }
340 
341     /**
342      * {@inheritDoc}
343      */
344     @Override
addFooter(Content contentTree)345     public void addFooter(Content contentTree) {
346         Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
347                 ? HtmlTree.FOOTER()
348                 : contentTree;
349         navBar.setUserFooter(getUserHeaderFooter(false));
350         htmlTree.addContent(navBar.getContent(false));
351         addBottom(htmlTree);
352         if (configuration.allowTag(HtmlTag.FOOTER)) {
353             contentTree.addContent(htmlTree);
354         }
355     }
356 
357     /**
358      * {@inheritDoc}
359      */
360     @Override
printDocument(Content contentTree)361     public void printDocument(Content contentTree) throws DocFileIOException {
362         printHtmlDocument(null, true, contentTree);
363     }
364 }
365