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

Wed, 27 Apr 2016 01:34:52 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:34:52 +0800
changeset 0
959103a6100f
child 2525
2eb010b6cb22
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/
changeset: 2573:53ca196be1ae
tag: jdk8u25-b17

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

mercurial