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 java.util.SortedSet;
29 
30 import javax.lang.model.element.PackageElement;
31 
32 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
33 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
34 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
35 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
36 import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
37 import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
38 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
39 import jdk.javadoc.internal.doclets.toolkit.Content;
40 import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
41 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
42 import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
43 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
44 
45 /**
46  * Generate Class Hierarchy page for all the Classes in this run.  Use
47  * ClassTree for building the Tree. The name of
48  * the generated file is "overview-tree.html" and it is generated in the
49  * current or the destination directory.
50  *
51  *  <p><b>This is NOT part of any supported API.
52  *  If you write code that depends on this, you do so at your own risk.
53  *  This code and its internal interfaces are subject to change or
54  *  deletion without notice.</b>
55  *
56  * @author Atul M Dambalkar
57  * @author Bhavesh Patel (Modified)
58  */
59 public class TreeWriter extends AbstractTreeWriter {
60 
61     /**
62      * Packages in this run.
63      */
64     SortedSet<PackageElement> packages;
65 
66     /**
67      * True if there are no packages specified on the command line,
68      * False otherwise.
69      */
70     private final boolean classesOnly;
71 
72     private final Navigation navBar;
73 
74     /**
75      * Constructor to construct TreeWriter object.
76      *
77      * @param configuration the current configuration of the doclet.
78      * @param filename String filename
79      * @param classtree the tree being built.
80      */
TreeWriter(HtmlConfiguration configuration, DocPath filename, ClassTree classtree)81     public TreeWriter(HtmlConfiguration configuration, DocPath filename, ClassTree classtree) {
82         super(configuration, filename, classtree);
83         packages = configuration.packages;
84         classesOnly = packages.isEmpty();
85         this.navBar = new Navigation(null, configuration, fixedNavDiv, PageMode.TREE, path);
86     }
87 
88     /**
89      * Create a TreeWriter object and use it to generate the
90      * "overview-tree.html" file.
91      *
92      * @param configuration the configuration for this doclet
93      * @param classtree the class tree being documented.
94      * @throws  DocFileIOException if there is a problem generating the overview tree page
95      */
generate(HtmlConfiguration configuration, ClassTree classtree)96     public static void generate(HtmlConfiguration configuration,
97                                 ClassTree classtree) throws DocFileIOException {
98         DocPath filename = DocPaths.OVERVIEW_TREE;
99         TreeWriter treegen = new TreeWriter(configuration, filename, classtree);
100         treegen.generateTreeFile();
101     }
102 
103     /**
104      * Generate the interface hierarchy and class hierarchy.
105      *
106      * @throws DocFileIOException if there is a problem generating the overview tree page
107      */
generateTreeFile()108     public void generateTreeFile() throws DocFileIOException {
109         HtmlTree body = getTreeHeader();
110         Content headContent = contents.hierarchyForAllPackages;
111         Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, false,
112                 HtmlStyle.title, headContent);
113         Content div = HtmlTree.DIV(HtmlStyle.header, heading);
114         addPackageTreeLinks(div);
115         HtmlTree htmlTree = (configuration.allowTag(HtmlTag.MAIN))
116                 ? HtmlTree.MAIN()
117                 : body;
118         htmlTree.addContent(div);
119         HtmlTree divTree = new HtmlTree(HtmlTag.DIV);
120         divTree.setStyle(HtmlStyle.contentContainer);
121         addTree(classtree.baseClasses(), "doclet.Class_Hierarchy", divTree);
122         addTree(classtree.baseInterfaces(), "doclet.Interface_Hierarchy", divTree);
123         addTree(classtree.baseAnnotationTypes(), "doclet.Annotation_Type_Hierarchy", divTree);
124         addTree(classtree.baseEnums(), "doclet.Enum_Hierarchy", divTree, true);
125         htmlTree.addContent(divTree);
126         if (configuration.allowTag(HtmlTag.MAIN)) {
127             body.addContent(htmlTree);
128         }
129         if (configuration.allowTag(HtmlTag.FOOTER)) {
130             htmlTree = HtmlTree.FOOTER();
131         } else {
132             htmlTree = body;
133         }
134         navBar.setUserFooter(getUserHeaderFooter(false));
135         htmlTree.addContent(navBar.getContent(false));
136         addBottom(htmlTree);
137         if (configuration.allowTag(HtmlTag.FOOTER)) {
138             body.addContent(htmlTree);
139         }
140         printHtmlDocument(null, true, body);
141     }
142 
143     /**
144      * Add the links to all the package tree files.
145      *
146      * @param contentTree the content tree to which the links will be added
147      */
addPackageTreeLinks(Content contentTree)148     protected void addPackageTreeLinks(Content contentTree) {
149         //Do nothing if only unnamed package is used
150         if (isUnnamedPackage()) {
151             return;
152         }
153         if (!classesOnly) {
154             Content span = HtmlTree.SPAN(HtmlStyle.packageHierarchyLabel,
155                     contents.packageHierarchies);
156             contentTree.addContent(span);
157             HtmlTree ul = new HtmlTree(HtmlTag.UL);
158             ul.setStyle(HtmlStyle.horizontal);
159             int i = 0;
160             for (PackageElement pkg : packages) {
161                 // If the package name length is 0 or if -nodeprecated option
162                 // is set and the package is marked as deprecated, do not include
163                 // the page in the list of package hierarchies.
164                 if (pkg.isUnnamed() ||
165                         (configuration.nodeprecated && utils.isDeprecated(pkg))) {
166                     i++;
167                     continue;
168                 }
169                 DocPath link = pathString(pkg, DocPaths.PACKAGE_TREE);
170                 Content li = HtmlTree.LI(links.createLink(link,
171                         new StringContent(utils.getPackageName(pkg))));
172                 if (i < packages.size() - 1) {
173                     li.addContent(", ");
174                 }
175                 ul.addContent(li);
176                 i++;
177             }
178             contentTree.addContent(ul);
179         }
180     }
181 
182     /**
183      * Get the tree header.
184      *
185      * @return a content tree for the tree header
186      */
getTreeHeader()187     protected HtmlTree getTreeHeader() {
188         String title = configuration.getText("doclet.Window_Class_Hierarchy");
189         HtmlTree bodyTree = getBody(true, getWindowTitle(title));
190         HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER))
191                 ? HtmlTree.HEADER()
192                 : bodyTree;
193         addTop(htmlTree);
194         navBar.setUserHeader(getUserHeaderFooter(true));
195         htmlTree.addContent(navBar.getContent(true));
196         if (configuration.allowTag(HtmlTag.HEADER)) {
197             bodyTree.addContent(htmlTree);
198         }
199         return bodyTree;
200     }
201 
isUnnamedPackage()202     private boolean isUnnamedPackage() {
203         return packages.size() == 1 && packages.first().isUnnamed();
204     }
205 }
206