Remove com.sun.javadoc.* dependencies from the GATK proper, and isolate them for doclet use only

Problem:
Classes in com.sun.javadoc.* are non-standard. Since we can't depend on their availability for
all users, the GATK proper should not have any runtime dependencies on this package.

Solution:
-Isolate com.sun.javadoc.* dependencies in a DocletUtils class for use only by doclets. The
 only users who need to run our doclets are those who compile from source, and they
 should be competent enough to figure out how to resolve a missing com.sun.* dependency.

-HelpUtils now contains no com.sun.javadoc.* dependencies and can be safely used by walkers/other
 tools.

-Added comments with instructions on when it is safe to use DocletUtils vs. HelpUtils

[delivers #51450385]
[delivers #50387199]
This commit is contained in:
David Roazen 2013-06-13 15:30:10 -04:00
parent fb5143a590
commit f9c986be74
6 changed files with 87 additions and 50 deletions

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2012 The Broad Institute
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.broadinstitute.sting.utils.help;
import com.sun.javadoc.FieldDoc;
import com.sun.javadoc.PackageDoc;
import com.sun.javadoc.ProgramElementDoc;
import org.broadinstitute.sting.utils.classloader.JVMUtils;
import java.lang.reflect.Field;
/**
* Methods in the class must ONLY be used by doclets, since the com.sun.javadoc.* classes are not
* available on all systems, and we don't want the GATK proper to depend on them.
*/
public class DocletUtils {
protected static boolean assignableToClass(ProgramElementDoc classDoc, Class lhsClass, boolean requireConcrete) {
try {
Class type = getClassForDoc(classDoc);
return lhsClass.isAssignableFrom(type) && (!requireConcrete || JVMUtils.isConcrete(type));
} catch (Throwable t) {
// Ignore errors.
return false;
}
}
protected static Class getClassForDoc(ProgramElementDoc doc) throws ClassNotFoundException {
return Class.forName(getClassName(doc));
}
protected static Field getFieldForFieldDoc(FieldDoc fieldDoc) {
try {
Class clazz = getClassForDoc(fieldDoc.containingClass());
return JVMUtils.findField(clazz, fieldDoc.name());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
/**
* Reconstitute the class name from the given class JavaDoc object.
*
* @param doc the Javadoc model for the given class.
* @return The (string) class name of the given class.
*/
protected static String getClassName(ProgramElementDoc doc) {
PackageDoc containingPackage = doc.containingPackage();
return containingPackage.name().length() > 0 ?
String.format("%s.%s", containingPackage.name(), doc.name()) :
String.format("%s", doc.name());
}
}

View File

@ -352,7 +352,7 @@ public class GATKDoclet {
private Class<? extends Object> getClassForClassDoc(ClassDoc doc) {
try {
// todo -- what do I need the ? extends Object to pass the compiler?
return (Class<? extends Object>) HelpUtils.getClassForDoc(doc);
return (Class<? extends Object>) DocletUtils.getClassForDoc(doc);
} catch (ClassNotFoundException e) {
//logger.warn("Couldn't find class for ClassDoc " + doc);
// we got a classdoc for a class we can't find. Maybe in a library or something

View File

@ -68,7 +68,7 @@ public class GenericDocumentationHandler extends DocumentedGATKFeatureHandler {
@Override
public boolean includeInDocs(ClassDoc doc) {
try {
Class type = HelpUtils.getClassForDoc(doc);
Class type = DocletUtils.getClassForDoc(doc);
boolean hidden = !getDoclet().showHiddenFeatures() && type.isAnnotationPresent(Hidden.class);
return !hidden && JVMUtils.isConcrete(type);
} catch (ClassNotFoundException e) {
@ -157,7 +157,7 @@ public class GenericDocumentationHandler extends DocumentedGATKFeatureHandler {
root.put("arguments", args);
try {
// loop over all of the arguments according to the parsing engine
for (final ArgumentSource argumentSource : parsingEngine.extractArgumentSources(HelpUtils.getClassForDoc(toProcess.classDoc))) {
for (final ArgumentSource argumentSource : parsingEngine.extractArgumentSources(DocletUtils.getClassForDoc(toProcess.classDoc))) {
// todo -- why can you have multiple ones?
ArgumentDefinition argDef = argumentSource.createArgumentDefinitions().get(0);
FieldDoc fieldDoc = getFieldDoc(toProcess.classDoc, argumentSource.field.getName());
@ -663,7 +663,7 @@ public class GenericDocumentationHandler extends DocumentedGATKFeatureHandler {
if (fieldDoc.name().equals(name))
return fieldDoc;
Field field = HelpUtils.getFieldForFieldDoc(fieldDoc);
Field field = DocletUtils.getFieldForFieldDoc(fieldDoc);
if (field == null)
throw new RuntimeException("Could not find the field corresponding to " + fieldDoc + ", presumably because the field is inaccessible");
if (field.isAnnotationPresent(ArgumentCollection.class)) {

View File

@ -25,57 +25,20 @@
package org.broadinstitute.sting.utils.help;
import com.sun.javadoc.FieldDoc;
import com.sun.javadoc.PackageDoc;
import com.sun.javadoc.ProgramElementDoc;
import org.broadinstitute.sting.gatk.walkers.annotator.interfaces.AnnotationType;
import org.broadinstitute.sting.gatk.walkers.annotator.interfaces.GenotypeAnnotation;
import org.broadinstitute.sting.gatk.walkers.annotator.interfaces.InfoFieldAnnotation;
import org.broadinstitute.sting.gatk.walkers.annotator.interfaces.StandardAnnotation;
import org.broadinstitute.sting.utils.classloader.JVMUtils;
import org.broadinstitute.sting.utils.classloader.PluginManager;
import java.lang.reflect.Field;
import java.util.List;
/**
* NON-javadoc/doclet help-related utility methods should go here. Anything with a com.sun.javadoc.* dependency
* should go into DocletUtils for use only by doclets.
*/
public class HelpUtils {
protected static boolean assignableToClass(ProgramElementDoc classDoc, Class lhsClass, boolean requireConcrete) {
try {
Class type = getClassForDoc(classDoc);
return lhsClass.isAssignableFrom(type) && (!requireConcrete || JVMUtils.isConcrete(type));
} catch (Throwable t) {
// Ignore errors.
return false;
}
}
protected static Class getClassForDoc(ProgramElementDoc doc) throws ClassNotFoundException {
return Class.forName(getClassName(doc));
}
protected static Field getFieldForFieldDoc(FieldDoc fieldDoc) {
try {
Class clazz = getClassForDoc(fieldDoc.containingClass());
return JVMUtils.findField(clazz, fieldDoc.name());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
/**
* Reconstitute the class name from the given class JavaDoc object.
*
* @param doc the Javadoc model for the given class.
* @return The (string) class name of the given class.
*/
protected static String getClassName(ProgramElementDoc doc) {
PackageDoc containingPackage = doc.containingPackage();
return containingPackage.name().length() > 0 ?
String.format("%s.%s", containingPackage.name(), doc.name()) :
String.format("%s", doc.name());
}
/**
* Simple method to print a list of available annotations.
*/
@ -98,5 +61,4 @@ public class HelpUtils {
System.out.println("\t" + c.getSimpleName());
System.out.println();
}
}
}

View File

@ -108,7 +108,7 @@ public class ResourceBundleExtractorDoclet {
if(isRequiredJavadocMissing(currentClass) && isWalker(currentClass))
undocumentedWalkers.add(currentClass.name());
renderHelpText(HelpUtils.getClassName(currentClass),currentClass);
renderHelpText(DocletUtils.getClassName(currentClass),currentClass);
}
for(PackageDoc currentPackage: packages)
@ -173,7 +173,7 @@ public class ResourceBundleExtractorDoclet {
* @return True if the class of the given name is a walker. False otherwise.
*/
protected static boolean isWalker(ClassDoc classDoc) {
return HelpUtils.assignableToClass(classDoc, Walker.class, true);
return DocletUtils.assignableToClass(classDoc, Walker.class, true);
}
/**

View File

@ -25,7 +25,6 @@
package org.broadinstitute.sting.utils.runtime;
import com.sun.corba.se.spi.orbutil.fsm.Input;
import java.io.File;
import java.util.Map;