feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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() { }
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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™ 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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
Reference in New Issue
Block a user