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