feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,284 @@
/*
* Copyright (c) 2001, 2012, 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.util.*;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.Configuration;
/**
* This class acts as an artificial PackageDoc for classes specified
* on the command line when running Javadoc. For example, if you
* specify several classes from package java.lang, this class will catalog
* those classes so that we can retrieve all of the classes from a particular
* package later.
*
* <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 Jamie Ho
* @since 1.4
*/
public class ClassDocCatalog {
/**
* Stores the set of packages that the classes specified on the command line
* belong to. Note that the default package is "".
*/
private Set<String> packageSet;
/**
* Stores all classes for each package
*/
private Map<String,Set<ClassDoc>> allClasses;
/**
* Stores ordinary classes (excluding Exceptions and Errors) for each
* package
*/
private Map<String,Set<ClassDoc>> ordinaryClasses;
/**
* Stores exceptions for each package
*/
private Map<String,Set<ClassDoc>> exceptions;
/**
* Stores enums for each package.
*/
private Map<String,Set<ClassDoc>> enums;
/**
* Stores annotation types for each package.
*/
private Map<String,Set<ClassDoc>> annotationTypes;
/**
* Stores errors for each package
*/
private Map<String,Set<ClassDoc>> errors;
/**
* Stores interfaces for each package
*/
private Map<String,Set<ClassDoc>> interfaces;
private Configuration configuration;
/**
* Construct a new ClassDocCatalog.
*
* @param classdocs the array of ClassDocs to catalog
*/
public ClassDocCatalog (ClassDoc[] classdocs, Configuration config) {
init();
this.configuration = config;
for (int i = 0; i < classdocs.length; i++) {
addClassDoc(classdocs[i]);
}
}
/**
* Construct a new ClassDocCatalog.
*
*/
public ClassDocCatalog () {
init();
}
private void init() {
allClasses = new HashMap<String,Set<ClassDoc>>();
ordinaryClasses = new HashMap<String,Set<ClassDoc>>();
exceptions = new HashMap<String,Set<ClassDoc>>();
enums = new HashMap<String,Set<ClassDoc>>();
annotationTypes = new HashMap<String,Set<ClassDoc>>();
errors = new HashMap<String,Set<ClassDoc>>();
interfaces = new HashMap<String,Set<ClassDoc>>();
packageSet = new HashSet<String>();
}
/**
* Add the given class to the catalog.
* @param classdoc the ClassDoc to add to the catelog.
*/
public void addClassDoc(ClassDoc classdoc) {
if (classdoc == null) {
return;
}
addClass(classdoc, allClasses);
if (classdoc.isOrdinaryClass()) {
addClass(classdoc, ordinaryClasses);
} else if (classdoc.isException()) {
addClass(classdoc, exceptions);
} else if (classdoc.isEnum()) {
addClass(classdoc, enums);
} else if (classdoc.isAnnotationType()) {
addClass(classdoc, annotationTypes);
} else if (classdoc.isError()) {
addClass(classdoc, errors);
} else if (classdoc.isInterface()) {
addClass(classdoc, interfaces);
}
}
/**
* Add the given class to the given map.
* @param classdoc the ClassDoc to add to the catelog.
* @param map the Map to add the ClassDoc to.
*/
private void addClass(ClassDoc classdoc, Map<String,Set<ClassDoc>> map) {
PackageDoc pkg = classdoc.containingPackage();
if (pkg.isIncluded() || (configuration.nodeprecated && Util.isDeprecated(pkg))) {
//No need to catalog this class if it's package is
//included on the command line or if -nodeprecated option is set
// and the containing package is marked as deprecated.
return;
}
String key = Util.getPackageName(pkg);
Set<ClassDoc> s = map.get(key);
if (s == null) {
packageSet.add(key);
s = new HashSet<ClassDoc>();
}
s.add(classdoc);
map.put(key, s);
}
private ClassDoc[] getArray(Map<String,Set<ClassDoc>> m, String key) {
Set<ClassDoc> s = m.get(key);
if (s == null) {
return new ClassDoc[] {};
} else {
return s.toArray(new ClassDoc[] {});
}
}
/**
* Return all of the classes specified on the command-line that
* belong to the given package.
* @param pkgDoc the package to return the classes for.
*/
public ClassDoc[] allClasses(PackageDoc pkgDoc) {
return pkgDoc.isIncluded() ?
pkgDoc.allClasses() :
getArray(allClasses, Util.getPackageName(pkgDoc));
}
/**
* Return all of the classes specified on the command-line that
* belong to the given package.
* @param packageName the name of the package specified on the
* command-line.
*/
public ClassDoc[] allClasses(String packageName) {
return getArray(allClasses, packageName);
}
/**
* Return the array of package names that this catalog stores
* ClassDocs for.
*/
public String[] packageNames() {
return packageSet.toArray(new String[] {});
}
/**
* Return true if the given package is known to this catalog.
* @param packageName the name to check.
* @return true if this catalog has any information about
* classes in the given package.
*/
public boolean isKnownPackage(String packageName) {
return packageSet.contains(packageName);
}
/**
* Return all of the errors specified on the command-line
* that belong to the given package.
* @param packageName the name of the package specified on the
* command-line.
*/
public ClassDoc[] errors(String packageName) {
return getArray(errors, packageName);
}
/**
* Return all of the exceptions specified on the command-line
* that belong to the given package.
* @param packageName the name of the package specified on the
* command-line.
*/
public ClassDoc[] exceptions(String packageName) {
return getArray(exceptions, packageName);
}
/**
* Return all of the enums specified on the command-line
* that belong to the given package.
* @param packageName the name of the package specified on the
* command-line.
*/
public ClassDoc[] enums(String packageName) {
return getArray(enums, packageName);
}
/**
* Return all of the annotation types specified on the command-line
* that belong to the given package.
* @param packageName the name of the package specified on the
* command-line.
*/
public ClassDoc[] annotationTypes(String packageName) {
return getArray(annotationTypes, packageName);
}
/**
* Return all of the interfaces specified on the command-line
* that belong to the given package.
* @param packageName the name of the package specified on the
* command-line.
*/
public ClassDoc[] interfaces(String packageName) {
return getArray(interfaces, packageName);
}
/**
* Return all of the ordinary classes specified on the command-line
* that belong to the given package.
* @param packageName the name of the package specified on the
* command-line.
*/
public ClassDoc[] ordinaryClasses(String packageName) {
return getArray(ordinaryClasses, packageName);
}
}

View File

@@ -0,0 +1,387 @@
/*
* Copyright (c) 1998, 2013, 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.util.*;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*;
/**
* Build Class Hierarchy for all the Classes. This class builds the Class
* Tree and the Interface Tree separately.
*
* <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>
*
* @see java.util.HashMap
* @see java.util.List
* @see com.sun.javadoc.Type
* @see com.sun.javadoc.ClassDoc
* @author Atul M Dambalkar
*/
public class ClassTree {
/**
* List of baseclasses. Contains only java.lang.Object. Can be used to get
* the mapped listing of sub-classes.
*/
private List<ClassDoc> baseclasses = new ArrayList<ClassDoc>();
/**
* Mapping for each Class with their SubClasses
*/
private Map<ClassDoc,List<ClassDoc>> subclasses = new HashMap<ClassDoc,List<ClassDoc>>();
/**
* List of base-interfaces. Contains list of all the interfaces who do not
* have super-interfaces. Can be used to get the mapped listing of
* sub-interfaces.
*/
private List<ClassDoc> baseinterfaces = new ArrayList<ClassDoc>();
/**
* Mapping for each Interface with their SubInterfaces
*/
private Map<ClassDoc,List<ClassDoc>> subinterfaces = new HashMap<ClassDoc,List<ClassDoc>>();
private List<ClassDoc> baseEnums = new ArrayList<ClassDoc>();
private Map<ClassDoc,List<ClassDoc>> subEnums = new HashMap<ClassDoc,List<ClassDoc>>();
private List<ClassDoc> baseAnnotationTypes = new ArrayList<ClassDoc>();
private Map<ClassDoc,List<ClassDoc>> subAnnotationTypes = new HashMap<ClassDoc,List<ClassDoc>>();
/**
* Mapping for each Interface with classes who implement it.
*/
private Map<ClassDoc,List<ClassDoc>> implementingclasses = new HashMap<ClassDoc,List<ClassDoc>>();
/**
* Constructor. Build the Tree using the Root of this Javadoc run.
*
* @param configuration the configuration of the doclet.
* @param noDeprecated Don't add deprecated classes in the class tree, if
* true.
*/
public ClassTree(Configuration configuration, boolean noDeprecated) {
configuration.message.notice("doclet.Building_Tree");
buildTree(configuration.root.classes(), configuration);
}
/**
* Constructor. Build the Tree using the Root of this Javadoc run.
*
* @param root Root of the Document.
* @param configuration The curren configuration of the doclet.
*/
public ClassTree(RootDoc root, Configuration configuration) {
buildTree(root.classes(), configuration);
}
/**
* Constructor. Build the tree for the given array of classes.
*
* @param classes Array of classes.
* @param configuration The curren configuration of the doclet.
*/
public ClassTree(ClassDoc[] classes, Configuration configuration) {
buildTree(classes, configuration);
}
/**
* Generate mapping for the sub-classes for every class in this run.
* Return the sub-class list for java.lang.Object which will be having
* sub-class listing for itself and also for each sub-class itself will
* have their own sub-class lists.
*
* @param classes all the classes in this run.
* @param configuration the current configuration of the doclet.
*/
private void buildTree(ClassDoc[] classes, Configuration configuration) {
for (int i = 0; i < classes.length; i++) {
// In the tree page (e.g overview-tree.html) do not include
// information of classes which are deprecated or are a part of a
// deprecated package.
if (configuration.nodeprecated &&
(Util.isDeprecated(classes[i]) ||
Util.isDeprecated(classes[i].containingPackage()))) {
continue;
}
if (configuration.javafx
&& classes[i].tags("treatAsPrivate").length > 0) {
continue;
}
if (classes[i].isEnum()) {
processType(classes[i], configuration, baseEnums, subEnums);
} else if (classes[i].isClass()) {
processType(classes[i], configuration, baseclasses, subclasses);
} else if (classes[i].isInterface()) {
processInterface(classes[i]);
List<ClassDoc> list = implementingclasses.get(classes[i]);
if (list != null) {
Collections.sort(list);
}
} else if (classes[i].isAnnotationType()) {
processType(classes[i], configuration, baseAnnotationTypes,
subAnnotationTypes);
}
}
Collections.sort(baseinterfaces);
for (Iterator<List<ClassDoc>> it = subinterfaces.values().iterator(); it.hasNext(); ) {
Collections.sort(it.next());
}
for (Iterator<List<ClassDoc>> it = subclasses.values().iterator(); it.hasNext(); ) {
Collections.sort(it.next());
}
}
/**
* For the class passed map it to it's own sub-class listing.
* For the Class passed, get the super class,
* if superclass is non null, (it is not "java.lang.Object")
* get the "value" from the hashmap for this key Class
* if entry not found create one and get that.
* add this Class as a sub class in the list
* Recurse till hits java.lang.Object Null SuperClass.
*
* @param cd class for which sub-class mapping to be generated.
* @param configuration the current configurtation of the doclet.
*/
private void processType(ClassDoc cd, Configuration configuration,
List<ClassDoc> bases, Map<ClassDoc,List<ClassDoc>> subs) {
ClassDoc superclass = Util.getFirstVisibleSuperClassCD(cd, configuration);
if (superclass != null) {
if (!add(subs, superclass, cd)) {
return;
} else {
processType(superclass, configuration, bases, subs);
}
} else { // cd is java.lang.Object, add it once to the list
if (!bases.contains(cd)) {
bases.add(cd);
}
}
List<Type> intfacs = Util.getAllInterfaces(cd, configuration);
for (Iterator<Type> iter = intfacs.iterator(); iter.hasNext();) {
add(implementingclasses, iter.next().asClassDoc(), cd);
}
}
/**
* For the interface passed get the interfaces which it extends, and then
* put this interface in the sub-interface list of those interfaces. Do it
* recursively. If a interface doesn't have super-interface just attach
* that interface in the list of all the baseinterfaces.
*
* @param cd Interface under consideration.
*/
private void processInterface(ClassDoc cd) {
ClassDoc[] intfacs = cd.interfaces();
if (intfacs.length > 0) {
for (int i = 0; i < intfacs.length; i++) {
if (!add(subinterfaces, intfacs[i], cd)) {
return;
} else {
processInterface(intfacs[i]); // Recurse
}
}
} else {
// we need to add all the interfaces who do not have
// super-interfaces to baseinterfaces list to traverse them
if (!baseinterfaces.contains(cd)) {
baseinterfaces.add(cd);
}
}
}
/**
* Adjust the Class Tree. Add the class interface in to it's super-class'
* or super-interface's sub-interface list.
*
* @param map the entire map.
* @param superclass java.lang.Object or the super-interface.
* @param cd sub-interface to be mapped.
* @returns boolean true if class added, false if class already processed.
*/
private boolean add(Map<ClassDoc,List<ClassDoc>> map, ClassDoc superclass, ClassDoc cd) {
List<ClassDoc> list = map.get(superclass);
if (list == null) {
list = new ArrayList<ClassDoc>();
map.put(superclass, list);
}
if (list.contains(cd)) {
return false;
} else {
list.add(cd);
}
return true;
}
/**
* From the map return the list of sub-classes or sub-interfaces. If list
* is null create a new one and return it.
*
* @param map The entire map.
* @param cd class for which the sub-class list is requested.
* @returns List Sub-Class list for the class passed.
*/
private List<ClassDoc> get(Map<ClassDoc,List<ClassDoc>> map, ClassDoc cd) {
List<ClassDoc> list = map.get(cd);
if (list == null) {
return new ArrayList<ClassDoc>();
}
return list;
}
/**
* Return the sub-class list for the class passed.
*
* @param cd class whose sub-class list is required.
*/
public List<ClassDoc> subclasses(ClassDoc cd) {
return get(subclasses, cd);
}
/**
* Return the sub-interface list for the interface passed.
*
* @param cd interface whose sub-interface list is required.
*/
public List<ClassDoc> subinterfaces(ClassDoc cd) {
return get(subinterfaces, cd);
}
/**
* Return the list of classes which implement the interface passed.
*
* @param cd interface whose implementing-classes list is required.
*/
public List<ClassDoc> implementingclasses(ClassDoc cd) {
List<ClassDoc> result = get(implementingclasses, cd);
List<ClassDoc> subinterfaces = allSubs(cd, false);
//If class x implements a subinterface of cd, then it follows
//that class x implements cd.
Iterator<ClassDoc> implementingClassesIter, subInterfacesIter = subinterfaces.listIterator();
ClassDoc c;
while(subInterfacesIter.hasNext()){
implementingClassesIter = implementingclasses(
subInterfacesIter.next()).listIterator();
while(implementingClassesIter.hasNext()){
c = implementingClassesIter.next();
if(! result.contains(c)){
result.add(c);
}
}
}
Collections.sort(result);
return result;
}
/**
* Return the sub-class/interface list for the class/interface passed.
*
* @param cd class/interface whose sub-class/interface list is required.
* @param isEnum true if the subclasses should be forced to come from the
* enum tree.
*/
public List<ClassDoc> subs(ClassDoc cd, boolean isEnum) {
if (isEnum) {
return get(subEnums, cd);
} else if (cd.isAnnotationType()) {
return get(subAnnotationTypes, cd);
} else if (cd.isInterface()) {
return get(subinterfaces, cd);
} else if (cd.isClass()) {
return get(subclasses, cd);
} else {
return null;
}
}
/**
* Return a list of all direct or indirect, sub-classes and subinterfaces
* of the ClassDoc argument.
*
* @param cd ClassDoc whose sub-classes or sub-interfaces are requested.
* @param isEnum true if the subclasses should be forced to come from the
* enum tree.
*/
public List<ClassDoc> allSubs(ClassDoc cd, boolean isEnum) {
List<ClassDoc> list = subs(cd, isEnum);
for (int i = 0; i < list.size(); i++) {
cd = list.get(i);
List<ClassDoc> tlist = subs(cd, isEnum);
for (int j = 0; j < tlist.size(); j++) {
ClassDoc tcd = tlist.get(j);
if (!list.contains(tcd)) {
list.add(tcd);
}
}
}
Collections.sort(list);
return list;
}
/**
* Return the base-classes list. This will have only one element namely
* thw classdoc for java.lang.Object, since this is the base class for all
* classes.
*/
public List<ClassDoc> baseclasses() {
return baseclasses;
}
/**
* Return the list of base interfaces. This is the list of interfaces
* which do not have super-interface.
*/
public List<ClassDoc> baseinterfaces() {
return baseinterfaces;
}
/**
* Return the list of base enums. This is the list of enums
* which do not have super-enums.
*/
public List<ClassDoc> baseEnums() {
return baseEnums;
}
/**
* Return the list of base annotation types. This is the list of
* annotation types which do not have super-annotation types.
*/
public List<ClassDoc> baseAnnotationTypes() {
return baseAnnotationTypes;
}
}

View File

