1 /*
2  * Copyright (c) 2016, 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 
36 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
37 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
38 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
39 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
40 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
41 import jdk.javadoc.internal.doclets.toolkit.Content;
42 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
43 import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
44 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
45 
46 /**
47  * Generate the module index page "overview-summary.html" for the right-hand
48  * frame.
49  *
50  *  <p><b>This is NOT part of any supported API.
51  *  If you write code that depends on this, you do so at your own risk.
52  *  This code and its internal interfaces are subject to change or
53  *  deletion without notice.</b>
54  *
55  * @author Bhavesh Patel
56  */
57 public class ModuleIndexWriter extends AbstractModuleIndexWriter {
58 
59     /**
60      * HTML tree for main tag.
61      */
62     private final HtmlTree htmlTree = HtmlTree.MAIN();
63 
64     /**
65      * Construct the ModuleIndexWriter.
66      * @param configuration the configuration object
67      * @param filename the name of the generated file
68      */
ModuleIndexWriter(HtmlConfiguration configuration, DocPath filename)69     public ModuleIndexWriter(HtmlConfiguration configuration, DocPath filename) {
70         super(configuration, filename);
71     }
72 
73     /**
74      * Generate the module index page for the right-hand frame.
75      *
76      * @param configuration the current configuration of the doclet.
77      * @throws DocFileIOException if there is a problem generating the module index page
78      */
generate(HtmlConfiguration configuration)79     public static void generate(HtmlConfiguration configuration) throws DocFileIOException {
80         DocPath filename = DocPaths.overviewSummary(configuration.frames);
81         ModuleIndexWriter mdlgen = new ModuleIndexWriter(configuration, filename);
82         mdlgen.buildModuleIndexFile("doclet.Window_Overview_Summary", true);
83     }
84 
85     /**
86      * Add the module index.
87      *
88      * @param body the documentation tree to which the index will be added
89      */
90     @Override
addIndex(Content body)91     protected void addIndex(Content body) {
92         addIndexContents(body);
93     }
94 
95     /**
96      * Adds module index contents.
97      *
98      * @param body the document tree to which the index contents will be added
99      */
addIndexContents(Content body)100     protected void addIndexContents(Content body) {
101         HtmlTree htmltree = (configuration.allowTag(HtmlTag.NAV))
102                 ? HtmlTree.NAV()
103                 : new HtmlTree(HtmlTag.DIV);
104         htmltree.setStyle(HtmlStyle.indexNav);
105         HtmlTree ul = new HtmlTree(HtmlTag.UL);
106         addAllClassesLink(ul);
107         if (configuration.showModules) {
108             addAllModulesLink(ul);
109         }
110         htmltree.addContent(ul);
111         body.addContent(htmltree);
112         addModulesList(body);
113     }
114 
115     /**
116      * Add the list of modules.
117      *
118      * @param body the content tree to which the module list will be added
119      */
120     @Override
addModulesList(Content body)121     protected void addModulesList(Content body) {
122         Map<String, SortedSet<ModuleElement>> groupModuleMap
123                 = configuration.group.groupModules(configuration.modules);
124 
125         if (!groupModuleMap.keySet().isEmpty()) {
126             String tableSummary = configuration.getText("doclet.Member_Table_Summary",
127                     configuration.getText("doclet.Module_Summary"), configuration.getText("doclet.modules"));
128             TableHeader header = new TableHeader(contents.moduleLabel, contents.descriptionLabel);
129             Table table =  new Table(configuration.htmlVersion, HtmlStyle.overviewSummary)
130                     .setSummary(tableSummary)
131                     .setHeader(header)
132                     .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast)
133                     .setDefaultTab(resources.getText("doclet.All_Modules"))
134                     .setTabScript(i -> "show(" + i + ");")
135                     .setTabId(i -> (i == 0) ? "t0" : ("t" + (1 << (i - 1))));
136 
137             // add the tabs in command-line order
138             for (String groupName : configuration.group.getGroupList()) {
139                 Set<ModuleElement> groupModules = groupModuleMap.get(groupName);
140                 if (groupModules != null) {
141                     table.addTab(groupName, groupModules::contains);
142                 }
143             }
144 
145             for (ModuleElement mdle : configuration.modules) {
146                 if (!mdle.isUnnamed()) {
147                     if (!(configuration.nodeprecated && utils.isDeprecated(mdle))) {
148                         Content moduleLinkContent = getModuleLink(mdle, new StringContent(mdle.getQualifiedName().toString()));
149                         Content summaryContent = new ContentBuilder();
150                         addSummaryComment(mdle, summaryContent);
151                         table.addRow(mdle, moduleLinkContent, summaryContent);
152                     }
153                 }
154             }
155 
156             Content div = HtmlTree.DIV(HtmlStyle.contentContainer, table.toContent());
157             if (configuration.allowTag(HtmlTag.MAIN)) {
158                 htmlTree.addContent(div);
159             } else {
160                 body.addContent(div);
161             }
162 
163             if (table.needsScript()) {
164                 mainBodyScript.append(table.getScript());
165             }
166         }
167     }
168 
169     /**
170      * Adds the overview summary comment for this documentation. Add one line
171      * summary at the top of the page and generate a link to the description,
172      * which is added at the end of this page.
173      *
174      * @param body the documentation tree to which the overview header will be added
175      */
176     @Override
addOverviewHeader(Content body)177     protected void addOverviewHeader(Content body) {
178         addConfigurationTitle(body);
179         if (!utils.getFullBody(configuration.overviewElement).isEmpty()) {
180             HtmlTree div = new HtmlTree(HtmlTag.DIV);
181             div.setStyle(HtmlStyle.contentContainer);
182             addOverviewComment(div);
183             if (configuration.allowTag(HtmlTag.MAIN)) {
184                 htmlTree.addContent(div);
185             } else {
186                 body.addContent(div);
187             }
188         }
189     }
190 
191     /**
192      * Adds the overview comment as provided in the file specified by the
193      * "-overview" option on the command line.
194      *
195      * @param htmltree the documentation tree to which the overview comment will
196      *                 be added
197      */
addOverviewComment(Content htmltree)198     protected void addOverviewComment(Content htmltree) {
199         if (!utils.getFullBody(configuration.overviewElement).isEmpty()) {
200             addInlineComment(configuration.overviewElement, htmltree);
201         }
202     }
203 
204     /**
205      * For HTML 5, add the htmlTree to the body. For HTML 4, do nothing.
206      *
207      * @param body the documentation tree to which the overview will be added
208      */
209     @Override
addOverview(Content body)210     protected void addOverview(Content body) {
211         if (configuration.allowTag(HtmlTag.MAIN)) {
212             body.addContent(htmlTree);
213         }
214     }
215 
216     /**
217      * Adds the top text (from the -top option), the upper
218      * navigation bar, and then the title (from the"-title"
219      * option), at the top of page.
220      *
221      * @param body the documentation tree to which the navigation bar header will be added
222      */
223     @Override
addNavigationBarHeader(Content body)224     protected void addNavigationBarHeader(Content body) {
225         Content tree = (configuration.allowTag(HtmlTag.HEADER))
226                 ? HtmlTree.HEADER()
227                 : body;
228         addTop(tree);
229         navBar.setUserHeader(getUserHeaderFooter(true));
230         tree.addContent(navBar.getContent(true));
231         if (configuration.allowTag(HtmlTag.HEADER)) {
232             body.addContent(tree);
233         }
234     }
235 
236     /**
237      * Adds the lower navigation bar and the bottom text
238      * (from the -bottom option) at the bottom of page.
239      *
240      * @param body the documentation tree to which the navigation bar footer will be added
241      */
242     @Override
addNavigationBarFooter(Content body)243     protected void addNavigationBarFooter(Content body) {
244         Content htmltree = (configuration.allowTag(HtmlTag.FOOTER))
245                 ? HtmlTree.FOOTER()
246                 : body;
247         navBar.setUserFooter(getUserHeaderFooter(false));
248         htmltree.addContent(navBar.getContent(false));
249         addBottom(htmltree);
250         if (configuration.allowTag(HtmlTag.FOOTER)) {
251             body.addContent(htmltree);
252         }
253     }
254 
255     @Override
addModulePackagesList(Map<ModuleElement, Set<PackageElement>> modules, String text, String tableSummary, Content body, ModuleElement mdle)256     protected void addModulePackagesList(Map<ModuleElement, Set<PackageElement>> modules, String text,
257             String tableSummary, Content body, ModuleElement mdle) {
258     }
259 }
260