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