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

Thu, 15 Nov 2012 19:54:20 -0800

author
jjg
date
Thu, 15 Nov 2012 19:54:20 -0800
changeset 1412
400a4e8accd3
parent 1410
bfec2a1cc869
child 1521
71f35e4b93a5
permissions
-rw-r--r--

8002079: update DocFile to use a JavaFileManager
Reviewed-by: darcy

duke@1 1 /*
jjg@1359 2 * Copyright (c) 1999, 2012, 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@197 28 import java.io.*;
jjg@197 29 import java.util.*;
jjg@197 30
duke@1 31 import com.sun.javadoc.*;
duke@1 32 import com.sun.tools.doclets.internal.toolkit.*;
jjg@1383 33 import javax.tools.StandardLocation;
duke@1 34
duke@1 35 /**
duke@1 36 * Utilities Class for Doclets.
duke@1 37 *
jjg@1359 38 * <p><b>This is NOT part of any supported API.
jjg@1359 39 * If you write code that depends on this, you do so at your own risk.
jjg@1359 40 * This code and its internal interfaces are subject to change or
jjg@1359 41 * deletion without notice.</b>
duke@1 42 *
duke@1 43 * @author Atul M Dambalkar
duke@1 44 * @author Jamie Ho
duke@1 45 */
duke@1 46 public class Util {
duke@1 47
duke@1 48 /**
duke@1 49 * Return array of class members whose documentation is to be generated.
duke@1 50 * If the member is deprecated do not include such a member in the
duke@1 51 * returned array.
duke@1 52 *
duke@1 53 * @param members Array of members to choose from.
duke@1 54 * @return ProgramElementDoc[] Array of eligible members for whom
duke@1 55 * documentation is getting generated.
duke@1 56 */
duke@1 57 public static ProgramElementDoc[] excludeDeprecatedMembers(
duke@1 58 ProgramElementDoc[] members) {
duke@1 59 return
duke@1 60 toProgramElementDocArray(excludeDeprecatedMembersAsList(members));
duke@1 61 }
duke@1 62
duke@1 63 /**
duke@1 64 * Return array of class members whose documentation is to be generated.
duke@1 65 * If the member is deprecated do not include such a member in the
duke@1 66 * returned array.
duke@1 67 *
duke@1 68 * @param members Array of members to choose from.
duke@1 69 * @return List List of eligible members for whom
duke@1 70 * documentation is getting generated.
duke@1 71 */
jjg@74 72 public static List<ProgramElementDoc> excludeDeprecatedMembersAsList(
duke@1 73 ProgramElementDoc[] members) {
jjg@74 74 List<ProgramElementDoc> list = new ArrayList<ProgramElementDoc>();
duke@1 75 for (int i = 0; i < members.length; i++) {
duke@1 76 if (members[i].tags("deprecated").length == 0) {
duke@1 77 list.add(members[i]);
duke@1 78 }
duke@1 79 }
duke@1 80 Collections.sort(list);
duke@1 81 return list;
duke@1 82 }
duke@1 83
duke@1 84 /**
duke@1 85 * Return the list of ProgramElementDoc objects as Array.
duke@1 86 */
mcimadamore@184 87 public static ProgramElementDoc[] toProgramElementDocArray(List<ProgramElementDoc> list) {
duke@1 88 ProgramElementDoc[] pgmarr = new ProgramElementDoc[list.size()];
duke@1 89 for (int i = 0; i < list.size(); i++) {
mcimadamore@184 90 pgmarr[i] = list.get(i);
duke@1 91 }
duke@1 92 return pgmarr;
duke@1 93 }
duke@1 94
duke@1 95 /**
duke@1 96 * Return true if a non-public member found in the given array.
duke@1 97 *
duke@1 98 * @param members Array of members to look into.
duke@1 99 * @return boolean True if non-public member found, false otherwise.
duke@1 100 */
duke@1 101 public static boolean nonPublicMemberFound(ProgramElementDoc[] members) {
duke@1 102 for (int i = 0; i < members.length; i++) {
duke@1 103 if (!members[i].isPublic()) {
duke@1 104 return true;
duke@1 105 }
duke@1 106 }
duke@1 107 return false;
duke@1 108 }
duke@1 109
duke@1 110 /**
duke@1 111 * Search for the given method in the given class.
duke@1 112 *
duke@1 113 * @param cd Class to search into.
duke@1 114 * @param method Method to be searched.
duke@1 115 * @return MethodDoc Method found, null otherwise.
duke@1 116 */
duke@1 117 public static MethodDoc findMethod(ClassDoc cd, MethodDoc method) {
duke@1 118 MethodDoc[] methods = cd.methods();
duke@1 119 for (int i = 0; i < methods.length; i++) {
duke@1 120 if (executableMembersEqual(method, methods[i])) {
duke@1 121 return methods[i];
duke@1 122
duke@1 123 }
duke@1 124 }
duke@1 125 return null;
duke@1 126 }
duke@1 127
duke@1 128 /**
duke@1 129 * @param member1 the first method to compare.
duke@1 130 * @param member2 the second method to compare.
duke@1 131 * @return true if member1 overrides/hides or is overriden/hidden by member2.
duke@1 132 */
duke@1 133 public static boolean executableMembersEqual(ExecutableMemberDoc member1,
duke@1 134 ExecutableMemberDoc member2) {
duke@1 135 if (! (member1 instanceof MethodDoc && member2 instanceof MethodDoc))
duke@1 136 return false;
duke@1 137
duke@1 138 MethodDoc method1 = (MethodDoc) member1;
duke@1 139 MethodDoc method2 = (MethodDoc) member2;
duke@1 140 if (method1.isStatic() && method2.isStatic()) {
duke@1 141 Parameter[] targetParams = method1.parameters();
duke@1 142 Parameter[] currentParams;
duke@1 143 if (method1.name().equals(method2.name()) &&
duke@1 144 (currentParams = method2.parameters()).length ==
duke@1 145 targetParams.length) {
duke@1 146 int j;
duke@1 147 for (j = 0; j < targetParams.length; j++) {
duke@1 148 if (! (targetParams[j].typeName().equals(
duke@1 149 currentParams[j].typeName()) ||
duke@1 150 currentParams[j].type() instanceof TypeVariable ||
duke@1 151 targetParams[j].type() instanceof TypeVariable)) {
duke@1 152 break;
duke@1 153 }
duke@1 154 }
duke@1 155 if (j == targetParams.length) {
duke@1 156 return true;
duke@1 157 }
duke@1 158 }
duke@1 159 return false;
duke@1 160 } else {
duke@1 161 return method1.overrides(method2) ||
duke@1 162 method2.overrides(method1) ||
duke@1 163 member1 == member2;
duke@1 164 }
duke@1 165 }
duke@1 166
duke@1 167 /**
jjh@972 168 * According to
jjh@972 169 * <cite>The Java&trade; Language Specification</cite>,
jjh@972 170 * all the outer classes and static inner classes are core classes.
duke@1 171 */
duke@1 172 public static boolean isCoreClass(ClassDoc cd) {
duke@1 173 return cd.containingClass() == null || cd.isStatic();
duke@1 174 }
duke@1 175
duke@1 176 public static boolean matches(ProgramElementDoc doc1,
duke@1 177 ProgramElementDoc doc2) {
duke@1 178 if (doc1 instanceof ExecutableMemberDoc &&
duke@1 179 doc2 instanceof ExecutableMemberDoc) {
duke@1 180 ExecutableMemberDoc ed1 = (ExecutableMemberDoc)doc1;
duke@1 181 ExecutableMemberDoc ed2 = (ExecutableMemberDoc)doc2;
duke@1 182 return executableMembersEqual(ed1, ed2);
duke@1 183 } else {
duke@1 184 return doc1.name().equals(doc2.name());
duke@1 185 }
duke@1 186 }
duke@1 187
duke@1 188 /**
duke@1 189 * Copy the given directory contents from the source package directory
duke@1 190 * to the generated documentation directory. For example for a package
duke@1 191 * java.lang this method find out the source location of the package using
duke@1 192 * {@link SourcePath} and if given directory is found in the source
duke@1 193 * directory structure, copy the entire directory, to the generated
duke@1 194 * documentation hierarchy.
duke@1 195 *
duke@1 196 * @param configuration The configuration of the current doclet.
duke@1 197 * @param path The relative path to the directory to be copied.
duke@1 198 * @param dir The original directory name to copy from.
duke@1 199 * @param overwrite Overwrite files if true.
duke@1 200 */
jjg@1383 201 public static void copyDocFiles(Configuration configuration, PackageDoc pd) {
jjg@1383 202 copyDocFiles(configuration, DocPath.forPackage(pd).resolve(DocPaths.DOC_FILES));
jjg@1383 203 }
jjg@1383 204
jjg@1383 205 public static void copyDocFiles(Configuration configuration, DocPath dir) {
duke@1 206 try {
jjg@1383 207 boolean first = true;
jjg@1383 208 for (DocFile f : DocFile.list(configuration, StandardLocation.SOURCE_PATH, dir)) {
jjg@1383 209 if (!f.isDirectory()) {
jjg@1383 210 continue;
jjg@1383 211 }
jjg@1383 212 DocFile srcdir = f;
jjg@1383 213 DocFile destdir = DocFile.createFileForOutput(configuration, dir);
jjg@1383 214 if (srcdir.isSameFile(destdir)) {
jjg@1383 215 continue;
jjg@1383 216 }
jjg@1383 217
jjg@1383 218 for (DocFile srcfile: srcdir.list()) {
jjg@1383 219 DocFile destfile = destdir.resolve(srcfile.getName());
jjg@1383 220 if (srcfile.isFile()) {
jjg@1383 221 if (destfile.exists() && !first) {
jjg@1383 222 configuration.message.warning((SourcePosition) null,
jjg@1383 223 "doclet.Copy_Overwrite_warning",
jjg@1383 224 srcfile.getPath(), destdir.getPath());
jjg@1383 225 } else {
jjg@1383 226 configuration.message.notice(
jjg@1383 227 "doclet.Copying_File_0_To_Dir_1",
jjg@1383 228 srcfile.getPath(), destdir.getPath());
jjg@1383 229 destfile.copyFile(srcfile);
jjg@1383 230 }
jjg@1383 231 } else if (srcfile.isDirectory()) {
jjg@1383 232 if (configuration.copydocfilesubdirs
jjg@1383 233 && !configuration.shouldExcludeDocFileDir(srcfile.getName())) {
jjg@1383 234 copyDocFiles(configuration, dir.resolve(srcfile.getName()));
jjg@1383 235 }
duke@1 236 }
duke@1 237 }
jjg@1383 238
jjg@1383 239 first = false;
duke@1 240 }
duke@1 241 } catch (SecurityException exc) {
duke@1 242 throw new DocletAbortException();
duke@1 243 } catch (IOException exc) {
duke@1 244 throw new DocletAbortException();
duke@1 245 }
duke@1 246 }
duke@1 247
duke@1 248 /**
duke@1 249 * We want the list of types in alphabetical order. However, types are not
duke@1 250 * comparable. We need a comparator for now.
duke@1 251 */
jjg@74 252 private static class TypeComparator implements Comparator<Type> {
jjg@74 253 public int compare(Type type1, Type type2) {
jjg@74 254 return type1.qualifiedTypeName().toLowerCase().compareTo(
jjg@74 255 type2.qualifiedTypeName().toLowerCase());
duke@1 256 }
duke@1 257 }
duke@1 258
duke@1 259 /**
duke@1 260 * For the class return all implemented interfaces including the
duke@1 261 * superinterfaces of the implementing interfaces, also iterate over for
duke@1 262 * all the superclasses. For interface return all the extended interfaces
duke@1 263 * as well as superinterfaces for those extended interfaces.
duke@1 264 *
duke@1 265 * @param type type whose implemented or
duke@1 266 * super interfaces are sought.
duke@1 267 * @param configuration the current configuration of the doclet.
duke@1 268 * @param sort if true, return list of interfaces sorted alphabetically.
duke@1 269 * @return List of all the required interfaces.
duke@1 270 */
jjg@74 271 public static List<Type> getAllInterfaces(Type type,
duke@1 272 Configuration configuration, boolean sort) {
jjg@74 273 Map<ClassDoc,Type> results = sort ? new TreeMap<ClassDoc,Type>() : new LinkedHashMap<ClassDoc,Type>();
duke@1 274 Type[] interfaceTypes = null;
duke@1 275 Type superType = null;
duke@1 276 if (type instanceof ParameterizedType) {
duke@1 277 interfaceTypes = ((ParameterizedType) type).interfaceTypes();
duke@1 278 superType = ((ParameterizedType) type).superclassType();
duke@1 279 } else if (type instanceof ClassDoc) {
duke@1 280 interfaceTypes = ((ClassDoc) type).interfaceTypes();
duke@1 281 superType = ((ClassDoc) type).superclassType();
duke@1 282 } else {
duke@1 283 interfaceTypes = type.asClassDoc().interfaceTypes();
duke@1 284 superType = type.asClassDoc().superclassType();
duke@1 285 }
duke@1 286
duke@1 287 for (int i = 0; i < interfaceTypes.length; i++) {
duke@1 288 Type interfaceType = interfaceTypes[i];
duke@1 289 ClassDoc interfaceClassDoc = interfaceType.asClassDoc();
duke@1 290 if (! (interfaceClassDoc.isPublic() ||
duke@1 291 (configuration == null ||
duke@1 292 isLinkable(interfaceClassDoc, configuration)))) {
duke@1 293 continue;
duke@1 294 }
duke@1 295 results.put(interfaceClassDoc, interfaceType);
mcimadamore@184 296 List<Type> superInterfaces = getAllInterfaces(interfaceType, configuration, sort);
mcimadamore@184 297 for (Iterator<Type> iter = superInterfaces.iterator(); iter.hasNext(); ) {
mcimadamore@184 298 Type t = iter.next();
duke@1 299 results.put(t.asClassDoc(), t);
duke@1 300 }
duke@1 301 }
duke@1 302 if (superType == null)
jjg@74 303 return new ArrayList<Type>(results.values());
duke@1 304 //Try walking the tree.
duke@1 305 addAllInterfaceTypes(results,
duke@1 306 superType,
duke@1 307 superType instanceof ClassDoc ?
duke@1 308 ((ClassDoc) superType).interfaceTypes() :
duke@1 309 ((ParameterizedType) superType).interfaceTypes(),
duke@1 310 false, configuration);
jjg@74 311 List<Type> resultsList = new ArrayList<Type>(results.values());
duke@1 312 if (sort) {
duke@1 313 Collections.sort(resultsList, new TypeComparator());
duke@1 314 }
duke@1 315 return resultsList;
duke@1 316 }
duke@1 317
mcimadamore@184 318 public static List<Type> getAllInterfaces(Type type, Configuration configuration) {
duke@1 319 return getAllInterfaces(type, configuration, true);
duke@1 320 }
duke@1 321
jjg@74 322 private static void findAllInterfaceTypes(Map<ClassDoc,Type> results, ClassDoc c, boolean raw,
duke@1 323 Configuration configuration) {
duke@1 324 Type superType = c.superclassType();
duke@1 325 if (superType == null)
duke@1 326 return;
duke@1 327 addAllInterfaceTypes(results, superType,
duke@1 328 superType instanceof ClassDoc ?
duke@1 329 ((ClassDoc) superType).interfaceTypes() :
duke@1 330 ((ParameterizedType) superType).interfaceTypes(),
duke@1 331 raw, configuration);
duke@1 332 }
duke@1 333
jjg@74 334 private static void findAllInterfaceTypes(Map<ClassDoc,Type> results, ParameterizedType p,
duke@1 335 Configuration configuration) {
duke@1 336 Type superType = p.superclassType();
duke@1 337 if (superType == null)
duke@1 338 return;
duke@1 339 addAllInterfaceTypes(results, superType,
duke@1 340 superType instanceof ClassDoc ?
duke@1 341 ((ClassDoc) superType).interfaceTypes() :
duke@1 342 ((ParameterizedType) superType).interfaceTypes(),
duke@1 343 false, configuration);
duke@1 344 }
duke@1 345
jjg@74 346 private static void addAllInterfaceTypes(Map<ClassDoc,Type> results, Type type,
duke@1 347 Type[] interfaceTypes, boolean raw,
duke@1 348 Configuration configuration) {
duke@1 349 for (int i = 0; i < interfaceTypes.length; i++) {
duke@1 350 Type interfaceType = interfaceTypes[i];
duke@1 351 ClassDoc interfaceClassDoc = interfaceType.asClassDoc();
duke@1 352 if (! (interfaceClassDoc.isPublic() ||
duke@1 353 (configuration != null &&
duke@1 354 isLinkable(interfaceClassDoc, configuration)))) {
duke@1 355 continue;
duke@1 356 }
duke@1 357 if (raw)
duke@1 358 interfaceType = interfaceType.asClassDoc();
duke@1 359 results.put(interfaceClassDoc, interfaceType);
mcimadamore@184 360 List<Type> superInterfaces = getAllInterfaces(interfaceType, configuration);
mcimadamore@184 361 for (Iterator<Type> iter = superInterfaces.iterator(); iter.hasNext(); ) {
mcimadamore@184 362 Type superInterface = iter.next();
duke@1 363 results.put(superInterface.asClassDoc(), superInterface);
duke@1 364 }
duke@1 365 }
duke@1 366 if (type instanceof ParameterizedType)
duke@1 367 findAllInterfaceTypes(results, (ParameterizedType) type, configuration);
duke@1 368 else if (((ClassDoc) type).typeParameters().length == 0)
duke@1 369 findAllInterfaceTypes(results, (ClassDoc) type, raw, configuration);
duke@1 370 else
duke@1 371 findAllInterfaceTypes(results, (ClassDoc) type, true, configuration);
duke@1 372 }
duke@1 373
duke@1 374 /**
duke@1 375 * Enclose in quotes, used for paths and filenames that contains spaces
duke@1 376 */
duke@1 377 public static String quote(String filepath) {
duke@1 378 return ("\"" + filepath + "\"");
duke@1 379 }
duke@1 380
duke@1 381 /**
jjg@1372 382 * Given a package, return its name.
duke@1 383 * @param packageDoc the package to check.
duke@1 384 * @return the name of the given package.
duke@1 385 */
duke@1 386 public static String getPackageName(PackageDoc packageDoc) {
duke@1 387 return packageDoc == null || packageDoc.name().length() == 0 ?
duke@1 388 DocletConstants.DEFAULT_PACKAGE_NAME : packageDoc.name();
duke@1 389 }
duke@1 390
duke@1 391 /**
jjg@1372 392 * Given a package, return its file name without the extension.
duke@1 393 * @param packageDoc the package to check.
duke@1 394 * @return the file name of the given package.
duke@1 395 */
duke@1 396 public static String getPackageFileHeadName(PackageDoc packageDoc) {
duke@1 397 return packageDoc == null || packageDoc.name().length() == 0 ?
duke@1 398 DocletConstants.DEFAULT_PACKAGE_FILE_NAME : packageDoc.name();
duke@1 399 }
duke@1 400
duke@1 401 /**
jjg@1372 402 * Given a string, replace all occurrences of 'newStr' with 'oldStr'.
duke@1 403 * @param originalStr the string to modify.
duke@1 404 * @param oldStr the string to replace.
duke@1 405 * @param newStr the string to insert in place of the old string.
duke@1 406 */
duke@1 407 public static String replaceText(String originalStr, String oldStr,
duke@1 408 String newStr) {
duke@1 409 if (oldStr == null || newStr == null || oldStr.equals(newStr)) {
duke@1 410 return originalStr;
duke@1 411 }
jjg@910 412 return originalStr.replace(oldStr, newStr);
duke@1 413 }
duke@1 414
duke@1 415 /**
duke@1 416 * Given a string, escape all special html characters and
duke@1 417 * return the result.
duke@1 418 *
duke@1 419 * @param s The string to check.
jjg@1410 420 * @return the original string with all of the HTML characters escaped.
duke@1 421 */
duke@1 422 public static String escapeHtmlChars(String s) {
jjg@1410 423 for (int i = 0; i < s.length(); i++) {
jjg@1410 424 char ch = s.charAt(i);
jjg@1410 425 switch (ch) {
jjg@1410 426 // only start building a new string if we need to
jjg@1410 427 case '<': case '>': case '&':
jjg@1410 428 StringBuilder sb = new StringBuilder(s.substring(0, i));
jjg@1410 429 for ( ; i < s.length(); i++) {
jjg@1410 430 ch = s.charAt(i);
jjg@1410 431 switch (ch) {
jjg@1410 432 case '<': sb.append("&lt;"); break;
jjg@1410 433 case '>': sb.append("&gt;"); break;
jjg@1410 434 case '&': sb.append("&amp;"); break;
jjg@1410 435 default: sb.append(ch); break;
jjg@1410 436 }
jjg@1410 437 }
jjg@1410 438 return sb.toString();
jjg@1410 439 }
duke@1 440 }
jjg@1410 441 return s;
jjg@1410 442 }
jjg@1410 443
jjg@1410 444 /**
jjg@1410 445 * Escape all special html characters in a string buffer.
jjg@1410 446 *
jjg@1410 447 * @param sb The string buffer to update
jjg@1410 448 */
jjg@1410 449 public static void escapeHtmlChars(StringBuilder sb) {
jjg@1410 450 // scan backwards, replacing characters as needed.
jjg@1410 451 for (int i = sb.length() - 1; i >= 0; i--) {
jjg@1410 452 switch (sb.charAt(i)) {
jjg@1410 453 case '<': sb.replace(i, i+1, "&lt;"); break;
jjg@1410 454 case '>': sb.replace(i, i+1, "&gt;"); break;
jjg@1410 455 case '&': sb.replace(i, i+1, "&amp;"); break;
jjg@1410 456 }
jjg@1410 457 }
duke@1 458 }
duke@1 459
duke@1 460 /**
bpatel@766 461 * Given a string, strips all html characters and
bpatel@766 462 * return the result.
bpatel@766 463 *
bpatel@766 464 * @param rawString The string to check.
bpatel@766 465 * @return the original string with all of the HTML characters
bpatel@766 466 * stripped.
bpatel@766 467 *
bpatel@766 468 */
bpatel@766 469 public static String stripHtml(String rawString) {
bpatel@766 470 // remove HTML tags
bpatel@766 471 rawString = rawString.replaceAll("\\<.*?>", " ");
bpatel@766 472 // consolidate multiple spaces between a word to a single space
bpatel@766 473 rawString = rawString.replaceAll("\\b\\s{2,}\\b", " ");
bpatel@766 474 // remove extra whitespaces
bpatel@766 475 return rawString.trim();
bpatel@766 476 }
bpatel@766 477
bpatel@766 478 /**
duke@1 479 * Given an annotation, return true if it should be documented and false
duke@1 480 * otherwise.
duke@1 481 *
duke@1 482 * @param annotationDoc the annotation to check.
duke@1 483 *
duke@1 484 * @return true return true if it should be documented and false otherwise.
duke@1 485 */
duke@1 486 public static boolean isDocumentedAnnotation(AnnotationTypeDoc annotationDoc) {
duke@1 487 AnnotationDesc[] annotationDescList = annotationDoc.annotations();
duke@1 488 for (int i = 0; i < annotationDescList.length; i++) {
duke@1 489 if (annotationDescList[i].annotationType().qualifiedName().equals(
duke@1 490 java.lang.annotation.Documented.class.getName())){
duke@1 491 return true;
duke@1 492 }
duke@1 493 }
duke@1 494 return false;
duke@1 495 }
duke@1 496
duke@1 497 /**
duke@1 498 * Return true if this class is linkable and false if we can't link to the
duke@1 499 * desired class.
duke@1 500 * <br>
duke@1 501 * <b>NOTE:</b> You can only link to external classes if they are public or
duke@1 502 * protected.
duke@1 503 *
duke@1 504 * @param classDoc the class to check.
duke@1 505 * @param configuration the current configuration of the doclet.
duke@1 506 *
duke@1 507 * @return true if this class is linkable and false if we can't link to the
duke@1 508 * desired class.
duke@1 509 */
duke@1 510 public static boolean isLinkable(ClassDoc classDoc,
duke@1 511 Configuration configuration) {
duke@1 512 return
duke@1 513 ((classDoc.isIncluded() && configuration.isGeneratedDoc(classDoc))) ||
duke@1 514 (configuration.extern.isExternal(classDoc) &&
duke@1 515 (classDoc.isPublic() || classDoc.isProtected()));
duke@1 516 }
duke@1 517
duke@1 518 /**
duke@1 519 * Given a class, return the closest visible super class.
duke@1 520 *
duke@1 521 * @param classDoc the class we are searching the parent for.
duke@1 522 * @param configuration the current configuration of the doclet.
duke@1 523 * @return the closest visible super class. Return null if it cannot
duke@1 524 * be found (i.e. classDoc is java.lang.Object).
duke@1 525 */
duke@1 526 public static Type getFirstVisibleSuperClass(ClassDoc classDoc,
duke@1 527 Configuration configuration) {
duke@1 528 if (classDoc == null) {
duke@1 529 return null;
duke@1 530 }
duke@1 531 Type sup = classDoc.superclassType();
duke@1 532 ClassDoc supClassDoc = classDoc.superclass();
duke@1 533 while (sup != null &&
duke@1 534 (! (supClassDoc.isPublic() ||
duke@1 535 isLinkable(supClassDoc, configuration))) ) {
duke@1 536 if (supClassDoc.superclass().qualifiedName().equals(supClassDoc.qualifiedName()))
duke@1 537 break;
duke@1 538 sup = supClassDoc.superclassType();
duke@1 539 supClassDoc = supClassDoc.superclass();
duke@1 540 }
duke@1 541 if (classDoc.equals(supClassDoc)) {
duke@1 542 return null;
duke@1 543 }
duke@1 544 return sup;
duke@1 545 }
duke@1 546
duke@1 547 /**
duke@1 548 * Given a class, return the closest visible super class.
duke@1 549 *
duke@1 550 * @param classDoc the class we are searching the parent for.
duke@1 551 * @param configuration the current configuration of the doclet.
duke@1 552 * @return the closest visible super class. Return null if it cannot
duke@1 553 * be found (i.e. classDoc is java.lang.Object).
duke@1 554 */
duke@1 555 public static ClassDoc getFirstVisibleSuperClassCD(ClassDoc classDoc,
duke@1 556 Configuration configuration) {
duke@1 557 if (classDoc == null) {
duke@1 558 return null;
duke@1 559 }
duke@1 560 ClassDoc supClassDoc = classDoc.superclass();
duke@1 561 while (supClassDoc != null &&
duke@1 562 (! (supClassDoc.isPublic() ||
duke@1 563 isLinkable(supClassDoc, configuration))) ) {
duke@1 564 supClassDoc = supClassDoc.superclass();
duke@1 565 }
duke@1 566 if (classDoc.equals(supClassDoc)) {
duke@1 567 return null;
duke@1 568 }
duke@1 569 return supClassDoc;
duke@1 570 }
duke@1 571
duke@1 572 /**
duke@1 573 * Given a ClassDoc, return the name of its type (Class, Interface, etc.).
duke@1 574 *
duke@1 575 * @param cd the ClassDoc to check.
duke@1 576 * @param lowerCaseOnly true if you want the name returned in lower case.
jjg@1397 577 * If false, the first letter of the name is capitalized.
duke@1 578 * @return
duke@1 579 */
duke@1 580 public static String getTypeName(Configuration config,
duke@1 581 ClassDoc cd, boolean lowerCaseOnly) {
duke@1 582 String typeName = "";
duke@1 583 if (cd.isOrdinaryClass()) {
duke@1 584 typeName = "doclet.Class";
duke@1 585 } else if (cd.isInterface()) {
duke@1 586 typeName = "doclet.Interface";
duke@1 587 } else if (cd.isException()) {
duke@1 588 typeName = "doclet.Exception";
duke@1 589 } else if (cd.isError()) {
duke@1 590 typeName = "doclet.Error";
duke@1 591 } else if (cd.isAnnotationType()) {
duke@1 592 typeName = "doclet.AnnotationType";
duke@1 593 } else if (cd.isEnum()) {
duke@1 594 typeName = "doclet.Enum";
duke@1 595 }
duke@1 596 return config.getText(
duke@1 597 lowerCaseOnly ? typeName.toLowerCase() : typeName);
duke@1 598 }
duke@1 599
duke@1 600 /**
jjg@1410 601 * Replace all tabs with the appropriate number of spaces.
jjg@1410 602 * @param configuration the doclet configuration defining the setting for the
jjg@1410 603 * tab length.
jjg@1410 604 * @param sb the StringBuilder in which to replace the tabs
duke@1 605 */
jjg@1410 606 public static void replaceTabs(Configuration configuration, StringBuilder sb) {
jjg@1410 607 int tabLength = configuration.sourcetab;
jjg@1410 608 String whitespace = configuration.tabSpaces;
jjg@910 609 int index = 0;
jjg@1410 610 while ((index = sb.indexOf("\t", index)) != -1) {
jjg@910 611 int spaceCount = tabLength - index % tabLength;
jjg@1410 612 sb.replace(index, index+1, whitespace.substring(0, spaceCount));
jjg@910 613 index += spaceCount;
duke@1 614 }
duke@1 615 }
duke@1 616
duke@1 617 /**
duke@1 618 * The documentation for values() and valueOf() in Enums are set by the
duke@1 619 * doclet.
duke@1 620 */
duke@1 621 public static void setEnumDocumentation(Configuration configuration,
duke@1 622 ClassDoc classDoc) {
duke@1 623 MethodDoc[] methods = classDoc.methods();
duke@1 624 for (int j = 0; j < methods.length; j++) {
duke@1 625 MethodDoc currentMethod = methods[j];
duke@1 626 if (currentMethod.name().equals("values") &&
duke@1 627 currentMethod.parameters().length == 0) {
duke@1 628 currentMethod.setRawCommentText(
duke@1 629 configuration.getText("doclet.enum_values_doc", classDoc.name()));
duke@1 630 } else if (currentMethod.name().equals("valueOf") &&
duke@1 631 currentMethod.parameters().length == 1) {
duke@1 632 Type paramType = currentMethod.parameters()[0].type();
duke@1 633 if (paramType != null &&
duke@1 634 paramType.qualifiedTypeName().equals(String.class.getName())) {
duke@1 635 currentMethod.setRawCommentText(
duke@1 636 configuration.getText("doclet.enum_valueof_doc"));
duke@1 637 }
duke@1 638 }
duke@1 639 }
duke@1 640 }
duke@1 641
duke@1 642 /**
duke@1 643 * Return true if the given Doc is deprecated.
duke@1 644 *
duke@1 645 * @param doc the Doc to check.
duke@1 646 * @return true if the given Doc is deprecated.
duke@1 647 */
bpatel@995 648 public static boolean isDeprecated(Doc doc) {
duke@1 649 if (doc.tags("deprecated").length > 0) {
duke@1 650 return true;
duke@1 651 }
bpatel@995 652 AnnotationDesc[] annotationDescList;
bpatel@995 653 if (doc instanceof PackageDoc)
bpatel@995 654 annotationDescList = ((PackageDoc)doc).annotations();
bpatel@995 655 else
bpatel@995 656 annotationDescList = ((ProgramElementDoc)doc).annotations();
duke@1 657 for (int i = 0; i < annotationDescList.length; i++) {
duke@1 658 if (annotationDescList[i].annotationType().qualifiedName().equals(
duke@1 659 java.lang.Deprecated.class.getName())){
duke@1 660 return true;
duke@1 661 }
duke@1 662 }
duke@1 663 return false;
duke@1 664 }
duke@1 665 }

mercurial