Tue, 09 Oct 2012 19:10:00 -0700
8000663: clean up langtools imports
Reviewed-by: darcy
1 /*
2 * Copyright (c) 1998, 2012, 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 */
26 package com.sun.tools.doclets.internal.toolkit.util;
28 import java.util.*;
30 import com.sun.javadoc.*;
31 import com.sun.tools.doclets.internal.toolkit.*;
33 /**
34 * Build Class Hierarchy for all the Classes. This class builds the Class
35 * Tree and the Interface Tree separately.
36 *
37 * This code is not part of an API.
38 * It is implementation that is subject to change.
39 * Do not use it as an API
40 *
41 * @see java.util.HashMap
42 * @see java.util.List
43 * @see com.sun.javadoc.Type
44 * @see com.sun.javadoc.ClassDoc
45 * @author Atul M Dambalkar
46 */
47 public class ClassTree {
49 /**
50 * List of baseclasses. Contains only java.lang.Object. Can be used to get
51 * the mapped listing of sub-classes.
52 */
53 private List<ClassDoc> baseclasses = new ArrayList<ClassDoc>();
55 /**
56 * Mapping for each Class with their SubClasses
57 */
58 private Map<ClassDoc,List<ClassDoc>> subclasses = new HashMap<ClassDoc,List<ClassDoc>>();
60 /**
61 * List of base-interfaces. Contains list of all the interfaces who do not
62 * have super-interfaces. Can be used to get the mapped listing of
63 * sub-interfaces.
64 */
65 private List<ClassDoc> baseinterfaces = new ArrayList<ClassDoc>();
67 /**
68 * Mapping for each Interface with their SubInterfaces
69 */
70 private Map<ClassDoc,List<ClassDoc>> subinterfaces = new HashMap<ClassDoc,List<ClassDoc>>();
72 private List<ClassDoc> baseEnums = new ArrayList<ClassDoc>();
73 private Map<ClassDoc,List<ClassDoc>> subEnums = new HashMap<ClassDoc,List<ClassDoc>>();
75 private List<ClassDoc> baseAnnotationTypes = new ArrayList<ClassDoc>();
76 private Map<ClassDoc,List<ClassDoc>> subAnnotationTypes = new HashMap<ClassDoc,List<ClassDoc>>();
78 /**
79 * Mapping for each Interface with classes who implement it.
80 */
81 private Map<ClassDoc,List<ClassDoc>> implementingclasses = new HashMap<ClassDoc,List<ClassDoc>>();
83 /**
84 * Constructor. Build the Tree using the Root of this Javadoc run.
85 *
86 * @param configuration the configuration of the doclet.
87 * @param noDeprecated Don't add deprecated classes in the class tree, if
88 * true.
89 */
90 public ClassTree(Configuration configuration, boolean noDeprecated) {
91 configuration.message.notice("doclet.Building_Tree");
92 buildTree(configuration.root.classes(), configuration);
93 }
95 /**
96 * Constructor. Build the Tree using the Root of this Javadoc run.
97 *
98 * @param root Root of the Document.
99 * @param configuration The curren configuration of the doclet.
100 */
101 public ClassTree(RootDoc root, Configuration configuration) {
102 buildTree(root.classes(), configuration);
103 }
105 /**
106 * Constructor. Build the tree for the given array of classes.
107 *
108 * @param classes Array of classes.
109 * @param configuration The curren configuration of the doclet.
110 */
111 public ClassTree(ClassDoc[] classes, Configuration configuration) {
112 buildTree(classes, configuration);
113 }
115 /**
116 * Generate mapping for the sub-classes for every class in this run.
117 * Return the sub-class list for java.lang.Object which will be having
118 * sub-class listing for itself and also for each sub-class itself will
119 * have their own sub-class lists.
120 *
121 * @param classes all the classes in this run.
122 * @param configuration the current configuration of the doclet.
123 */
124 private void buildTree(ClassDoc[] classes, Configuration configuration) {
125 for (int i = 0; i < classes.length; i++) {
126 // In the tree page (e.g overview-tree.html) do not include
127 // information of classes which are deprecated or are a part of a
128 // deprecated package.
129 if (configuration.nodeprecated &&
130 (Util.isDeprecated(classes[i]) ||
131 Util.isDeprecated(classes[i].containingPackage()))) {
132 continue;
133 }
134 if (classes[i].isEnum()) {
135 processType(classes[i], configuration, baseEnums, subEnums);
136 } else if (classes[i].isClass()) {
137 processType(classes[i], configuration, baseclasses, subclasses);
138 } else if (classes[i].isInterface()) {
139 processInterface(classes[i]);
140 List<ClassDoc> list = implementingclasses.get(classes[i]);
141 if (list != null) {
142 Collections.sort(list);
143 }
144 } else if (classes[i].isAnnotationType()) {
145 processType(classes[i], configuration, baseAnnotationTypes,
146 subAnnotationTypes);
147 }
148 }
150 Collections.sort(baseinterfaces);
151 for (Iterator<List<ClassDoc>> it = subinterfaces.values().iterator(); it.hasNext(); ) {
152 Collections.sort(it.next());
153 }
154 for (Iterator<List<ClassDoc>> it = subclasses.values().iterator(); it.hasNext(); ) {
155 Collections.sort(it.next());
156 }
157 }
159 /**
160 * For the class passed map it to it's own sub-class listing.
161 * For the Class passed, get the super class,
162 * if superclass is non null, (it is not "java.lang.Object")
163 * get the "value" from the hashmap for this key Class
164 * if entry not found create one and get that.
165 * add this Class as a sub class in the list
166 * Recurse till hits java.lang.Object Null SuperClass.
167 *
168 * @param cd class for which sub-class mapping to be generated.
169 * @param configuration the current configurtation of the doclet.
170 */
171 private void processType(ClassDoc cd, Configuration configuration,
172 List<ClassDoc> bases, Map<ClassDoc,List<ClassDoc>> subs) {
173 ClassDoc superclass = Util.getFirstVisibleSuperClassCD(cd, configuration);
174 if (superclass != null) {
175 if (!add(subs, superclass, cd)) {
176 return;
177 } else {
178 processType(superclass, configuration, bases, subs);
179 }
180 } else { // cd is java.lang.Object, add it once to the list
181 if (!bases.contains(cd)) {
182 bases.add(cd);
183 }
184 }
185 List<Type> intfacs = Util.getAllInterfaces(cd, configuration);
186 for (Iterator<Type> iter = intfacs.iterator(); iter.hasNext();) {
187 add(implementingclasses, iter.next().asClassDoc(), cd);
188 }
189 }
191 /**
192 * For the interface passed get the interfaces which it extends, and then
193 * put this interface in the sub-interface list of those interfaces. Do it
194 * recursively. If a interface doesn't have super-interface just attach
195 * that interface in the list of all the baseinterfaces.
196 *
197 * @param cd Interface under consideration.
198 */
199 private void processInterface(ClassDoc cd) {
200 ClassDoc[] intfacs = cd.interfaces();
201 if (intfacs.length > 0) {
202 for (int i = 0; i < intfacs.length; i++) {
203 if (!add(subinterfaces, intfacs[i], cd)) {
204 return;
205 } else {
206 processInterface(intfacs[i]); // Recurse
207 }
208 }
209 } else {
210 // we need to add all the interfaces who do not have
211 // super-interfaces to baseinterfaces list to traverse them
212 if (!baseinterfaces.contains(cd)) {
213 baseinterfaces.add(cd);
214 }
215 }
216 }
218 /**
219 * Adjust the Class Tree. Add the class interface in to it's super-class'
220 * or super-interface's sub-interface list.
221 *
222 * @param map the entire map.
223 * @param superclass java.lang.Object or the super-interface.
224 * @param cd sub-interface to be mapped.
225 * @returns boolean true if class added, false if class already processed.
226 */
227 private boolean add(Map<ClassDoc,List<ClassDoc>> map, ClassDoc superclass, ClassDoc cd) {
228 List<ClassDoc> list = map.get(superclass);
229 if (list == null) {
230 list = new ArrayList<ClassDoc>();
231 map.put(superclass, list);
232 }
233 if (list.contains(cd)) {
234 return false;
235 } else {
236 list.add(cd);
237 }
238 return true;
239 }
241 /**
242 * From the map return the list of sub-classes or sub-interfaces. If list
243 * is null create a new one and return it.
244 *
245 * @param map The entire map.
246 * @param cd class for which the sub-class list is requested.
247 * @returns List Sub-Class list for the class passed.
248 */
249 private List<ClassDoc> get(Map<ClassDoc,List<ClassDoc>> map, ClassDoc cd) {
250 List<ClassDoc> list = map.get(cd);
251 if (list == null) {
252 return new ArrayList<ClassDoc>();
253 }
254 return list;
255 }
257 /**
258 * Return the sub-class list for the class passed.
259 *
260 * @param cd class whose sub-class list is required.
261 */
262 public List<ClassDoc> subclasses(ClassDoc cd) {
263 return get(subclasses, cd);
264 }
266 /**
267 * Return the sub-interface list for the interface passed.
268 *
269 * @param cd interface whose sub-interface list is required.
270 */
271 public List<ClassDoc> subinterfaces(ClassDoc cd) {
272 return get(subinterfaces, cd);
273 }
275 /**
276 * Return the list of classes which implement the interface passed.
277 *
278 * @param cd interface whose implementing-classes list is required.
279 */
280 public List<ClassDoc> implementingclasses(ClassDoc cd) {
281 List<ClassDoc> result = get(implementingclasses, cd);
282 List<ClassDoc> subinterfaces = allSubs(cd, false);
284 //If class x implements a subinterface of cd, then it follows
285 //that class x implements cd.
286 Iterator<ClassDoc> implementingClassesIter, subInterfacesIter = subinterfaces.listIterator();
287 ClassDoc c;
288 while(subInterfacesIter.hasNext()){
289 implementingClassesIter = implementingclasses(
290 subInterfacesIter.next()).listIterator();
291 while(implementingClassesIter.hasNext()){
292 c = implementingClassesIter.next();
293 if(! result.contains(c)){
294 result.add(c);
295 }
296 }
297 }
298 Collections.sort(result);
299 return result;
300 }
302 /**
303 * Return the sub-class/interface list for the class/interface passed.
304 *
305 * @param cd class/interface whose sub-class/interface list is required.
306 * @param isEnum true if the subclasses should be forced to come from the
307 * enum tree.
308 */
309 public List<ClassDoc> subs(ClassDoc cd, boolean isEnum) {
310 if (isEnum) {
311 return get(subEnums, cd);
312 } else if (cd.isAnnotationType()) {
313 return get(subAnnotationTypes, cd);
314 } else if (cd.isInterface()) {
315 return get(subinterfaces, cd);
316 } else if (cd.isClass()) {
317 return get(subclasses, cd);
318 } else {
319 return null;
320 }
322 }
324 /**
325 * Return a list of all direct or indirect, sub-classes and subinterfaces
326 * of the ClassDoc argument.
327 *
328 * @param cd ClassDoc whose sub-classes or sub-interfaces are requested.
329 * @param isEnum true if the subclasses should be forced to come from the
330 * enum tree.
331 */
332 public List<ClassDoc> allSubs(ClassDoc cd, boolean isEnum) {
333 List<ClassDoc> list = subs(cd, isEnum);
334 for (int i = 0; i < list.size(); i++) {
335 cd = list.get(i);
336 List<ClassDoc> tlist = subs(cd, isEnum);
337 for (int j = 0; j < tlist.size(); j++) {
338 ClassDoc tcd = tlist.get(j);
339 if (!list.contains(tcd)) {
340 list.add(tcd);
341 }
342 }
343 }
344 Collections.sort(list);
345 return list;
346 }
348 /**
349 * Return the base-classes list. This will have only one element namely
350 * thw classdoc for java.lang.Object, since this is the base class for all
351 * classes.
352 */
353 public List<ClassDoc> baseclasses() {
354 return baseclasses;
355 }
357 /**
358 * Return the list of base interfaces. This is the list of interfaces
359 * which do not have super-interface.
360 */
361 public List<ClassDoc> baseinterfaces() {
362 return baseinterfaces;
363 }
365 /**
366 * Return the list of base enums. This is the list of enums
367 * which do not have super-enums.
368 */
369 public List<ClassDoc> baseEnums() {
370 return baseEnums;
371 }
373 /**
374 * Return the list of base annotation types. This is the list of
375 * annotation types which do not have super-annotation types.
376 */
377 public List<ClassDoc> baseAnnotationTypes() {
378 return baseAnnotationTypes;
379 }
380 }