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

changeset 0
959103a6100f
child 2525
2eb010b6cb22
equal deleted inserted replaced
-1:000000000000 0:959103a6100f
1 /*
2 * Copyright (c) 1999, 2013, 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 */
25
26 package com.sun.tools.doclets.internal.toolkit.util;
27
28 import java.io.*;
29 import java.lang.annotation.ElementType;
30 import java.util.*;
31 import javax.tools.StandardLocation;
32
33 import com.sun.javadoc.*;
34 import com.sun.javadoc.AnnotationDesc.ElementValuePair;
35 import com.sun.tools.doclets.internal.toolkit.*;
36 import com.sun.tools.javac.util.StringUtils;
37
38 /**
39 * Utilities Class for Doclets.
40 *
41 * <p><b>This is NOT part of any supported API.
42 * If you write code that depends on this, you do so at your own risk.
43 * This code and its internal interfaces are subject to change or
44 * deletion without notice.</b>
45 *
46 * @author Atul M Dambalkar
47 * @author Jamie Ho
48 */
49 public class Util {
50
51 /**
52 * Return array of class members whose documentation is to be generated.
53 * If the member is deprecated do not include such a member in the
54 * returned array.
55 *
56 * @param members Array of members to choose from.
57 * @return ProgramElementDoc[] Array of eligible members for whom
58 * documentation is getting generated.
59 */
60 public static ProgramElementDoc[] excludeDeprecatedMembers(
61 ProgramElementDoc[] members) {
62 return
63 toProgramElementDocArray(excludeDeprecatedMembersAsList(members));
64 }
65
66 /**
67 * Return array of class members whose documentation is to be generated.
68 * If the member is deprecated do not include such a member in the
69 * returned array.
70 *
71 * @param members Array of members to choose from.
72 * @return List List of eligible members for whom
73 * documentation is getting generated.
74 */
75 public static List<ProgramElementDoc> excludeDeprecatedMembersAsList(
76 ProgramElementDoc[] members) {
77 List<ProgramElementDoc> list = new ArrayList<ProgramElementDoc>();
78 for (int i = 0; i < members.length; i++) {
79 if (members[i].tags("deprecated").length == 0) {
80 list.add(members[i]);
81 }
82 }
83 Collections.sort(list);
84 return list;
85 }
86
87 /**
88 * Return the list of ProgramElementDoc objects as Array.
89 */
90 public static ProgramElementDoc[] toProgramElementDocArray(List<ProgramElementDoc> list) {
91 ProgramElementDoc[] pgmarr = new ProgramElementDoc[list.size()];
92 for (int i = 0; i < list.size(); i++) {
93 pgmarr[i] = list.get(i);
94 }
95 return pgmarr;
96 }
97
98 /**
99 * Return true if a non-public member found in the given array.
100 *
101 * @param members Array of members to look into.
102 * @return boolean True if non-public member found, false otherwise.
103 */
104 public static boolean nonPublicMemberFound(ProgramElementDoc[] members) {
105 for (int i = 0; i < members.length; i++) {
106 if (!members[i].isPublic()) {
107 return true;
108 }
109 }
110 return false;
111 }
112
113 /**
114 * Search for the given method in the given class.
115 *
116 * @param cd Class to search into.
117 * @param method Method to be searched.
118 * @return MethodDoc Method found, null otherwise.
119 */
120 public static MethodDoc findMethod(ClassDoc cd, MethodDoc method) {
121 MethodDoc[] methods = cd.methods();
122 for (int i = 0; i < methods.length; i++) {
123 if (executableMembersEqual(method, methods[i])) {
124 return methods[i];
125
126 }
127 }
128 return null;
129 }
130
131 /**
132 * @param member1 the first method to compare.
133 * @param member2 the second method to compare.
134 * @return true if member1 overrides/hides or is overriden/hidden by member2.
135 */
136 public static boolean executableMembersEqual(ExecutableMemberDoc member1,
137 ExecutableMemberDoc member2) {
138 if (! (member1 instanceof MethodDoc && member2 instanceof MethodDoc))
139 return false;
140
141 MethodDoc method1 = (MethodDoc) member1;
142 MethodDoc method2 = (MethodDoc) member2;
143 if (method1.isStatic() && method2.isStatic()) {
144 Parameter[] targetParams = method1.parameters();
145 Parameter[] currentParams;
146 if (method1.name().equals(method2.name()) &&
147 (currentParams = method2.parameters()).length ==
148 targetParams.length) {
149 int j;
150 for (j = 0; j < targetParams.length; j++) {
151 if (! (targetParams[j].typeName().equals(
152 currentParams[j].typeName()) ||
153 currentParams[j].type() instanceof TypeVariable ||
154 targetParams[j].type() instanceof TypeVariable)) {
155 break;
156 }
157 }
158 if (j == targetParams.length) {
159 return true;
160 }
161 }
162 return false;
163 } else {
164 return method1.overrides(method2) ||
165 method2.overrides(method1) ||
166 member1 == member2;
167 }
168 }
169
170 /**
171 * According to
172 * <cite>The Java&trade; Language Specification</cite>,
173 * all the outer classes and static inner classes are core classes.
174 */
175 public static boolean isCoreClass(ClassDoc cd) {
176 return cd.containingClass() == null || cd.isStatic();
177 }
178
179 public static boolean matches(ProgramElementDoc doc1,
180 ProgramElementDoc doc2) {
181 if (doc1 instanceof ExecutableMemberDoc &&
182 doc2 instanceof ExecutableMemberDoc) {
183 ExecutableMemberDoc ed1 = (ExecutableMemberDoc)doc1;
184 ExecutableMemberDoc ed2 = (ExecutableMemberDoc)doc2;
185 return executableMembersEqual(ed1, ed2);
186 } else {
187 return doc1.name().equals(doc2.name());
188 }
189 }
190
191 /**
192 * Copy the given directory contents from the source package directory
193 * to the generated documentation directory. For example for a package
194 * java.lang this method find out the source location of the package using
195 * {@link SourcePath} and if given directory is found in the source
196 * directory structure, copy the entire directory, to the generated
197 * documentation hierarchy.
198 *
199 * @param configuration The configuration of the current doclet.
200 * @param path The relative path to the directory to be copied.
201 * @param dir The original directory name to copy from.
202 * @param overwrite Overwrite files if true.
203 */
204 public static void copyDocFiles(Configuration configuration, PackageDoc pd) {
205 copyDocFiles(configuration, DocPath.forPackage(pd).resolve(DocPaths.DOC_FILES));
206 }
207
208 public static void copyDocFiles(Configuration configuration, DocPath dir) {
209 try {
210 boolean first = true;
211 for (DocFile f : DocFile.list(configuration, StandardLocation.SOURCE_PATH, dir)) {
212 if (!f.isDirectory()) {
213 continue;
214 }
215 DocFile srcdir = f;
216 DocFile destdir = DocFile.createFileForOutput(configuration, dir);
217 if (srcdir.isSameFile(destdir)) {
218 continue;
219 }
220
221 for (DocFile srcfile: srcdir.list()) {
222 DocFile destfile = destdir.resolve(srcfile.getName());
223 if (srcfile.isFile()) {
224 if (destfile.exists() && !first) {
225 configuration.message.warning((SourcePosition) null,
226 "doclet.Copy_Overwrite_warning",
227 srcfile.getPath(), destdir.getPath());
228 } else {
229 configuration.message.notice(
230 "doclet.Copying_File_0_To_Dir_1",
231 srcfile.getPath(), destdir.getPath());
232 destfile.copyFile(srcfile);
233 }
234 } else if (srcfile.isDirectory()) {
235 if (configuration.copydocfilesubdirs
236 && !configuration.shouldExcludeDocFileDir(srcfile.getName())) {
237 copyDocFiles(configuration, dir.resolve(srcfile.getName()));
238 }
239 }
240 }
241
242 first = false;
243 }
244 } catch (SecurityException exc) {
245 throw new DocletAbortException(exc);
246 } catch (IOException exc) {
247 throw new DocletAbortException(exc);
248 }
249 }
250
251 /**
252 * We want the list of types in alphabetical order. However, types are not
253 * comparable. We need a comparator for now.
254 */
255 private static class TypeComparator implements Comparator<Type> {
256 public int compare(Type type1, Type type2) {
257 return type1.qualifiedTypeName().compareToIgnoreCase(
258 type2.qualifiedTypeName());
259 }
260 }
261
262 /**
263 * For the class return all implemented interfaces including the
264 * superinterfaces of the implementing interfaces, also iterate over for
265 * all the superclasses. For interface return all the extended interfaces
266 * as well as superinterfaces for those extended interfaces.
267 *
268 * @param type type whose implemented or
269 * super interfaces are sought.
270 * @param configuration the current configuration of the doclet.
271 * @param sort if true, return list of interfaces sorted alphabetically.
272 * @return List of all the required interfaces.
273 */
274 public static List<Type> getAllInterfaces(Type type,
275 Configuration configuration, boolean sort) {
276 Map<ClassDoc,Type> results = sort ? new TreeMap<ClassDoc,Type>() : new LinkedHashMap<ClassDoc,Type>();
277 Type[] interfaceTypes = null;
278 Type superType = null;
279 if (type instanceof ParameterizedType) {
280 interfaceTypes = ((ParameterizedType) type).interfaceTypes();
281 superType = ((ParameterizedType) type).superclassType();
282 } else if (type instanceof ClassDoc) {
283 interfaceTypes = ((ClassDoc) type).interfaceTypes();
284 superType = ((ClassDoc) type).superclassType();
285 } else {
286 interfaceTypes = type.asClassDoc().interfaceTypes();
287 superType = type.asClassDoc().superclassType();
288 }
289
290 for (int i = 0; i < interfaceTypes.length; i++) {
291 Type interfaceType = interfaceTypes[i];
292 ClassDoc interfaceClassDoc = interfaceType.asClassDoc();
293 if (! (interfaceClassDoc.isPublic() ||
294 (configuration == null ||
295 isLinkable(interfaceClassDoc, configuration)))) {
296 continue;
297 }
298 results.put(interfaceClassDoc, interfaceType);
299 List<Type> superInterfaces = getAllInterfaces(interfaceType, configuration, sort);
300 for (Iterator<Type> iter = superInterfaces.iterator(); iter.hasNext(); ) {
301 Type t = iter.next();
302 results.put(t.asClassDoc(), t);
303 }
304 }
305 if (superType == null)
306 return new ArrayList<Type>(results.values());
307 //Try walking the tree.
308 addAllInterfaceTypes(results,
309 superType,
310 interfaceTypesOf(superType),
311 false, configuration);
312 List<Type> resultsList = new ArrayList<Type>(results.values());
313 if (sort) {
314 Collections.sort(resultsList, new TypeComparator());
315 }
316 return resultsList;
317 }
318
319 private static Type[] interfaceTypesOf(Type type) {
320 if (type instanceof AnnotatedType)
321 type = ((AnnotatedType)type).underlyingType();
322 return type instanceof ClassDoc ?
323 ((ClassDoc)type).interfaceTypes() :
324 ((ParameterizedType)type).interfaceTypes();
325 }
326
327 public static List<Type> getAllInterfaces(Type type, Configuration configuration) {
328 return getAllInterfaces(type, configuration, true);
329 }
330
331 private static void findAllInterfaceTypes(Map<ClassDoc,Type> results, ClassDoc c, boolean raw,
332 Configuration configuration) {
333 Type superType = c.superclassType();
334 if (superType == null)
335 return;
336 addAllInterfaceTypes(results, superType,
337 interfaceTypesOf(superType),
338 raw, configuration);
339 }
340
341 private static void findAllInterfaceTypes(Map<ClassDoc,Type> results, ParameterizedType p,
342 Configuration configuration) {
343 Type superType = p.superclassType();
344 if (superType == null)
345 return;
346 addAllInterfaceTypes(results, superType,
347 interfaceTypesOf(superType),
348 false, configuration);
349 }
350
351 private static void addAllInterfaceTypes(Map<ClassDoc,Type> results, Type type,
352 Type[] interfaceTypes, boolean raw,
353 Configuration configuration) {
354 for (int i = 0; i < interfaceTypes.length; i++) {
355 Type interfaceType = interfaceTypes[i];
356 ClassDoc interfaceClassDoc = interfaceType.asClassDoc();
357 if (! (interfaceClassDoc.isPublic() ||
358 (configuration != null &&
359 isLinkable(interfaceClassDoc, configuration)))) {
360 continue;
361 }
362 if (raw)
363 interfaceType = interfaceType.asClassDoc();
364 results.put(interfaceClassDoc, interfaceType);
365 List<Type> superInterfaces = getAllInterfaces(interfaceType, configuration);
366 for (Iterator<Type> iter = superInterfaces.iterator(); iter.hasNext(); ) {
367 Type superInterface = iter.next();
368 results.put(superInterface.asClassDoc(), superInterface);
369 }
370 }
371 if (type instanceof AnnotatedType)
372 type = ((AnnotatedType)type).underlyingType();
373
374 if (type instanceof ParameterizedType)
375 findAllInterfaceTypes(results, (ParameterizedType) type, configuration);
376 else if (((ClassDoc) type).typeParameters().length == 0)
377 findAllInterfaceTypes(results, (ClassDoc) type, raw, configuration);
378 else
379 findAllInterfaceTypes(results, (ClassDoc) type, true, configuration);
380 }
381
382 /**
383 * Enclose in quotes, used for paths and filenames that contains spaces
384 */
385 public static String quote(String filepath) {
386 return ("\"" + filepath + "\"");
387 }
388
389 /**
390 * Given a package, return its name.
391 * @param packageDoc the package to check.
392 * @return the name of the given package.
393 */
394 public static String getPackageName(PackageDoc packageDoc) {
395 return packageDoc == null || packageDoc.name().length() == 0 ?
396 DocletConstants.DEFAULT_PACKAGE_NAME : packageDoc.name();
397 }
398
399 /**
400 * Given a package, return its file name without the extension.
401 * @param packageDoc the package to check.
402 * @return the file name of the given package.
403 */
404 public static String getPackageFileHeadName(PackageDoc packageDoc) {
405 return packageDoc == null || packageDoc.name().length() == 0 ?
406 DocletConstants.DEFAULT_PACKAGE_FILE_NAME : packageDoc.name();
407 }
408
409 /**
410 * Given a string, replace all occurrences of 'newStr' with 'oldStr'.
411 * @param originalStr the string to modify.
412 * @param oldStr the string to replace.
413 * @param newStr the string to insert in place of the old string.
414 */
415 public static String replaceText(String originalStr, String oldStr,
416 String newStr) {
417 if (oldStr == null || newStr == null || oldStr.equals(newStr)) {
418 return originalStr;
419 }
420 return originalStr.replace(oldStr, newStr);
421 }
422
423 /**
424 * Given an annotation, return true if it should be documented and false
425 * otherwise.
426 *
427 * @param annotationDoc the annotation to check.
428 *
429 * @return true return true if it should be documented and false otherwise.
430 */
431 public static boolean isDocumentedAnnotation(AnnotationTypeDoc annotationDoc) {
432 AnnotationDesc[] annotationDescList = annotationDoc.annotations();
433 for (int i = 0; i < annotationDescList.length; i++) {
434 if (annotationDescList[i].annotationType().qualifiedName().equals(
435 java.lang.annotation.Documented.class.getName())){
436 return true;
437 }
438 }
439 return false;
440 }
441
442 private static boolean isDeclarationTarget(AnnotationDesc targetAnno) {
443 // The error recovery steps here are analogous to TypeAnnotations
444 ElementValuePair[] elems = targetAnno.elementValues();
445 if (elems == null
446 || elems.length != 1
447 || !"value".equals(elems[0].element().name())
448 || !(elems[0].value().value() instanceof AnnotationValue[]))
449 return true; // error recovery
450
451 AnnotationValue[] values = (AnnotationValue[])elems[0].value().value();
452 for (int i = 0; i < values.length; i++) {
453 Object value = values[i].value();
454 if (!(value instanceof FieldDoc))
455 return true; // error recovery
456
457 FieldDoc eValue = (FieldDoc)value;
458 if (Util.isJava5DeclarationElementType(eValue)) {
459 return true;
460 }
461 }
462
463 return false;
464 }
465
466 /**
467 * Returns true if the {@code annotationDoc} is to be treated
468 * as a declaration annotation, when targeting the
469 * {@code elemType} element type.
470 *
471 * @param annotationDoc the annotationDoc to check
472 * @param elemType the targeted elemType
473 * @return true if annotationDoc is a declaration annotation
474 */
475 public static boolean isDeclarationAnnotation(AnnotationTypeDoc annotationDoc,
476 boolean isJava5DeclarationLocation) {
477 if (!isJava5DeclarationLocation)
478 return false;
479 AnnotationDesc[] annotationDescList = annotationDoc.annotations();
480 // Annotations with no target are treated as declaration as well
481 if (annotationDescList.length==0)
482 return true;
483 for (int i = 0; i < annotationDescList.length; i++) {
484 if (annotationDescList[i].annotationType().qualifiedName().equals(
485 java.lang.annotation.Target.class.getName())) {
486 if (isDeclarationTarget(annotationDescList[i]))
487 return true;
488 }
489 }
490 return false;
491 }
492
493 /**
494 * Return true if this class is linkable and false if we can't link to the
495 * desired class.
496 * <br>
497 * <b>NOTE:</b> You can only link to external classes if they are public or
498 * protected.
499 *
500 * @param classDoc the class to check.
501 * @param configuration the current configuration of the doclet.
502 *
503 * @return true if this class is linkable and false if we can't link to the
504 * desired class.
505 */
506 public static boolean isLinkable(ClassDoc classDoc,
507 Configuration configuration) {
508 return
509 ((classDoc.isIncluded() && configuration.isGeneratedDoc(classDoc))) ||
510 (configuration.extern.isExternal(classDoc) &&
511 (classDoc.isPublic() || classDoc.isProtected()));
512 }
513
514 /**
515 * Given a class, return the closest visible super class.
516 *
517 * @param classDoc the class we are searching the parent for.
518 * @param configuration the current configuration of the doclet.
519 * @return the closest visible super class. Return null if it cannot
520 * be found (i.e. classDoc is java.lang.Object).
521 */
522 public static Type getFirstVisibleSuperClass(ClassDoc classDoc,
523 Configuration configuration) {
524 if (classDoc == null) {
525 return null;
526 }
527 Type sup = classDoc.superclassType();
528 ClassDoc supClassDoc = classDoc.superclass();
529 while (sup != null &&
530 (! (supClassDoc.isPublic() ||
531 isLinkable(supClassDoc, configuration))) ) {
532 if (supClassDoc.superclass().qualifiedName().equals(supClassDoc.qualifiedName()))
533 break;
534 sup = supClassDoc.superclassType();
535 supClassDoc = supClassDoc.superclass();
536 }
537 if (classDoc.equals(supClassDoc)) {
538 return null;
539 }
540 return sup;
541 }
542
543 /**
544 * Given a class, return the closest visible super class.
545 *
546 * @param classDoc the class we are searching the parent for.
547 * @param configuration the current configuration of the doclet.
548 * @return the closest visible super class. Return null if it cannot
549 * be found (i.e. classDoc is java.lang.Object).
550 */
551 public static ClassDoc getFirstVisibleSuperClassCD(ClassDoc classDoc,
552 Configuration configuration) {
553 if (classDoc == null) {
554 return null;
555 }
556 ClassDoc supClassDoc = classDoc.superclass();
557 while (supClassDoc != null &&
558 (! (supClassDoc.isPublic() ||
559 isLinkable(supClassDoc, configuration))) ) {
560 supClassDoc = supClassDoc.superclass();
561 }
562 if (classDoc.equals(supClassDoc)) {
563 return null;
564 }
565 return supClassDoc;
566 }
567
568 /**
569 * Given a ClassDoc, return the name of its type (Class, Interface, etc.).
570 *
571 * @param cd the ClassDoc to check.
572 * @param lowerCaseOnly true if you want the name returned in lower case.
573 * If false, the first letter of the name is capitalized.
574 * @return
575 */
576 public static String getTypeName(Configuration config,
577 ClassDoc cd, boolean lowerCaseOnly) {
578 String typeName = "";
579 if (cd.isOrdinaryClass()) {
580 typeName = "doclet.Class";
581 } else if (cd.isInterface()) {
582 typeName = "doclet.Interface";
583 } else if (cd.isException()) {
584 typeName = "doclet.Exception";
585 } else if (cd.isError()) {
586 typeName = "doclet.Error";
587 } else if (cd.isAnnotationType()) {
588 typeName = "doclet.AnnotationType";
589 } else if (cd.isEnum()) {
590 typeName = "doclet.Enum";
591 }
592 return config.getText(
593 lowerCaseOnly ? StringUtils.toLowerCase(typeName) : typeName);
594 }
595
596 /**
597 * Replace all tabs in a string with the appropriate number of spaces.
598 * The string may be a multi-line string.
599 * @param configuration the doclet configuration defining the setting for the
600 * tab length.
601 * @param text the text for which the tabs should be expanded
602 * @return the text with all tabs expanded
603 */
604 public static String replaceTabs(Configuration configuration, String text) {
605 if (text.indexOf("\t") == -1)
606 return text;
607
608 final int tabLength = configuration.sourcetab;
609 final String whitespace = configuration.tabSpaces;
610 final int textLength = text.length();
611 StringBuilder result = new StringBuilder(textLength);
612 int pos = 0;
613 int lineLength = 0;
614 for (int i = 0; i < textLength; i++) {
615 char ch = text.charAt(i);
616 switch (ch) {
617 case '\n': case '\r':
618 lineLength = 0;
619 break;
620 case '\t':
621 result.append(text, pos, i);
622 int spaceCount = tabLength - lineLength % tabLength;
623 result.append(whitespace, 0, spaceCount);
624 lineLength += spaceCount;
625 pos = i + 1;
626 break;
627 default:
628 lineLength++;
629 }
630 }
631 result.append(text, pos, textLength);
632 return result.toString();
633 }
634
635 public static String normalizeNewlines(String text) {
636 StringBuilder sb = new StringBuilder();
637 final int textLength = text.length();
638 final String NL = DocletConstants.NL;
639 int pos = 0;
640 for (int i = 0; i < textLength; i++) {
641 char ch = text.charAt(i);
642 switch (ch) {
643 case '\n':
644 sb.append(text, pos, i);
645 sb.append(NL);
646 pos = i + 1;
647 break;
648 case '\r':
649 sb.append(text, pos, i);
650 sb.append(NL);
651 if (i + 1 < textLength && text.charAt(i + 1) == '\n')
652 i++;
653 pos = i + 1;
654 break;
655 }
656 }
657 sb.append(text, pos, textLength);
658 return sb.toString();
659 }
660
661 /**
662 * The documentation for values() and valueOf() in Enums are set by the
663 * doclet.
664 */
665 public static void setEnumDocumentation(Configuration configuration,
666 ClassDoc classDoc) {
667 MethodDoc[] methods = classDoc.methods();
668 for (int j = 0; j < methods.length; j++) {
669 MethodDoc currentMethod = methods[j];
670 if (currentMethod.name().equals("values") &&
671 currentMethod.parameters().length == 0) {
672 StringBuilder sb = new StringBuilder();
673 sb.append(configuration.getText("doclet.enum_values_doc.main", classDoc.name()));
674 sb.append("\n@return ");
675 sb.append(configuration.getText("doclet.enum_values_doc.return"));
676 currentMethod.setRawCommentText(sb.toString());
677 } else if (currentMethod.name().equals("valueOf") &&
678 currentMethod.parameters().length == 1) {
679 Type paramType = currentMethod.parameters()[0].type();
680 if (paramType != null &&
681 paramType.qualifiedTypeName().equals(String.class.getName())) {
682 StringBuilder sb = new StringBuilder();
683 sb.append(configuration.getText("doclet.enum_valueof_doc.main", classDoc.name()));
684 sb.append("\n@param name ");
685 sb.append(configuration.getText("doclet.enum_valueof_doc.param_name"));
686 sb.append("\n@return ");
687 sb.append(configuration.getText("doclet.enum_valueof_doc.return"));
688 sb.append("\n@throws IllegalArgumentException ");
689 sb.append(configuration.getText("doclet.enum_valueof_doc.throws_ila"));
690 sb.append("\n@throws NullPointerException ");
691 sb.append(configuration.getText("doclet.enum_valueof_doc.throws_npe"));
692 currentMethod.setRawCommentText(sb.toString());
693 }
694 }
695 }
696 }
697
698 /**
699 * Return true if the given Doc is deprecated.
700 *
701 * @param doc the Doc to check.
702 * @return true if the given Doc is deprecated.
703 */
704 public static boolean isDeprecated(Doc doc) {
705 if (doc.tags("deprecated").length > 0) {
706 return true;
707 }
708 AnnotationDesc[] annotationDescList;
709 if (doc instanceof PackageDoc)
710 annotationDescList = ((PackageDoc)doc).annotations();
711 else
712 annotationDescList = ((ProgramElementDoc)doc).annotations();
713 for (int i = 0; i < annotationDescList.length; i++) {
714 if (annotationDescList[i].annotationType().qualifiedName().equals(
715 java.lang.Deprecated.class.getName())){
716 return true;
717 }
718 }
719 return false;
720 }
721
722 /**
723 * A convenience method to get property name from the name of the
724 * getter or setter method.
725 * @param name name of the getter or setter method.
726 * @return the name of the property of the given setter of getter.
727 */
728 public static String propertyNameFromMethodName(Configuration configuration, String name) {
729 String propertyName = null;
730 if (name.startsWith("get") || name.startsWith("set")) {
731 propertyName = name.substring(3);
732 } else if (name.startsWith("is")) {
733 propertyName = name.substring(2);
734 }
735 if ((propertyName == null) || propertyName.isEmpty()){
736 return "";
737 }
738 return propertyName.substring(0, 1).toLowerCase(configuration.getLocale())
739 + propertyName.substring(1);
740 }
741
742 /**
743 * In case of JavaFX mode on, filters out classes that are private,
744 * package private or having the @treatAsPrivate annotation. Those are not
745 * documented in JavaFX mode.
746 *
747 * @param classes array of classes to be filtered.
748 * @param javafx set to true if in JavaFX mode.
749 * @return list of filtered classes.
750 */
751 public static ClassDoc[] filterOutPrivateClasses(final ClassDoc[] classes,
752 boolean javafx) {
753 if (!javafx) {
754 return classes;
755 }
756 final List<ClassDoc> filteredOutClasses =
757 new ArrayList<ClassDoc>(classes.length);
758 for (ClassDoc classDoc : classes) {
759 if (classDoc.isPrivate() || classDoc.isPackagePrivate()) {
760 continue;
761 }
762 Tag[] aspTags = classDoc.tags("treatAsPrivate");
763 if (aspTags != null && aspTags.length > 0) {
764 continue;
765 }
766 filteredOutClasses.add(classDoc);
767 }
768
769 return filteredOutClasses.toArray(new ClassDoc[0]);
770 }
771
772 /**
773 * Test whether the given FieldDoc is one of the declaration annotation ElementTypes
774 * defined in Java 5.
775 * Instead of testing for one of the new enum constants added in Java 8, test for
776 * the old constants. This prevents bootstrapping problems.
777 *
778 * @param elt The FieldDoc to test
779 * @return true, iff the given ElementType is one of the constants defined in Java 5
780 * @since 1.8
781 */
782 public static boolean isJava5DeclarationElementType(FieldDoc elt) {
783 return elt.name().contentEquals(ElementType.ANNOTATION_TYPE.name()) ||
784 elt.name().contentEquals(ElementType.CONSTRUCTOR.name()) ||
785 elt.name().contentEquals(ElementType.FIELD.name()) ||
786 elt.name().contentEquals(ElementType.LOCAL_VARIABLE.name()) ||
787 elt.name().contentEquals(ElementType.METHOD.name()) ||
788 elt.name().contentEquals(ElementType.PACKAGE.name()) ||
789 elt.name().contentEquals(ElementType.PARAMETER.name()) ||
790 elt.name().contentEquals(ElementType.TYPE.name());
791 }
792 }

mercurial