Semi-working version of extraDocs tag in annotation to refer to one capability being accessible in another
Required a significant refactoring of the GATKDoclet, which now has a unified place where the ClassDoc, class, annotation, and handler are all stored together.
This commit is contained in:
parent
999acacfa1
commit
7420ed098e
|
|
@ -468,7 +468,7 @@
|
|||
</javadoc>
|
||||
</target>
|
||||
|
||||
<target name="gatkdocs" unless="uptodate.extracthelp"
|
||||
<target name="gatkdocs" depends="gatk.compile"
|
||||
description="Extract help key/value pair file from the JavaDoc tags.">
|
||||
<path id="doclet.classpath">
|
||||
<path refid="external.dependencies" />
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import org.broadinstitute.sting.commandline.Argument;
|
|||
import org.broadinstitute.sting.commandline.ArgumentCollection;
|
||||
import org.broadinstitute.sting.commandline.CommandLineProgram;
|
||||
import org.broadinstitute.sting.gatk.arguments.GATKArgumentCollection;
|
||||
import org.broadinstitute.sting.gatk.filters.ReadFilter;
|
||||
import org.broadinstitute.sting.gatk.walkers.Attribution;
|
||||
import org.broadinstitute.sting.gatk.walkers.Walker;
|
||||
import org.broadinstitute.sting.utils.exceptions.UserException;
|
||||
|
|
@ -40,12 +41,8 @@ import org.broadinstitute.sting.utils.text.TextFormattingUtils;
|
|||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author aaron
|
||||
* @version 1.0
|
||||
* @date May 8, 2009
|
||||
* <p/>
|
||||
* Class CommandLineGATK
|
||||
* <p/>
|
||||
* The GATK engine itself. Manages map/reduce data access and runs walkers.
|
||||
*
|
||||
* We run command line GATK programs using this class. It gets the command line args, parses them, and hands the
|
||||
* gatk all the parsed out information. Pretty much anything dealing with the underlying system should go here,
|
||||
* the gatk engine should deal with any data related information.
|
||||
|
|
@ -53,6 +50,8 @@ import java.util.*;
|
|||
@DocumentedGATKFeature(
|
||||
groupName = "GATK Engine",
|
||||
summary = "Features and arguments for the GATK engine itself, available to all walkers." )
|
||||
//,
|
||||
// extraDocs = { ReadFilter.class, UserException.class })
|
||||
public class CommandLineGATK extends CommandLineExecutable {
|
||||
@Argument(fullName = "analysis_type", shortName = "T", doc = "Type of analysis to run")
|
||||
private String analysisName = null;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
package org.broadinstitute.sting.gatk.walkers;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.broadinstitute.sting.gatk.CommandLineGATK;
|
||||
import org.broadinstitute.sting.gatk.GenomeAnalysisEngine;
|
||||
import org.broadinstitute.sting.gatk.filters.MalformedReadFilter;
|
||||
import org.broadinstitute.sting.utils.GenomeLoc;
|
||||
|
|
@ -48,7 +49,8 @@ import java.util.List;
|
|||
@BAQMode(QualityMode = BAQ.QualityMode.OVERWRITE_QUALS, ApplicationTime = BAQ.ApplicationTime.ON_INPUT)
|
||||
@DocumentedGATKFeature(
|
||||
groupName = "GATK walkers",
|
||||
summary = "General tools available for running on the command line as part of the GATK package" )
|
||||
summary = "General tools available for running on the command line as part of the GATK package",
|
||||
extraDocs = {CommandLineGATK.class})
|
||||
public abstract class Walker<MapType, ReduceType> {
|
||||
final protected static Logger logger = Logger.getLogger(Walker.class);
|
||||
private GenomeAnalysisEngine toolkit;
|
||||
|
|
|
|||
|
|
@ -36,8 +36,9 @@ import java.lang.annotation.*;
|
|||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface DocumentedGATKFeature {
|
||||
boolean enable() default true;
|
||||
String groupName();
|
||||
String summary() default "";
|
||||
Class<? extends DocumentedGATKFeatureHandler> handler() default GenericDocumentationHandler.class;
|
||||
public boolean enable() default true;
|
||||
public String groupName();
|
||||
public String summary() default "";
|
||||
public Class<? extends DocumentedGATKFeatureHandler> handler() default GenericDocumentationHandler.class;
|
||||
public Class[] extraDocs() default {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,14 +28,13 @@ import com.sun.javadoc.ClassDoc;
|
|||
import com.sun.javadoc.RootDoc;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class DocumentedGATKFeatureHandler {
|
||||
private GATKDoclet doclet;
|
||||
private String groupName;
|
||||
private DocumentedGATKFeature annotation;
|
||||
|
||||
protected RootDoc getRootDoc() {
|
||||
return this.doclet.rootDoc;
|
||||
|
|
@ -45,28 +44,12 @@ public abstract class DocumentedGATKFeatureHandler {
|
|||
this.doclet = doclet;
|
||||
}
|
||||
|
||||
public DocumentedGATKFeature getAnnotation() {
|
||||
return annotation;
|
||||
}
|
||||
|
||||
public void setAnnotation(DocumentedGATKFeature annotation) {
|
||||
this.annotation = annotation;
|
||||
}
|
||||
|
||||
public boolean shouldBeProcessed(ClassDoc doc) { return true; }
|
||||
|
||||
public String getDestinationFilename(ClassDoc doc) {
|
||||
return HelpUtils.getClassName(doc).replace(".", "_") + ".html";
|
||||
}
|
||||
|
||||
final public String getGroupName() {
|
||||
return groupName;
|
||||
}
|
||||
|
||||
final public void setGroupName(String groupName) {
|
||||
this.groupName = groupName;
|
||||
}
|
||||
|
||||
public abstract String getTemplateName(ClassDoc doc) throws IOException;
|
||||
public abstract GATKDoclet.DocumentationData processOne(ClassDoc doc);
|
||||
public abstract void processOne(GATKDoclet.DocWorkUnit toProcess, Map<Class, GATKDoclet.DocWorkUnit> all);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,25 +42,34 @@ import java.util.*;
|
|||
public class GATKDoclet extends ResourceBundleExtractorDoclet {
|
||||
final protected static Logger logger = Logger.getLogger(GATKDoclet.class);
|
||||
|
||||
public static class DocumentationData implements Comparable<DocumentationData> {
|
||||
String name, summary, filename;
|
||||
Map<String, Object> forTemplate;
|
||||
String group;
|
||||
public static class DocWorkUnit implements Comparable<DocWorkUnit> {
|
||||
// known at the start
|
||||
String name, filename, group;
|
||||
DocumentedGATKFeatureHandler handler;
|
||||
ClassDoc classDoc;
|
||||
Class clazz;
|
||||
DocumentedGATKFeature annotation;
|
||||
|
||||
public DocumentationData(String name, String summary, Map<String, Object> forTemplate) {
|
||||
// set by the handler
|
||||
String summary;
|
||||
Map<String, Object> forTemplate;
|
||||
|
||||
public DocWorkUnit(DocumentedGATKFeature annotation, String name, String filename, String group,
|
||||
DocumentedGATKFeatureHandler handler, ClassDoc classDoc, Class clazz) {
|
||||
this.annotation = annotation;
|
||||
this.name = name;
|
||||
this.filename = filename;
|
||||
this.group = group;
|
||||
this.handler = handler;
|
||||
this.classDoc = classDoc;
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public void setHandlerContent(String summary, Map<String, Object> forTemplate) {
|
||||
this.summary = summary;
|
||||
this.forTemplate = forTemplate;
|
||||
}
|
||||
|
||||
public void setGroup(String group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public void setFilename(String filename) {
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
public Map<String, String> toMap() {
|
||||
Map<String, String> data = new HashMap<String, String>();
|
||||
data.put("name", name);
|
||||
|
|
@ -70,7 +79,7 @@ public class GATKDoclet extends ResourceBundleExtractorDoclet {
|
|||
return data;
|
||||
}
|
||||
|
||||
public int compareTo(DocumentationData other) {
|
||||
public int compareTo(DocWorkUnit other) {
|
||||
return this.name.compareTo(other.name);
|
||||
}
|
||||
}
|
||||
|
|
@ -93,6 +102,26 @@ public class GATKDoclet extends ResourceBundleExtractorDoclet {
|
|||
return ResourceBundleExtractorDoclet.optionLength(option);
|
||||
}
|
||||
|
||||
public Map<Class, DocWorkUnit> workUnits() {
|
||||
Map<Class, DocWorkUnit> m = new HashMap<Class, DocWorkUnit>();
|
||||
|
||||
for ( ClassDoc doc : rootDoc.classes() ) {
|
||||
System.out.printf("Considering %s%n", doc);
|
||||
Class clazz = getClassForClassDoc(doc);
|
||||
DocumentedGATKFeature feature = getFeatureForClassDoc(doc);
|
||||
DocumentedGATKFeatureHandler handler = createHandler(doc, feature);
|
||||
if ( handler != null && handler.shouldBeProcessed(doc) ) {
|
||||
String filename = handler.getDestinationFilename(doc);
|
||||
DocWorkUnit unit = new DocWorkUnit(feature,
|
||||
doc.name(), filename, feature.groupName(),
|
||||
handler, doc, clazz );
|
||||
m.put(clazz, unit);
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processDocs(RootDoc rootDoc, PrintStream ignore) {
|
||||
// setup the global access to the root
|
||||
|
|
@ -108,19 +137,12 @@ public class GATKDoclet extends ResourceBundleExtractorDoclet {
|
|||
// Specify how templates will see the data-model. This is an advanced topic...
|
||||
cfg.setObjectWrapper(new DefaultObjectWrapper());
|
||||
|
||||
List<DocumentationData> indexData = new ArrayList<DocumentationData>();
|
||||
Set<DocumentedGATKFeature> docFeatures = new HashSet<DocumentedGATKFeature>();
|
||||
for ( ClassDoc doc : rootDoc.classes() ) {
|
||||
System.out.printf("Considering %s%n", doc);
|
||||
DocumentedGATKFeatureHandler handler = getHandlerForClassDoc(doc);
|
||||
if ( handler != null && handler.shouldBeProcessed(doc) ) {
|
||||
DocumentationData docData = processDocumentationWithHandler(cfg, handler, doc);
|
||||
docFeatures.add(handler.getAnnotation());
|
||||
indexData.add(docData);
|
||||
}
|
||||
Map<Class, DocWorkUnit> workUnitMap = workUnits();
|
||||
for ( DocWorkUnit workUnit : workUnitMap.values() ) {
|
||||
processDocWorkUnit(cfg, workUnit, workUnitMap);
|
||||
}
|
||||
|
||||
processIndex(cfg, indexData, new ArrayList<DocumentedGATKFeature>(docFeatures));
|
||||
processIndex(cfg, new ArrayList<DocWorkUnit>(workUnitMap.values()));
|
||||
} catch ( FileNotFoundException e ) {
|
||||
throw new RuntimeException(e);
|
||||
} catch ( IOException e ) {
|
||||
|
|
@ -128,53 +150,66 @@ public class GATKDoclet extends ResourceBundleExtractorDoclet {
|
|||
}
|
||||
}
|
||||
|
||||
private DocumentedGATKFeatureHandler getHandlerForClassDoc(ClassDoc doc) {
|
||||
private DocumentedGATKFeatureHandler createHandler(ClassDoc doc, DocumentedGATKFeature feature) {
|
||||
try {
|
||||
// todo -- what do I need the ? extends Object to pass the compiler?
|
||||
Class<? extends Object> docClass = HelpUtils.getClassForDoc(doc);
|
||||
if ( docClass.isAnnotationPresent(DocumentedGATKFeature.class) ) {
|
||||
DocumentedGATKFeature feature = docClass.getAnnotation(DocumentedGATKFeature.class);
|
||||
if ( feature != null ) {
|
||||
if ( feature.enable() ) {
|
||||
DocumentedGATKFeatureHandler handler = feature.handler().newInstance();
|
||||
handler.setGroupName(feature.groupName());
|
||||
handler.setDoclet(this);
|
||||
handler.setAnnotation(feature);
|
||||
return handler;
|
||||
} else {
|
||||
logger.info("Skipping disabled Documentation for " + doc);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null; // not annotated so it shouldn't be documented
|
||||
}
|
||||
} 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
|
||||
return null;
|
||||
} catch ( IllegalAccessException e) {
|
||||
throw new RuntimeException(e); // the constructor is now private -- this is an error
|
||||
} catch ( InstantiationException e) {
|
||||
throw new RuntimeException(e); // the constructor is now private -- this is an error
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private DocumentedGATKFeature getFeatureForClassDoc(ClassDoc doc) {
|
||||
// todo -- what do I need the ? extends Object to pass the compiler?
|
||||
Class<? extends Object> docClass = getClassForClassDoc(doc);
|
||||
if ( docClass != null && docClass.isAnnotationPresent(DocumentedGATKFeature.class) ) {
|
||||
return docClass.getAnnotation(DocumentedGATKFeature.class);
|
||||
} else {
|
||||
return null; // not annotated so it shouldn't be documented
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
} 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
|
||||
return null;
|
||||
} catch ( NoClassDefFoundError e ) {
|
||||
return null;
|
||||
} catch ( UnsatisfiedLinkError e) {
|
||||
return null; // naughty BWA bindings
|
||||
}
|
||||
}
|
||||
|
||||
private void processIndex(Configuration cfg, List<DocumentationData> indexData, List<DocumentedGATKFeature> docFeatures) throws IOException {
|
||||
private void processIndex(Configuration cfg, List<DocWorkUnit> indexData) throws IOException {
|
||||
/* Get or create a template */
|
||||
Template temp = cfg.getTemplate("generic.index.template.html");
|
||||
|
||||
/* Merge data-model with template */
|
||||
Writer out = new OutputStreamWriter(new FileOutputStream(new File("testdoc/index.html")));
|
||||
try {
|
||||
temp.process(groupIndexData(indexData, docFeatures), out);
|
||||
temp.process(groupIndexData(indexData), out);
|
||||
out.flush();
|
||||
} catch ( TemplateException e ) {
|
||||
throw new ReviewedStingException("Failed to create GATK documentation", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> groupIndexData(List<DocumentationData> indexData, List<DocumentedGATKFeature> docFeatures) {
|
||||
private Map<String, Object> groupIndexData(List<DocWorkUnit> indexData) {
|
||||
//
|
||||
// root -> data -> { summary -> y, filename -> z }, etc
|
||||
// -> groups -> group1, group2, etc.
|
||||
|
|
@ -182,9 +217,11 @@ public class GATKDoclet extends ResourceBundleExtractorDoclet {
|
|||
|
||||
Collections.sort(indexData);
|
||||
|
||||
Set<DocumentedGATKFeature> docFeatures = new HashSet<DocumentedGATKFeature>();
|
||||
List<Map<String, String>> data = new ArrayList<Map<String, String>>();
|
||||
for ( DocumentationData indexDatum : indexData ) {
|
||||
data.add(indexDatum.toMap());
|
||||
for ( DocWorkUnit workUnit : indexData ) {
|
||||
data.add(workUnit.toMap());
|
||||
docFeatures.add(workUnit.annotation);
|
||||
}
|
||||
|
||||
List<Map<String, String>> groups = new ArrayList<Map<String, String>>();
|
||||
|
|
@ -205,30 +242,23 @@ public class GATKDoclet extends ResourceBundleExtractorDoclet {
|
|||
return root;
|
||||
}
|
||||
|
||||
private DocumentationData processDocumentationWithHandler(Configuration cfg,
|
||||
DocumentedGATKFeatureHandler handler,
|
||||
ClassDoc doc)
|
||||
private void processDocWorkUnit(Configuration cfg, DocWorkUnit unit, Map<Class, DocWorkUnit> all)
|
||||
throws IOException {
|
||||
System.out.printf("Processing documentation for class %s%n", doc);
|
||||
System.out.printf("Processing documentation for class %s%n", unit.classDoc);
|
||||
|
||||
DocumentationData docData = handler.processOne(doc);
|
||||
docData.setGroup(handler.getGroupName());
|
||||
unit.handler.processOne(unit, all);
|
||||
|
||||
// Get or create a template
|
||||
Template temp = cfg.getTemplate(handler.getTemplateName(doc));
|
||||
Template temp = cfg.getTemplate(unit.handler.getTemplateName(unit.classDoc));
|
||||
|
||||
// Merge data-model with template
|
||||
String filename = handler.getDestinationFilename(doc);
|
||||
docData.setFilename(filename);
|
||||
File outputPath = new File("testdoc/" + filename);
|
||||
File outputPath = new File("testdoc/" + unit.filename);
|
||||
try {
|
||||
Writer out = new OutputStreamWriter(new FileOutputStream(outputPath));
|
||||
temp.process(docData.forTemplate, out);
|
||||
temp.process(unit.forTemplate, out);
|
||||
out.flush();
|
||||
} catch ( TemplateException e ) {
|
||||
throw new ReviewedStingException("Failed to create GATK documentation", e);
|
||||
}
|
||||
|
||||
return docData;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,10 +35,7 @@ import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
|||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -54,20 +51,16 @@ public class GenericDocumentationHandler extends DocumentedGATKFeatureHandler {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getTemplateName(ClassDoc doc) throws IOException {
|
||||
return "generic.template.html";
|
||||
}
|
||||
|
||||
@Override
|
||||
public GATKDoclet.DocumentationData processOne(ClassDoc doc) {
|
||||
System.out.printf("%s class %s%n", getGroupName(), doc);
|
||||
Map<String, Object> root = buildWalkerDataModel(doc); // Create the root hash
|
||||
return new GATKDoclet.DocumentationData(doc.name(), (String)root.get("summary"), root);
|
||||
}
|
||||
|
||||
|
||||
private Map<String, Object> buildWalkerDataModel(ClassDoc classdoc) {
|
||||
public void processOne(GATKDoclet.DocWorkUnit toProcess, Map<Class, GATKDoclet.DocWorkUnit> all) {
|
||||
System.out.printf("%s class %s%n", toProcess.group, toProcess.classDoc);
|
||||
ClassDoc classdoc = toProcess.classDoc;
|
||||
Map<String, Object> root = new HashMap<String, Object>();
|
||||
|
||||
root.put("name", classdoc.name());
|
||||
|
|
@ -109,8 +102,21 @@ public class GenericDocumentationHandler extends DocumentedGATKFeatureHandler {
|
|||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
List<Map<String, Object>> extraDocsData = new ArrayList<Map<String, Object>>();
|
||||
for ( Class extraDocClass : toProcess.annotation.extraDocs() ) {
|
||||
final GATKDoclet.DocWorkUnit otherUnit = all.get(extraDocClass);
|
||||
if ( otherUnit == null )
|
||||
throw new ReviewedStingException("Requested extraDocs for class without any documentation: " + extraDocClass);
|
||||
extraDocsData.add(
|
||||
new HashMap<String, Object>(){{
|
||||
put("filename", otherUnit.filename);
|
||||
put("name", otherUnit.name);}});
|
||||
|
||||
}
|
||||
root.put("extradocs", extraDocsData);
|
||||
|
||||
//System.out.printf("Root is %s%n", root);
|
||||
return root;
|
||||
toProcess.setHandlerContent(summaryBuilder.toString(), root);
|
||||
}
|
||||
|
||||
protected ParsingEngine createStandardGATKParsingEngine() {
|
||||
|
|
|
|||
|
|
@ -38,26 +38,47 @@
|
|||
</#if>
|
||||
<h2>Description</h2>
|
||||
${description}
|
||||
<#-- Create the argument summary -->
|
||||
<h2>Arguments</h2>
|
||||
<table border="1" cellpadding="2">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Synonyms</th>
|
||||
<th>Type</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
<@argumentlist name="Required" myargs=arguments.required/>
|
||||
<@argumentlist name="Optional" myargs=arguments.optional/>
|
||||
<@argumentlist name="Hidden" myargs=arguments.hidden/>
|
||||
<@argumentlist name="Depreciated" myargs=arguments.depreciated/>
|
||||
</table>
|
||||
|
||||
<#-- Create the argument details -->
|
||||
<h2>Argument details</h2>
|
||||
<#list arguments.all as arg>
|
||||
<@argumentDetails arg=arg/>
|
||||
</#list>
|
||||
|
||||
<#-- Create the argument summary -->
|
||||
<#if arguments.all?size != 0>
|
||||
<hr>
|
||||
<h2>Feature specific arguments</h2>
|
||||
<table border="1" cellpadding="2">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Synonyms</th>
|
||||
<th>Type</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
<@argumentlist name="Required" myargs=arguments.required/>
|
||||
<@argumentlist name="Optional" myargs=arguments.optional/>
|
||||
<@argumentlist name="Hidden" myargs=arguments.hidden/>
|
||||
<@argumentlist name="Depreciated" myargs=arguments.depreciated/>
|
||||
</table>
|
||||
</#if>
|
||||
|
||||
<#-- Create references to related capabilities if appropriate -->
|
||||
<#if extradocs?size != 0>
|
||||
<hr>
|
||||
<h2>Related capabilities</h2>
|
||||
The arguments described in the entries below can be supplied to this tool to modify
|
||||
its behavior. For example, the -L argument directs the GATK engine restricts processing
|
||||
to specific genomic intervals. This capability is available to all GATK walkers.
|
||||
<ul>
|
||||
<#list extradocs as extradoc>
|
||||
<li><a href="${extradoc.filename}">${extradoc.name}</a></li>
|
||||
</#list>
|
||||
</ul>
|
||||
</#if>
|
||||
|
||||
<#-- List all of the -->
|
||||
<#if arguments.all?size != 0>
|
||||
<hr>
|
||||
<#-- Create the argument details -->
|
||||
<h2>Argument details</h2>
|
||||
<#list arguments.all as arg>
|
||||
<@argumentDetails arg=arg/>
|
||||
</#list>
|
||||
</#if>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Reference in New Issue