|
1 /* |
|
2 * Copyright (c) 1998, 2016, 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.io.*; |
|
29 import java.util.*; |
|
30 |
|
31 import javax.lang.model.element.TypeElement; |
|
32 |
|
33 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants; |
|
34 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; |
|
35 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; |
|
36 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; |
|
37 import jdk.javadoc.internal.doclets.toolkit.Content; |
|
38 import jdk.javadoc.internal.doclets.toolkit.util.ClassTree; |
|
39 import jdk.javadoc.internal.doclets.toolkit.util.DocPath; |
|
40 import jdk.javadoc.internal.doclets.toolkit.util.DocletAbortException; |
|
41 |
|
42 |
|
43 /** |
|
44 * Abstract class to print the class hierarchy page for all the Classes. This |
|
45 * is sub-classed by {@link PackageTreeWriter} and {@link TreeWriter} to |
|
46 * generate the Package Tree and global Tree(for all the classes and packages) |
|
47 * pages. |
|
48 * |
|
49 * <p><b>This is NOT part of any supported API. |
|
50 * If you write code that depends on this, you do so at your own risk. |
|
51 * This code and its internal interfaces are subject to change or |
|
52 * deletion without notice.</b> |
|
53 * |
|
54 * @author Atul M Dambalkar |
|
55 */ |
|
56 public abstract class AbstractTreeWriter extends HtmlDocletWriter { |
|
57 |
|
58 /** |
|
59 * The class and interface tree built by using {@link ClassTree} |
|
60 */ |
|
61 protected final ClassTree classtree; |
|
62 |
|
63 /** |
|
64 * Constructor initializes classtree variable. This constructor will be used |
|
65 * while generating global tree file "overview-tree.html". |
|
66 * |
|
67 * @param configuration The current configuration |
|
68 * @param filename File to be generated. |
|
69 * @param classtree Tree built by {@link ClassTree}. |
|
70 * @throws IOException |
|
71 * @throws DocletAbortException |
|
72 */ |
|
73 protected AbstractTreeWriter(ConfigurationImpl configuration, |
|
74 DocPath filename, ClassTree classtree) |
|
75 throws IOException { |
|
76 super(configuration, filename); |
|
77 this.classtree = classtree; |
|
78 } |
|
79 |
|
80 /** |
|
81 * Add each level of the class tree. For each sub-class or |
|
82 * sub-interface indents the next level information. |
|
83 * Recurses itself to add sub-classes info. |
|
84 * |
|
85 * @param parent the superclass or superinterface of the sset |
|
86 * @param collection a collection of the sub-classes at this level |
|
87 * @param isEnum true if we are generating a tree for enums |
|
88 * @param contentTree the content tree to which the level information will be added |
|
89 */ |
|
90 protected void addLevelInfo(TypeElement parent, Collection<TypeElement> collection, |
|
91 boolean isEnum, Content contentTree) { |
|
92 if (!collection.isEmpty()) { |
|
93 Content ul = new HtmlTree(HtmlTag.UL); |
|
94 for (TypeElement local : collection) { |
|
95 HtmlTree li = new HtmlTree(HtmlTag.LI); |
|
96 li.addStyle(HtmlStyle.circle); |
|
97 addPartialInfo(local, li); |
|
98 addExtendsImplements(parent, local, li); |
|
99 addLevelInfo(local, classtree.directSubClasses(local, isEnum), |
|
100 isEnum, li); // Recurse |
|
101 ul.addContent(li); |
|
102 } |
|
103 contentTree.addContent(ul); |
|
104 } |
|
105 } |
|
106 |
|
107 /** |
|
108 * Add the heading for the tree depending upon tree type if it's a |
|
109 * Class Tree or Interface tree. |
|
110 * |
|
111 * @param sset classes which are at the most base level, all the |
|
112 * other classes in this run will derive from these classes |
|
113 * @param heading heading for the tree |
|
114 * @param div the content tree to which the tree will be added |
|
115 */ |
|
116 protected void addTree(SortedSet<TypeElement> sset, String heading, HtmlTree div) { |
|
117 addTree(sset, heading, div, false); |
|
118 } |
|
119 |
|
120 protected void addTree(SortedSet<TypeElement> sset, String heading, |
|
121 HtmlTree div, boolean isEnums) { |
|
122 if (!sset.isEmpty()) { |
|
123 TypeElement firstTypeElement = sset.first(); |
|
124 Content headingContent = getResource(heading); |
|
125 Content sectionHeading = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING, true, |
|
126 headingContent); |
|
127 HtmlTree htmlTree; |
|
128 if (configuration.allowTag(HtmlTag.SECTION)) { |
|
129 htmlTree = HtmlTree.SECTION(sectionHeading); |
|
130 } else { |
|
131 div.addContent(sectionHeading); |
|
132 htmlTree = div; |
|
133 } |
|
134 addLevelInfo(!utils.isInterface(firstTypeElement) ? firstTypeElement : null, |
|
135 sset, isEnums, htmlTree); |
|
136 if (configuration.allowTag(HtmlTag.SECTION)) { |
|
137 div.addContent(htmlTree); |
|
138 } |
|
139 } |
|
140 } |
|
141 |
|
142 /** |
|
143 * Add information regarding the classes which this class extends or |
|
144 * implements. |
|
145 * |
|
146 * @param parent the parent class of the class being documented |
|
147 * @param typeElement the TypeElement under consideration |
|
148 * @param contentTree the content tree to which the information will be added |
|
149 */ |
|
150 protected void addExtendsImplements(TypeElement parent, TypeElement typeElement, |
|
151 Content contentTree) { |
|
152 SortedSet<TypeElement> interfaces = new TreeSet<>(utils.makeGeneralPurposeComparator()); |
|
153 typeElement.getInterfaces().stream().forEach((t) -> { |
|
154 interfaces.add(utils.asTypeElement(t)); |
|
155 }); |
|
156 if (interfaces.size() > (utils.isInterface(typeElement) ? 1 : 0)) { |
|
157 boolean isFirst = true; |
|
158 for (TypeElement intf : interfaces) { |
|
159 if (parent != intf) { |
|
160 if (utils.isPublic(intf) || utils.isLinkable(intf)) { |
|
161 if (isFirst) { |
|
162 isFirst = false; |
|
163 if (utils.isInterface(typeElement)) { |
|
164 contentTree.addContent(" ("); |
|
165 contentTree.addContent(getResource("doclet.also")); |
|
166 contentTree.addContent(" extends "); |
|
167 } else { |
|
168 contentTree.addContent(" (implements "); |
|
169 } |
|
170 } else { |
|
171 contentTree.addContent(", "); |
|
172 } |
|
173 addPreQualifiedClassLink(LinkInfoImpl.Kind.TREE, intf, contentTree); |
|
174 } |
|
175 } |
|
176 } |
|
177 if (!isFirst) { |
|
178 contentTree.addContent(")"); |
|
179 } |
|
180 } |
|
181 } |
|
182 |
|
183 /** |
|
184 * Add information about the class kind, if it's a "class" or "interface". |
|
185 * |
|
186 * @param typeElement the class being documented |
|
187 * @param contentTree the content tree to which the information will be added |
|
188 */ |
|
189 protected void addPartialInfo(TypeElement typeElement, Content contentTree) { |
|
190 addPreQualifiedStrongClassLink(LinkInfoImpl.Kind.TREE, typeElement, contentTree); |
|
191 } |
|
192 |
|
193 /** |
|
194 * Get the tree label for the navigation bar. |
|
195 * |
|
196 * @return a content tree for the tree label |
|
197 */ |
|
198 protected Content getNavLinkTree() { |
|
199 Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, treeLabel); |
|
200 return li; |
|
201 } |
|
202 } |