src/share/classes/com/sun/tools/doclets/internal/toolkit/util/ClassTree.java

Sun, 24 Feb 2013 11:36:58 -0800

author
jjg
date
Sun, 24 Feb 2013 11:36:58 -0800
changeset 1606
ccbe7ffdd867
parent 1359
25e14ad23cef
child 2525
2eb010b6cb22
permissions
-rw-r--r--

7112427: The doclet needs to be able to generate JavaFX documentation.
Reviewed-by: jjg
Contributed-by: jan.valenta@oracle.com

duke@1 1 /*
jjg@1606 2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
ohair@554 7 * published by the Free Software Foundation. Oracle designates this
duke@1 8 * particular file as subject to the "Classpath" exception as provided
ohair@554 9 * by Oracle in the LICENSE file that accompanied this code.
duke@1 10 *
duke@1 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 15 * accompanied this code).
duke@1 16 *
duke@1 17 * You should have received a copy of the GNU General Public License version
duke@1 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 20 *
ohair@554 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@554 22 * or visit www.oracle.com if you need additional information or have any
ohair@554 23 * questions.
duke@1 24 */
duke@1 25
duke@1 26 package com.sun.tools.doclets.internal.toolkit.util;
duke@1 27
jjg@1357 28 import java.util.*;
jjg@1357 29
jjg@1357 30 import com.sun.javadoc.*;
duke@1 31 import com.sun.tools.doclets.internal.toolkit.*;
duke@1 32
duke@1 33 /**
duke@1 34 * Build Class Hierarchy for all the Classes. This class builds the Class
duke@1 35 * Tree and the Interface Tree separately.
duke@1 36 *
jjg@1359 37 * <p><b>This is NOT part of any supported API.
jjg@1359 38 * If you write code that depends on this, you do so at your own risk.
jjg@1359 39 * This code and its internal interfaces are subject to change or
jjg@1359 40 * deletion without notice.</b>
duke@1 41 *
duke@1 42 * @see java.util.HashMap
duke@1 43 * @see java.util.List
duke@1 44 * @see com.sun.javadoc.Type
duke@1 45 * @see com.sun.javadoc.ClassDoc
duke@1 46 * @author Atul M Dambalkar
duke@1 47 */
duke@1 48 public class ClassTree {
duke@1 49
duke@1 50 /**
duke@1 51 * List of baseclasses. Contains only java.lang.Object. Can be used to get
duke@1 52 * the mapped listing of sub-classes.
duke@1 53 */
jjg@74 54 private List<ClassDoc> baseclasses = new ArrayList<ClassDoc>();
duke@1 55
duke@1 56 /**
duke@1 57 * Mapping for each Class with their SubClasses
duke@1 58 */
jjg@74 59 private Map<ClassDoc,List<ClassDoc>> subclasses = new HashMap<ClassDoc,List<ClassDoc>>();
duke@1 60
duke@1 61 /**
duke@1 62 * List of base-interfaces. Contains list of all the interfaces who do not
duke@1 63 * have super-interfaces. Can be used to get the mapped listing of
duke@1 64 * sub-interfaces.
duke@1 65 */
jjg@74 66 private List<ClassDoc> baseinterfaces = new ArrayList<ClassDoc>();
duke@1 67
duke@1 68 /**
duke@1 69 * Mapping for each Interface with their SubInterfaces
duke@1 70 */
jjg@74 71 private Map<ClassDoc,List<ClassDoc>> subinterfaces = new HashMap<ClassDoc,List<ClassDoc>>();
duke@1 72
jjg@74 73 private List<ClassDoc> baseEnums = new ArrayList<ClassDoc>();
jjg@74 74 private Map<ClassDoc,List<ClassDoc>> subEnums = new HashMap<ClassDoc,List<ClassDoc>>();
duke@1 75
jjg@74 76 private List<ClassDoc> baseAnnotationTypes = new ArrayList<ClassDoc>();
jjg@74 77 private Map<ClassDoc,List<ClassDoc>> subAnnotationTypes = new HashMap<ClassDoc,List<ClassDoc>>();
duke@1 78
duke@1 79 /**
duke@1 80 * Mapping for each Interface with classes who implement it.
duke@1 81 */
jjg@74 82 private Map<ClassDoc,List<ClassDoc>> implementingclasses = new HashMap<ClassDoc,List<ClassDoc>>();
duke@1 83
duke@1 84 /**
duke@1 85 * Constructor. Build the Tree using the Root of this Javadoc run.
duke@1 86 *
duke@1 87 * @param configuration the configuration of the doclet.
duke@1 88 * @param noDeprecated Don't add deprecated classes in the class tree, if
duke@1 89 * true.
duke@1 90 */
duke@1 91 public ClassTree(Configuration configuration, boolean noDeprecated) {
duke@1 92 configuration.message.notice("doclet.Building_Tree");
duke@1 93 buildTree(configuration.root.classes(), configuration);
duke@1 94 }
duke@1 95
duke@1 96 /**
duke@1 97 * Constructor. Build the Tree using the Root of this Javadoc run.
duke@1 98 *
duke@1 99 * @param root Root of the Document.
duke@1 100 * @param configuration The curren configuration of the doclet.
duke@1 101 */
duke@1 102 public ClassTree(RootDoc root, Configuration configuration) {
duke@1 103 buildTree(root.classes(), configuration);
duke@1 104 }
duke@1 105
duke@1 106 /**
duke@1 107 * Constructor. Build the tree for the given array of classes.
duke@1 108 *
duke@1 109 * @param classes Array of classes.
duke@1 110 * @param configuration The curren configuration of the doclet.
duke@1 111 */
duke@1 112 public ClassTree(ClassDoc[] classes, Configuration configuration) {
duke@1 113 buildTree(classes, configuration);
duke@1 114 }
duke@1 115
duke@1 116 /**
duke@1 117 * Generate mapping for the sub-classes for every class in this run.
duke@1 118 * Return the sub-class list for java.lang.Object which will be having
duke@1 119 * sub-class listing for itself and also for each sub-class itself will
duke@1 120 * have their own sub-class lists.
duke@1 121 *
duke@1 122 * @param classes all the classes in this run.
duke@1 123 * @param configuration the current configuration of the doclet.
duke@1 124 */
duke@1 125 private void buildTree(ClassDoc[] classes, Configuration configuration) {
duke@1 126 for (int i = 0; i < classes.length; i++) {
bpatel@995 127 // In the tree page (e.g overview-tree.html) do not include
bpatel@995 128 // information of classes which are deprecated or are a part of a
bpatel@995 129 // deprecated package.
duke@1 130 if (configuration.nodeprecated &&
bpatel@995 131 (Util.isDeprecated(classes[i]) ||
bpatel@995 132 Util.isDeprecated(classes[i].containingPackage()))) {
duke@1 133 continue;
duke@1 134 }
jjg@1606 135
jjg@1606 136 if (configuration.javafx
jjg@1606 137 && classes[i].tags("treatAsPrivate").length > 0) {
jjg@1606 138 continue;
jjg@1606 139 }
jjg@1606 140
duke@1 141 if (classes[i].isEnum()) {
duke@1 142 processType(classes[i], configuration, baseEnums, subEnums);
duke@1 143 } else if (classes[i].isClass()) {
duke@1 144 processType(classes[i], configuration, baseclasses, subclasses);
duke@1 145 } else if (classes[i].isInterface()) {
duke@1 146 processInterface(classes[i]);
jjg@74 147 List<ClassDoc> list = implementingclasses.get(classes[i]);
duke@1 148 if (list != null) {
duke@1 149 Collections.sort(list);
duke@1 150 }
duke@1 151 } else if (classes[i].isAnnotationType()) {
duke@1 152 processType(classes[i], configuration, baseAnnotationTypes,
duke@1 153 subAnnotationTypes);
duke@1 154 }
duke@1 155 }
duke@1 156
duke@1 157 Collections.sort(baseinterfaces);
jjg@74 158 for (Iterator<List<ClassDoc>> it = subinterfaces.values().iterator(); it.hasNext(); ) {
jjg@74 159 Collections.sort(it.next());
duke@1 160 }
jjg@74 161 for (Iterator<List<ClassDoc>> it = subclasses.values().iterator(); it.hasNext(); ) {
jjg@74 162 Collections.sort(it.next());
duke@1 163 }
duke@1 164 }
duke@1 165
duke@1 166 /**
duke@1 167 * For the class passed map it to it's own sub-class listing.
duke@1 168 * For the Class passed, get the super class,
duke@1 169 * if superclass is non null, (it is not "java.lang.Object")
duke@1 170 * get the "value" from the hashmap for this key Class
duke@1 171 * if entry not found create one and get that.
duke@1 172 * add this Class as a sub class in the list
duke@1 173 * Recurse till hits java.lang.Object Null SuperClass.
duke@1 174 *
duke@1 175 * @param cd class for which sub-class mapping to be generated.
duke@1 176 * @param configuration the current configurtation of the doclet.
duke@1 177 */
duke@1 178 private void processType(ClassDoc cd, Configuration configuration,
jjg@74 179 List<ClassDoc> bases, Map<ClassDoc,List<ClassDoc>> subs) {
duke@1 180 ClassDoc superclass = Util.getFirstVisibleSuperClassCD(cd, configuration);
duke@1 181 if (superclass != null) {
duke@1 182 if (!add(subs, superclass, cd)) {
duke@1 183 return;
duke@1 184 } else {
duke@1 185 processType(superclass, configuration, bases, subs);
duke@1 186 }
duke@1 187 } else { // cd is java.lang.Object, add it once to the list
duke@1 188 if (!bases.contains(cd)) {
duke@1 189 bases.add(cd);
duke@1 190 }
duke@1 191 }
mcimadamore@184 192 List<Type> intfacs = Util.getAllInterfaces(cd, configuration);
mcimadamore@184 193 for (Iterator<Type> iter = intfacs.iterator(); iter.hasNext();) {
mcimadamore@184 194 add(implementingclasses, iter.next().asClassDoc(), cd);
duke@1 195 }
duke@1 196 }
duke@1 197
duke@1 198 /**
duke@1 199 * For the interface passed get the interfaces which it extends, and then
duke@1 200 * put this interface in the sub-interface list of those interfaces. Do it
duke@1 201 * recursively. If a interface doesn't have super-interface just attach
duke@1 202 * that interface in the list of all the baseinterfaces.
duke@1 203 *
duke@1 204 * @param cd Interface under consideration.
duke@1 205 */
duke@1 206 private void processInterface(ClassDoc cd) {
duke@1 207 ClassDoc[] intfacs = cd.interfaces();
duke@1 208 if (intfacs.length > 0) {
duke@1 209 for (int i = 0; i < intfacs.length; i++) {
duke@1 210 if (!add(subinterfaces, intfacs[i], cd)) {
duke@1 211 return;
duke@1 212 } else {
duke@1 213 processInterface(intfacs[i]); // Recurse
duke@1 214 }
duke@1 215 }
duke@1 216 } else {
duke@1 217 // we need to add all the interfaces who do not have
duke@1 218 // super-interfaces to baseinterfaces list to traverse them
duke@1 219 if (!baseinterfaces.contains(cd)) {
duke@1 220 baseinterfaces.add(cd);
duke@1 221 }
duke@1 222 }
duke@1 223 }
duke@1 224
duke@1 225 /**
duke@1 226 * Adjust the Class Tree. Add the class interface in to it's super-class'
duke@1 227 * or super-interface's sub-interface list.
duke@1 228 *
duke@1 229 * @param map the entire map.
duke@1 230 * @param superclass java.lang.Object or the super-interface.
duke@1 231 * @param cd sub-interface to be mapped.
duke@1 232 * @returns boolean true if class added, false if class already processed.
duke@1 233 */
jjg@74 234 private boolean add(Map<ClassDoc,List<ClassDoc>> map, ClassDoc superclass, ClassDoc cd) {
jjg@74 235 List<ClassDoc> list = map.get(superclass);
duke@1 236 if (list == null) {
jjg@74 237 list = new ArrayList<ClassDoc>();
duke@1 238 map.put(superclass, list);
duke@1 239 }
duke@1 240 if (list.contains(cd)) {
duke@1 241 return false;
duke@1 242 } else {
duke@1 243 list.add(cd);
duke@1 244 }
duke@1 245 return true;
duke@1 246 }
duke@1 247
duke@1 248 /**
duke@1 249 * From the map return the list of sub-classes or sub-interfaces. If list
duke@1 250 * is null create a new one and return it.
duke@1 251 *
duke@1 252 * @param map The entire map.
duke@1 253 * @param cd class for which the sub-class list is requested.
duke@1 254 * @returns List Sub-Class list for the class passed.
duke@1 255 */
jjg@74 256 private List<ClassDoc> get(Map<ClassDoc,List<ClassDoc>> map, ClassDoc cd) {
jjg@74 257 List<ClassDoc> list = map.get(cd);
duke@1 258 if (list == null) {
jjg@74 259 return new ArrayList<ClassDoc>();
duke@1 260 }
duke@1 261 return list;
duke@1 262 }
duke@1 263
duke@1 264 /**
duke@1 265 * Return the sub-class list for the class passed.
duke@1 266 *
duke@1 267 * @param cd class whose sub-class list is required.
duke@1 268 */
jjg@74 269 public List<ClassDoc> subclasses(ClassDoc cd) {
duke@1 270 return get(subclasses, cd);
duke@1 271 }
duke@1 272
duke@1 273 /**
duke@1 274 * Return the sub-interface list for the interface passed.
duke@1 275 *
duke@1 276 * @param cd interface whose sub-interface list is required.
duke@1 277 */
jjg@74 278 public List<ClassDoc> subinterfaces(ClassDoc cd) {
duke@1 279 return get(subinterfaces, cd);
duke@1 280 }
duke@1 281
duke@1 282 /**
duke@1 283 * Return the list of classes which implement the interface passed.
duke@1 284 *
duke@1 285 * @param cd interface whose implementing-classes list is required.
duke@1 286 */
jjg@74 287 public List<ClassDoc> implementingclasses(ClassDoc cd) {
jjg@74 288 List<ClassDoc> result = get(implementingclasses, cd);
jjg@74 289 List<ClassDoc> subinterfaces = allSubs(cd, false);
duke@1 290
duke@1 291 //If class x implements a subinterface of cd, then it follows
duke@1 292 //that class x implements cd.
mcimadamore@184 293 Iterator<ClassDoc> implementingClassesIter, subInterfacesIter = subinterfaces.listIterator();
duke@1 294 ClassDoc c;
duke@1 295 while(subInterfacesIter.hasNext()){
mcimadamore@184 296 implementingClassesIter = implementingclasses(
duke@1 297 subInterfacesIter.next()).listIterator();
duke@1 298 while(implementingClassesIter.hasNext()){
mcimadamore@184 299 c = implementingClassesIter.next();
duke@1 300 if(! result.contains(c)){
duke@1 301 result.add(c);
duke@1 302 }
duke@1 303 }
duke@1 304 }
duke@1 305 Collections.sort(result);
duke@1 306 return result;
duke@1 307 }
duke@1 308
duke@1 309 /**
duke@1 310 * Return the sub-class/interface list for the class/interface passed.
duke@1 311 *
duke@1 312 * @param cd class/interface whose sub-class/interface list is required.
duke@1 313 * @param isEnum true if the subclasses should be forced to come from the
duke@1 314 * enum tree.
duke@1 315 */
jjg@74 316 public List<ClassDoc> subs(ClassDoc cd, boolean isEnum) {
duke@1 317 if (isEnum) {
duke@1 318 return get(subEnums, cd);
duke@1 319 } else if (cd.isAnnotationType()) {
duke@1 320 return get(subAnnotationTypes, cd);
duke@1 321 } else if (cd.isInterface()) {
duke@1 322 return get(subinterfaces, cd);
duke@1 323 } else if (cd.isClass()) {
duke@1 324 return get(subclasses, cd);
duke@1 325 } else {
duke@1 326 return null;
duke@1 327 }
duke@1 328
duke@1 329 }
duke@1 330
duke@1 331 /**
duke@1 332 * Return a list of all direct or indirect, sub-classes and subinterfaces
duke@1 333 * of the ClassDoc argument.
duke@1 334 *
duke@1 335 * @param cd ClassDoc whose sub-classes or sub-interfaces are requested.
duke@1 336 * @param isEnum true if the subclasses should be forced to come from the
duke@1 337 * enum tree.
duke@1 338 */
jjg@74 339 public List<ClassDoc> allSubs(ClassDoc cd, boolean isEnum) {
jjg@74 340 List<ClassDoc> list = subs(cd, isEnum);
duke@1 341 for (int i = 0; i < list.size(); i++) {
jjg@74 342 cd = list.get(i);
mcimadamore@184 343 List<ClassDoc> tlist = subs(cd, isEnum);
duke@1 344 for (int j = 0; j < tlist.size(); j++) {
mcimadamore@184 345 ClassDoc tcd = tlist.get(j);
duke@1 346 if (!list.contains(tcd)) {
duke@1 347 list.add(tcd);
duke@1 348 }
duke@1 349 }
duke@1 350 }
duke@1 351 Collections.sort(list);
duke@1 352 return list;
duke@1 353 }
duke@1 354
duke@1 355 /**
duke@1 356 * Return the base-classes list. This will have only one element namely
duke@1 357 * thw classdoc for java.lang.Object, since this is the base class for all
duke@1 358 * classes.
duke@1 359 */
mcimadamore@184 360 public List<ClassDoc> baseclasses() {
duke@1 361 return baseclasses;
duke@1 362 }
duke@1 363
duke@1 364 /**
duke@1 365 * Return the list of base interfaces. This is the list of interfaces
duke@1 366 * which do not have super-interface.
duke@1 367 */
mcimadamore@184 368 public List<ClassDoc> baseinterfaces() {
duke@1 369 return baseinterfaces;
duke@1 370 }
duke@1 371
duke@1 372 /**
duke@1 373 * Return the list of base enums. This is the list of enums
duke@1 374 * which do not have super-enums.
duke@1 375 */
mcimadamore@184 376 public List<ClassDoc> baseEnums() {
duke@1 377 return baseEnums;
duke@1 378 }
duke@1 379
duke@1 380 /**
duke@1 381 * Return the list of base annotation types. This is the list of
duke@1 382 * annotation types which do not have super-annotation types.
duke@1 383 */
mcimadamore@184 384 public List<ClassDoc> baseAnnotationTypes() {
duke@1 385 return baseAnnotationTypes;
duke@1 386 }
duke@1 387 }

mercurial