Completely hacked together version of a FreeMarker + javadoc + custom doclet walker documentation generator
This commit is contained in:
parent
45c73ff0e5
commit
6fa17d86ae
20
build.xml
20
build.xml
|
|
@ -457,6 +457,26 @@
|
||||||
</javadoc>
|
</javadoc>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
<target name="walkerdocs" unless="uptodate.extracthelp"
|
||||||
|
description="Extract help key/value pair file from the JavaDoc tags.">
|
||||||
|
<path id="doclet.classpath">
|
||||||
|
<path refid="external.dependencies" />
|
||||||
|
<pathelement location="${java.classes}" />
|
||||||
|
</path>
|
||||||
|
|
||||||
|
<javadoc doclet="org.broadinstitute.sting.utils.help.GATKDoclet"
|
||||||
|
docletpathref="doclet.classpath"
|
||||||
|
classpathref="external.dependencies"
|
||||||
|
classpath="${java.classes}"
|
||||||
|
additionalparam="-build-timestamp "${build.timestamp}" -absolute-version ${build.version} -out ${basedir}/${resource.path} -quiet">
|
||||||
|
<sourcefiles>
|
||||||
|
<union>
|
||||||
|
<fileset refid="java.source.files"/>
|
||||||
|
</union>
|
||||||
|
</sourcefiles>
|
||||||
|
</javadoc>
|
||||||
|
</target>
|
||||||
|
|
||||||
<target name="sting.compile" depends="gatk.compile, scala.compile" />
|
<target name="sting.compile" depends="gatk.compile, scala.compile" />
|
||||||
|
|
||||||
<target name="init.jar" depends="sting.compile,extracthelp">
|
<target name="init.jar" depends="sting.compile,extracthelp">
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ import java.util.Locale;
|
||||||
public abstract class CommandLineProgram {
|
public abstract class CommandLineProgram {
|
||||||
|
|
||||||
/** The command-line program and the arguments it returned. */
|
/** The command-line program and the arguments it returned. */
|
||||||
protected ParsingEngine parser = null;
|
public ParsingEngine parser = null;
|
||||||
|
|
||||||
/** the default log level */
|
/** the default log level */
|
||||||
@Argument(fullName = "logging_level",
|
@Argument(fullName = "logging_level",
|
||||||
|
|
@ -144,6 +144,11 @@ public abstract class CommandLineProgram {
|
||||||
|
|
||||||
public static int result = -1;
|
public static int result = -1;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static void start(CommandLineProgram clp, String[] args) throws Exception {
|
||||||
|
start(clp, args, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is called to start processing the command line, and kick
|
* This function is called to start processing the command line, and kick
|
||||||
* off the execute message of the program.
|
* off the execute message of the program.
|
||||||
|
|
@ -153,7 +158,7 @@ public abstract class CommandLineProgram {
|
||||||
* @throws Exception when an exception occurs
|
* @throws Exception when an exception occurs
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static void start(CommandLineProgram clp, String[] args) throws Exception {
|
public static void start(CommandLineProgram clp, String[] args, boolean dryRun) throws Exception {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// setup our log layout
|
// setup our log layout
|
||||||
|
|
@ -180,8 +185,9 @@ public abstract class CommandLineProgram {
|
||||||
// - InvalidArgument in case these arguments are specified by plugins.
|
// - InvalidArgument in case these arguments are specified by plugins.
|
||||||
// - MissingRequiredArgument in case the user requested help. Handle that later, once we've
|
// - MissingRequiredArgument in case the user requested help. Handle that later, once we've
|
||||||
// determined the full complement of arguments.
|
// determined the full complement of arguments.
|
||||||
parser.validate(EnumSet.of(ParsingEngine.ValidationType.MissingRequiredArgument,
|
if ( ! dryRun )
|
||||||
ParsingEngine.ValidationType.InvalidArgument));
|
parser.validate(EnumSet.of(ParsingEngine.ValidationType.MissingRequiredArgument,
|
||||||
|
ParsingEngine.ValidationType.InvalidArgument));
|
||||||
parser.loadArgumentsIntoObject(clp);
|
parser.loadArgumentsIntoObject(clp);
|
||||||
|
|
||||||
// Initialize the logger using the loaded command line.
|
// Initialize the logger using the loaded command line.
|
||||||
|
|
@ -195,36 +201,40 @@ public abstract class CommandLineProgram {
|
||||||
if (isHelpPresent(parser))
|
if (isHelpPresent(parser))
|
||||||
printHelpAndExit(clp, parser);
|
printHelpAndExit(clp, parser);
|
||||||
|
|
||||||
parser.validate();
|
if ( ! dryRun ) parser.validate();
|
||||||
} else {
|
} else {
|
||||||
parser.parse(args);
|
parser.parse(args);
|
||||||
|
|
||||||
if (isHelpPresent(parser))
|
if ( ! dryRun ) {
|
||||||
printHelpAndExit(clp, parser);
|
if (isHelpPresent(parser))
|
||||||
|
printHelpAndExit(clp, parser);
|
||||||
|
|
||||||
parser.validate();
|
parser.validate();
|
||||||
|
}
|
||||||
parser.loadArgumentsIntoObject(clp);
|
parser.loadArgumentsIntoObject(clp);
|
||||||
|
|
||||||
// Initialize the logger using the loaded command line.
|
// Initialize the logger using the loaded command line.
|
||||||
clp.setupLoggerLevel(layout);
|
clp.setupLoggerLevel(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if they specify a log location, output our data there
|
if ( ! dryRun ) {
|
||||||
if (clp.toFile != null) {
|
// if they specify a log location, output our data there
|
||||||
FileAppender appender;
|
if (clp.toFile != null) {
|
||||||
try {
|
FileAppender appender;
|
||||||
appender = new FileAppender(layout, clp.toFile, false);
|
try {
|
||||||
logger.addAppender(appender);
|
appender = new FileAppender(layout, clp.toFile, false);
|
||||||
} catch (IOException e) {
|
logger.addAppender(appender);
|
||||||
throw new RuntimeException("Unable to re-route log output to " + clp.toFile + " make sure the destination exists");
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Unable to re-route log output to " + clp.toFile + " make sure the destination exists");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// regardless of what happens next, generate the header information
|
||||||
|
HelpFormatter.generateHeaderInformation(clp.getApplicationDetails(), args);
|
||||||
|
|
||||||
|
// call the execute
|
||||||
|
CommandLineProgram.result = clp.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
// regardless of what happens next, generate the header information
|
|
||||||
HelpFormatter.generateHeaderInformation(clp.getApplicationDetails(), args);
|
|
||||||
|
|
||||||
// call the execute
|
|
||||||
CommandLineProgram.result = clp.execute();
|
|
||||||
}
|
}
|
||||||
catch (ArgumentException e) {
|
catch (ArgumentException e) {
|
||||||
clp.parser.printHelp(clp.getApplicationDetails());
|
clp.parser.printHelp(clp.getApplicationDetails());
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ public class ParsingEngine {
|
||||||
* A list of defined arguments against which command lines are matched.
|
* A list of defined arguments against which command lines are matched.
|
||||||
* Package protected for testing access.
|
* Package protected for testing access.
|
||||||
*/
|
*/
|
||||||
ArgumentDefinitions argumentDefinitions = new ArgumentDefinitions();
|
public ArgumentDefinitions argumentDefinitions = new ArgumentDefinitions();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of matches from defined arguments to command-line text.
|
* A list of matches from defined arguments to command-line text.
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,14 @@ import freemarker.template.Configuration;
|
||||||
import freemarker.template.DefaultObjectWrapper;
|
import freemarker.template.DefaultObjectWrapper;
|
||||||
import freemarker.template.Template;
|
import freemarker.template.Template;
|
||||||
import freemarker.template.TemplateException;
|
import freemarker.template.TemplateException;
|
||||||
|
import org.broadinstitute.sting.commandline.*;
|
||||||
|
import org.broadinstitute.sting.gatk.CommandLineExecutable;
|
||||||
|
import org.broadinstitute.sting.gatk.CommandLineGATK;
|
||||||
import org.broadinstitute.sting.gatk.walkers.Walker;
|
import org.broadinstitute.sting.gatk.walkers.Walker;
|
||||||
import org.broadinstitute.sting.utils.Utils;
|
import org.broadinstitute.sting.utils.Utils;
|
||||||
import org.broadinstitute.sting.utils.classloader.JVMUtils;
|
import org.broadinstitute.sting.utils.classloader.JVMUtils;
|
||||||
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
||||||
|
import scala.reflect.Print;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
@ -40,7 +44,7 @@ import java.util.*;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class GATKDoclet {
|
public class GATKDoclet extends ResourceBundleExtractorDoclet {
|
||||||
/**
|
/**
|
||||||
* Extracts the contents of certain types of javadoc and adds them to an XML file.
|
* Extracts the contents of certain types of javadoc and adds them to an XML file.
|
||||||
* @param rootDoc The documentation root.
|
* @param rootDoc The documentation root.
|
||||||
|
|
@ -48,47 +52,164 @@ public class GATKDoclet {
|
||||||
* @throws java.io.IOException if output can't be written.
|
* @throws java.io.IOException if output can't be written.
|
||||||
*/
|
*/
|
||||||
public static boolean start(RootDoc rootDoc) throws IOException {
|
public static boolean start(RootDoc rootDoc) throws IOException {
|
||||||
/* ------------------------------------------------------------------- */
|
GATKDoclet doclet = new GATKDoclet();
|
||||||
/* You should do this ONLY ONCE in the whole application life-cycle: */
|
//PrintStream out = doclet.loadData(rootDoc, false);
|
||||||
|
doclet.processDocs(rootDoc, null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Configuration cfg = new Configuration();
|
public static int optionLength(String option) {
|
||||||
// Specify the data source where the template files come from.
|
return ResourceBundleExtractorDoclet.optionLength(option);
|
||||||
// Here I set a file directory for it:
|
}
|
||||||
cfg.setDirectoryForTemplateLoading(new File("settings/helpTemplates/"));
|
|
||||||
// Specify how templates will see the data-model. This is an advanced topic...
|
|
||||||
// but just use this:
|
|
||||||
cfg.setObjectWrapper(new DefaultObjectWrapper());
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void processDocs(RootDoc rootDoc, PrintStream ignore) {
|
||||||
|
try {
|
||||||
|
/* ------------------------------------------------------------------- */
|
||||||
|
/* You should do this ONLY ONCE in the whole application life-cycle: */
|
||||||
|
|
||||||
|
Configuration cfg = new Configuration();
|
||||||
|
// Specify the data source where the template files come from.
|
||||||
|
// Here I set a file directory for it:
|
||||||
|
cfg.setDirectoryForTemplateLoading(new File("settings/helpTemplates/"));
|
||||||
|
// Specify how templates will see the data-model. This is an advanced topic...
|
||||||
|
// but just use this:
|
||||||
|
cfg.setObjectWrapper(new DefaultObjectWrapper());
|
||||||
|
|
||||||
|
for ( ClassDoc doc : rootDoc.classes() ) {
|
||||||
|
if ( ResourceBundleExtractorDoclet.isWalker(doc) ) {
|
||||||
|
System.out.printf("Walker class %s%n", doc);
|
||||||
|
processWalkerDocs(cfg, doc);
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// System.out.printf("Excluding non-walker class %s%n", doc);
|
||||||
|
}
|
||||||
|
} catch ( FileNotFoundException e ) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch ( IOException e ) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processWalkerDocs(Configuration cfg, ClassDoc doc) throws IOException {
|
||||||
/* ------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------- */
|
||||||
/* You usually do these for many times in the application life-cycle: */
|
/* You usually do these for many times in the application life-cycle: */
|
||||||
|
|
||||||
/* Create a data-model */
|
|
||||||
// Create the root hash
|
// Create the root hash
|
||||||
Map root = new HashMap();
|
Map root = buildWalkerDataModel(doc);
|
||||||
// Put string ``user'' into the root
|
|
||||||
root.put("user", "Mark DePristo");
|
|
||||||
|
|
||||||
/* Get or create a template */
|
/* Get or create a template */
|
||||||
Template temp = cfg.getTemplate("test.html");
|
Template temp = cfg.getTemplate("test.html");
|
||||||
|
|
||||||
/* Merge data-model with template */
|
/* Merge data-model with template */
|
||||||
Writer out = new OutputStreamWriter(System.out);
|
Writer out = new OutputStreamWriter(new FileOutputStream(new File("testdoc/" + getClassName(doc).replace(".", "_") + ".html")));
|
||||||
try {
|
try {
|
||||||
temp.process(root, out);
|
temp.process(root, out);
|
||||||
out.flush();
|
out.flush();
|
||||||
} catch ( TemplateException e ) {
|
} catch ( TemplateException e ) {
|
||||||
throw new ReviewedStingException("Failed to create GATK documentation", e);
|
throw new ReviewedStingException("Failed to create GATK documentation", e);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate the given options against options supported by this doclet.
|
private Map buildWalkerDataModel(ClassDoc classdoc) {
|
||||||
* @param option Option to validate.
|
Map<String, Object> root = new HashMap<String, Object>();
|
||||||
* @return Number of potential parameters; 0 if not supported.
|
|
||||||
*/
|
root.put("name", classdoc.name());
|
||||||
public static int optionLength(String option) {
|
|
||||||
return 0;
|
// Extract overrides from the doc tags.
|
||||||
|
StringBuilder summaryBuilder = new StringBuilder();
|
||||||
|
for(Tag tag: classdoc.firstSentenceTags())
|
||||||
|
summaryBuilder.append(tag.text());
|
||||||
|
root.put("summary", summaryBuilder.toString());
|
||||||
|
root.put("description", classdoc.commentText());
|
||||||
|
|
||||||
|
for(Tag tag: classdoc.tags()) {
|
||||||
|
root.put(tag.name(), tag.text());
|
||||||
|
}
|
||||||
|
|
||||||
|
ParsingEngine parsingEngine = createStandardGATKParsingEngine();
|
||||||
|
// for (ArgumentDefinition argumentDefinition : parsingEngine.argumentDefinitions )
|
||||||
|
// System.out.println(argumentDefinition);
|
||||||
|
|
||||||
|
Map<String, List<Object>> args = new HashMap<String, List<Object>>();
|
||||||
|
root.put("arguments", args);
|
||||||
|
args.put("required", new ArrayList<Object>());
|
||||||
|
args.put("optional", new ArrayList<Object>());
|
||||||
|
args.put("hidden", new ArrayList<Object>());
|
||||||
|
args.put("depreciated", new ArrayList<Object>());
|
||||||
|
try {
|
||||||
|
for ( ArgumentSource argumentSource : parsingEngine.extractArgumentSources(getClassForDoc(classdoc)) ) {
|
||||||
|
String kind = "optional";
|
||||||
|
if ( argumentSource.isRequired() ) kind = "required";
|
||||||
|
else if ( argumentSource.isHidden() ) kind = "hidden";
|
||||||
|
else if ( argumentSource.isDeprecated() ) kind = "depreciated";
|
||||||
|
args.get(kind).add(argumentDataModel(argumentSource.createArgumentDefinitions().get(0)));
|
||||||
|
System.out.printf("Processing %s%n", argumentSource);
|
||||||
|
|
||||||
|
// for(FieldDoc fieldDoc: classdoc.fields()) {
|
||||||
|
// //for ( AnnotationDesc desc : fieldDoc.annotations() ) {
|
||||||
|
// System.out.printf("AnnotationDesc %s%n", desc);
|
||||||
|
// if ( implementsInterface(desc.annotationType(), Argument.class, Output.class, Input.class) ) {
|
||||||
|
// (requiredAnnotation(desc) ? requiredArgs : optionalArgs).add(dataModelForArgument(desc));
|
||||||
|
// System.out.printf("Processing %s%n", desc);
|
||||||
|
// } else {
|
||||||
|
// System.out.printf("Skipping %s%n", desc);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
} catch ( ClassNotFoundException e ) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.printf("Root is %s%n", root);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String withDefault(String val, String def) {
|
||||||
|
return val == null ? def : val;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<String, Object> argumentDataModel(ArgumentDefinition argumentDefinition) {
|
||||||
|
Map<String, Object> root = new HashMap<String, Object>();
|
||||||
|
root.put("shortName", withDefault(argumentDefinition.shortName, "None provided"));
|
||||||
|
root.put("required", argumentDefinition.required);
|
||||||
|
root.put("fullName", withDefault(argumentDefinition.fullName, "None provided"));
|
||||||
|
root.put("argumentType", argumentDefinition.argumentType);
|
||||||
|
root.put("doc", withDefault(argumentDefinition.doc, "None provided"));
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ParsingEngine createStandardGATKParsingEngine() {
|
||||||
|
CommandLineProgram clp = new CommandLineGATK();
|
||||||
|
try {
|
||||||
|
CommandLineProgram.start(clp, new String[]{}, true);
|
||||||
|
return clp.parser;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<String, Object> dataModelForArgument(AnnotationDesc desc) {
|
||||||
|
Map<String, Object> root = new HashMap<String, Object>();
|
||||||
|
root.put("shortName", "None provided");
|
||||||
|
root.put("required", false);
|
||||||
|
root.put("fullName", "None provided");
|
||||||
|
root.put("doc", "None provided");
|
||||||
|
|
||||||
|
for ( AnnotationDesc.ElementValuePair keyvalue : desc.elementValues() ) {
|
||||||
|
root.put(keyvalue.element().name(), keyvalue.value().value());
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean requiredAnnotation(AnnotationDesc desc) {
|
||||||
|
for ( AnnotationDesc.ElementValuePair keyvalue : desc.elementValues() ) {
|
||||||
|
if ( keyvalue.element().name().equals("required") )
|
||||||
|
return keyvalue.value().toString().equals("true");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,10 @@ import org.broadinstitute.sting.gatk.walkers.Walker;
|
||||||
import org.broadinstitute.sting.utils.Utils;
|
import org.broadinstitute.sting.utils.Utils;
|
||||||
import org.broadinstitute.sting.utils.classloader.JVMUtils;
|
import org.broadinstitute.sting.utils.classloader.JVMUtils;
|
||||||
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
||||||
|
import sun.tools.java.ClassNotFound;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Scanner;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts certain types of javadoc (specifically package and class descriptions) and makes them available
|
* Extracts certain types of javadoc (specifically package and class descriptions) and makes them available
|
||||||
|
|
@ -48,17 +46,19 @@ public class ResourceBundleExtractorDoclet {
|
||||||
/**
|
/**
|
||||||
* Taglet for the particular version number.
|
* Taglet for the particular version number.
|
||||||
*/
|
*/
|
||||||
private static final String VERSION_TAGLET_NAME = "version";
|
protected static final String VERSION_TAGLET_NAME = "version";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maintains a collection of resources in memory as they're accumulated.
|
* Maintains a collection of resources in memory as they're accumulated.
|
||||||
*/
|
*/
|
||||||
private static final Properties resourceText = new Properties();
|
protected final Properties resourceText = new Properties();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maintains a collection of classes that should really be documented.
|
* Maintains a collection of classes that should really be documented.
|
||||||
*/
|
*/
|
||||||
private static final Set<String> undocumentedWalkers = new HashSet<String>();
|
protected final Set<String> undocumentedWalkers = new HashSet<String>();
|
||||||
|
|
||||||
|
protected String buildTimestamp = null, versionPrefix = null, versionSuffix = null, absoluteVersion = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts the contents of certain types of javadoc and adds them to an XML file.
|
* Extracts the contents of certain types of javadoc and adds them to an XML file.
|
||||||
|
|
@ -67,13 +67,26 @@ public class ResourceBundleExtractorDoclet {
|
||||||
* @throws IOException if output can't be written.
|
* @throws IOException if output can't be written.
|
||||||
*/
|
*/
|
||||||
public static boolean start(RootDoc rootDoc) throws IOException {
|
public static boolean start(RootDoc rootDoc) throws IOException {
|
||||||
|
ResourceBundleExtractorDoclet doclet = new ResourceBundleExtractorDoclet();
|
||||||
|
PrintStream out = doclet.loadData(rootDoc, true);
|
||||||
|
doclet.processDocs(rootDoc, out);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PrintStream loadData(RootDoc rootDoc, boolean overwriteResourcesFile) {
|
||||||
PrintStream out = System.out;
|
PrintStream out = System.out;
|
||||||
String buildTimestamp = null, versionPrefix = null, versionSuffix = null, absoluteVersion = null;
|
|
||||||
|
|
||||||
for(String[] options: rootDoc.options()) {
|
for(String[] options: rootDoc.options()) {
|
||||||
if(options[0].equals("-out")) {
|
if(options[0].equals("-out")) {
|
||||||
loadExistingResourceFile(options[1], rootDoc);
|
try {
|
||||||
out = new PrintStream(options[1]);
|
loadExistingResourceFile(options[1], rootDoc);
|
||||||
|
if ( overwriteResourcesFile )
|
||||||
|
out = new PrintStream(options[1]);
|
||||||
|
} catch ( FileNotFoundException e ) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch ( IOException e ) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(options[0].equals("-build-timestamp"))
|
if(options[0].equals("-build-timestamp"))
|
||||||
buildTimestamp = options[1];
|
buildTimestamp = options[1];
|
||||||
|
|
@ -86,7 +99,10 @@ public class ResourceBundleExtractorDoclet {
|
||||||
}
|
}
|
||||||
|
|
||||||
resourceText.setProperty("build.timestamp",buildTimestamp);
|
resourceText.setProperty("build.timestamp",buildTimestamp);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void processDocs(RootDoc rootDoc, PrintStream out) {
|
||||||
// Cache packages as we see them, since there's no direct way to iterate over packages.
|
// Cache packages as we see them, since there's no direct way to iterate over packages.
|
||||||
Set<PackageDoc> packages = new HashSet<PackageDoc>();
|
Set<PackageDoc> packages = new HashSet<PackageDoc>();
|
||||||
|
|
||||||
|
|
@ -97,13 +113,19 @@ public class ResourceBundleExtractorDoclet {
|
||||||
if(isRequiredJavadocMissing(currentClass) && isWalker(currentClass))
|
if(isRequiredJavadocMissing(currentClass) && isWalker(currentClass))
|
||||||
undocumentedWalkers.add(currentClass.name());
|
undocumentedWalkers.add(currentClass.name());
|
||||||
|
|
||||||
renderHelpText(getClassName(currentClass),currentClass,versionPrefix,versionSuffix,absoluteVersion);
|
renderHelpText(getClassName(currentClass),currentClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(PackageDoc currentPackage: packages)
|
for(PackageDoc currentPackage: packages)
|
||||||
renderHelpText(currentPackage.name(),currentPackage,versionPrefix,versionSuffix,absoluteVersion);
|
renderHelpText(currentPackage.name(),currentPackage);
|
||||||
|
|
||||||
resourceText.store(out,"Strings displayed by the Sting help system");
|
try {
|
||||||
|
resourceText.store(out,"Strings displayed by the Sting help system");
|
||||||
|
} catch ( FileNotFoundException e ) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch ( IOException e ) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
// ASCII codes for making text blink
|
// ASCII codes for making text blink
|
||||||
final String blink = "\u001B\u005B\u0035\u006D";
|
final String blink = "\u001B\u005B\u0035\u006D";
|
||||||
|
|
@ -111,8 +133,6 @@ public class ResourceBundleExtractorDoclet {
|
||||||
|
|
||||||
if(undocumentedWalkers.size() > 0)
|
if(undocumentedWalkers.size() > 0)
|
||||||
Utils.warnUser(String.format("The following walkers are currently undocumented: %s%s%s", blink, Utils.join(" ",undocumentedWalkers), reset));
|
Utils.warnUser(String.format("The following walkers are currently undocumented: %s%s%s", blink, Utils.join(" ",undocumentedWalkers), reset));
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -137,7 +157,7 @@ public class ResourceBundleExtractorDoclet {
|
||||||
* @throws IOException if there is an I/O-related error other than FileNotFoundException
|
* @throws IOException if there is an I/O-related error other than FileNotFoundException
|
||||||
* while attempting to read the resource file.
|
* while attempting to read the resource file.
|
||||||
*/
|
*/
|
||||||
private static void loadExistingResourceFile( String resourceFileName, RootDoc rootDoc ) throws IOException {
|
private void loadExistingResourceFile( String resourceFileName, RootDoc rootDoc ) throws IOException {
|
||||||
try {
|
try {
|
||||||
BufferedReader resourceFile = new BufferedReader(new FileReader(resourceFileName));
|
BufferedReader resourceFile = new BufferedReader(new FileReader(resourceFileName));
|
||||||
try {
|
try {
|
||||||
|
|
@ -157,10 +177,21 @@ public class ResourceBundleExtractorDoclet {
|
||||||
* @param classDoc the type of the given class.
|
* @param classDoc the type of the given class.
|
||||||
* @return True if the class of the given name is a walker. False otherwise.
|
* @return True if the class of the given name is a walker. False otherwise.
|
||||||
*/
|
*/
|
||||||
private static boolean isWalker(ClassDoc classDoc) {
|
protected static boolean isWalker(ClassDoc classDoc) {
|
||||||
|
return assignableToClass(classDoc, Walker.class, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static boolean implementsInterface(ProgramElementDoc classDoc, Class... interfaceClasses) {
|
||||||
|
for ( Class interfaceClass : interfaceClasses )
|
||||||
|
if ( assignableToClass(classDoc, interfaceClass, false) )
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static boolean assignableToClass(ProgramElementDoc classDoc, Class lhsClass, boolean requireConcrete) {
|
||||||
try {
|
try {
|
||||||
Class type = Class.forName(getClassName(classDoc));
|
Class type = getClassForDoc(classDoc);
|
||||||
return Walker.class.isAssignableFrom(type) && JVMUtils.isConcrete(type);
|
return lhsClass.isAssignableFrom(type) && (!requireConcrete || JVMUtils.isConcrete(type));
|
||||||
}
|
}
|
||||||
catch(Throwable t) {
|
catch(Throwable t) {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
|
|
@ -168,16 +199,20 @@ public class ResourceBundleExtractorDoclet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static Class getClassForDoc(ProgramElementDoc doc) throws ClassNotFoundException {
|
||||||
|
return Class.forName(getClassName(doc));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reconstitute the class name from the given class JavaDoc object.
|
* Reconstitute the class name from the given class JavaDoc object.
|
||||||
* @param classDoc the Javadoc model for the given class.
|
* @param doc the Javadoc model for the given class.
|
||||||
* @return The (string) class name of the given class.
|
* @return The (string) class name of the given class.
|
||||||
*/
|
*/
|
||||||
private static String getClassName(ClassDoc classDoc) {
|
protected static String getClassName(ProgramElementDoc doc) {
|
||||||
PackageDoc containingPackage = classDoc.containingPackage();
|
PackageDoc containingPackage = doc.containingPackage();
|
||||||
return containingPackage.name().length() > 0 ?
|
return containingPackage.name().length() > 0 ?
|
||||||
String.format("%s.%s",containingPackage.name(),classDoc.name()) :
|
String.format("%s.%s",containingPackage.name(),doc.name()) :
|
||||||
String.format("%s",classDoc.name());
|
String.format("%s",doc.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -193,10 +228,8 @@ public class ResourceBundleExtractorDoclet {
|
||||||
* Renders all the help text required for a given name.
|
* Renders all the help text required for a given name.
|
||||||
* @param elementName element name to use as the key
|
* @param elementName element name to use as the key
|
||||||
* @param element Doc element to process.
|
* @param element Doc element to process.
|
||||||
* @param versionPrefix Text to add to the start of the version string.
|
|
||||||
* @param versionSuffix Text to add to the end of the version string.
|
|
||||||
*/
|
*/
|
||||||
private static void renderHelpText(String elementName, Doc element, String versionPrefix, String versionSuffix, String absoluteVersion) {
|
private void renderHelpText(String elementName, Doc element) {
|
||||||
// Extract overrides from the doc tags.
|
// Extract overrides from the doc tags.
|
||||||
String name = null;
|
String name = null;
|
||||||
String version = null;
|
String version = null;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
<#macro argumentlist myargs>
|
||||||
|
<table border="1" span=100>
|
||||||
|
<tr>
|
||||||
|
<th>Short name</th>
|
||||||
|
<th>Full name</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
<#list myargs as arg>
|
||||||
|
<tr>
|
||||||
|
<td>${arg.shortName}</td>
|
||||||
|
<td>${arg.fullName}</td>
|
||||||
|
<td>${arg.doc}</td>
|
||||||
|
</tr>
|
||||||
|
<#--
|
||||||
|
<td>${arg.required}</td>
|
||||||
|
-->
|
||||||
|
</#list>
|
||||||
|
</table>
|
||||||
|
</#macro>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>${name} documentation</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>${name}<h1>
|
||||||
|
<h2>Summary</h2>
|
||||||
|
${summary}
|
||||||
|
<h2>Version</h2>
|
||||||
|
${version!"unknown version"}
|
||||||
|
<#if author??>
|
||||||
|
<h2>Author</h2>
|
||||||
|
${author}
|
||||||
|
</#if>
|
||||||
|
<h2>Description</h2>
|
||||||
|
${description}
|
||||||
|
<h2>Arguments</h2>
|
||||||
|
<h3>Required</h3> <@argumentlist myargs=arguments.required/>
|
||||||
|
<h3>Optional</h3> <@argumentlist myargs=arguments.optional/>
|
||||||
|
<h3>Hidden</h3> <@argumentlist myargs=arguments.hidden/>
|
||||||
|
<h3>Depreciated</h3> <@argumentlist myargs=arguments.depreciated/>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue