/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.doclets.internal.toolkit.util;
import java.io.*;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.text.Collator;
import java.util.*;
import javax.tools.JavaFileManager.Location;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.javac.util.StringUtils;
Utilities Class for Doclets.
This is NOT part of any supported API.
If you write code that depends on this, you do so at your own risk.
This code and its internal interfaces are subject to change or
deletion without notice.
Author: Atul M Dambalkar, Jamie Ho
/**
* Utilities Class for Doclets.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*
* @author Atul M Dambalkar
* @author Jamie Ho
*/
@Deprecated
public class Utils {
Return array of class members whose documentation is to be generated.
If the member is deprecated do not include such a member in the
returned array.
Params: - members – Array of members to choose from.
Returns: ProgramElementDoc[] Array of eligible members for whom
documentation is getting generated.
/**
* Return array of class members whose documentation is to be generated.
* If the member is deprecated do not include such a member in the
* returned array.
*
* @param members Array of members to choose from.
* @return ProgramElementDoc[] Array of eligible members for whom
* documentation is getting generated.
*/
public ProgramElementDoc[] excludeDeprecatedMembers(
ProgramElementDoc[] members) {
return
toProgramElementDocArray(excludeDeprecatedMembersAsList(members));
}
Return array of class members whose documentation is to be generated.
If the member is deprecated do not include such a member in the
returned array.
Params: - members – Array of members to choose from.
Returns: List List of eligible members for whom
documentation is getting generated.
/**
* Return array of class members whose documentation is to be generated.
* If the member is deprecated do not include such a member in the
* returned array.
*
* @param members Array of members to choose from.
* @return List List of eligible members for whom
* documentation is getting generated.
*/
public List<ProgramElementDoc> excludeDeprecatedMembersAsList(
ProgramElementDoc[] members) {
List<ProgramElementDoc> list = new ArrayList<>();
for (ProgramElementDoc member : members) {
if (member.tags("deprecated").length == 0) {
list.add(member);
}
}
Collections.sort(list);
return list;
}
Return the list of ProgramElementDoc objects as Array.
/**
* Return the list of ProgramElementDoc objects as Array.
*/
public ProgramElementDoc[] toProgramElementDocArray(List<ProgramElementDoc> list) {
ProgramElementDoc[] pgmarr = new ProgramElementDoc[list.size()];
for (int i = 0; i < list.size(); i++) {
pgmarr[i] = list.get(i);
}
return pgmarr;
}
Return true if a non-public member found in the given array.
Params: - members – Array of members to look into.
Returns: boolean True if non-public member found, false otherwise.
/**
* Return true if a non-public member found in the given array.
*
* @param members Array of members to look into.
* @return boolean True if non-public member found, false otherwise.
*/
public boolean nonPublicMemberFound(ProgramElementDoc[] members) {
for (ProgramElementDoc member : members) {
if (!member.isPublic()) {
return true;
}
}
return false;
}
Search for the given method in the given class.
Params: - cd – Class to search into.
- method – Method to be searched.
Returns: MethodDoc Method found, null otherwise.
/**
* Search for the given method in the given class.
*
* @param cd Class to search into.
* @param method Method to be searched.
* @return MethodDoc Method found, null otherwise.
*/
public MethodDoc findMethod(ClassDoc cd, MethodDoc method) {
MethodDoc[] methods = cd.methods();
for (MethodDoc m : methods) {
if (executableMembersEqual(method, m)) {
return m;
}
}
return null;
}
Params: - member1 – the first method to compare.
- member2 – the second method to compare.
Returns: true if member1 overrides/hides or is overriden/hidden by member2.
/**
* @param member1 the first method to compare.
* @param member2 the second method to compare.
* @return true if member1 overrides/hides or is overriden/hidden by member2.
*/
public boolean executableMembersEqual(ExecutableMemberDoc member1,
ExecutableMemberDoc member2) {
if (! (member1 instanceof MethodDoc && member2 instanceof MethodDoc))
return false;
MethodDoc method1 = (MethodDoc) member1;
MethodDoc method2 = (MethodDoc) member2;
if (method1.isStatic() && method2.isStatic()) {
Parameter[] targetParams = method1.parameters();
Parameter[] currentParams;
if (method1.name().equals(method2.name()) &&
(currentParams = method2.parameters()).length ==
targetParams.length) {
int j;
for (j = 0; j < targetParams.length; j++) {
if (! (targetParams[j].typeName().equals(
currentParams[j].typeName()) ||
currentParams[j].type() instanceof TypeVariable ||
targetParams[j].type() instanceof TypeVariable)) {
break;
}
}
if (j == targetParams.length) {
return true;
}
}
return false;
} else {
return method1.overrides(method2) ||
method2.overrides(method1) ||
member1 == member2;
}
}
According to
The Java™ Language Specification,
all the outer classes and static inner classes are core classes.
/**
* According to
* <cite>The Java™ Language Specification</cite>,
* all the outer classes and static inner classes are core classes.
*/
public boolean isCoreClass(ClassDoc cd) {
return cd.containingClass() == null || cd.isStatic();
}
public boolean matches(ProgramElementDoc doc1,
ProgramElementDoc doc2) {
if (doc1 instanceof ExecutableMemberDoc &&
doc2 instanceof ExecutableMemberDoc) {
ExecutableMemberDoc ed1 = (ExecutableMemberDoc)doc1;
ExecutableMemberDoc ed2 = (ExecutableMemberDoc)doc2;
return executableMembersEqual(ed1, ed2);
} else {
return doc1.name().equals(doc2.name());
}
}
Copy the given directory contents from the source package directory to the generated documentation directory. For example for a package java.lang this method find out the source location of the package using SourcePath
and if given directory is found in the source directory structure, copy the entire directory, to the generated documentation hierarchy. Params: - configuration – The configuration of the current doclet.
- path – The relative path to the directory to be copied.
- dir – The original directory name to copy from.
- overwrite – Overwrite files if true.
/**
* Copy the given directory contents from the source package directory
* to the generated documentation directory. For example for a package
* java.lang this method find out the source location of the package using
* {@link SourcePath} and if given directory is found in the source
* directory structure, copy the entire directory, to the generated
* documentation hierarchy.
*
* @param configuration The configuration of the current doclet.
* @param path The relative path to the directory to be copied.
* @param dir The original directory name to copy from.
* @param overwrite Overwrite files if true.
*/
public void copyDocFiles(Configuration configuration, PackageDoc pd) {
Location locn = configuration.getLocationForPackage(pd);
copyDocFiles(configuration, locn, DocPath.forPackage(pd).resolve(DocPaths.DOC_FILES));
}
public void copyDocFiles(Configuration configuration, Location locn, DocPath dir) {
try {
boolean first = true;
for (DocFile f : DocFile.list(configuration, locn, dir)) {
if (!f.isDirectory()) {
continue;
}
DocFile srcdir = f;
DocFile destdir = DocFile.createFileForOutput(configuration, dir);
if (srcdir.isSameFile(destdir)) {
continue;
}
for (DocFile srcfile: srcdir.list()) {
DocFile destfile = destdir.resolve(srcfile.getName());
if (srcfile.isFile()) {
if (destfile.exists() && !first) {
configuration.message.warning((SourcePosition) null,
"doclet.Copy_Overwrite_warning",
srcfile.getPath(), destdir.getPath());
} else {
configuration.message.notice(
"doclet.Copying_File_0_To_Dir_1",
srcfile.getPath(), destdir.getPath());
destfile.copyFile(srcfile);
}
} else if (srcfile.isDirectory()) {
if (configuration.copydocfilesubdirs
&& !configuration.shouldExcludeDocFileDir(srcfile.getName())) {
copyDocFiles(configuration, locn, dir.resolve(srcfile.getName()));
}
}
}
first = false;
}
} catch (SecurityException | IOException exc) {
throw new DocletAbortException(exc);
}
}
Returns a TypeComparator object suitable for sorting Types.
Returns: a TypeComparator objectt
/**
* Returns a TypeComparator object suitable for sorting Types.
* @return a TypeComparator objectt
*/
public Comparator<Type> makeTypeComparator() {
return new TypeComparator();
}
We want the list of types in alphabetical order. However, types are not
comparable. We need a comparator for now.
/**
* We want the list of types in alphabetical order. However, types are not
* comparable. We need a comparator for now.
*/
private static class TypeComparator implements Comparator<Type> {
public int compare(Type type1, Type type2) {
return compareStrings(type1.qualifiedTypeName(), type2.qualifiedTypeName());
}
}
For the class return all implemented interfaces including the
superinterfaces of the implementing interfaces, also iterate over for
all the superclasses. For interface return all the extended interfaces
as well as superinterfaces for those extended interfaces.
Params: - type – type whose implemented or
super interfaces are sought.
- configuration – the current configuration of the doclet.
- sort – if true, return list of interfaces sorted alphabetically.
Returns: List of all the required interfaces.
/**
* For the class return all implemented interfaces including the
* superinterfaces of the implementing interfaces, also iterate over for
* all the superclasses. For interface return all the extended interfaces
* as well as superinterfaces for those extended interfaces.
*
* @param type type whose implemented or
* super interfaces are sought.
* @param configuration the current configuration of the doclet.
* @param sort if true, return list of interfaces sorted alphabetically.
* @return List of all the required interfaces.
*/
public List<Type> getAllInterfaces(Type type,
Configuration configuration, boolean sort) {
Map<ClassDoc,Type> results = sort ?
new TreeMap<ClassDoc,Type>() :
new LinkedHashMap<ClassDoc,Type>();
Type[] interfaceTypes = null;
Type superType = null;
if (type instanceof ParameterizedType) {
interfaceTypes = ((ParameterizedType) type).interfaceTypes();
superType = ((ParameterizedType) type).superclassType();
} else if (type instanceof ClassDoc) {
interfaceTypes = ((ClassDoc) type).interfaceTypes();
superType = ((ClassDoc) type).superclassType();
} else {
interfaceTypes = type.asClassDoc().interfaceTypes();
superType = type.asClassDoc().superclassType();
}
for (Type interfaceType : interfaceTypes) {
ClassDoc interfaceClassDoc = interfaceType.asClassDoc();
if (!(interfaceClassDoc.isPublic() ||
(configuration == null ||
isLinkable(interfaceClassDoc, configuration)))) {
continue;
}
results.put(interfaceClassDoc, interfaceType);
for (Type t : getAllInterfaces(interfaceType, configuration, sort)) {
results.put(t.asClassDoc(), t);
}
}
if (superType == null)
return new ArrayList<>(results.values());
//Try walking the tree.
addAllInterfaceTypes(results,
superType,
interfaceTypesOf(superType),
false, configuration);
List<Type> resultsList = new ArrayList<>(results.values());
if (sort) {
Collections.sort(resultsList, new TypeComparator());
}
return resultsList;
}
private Type[] interfaceTypesOf(Type type) {
if (type instanceof AnnotatedType)
type = ((AnnotatedType)type).underlyingType();
return type instanceof ClassDoc ?
((ClassDoc)type).interfaceTypes() :
((ParameterizedType)type).interfaceTypes();
}
public List<Type> getAllInterfaces(Type type, Configuration configuration) {
return getAllInterfaces(type, configuration, true);
}
private void findAllInterfaceTypes(Map<ClassDoc,Type> results, ClassDoc c, boolean raw,
Configuration configuration) {
Type superType = c.superclassType();
if (superType == null)
return;
addAllInterfaceTypes(results, superType,
interfaceTypesOf(superType),
raw, configuration);
}
private void findAllInterfaceTypes(Map<ClassDoc,Type> results, ParameterizedType p,
Configuration configuration) {
Type superType = p.superclassType();
if (superType == null)
return;
addAllInterfaceTypes(results, superType,
interfaceTypesOf(superType),
false, configuration);
}
private void addAllInterfaceTypes(Map<ClassDoc,Type> results, Type type,
Type[] interfaceTypes, boolean raw,
Configuration configuration) {
for (Type interfaceType : interfaceTypes) {
ClassDoc interfaceClassDoc = interfaceType.asClassDoc();
if (!(interfaceClassDoc.isPublic() ||
(configuration != null &&
isLinkable(interfaceClassDoc, configuration)))) {
continue;
}
if (raw)
interfaceType = interfaceType.asClassDoc();
results.put(interfaceClassDoc, interfaceType);
List<Type> superInterfaces = getAllInterfaces(interfaceType, configuration);
for (Type superInterface : superInterfaces) {
results.put(superInterface.asClassDoc(), superInterface);
}
}
if (type instanceof AnnotatedType)
type = ((AnnotatedType)type).underlyingType();
if (type instanceof ParameterizedType)
findAllInterfaceTypes(results, (ParameterizedType) type, configuration);
else if (((ClassDoc) type).typeParameters().length == 0)
findAllInterfaceTypes(results, (ClassDoc) type, raw, configuration);
else
findAllInterfaceTypes(results, (ClassDoc) type, true, configuration);
}
Enclose in quotes, used for paths and filenames that contains spaces
/**
* Enclose in quotes, used for paths and filenames that contains spaces
*/
public String quote(String filepath) {
return ("\"" + filepath + "\"");
}
Given a package, return its name.
Params: - packageDoc – the package to check.
Returns: the name of the given package.
/**
* Given a package, return its name.
* @param packageDoc the package to check.
* @return the name of the given package.
*/
public String getPackageName(PackageDoc packageDoc) {
return packageDoc == null || packageDoc.name().length() == 0 ?
DocletConstants.DEFAULT_PACKAGE_NAME : packageDoc.name();
}
Given a package, return its file name without the extension.
Params: - packageDoc – the package to check.
Returns: the file name of the given package.
/**
* Given a package, return its file name without the extension.
* @param packageDoc the package to check.
* @return the file name of the given package.
*/
public String getPackageFileHeadName(PackageDoc packageDoc) {
return packageDoc == null || packageDoc.name().length() == 0 ?
DocletConstants.DEFAULT_PACKAGE_FILE_NAME : packageDoc.name();
}
Given a string, replace all occurrences of 'newStr' with 'oldStr'.
Params: - originalStr – the string to modify.
- oldStr – the string to replace.
- newStr – the string to insert in place of the old string.
/**
* Given a string, replace all occurrences of 'newStr' with 'oldStr'.
* @param originalStr the string to modify.
* @param oldStr the string to replace.
* @param newStr the string to insert in place of the old string.
*/
public String replaceText(String originalStr, String oldStr,
String newStr) {
if (oldStr == null || newStr == null || oldStr.equals(newStr)) {
return originalStr;
}
return originalStr.replace(oldStr, newStr);
}
Given an annotation, return true if it should be documented and false
otherwise.
Params: - annotationDoc – the annotation to check.
Returns: true return true if it should be documented and false otherwise.
/**
* Given an annotation, return true if it should be documented and false
* otherwise.
*
* @param annotationDoc the annotation to check.
*
* @return true return true if it should be documented and false otherwise.
*/
public boolean isDocumentedAnnotation(AnnotationTypeDoc annotationDoc) {
for (AnnotationDesc anno : annotationDoc.annotations()) {
if (anno.annotationType().qualifiedName().equals(
Documented.class.getName())) {
return true;
}
}
return false;
}
private boolean isDeclarationTarget(AnnotationDesc targetAnno) {
// The error recovery steps here are analogous to TypeAnnotations
AnnotationDesc.ElementValuePair[] elems = targetAnno.elementValues();
if (elems == null
|| elems.length != 1
|| !"value".equals(elems[0].element().name())
|| !(elems[0].value().value() instanceof AnnotationValue[]))
return true; // error recovery
for (AnnotationValue aValue : (AnnotationValue[])elems[0].value().value()) {
Object value = aValue.value();
if (!(value instanceof FieldDoc))
return true; // error recovery
FieldDoc eValue = (FieldDoc) value;
if (isJava5DeclarationElementType(eValue)) {
return true;
}
}
return false;
}
Returns true if the annotationDoc
is to be treated as a declaration annotation, when targeting the elemType
element type. Params: - annotationDoc – the annotationDoc to check
- elemType – the targeted elemType
Returns: true if annotationDoc is a declaration annotation
/**
* Returns true if the {@code annotationDoc} is to be treated
* as a declaration annotation, when targeting the
* {@code elemType} element type.
*
* @param annotationDoc the annotationDoc to check
* @param elemType the targeted elemType
* @return true if annotationDoc is a declaration annotation
*/
public boolean isDeclarationAnnotation(AnnotationTypeDoc annotationDoc,
boolean isJava5DeclarationLocation) {
if (!isJava5DeclarationLocation)
return false;
AnnotationDesc[] annotationDescList = annotationDoc.annotations();
// Annotations with no target are treated as declaration as well
if (annotationDescList.length==0)
return true;
for (AnnotationDesc anno : annotationDescList) {
if (anno.annotationType().qualifiedName().equals(
Target.class.getName())) {
if (isDeclarationTarget(anno))
return true;
}
}
return false;
}
Return true if this class is linkable and false if we can't link to the
desired class.
NOTE: You can only link to external classes if they are public or
protected.
Params: - classDoc – the class to check.
- configuration – the current configuration of the doclet.
Returns: true if this class is linkable and false if we can't link to the
desired class.
/**
* Return true if this class is linkable and false if we can't link to the
* desired class.
* <br>
* <b>NOTE:</b> You can only link to external classes if they are public or
* protected.
*
* @param classDoc the class to check.
* @param configuration the current configuration of the doclet.
*
* @return true if this class is linkable and false if we can't link to the
* desired class.
*/
public boolean isLinkable(ClassDoc classDoc,
Configuration configuration) {
return
((classDoc.isIncluded() && configuration.isGeneratedDoc(classDoc))) ||
(configuration.extern.isExternal(classDoc) &&
(classDoc.isPublic() || classDoc.isProtected()));
}
Given a class, return the closest visible super class.
Params: - classDoc – the class we are searching the parent for.
- configuration – the current configuration of the doclet.
Returns: the closest visible super class. Return null if it cannot
be found (i.e. classDoc is java.lang.Object).
/**
* Given a class, return the closest visible super class.
*
* @param classDoc the class we are searching the parent for.
* @param configuration the current configuration of the doclet.
* @return the closest visible super class. Return null if it cannot
* be found (i.e. classDoc is java.lang.Object).
*/
public Type getFirstVisibleSuperClass(ClassDoc classDoc,
Configuration configuration) {
if (classDoc == null) {
return null;
}
Type sup = classDoc.superclassType();
ClassDoc supClassDoc = classDoc.superclass();
while (sup != null &&
(! (supClassDoc.isPublic() ||
isLinkable(supClassDoc, configuration))) ) {
if (supClassDoc.superclass().qualifiedName().equals(supClassDoc.qualifiedName()))
break;
sup = supClassDoc.superclassType();
supClassDoc = supClassDoc.superclass();
}
if (classDoc.equals(supClassDoc)) {
return null;
}
return sup;
}
Given a class, return the closest visible super class.
Params: - classDoc – the class we are searching the parent for.
- configuration – the current configuration of the doclet.
Returns: the closest visible super class. Return null if it cannot
be found (i.e. classDoc is java.lang.Object).
/**
* Given a class, return the closest visible super class.
*
* @param classDoc the class we are searching the parent for.
* @param configuration the current configuration of the doclet.
* @return the closest visible super class. Return null if it cannot
* be found (i.e. classDoc is java.lang.Object).
*/
public ClassDoc getFirstVisibleSuperClassCD(ClassDoc classDoc,
Configuration configuration) {
if (classDoc == null) {
return null;
}
ClassDoc supClassDoc = classDoc.superclass();
while (supClassDoc != null &&
(! (supClassDoc.isPublic() ||
isLinkable(supClassDoc, configuration))) ) {
supClassDoc = supClassDoc.superclass();
}
if (classDoc.equals(supClassDoc)) {
return null;
}
return supClassDoc;
}
Given a ClassDoc, return the name of its type (Class, Interface, etc.).
Params: - cd – the ClassDoc to check.
- lowerCaseOnly – true if you want the name returned in lower case.
If false, the first letter of the name is capitalized.
Returns:
/**
* Given a ClassDoc, return the name of its type (Class, Interface, etc.).
*
* @param cd the ClassDoc to check.
* @param lowerCaseOnly true if you want the name returned in lower case.
* If false, the first letter of the name is capitalized.
* @return
*/
public String getTypeName(Configuration config,
ClassDoc cd, boolean lowerCaseOnly) {
String typeName = "";
if (cd.isOrdinaryClass()) {
typeName = "doclet.Class";
} else if (cd.isInterface()) {
typeName = "doclet.Interface";
} else if (cd.isException()) {
typeName = "doclet.Exception";
} else if (cd.isError()) {
typeName = "doclet.Error";
} else if (cd.isAnnotationType()) {
typeName = "doclet.AnnotationType";
} else if (cd.isEnum()) {
typeName = "doclet.Enum";
}
return config.getText(
lowerCaseOnly ? StringUtils.toLowerCase(typeName) : typeName);
}
Replace all tabs in a string with the appropriate number of spaces.
The string may be a multi-line string.
Params: - configuration – the doclet configuration defining the setting for the
tab length.
- text – the text for which the tabs should be expanded
Returns: the text with all tabs expanded
/**
* Replace all tabs in a string with the appropriate number of spaces.
* The string may be a multi-line string.
* @param configuration the doclet configuration defining the setting for the
* tab length.
* @param text the text for which the tabs should be expanded
* @return the text with all tabs expanded
*/
public String replaceTabs(Configuration configuration, String text) {
if (!text.contains("\t"))
return text;
final int tabLength = configuration.sourcetab;
final String whitespace = configuration.tabSpaces;
final int textLength = text.length();
StringBuilder result = new StringBuilder(textLength);
int pos = 0;
int lineLength = 0;
for (int i = 0; i < textLength; i++) {
char ch = text.charAt(i);
switch (ch) {
case '\n': case '\r':
lineLength = 0;
break;
case '\t':
result.append(text, pos, i);
int spaceCount = tabLength - lineLength % tabLength;
result.append(whitespace, 0, spaceCount);
lineLength += spaceCount;
pos = i + 1;
break;
default:
lineLength++;
}
}
result.append(text, pos, textLength);
return result.toString();
}
public String normalizeNewlines(String text) {
StringBuilder sb = new StringBuilder();
final int textLength = text.length();
final String NL = DocletConstants.NL;
int pos = 0;
for (int i = 0; i < textLength; i++) {
char ch = text.charAt(i);
switch (ch) {
case '\n':
sb.append(text, pos, i);
sb.append(NL);
pos = i + 1;
break;
case '\r':
sb.append(text, pos, i);
sb.append(NL);
if (i + 1 < textLength && text.charAt(i + 1) == '\n')
i++;
pos = i + 1;
break;
}
}
sb.append(text, pos, textLength);
return sb.toString();
}
The documentation for values() and valueOf() in Enums are set by the
doclet.
/**
* The documentation for values() and valueOf() in Enums are set by the
* doclet.
*/
public void setEnumDocumentation(Configuration configuration,
ClassDoc classDoc) {
for (MethodDoc currentMethod : classDoc.methods()) {
if (currentMethod.name().equals("values") &&
currentMethod.parameters().length == 0) {
StringBuilder sb = new StringBuilder();
sb.append(configuration.getText("doclet.enum_values_doc.main", classDoc.name()));
sb.append("\n@return ");
sb.append(configuration.getText("doclet.enum_values_doc.return"));
currentMethod.setRawCommentText(sb.toString());
} else if (currentMethod.name().equals("valueOf") &&
currentMethod.parameters().length == 1) {
Type paramType = currentMethod.parameters()[0].type();
if (paramType != null &&
paramType.qualifiedTypeName().equals(String.class.getName())) {
StringBuilder sb = new StringBuilder();
sb.append(configuration.getText("doclet.enum_valueof_doc.main", classDoc.name()));
sb.append("\n@param name ");
sb.append(configuration.getText("doclet.enum_valueof_doc.param_name"));
sb.append("\n@return ");
sb.append(configuration.getText("doclet.enum_valueof_doc.return"));
sb.append("\n@throws IllegalArgumentException ");
sb.append(configuration.getText("doclet.enum_valueof_doc.throws_ila"));
sb.append("\n@throws NullPointerException ");
sb.append(configuration.getText("doclet.enum_valueof_doc.throws_npe"));
currentMethod.setRawCommentText(sb.toString());
}
}
}
}
Return true if the given Doc is deprecated.
Params: - doc – the Doc to check.
Returns: true if the given Doc is deprecated.
/**
* Return true if the given Doc is deprecated.
*
* @param doc the Doc to check.
* @return true if the given Doc is deprecated.
*/
public boolean isDeprecated(Doc doc) {
if (doc.tags("deprecated").length > 0) {
return true;
}
AnnotationDesc[] annotationDescList;
if (doc instanceof PackageDoc)
annotationDescList = ((PackageDoc)doc).annotations();
else
annotationDescList = ((ProgramElementDoc)doc).annotations();
for (AnnotationDesc anno : annotationDescList) {
if (anno.annotationType().qualifiedName().equals(
Deprecated.class.getName())) {
return true;
}
}
return false;
}
A convenience method to get property name from the name of the
getter or setter method.
Params: - name – name of the getter or setter method.
Returns: the name of the property of the given setter of getter.
/**
* A convenience method to get property name from the name of the
* getter or setter method.
* @param name name of the getter or setter method.
* @return the name of the property of the given setter of getter.
*/
public String propertyNameFromMethodName(Configuration configuration, String name) {
String propertyName = null;
if (name.startsWith("get") || name.startsWith("set")) {
propertyName = name.substring(3);
} else if (name.startsWith("is")) {
propertyName = name.substring(2);
}
if ((propertyName == null) || propertyName.isEmpty()){
return "";
}
return propertyName.substring(0, 1).toLowerCase(configuration.getLocale())
+ propertyName.substring(1);
}
In case of JavaFX mode on, filters out classes that are private,
package private or having the @treatAsPrivate annotation. Those are not
documented in JavaFX mode.
Params: - classes – array of classes to be filtered.
- javafx – set to true if in JavaFX mode.
Returns: list of filtered classes.
/**
* In case of JavaFX mode on, filters out classes that are private,
* package private or having the @treatAsPrivate annotation. Those are not
* documented in JavaFX mode.
*
* @param classes array of classes to be filtered.
* @param javafx set to true if in JavaFX mode.
* @return list of filtered classes.
*/
public ClassDoc[] filterOutPrivateClasses(final ClassDoc[] classes,
boolean javafx) {
if (!javafx) {
return classes;
}
final List<ClassDoc> filteredOutClasses = new ArrayList<>(classes.length);
for (ClassDoc classDoc : classes) {
if (classDoc.isPrivate() || classDoc.isPackagePrivate()) {
continue;
}
Tag[] aspTags = classDoc.tags("treatAsPrivate");
if (aspTags != null && aspTags.length > 0) {
continue;
}
filteredOutClasses.add(classDoc);
}
return filteredOutClasses.toArray(new ClassDoc[0]);
}
Test whether the given FieldDoc is one of the declaration annotation ElementTypes
defined in Java 5.
Instead of testing for one of the new enum constants added in Java 8, test for
the old constants. This prevents bootstrapping problems.
Params: - elt – The FieldDoc to test
Returns: true, iff the given ElementType is one of the constants defined in Java 5 Since: 1.8
/**
* Test whether the given FieldDoc is one of the declaration annotation ElementTypes
* defined in Java 5.
* Instead of testing for one of the new enum constants added in Java 8, test for
* the old constants. This prevents bootstrapping problems.
*
* @param elt The FieldDoc to test
* @return true, iff the given ElementType is one of the constants defined in Java 5
* @since 1.8
*/
public boolean isJava5DeclarationElementType(FieldDoc elt) {
return elt.name().contentEquals(ElementType.ANNOTATION_TYPE.name()) ||
elt.name().contentEquals(ElementType.CONSTRUCTOR.name()) ||
elt.name().contentEquals(ElementType.FIELD.name()) ||
elt.name().contentEquals(ElementType.LOCAL_VARIABLE.name()) ||
elt.name().contentEquals(ElementType.METHOD.name()) ||
elt.name().contentEquals(ElementType.PACKAGE.name()) ||
elt.name().contentEquals(ElementType.PARAMETER.name()) ||
elt.name().contentEquals(ElementType.TYPE.name());
}
A general purpose case insensitive String comparator, which compares two Strings using a Collator
strength of "TERTIARY".
Params: - s1 – first String to compare.
- s2 – second String to compare.
Returns: a negative integer, zero, or a positive integer as the first
argument is less than, equal to, or greater than the second.
/**
* A general purpose case insensitive String comparator, which compares two Strings using a Collator
* strength of "TERTIARY".
*
* @param s1 first String to compare.
* @param s2 second String to compare.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
public static int compareStrings(String s1, String s2) {
return compareStrings(true, s1, s2);
}
A general purpose case sensitive String comparator, which compares two Strings using a Collator
strength of "SECONDARY".
Params: - s1 – first String to compare.
- s2 – second String to compare.
Returns: a negative integer, zero, or a positive integer as the first
argument is less than, equal to, or greater than the second.
/**
* A general purpose case sensitive String comparator, which compares two Strings using a Collator
* strength of "SECONDARY".
*
* @param s1 first String to compare.
* @param s2 second String to compare.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
public static int compareCaseCompare(String s1, String s2) {
return compareStrings(false, s1, s2);
}
private static int compareStrings(boolean caseSensitive, String s1, String s2) {
Collator collator = Collator.getInstance();
collator.setStrength(caseSensitive ? Collator.TERTIARY : Collator.SECONDARY);
return collator.compare(s1, s2);
}
A simple comparator which compares simple names, then the fully qualified names
and finally the kinds, ClassUse comparator works well for this purpose.
Returns: a simple general purpose doc comparator
/**
* A simple comparator which compares simple names, then the fully qualified names
* and finally the kinds, ClassUse comparator works well for this purpose.
*
* @return a simple general purpose doc comparator
*/
public Comparator<Doc> makeGeneralPurposeComparator() {
return makeComparatorForClassUse();
}
A comparator for index file presentations, and are sorted as follows:
1. sort on simple names of entities
2. if equal, then compare the DocKind ex: Package, Interface etc.
3a. if equal and if the type is of ExecutableMemberDoc(Constructor, Methods),
a case insensitive comparison of parameter the type signatures
3b. if equal, case sensitive comparison of the type signatures
4. finally, if equal, compare the FQNs of the entities
Returns: a comparator for index file use
/**
* A comparator for index file presentations, and are sorted as follows:
* 1. sort on simple names of entities
* 2. if equal, then compare the DocKind ex: Package, Interface etc.
* 3a. if equal and if the type is of ExecutableMemberDoc(Constructor, Methods),
* a case insensitive comparison of parameter the type signatures
* 3b. if equal, case sensitive comparison of the type signatures
* 4. finally, if equal, compare the FQNs of the entities
* @return a comparator for index file use
*/
public Comparator<Doc> makeComparatorForIndexUse() {
return new Utils.DocComparator<Doc>() {
Compare two given Doc entities, first sort on names, then on the kinds,
then on the parameters only if the type is an instance of ExecutableMemberDocs,
the parameters are compared and finally the fully qualified names.
Params: - d1 – - a Doc element.
- d2 – - a Doc element.
Returns: a negative integer, zero, or a positive integer as the first
argument is less than, equal to, or greater than the second.
/**
* Compare two given Doc entities, first sort on names, then on the kinds,
* then on the parameters only if the type is an instance of ExecutableMemberDocs,
* the parameters are compared and finally the fully qualified names.
*
* @param d1 - a Doc element.
* @param d2 - a Doc element.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
public int compare(Doc d1, Doc d2) {
int result = compareNames(d1, d2);
if (result != 0) {
return result;
}
result = compareDocKinds(d1, d2);
if (result != 0) {
return result;
}
if (hasParameters(d1)) {
Parameter[] param1 = ((ExecutableMemberDoc) d1).parameters();
Parameter[] param2 = ((ExecutableMemberDoc) d2).parameters();
result = compareParameters(false, param1, param2);
if (result != 0) {
return result;
}
result = compareParameters(true, param1, param2);
if (result != 0) {
return result;
}
}
return compareFullyQualifiedNames(d1, d2);
}
};
}
Comparator for ClassUse presentations, and sorted as follows,
1. compares simple names of entities
2. if equal, the fully qualified names of the entities
3. if equal and if applicable, the string representation of parameter types
3a. first by using case insensitive comparison
3b. second by using a case sensitive comparison
4. finally the Doc kinds ie. package, class, interface etc.
Returns: a comparator to sort classes and members for class use
/**
* Comparator for ClassUse presentations, and sorted as follows,
* 1. compares simple names of entities
* 2. if equal, the fully qualified names of the entities
* 3. if equal and if applicable, the string representation of parameter types
* 3a. first by using case insensitive comparison
* 3b. second by using a case sensitive comparison
* 4. finally the Doc kinds ie. package, class, interface etc.
* @return a comparator to sort classes and members for class use
*/
public Comparator<Doc> makeComparatorForClassUse() {
return new Utils.DocComparator<Doc>() {
Compares two given Doc entities, first sort on name, and if
applicable on the fully qualified name, and if applicable
on the parameter types, and finally the DocKind.
Params: - d1 – - a Doc element.
- d2 – - a Doc element.
Returns: a negative integer, zero, or a positive integer as the first
argument is less than, equal to, or greater than the second.
/**
* Compares two given Doc entities, first sort on name, and if
* applicable on the fully qualified name, and if applicable
* on the parameter types, and finally the DocKind.
* @param d1 - a Doc element.
* @param d2 - a Doc element.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
public int compare(Doc d1, Doc d2) {
int result = compareNames(d1, d2);
if (result != 0) {
return result;
}
result = compareFullyQualifiedNames(d1, d2);
if (result != 0) {
return result;
}
if (hasParameters(d1) && hasParameters(d2)) {
Parameter[] param1 = ((ExecutableMemberDoc) d1).parameters();
Parameter[] param2 = ((ExecutableMemberDoc) d2).parameters();
result = compareParameters(false, param1, param2);
if (result != 0) {
return result;
}
return compareParameters(true, param1, param2);
}
return compareDocKinds(d1, d2);
}
};
}
A general purpose comparator to sort Doc entities, basically provides the building blocks
for creating specific comparators for an use-case.
Type parameters: - <T> – a Doc entity
/**
* A general purpose comparator to sort Doc entities, basically provides the building blocks
* for creating specific comparators for an use-case.
* @param <T> a Doc entity
*/
static abstract class DocComparator<T extends Doc> implements Comparator<Doc> {
static enum DocKind {
PACKAGE,
CLASS,
ENUM,
INTERFACE,
ANNOTATION,
FIELD,
CONSTRUCTOR,
METHOD
};
boolean hasParameters(Doc d) {
return d instanceof ExecutableMemberDoc;
}
DocKind getDocKind(Doc d) {
if (d.isAnnotationType() || d.isAnnotationTypeElement()) {
return DocKind.ANNOTATION;
} else if (d.isEnum() || d.isEnumConstant()) {
return DocKind.ENUM;
} else if (d.isField()) {
return DocKind.FIELD;
} else if (d.isInterface()) {
return DocKind.INTERFACE;
} else if (d.isClass()) {
return DocKind.CLASS;
} else if (d.isConstructor()) {
return DocKind.CONSTRUCTOR;
} else if (d.isMethod()) {
return DocKind.METHOD;
} else {
return DocKind.PACKAGE;
}
}
Compares two Doc entities' kinds, and these are ordered as defined in
the DocKind enumeration.
Params: - d1 – the first Doc object
- d2 – the second Doc object
Returns: a negative integer, zero, or a positive integer as the first
argument is less than, equal to, or greater than the second.
/**
* Compares two Doc entities' kinds, and these are ordered as defined in
* the DocKind enumeration.
* @param d1 the first Doc object
* @param d2 the second Doc object
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
protected int compareDocKinds(Doc d1, Doc d2) {
return getDocKind(d1).compareTo(getDocKind(d2));
}
Compares arrays of parameters as a string representation of their types.
Params: - ignoreCase – specifies case sensitive or insensitive comparison.
- params1 – the first parameter array.
- params2 – the first parameter array.
Returns: a negative integer, zero, or a positive integer as the first argument is less
than, equal to, or greater than the second.
/**
* Compares arrays of parameters as a string representation of their types.
*
* @param ignoreCase specifies case sensitive or insensitive comparison.
* @param params1 the first parameter array.
* @param params2 the first parameter array.
* @return a negative integer, zero, or a positive integer as the first argument is less
* than, equal to, or greater than the second.
*/
protected int compareParameters(boolean caseSensitive,
Parameter[] params1,
Parameter[] params2) {
String s1 = getParametersAsString(params1);
String s2 = getParametersAsString(params2);
return compareStrings(caseSensitive, s1, s2);
}
/*
* This method returns a string representation solely for comparison purposes.
*/
protected String getParametersAsString(Parameter[] params) {
StringBuilder sb = new StringBuilder();
for (Parameter param : params) {
Type t = param.type();
// add parameter type to arrays, as TypeMirror does.
String tname = (t.asParameterizedType() != null && t.getElementType() != null)
? t.getElementType() + t.dimension()
: t.toString();
// prefix P for primitive and R for reference types, thus items will
// be ordered naturally.
sb.append(t.isPrimitive() ? "P" : "R").append("-").append(tname).append("-");
}
return sb.toString();
}
Compares two Doc entities typically the simple name of a method,
field, constructor etc.
Params: - d1 – the first Doc.
- d2 – the second Doc.
Returns: a negative integer, zero, or a positive integer as the first
argument is less than, equal to, or greater than the second.
/**
* Compares two Doc entities typically the simple name of a method,
* field, constructor etc.
* @param d1 the first Doc.
* @param d2 the second Doc.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
protected int compareNames(Doc d1, Doc d2) {
return compareStrings(d1.name(), d2.name());
}
Compares the fully qualified names of the entities
Params: - d1 – the first entity
- d2 – the second entity
Returns: a negative integer, zero, or a positive integer as the first
argument is less than, equal to, or greater than the second.
/**
* Compares the fully qualified names of the entities
* @param d1 the first entity
* @param d2 the second entity
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
protected int compareFullyQualifiedNames(Doc d1, Doc d2) {
String name1 = (d1 instanceof ProgramElementDoc)
? ((ProgramElementDoc)d1).qualifiedName()
: d1.name();
String name2 = (d2 instanceof ProgramElementDoc)
? ((ProgramElementDoc)d2).qualifiedName()
: d2.name();
return compareStrings(name1, name2);
}
}
}