@@ -0,0 +1,494 @@
/*
* Copyright (c) 1998, 2013, 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.util.*;
import com.sun.javadoc.*;
/**
* Map all class uses for a given class.
*
* <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>
*
* @since 1.2
* @author Robert G. Field
*/
public class ClassUseMapper {
private final ClassTree classtree;
/**
* Mapping of ClassDocs to set of PackageDoc used by that class.
* Entries may be null.
*/
public Map<String,Set<PackageDoc>> classToPackage = new HashMap<String,Set<PackageDoc>>();
/**
* Mapping of Annotations to set of PackageDoc that use the annotation.
*/
public Map<String,List<PackageDoc>> classToPackageAnnotations = new HashMap<String,List<PackageDoc>>();
/**
* Mapping of ClassDocs to set of ClassDoc used by that class.
* Entries may be null.
*/
public Map<String,Set<ClassDoc>> classToClass = new HashMap<String,Set<ClassDoc>>();
/**
* Mapping of ClassDocs to list of ClassDoc which are direct or
* indirect subclasses of that class.
* Entries may be null.
*/
public Map<String,List<ClassDoc>> classToSubclass = new HashMap<String,List<ClassDoc>>();
/**
* Mapping of ClassDocs to list of ClassDoc which are direct or
* indirect subinterfaces of that interface.
* Entries may be null.
*/
public Map<String,List<ClassDoc>> classToSubinterface = new HashMap<String,List<ClassDoc>>();
/**
* Mapping of ClassDocs to list of ClassDoc which implement
* this interface.
* Entries may be null.
*/
public Map<String,List<ClassDoc>> classToImplementingClass = new HashMap<String,List<ClassDoc>>();
/**
* Mapping of ClassDocs to list of FieldDoc declared as that class.
* Entries may be null.
*/
public Map<String,List<FieldDoc>> classToField = new HashMap<String,List<FieldDoc>>();
/**
* Mapping of ClassDocs to list of MethodDoc returning that class.
* Entries may be null.
*/
public Map<String,List<MethodDoc>> classToMethodReturn = new HashMap<String,List<MethodDoc>>();
/**
* Mapping of ClassDocs to list of MethodDoc having that class
* as an arg.
* Entries may be null.
*/
public Map<String,List<ExecutableMemberDoc>> classToMethodArgs = new HashMap<String,List<ExecutableMemberDoc>>();
/**
* Mapping of ClassDocs to list of MethodDoc which throws that class.
* Entries may be null.
*/
public Map<String,List<ExecutableMemberDoc>> classToMethodThrows = new HashMap<String,List<ExecutableMemberDoc>>();
/**
* Mapping of ClassDocs to list of ConstructorDoc having that class
* as an arg.
* Entries may be null.
*/
public Map<String,List<ExecutableMemberDoc>> classToConstructorArgs = new HashMap<String,List<ExecutableMemberDoc>>();
/**
* Mapping of ClassDocs to list of ConstructorDoc which throws that class.
* Entries may be null.
*/
public Map<String,List<ExecutableMemberDoc>> classToConstructorThrows = new HashMap<String,List<ExecutableMemberDoc>>();
/**
* The mapping of AnnotationTypeDocs to constructors that use them.
*/
public Map<String,List<ConstructorDoc>> classToConstructorAnnotations = new HashMap<String,List<ConstructorDoc>>();
/**
* The mapping of AnnotationTypeDocs to Constructor parameters that use them.
*/
public Map<String,List<ExecutableMemberDoc>> classToConstructorParamAnnotation = new HashMap<String,List<ExecutableMemberDoc>>();
/**
* The mapping of ClassDocs to Constructor arguments that use them as type parameters.
*/
public Map<String,List<ExecutableMemberDoc>> classToConstructorDocArgTypeParam = new HashMap<String,List<ExecutableMemberDoc>>();
/**
* The mapping of ClassDocs to ClassDocs that use them as type parameters.
*/
public Map<String,List<ClassDoc>> classToClassTypeParam = new HashMap<String,List<ClassDoc>>();
/**
* The mapping of AnnotationTypeDocs to ClassDocs that use them.
*/
public Map<String,List<ClassDoc>> classToClassAnnotations = new HashMap<String,List<ClassDoc>>();
/**
* The mapping of ClassDocs to ExecutableMemberDocs that use them as type parameters.
*/
public Map<String,List<MethodDoc>> classToExecMemberDocTypeParam = new HashMap<String,List<MethodDoc>>();
/**
* The mapping of ClassDocs to ExecutableMemberDocs arguments that use them as type parameters.
*/
public Map<String,List<ExecutableMemberDoc>> classToExecMemberDocArgTypeParam = new HashMap<String,List<ExecutableMemberDoc>>();
/**
* The mapping of AnnotationTypeDocs to ExecutableMemberDocs that use them.
*/
public Map<String,List<MethodDoc>> classToExecMemberDocAnnotations = new HashMap<String,List<MethodDoc>>();
/**
* The mapping of ClassDocs to ExecutableMemberDocs that have return type
* with type parameters of that class.
*/
public Map<String,List<MethodDoc>> classToExecMemberDocReturnTypeParam = new HashMap<String,List<MethodDoc>>();
/**
* The mapping of AnnotationTypeDocs to MethodDoc parameters that use them.
*/
public Map<String,List<ExecutableMemberDoc>> classToExecMemberDocParamAnnotation = new HashMap<String,List<ExecutableMemberDoc>>();
/**
* The mapping of ClassDocs to FieldDocs that use them as type parameters.
*/
public Map<String,List<FieldDoc>> classToFieldDocTypeParam = new HashMap<String,List<FieldDoc>>();
/**
* The mapping of AnnotationTypeDocs to FieldDocs that use them.
*/
public Map<String,List<FieldDoc>> annotationToFieldDoc = new HashMap<String,List<FieldDoc>>();
public ClassUseMapper(RootDoc root, ClassTree classtree) {
this.classtree = classtree;
// Map subclassing, subinterfacing implementing, ...
for (Iterator<ClassDoc> it = classtree.baseclasses().iterator(); it.hasNext();) {
subclasses(it.next());
}
for (Iterator<ClassDoc> it = classtree.baseinterfaces().iterator(); it.hasNext();) {
// does subinterfacing as side-effect
implementingClasses(it.next());
}
// Map methods, fields, constructors using a class.
ClassDoc[] classes = root.classes();
for (int i = 0; i < classes.length; i++) {
PackageDoc pkg = classes[i].containingPackage();
mapAnnotations(classToPackageAnnotations, pkg, pkg);
ClassDoc cd = classes[i];
mapTypeParameters(classToClassTypeParam, cd, cd);
mapAnnotations(classToClassAnnotations, cd, cd);
FieldDoc[] fields = cd.fields();
for (int j = 0; j < fields.length; j++) {
FieldDoc fd = fields[j];
mapTypeParameters(classToFieldDocTypeParam, fd, fd);
mapAnnotations(annotationToFieldDoc, fd, fd);
if (! fd.type().isPrimitive()) {
add(classToField, fd.type().asClassDoc(), fd);
}
}
ConstructorDoc[] cons = cd.constructors();
for (int j = 0; j < cons.length; j++) {
mapAnnotations(classToConstructorAnnotations, cons[j], cons[j]);
mapExecutable(cons[j]);
}
MethodDoc[] meths = cd.methods();
for (int j = 0; j < meths.length; j++) {
MethodDoc md = meths[j];
mapExecutable(md);
mapTypeParameters(classToExecMemberDocTypeParam, md, md);
mapAnnotations(classToExecMemberDocAnnotations, md, md);
if (! (md.returnType().isPrimitive() || md.returnType() instanceof TypeVariable)) {
mapTypeParameters(classToExecMemberDocReturnTypeParam,
md.returnType(), md);
add(classToMethodReturn, md.returnType().asClassDoc(), md);
}
}
}
}
/**
* Return all subclasses of a class AND fill-in classToSubclass map.
*/
private Collection<ClassDoc> subclasses(ClassDoc cd) {
Collection<ClassDoc> ret = classToSubclass.get(cd.qualifiedName());
if (ret == null) {
ret = new TreeSet<ClassDoc>();
List<ClassDoc> subs = classtree.subclasses(cd);
if (subs != null) {
ret.addAll(subs);
for (Iterator<ClassDoc> it = subs.iterator(); it.hasNext();) {
ret.addAll(subclasses(it.next()));
}
}
addAll(classToSubclass, cd, ret);
}
return ret;
}
/**
* Return all subinterfaces of an interface AND fill-in classToSubinterface map.
*/
private Collection<ClassDoc> subinterfaces(ClassDoc cd) {
Collection<ClassDoc> ret = classToSubinterface.get(cd.qualifiedName());
if (ret == null) {
ret = new TreeSet<ClassDoc>();
List<ClassDoc> subs = classtree.subinterfaces(cd);
if (subs != null) {
ret.addAll(subs);
for (Iterator<ClassDoc> it = subs.iterator(); it.hasNext();) {
ret.addAll(subinterfaces(it.next()));
}
}
addAll(classToSubinterface, cd, ret);
}
return ret;
}
/**
* Return all implementing classes of an interface (including
* all subclasses of implementing classes and all classes
* implementing subinterfaces) AND fill-in both classToImplementingClass
* and classToSubinterface maps.
*/
private Collection<ClassDoc> implementingClasses(ClassDoc cd) {
Collection<ClassDoc> ret = classToImplementingClass.get(cd.qualifiedName());
if (ret == null) {
ret = new TreeSet<ClassDoc>();
List<ClassDoc> impl = classtree.implementingclasses(cd);
if (impl != null) {
ret.addAll(impl);
for (Iterator<ClassDoc> it = impl.iterator(); it.hasNext();) {
ret.addAll(subclasses(it.next()));
}
}
for (Iterator<ClassDoc> it = subinterfaces(cd).iterator(); it.hasNext();) {
ret.addAll(implementingClasses(it.next()));
}
addAll(classToImplementingClass, cd, ret);
}
return ret;
}
/**
* Determine classes used by a method or constructor, so they can be
* inverse mapped.
*/
private void mapExecutable(ExecutableMemberDoc em) {
Parameter[] params = em.parameters();
boolean isConstructor = em.isConstructor();
List<Type> classArgs = new ArrayList<Type>();
for (int k = 0; k < params.length; k++) {
Type pcd = params[k].type();
// primitives don't get mapped, also avoid dups
if ((! params[k].type().isPrimitive()) &&
! classArgs.contains(pcd) &&
! (pcd instanceof TypeVariable)) {
add(isConstructor? classToConstructorArgs :classToMethodArgs,
pcd.asClassDoc(), em);
classArgs.add(pcd);
mapTypeParameters(isConstructor?
classToConstructorDocArgTypeParam : classToExecMemberDocArgTypeParam,
pcd, em);
}
mapAnnotations(
isConstructor ?
classToConstructorParamAnnotation :
classToExecMemberDocParamAnnotation,
params[k], em);
}
ClassDoc[] thr = em.thrownExceptions();
for (int k = 0; k < thr.length; k++) {
add(isConstructor? classToConstructorThrows : classToMethodThrows,
thr[k], em);
}
}
private <T> List<T> refList(Map<String,List<T>> map, ClassDoc cd) {
List<T> list = map.get(cd.qualifiedName());
if (list == null) {
List<T> l = new ArrayList<T>();
list = l;
map.put(cd.qualifiedName(), list);
}
return list;
}
private Set<PackageDoc> packageSet(ClassDoc cd) {
Set<PackageDoc> pkgSet = classToPackage.get(cd.qualifiedName());
if (pkgSet == null) {
pkgSet = new TreeSet<PackageDoc>();
classToPackage.put(cd.qualifiedName(), pkgSet);
}
return pkgSet;
}
private Set<ClassDoc> classSet(ClassDoc cd) {
Set<ClassDoc> clsSet = classToClass.get(cd.qualifiedName());
if (clsSet == null) {
Set<ClassDoc> s = new TreeSet<ClassDoc>();
clsSet = s;
classToClass.put(cd.qualifiedName(), clsSet);
}
return clsSet;
}
private <T extends ProgramElementDoc> void add(Map<String,List<T>> map, ClassDoc cd, T ref) {
// add to specified map
refList(map, cd).add(ref);
// add ref's package to package map and class map
packageSet(cd).add(ref.containingPackage());
classSet(cd).add(ref instanceof MemberDoc?
((MemberDoc)ref).containingClass() :
(ClassDoc)ref);
}
private void addAll(Map<String,List<ClassDoc>> map, ClassDoc cd, Collection<ClassDoc> refs) {
if (refs == null) {
return;
}
// add to specified map
refList(map, cd).addAll(refs);
Set<PackageDoc> pkgSet = packageSet(cd);
Set<ClassDoc> clsSet = classSet(cd);
// add ref's package to package map and class map
for (Iterator<ClassDoc> it = refs.iterator(); it.hasNext();) {
ClassDoc cls = it.next();
pkgSet.add(cls.containingPackage());
clsSet.add(cls);
}
}
/**
* Map the ClassDocs to the ProgramElementDocs that use them as
* type parameters.
*
* @param map the map the insert the information into.
* @param doc the doc whose type parameters are being checked.
* @param holder the holder that owns the type parameters.
*/
private <T extends ProgramElementDoc> void mapTypeParameters(Map<String,List<T>> map, Object doc,
T holder) {
TypeVariable[] typeVariables;
if (doc instanceof ClassDoc) {
typeVariables = ((ClassDoc) doc).typeParameters();
} else if (doc instanceof WildcardType) {
Type[] extendsBounds = ((WildcardType) doc).extendsBounds();
for (int k = 0; k < extendsBounds.length; k++) {
addTypeParameterToMap(map, extendsBounds[k], holder);
}
Type[] superBounds = ((WildcardType) doc).superBounds();
for (int k = 0; k < superBounds.length; k++) {
addTypeParameterToMap(map, superBounds[k], holder);
}
return;
} else if (doc instanceof ParameterizedType) {
Type[] typeArguments = ((ParameterizedType) doc).typeArguments();
for (int k = 0; k < typeArguments.length; k++) {
addTypeParameterToMap(map, typeArguments[k], holder);
}
return;
} else if (doc instanceof ExecutableMemberDoc) {
typeVariables = ((ExecutableMemberDoc) doc).typeParameters();
} else if (doc instanceof FieldDoc) {
Type fieldType = ((FieldDoc) doc).type();
mapTypeParameters(map, fieldType, holder);
return;
} else {
return;
}
for (int i = 0; i < typeVariables.length; i++) {
Type[] bounds = typeVariables[i].bounds();
for (int j = 0; j < bounds.length; j++) {
addTypeParameterToMap(map, bounds[j], holder);
}
}
}
/**
* Map the AnnotationType to the ProgramElementDocs that use them as
* type parameters.
*
* @param map the map the insert the information into.
* @param doc the doc whose type parameters are being checked.
* @param holder the holder that owns the type parameters.
*/
private <T extends ProgramElementDoc> void mapAnnotations(Map<String,List<T>> map, Object doc,
T holder) {
AnnotationDesc[] annotations;
boolean isPackage = false;
if (doc instanceof ProgramElementDoc) {
annotations = ((ProgramElementDoc) doc).annotations();
} else if (doc instanceof PackageDoc) {
annotations = ((PackageDoc) doc).annotations();
isPackage = true;
} else if (doc instanceof Parameter) {
annotations = ((Parameter) doc).annotations();
} else {
throw new DocletAbortException("should not happen");
}
for (int i = 0; i < annotations.length; i++) {
AnnotationTypeDoc annotationDoc = annotations[i].annotationType();
if (isPackage)
refList(map, annotationDoc).add(holder);
else
add(map, annotationDoc, holder);
}
}
/**
* Map the AnnotationType to the ProgramElementDocs that use them as
* type parameters.
*
* @param map the map the insert the information into.
* @param doc the doc whose type parameters are being checked.
* @param holder the holder that owns the type parameters.
*/
private <T extends PackageDoc> void mapAnnotations(Map<String,List<T>> map, PackageDoc doc,
T holder) {
AnnotationDesc[] annotations;
annotations = doc.annotations();
for (int i = 0; i < annotations.length; i++) {
AnnotationTypeDoc annotationDoc = annotations[i].annotationType();
refList(map, annotationDoc).add(holder);
}
}
private <T extends ProgramElementDoc> void addTypeParameterToMap(Map<String,List<T>> map, Type type,
T holder) {
if (type instanceof ClassDoc) {
add(map, (ClassDoc) type, holder);
} else if (type instanceof ParameterizedType) {
add(map, ((ParameterizedType) type).asClassDoc(), holder);
}
mapTypeParameters(map, type, holder);
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 1999, 2012, 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 com.sun.javadoc.*;
/**
* Find a commented method.
*
* <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>
*
*/
public class CommentedMethodFinder extends MethodFinder {
public boolean isCorrectMethod(MethodDoc method) {
return method.inlineTags().length > 0;
}
}

View File

@@ -0,0 +1,168 @@
/*
* Copyright (c) 1998, 2012, 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.util.*;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.Configuration;
/**
* Build list of all the deprecated packages, classes, constructors, fields and methods.
*
* <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
*/
public class DeprecatedAPIListBuilder {
public static final int NUM_TYPES = 12;
public static final int PACKAGE = 0;
public static final int INTERFACE = 1;
public static final int CLASS = 2;
public static final int ENUM = 3;
public static final int EXCEPTION = 4;
public static final int ERROR = 5;
public static final int ANNOTATION_TYPE = 6;
public static final int FIELD = 7;
public static final int METHOD = 8;
public static final int CONSTRUCTOR = 9;
public static final int ENUM_CONSTANT = 10;
public static final int ANNOTATION_TYPE_MEMBER = 11;
/**
* List of deprecated type Lists.
*/
private List<List<Doc>> deprecatedLists;
/**
* Constructor.
*
* @param configuration the current configuration of the doclet
*/
public DeprecatedAPIListBuilder(Configuration configuration) {
deprecatedLists = new ArrayList<List<Doc>>();
for (int i = 0; i < NUM_TYPES; i++) {
deprecatedLists.add(i, new ArrayList<Doc>());
}
buildDeprecatedAPIInfo(configuration);
}
/**
* Build the sorted list of all the deprecated APIs in this run.
* Build separate lists for deprecated packages, classes, constructors,
* methods and fields.
*
* @param configuration the current configuration of the doclet.
*/
private void buildDeprecatedAPIInfo(Configuration configuration) {
PackageDoc[] packages = configuration.packages;
PackageDoc pkg;
for (int c = 0; c < packages.length; c++) {
pkg = packages[c];
if (Util.isDeprecated(pkg)) {
getList(PACKAGE).add(pkg);
}
}
ClassDoc[] classes = configuration.root.classes();
for (int i = 0; i < classes.length; i++) {
ClassDoc cd = classes[i];
if (Util.isDeprecated(cd)) {
if (cd.isOrdinaryClass()) {
getList(CLASS).add(cd);
} else if (cd.isInterface()) {
getList(INTERFACE).add(cd);
} else if (cd.isException()) {
getList(EXCEPTION).add(cd);
} else if (cd.isEnum()) {
getList(ENUM).add(cd);
} else if (cd.isError()) {
getList(ERROR).add(cd);
} else if (cd.isAnnotationType()) {
getList(ANNOTATION_TYPE).add(cd);
}
}
composeDeprecatedList(getList(FIELD), cd.fields());
composeDeprecatedList(getList(METHOD), cd.methods());
composeDeprecatedList(getList(CONSTRUCTOR), cd.constructors());
if (cd.isEnum()) {
composeDeprecatedList(getList(ENUM_CONSTANT), cd.enumConstants());
}
if (cd.isAnnotationType()) {
composeDeprecatedList(getList(ANNOTATION_TYPE_MEMBER),
((AnnotationTypeDoc) cd).elements());
}
}
sortDeprecatedLists();
}
/**
* Add the members into a single list of deprecated members.
*
* @param list List of all the particular deprecated members, e.g. methods.
* @param members members to be added in the list.
*/
private void composeDeprecatedList(List<Doc> list, MemberDoc[] members) {
for (int i = 0; i < members.length; i++) {
if (Util.isDeprecated(members[i])) {
list.add(members[i]);
}
}
}
/**
* Sort the deprecated lists for class kinds, fields, methods and
* constructors.
*/
private void sortDeprecatedLists() {
for (int i = 0; i < NUM_TYPES; i++) {
Collections.sort(getList(i));
}
}
/**
* Return the list of deprecated Doc objects of a given type.
*
* @param type the constant representing the type of list being returned.
*/
public List<Doc> getList(int type) {
return deprecatedLists.get(type);
}
/**
* Return true if the list of a given type has size greater than 0.
*
* @param type the type of list being checked.
*/
public boolean hasDocumentation(int type) {
return (deprecatedLists.get(type)).size() > 0;
}
}

View File

@@ -0,0 +1,259 @@
/*
* Copyright (c) 1998, 2013, 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.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import javax.tools.JavaFileManager.Location;
import javax.tools.StandardLocation;
import com.sun.tools.doclets.internal.toolkit.Configuration;
/**
* Abstraction for handling files, which may be specified directly
* (e.g. via a path on the command line) or relative to a Location.
*
* <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>
*
* @since 8
*/
public abstract class DocFile {
/** Create a DocFile for a directory. */
public static DocFile createFileForDirectory(Configuration configuration, String file) {
return DocFileFactory.getFactory(configuration).createFileForDirectory(file);
}
/** Create a DocFile for a file that will be opened for reading. */
public static DocFile createFileForInput(Configuration configuration, String file) {
return DocFileFactory.getFactory(configuration).createFileForInput(file);
}
/** Create a DocFile for a file that will be opened for writing. */
public static DocFile createFileForOutput(Configuration configuration, DocPath path) {
return DocFileFactory.getFactory(configuration).createFileForOutput(path);
}
private final Configuration configuration;
/**
* The location for this file. Maybe null if the file was created without
* a location or path.
*/
protected final Location location;
/**
* The path relative to the (output) location. Maybe null if the file was
* created without a location or path.
*/
protected final DocPath path;
/**
* List the directories and files found in subdirectories along the
* elements of the given location.
* @param configuration the doclet configuration
* @param location currently, only {@link StandardLocation#SOURCE_PATH} is supported.
* @param path the subdirectory of the directories of the location for which to
* list files
*/
public static Iterable<DocFile> list(Configuration configuration, Location location, DocPath path) {
return DocFileFactory.getFactory(configuration).list(location, path);
}
/** Create a DocFile without a location or path */
protected DocFile(Configuration configuration) {
this.configuration = configuration;
this.location = null;
this.path = null;
}
/** Create a DocFile for a given location and relative path. */
protected DocFile(Configuration configuration, Location location, DocPath path) {
this.configuration = configuration;
this.location = location;
this.path = path;
}
/** Open an input stream for the file. */
public abstract InputStream openInputStream() throws IOException;
/**
* Open an output stream for the file.
* The file must have been created with a location of
* {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT}
* and a corresponding relative path.
*/
public abstract OutputStream openOutputStream() throws IOException, UnsupportedEncodingException;
/**
* Open an writer for the file, using the encoding (if any) given in the
* doclet configuration.
* The file must have been created with a location of
* {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
*/
public abstract Writer openWriter() throws IOException, UnsupportedEncodingException;
/**
* Copy the contents of another file directly to this file.
*/
public void copyFile(DocFile fromFile) throws IOException {
InputStream input = fromFile.openInputStream();
OutputStream output = openOutputStream();
try {
byte[] bytearr = new byte[1024];
int len;
while ((len = input.read(bytearr)) != -1) {
output.write(bytearr, 0, len);
}
} catch (FileNotFoundException exc) {
} catch (SecurityException exc) {
} finally {
input.close();
output.close();
}
}
/**
* Copy the contents of a resource file to this file.
* @param resource the path of the resource, relative to the package of this class
* @param overwrite whether or not to overwrite the file if it already exists
* @param replaceNewLine if false, the file is copied as a binary file;
* if true, the file is written line by line, using the platform line
* separator
*/
public void copyResource(DocPath resource, boolean overwrite, boolean replaceNewLine) {
if (exists() && !overwrite)
return;
try {
InputStream in = Configuration.class.getResourceAsStream(resource.getPath());
if (in == null)
return;
OutputStream out = openOutputStream();
try {
if (!replaceNewLine) {
byte[] buf = new byte[2048];
int n;
while((n = in.read(buf))>0) out.write(buf,0,n);
} else {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
BufferedWriter writer;
if (configuration.docencoding == null) {
writer = new BufferedWriter(new OutputStreamWriter(out));
} else {
writer = new BufferedWriter(new OutputStreamWriter(out,
configuration.docencoding));
}
try {
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.write(DocletConstants.NL);
}
} finally {
reader.close();
writer.close();
}
}
} finally {
in.close();
out.close();
}
} catch (IOException e) {
e.printStackTrace(System.err);
throw new DocletAbortException(e);
}
}
/** Return true if the file can be read. */
public abstract boolean canRead();
/** Return true if the file can be written. */
public abstract boolean canWrite();
/** Return true if the file exists. */
public abstract boolean exists();
/** Return the base name (last component) of the file name. */
public abstract String getName();
/** Return the file system path for this file. */
public abstract String getPath();
/** Return true if file has an absolute path name. */
public abstract boolean isAbsolute();
/** Return true if file identifies a directory. */
public abstract boolean isDirectory();
/** Return true if file identifies a file. */
public abstract boolean isFile();
/** Return true if this file is the same as another. */
public abstract boolean isSameFile(DocFile other);
/** If the file is a directory, list its contents. */
public abstract Iterable<DocFile> list() throws IOException;
/** Create the file as a directory, including any parent directories. */
public abstract boolean mkdirs();
/**
* Derive a new file by resolving a relative path against this file.
* The new file will inherit the configuration and location of this file
* If this file has a path set, the new file will have a corresponding
* new path.
*/
public abstract DocFile resolve(DocPath p);
/**
* Derive a new file by resolving a relative path against this file.
* The new file will inherit the configuration and location of this file
* If this file has a path set, the new file will have a corresponding
* new path.
*/
public abstract DocFile resolve(String p);
/**
* Resolve a relative file against the given output location.
* @param locn Currently, only
* {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} is supported.
*/
public abstract DocFile resolveAgainst(Location locn);
}

View File

@@ -0,0 +1,100 @@
/*
* Copyright (c) 1998, 2012, 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.util.Map;
import java.util.WeakHashMap;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileManager.Location;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import com.sun.tools.doclets.internal.toolkit.Configuration;
/**
* Factory for DocFile objects.
*
* <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>
*
* @since 1.8
*/
abstract class DocFileFactory {
private static final Map<Configuration, DocFileFactory> factories =
new WeakHashMap<Configuration, DocFileFactory>();
/**
* Get the appropriate factory, based on the file manager given in the
* configuration.
*/
static synchronized DocFileFactory getFactory(Configuration configuration) {
DocFileFactory f = factories.get(configuration);
if (f == null) {
JavaFileManager fm = configuration.getFileManager();
if (fm instanceof StandardJavaFileManager)
f = new StandardDocFileFactory(configuration);
else {
try {
Class<?> pathFileManagerClass =
Class.forName("com.sun.tools.javac.nio.PathFileManager");
if (pathFileManagerClass.isAssignableFrom(fm.getClass()))
f = new PathDocFileFactory(configuration);
} catch (Throwable t) {
throw new IllegalStateException(t);
}
}
factories.put(configuration, f);
}
return f;
}
protected Configuration configuration;
protected DocFileFactory(Configuration configuration) {
this.configuration = configuration;
}
/** Create a DocFile for a directory. */
abstract DocFile createFileForDirectory(String file);
/** Create a DocFile for a file that will be opened for reading. */
abstract DocFile createFileForInput(String file);
/** Create a DocFile for a file that will be opened for writing. */
abstract DocFile createFileForOutput(DocPath path);
/**
* List the directories and files found in subdirectories along the
* elements of the given location.
* @param location currently, only {@link StandardLocation#SOURCE_PATH} is supported.
* @param path the subdirectory of the directories of the location for which to
* list files
*/
abstract Iterable<DocFile> list(Location location, DocPath path);
}

View File

@@ -0,0 +1,244 @@
/*
* Copyright (c) 2003, 2013, 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.util.*;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.taglets.*;
/**
* Search for the requested documentation. Inherit documentation if necessary.
*
* <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 Jamie Ho
* @since 1.5
*/
public class DocFinder {
/**
* The class that encapsulates the input.
*/
public static class Input {
/**
* The element to search documentation from.
*/
public ProgramElementDoc element;
/**
* The taglet to search for documentation on behalf of. Null if we want
* to search for overall documentation.
*/
public InheritableTaglet taglet = null;
/**
* The id of the tag to retrieve documentation for.
*/
public String tagId = null;
/**
* The tag to retrieve documentation for. This is only used for the
* inheritDoc tag.
*/
public Tag tag = null;
/**
* True if we only want to search for the first sentence.
*/
public boolean isFirstSentence = false;
/**
* True if we are looking for documentation to replace the inheritDocTag.
*/
public boolean isInheritDocTag = false;
/**
* Used to distinguish between type variable param tags and regular
* param tags.
*/
public boolean isTypeVariableParamTag = false;
public Input(ProgramElementDoc element, InheritableTaglet taglet, Tag tag,
boolean isFirstSentence, boolean isInheritDocTag) {
this(element);
this.taglet = taglet;
this.tag = tag;
this.isFirstSentence = isFirstSentence;
this.isInheritDocTag = isInheritDocTag;
}
public Input(ProgramElementDoc element, InheritableTaglet taglet, String tagId) {
this(element);
this.taglet = taglet;
this.tagId = tagId;
}
public Input(ProgramElementDoc element, InheritableTaglet taglet, String tagId,
boolean isTypeVariableParamTag) {
this(element);
this.taglet = taglet;
this.tagId = tagId;
this.isTypeVariableParamTag = isTypeVariableParamTag;
}
public Input(ProgramElementDoc element, InheritableTaglet taglet) {
this(element);
this.taglet = taglet;
}
public Input(ProgramElementDoc element) {
if (element == null)
throw new NullPointerException();
this.element = element;
}
public Input(ProgramElementDoc element, boolean isFirstSentence) {
this(element);
this.isFirstSentence = isFirstSentence;
}
public Input copy() {
Input clone = new Input(this.element);
clone.taglet = this.taglet;
clone.tagId = this.tagId;
clone.tag = this.tag;
clone.isFirstSentence = this.isFirstSentence;
clone.isInheritDocTag = this.isInheritDocTag;
clone.isTypeVariableParamTag = this.isTypeVariableParamTag;
if (clone.element == null)
throw new NullPointerException();
return clone;
}
}
/**
* The class that encapsulates the output.
*/
public static class Output {
/**
* The tag that holds the documentation. Null if documentation
* is not held by a tag.
*/
public Tag holderTag;
/**
* The Doc object that holds the documentation.
*/
public Doc holder;
/**
* The inherited documentation.
*/
public Tag[] inlineTags = new Tag[] {};
/**
* False if documentation could not be inherited.
*/
public boolean isValidInheritDocTag = true;
/**
* When automatically inheriting throws tags, you sometime must inherit
* more than one tag. For example if the element declares that it throws
* IOException and the overridden element has throws tags for IOException and
* ZipException, both tags would be inherited because ZipException is a
* subclass of IOException. This subclass of DocFinder.Output allows
* multiple tag inheritence.
*/
public List<Tag> tagList = new ArrayList<Tag>();
}
/**
* Search for the requested comments in the given element. If it does not
* have comments, return documentation from the overriden element if possible.
* If the overriden element does not exist or does not have documentation to
* inherit, search for documentation to inherit from implemented methods.
*
* @param input the input object used to perform the search.
*
* @return an Output object representing the documentation that was found.
*/
public static Output search(Input input) {
Output output = new Output();
if (input.isInheritDocTag) {
//Do nothing because "element" does not have any documentation.
//All it has it {@inheritDoc}.
} else if (input.taglet == null) {
//We want overall documentation.
output.inlineTags = input.isFirstSentence ?
input.element.firstSentenceTags() :
input.element.inlineTags();
output.holder = input.element;
} else {
input.taglet.inherit(input, output);
}
if (output.inlineTags != null && output.inlineTags.length > 0) {
return output;
}
output.isValidInheritDocTag = false;
Input inheritedSearchInput = input.copy();
inheritedSearchInput.isInheritDocTag = false;
if (input.element instanceof MethodDoc) {
MethodDoc overriddenMethod = ((MethodDoc) input.element).overriddenMethod();
if (overriddenMethod != null) {
inheritedSearchInput.element = overriddenMethod;
output = search(inheritedSearchInput);
output.isValidInheritDocTag = true;
if (output.inlineTags.length > 0) {
return output;
}
}
//NOTE: When we fix the bug where ClassDoc.interfaceTypes() does
// not pass all implemented interfaces, we will use the
// appropriate element here.
MethodDoc[] implementedMethods =
(new ImplementedMethods((MethodDoc) input.element, null)).build(false);
for (int i = 0; i < implementedMethods.length; i++) {
inheritedSearchInput.element = implementedMethods[i];
output = search(inheritedSearchInput);
output.isValidInheritDocTag = true;
if (output.inlineTags.length > 0) {
return output;
}
}
} else if (input.element instanceof ClassDoc) {
ProgramElementDoc superclass = ((ClassDoc) input.element).superclass();
if (superclass != null) {
inheritedSearchInput.element = superclass;
output = search(inheritedSearchInput);
output.isValidInheritDocTag = true;
if (output.inlineTags.length > 0) {
return output;
}
}
}
return output;
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2012, 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;
/**
* Abstraction for simple relative URIs, consisting of a path,
* an optional query, and an optional fragment. DocLink objects can
* be created by the constructors below or from a DocPath using the
* convenience methods, {@link DocPath#fragment fragment} and
* {@link DocPath#query query}.
*
* <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>
*
*/
public class DocLink {
final String path;
final String query;
final String fragment;
/** Create a DocLink representing the URI {@code #fragment}. */
public static DocLink fragment(String fragment) {
return new DocLink((String) null, (String) null, fragment);
}
/** Create a DocLink representing the URI {@code path}. */
public DocLink(DocPath path) {
this(path.getPath(), null, null);
}
/**
* Create a DocLink representing the URI {@code path?query#fragment}.
* query and fragment may be null.
*/
public DocLink(DocPath path, String query, String fragment) {
this(path.getPath(), query, fragment);
}
/**
* Create a DocLink representing the URI {@code path?query#fragment}.
* Any of the component parts may be null.
*/
public DocLink(String path, String query, String fragment) {
this.path = path;
this.query = query;
this.fragment = fragment;
}
/**
* Return the link in the form "path?query#fragment", omitting any empty
* components.
*/
@Override
public String toString() {
// common fast path
if (path != null && isEmpty(query) && isEmpty(fragment))
return path;
StringBuilder sb = new StringBuilder();
if (path != null)
sb.append(path);
if (!isEmpty(query))
sb.append("?").append(query);
if (!isEmpty(fragment))
sb.append("#").append(fragment);
return sb.toString();
}
private static boolean isEmpty(String s) {
return (s == null) || s.isEmpty();
}
}

View File

@@ -0,0 +1,191 @@
/*
* Copyright (c) 1998, 2012, 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 com.sun.javadoc.ClassDoc;
import com.sun.javadoc.PackageDoc;
/**
* Abstraction for immutable relative paths.
* Paths always use '/' as a separator, and never begin or end with '/'.
*
* <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>
*/
public class DocPath {
private final String path;
/** The empty path. */
public static final DocPath empty = new DocPath("");
/** The empty path. */
public static final DocPath parent = new DocPath("..");
/**
* Create a path from a string.
*/
public static DocPath create(String p) {
return (p == null) || p.isEmpty() ? empty : new DocPath(p);
}
/**
* Return the path for a class.
* For example, if the class is java.lang.Object,
* the path is java/lang/Object.html.
*/
public static DocPath forClass(ClassDoc cd) {
return (cd == null) ? empty :
forPackage(cd.containingPackage()).resolve(forName(cd));
}
/**
* Return the path for the simple name of the class.
* For example, if the class is java.lang.Object,
* the path is Object.html.
*/
public static DocPath forName(ClassDoc cd) {
return (cd == null) ? empty : new DocPath(cd.name() + ".html");
}
/**
* Return the path for the package of a class.
* For example, if the class is java.lang.Object,
* the path is java/lang.
*/
public static DocPath forPackage(ClassDoc cd) {
return (cd == null) ? empty : forPackage(cd.containingPackage());
}
/**
* Return the path for a package.
* For example, if the package is java.lang,
* the path is java/lang.
*/
public static DocPath forPackage(PackageDoc pd) {
return (pd == null) ? empty : DocPath.create(pd.name().replace('.', '/'));
}
/**
* Return the inverse path for a package.
* For example, if the package is java.lang,
* the inverse path is ../...
*/
public static DocPath forRoot(PackageDoc pd) {
String name = (pd == null) ? "" : pd.name();
if (name.isEmpty())
return empty;
return new DocPath(name.replace('.', '/').replaceAll("[^/]+", ".."));
}
/**
* Return the relative path from one package to another.
*/
public static DocPath relativePath(PackageDoc from, PackageDoc to) {
return forRoot(from).resolve(forPackage(to));
}
protected DocPath(String p) {
path = (p.endsWith("/") ? p.substring(0, p.length() - 1) : p);
}
/** {@inheritDoc} */
@Override
public boolean equals(Object other) {
return (other instanceof DocPath) && path.equals(((DocPath)other).path);
}
/** {@inheritDoc} */
@Override
public int hashCode() {
return path.hashCode();
}
public DocPath basename() {
int sep = path.lastIndexOf("/");
return (sep == -1) ? this : new DocPath(path.substring(sep + 1));
}
public DocPath parent() {
int sep = path.lastIndexOf("/");
return (sep == -1) ? empty : new DocPath(path.substring(0, sep));
}
/**
* Return the path formed by appending the specified string to the current path.
*/
public DocPath resolve(String p) {
if (p == null || p.isEmpty())
return this;
if (path.isEmpty())
return new DocPath(p);
return new DocPath(path + "/" + p);
}
/**
* Return the path by appending the specified path to the current path.
*/
public DocPath resolve(DocPath p) {
if (p == null || p.isEmpty())
return this;
if (path.isEmpty())
return p;
return new DocPath(path + "/" + p.getPath());
}
/**
* Return the inverse path for this path.
* For example, if the path is a/b/c, the inverse path is ../../..
*/
public DocPath invert() {
return new DocPath(path.replaceAll("[^/]+", ".."));
}
/**
* Return true if this path is empty.
*/
public boolean isEmpty() {
return path.isEmpty();
}
public DocLink fragment(String fragment) {
return new DocLink(path, null, fragment);
}
public DocLink query(String query) {
return new DocLink(path, query, null);
}
/**
* Return this path as a string.
*/
// This is provided instead of using toString() to help catch
// unintended use of toString() in string concatenation sequences.
public String getPath() {
return path;
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (c) 1998, 2013, 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;
/**
* Standard DocPath objects.
*
* <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>
*
* @since 8
*/
public class DocPaths {
/** The name of the file for all classes, using frames. */
public static final DocPath ALLCLASSES_FRAME = DocPath.create("allclasses-frame.html");
/** The name of the file for all classes, without using frames. */
public static final DocPath ALLCLASSES_NOFRAME = DocPath.create("allclasses-noframe.html");
/** The name of the sub-directory for storing class usage info. */
public static final DocPath CLASS_USE = DocPath.create("class-use");
/** The name of the file for constant values. */
public static final DocPath CONSTANT_VALUES = DocPath.create("constant-values.html");
/** The name of the fie for deprecated elements. */
public static final DocPath DEPRECATED_LIST = DocPath.create("deprecated-list.html");
/** The name of the subdirectory for user-provided additional documentation files. */
public static final DocPath DOC_FILES = DocPath.create("doc-files");
/** The name of the file for help info. */
public static final DocPath HELP_DOC = DocPath.create("help-doc.html");
/** The name of the main index file. */
public static final DocPath INDEX = DocPath.create("index.html");
/** The name of the single index file for all classes. */
public static final DocPath INDEX_ALL = DocPath.create("index-all.html");
/** The name of the directory for the split index files. */
public static final DocPath INDEX_FILES = DocPath.create("index-files");
/** Generate the name of one of the files in the split index. */
public static final DocPath indexN(int n) {
return DocPath.create("index-" + n + ".html");
}
/** The name of the default javascript file. */
public static final DocPath JAVASCRIPT = DocPath.create("script.js");
/** The name of the file for the overview frame. */
public static final DocPath OVERVIEW_FRAME = DocPath.create("overview-frame.html");
/** The name of the file for the overview summary. */
public static final DocPath OVERVIEW_SUMMARY = DocPath.create("overview-summary.html");
/** The name of the file for the overview tree. */
public static final DocPath OVERVIEW_TREE = DocPath.create("overview-tree.html");
/** The name of the file for the package frame. */
public static final DocPath PACKAGE_FRAME = DocPath.create("package-frame.html");
/** The name of the file for the profile frame. */
public static final DocPath profileFrame(String profileName) {
return DocPath.create(profileName + "-frame.html");
}
/** The name of the file for the profile package frame. */
public static final DocPath profilePackageFrame(String profileName) {
return DocPath.create(profileName + "-package-frame.html");
}
/** The name of the file for the profile package summary. */
public static final DocPath profilePackageSummary(String profileName) {
return DocPath.create(profileName + "-package-summary.html");
}
/** The name of the file for the profile summary. */
public static final DocPath profileSummary(String profileName) {
return DocPath.create(profileName + "-summary.html");
}
/** The name of the file for the package list. */
public static final DocPath PACKAGE_LIST = DocPath.create("package-list");
/** The name of the file for the package summary. */
public static final DocPath PACKAGE_SUMMARY = DocPath.create("package-summary.html");
/** The name of the file for the package tree. */
public static final DocPath PACKAGE_TREE = DocPath.create("package-tree.html");
/** The name of the file for the package usage info. */
public static final DocPath PACKAGE_USE = DocPath.create("package-use.html");
/** The name of the file for the overview frame. */
public static final DocPath PROFILE_OVERVIEW_FRAME = DocPath.create("profile-overview-frame.html");
/** The name of the sub-package from which resources are read. */
public static final DocPath RESOURCES = DocPath.create("resources");
/** The name of the file for the serialized form info. */
public static final DocPath SERIALIZED_FORM = DocPath.create("serialized-form.html");
/** The name of the directory in which HTML versions of the source code
* are generated.
*/
public static final DocPath SOURCE_OUTPUT = DocPath.create("src-html");
/** The name of the default stylesheet. */
public static final DocPath STYLESHEET = DocPath.create("stylesheet.css");
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 1997, 2013, 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;
/**
* <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>
*/
public class DocletAbortException extends RuntimeException {
private static final long serialVersionUID = -9131058909576418984L;
public DocletAbortException(String message) {
super(message);
}
public DocletAbortException(Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2003, 2013, 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;
/**
* Stores all constants for a Doclet. Extend this class if you have doclet
* specific constants to add.
*
* <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 Jamie Ho
* @since 1.5
*/
public class DocletConstants {
/**
* The default amount of space between tab stops.
*/
public static final int DEFAULT_TAB_STOP_LENGTH = 8;
/**
* The line separator for the current operating system.
*/
public static final String NL = System.getProperty("line.separator");
/**
* The default package name.
*/
public static final String DEFAULT_PACKAGE_NAME = "<Unnamed>";
/**
* The default package file name.
*/
public static final String DEFAULT_PACKAGE_FILE_NAME = "default";
}

View File

@@ -0,0 +1,316 @@
/*
* Copyright (c) 1998, 2014, 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.net.*;
import java.util.HashMap;
import java.util.Map;
import javax.tools.DocumentationTool;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*;
/**
* Process and manage "-link" and "-linkoffline" to external packages. The
* options "-link" and "-linkoffline" both depend on the fact that Javadoc now
* generates "package-list"(lists all the packages which are getting
* documented) file in the current or the destination directory, while
* generating the documentation.
*
* <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 Robert Field
*/
public class Extern {
/**
* Map package names onto Extern Item objects.
* Lazily initialized.
*/
private Map<String,Item> packageToItemMap;
/**
* The global configuration information for this run.
*/
private final Configuration configuration;
/**
* True if we are using -linkoffline and false if -link is used instead.
*/
private boolean linkoffline = false;
/**
* Stores the info for one external doc set
*/
private class Item {
/**
* Package name, found in the "package-list" file in the {@link path}.
*/
final String packageName;
/**
* The URL or the directory path at which the package documentation will be
* avaliable.
*/
final String path;
/**
* If given path is directory path then true else if it is a URL then false.
*/
final boolean relative;
/**
* Constructor to build a Extern Item object and map it with the package name.
* If the same package name is found in the map, then the first mapped
* Item object or offline location will be retained.
*
* @param packageName Package name found in the "package-list" file.
* @param path URL or Directory path from where the "package-list"
* file is picked.
* @param relative True if path is URL, false if directory path.
*/
Item(String packageName, String path, boolean relative) {
this.packageName = packageName;
this.path = path;
this.relative = relative;
if (packageToItemMap == null) {
packageToItemMap = new HashMap<String,Item>();
}
if (!packageToItemMap.containsKey(packageName)) { // save the previous
packageToItemMap.put(packageName, this); // mapped location
}
}
/**
* String representation of "this" with packagename and the path.
*/
public String toString() {
return packageName + (relative? " -> " : " => ") + path;
}
}
public Extern(Configuration configuration) {
this.configuration = configuration;
}
/**
* Determine if a doc item is externally documented.
*
* @param doc A ProgramElementDoc.
*/
public boolean isExternal(ProgramElementDoc doc) {
if (packageToItemMap == null) {
return false;
}
return packageToItemMap.get(doc.containingPackage().name()) != null;
}
/**
* Convert a link to be an external link if appropriate.
*
* @param pkgName The package name.
* @param relativepath The relative path.
* @param filename The link to convert.
* @return if external return converted link else return null
*/
public DocLink getExternalLink(String pkgName,
DocPath relativepath, String filename) {
return getExternalLink(pkgName, relativepath, filename, null);
}
public DocLink getExternalLink(String pkgName,
DocPath relativepath, String filename, String memberName) {
Item fnd = findPackageItem(pkgName);
if (fnd == null)
return null;
DocPath p = fnd.relative ?
relativepath.resolve(fnd.path).resolve(filename) :
DocPath.create(fnd.path).resolve(filename);
return new DocLink(p, "is-external=true", memberName);
}
/**
* Build the extern package list from given URL or the directory path.
* Flag error if the "-link" or "-linkoffline" option is already used.
*
* @param url URL or Directory path.
* @param pkglisturl This can be another URL for "package-list" or ordinary
* file.
* @param reporter The <code>DocErrorReporter</code> used to report errors.
* @param linkoffline True if -linkoffline is used and false if -link is used.
*/
public boolean link(String url, String pkglisturl,
DocErrorReporter reporter, boolean linkoffline) {
this.linkoffline = linkoffline;
try {
url = adjustEndFileSeparator(url);
if (isUrl(pkglisturl)) {
readPackageListFromURL(url, toURL(adjustEndFileSeparator(pkglisturl)));
} else {
readPackageListFromFile(url, DocFile.createFileForInput(configuration, pkglisturl));
}
return true;
} catch (Fault f) {
reporter.printWarning(f.getMessage());
return false;
}
}
private URL toURL(String url) throws Fault {
try {
return new URL(url);
} catch (MalformedURLException e) {
throw new Fault(configuration.getText("doclet.MalformedURL", url), e);
}
}
private class Fault extends Exception {
private static final long serialVersionUID = 0;
Fault(String msg, Exception cause) {
super(msg, cause);
}
}
/**
* Get the Extern Item object associated with this package name.
*
* @param pkgName Package name.
*/
private Item findPackageItem(String pkgName) {
if (packageToItemMap == null) {
return null;
}
return packageToItemMap.get(pkgName);
}
/**
* If the URL or Directory path is missing end file separator, add that.
*/
private String adjustEndFileSeparator(String url) {
return url.endsWith("/") ? url : url + '/';
}
/**
* Fetch the URL and read the "package-list" file.
*
* @param urlpath Path to the packages.
* @param pkglisturlpath URL or the path to the "package-list" file.
*/
private void readPackageListFromURL(String urlpath, URL pkglisturlpath)
throws Fault {
try {
URL link = pkglisturlpath.toURI().resolve(DocPaths.PACKAGE_LIST.getPath()).toURL();
readPackageList(link.openStream(), urlpath, false);
} catch (URISyntaxException exc) {
throw new Fault(configuration.getText("doclet.MalformedURL", pkglisturlpath.toString()), exc);
} catch (MalformedURLException exc) {
throw new Fault(configuration.getText("doclet.MalformedURL", pkglisturlpath.toString()), exc);
} catch (IOException exc) {
throw new Fault(configuration.getText("doclet.URL_error", pkglisturlpath.toString()), exc);
}
}
/**
* Read the "package-list" file which is available locally.
*
* @param path URL or directory path to the packages.
* @param pkgListPath Path to the local "package-list" file.
*/
private void readPackageListFromFile(String path, DocFile pkgListPath)
throws Fault {
DocFile file = pkgListPath.resolve(DocPaths.PACKAGE_LIST);
if (! (file.isAbsolute() || linkoffline)){
file = file.resolveAgainst(DocumentationTool.Location.DOCUMENTATION_OUTPUT);
}
try {
if (file.exists() && file.canRead()) {
boolean pathIsRelative =
!DocFile.createFileForInput(configuration, path).isAbsolute()
&& !isUrl(path);
readPackageList(file.openInputStream(), path, pathIsRelative);
} else {
throw new Fault(configuration.getText("doclet.File_error", file.getPath()), null);
}
} catch (IOException exc) {
throw new Fault(configuration.getText("doclet.File_error", file.getPath()), exc);
}
}
/**
* Read the file "package-list" and for each package name found, create
* Extern object and associate it with the package name in the map.
*
* @param input InputStream from the "package-list" file.
* @param path URL or the directory path to the packages.
* @param relative Is path relative?
*/
private void readPackageList(InputStream input, String path,
boolean relative)
throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(input));
StringBuilder strbuf = new StringBuilder();
try {
int c;
while ((c = in.read()) >= 0) {
char ch = (char)c;
if (ch == '\n' || ch == '\r') {
if (strbuf.length() > 0) {
String packname = strbuf.toString();
String packpath = path +
packname.replace('.', '/') + '/';
new Item(packname, packpath, relative);
strbuf.setLength(0);
}
} else {
strbuf.append(ch);
}
}
} finally {
input.close();
}
}
public boolean isUrl (String urlCandidate) {
try {
new URL(urlCandidate);
//No exception was thrown, so this must really be a URL.
return true;
} catch (MalformedURLException e) {
//Since exception is thrown, this must be a directory path.
return false;
}
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2016, 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;
/**
* <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>
*/
@Deprecated
public class FatalError extends Error {
private static final long serialVersionUID = -9131058909576418984L;
public FatalError() { }
}

View File

@@ -0,0 +1,247 @@
/*
* Copyright (c) 1998, 2012, 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.util.*;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*;
/**
* Process and manage grouping of packages, as specified by "-group" option on
* the command line.
* <p>
* For example, if user has used -group option as
* -group "Core Packages" "java.*" -group "CORBA Packages" "org.omg.*", then
* the packages specified on the command line will be grouped according to their
* names starting with either "java." or "org.omg.". All the other packages
* which do not fall in the user given groups, are grouped in default group,
* named as either "Other Packages" or "Packages" depending upon if "-group"
* option used or not at all used respectively.
* </p>
* <p>
* Also the packages are grouped according to the longest possible match of
* their names with the grouping information provided. For example, if there
* are two groups, like -group "Lang" "java.lang" and -group "Core" "java.*",
* will put the package java.lang in the group "Lang" and not in group "Core".
* </p>
*
* <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
*/
public class Group {
/**
* Map of regular expressions with the corresponding group name.
*/
private Map<String,String> regExpGroupMap = new HashMap<String,String>();
/**
* List of regular expressions sorted according to the length. Regular
* expression with longest length will be first in the sorted order.
*/
private List<String> sortedRegExpList = new ArrayList<String>();
/**
* List of group names in the same order as given on the command line.
*/
private List<String> groupList = new ArrayList<String>();
/**
* Map of non-regular expressions(possible package names) with the
* corresponding group name.
*/
private Map<String,String> pkgNameGroupMap = new HashMap<String,String>();
/**
* The global configuration information for this run.
*/
private final Configuration configuration;
/**
* Since we need to sort the keys in the reverse order(longest key first),
* the compare method in the implementing class is doing the reverse
* comparison.
*/
private static class MapKeyComparator implements Comparator<String> {
public int compare(String key1, String key2) {
return key2.length() - key1.length();
}
}
public Group(Configuration configuration) {
this.configuration = configuration;
}
/**
* Depending upon the format of the package name provided in the "-group"
* option, generate two separate maps. There will be a map for mapping
* regular expression(only meta character allowed is '*' and that is at the
* end of the regular expression) on to the group name. And another map
* for mapping (possible) package names(if the name format doesen't contain
* meta character '*', then it is assumed to be a package name) on to the
* group name. This will also sort all the regular expressions found in the
* reverse order of their lengths, i.e. longest regular expression will be
* first in the sorted list.
*
* @param groupname The name of the group from -group option.
* @param pkgNameFormList List of the package name formats.
*/
public boolean checkPackageGroups(String groupname,
String pkgNameFormList) {
StringTokenizer strtok = new StringTokenizer(pkgNameFormList, ":");
if (groupList.contains(groupname)) {
configuration.message.warning("doclet.Groupname_already_used", groupname);
return false;
}
groupList.add(groupname);
while (strtok.hasMoreTokens()) {
String id = strtok.nextToken();
if (id.length() == 0) {
configuration.message.warning("doclet.Error_in_packagelist", groupname, pkgNameFormList);
return false;
}
if (id.endsWith("*")) {
id = id.substring(0, id.length() - 1);
if (foundGroupFormat(regExpGroupMap, id)) {
return false;
}
regExpGroupMap.put(id, groupname);
sortedRegExpList.add(id);
} else {
if (foundGroupFormat(pkgNameGroupMap, id)) {
return false;
}
pkgNameGroupMap.put(id, groupname);
}
}
Collections.sort(sortedRegExpList, new MapKeyComparator());
return true;
}
/**
* Search if the given map has given the package format.
*
* @param map Map to be searched.
* @param pkgFormat The pacakge format to search.
*
* @return true if package name format found in the map, else false.
*/
boolean foundGroupFormat(Map<String,?> map, String pkgFormat) {
if (map.containsKey(pkgFormat)) {
configuration.message.error("doclet.Same_package_name_used", pkgFormat);
return true;
}
return false;
}
/**
* Group the packages according the grouping information provided on the
* command line. Given a list of packages, search each package name in
* regular expression map as well as package name map to get the
* corresponding group name. Create another map with mapping of group name
* to the package list, which will fall under the specified group. If any
* package doesen't belong to any specified group on the comamnd line, then
* a new group named "Other Packages" will be created for it. If there are
* no groups found, in other words if "-group" option is not at all used,
* then all the packages will be grouped under group "Packages".
*
* @param packages Packages specified on the command line.
*/
public Map<String,List<PackageDoc>> groupPackages(PackageDoc[] packages) {
Map<String,List<PackageDoc>> groupPackageMap = new HashMap<String,List<PackageDoc>>();
String defaultGroupName =
(pkgNameGroupMap.isEmpty() && regExpGroupMap.isEmpty())?
configuration.message.getText("doclet.Packages") :
configuration.message.getText("doclet.Other_Packages");
// if the user has not used the default group name, add it
if (!groupList.contains(defaultGroupName)) {
groupList.add(defaultGroupName);
}
for (int i = 0; i < packages.length; i++) {
PackageDoc pkg = packages[i];
String pkgName = pkg.name();
String groupName = pkgNameGroupMap.get(pkgName);
// if this package is not explicitly assigned to a group,
// try matching it to group specified by regular expression
if (groupName == null) {
groupName = regExpGroupName(pkgName);
}
// if it is in neither group map, put it in the default
// group
if (groupName == null) {
groupName = defaultGroupName;
}
getPkgList(groupPackageMap, groupName).add(pkg);
}
return groupPackageMap;
}
/**
* Search for package name in the sorted regular expression
* list, if found return the group name. If not, return null.
*
* @param pkgName Name of package to be found in the regular
* expression list.
*/
String regExpGroupName(String pkgName) {
for (int j = 0; j < sortedRegExpList.size(); j++) {
String regexp = sortedRegExpList.get(j);
if (pkgName.startsWith(regexp)) {
return regExpGroupMap.get(regexp);
}
}
return null;
}
/**
* For the given group name, return the package list, on which it is mapped.
* Create a new list, if not found.
*
* @param map Map to be searched for gorup name.
* @param groupname Group name to search.
*/
List<PackageDoc> getPkgList(Map<String,List<PackageDoc>> map, String groupname) {
List<PackageDoc> list = map.get(groupname);
if (list == null) {
list = new ArrayList<PackageDoc>();
map.put(groupname, list);
}
return list;
}
/**
* Return the list of groups, in the same order as specified
* on the command line.
*/
public List<String> getGroupList() {
return groupList;
}
}

View File

@@ -0,0 +1,151 @@
/*
* Copyright (c) 1999, 2012, 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.util.*;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.Configuration;
/**
* For a given class method, build an array of interface methods which it
* implements.
*
* <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
*/
public class ImplementedMethods {
private Map<MethodDoc,Type> interfaces = new HashMap<MethodDoc,Type>();
private List<MethodDoc> methlist = new ArrayList<MethodDoc>();
private Configuration configuration;
private final ClassDoc classdoc;
private final MethodDoc method;
public ImplementedMethods(MethodDoc method, Configuration configuration) {
this.method = method;
this.configuration = configuration;
classdoc = method.containingClass();
}
/**
* Return the array of interface methods which the method passed in the
* constructor is implementing. The search/build order is as follows:
* <pre>
* 1. Search in all the immediate interfaces which this method's class is
* implementing. Do it recursively for the superinterfaces as well.
* 2. Traverse all the superclasses and search recursively in the
* interfaces which those superclasses implement.
*</pre>
*
* @return MethodDoc[] Array of implemented methods.
*/
public MethodDoc[] build(boolean sort) {
buildImplementedMethodList(sort);
return methlist.toArray(new MethodDoc[methlist.size()]);
}
public MethodDoc[] build() {
return build(true);
}
public Type getMethodHolder(MethodDoc methodDoc) {
return interfaces.get(methodDoc);
}
/**
* Search for the method in the array of interfaces. If found check if it is
* overridden by any other subinterface method which this class
* implements. If it is not overidden, add it in the method list.
* Do this recursively for all the extended interfaces for each interface
* from the array passed.
*/
private void buildImplementedMethodList(boolean sort) {
List<Type> intfacs = Util.getAllInterfaces(classdoc, configuration, sort);
for (Iterator<Type> iter = intfacs.iterator(); iter.hasNext(); ) {
Type interfaceType = iter.next();
MethodDoc found = Util.findMethod(interfaceType.asClassDoc(), method);
if (found != null) {
removeOverriddenMethod(found);
if (!overridingMethodFound(found)) {
methlist.add(found);
interfaces.put(found, interfaceType);
}
}
}
}
/**
* Search in the method list and check if it contains a method which
* is overridden by the method as parameter. If found, remove the
* overridden method from the method list.
*
* @param method Is this method overriding a method in the method list.
*/
private void removeOverriddenMethod(MethodDoc method) {
ClassDoc overriddenClass = method.overriddenClass();
if (overriddenClass != null) {
for (int i = 0; i < methlist.size(); i++) {
ClassDoc cd = methlist.get(i).containingClass();
if (cd == overriddenClass || overriddenClass.subclassOf(cd)) {
methlist.remove(i); // remove overridden method
return;
}
}
}
}
/**
* Search in the already found methods' list and check if it contains
* a method which is overriding the method parameter or is the method
* parameter itself.
*
* @param method MethodDoc Method to be searched in the Method List for
* an overriding method.
*/
private boolean overridingMethodFound(MethodDoc method) {
ClassDoc containingClass = method.containingClass();
for (int i = 0; i < methlist.size(); i++) {
MethodDoc listmethod = methlist.get(i);
if (containingClass == listmethod.containingClass()) {
// it's the same method.
return true;
}
ClassDoc cd = listmethod.overriddenClass();
if (cd == null) {
continue;
}
if (cd == containingClass || cd.subclassOf(containingClass)) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,262 @@
/*
* Copyright (c) 1998, 2013, 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.util.*;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*;
/**
* Build the mapping of each Unicode character with it's member lists
* containing members names starting with it. Also build a list for all the
* Unicode characters which start a member name. Member name is
* classkind or field or method or constructor name.
*
* <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>
*
* @since 1.2
* @see java.lang.Character
* @author Atul M Dambalkar
*/
public class IndexBuilder {
/**
* Mapping of each Unicode Character with the member list containing
* members with names starting with it.
*/
private Map<Character,List<Doc>> indexmap = new HashMap<Character,List<Doc>>();
/**
* Don't generate deprecated information if true.
*/
private boolean noDeprecated;
/**
* Build this Index only for classes?
*/
private boolean classesOnly;
/**
* Indicates javafx mode.
*/
private boolean javafx;
// make ProgramElementDoc[] when new toArray is available
protected final Object[] elements;
/**
* A comparator used to sort classes and members.
* Note: Maybe this compare code belongs in the tool?
*/
private class DocComparator implements Comparator<Doc> {
public int compare(Doc d1, Doc d2) {
String doc1 = d1.name();
String doc2 = d2.name();
int compareResult;
if ((compareResult = doc1.compareToIgnoreCase(doc2)) != 0) {
return compareResult;
} else if (d1 instanceof ProgramElementDoc && d2 instanceof ProgramElementDoc) {
doc1 = (((ProgramElementDoc) d1).qualifiedName());
doc2 = (((ProgramElementDoc) d2).qualifiedName());
return doc1.compareToIgnoreCase(doc2);
} else {
return 0;
}
}
}
/**
* Constructor. Build the index map.
*
* @param configuration the current configuration of the doclet.
* @param noDeprecated true if -nodeprecated option is used,
* false otherwise.
*/
public IndexBuilder(Configuration configuration, boolean noDeprecated) {
this(configuration, noDeprecated, false);
}
/**
* Constructor. Build the index map.
*
* @param configuration the current configuration of the doclet.
* @param noDeprecated true if -nodeprecated option is used,
* false otherwise.
* @param classesOnly Include only classes in index.
*/
public IndexBuilder(Configuration configuration, boolean noDeprecated,
boolean classesOnly) {
if (classesOnly) {
configuration.message.notice("doclet.Building_Index_For_All_Classes");
} else {
configuration.message.notice("doclet.Building_Index");
}
this.noDeprecated = noDeprecated;
this.classesOnly = classesOnly;
this.javafx = configuration.javafx;
buildIndexMap(configuration.root);
Set<Character> set = indexmap.keySet();
elements = set.toArray();
Arrays.sort(elements);
}
/**
* Sort the index map. Traverse the index map for all it's elements and
* sort each element which is a list.
*/
protected void sortIndexMap() {
for (Iterator<List<Doc>> it = indexmap.values().iterator(); it.hasNext(); ) {
Collections.sort(it.next(), new DocComparator());
}
}
/**
* Get all the members in all the Packages and all the Classes
* given on the command line. Form separate list of those members depending
* upon their names.
*
* @param root Root of the documemt.
*/
protected void buildIndexMap(RootDoc root) {
PackageDoc[] packages = root.specifiedPackages();
ClassDoc[] classes = root.classes();
if (!classesOnly) {
if (packages.length == 0) {
Set<PackageDoc> set = new HashSet<PackageDoc>();
PackageDoc pd;
for (int i = 0; i < classes.length; i++) {
pd = classes[i].containingPackage();
if (pd != null && pd.name().length() > 0) {
set.add(pd);
}
}
adjustIndexMap(set.toArray(packages));
} else {
adjustIndexMap(packages);
}
}
adjustIndexMap(classes);
if (!classesOnly) {
for (int i = 0; i < classes.length; i++) {
if (shouldAddToIndexMap(classes[i])) {
putMembersInIndexMap(classes[i]);
}
}
}
sortIndexMap();
}
/**
* Put all the members(fields, methods and constructors) in the classdoc
* to the indexmap.
*
* @param classdoc ClassDoc whose members will be added to the indexmap.
*/
protected void putMembersInIndexMap(ClassDoc classdoc) {
adjustIndexMap(classdoc.fields());
adjustIndexMap(classdoc.methods());
adjustIndexMap(classdoc.constructors());
}
/**
* Adjust list of members according to their names. Check the first
* character in a member name, and then add the member to a list of members
* for that particular unicode character.
*
* @param elements Array of members.
*/
protected void adjustIndexMap(Doc[] elements) {
for (int i = 0; i < elements.length; i++) {
if (shouldAddToIndexMap(elements[i])) {
String name = elements[i].name();
char ch = (name.length()==0)?
'*' :
Character.toUpperCase(name.charAt(0));
Character unicode = new Character(ch);
List<Doc> list = indexmap.get(unicode);
if (list == null) {
list = new ArrayList<Doc>();
indexmap.put(unicode, list);
}
list.add(elements[i]);
}
}
}
/**
* Should this doc element be added to the index map?
*/
protected boolean shouldAddToIndexMap(Doc element) {
if (javafx) {
if (element.tags("treatAsPrivate").length > 0) {
return false;
}
}
if (element instanceof PackageDoc)
// Do not add to index map if -nodeprecated option is set and the
// package is marked as deprecated.
return !(noDeprecated && Util.isDeprecated(element));
else
// Do not add to index map if -nodeprecated option is set and if the
// Doc is marked as deprecated or the containing package is marked as
// deprecated.
return !(noDeprecated &&
(Util.isDeprecated(element) ||
Util.isDeprecated(((ProgramElementDoc)element).containingPackage())));
}
/**
* Return a map of all the individual member lists with Unicode character.
*
* @return Map index map.
*/
public Map<Character,List<Doc>> getIndexMap() {
return indexmap;
}
/**
* Return the sorted list of members, for passed Unicode Character.
*
* @param index index Unicode character.
* @return List member list for specific Unicode character.
*/
public List<Doc> getMemberList(Character index) {
return indexmap.get(index);
}
/**
* Array of IndexMap keys, Unicode characters.
*/
public Object[] elements() {
return elements;
}
}

View File

@@ -0,0 +1,226 @@
/*
* Copyright (c) 1998, 2013, 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.text.MessageFormat;
import java.util.*;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.Configuration;
/**
* Retrieve and format messages stored in a resource.
*
* <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>
*
* @since 1.2
* @author Atul M Dambalkar
* @author Robert Field
*/
public class MessageRetriever {
/**
* The global configuration information for this run.
*/
private final Configuration configuration;
/**
* The location from which to lazily fetch the resource..
*/
private final String resourcelocation;
/**
* The lazily fetched resource..
*/
private ResourceBundle messageRB;
/**
* Initialize the ResourceBundle with the given resource.
*
* @param rb the resource bundle to read.
*/
public MessageRetriever(ResourceBundle rb) {
this.configuration = null;
this.messageRB = rb;
this.resourcelocation = null;
}
/**
* Initialize the ResourceBundle with the given resource.
*
* @param configuration the configuration
* @param resourcelocation Resource.
*/
public MessageRetriever(Configuration configuration,
String resourcelocation) {
this.configuration = configuration;
this.resourcelocation = resourcelocation;
}
/**
* Get and format message string from resource
*
* @param key selects message from resource
* @param args arguments to be replaced in the message.
* @throws MissingResourceException when the key does not
* exist in the properties file.
*/
public String getText(String key, Object... args) throws MissingResourceException {
if (messageRB == null) {
try {
messageRB = ResourceBundle.getBundle(resourcelocation);
} catch (MissingResourceException e) {
throw new Error("Fatal: Resource (" + resourcelocation +
") for javadoc doclets is missing.");
}
}
String message = messageRB.getString(key);
return MessageFormat.format(message, args);
}
/**
* Print error message, increment error count.
*
* @param pos the position of the source
* @param msg message to print
*/
private void printError(SourcePosition pos, String msg) {
configuration.root.printError(pos, msg);
}
/**
* Print error message, increment error count.
*
* @param msg message to print
*/
private void printError(String msg) {
configuration.root.printError(msg);
}
/**
* Print warning message, increment warning count.
*
* @param pos the position of the source
* @param msg message to print
*/
private void printWarning(SourcePosition pos, String msg) {
configuration.root.printWarning(pos, msg);
}
/**
* Print warning message, increment warning count.
*
* @param msg message to print
*/
private void printWarning(String msg) {
configuration.root.printWarning(msg);
}
/**
* Print a message.
*
* @param pos the position of the source
* @param msg message to print
*/
private void printNotice(SourcePosition pos, String msg) {
configuration.root.printNotice(pos, msg);
}
/**
* Print a message.
*
* @param msg message to print
*/
private void printNotice(String msg) {
configuration.root.printNotice(msg);
}
/**
* Print error message, increment error count.
*
* @param pos the position of the source
* @param key selects message from resource
* @param args arguments to be replaced in the message.
*/
public void error(SourcePosition pos, String key, Object... args) {
printError(pos, getText(key, args));
}
/**
* Print error message, increment error count.
*
* @param key selects message from resource
* @param args arguments to be replaced in the message.
*/
public void error(String key, Object... args) {
printError(getText(key, args));
}
/**
* Print warning message, increment warning count.
*
* @param pos the position of the source
* @param key selects message from resource
* @param args arguments to be replaced in the message.
*/
public void warning(SourcePosition pos, String key, Object... args) {
if (configuration.showMessage(pos, key))
printWarning(pos, getText(key, args));
}
/**
* Print warning message, increment warning count.
*
* @param key selects message from resource
* @param args arguments to be replaced in the message.
*/
public void warning(String key, Object... args) {
printWarning(getText(key, args));
}
/**
* Print a message.
*
* @param pos the position of the source
* @param key selects message from resource
* @param args arguments to be replaced in the message.
*/
public void notice(SourcePosition pos, String key, Object... args) {
printNotice(pos, getText(key, args));
}
/**
* Print a message.
*
* @param key selects message from resource
* @param args arguments to be replaced in the message.
*/
public void notice(String key, Object... args) {
printNotice(getText(key, args));
}
}

View File

@@ -0,0 +1,159 @@
/*
* Copyright (c) 2002, 2013, 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.util.*;
import com.sun.javadoc.*;
import com.sun.tools.javac.jvm.Profile;
import com.sun.tools.doclets.internal.toolkit.*;
/**
* Provides methods for creating an array of class, method and
* field names to be included as meta keywords in the HTML header
* of class pages. These keywords improve search results
* on browsers that look for keywords.
*
* <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 Doug Kramer
*/
public class MetaKeywords {
/**
* The global configuration information for this run.
*/
private final Configuration configuration;
/**
* Constructor
*/
public MetaKeywords(Configuration configuration) {
this.configuration = configuration;
}
/**
* Returns an array of strings where each element
* is a class, method or field name. This array is
* used to create one meta keyword tag for each element.
* Method parameter lists are converted to "()" and
* overloads are combined.
*
* Constructors are not included because they have the same
* name as the class, which is already included.
* Nested class members are not included because their
* definitions are on separate pages.
*/
public String[] getMetaKeywords(ClassDoc classdoc) {
ArrayList<String> results = new ArrayList<String>();
// Add field and method keywords only if -keywords option is used
if( configuration.keywords ) {
results.addAll(getClassKeyword(classdoc));
results.addAll(getMemberKeywords(classdoc.fields()));
results.addAll(getMemberKeywords(classdoc.methods()));
}
return results.toArray(new String[]{});
}
/**
* Get the current class for a meta tag keyword, as the first
* and only element of an array list.
*/
protected ArrayList<String> getClassKeyword(ClassDoc classdoc) {
String cltypelower = classdoc.isInterface() ? "interface" : "class";
ArrayList<String> metakeywords = new ArrayList<String>(1);
metakeywords.add(classdoc.qualifiedName() + " " + cltypelower);
return metakeywords;
}
/**
* Get the package keywords.
*/
public String[] getMetaKeywords(PackageDoc packageDoc) {
if( configuration.keywords ) {
String pkgName = Util.getPackageName(packageDoc);
return new String[] { pkgName + " " + "package" };
} else {
return new String[] {};
}
}
/**
* Get the profile keywords.
*
* @param profile the profile being documented
*/
public String[] getMetaKeywords(Profile profile) {
if( configuration.keywords ) {
String profileName = profile.name;
return new String[] { profileName + " " + "profile" };
} else {
return new String[] {};
}
}
/**
* Get the overview keywords.
*/
public String[] getOverviewMetaKeywords(String title, String docTitle) {
if( configuration.keywords ) {
String windowOverview = configuration.getText(title);
String[] metakeywords = { windowOverview };
if (docTitle.length() > 0 ) {
metakeywords[0] += ", " + docTitle;
}
return metakeywords;
} else {
return new String[] {};
}
}
/**
* Get members for meta tag keywords as an array,
* where each member name is a string element of the array.
* The parameter lists are not included in the keywords;
* therefore all overloaded methods are combined.<br>
* Example: getValue(Object) is returned in array as getValue()
*
* @param memberdocs array of MemberDoc objects to be added to keywords
*/
protected ArrayList<String> getMemberKeywords(MemberDoc[] memberdocs) {
ArrayList<String> results = new ArrayList<String>();
String membername;
for (int i=0; i < memberdocs.length; i++) {
membername = memberdocs[i].name()
+ (memberdocs[i].isMethod() ? "()" : "");
if ( ! results.contains(membername) ) {
results.add(membername);
}
}
return results;
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 1999, 2012, 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 com.sun.javadoc.*;
/**
* This class is useful for searching a method which has documentation
* comment and documentation tags. The method is searched in all the
* superclasses and interfaces(subsequently super-interfaces also)
* recursively.
*
* <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>
*/
public abstract class MethodFinder {
abstract boolean isCorrectMethod(MethodDoc method);
public MethodDoc search(ClassDoc cd, MethodDoc method) {
MethodDoc meth = searchInterfaces(cd, method);
if (meth != null) {
return meth;
}
ClassDoc icd = cd.superclass();
if (icd != null) {
meth = Util.findMethod(icd, method);
if (meth != null) {
if (isCorrectMethod(meth)) {
return meth;
}
}
return search(icd, method);
}
return null;
}
public MethodDoc searchInterfaces(ClassDoc cd, MethodDoc method) {
MethodDoc[] implementedMethods = (new ImplementedMethods(method, null)).build();
for (int i = 0; i < implementedMethods.length; i++) {
if (isCorrectMethod(implementedMethods[i])) {
return implementedMethods[i];
}
}
return null;
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2012, 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;
/**
* Enum representing method types.
*
* @author Bhavesh Patel
*/
public enum MethodTypes {
ALL(0xffff, "doclet.All_Methods", "t0", true),
STATIC(0x1, "doclet.Static_Methods", "t1", false),
INSTANCE(0x2, "doclet.Instance_Methods", "t2", false),
ABSTRACT(0x4, "doclet.Abstract_Methods", "t3", false),
CONCRETE(0x8, "doclet.Concrete_Methods", "t4", false),
DEFAULT(0x10, "doclet.Default_Methods", "t5", false),
DEPRECATED(0x20, "doclet.Deprecated_Methods", "t6", false);
private final int value;
private final String resourceKey;
private final String tabId;
private final boolean isDefaultTab;
MethodTypes(int v, String k, String id, boolean dt) {
this.value = v;
this.resourceKey = k;
this.tabId = id;
this.isDefaultTab = dt;
}
public int value() {
return value;
}
public String resourceKey() {
return resourceKey;
}
public String tabId() {
return tabId;
}
public boolean isDefaultTab() {
return isDefaultTab;
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright (c) 1998, 2013, 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.util.*;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*;
/**
* Write out the package index.
*
* <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>
*
* @see com.sun.javadoc.PackageDoc
* @author Atul M Dambalkar
*/
public class PackageListWriter extends PrintWriter {
private Configuration configuration;
/**
* Constructor.
*
* @param configuration the current configuration of the doclet.
*/
public PackageListWriter(Configuration configuration) throws IOException {
super(DocFile.createFileForOutput(configuration, DocPaths.PACKAGE_LIST).openWriter());
this.configuration = configuration;
}
/**
* Generate the package index.
*
* @param configuration the current configuration of the doclet.
* @throws DocletAbortException
*/
public static void generate(Configuration configuration) {
PackageListWriter packgen;
try {
packgen = new PackageListWriter(configuration);
packgen.generatePackageListFile(configuration.root);
packgen.close();
} catch (IOException exc) {
configuration.message.error("doclet.exception_encountered",
exc.toString(), DocPaths.PACKAGE_LIST);
throw new DocletAbortException(exc);
}
}
protected void generatePackageListFile(RootDoc root) {
PackageDoc[] packages = configuration.packages;
ArrayList<String> names = new ArrayList<String>();
for (int i = 0; i < packages.length; i++) {
// if the -nodeprecated option is set and the package is marked as
// deprecated, do not include it in the packages list.
if (!(configuration.nodeprecated && Util.isDeprecated(packages[i])))
names.add(packages[i].name());
}
Collections.sort(names);
for (int i = 0; i < names.size(); i++) {
println(names.get(i));
}
}
}

View File

@@ -0,0 +1,320 @@
/*
* Copyright (c) 1998, 2013, 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.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.tools.DocumentationTool;
import javax.tools.FileObject;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
import com.sun.tools.doclets.internal.toolkit.Configuration;
import com.sun.tools.javac.nio.PathFileManager;
/**
* Implementation of DocFileFactory using a {@link PathFileManager}.
*
* <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>
*
* @since 1.8
*/
class PathDocFileFactory extends DocFileFactory {
private final PathFileManager fileManager;
private final Path destDir;
public PathDocFileFactory(Configuration configuration) {
super(configuration);
fileManager = (PathFileManager) configuration.getFileManager();
if (!configuration.destDirName.isEmpty()
|| !fileManager.hasLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT)) {
try {
String dirName = configuration.destDirName.isEmpty() ? "." : configuration.destDirName;
Path dir = fileManager.getDefaultFileSystem().getPath(dirName);
fileManager.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(dir));
} catch (IOException e) {
throw new DocletAbortException(e);
}
}
destDir = fileManager.getLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT).iterator().next();
}
public DocFile createFileForDirectory(String file) {
return new StandardDocFile(fileManager.getDefaultFileSystem().getPath(file));
}
public DocFile createFileForInput(String file) {
return new StandardDocFile(fileManager.getDefaultFileSystem().getPath(file));
}
public DocFile createFileForOutput(DocPath path) {
return new StandardDocFile(DocumentationTool.Location.DOCUMENTATION_OUTPUT, path);
}
@Override
Iterable<DocFile> list(Location location, DocPath path) {
if (location != StandardLocation.SOURCE_PATH)
throw new IllegalArgumentException();
Set<DocFile> files = new LinkedHashSet<DocFile>();
if (fileManager.hasLocation(location)) {
for (Path f: fileManager.getLocation(location)) {
if (Files.isDirectory(f)) {
f = f.resolve(path.getPath());
if (Files.exists(f))
files.add(new StandardDocFile(f));
}
}
}
return files;
}
class StandardDocFile extends DocFile {
private Path file;
/** Create a StandardDocFile for a given file. */
private StandardDocFile(Path file) {
super(configuration);
this.file = file;
}
/** Create a StandardDocFile for a given location and relative path. */
private StandardDocFile(Location location, DocPath path) {
super(configuration, location, path);
this.file = destDir.resolve(path.getPath());
}
/** Open an input stream for the file. */
public InputStream openInputStream() throws IOException {
JavaFileObject fo = getJavaFileObjectForInput(file);
return new BufferedInputStream(fo.openInputStream());
}
/**
* Open an output stream for the file.
* The file must have been created with a location of
* {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
*/
public OutputStream openOutputStream() throws IOException, UnsupportedEncodingException {
if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
throw new IllegalStateException();
OutputStream out = getFileObjectForOutput(path).openOutputStream();
return new BufferedOutputStream(out);
}
/**
* Open an writer for the file, using the encoding (if any) given in the
* doclet configuration.
* The file must have been created with a location of
* {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
*/
public Writer openWriter() throws IOException, UnsupportedEncodingException {
if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
throw new IllegalStateException();
OutputStream out = getFileObjectForOutput(path).openOutputStream();
if (configuration.docencoding == null) {
return new BufferedWriter(new OutputStreamWriter(out));
} else {
return new BufferedWriter(new OutputStreamWriter(out, configuration.docencoding));
}
}
/** Return true if the file can be read. */
public boolean canRead() {
return Files.isReadable(file);
}
/** Return true if the file can be written. */
public boolean canWrite() {
return Files.isWritable(file);
}
/** Return true if the file exists. */
public boolean exists() {
return Files.exists(file);
}
/** Return the base name (last component) of the file name. */
public String getName() {
return file.getFileName().toString();
}
/** Return the file system path for this file. */
public String getPath() {
return file.toString();
}
/** Return true is file has an absolute path name. */
public boolean isAbsolute() {
return file.isAbsolute();
}
/** Return true is file identifies a directory. */
public boolean isDirectory() {
return Files.isDirectory(file);
}
/** Return true is file identifies a file. */
public boolean isFile() {
return Files.isRegularFile(file);
}
/** Return true if this file is the same as another. */
public boolean isSameFile(DocFile other) {
if (!(other instanceof StandardDocFile))
return false;
try {
return Files.isSameFile(file, ((StandardDocFile) other).file);
} catch (IOException e) {
return false;
}
}
/** If the file is a directory, list its contents. */
public Iterable<DocFile> list() throws IOException {
List<DocFile> files = new ArrayList<DocFile>();
try (DirectoryStream<Path> ds = Files.newDirectoryStream(file)) {
for (Path f: ds) {
files.add(new StandardDocFile(f));
}
}
return files;
}
/** Create the file as a directory, including any parent directories. */
public boolean mkdirs() {
try {
Files.createDirectories(file);
return true;
} catch (IOException e) {
return false;
}
}
/**
* Derive a new file by resolving a relative path against this file.
* The new file will inherit the configuration and location of this file
* If this file has a path set, the new file will have a corresponding
* new path.
*/
public DocFile resolve(DocPath p) {
return resolve(p.getPath());
}
/**
* Derive a new file by resolving a relative path against this file.
* The new file will inherit the configuration and location of this file
* If this file has a path set, the new file will have a corresponding
* new path.
*/
public DocFile resolve(String p) {
if (location == null && path == null) {
return new StandardDocFile(file.resolve(p));
} else {
return new StandardDocFile(location, path.resolve(p));
}
}
/**
* Resolve a relative file against the given output location.
* @param locn Currently, only
* {@link DocumentationTool.Location.DOCUMENTATION_OUTPUT} is supported.
*/
public DocFile resolveAgainst(Location locn) {
if (locn != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
throw new IllegalArgumentException();
return new StandardDocFile(destDir.resolve(file));
}
/** Return a string to identify the contents of this object,
* for debugging purposes.
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("PathDocFile[");
if (location != null)
sb.append("locn:").append(location).append(",");
if (path != null)
sb.append("path:").append(path.getPath()).append(",");
sb.append("file:").append(file);
sb.append("]");
return sb.toString();
}
private JavaFileObject getJavaFileObjectForInput(Path file) {
return fileManager.getJavaFileObjects(file).iterator().next();
}
private FileObject getFileObjectForOutput(DocPath path) throws IOException {
// break the path into a package-part and the rest, by finding
// the position of the last '/' before an invalid character for a
// package name, such as the "." before an extension or the "-"
// in filenames like package-summary.html, doc-files or src-html.
String p = path.getPath();
int lastSep = -1;
for (int i = 0; i < p.length(); i++) {
char ch = p.charAt(i);
if (ch == '/') {
lastSep = i;
} else if (i == lastSep + 1 && !Character.isJavaIdentifierStart(ch)
|| !Character.isJavaIdentifierPart(ch)) {
break;
}
}
String pkg = (lastSep == -1) ? "" : p.substring(0, lastSep);
String rest = p.substring(lastSep + 1);
return fileManager.getFileForOutput(location, pkg, rest, null);
}
}
}

View File

@@ -0,0 +1,292 @@
/*
* Copyright (c) 1998, 2013, 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.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.tools.DocumentationTool;
import javax.tools.JavaFileManager.Location;
import javax.tools.StandardLocation;
import com.sun.tools.doclets.internal.toolkit.Configuration;
/**
* Implementation of DocFileFactory that just uses java.io.File API,
* and does not use a JavaFileManager..
*
* <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>
*
* @since 1.8
*/
class SimpleDocFileFactory extends DocFileFactory {
public SimpleDocFileFactory(Configuration configuration) {
super(configuration);
}
public DocFile createFileForDirectory(String file) {
return new SimpleDocFile(new File(file));
}
public DocFile createFileForInput(String file) {
return new SimpleDocFile(new File(file));
}
public DocFile createFileForOutput(DocPath path) {
return new SimpleDocFile(DocumentationTool.Location.DOCUMENTATION_OUTPUT, path);
}
@Override
Iterable<DocFile> list(Location location, DocPath path) {
if (location != StandardLocation.SOURCE_PATH)
throw new IllegalArgumentException();
Set<DocFile> files = new LinkedHashSet<DocFile>();
for (String s : configuration.sourcepath.split(File.pathSeparator)) {
if (s.isEmpty())
continue;
File f = new File(s);
if (f.isDirectory()) {
f = new File(f, path.getPath());
if (f.exists())
files.add(new SimpleDocFile(f));
}
}
return files;
}
class SimpleDocFile extends DocFile {
private File file;
/** Create a DocFile for a given file. */
private SimpleDocFile(File file) {
super(configuration);
this.file = file;
}
/** Create a DocFile for a given location and relative path. */
private SimpleDocFile(Location location, DocPath path) {
super(configuration, location, path);
String destDirName = configuration.destDirName;
this.file = destDirName.isEmpty() ? new File(path.getPath())
: new File(destDirName, path.getPath());
}
/** Open an input stream for the file. */
public InputStream openInputStream() throws FileNotFoundException {
return new BufferedInputStream(new FileInputStream(file));
}
/**
* Open an output stream for the file.
* The file must have been created with a location of
* {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
*/
public OutputStream openOutputStream() throws IOException, UnsupportedEncodingException {
if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
throw new IllegalStateException();
createDirectoryForFile(file);
return new BufferedOutputStream(new FileOutputStream(file));
}
/**
* Open an writer for the file, using the encoding (if any) given in the
* doclet configuration.
* The file must have been created with a location of
* {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
*/
public Writer openWriter() throws IOException, UnsupportedEncodingException {
if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
throw new IllegalStateException();
createDirectoryForFile(file);
FileOutputStream fos = new FileOutputStream(file);
if (configuration.docencoding == null) {
return new BufferedWriter(new OutputStreamWriter(fos));
} else {
return new BufferedWriter(new OutputStreamWriter(fos, configuration.docencoding));
}
}
/** Return true if the file can be read. */
public boolean canRead() {
return file.canRead();
}
/** Return true if the file can be written. */
public boolean canWrite() {
return file.canRead();
}
/** Return true if the file exists. */
public boolean exists() {
return file.exists();
}
/** Return the base name (last component) of the file name. */
public String getName() {
return file.getName();
}
/** Return the file system path for this file. */
public String getPath() {
return file.getPath();
}
/** Return true is file has an absolute path name. */
public boolean isAbsolute() {
return file.isAbsolute();
}
/** Return true is file identifies a directory. */
public boolean isDirectory() {
return file.isDirectory();
}
/** Return true is file identifies a file. */
public boolean isFile() {
return file.isFile();
}
/** Return true if this file is the same as another. */
public boolean isSameFile(DocFile other) {
if (!(other instanceof SimpleDocFile))
return false;
try {
return file.exists()
&& file.getCanonicalFile().equals(((SimpleDocFile)other).file.getCanonicalFile());
} catch (IOException e) {
return false;
}
}
/** If the file is a directory, list its contents. */
public Iterable<DocFile> list() {
List<DocFile> files = new ArrayList<DocFile>();
for (File f: file.listFiles()) {
files.add(new SimpleDocFile(f));
}
return files;
}
/** Create the file as a directory, including any parent directories. */
public boolean mkdirs() {
return file.mkdirs();
}
/**
* Derive a new file by resolving a relative path against this file.
* The new file will inherit the configuration and location of this file
* If this file has a path set, the new file will have a corresponding
* new path.
*/
public DocFile resolve(DocPath p) {
return resolve(p.getPath());
}
/**
* Derive a new file by resolving a relative path against this file.
* The new file will inherit the configuration and location of this file
* If this file has a path set, the new file will have a corresponding
* new path.
*/
public DocFile resolve(String p) {
if (location == null && path == null) {
return new SimpleDocFile(new File(file, p));
} else {
return new SimpleDocFile(location, path.resolve(p));
}
}
/**
* Resolve a relative file against the given output location.
* @param locn Currently, only
* {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} is supported.
*/
public DocFile resolveAgainst(Location locn) {
if (locn != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
throw new IllegalArgumentException();
return new SimpleDocFile(
new File(configuration.destDirName, file.getPath()));
}
/**
* Given a path string create all the directories in the path. For example,
* if the path string is "java/applet", the method will create directory
* "java" and then "java/applet" if they don't exist. The file separator
* string "/" is platform dependent system property.
*
* @param path Directory path string.
*/
private void createDirectoryForFile(File file) {
File dir = file.getParentFile();
if (dir == null || dir.exists() || dir.mkdirs())
return;
configuration.message.error(
"doclet.Unable_to_create_directory_0", dir.getPath());
throw new DocletAbortException("can't create directory");
}
/** Return a string to identify the contents of this object,
* for debugging purposes.
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("DocFile[");
if (location != null)
sb.append("locn:").append(location).append(",");
if (path != null)
sb.append("path:").append(path.getPath()).append(",");
sb.append("file:").append(file);
sb.append("]");
return sb.toString();
}
}
}

View File

@@ -0,0 +1,322 @@
/*
* Copyright (c) 1998, 2013, 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.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.tools.DocumentationTool;
import javax.tools.FileObject;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import com.sun.tools.doclets.internal.toolkit.Configuration;
import com.sun.tools.javac.util.Assert;
/**
* Implementation of DocFileFactory using a {@link StandardJavaFileManager}.
*
* <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>
*
* @since 1.8
*/
class StandardDocFileFactory extends DocFileFactory {
private final StandardJavaFileManager fileManager;
private File destDir;
public StandardDocFileFactory(Configuration configuration) {
super(configuration);
fileManager = (StandardJavaFileManager) configuration.getFileManager();
}
private File getDestDir() {
if (destDir == null) {
if (!configuration.destDirName.isEmpty()
|| !fileManager.hasLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT)) {
try {
String dirName = configuration.destDirName.isEmpty() ? "." : configuration.destDirName;
File dir = new File(dirName);
fileManager.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(dir));
} catch (IOException e) {
throw new DocletAbortException(e);
}
}
destDir = fileManager.getLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT).iterator().next();
}
return destDir;
}
public DocFile createFileForDirectory(String file) {
return new StandardDocFile(new File(file));
}
public DocFile createFileForInput(String file) {
return new StandardDocFile(new File(file));
}
public DocFile createFileForOutput(DocPath path) {
return new StandardDocFile(DocumentationTool.Location.DOCUMENTATION_OUTPUT, path);
}
@Override
Iterable<DocFile> list(Location location, DocPath path) {
if (location != StandardLocation.SOURCE_PATH)
throw new IllegalArgumentException();
Set<DocFile> files = new LinkedHashSet<DocFile>();
Location l = fileManager.hasLocation(StandardLocation.SOURCE_PATH)
? StandardLocation.SOURCE_PATH : StandardLocation.CLASS_PATH;
for (File f: fileManager.getLocation(l)) {
if (f.isDirectory()) {
f = new File(f, path.getPath());
if (f.exists())
files.add(new StandardDocFile(f));
}
}
return files;
}
private static File newFile(File dir, String path) {
return (dir == null) ? new File(path) : new File(dir, path);
}
class StandardDocFile extends DocFile {
private File file;
/** Create a StandardDocFile for a given file. */
private StandardDocFile(File file) {
super(configuration);
this.file = file;
}
/** Create a StandardDocFile for a given location and relative path. */
private StandardDocFile(Location location, DocPath path) {
super(configuration, location, path);
Assert.check(location == DocumentationTool.Location.DOCUMENTATION_OUTPUT);
this.file = newFile(getDestDir(), path.getPath());
}
/** Open an input stream for the file. */
public InputStream openInputStream() throws IOException {
JavaFileObject fo = getJavaFileObjectForInput(file);
return new BufferedInputStream(fo.openInputStream());
}
/**
* Open an output stream for the file.
* The file must have been created with a location of
* {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
*/
public OutputStream openOutputStream() throws IOException, UnsupportedEncodingException {
if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
throw new IllegalStateException();
OutputStream out = getFileObjectForOutput(path).openOutputStream();
return new BufferedOutputStream(out);
}
/**
* Open an writer for the file, using the encoding (if any) given in the
* doclet configuration.
* The file must have been created with a location of
* {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
*/
public Writer openWriter() throws IOException, UnsupportedEncodingException {
if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
throw new IllegalStateException();
OutputStream out = getFileObjectForOutput(path).openOutputStream();
if (configuration.docencoding == null) {
return new BufferedWriter(new OutputStreamWriter(out));
} else {
return new BufferedWriter(new OutputStreamWriter(out, configuration.docencoding));
}
}
/** Return true if the file can be read. */
public boolean canRead() {
return file.canRead();
}
/** Return true if the file can be written. */
public boolean canWrite() {
return file.canWrite();
}
/** Return true if the file exists. */
public boolean exists() {
return file.exists();
}
/** Return the base name (last component) of the file name. */
public String getName() {
return file.getName();
}
/** Return the file system path for this file. */
public String getPath() {
return file.getPath();
}
/** Return true is file has an absolute path name. */
public boolean isAbsolute() {
return file.isAbsolute();
}
/** Return true is file identifies a directory. */
public boolean isDirectory() {
return file.isDirectory();
}
/** Return true is file identifies a file. */
public boolean isFile() {
return file.isFile();
}
/** Return true if this file is the same as another. */
public boolean isSameFile(DocFile other) {
if (!(other instanceof StandardDocFile))
return false;
try {
return file.exists()
&& file.getCanonicalFile().equals(((StandardDocFile) other).file.getCanonicalFile());
} catch (IOException e) {
return false;
}
}
/** If the file is a directory, list its contents. */
public Iterable<DocFile> list() {
List<DocFile> files = new ArrayList<DocFile>();
for (File f: file.listFiles()) {
files.add(new StandardDocFile(f));
}
return files;
}
/** Create the file as a directory, including any parent directories. */
public boolean mkdirs() {
return file.mkdirs();
}
/**
* Derive a new file by resolving a relative path against this file.
* The new file will inherit the configuration and location of this file
* If this file has a path set, the new file will have a corresponding
* new path.
*/
public DocFile resolve(DocPath p) {
return resolve(p.getPath());
}
/**
* Derive a new file by resolving a relative path against this file.
* The new file will inherit the configuration and location of this file
* If this file has a path set, the new file will have a corresponding
* new path.
*/
public DocFile resolve(String p) {
if (location == null && path == null) {
return new StandardDocFile(new File(file, p));
} else {
return new StandardDocFile(location, path.resolve(p));
}
}
/**
* Resolve a relative file against the given output location.
* @param locn Currently, only
* {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} is supported.
*/
public DocFile resolveAgainst(Location locn) {
if (locn != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
throw new IllegalArgumentException();
return new StandardDocFile(newFile(getDestDir(), file.getPath()));
}
/** Return a string to identify the contents of this object,
* for debugging purposes.
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("StandardDocFile[");
if (location != null)
sb.append("locn:").append(location).append(",");
if (path != null)
sb.append("path:").append(path.getPath()).append(",");
sb.append("file:").append(file);
sb.append("]");
return sb.toString();
}
private JavaFileObject getJavaFileObjectForInput(File file) {
return fileManager.getJavaFileObjects(file).iterator().next();
}
private FileObject getFileObjectForOutput(DocPath path) throws IOException {
// break the path into a package-part and the rest, by finding
// the position of the last '/' before an invalid character for a
// package name, such as the "." before an extension or the "-"
// in filenames like package-summary.html, doc-files or src-html.
String p = path.getPath();
int lastSep = -1;
for (int i = 0; i < p.length(); i++) {
char ch = p.charAt(i);
if (ch == '/') {
lastSep = i;
} else if (i == lastSep + 1 && !Character.isJavaIdentifierStart(ch)
|| !Character.isJavaIdentifierPart(ch)) {
break;
}
}
String pkg = (lastSep == -1) ? "" : p.substring(0, lastSep);
String rest = p.substring(lastSep + 1);
return fileManager.getFileForOutput(location, pkg, rest, null);
}
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 1999, 2012, 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 com.sun.javadoc.*;
/**
* Find a tagged method.
*
* <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
*/
public class TaggedMethodFinder extends MethodFinder {
public boolean isCorrectMethod(MethodDoc method) {
return method.paramTags().length + method.tags("return").length +
method.throwsTags().length + method.seeTags().length > 0;
}
}

View File

@@ -0,0 +1,110 @@
/*
* Copyright (c) 2003, 2012, 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 com.sun.javadoc.*;
/**
* A tag that holds nothing but plain text. This is useful for passing
* text to methods that only accept inline tags as a parameter.
*
* <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 Jamie Ho
* @since 1.5
*/
public class TextTag implements Tag {
protected final String text;
protected final String name = "Text";
protected final Doc holder;
/**
* Constructor
*/
public TextTag(Doc holder, String text) {
super();
this.holder = holder;
this.text = text;
}
/**
* {@inheritDoc}
*/
public String name() {
return name;
}
/**
* {@inheritDoc}
*/
public Doc holder() {
return holder;
}
/**
* {@inheritDoc}
*/
public String kind() {
return name;
}
/**
* {@inheritDoc}
*/
public String text() {
return text;
}
/**
* {@inheritDoc}
*/
public String toString() {
return name + ":" + text;
}
/**
* {@inheritDoc}
*/
public Tag[] inlineTags() {
return new Tag[] {this};
}
/**
* {@inheritDoc}
*/
public Tag[] firstSentenceTags() {
return new Tag[] {this};
}
/**
* {@inheritDoc}
*/
public SourcePosition position() {
return holder.position();
}
}

View File

@@ -0,0 +1,792 @@
/*
* Copyright (c) 1999, 2013, 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.ElementType;
import java.util.*;
import javax.tools.StandardLocation;
import com.sun.javadoc.*;
import com.sun.javadoc.AnnotationDesc.ElementValuePair;
import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.javac.util.StringUtils;
/**
* 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
*/
public class Util {
/**
* 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 static 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.
*
* @param members Array of members to choose from.
* @return List List of eligible members for whom
* documentation is getting generated.
*/
public static List<ProgramElementDoc> excludeDeprecatedMembersAsList(
ProgramElementDoc[] members) {
List<ProgramElementDoc> list = new ArrayList<ProgramElementDoc>();
for (int i = 0; i < members.length; i++) {
if (members[i].tags("deprecated").length == 0) {
list.add(members[i]);
}
}
Collections.sort(list);
return list;
}
/**
* Return the list of ProgramElementDoc objects as Array.
*/
public static 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.
*
* @param members Array of members to look into.
* @return boolean True if non-public member found, false otherwise.
*/
public static boolean nonPublicMemberFound(ProgramElementDoc[] members) {
for (int i = 0; i < members.length; i++) {
if (!members[i].isPublic()) {
return true;
}
}
return false;
}
/**
* 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 static MethodDoc findMethod(ClassDoc cd, MethodDoc method) {
MethodDoc[] methods = cd.methods();
for (int i = 0; i < methods.length; i++) {
if (executableMembersEqual(method, methods[i])) {
return methods[i];
}
}
return null;
}
/**
* @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 static 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
* <cite>The Java&trade; Language Specification</cite>,
* all the outer classes and static inner classes are core classes.
*/
public static boolean isCoreClass(ClassDoc cd) {
return cd.containingClass() == null || cd.isStatic();
}
public static 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
* {@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 static void copyDocFiles(Configuration configuration, PackageDoc pd) {
copyDocFiles(configuration, DocPath.forPackage(pd).resolve(DocPaths.DOC_FILES));
}
public static void copyDocFiles(Configuration configuration, DocPath dir) {
try {
boolean first = true;
for (DocFile f : DocFile.list(configuration, StandardLocation.SOURCE_PATH, 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, dir.resolve(srcfile.getName()));
}
}
}
first = false;
}
} catch (SecurityException exc) {
throw new DocletAbortException(exc);
} catch (IOException exc) {
throw new DocletAbortException(exc);
}
}
/**
* 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 type1.qualifiedTypeName().compareToIgnoreCase(
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.
*
* @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 static 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 (int i = 0; i < interfaceTypes.length; i++) {
Type interfaceType = interfaceTypes[i];
ClassDoc interfaceClassDoc = interfaceType.asClassDoc();
if (! (interfaceClassDoc.isPublic() ||
(configuration == null ||
isLinkable(interfaceClassDoc, configuration)))) {
continue;
}
results.put(interfaceClassDoc, interfaceType);
List<Type> superInterfaces = getAllInterfaces(interfaceType, configuration, sort);
for (Iterator<Type> iter = superInterfaces.iterator(); iter.hasNext(); ) {
Type t = iter.next();
results.put(t.asClassDoc(), t);
}
}
if (superType == null)
return new ArrayList<Type>(results.values());
//Try walking the tree.
addAllInterfaceTypes(results,
superType,
interfaceTypesOf(superType),
false, configuration);
List<Type> resultsList = new ArrayList<Type>(results.values());
if (sort) {
Collections.sort(resultsList, new TypeComparator());
}
return resultsList;
}
private static Type[] interfaceTypesOf(Type type) {
if (type instanceof AnnotatedType)
type = ((AnnotatedType)type).underlyingType();
return type instanceof ClassDoc ?
((ClassDoc)type).interfaceTypes() :
((ParameterizedType)type).interfaceTypes();
}
public static List<Type> getAllInterfaces(Type type, Configuration configuration) {
return getAllInterfaces(type, configuration, true);
}
private static 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 static 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 static void addAllInterfaceTypes(Map<ClassDoc,Type> results, Type type,
Type[] interfaceTypes, boolean raw,
Configuration configuration) {
for (int i = 0; i < interfaceTypes.length; i++) {
Type interfaceType = interfaceTypes[i];
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 (Iterator<Type> iter = superInterfaces.iterator(); iter.hasNext(); ) {
Type superInterface = iter.next();
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
*/
public static String quote(String filepath) {
return ("\"" + filepath + "\"");
}
/**
* Given a package, return its name.
* @param packageDoc the package to check.
* @return the name of the given package.
*/
public static 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.
* @param packageDoc the package to check.
* @return the file name of the given package.
*/
public static 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'.
* @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 static 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.
*
* @param annotationDoc the annotation to check.
*
* @return true return true if it should be documented and false otherwise.
*/
public static boolean isDocumentedAnnotation(AnnotationTypeDoc annotationDoc) {
AnnotationDesc[] annotationDescList = annotationDoc.annotations();
for (int i = 0; i < annotationDescList.length; i++) {
if (annotationDescList[i].annotationType().qualifiedName().equals(
java.lang.annotation.Documented.class.getName())){
return true;
}
}
return false;
}
private static boolean isDeclarationTarget(AnnotationDesc targetAnno) {
// The error recovery steps here are analogous to TypeAnnotations
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
AnnotationValue[] values = (AnnotationValue[])elems[0].value().value();
for (int i = 0; i < values.length; i++) {
Object value = values[i].value();
if (!(value instanceof FieldDoc))
return true; // error recovery
FieldDoc eValue = (FieldDoc)value;
if (Util.isJava5DeclarationElementType(eValue)) {
return true;
}
}
return false;
}
/**
* 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 static 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 (int i = 0; i < annotationDescList.length; i++) {
if (annotationDescList[i].annotationType().qualifiedName().equals(
java.lang.annotation.Target.class.getName())) {
if (isDeclarationTarget(annotationDescList[i]))
return true;
}
}
return false;
}
/**
* 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 static 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.
*
* @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 static 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.
*
* @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 static 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.).
*
* @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 static 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.
* @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 static String replaceTabs(Configuration configuration, String text) {
if (text.indexOf("\t") == -1)
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 static 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.
*/
public static void setEnumDocumentation(Configuration configuration,
ClassDoc classDoc) {
MethodDoc[] methods = classDoc.methods();
for (int j = 0; j < methods.length; j++) {
MethodDoc currentMethod = methods[j];
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.
*
* @param doc the Doc to check.
* @return true if the given Doc is deprecated.
*/
public static 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 (int i = 0; i < annotationDescList.length; i++) {
if (annotationDescList[i].annotationType().qualifiedName().equals(
java.lang.Deprecated.class.getName())){
return true;
}
}
return false;
}
/**
* 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 static 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.
*
* @param classes array of classes to be filtered.
* @param javafx set to true if in JavaFX mode.
* @return list of filtered classes.
*/
public static ClassDoc[] filterOutPrivateClasses(final ClassDoc[] classes,
boolean javafx) {
if (!javafx) {
return classes;
}
final List<ClassDoc> filteredOutClasses =
new ArrayList<ClassDoc>(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.
*
* @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 static 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());
}
}

View File

@@ -0,0 +1,780 @@
/*
* Copyright (c) 1999, 2016, 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.util.*;
import java.util.regex.Pattern;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*;
/**
* A data structure that encapsulates the visible members of a particular
* type for a given class tree. To use this data structor, you must specify
* the type of member you are interested in (nested class, field, constructor
* or method) and the leaf of the class tree. The data structure will map
* all visible members in the leaf and classes above the leaf in the tree.
*
* <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 (rewrite)
*/
public class VisibleMemberMap {
private boolean noVisibleMembers = true;
public static final int INNERCLASSES = 0;
public static final int ENUM_CONSTANTS = 1;
public static final int FIELDS = 2;
public static final int CONSTRUCTORS = 3;
public static final int METHODS = 4;
public static final int ANNOTATION_TYPE_FIELDS = 5;
public static final int ANNOTATION_TYPE_MEMBER_OPTIONAL = 6;
public static final int ANNOTATION_TYPE_MEMBER_REQUIRED = 7;
public static final int PROPERTIES = 8;
/**
* The total number of member types is {@value}.
*/
public static final int NUM_MEMBER_TYPES = 9;
public static final String STARTLEVEL = "start";
/**
* List of ClassDoc objects for which ClassMembers objects are built.
*/
private final List<ClassDoc> visibleClasses = new ArrayList<ClassDoc>();
/**
* Map for each member name on to a map which contains members with same
* name-signature. The mapped map will contain mapping for each MemberDoc
* onto it's respecive level string.
*/
private final Map<Object,Map<ProgramElementDoc,String>> memberNameMap = new HashMap<Object,Map<ProgramElementDoc,String>>();
/**
* Map of class and it's ClassMembers object.
*/
private final Map<ClassDoc,ClassMembers> classMap = new HashMap<ClassDoc,ClassMembers>();
/**
* Type whose visible members are requested. This is the leaf of
* the class tree being mapped.
*/
private final ClassDoc classdoc;
/**
* Member kind: InnerClasses/Fields/Methods?
*/
private final int kind;
/**
* The configuration this VisibleMemberMap was created with.
*/
private final Configuration configuration;
private static final Map<ClassDoc, ProgramElementDoc[]> propertiesCache =
new HashMap<ClassDoc, ProgramElementDoc[]>();
private static final Map<ProgramElementDoc, ProgramElementDoc> classPropertiesMap =
new HashMap<ProgramElementDoc, ProgramElementDoc>();
private static final Map<ProgramElementDoc, GetterSetter> getterSetterMap =
new HashMap<ProgramElementDoc, GetterSetter>();
/**
* Construct a VisibleMemberMap of the given type for the given
* class.
*
* @param classdoc the class whose members are being mapped.
* @param kind the kind of member that is being mapped.
* @param configuration the configuration to use to construct this
* VisibleMemberMap. If the field configuration.nodeprecated is true the
* deprecated members are excluded from the map. If the field
* configuration.javafx is true the JavaFX features are used.
*/
public VisibleMemberMap(ClassDoc classdoc,
int kind,
Configuration configuration) {
this.classdoc = classdoc;
this.kind = kind;
this.configuration = configuration;
new ClassMembers(classdoc, STARTLEVEL).build();
}
/**
* Return the list of visible classes in this map.
*
* @return the list of visible classes in this map.
*/
public List<ClassDoc> getVisibleClassesList() {
sort(visibleClasses);
return visibleClasses;
}
/**
* Returns the property field documentation belonging to the given member.
* @param ped the member for which the property documentation is needed.
* @return the property field documentation, null if there is none.
*/
public ProgramElementDoc getPropertyMemberDoc(ProgramElementDoc ped) {
return classPropertiesMap.get(ped);
}
/**
* Returns the getter documentation belonging to the given property method.
* @param propertyMethod the method for which the getter is needed.
* @return the getter documentation, null if there is none.
*/
public ProgramElementDoc getGetterForProperty(ProgramElementDoc propertyMethod) {
return getterSetterMap.get(propertyMethod).getGetter();
}
/**
* Returns the setter documentation belonging to the given property method.
* @param propertyMethod the method for which the setter is needed.
* @return the setter documentation, null if there is none.
*/
public ProgramElementDoc getSetterForProperty(ProgramElementDoc propertyMethod) {
return getterSetterMap.get(propertyMethod).getSetter();
}
/**
* Return the package private members inherited by the class. Only return
* if parent is package private and not documented.
*
* @param configuration the current configuration of the doclet.
* @return the package private members inherited by the class.
*/
private List<ProgramElementDoc> getInheritedPackagePrivateMethods(Configuration configuration) {
List<ProgramElementDoc> results = new ArrayList<ProgramElementDoc>();
for (Iterator<ClassDoc> iter = visibleClasses.iterator(); iter.hasNext(); ) {
ClassDoc currentClass = iter.next();
if (currentClass != classdoc &&
currentClass.isPackagePrivate() &&
!Util.isLinkable(currentClass, configuration)) {
// Document these members in the child class because
// the parent is inaccessible.
results.addAll(getMembersFor(currentClass));
}
}
return results;
}
/**
* Return the visible members of the class being mapped. Also append at the
* end of the list members that are inherited by inaccessible parents. We
* document these members in the child because the parent is not documented.
*
* @param configuration the current configuration of the doclet.
*/
public List<ProgramElementDoc> getLeafClassMembers(Configuration configuration) {
List<ProgramElementDoc> result = getMembersFor(classdoc);
result.addAll(getInheritedPackagePrivateMethods(configuration));
return result;
}
/**
* Retrn the list of members for the given class.
*
* @param cd the class to retrieve the list of visible members for.
*
* @return the list of members for the given class.
*/
public List<ProgramElementDoc> getMembersFor(ClassDoc cd) {
ClassMembers clmembers = classMap.get(cd);
if (clmembers == null) {
return new ArrayList<ProgramElementDoc>();
}
return clmembers.getMembers();
}
/**
* Sort the given mixed list of classes and interfaces to a list of
* classes followed by interfaces traversed. Don't sort alphabetically.
*/
private void sort(List<ClassDoc> list) {
List<ClassDoc> classes = new ArrayList<ClassDoc>();
List<ClassDoc> interfaces = new ArrayList<ClassDoc>();
for (int i = 0; i < list.size(); i++) {
ClassDoc cd = list.get(i);
if (cd.isClass()) {
classes.add(cd);
} else {
interfaces.add(cd);
}
}
list.clear();
list.addAll(classes);
list.addAll(interfaces);
}
private void fillMemberLevelMap(List<ProgramElementDoc> list, String level) {
for (int i = 0; i < list.size(); i++) {
Object key = getMemberKey(list.get(i));
Map<ProgramElementDoc,String> memberLevelMap = memberNameMap.get(key);
if (memberLevelMap == null) {
memberLevelMap = new HashMap<ProgramElementDoc,String>();
memberNameMap.put(key, memberLevelMap);
}
memberLevelMap.put(list.get(i), level);
}
}
private void purgeMemberLevelMap(List<ProgramElementDoc> list, String level) {
for (int i = 0; i < list.size(); i++) {
Object key = getMemberKey(list.get(i));
Map<ProgramElementDoc, String> memberLevelMap = memberNameMap.get(key);
if (memberLevelMap != null && level.equals(memberLevelMap.get(list.get(i))))
memberLevelMap.remove(list.get(i));
}
}
/**
* Represents a class member. We should be able to just use a
* ProgramElementDoc instead of this class, but that doesn't take
* type variables in consideration when comparing.
*/
private class ClassMember {
private Set<ProgramElementDoc> members;
public ClassMember(ProgramElementDoc programElementDoc) {
members = new HashSet<ProgramElementDoc>();
members.add(programElementDoc);
}
public void addMember(ProgramElementDoc programElementDoc) {
members.add(programElementDoc);
}
public boolean isEqual(MethodDoc member) {
for (Iterator<ProgramElementDoc> iter = members.iterator(); iter.hasNext(); ) {
MethodDoc member2 = (MethodDoc) iter.next();
if (Util.executableMembersEqual(member, member2)) {
members.add(member);
return true;
}
}
return false;
}
}
/**
* A data structure that represents the class members for
* a visible class.
*/
private class ClassMembers {
/**
* The mapping class, whose inherited members are put in the
* {@link #members} list.
*/
private ClassDoc mappingClass;
/**
* List of inherited members from the mapping class.
*/
private List<ProgramElementDoc> members = new ArrayList<ProgramElementDoc>();
/**
* Level/Depth of inheritance.
*/
private String level;
/**
* Return list of inherited members from mapping class.
*
* @return List Inherited members.
*/
public List<ProgramElementDoc> getMembers() {
return members;
}
private ClassMembers(ClassDoc mappingClass, String level) {
this.mappingClass = mappingClass;
this.level = level;
if (classMap.containsKey(mappingClass) &&
level.startsWith(classMap.get(mappingClass).level)) {
//Remove lower level class so that it can be replaced with
//same class found at higher level.
purgeMemberLevelMap(getClassMembers(mappingClass, false),
classMap.get(mappingClass).level);
classMap.remove(mappingClass);
visibleClasses.remove(mappingClass);
}
if (!classMap.containsKey(mappingClass)) {
classMap.put(mappingClass, this);
visibleClasses.add(mappingClass);
}
}
private void build() {
if (kind == CONSTRUCTORS) {
addMembers(mappingClass);
} else {
mapClass();
}
}
private void mapClass() {
addMembers(mappingClass);
ClassDoc[] interfaces = mappingClass.interfaces();
for (int i = 0; i < interfaces.length; i++) {
String locallevel = level + 1;
ClassMembers cm = new ClassMembers(interfaces[i], locallevel);
cm.mapClass();
}
if (mappingClass.isClass()) {
ClassDoc superclass = mappingClass.superclass();
if (!(superclass == null || mappingClass.equals(superclass))) {
ClassMembers cm = new ClassMembers(superclass,
level + "c");
cm.mapClass();
}
}
}
/**
* Get all the valid members from the mapping class. Get the list of
* members for the class to be included into(ctii), also get the level
* string for ctii. If mapping class member is not already in the
* inherited member list and if it is visible in the ctii and not
* overridden, put such a member in the inherited member list.
* Adjust member-level-map, class-map.
*/
private void addMembers(ClassDoc fromClass) {
List<ProgramElementDoc> cdmembers = getClassMembers(fromClass, true);
List<ProgramElementDoc> incllist = new ArrayList<ProgramElementDoc>();
for (int i = 0; i < cdmembers.size(); i++) {
ProgramElementDoc pgmelem = cdmembers.get(i);
if (!found(members, pgmelem) &&
memberIsVisible(pgmelem) &&
!isOverridden(pgmelem, level) &&
!isTreatedAsPrivate(pgmelem)) {
incllist.add(pgmelem);
}
}
if (incllist.size() > 0) {
noVisibleMembers = false;
}
members.addAll(incllist);
fillMemberLevelMap(getClassMembers(fromClass, false), level);
}
private boolean isTreatedAsPrivate(ProgramElementDoc pgmelem) {
if (!configuration.javafx) {
return false;
}
Tag[] aspTags = pgmelem.tags("@treatAsPrivate");
boolean result = (aspTags != null) && (aspTags.length > 0);
return result;
}
/**
* Is given doc item visible in given classdoc in terms fo inheritance?
* The given doc item is visible in the given classdoc if it is public
* or protected and if it is package-private if it's containing class
* is in the same package as the given classdoc.
*/
private boolean memberIsVisible(ProgramElementDoc pgmdoc) {
if (pgmdoc.containingClass().equals(classdoc)) {
//Member is in class that we are finding visible members for.
//Of course it is visible.
return true;
} else if (pgmdoc.isPrivate()) {
//Member is in super class or implemented interface.
//Private, so not inherited.
return false;
} else if (pgmdoc.isPackagePrivate()) {
//Member is package private. Only return true if its class is in
//same package.
return pgmdoc.containingClass().containingPackage().equals(
classdoc.containingPackage());
} else {
//Public members are always inherited.
return true;
}
}
/**
* Return all available class members.
*/
private List<ProgramElementDoc> getClassMembers(ClassDoc cd, boolean filter) {
if (cd.isEnum() && kind == CONSTRUCTORS) {
//If any of these rules are hit, return empty array because
//we don't document these members ever.
return Arrays.asList(new ProgramElementDoc[] {});
}
ProgramElementDoc[] members = null;
switch (kind) {
case ANNOTATION_TYPE_FIELDS:
members = cd.fields(filter);
break;
case ANNOTATION_TYPE_MEMBER_OPTIONAL:
members = cd.isAnnotationType() ?
filter((AnnotationTypeDoc) cd, false) :
new AnnotationTypeElementDoc[] {};
break;
case ANNOTATION_TYPE_MEMBER_REQUIRED:
members = cd.isAnnotationType() ?
filter((AnnotationTypeDoc) cd, true) :
new AnnotationTypeElementDoc[] {};
break;
case INNERCLASSES:
members = cd.innerClasses(filter);
break;
case ENUM_CONSTANTS:
members = cd.enumConstants();
break;
case FIELDS:
members = cd.fields(filter);
break;
case CONSTRUCTORS:
members = cd.constructors();
break;
case METHODS:
members = cd.methods(filter);
checkOnPropertiesTags((MethodDoc[])members);
break;
case PROPERTIES:
members = properties(cd, filter);
break;
default:
members = new ProgramElementDoc[0];
}
// Deprected members should be excluded or not?
if (configuration.nodeprecated) {
return Util.excludeDeprecatedMembersAsList(members);
}
return Arrays.asList(members);
}
/**
* Filter the annotation type members and return either the required
* members or the optional members, depending on the value of the
* required parameter.
*
* @param doc The annotation type to process.
* @param required
* @return the annotation type members and return either the required
* members or the optional members, depending on the value of the
* required parameter.
*/
private AnnotationTypeElementDoc[] filter(AnnotationTypeDoc doc,
boolean required) {
AnnotationTypeElementDoc[] members = doc.elements();
List<AnnotationTypeElementDoc> targetMembers = new ArrayList<AnnotationTypeElementDoc>();
for (int i = 0; i < members.length; i++) {
if ((required && members[i].defaultValue() == null) ||
((!required) && members[i].defaultValue() != null)){
targetMembers.add(members[i]);
}
}
return targetMembers.toArray(new AnnotationTypeElementDoc[]{});
}
private boolean found(List<ProgramElementDoc> list, ProgramElementDoc elem) {
for (int i = 0; i < list.size(); i++) {
ProgramElementDoc pgmelem = list.get(i);
if (Util.matches(pgmelem, elem)) {
return true;
}
}
return false;
}
/**
* Is member overridden? The member is overridden if it is found in the
* same level hierarchy e.g. member at level "11" overrides member at
* level "111".
*/
private boolean isOverridden(ProgramElementDoc pgmdoc, String level) {
Map<?,String> memberLevelMap = (Map<?,String>) memberNameMap.get(getMemberKey(pgmdoc));
if (memberLevelMap == null)
return false;
String mappedlevel = null;
Iterator<String> iterator = memberLevelMap.values().iterator();
while (iterator.hasNext()) {
mappedlevel = iterator.next();
if (mappedlevel.equals(STARTLEVEL) ||
(level.startsWith(mappedlevel) &&
!level.equals(mappedlevel))) {
return true;
}
}
return false;
}
private ProgramElementDoc[] properties(final ClassDoc cd, final boolean filter) {
final MethodDoc[] allMethods = cd.methods(filter);
final FieldDoc[] allFields = cd.fields(false);
if (propertiesCache.containsKey(cd)) {
return propertiesCache.get(cd);
}
final List<MethodDoc> result = new ArrayList<MethodDoc>();
for (final MethodDoc propertyMethod : allMethods) {
if (!isPropertyMethod(propertyMethod)) {
continue;
}
final MethodDoc getter = getterForField(allMethods, propertyMethod);
final MethodDoc setter = setterForField(allMethods, propertyMethod);
final FieldDoc field = fieldForProperty(allFields, propertyMethod);
addToPropertiesMap(setter, getter, propertyMethod, field);
getterSetterMap.put(propertyMethod, new GetterSetter(getter, setter));
result.add(propertyMethod);
}
final ProgramElementDoc[] resultAray =
result.toArray(new ProgramElementDoc[result.size()]);
propertiesCache.put(cd, resultAray);
return resultAray;
}
private void addToPropertiesMap(MethodDoc setter,
MethodDoc getter,
MethodDoc propertyMethod,
FieldDoc field) {
if ((field == null)
|| (field.getRawCommentText() == null)
|| field.getRawCommentText().length() == 0) {
addToPropertiesMap(setter, propertyMethod);
addToPropertiesMap(getter, propertyMethod);
addToPropertiesMap(propertyMethod, propertyMethod);
} else {
addToPropertiesMap(getter, field);
addToPropertiesMap(setter, field);
addToPropertiesMap(propertyMethod, field);
}
}
private void addToPropertiesMap(ProgramElementDoc propertyMethod,
ProgramElementDoc commentSource) {
if (null == propertyMethod || null == commentSource) {
return;
}
final String methodRawCommentText = propertyMethod.getRawCommentText();
/* The second condition is required for the property buckets. In
* this case the comment is at the property method (not at the field)
* and it needs to be listed in the map.
*/
if ((null == methodRawCommentText || 0 == methodRawCommentText.length())
|| propertyMethod.equals(commentSource)) {
classPropertiesMap.put(propertyMethod, commentSource);
}
}
private MethodDoc getterForField(MethodDoc[] methods,
MethodDoc propertyMethod) {
final String propertyMethodName = propertyMethod.name();
final String fieldName =
propertyMethodName.substring(0,
propertyMethodName.lastIndexOf("Property"));
final String fieldNameUppercased =
"" + Character.toUpperCase(fieldName.charAt(0))
+ fieldName.substring(1);
final String getterNamePattern;
final String fieldTypeName = propertyMethod.returnType().toString();
if ("boolean".equals(fieldTypeName)
|| fieldTypeName.endsWith("BooleanProperty")) {
getterNamePattern = "(is|get)" + fieldNameUppercased;
} else {
getterNamePattern = "get" + fieldNameUppercased;
}
for (MethodDoc methodDoc : methods) {
if (Pattern.matches(getterNamePattern, methodDoc.name())) {
if (0 == methodDoc.parameters().length
&& (methodDoc.isPublic() || methodDoc.isProtected())) {
return methodDoc;
}
}
}
return null;
}
private MethodDoc setterForField(MethodDoc[] methods,
MethodDoc propertyMethod) {
final String propertyMethodName = propertyMethod.name();
final String fieldName =
propertyMethodName.substring(0,
propertyMethodName.lastIndexOf("Property"));
final String fieldNameUppercased =
"" + Character.toUpperCase(fieldName.charAt(0))
+ fieldName.substring(1);
final String setter = "set" + fieldNameUppercased;
for (MethodDoc methodDoc : methods) {
if (setter.equals(methodDoc.name())) {
if (1 == methodDoc.parameters().length
&& "void".equals(methodDoc.returnType().simpleTypeName())
&& (methodDoc.isPublic() || methodDoc.isProtected())) {
return methodDoc;
}
}
}
return null;
}
private FieldDoc fieldForProperty(FieldDoc[] fields, MethodDoc property) {
for (FieldDoc field : fields) {
final String fieldName = field.name();
final String propertyName = fieldName + "Property";
if (propertyName.equals(property.name())) {
return field;
}
}
return null;
}
// properties aren't named setA* or getA*
private final Pattern pattern = Pattern.compile("[sg]et\\p{Upper}.*");
private boolean isPropertyMethod(MethodDoc method) {
if (!configuration.javafx) {
return false;
}
if (!method.name().endsWith("Property")) {
return false;
}
if (! memberIsVisible(method)) {
return false;
}
if (pattern.matcher(method.name()).matches()) {
return false;
}
if (method.typeParameters().length > 0) {
return false;
}
return 0 == method.parameters().length
&& !"void".equals(method.returnType().simpleTypeName());
}
private void checkOnPropertiesTags(MethodDoc[] members) {
for (MethodDoc methodDoc: members) {
if (methodDoc.isIncluded()) {
for (Tag tag: methodDoc.tags()) {
String tagName = tag.name();
if (tagName.equals("@propertySetter")
|| tagName.equals("@propertyGetter")
|| tagName.equals("@propertyDescription")) {
if (!isPropertyGetterOrSetter(members, methodDoc)) {
configuration.message.warning(tag.position(),
"doclet.javafx_tag_misuse");
}
break;
}
}
}
}
}
private boolean isPropertyGetterOrSetter(MethodDoc[] members,
MethodDoc methodDoc) {
boolean found = false;
String propertyName = Util.propertyNameFromMethodName(configuration, methodDoc.name());
if (!propertyName.isEmpty()) {
String propertyMethodName = propertyName + "Property";
for (MethodDoc member: members) {
if (member.name().equals(propertyMethodName)) {
found = true;
break;
}
}
}
return found;
}
}
private class GetterSetter {
private final ProgramElementDoc getter;
private final ProgramElementDoc setter;
public GetterSetter(ProgramElementDoc getter, ProgramElementDoc setter) {
this.getter = getter;
this.setter = setter;
}
public ProgramElementDoc getGetter() {
return getter;
}
public ProgramElementDoc getSetter() {
return setter;
}
}
/**
* Return true if this map has no visible members.
*
* @return true if this map has no visible members.
*/
public boolean noVisibleMembers() {
return noVisibleMembers;
}
private ClassMember getClassMember(MethodDoc member) {
for (Iterator<?> iter = memberNameMap.keySet().iterator(); iter.hasNext();) {
Object key = iter.next();
if (key instanceof String) {
continue;
} else if (((ClassMember) key).isEqual(member)) {
return (ClassMember) key;
}
}
return new ClassMember(member);
}
/**
* Return the key to the member map for the given member.
*/
private Object getMemberKey(ProgramElementDoc doc) {
if (doc.isConstructor()) {
return doc.name() + ((ExecutableMemberDoc)doc).signature();
} else if (doc.isMethod()) {
return getClassMember((MethodDoc) doc);
} else if (doc.isField() || doc.isEnumConstant() || doc.isAnnotationTypeElement()) {
return doc.name();
} else { // it's a class or interface
String classOrIntName = doc.name();
//Strip off the containing class name because we only want the member name.
classOrIntName = classOrIntName.indexOf('.') != 0 ? classOrIntName.substring(classOrIntName.lastIndexOf('.'), classOrIntName.length()) : classOrIntName;
return "clint" + classOrIntName;
}
}
}

View File

@@ -0,0 +1,261 @@
/*
* Copyright (c) 2003, 2013, 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.links;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.Content;
/**
* A factory that constructs links from given link information.
*
* <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 Jamie Ho
* @since 1.5
*/
public abstract class LinkFactory {
/**
* Return an empty instance of a content object.
*
* @return an empty instance of a content object.
*/
protected abstract Content newContent();
/**
* Constructs a link from the given link information.
*
* @param linkInfo the information about the link.
* @return the output of the link.
*/
public Content getLink(LinkInfo linkInfo) {
if (linkInfo.type != null) {
Type type = linkInfo.type;
Content link = newContent();
if (type.isPrimitive()) {
//Just a primitive.
link.addContent(type.typeName());
} else if (type.asAnnotatedType() != null && type.dimension().length() == 0) {
link.addContent(getTypeAnnotationLinks(linkInfo));
linkInfo.type = type.asAnnotatedType().underlyingType();
link.addContent(getLink(linkInfo));
return link;
} else if (type.asWildcardType() != null) {
//Wildcard type.
linkInfo.isTypeBound = true;
link.addContent("?");
WildcardType wildcardType = type.asWildcardType();
Type[] extendsBounds = wildcardType.extendsBounds();
for (int i = 0; i < extendsBounds.length; i++) {
link.addContent(i > 0 ? ", " : " extends ");
setBoundsLinkInfo(linkInfo, extendsBounds[i]);
link.addContent(getLink(linkInfo));
}
Type[] superBounds = wildcardType.superBounds();
for (int i = 0; i < superBounds.length; i++) {
link.addContent(i > 0 ? ", " : " super ");
setBoundsLinkInfo(linkInfo, superBounds[i]);
link.addContent(getLink(linkInfo));
}
} else if (type.asTypeVariable()!= null) {
link.addContent(getTypeAnnotationLinks(linkInfo));
linkInfo.isTypeBound = true;
//A type variable.
Doc owner = type.asTypeVariable().owner();
if ((! linkInfo.excludeTypeParameterLinks) &&
owner instanceof ClassDoc) {
linkInfo.classDoc = (ClassDoc) owner;
Content label = newContent();
label.addContent(type.typeName());
linkInfo.label = label;
link.addContent(getClassLink(linkInfo));
} else {
//No need to link method type parameters.
link.addContent(type.typeName());
}
Type[] bounds = type.asTypeVariable().bounds();
if (! linkInfo.excludeTypeBounds) {
linkInfo.excludeTypeBounds = true;
for (int i = 0; i < bounds.length; i++) {
link.addContent(i > 0 ? " & " : " extends ");
setBoundsLinkInfo(linkInfo, bounds[i]);
link.addContent(getLink(linkInfo));
}
}
} else if (type.asClassDoc() != null) {
//A class type.
if (linkInfo.isTypeBound &&
linkInfo.excludeTypeBoundsLinks) {
//Since we are excluding type parameter links, we should not
//be linking to the type bound.
link.addContent(type.typeName());
link.addContent(getTypeParameterLinks(linkInfo));
return link;
} else {
linkInfo.classDoc = type.asClassDoc();
link = newContent();
link.addContent(getClassLink(linkInfo));
if (linkInfo.includeTypeAsSepLink) {
link.addContent(getTypeParameterLinks(linkInfo, false));
}
}
}
if (linkInfo.isVarArg) {
if (type.dimension().length() > 2) {
//Javadoc returns var args as array.
//Strip out the first [] from the var arg.
link.addContent(type.dimension().substring(2));
}
link.addContent("...");
} else {
while (type != null && type.dimension().length() > 0) {
if (type.asAnnotatedType() != null) {
linkInfo.type = type;
link.addContent(" ");
link.addContent(getTypeAnnotationLinks(linkInfo));
link.addContent("[]");
type = type.asAnnotatedType().underlyingType().getElementType();
} else {
link.addContent("[]");
type = type.getElementType();
}
}
linkInfo.type = type;
Content newLink = newContent();
newLink.addContent(getTypeAnnotationLinks(linkInfo));
newLink.addContent(link);
link = newLink;
}
return link;
} else if (linkInfo.classDoc != null) {
//Just a class link
Content link = newContent();
link.addContent(getClassLink(linkInfo));
if (linkInfo.includeTypeAsSepLink) {
link.addContent(getTypeParameterLinks(linkInfo, false));
}
return link;
} else {
return null;
}
}
private void setBoundsLinkInfo(LinkInfo linkInfo, Type bound) {
linkInfo.classDoc = null;
linkInfo.label = null;
linkInfo.type = bound;
}
/**
* Return the link to the given class.
*
* @param linkInfo the information about the link to construct.
*
* @return the link for the given class.
*/
protected abstract Content getClassLink(LinkInfo linkInfo);
/**
* Return the link to the given type parameter.
*
* @param linkInfo the information about the link to construct.
* @param typeParam the type parameter to link to.
*/
protected abstract Content getTypeParameterLink(LinkInfo linkInfo,
Type typeParam);
protected abstract Content getTypeAnnotationLink(LinkInfo linkInfo,
AnnotationDesc annotation);
/**
* Return the links to the type parameters.
*
* @param linkInfo the information about the link to construct.
* @return the links to the type parameters.
*/
public Content getTypeParameterLinks(LinkInfo linkInfo) {
return getTypeParameterLinks(linkInfo, true);
}
/**
* Return the links to the type parameters.
*
* @param linkInfo the information about the link to construct.
* @param isClassLabel true if this is a class label. False if it is
* the type parameters portion of the link.
* @return the links to the type parameters.
*/
public Content getTypeParameterLinks(LinkInfo linkInfo, boolean isClassLabel) {
Content links = newContent();
Type[] vars;
if (linkInfo.executableMemberDoc != null) {
vars = linkInfo.executableMemberDoc.typeParameters();
} else if (linkInfo.type != null &&
linkInfo.type.asParameterizedType() != null){
vars = linkInfo.type.asParameterizedType().typeArguments();
} else if (linkInfo.classDoc != null){
vars = linkInfo.classDoc.typeParameters();
} else {
//Nothing to document.
return links;
}
if (((linkInfo.includeTypeInClassLinkLabel && isClassLabel) ||
(linkInfo.includeTypeAsSepLink && ! isClassLabel)
)
&& vars.length > 0) {
links.addContent("<");
for (int i = 0; i < vars.length; i++) {
if (i > 0) {
links.addContent(",");
}
links.addContent(getTypeParameterLink(linkInfo, vars[i]));
}
links.addContent(">");
}
return links;
}
public Content getTypeAnnotationLinks(LinkInfo linkInfo) {
Content links = newContent();
if (linkInfo.type.asAnnotatedType() == null)
return links;
AnnotationDesc[] annotations = linkInfo.type.asAnnotatedType().annotations();
for (int i = 0; i < annotations.length; i++) {
if (i > 0) {
links.addContent(" ");
}
links.addContent(getTypeAnnotationLink(linkInfo, annotations[i]));
}
links.addContent(" ");
return links;
}
}

View File

@@ -0,0 +1,154 @@
/*
* Copyright (c) 2003, 2013, 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.links;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.Configuration;
import com.sun.tools.doclets.internal.toolkit.Content;
/**
* Encapsulates information about a link.
*
* <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 Jamie Ho
* @since 1.5
*/
public abstract class LinkInfo {
/**
* The ClassDoc we want to link to. Null if we are not linking
* to a ClassDoc.
*/
public ClassDoc classDoc;
/**
* The executable member doc we want to link to. Null if we are not linking
* to an executable member.
*/
public ExecutableMemberDoc executableMemberDoc;
/**
* The Type we want to link to. Null if we are not linking to a type.
*/
public Type type;
/**
* True if this is a link to a VarArg.
*/
public boolean isVarArg = false;
/**
* Set this to true to indicate that you are linking to a type parameter.
*/
public boolean isTypeBound = false;
/**
* Whether the document element is in a Java 5 declaration
* location or not.
*/
public boolean isJava5DeclarationLocation = true;
/**
* The label for the link.
*/
public Content label;
/**
* True if the link should be strong.
*/
public boolean isStrong = false;
/**
* True if we should include the type in the link label. False otherwise.
*/
public boolean includeTypeInClassLinkLabel = true;
/**
* True if we should include the type as separate link. False otherwise.
*/
public boolean includeTypeAsSepLink = false;
/**
* True if we should exclude the type bounds for the type parameter.
*/
public boolean excludeTypeBounds = false;
/**
* True if we should print the type parameters, but not link them.
*/
public boolean excludeTypeParameterLinks = false;
/**
* True if we should print the type bounds, but not link them.
*/
public boolean excludeTypeBoundsLinks = false;
/**
* By default, the link can be to the page it's already on. However,
* there are cases where we don't want this (e.g. heading of class page).
*/
public boolean linkToSelf = true;
/**
* Return an empty instance of a content object.
*
* @return an empty instance of a content object.
*/
protected abstract Content newContent();
/**
* Return true if this link is linkable and false if we can't link to the
* desired place.
*
* @return true if this link is linkable and false if we can't link to the
* desired place.
*/
public abstract boolean isLinkable();
/**
* Return the label for this class link.
*
* @param configuration the current configuration of the doclet.
* @return the label for this class link.
*/
public Content getClassLinkLabel(Configuration configuration) {
if (label != null && !label.isEmpty()) {
return label;
} else if (isLinkable()) {
Content label = newContent();
label.addContent(classDoc.name());
return label;
} else {
Content label = newContent();
label.addContent(configuration.getClassName(classDoc));
return label;
}
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2003, 2013, 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.links;
/**
* Stores output of a link.
*
* <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 Jamie Ho
* @since 1.5
*/
public interface LinkOutput {
/**
* Append the given object to the output.
*
* @param o the object to append.
*/
public void append(Object o);
/**
* Insert the given object into the output sequence.
*
* @param offset the offset.
* @param o the object to be inserted.
*/
public void insert(int offset, Object o);
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2003, 2013, 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.
*/
/**
Provides a factory for constructing links.
<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>
*/
@jdk.Exported(false)
package com.sun.tools.doclets.internal.toolkit.util.links;

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2003, 2013, 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.
*/
/**
This package has utility classes that perform common services required
for API documentation generation.
<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>
*/
@jdk.Exported(false)
package com.sun.tools.doclets.internal.toolkit.util;