Move some files around to reflect our growing help infrastructure.

git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@2280 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
hanna 2009-12-07 19:23:12 +00:00
parent 16ef500139
commit 10be5a5de9
12 changed files with 466 additions and 91 deletions

View File

@ -98,7 +98,7 @@
<target name="extracthelp" depends="compile"
description="Extract help key/value pair file from the JavaDoc tags.">
<javadoc doclet="org.broadinstitute.sting.utils.doc.HelpExtractorDoclet"
<javadoc doclet="org.broadinstitute.sting.utils.help.HelpExtractorDoclet"
docletpath="build"
classpathref="runtime.dependencies"
additionalparam="-out ${help.file}">

View File

@ -2,6 +2,7 @@ package org.broadinstitute.sting.gatk;
import org.broadinstitute.sting.utils.GATKErrorReport;
import org.broadinstitute.sting.utils.TextFormattingUtils;
import org.broadinstitute.sting.utils.help.ApplicationDetails;
import org.broadinstitute.sting.utils.cmdLine.*;
import org.broadinstitute.sting.gatk.walkers.Walker;

View File

@ -35,7 +35,7 @@ import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedData;
import org.broadinstitute.sting.gatk.filters.FilterManager;
import org.broadinstitute.sting.utils.StingException;
import org.broadinstitute.sting.utils.PluginManager;
import org.broadinstitute.sting.utils.doc.DisplayNameTaglet;
import org.broadinstitute.sting.utils.help.DisplayNameTaglet;
import org.apache.log4j.Logger;
import net.sf.picard.filter.SamRecordFilter;

View File

@ -0,0 +1,64 @@
package org.broadinstitute.sting.utils.cmdLine;
import org.broadinstitute.sting.utils.StingException;
import java.util.List;
import java.util.Collections;
import java.util.ArrayList;
import java.util.Iterator;
/**
* A group of argument definitions.
*/
public class ArgumentDefinitionGroup implements Iterable<ArgumentDefinition> {
/**
* Name of this group.
*/
public final String groupName;
/**
* The argument definitions associated with this group.
*/
public final List<ArgumentDefinition> argumentDefinitions;
public ArgumentDefinitionGroup( String groupName, List<ArgumentDefinition> argumentDefinitions ) {
this.groupName = groupName;
this.argumentDefinitions = Collections.unmodifiableList( argumentDefinitions );
}
/**
* Does the name of this argument group match the name of another?
*/
public boolean groupNameMatches( ArgumentDefinitionGroup other ) {
if( this.groupName == null && other.groupName == null )
return true;
if( this.groupName == null && other.groupName != null )
return false;
return this.groupName.equals(other.groupName);
}
/**
* Merges another argument group into this argument group. Return a new
* group since argument groups are supposed to be immutable. Asserts that
* both argument groups have the same name.
*/
public ArgumentDefinitionGroup merge( ArgumentDefinitionGroup other ) {
if( !groupNameMatches(other) )
throw new StingException("Unable to merge two argument groups with differing names.");
// Create a merged definition group.
List<ArgumentDefinition> mergedDefinitions = new ArrayList<ArgumentDefinition>();
mergedDefinitions.addAll(this.argumentDefinitions);
mergedDefinitions.addAll(other.argumentDefinitions);
return new ArgumentDefinitionGroup(groupName,mergedDefinitions);
}
/**
* Iterate over the arguments in an argument definition group.
* @return
*/
public Iterator<ArgumentDefinition> iterator() {
return argumentDefinitions.iterator();
}
}

View File

@ -27,7 +27,7 @@ import java.util.Collections;
/**
* A collection of argument definitions.
*/
class ArgumentDefinitions implements Iterable<ArgumentDefinition> {
public class ArgumentDefinitions implements Iterable<ArgumentDefinition> {
/**
* Backing data set of argument stored by short name and long name.
*/
@ -117,7 +117,7 @@ class ArgumentDefinitions implements Iterable<ArgumentDefinition> {
* Return a list of the available argument groups.
* @return All the argument groups that have been added.
*/
Collection<ArgumentDefinitionGroup> getArgumentDefinitionGroups() {
public Collection<ArgumentDefinitionGroup> getArgumentDefinitionGroups() {
return argumentDefinitionGroups;
}
@ -171,62 +171,6 @@ class ArgumentDefinitions implements Iterable<ArgumentDefinition> {
};
}
/**
* A group of argument definitions.
*/
class ArgumentDefinitionGroup implements Iterable<ArgumentDefinition> {
/**
* Name of this group.
*/
public final String groupName;
/**
* The argument definitions associated with this group.
*/
public final List<ArgumentDefinition> argumentDefinitions;
public ArgumentDefinitionGroup( String groupName, List<ArgumentDefinition> argumentDefinitions ) {
this.groupName = groupName;
this.argumentDefinitions = Collections.unmodifiableList( argumentDefinitions );
}
/**
* Does the name of this argument group match the name of another?
*/
public boolean groupNameMatches( ArgumentDefinitionGroup other ) {
if( this.groupName == null && other.groupName == null )
return true;
if( this.groupName == null && other.groupName != null )
return false;
return this.groupName.equals(other.groupName);
}
/**
* Merges another argument group into this argument group. Return a new
* group since argument groups are supposed to be immutable. Asserts that
* both argument groups have the same name.
*/
public ArgumentDefinitionGroup merge( ArgumentDefinitionGroup other ) {
if( !groupNameMatches(other) )
throw new StingException("Unable to merge two argument groups with differing names.");
// Create a merged definition group.
List<ArgumentDefinition> mergedDefinitions = new ArrayList<ArgumentDefinition>();
mergedDefinitions.addAll(this.argumentDefinitions);
mergedDefinitions.addAll(other.argumentDefinitions);
return new ArgumentDefinitionGroup(groupName,mergedDefinitions);
}
/**
* Iterate over the arguments in an argument definition group.
* @return
*/
public Iterator<ArgumentDefinition> iterator() {
return argumentDefinitions.iterator();
}
}
/**
* A Comparator-esque interface for finding argument definitions within a collection.
*/

View File

@ -1,12 +1,12 @@
package org.broadinstitute.sting.utils.cmdLine;
import org.apache.log4j.*;
import org.broadinstitute.sting.utils.help.ApplicationDetails;
import org.broadinstitute.sting.utils.help.HelpFormatter;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
@ -224,7 +224,7 @@ public abstract class CommandLineProgram {
clp.setupLoggerLevel();
// regardless of what happens next, generate the header information
generateHeaderInformation(clp, args);
HelpFormatter.generateHeaderInformation(clp.getApplicationDetails(), args);
// call the execute
CommandLineProgram.result = clp.execute();
@ -284,32 +284,6 @@ public abstract class CommandLineProgram {
parser.addArgumentSource(clp.getArgumentSourceName(cls), cls);
}
/**
* generateHeaderInformation
* <p/>
* <p/>
* Generate a standard header for the logger
*
* @param clp the command line program to execute
* @param args the command line arguments passed in
*/
protected static void generateHeaderInformation(CommandLineProgram clp, String[] args) {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
java.util.Date date = new java.util.Date();
logger.info("-------------------------------------------------------");
for (String headerLine : clp.getApplicationDetails().applicationHeader)
logger.info(headerLine);
String output = "";
for (String str : args) {
output = output + str + " ";
}
logger.info("Program Args: " + output);
logger.info("Date/Time: " + dateFormat.format(date));
logger.info("-------------------------------------------------------");
}
/**
* this function checks the logger level passed in on the command line, taking the lowest
* level that was provided.

View File

@ -3,6 +3,8 @@ package org.broadinstitute.sting.utils.cmdLine;
import org.broadinstitute.sting.utils.StingException;
import org.broadinstitute.sting.utils.Pair;
import org.broadinstitute.sting.utils.JVMUtils;
import org.broadinstitute.sting.utils.help.ApplicationDetails;
import org.broadinstitute.sting.utils.help.HelpFormatter;
import org.apache.log4j.Logger;
import java.lang.reflect.*;

View File

@ -23,10 +23,11 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
package org.broadinstitute.sting.utils.cmdLine;
package org.broadinstitute.sting.utils.help;
import org.broadinstitute.sting.utils.JVMUtils;
import org.broadinstitute.sting.utils.StingException;
import org.broadinstitute.sting.utils.cmdLine.CommandLineProgram;
import java.util.List;
import java.util.Collections;

View File

@ -0,0 +1,120 @@
package org.broadinstitute.sting.utils.help;
import com.sun.tools.doclets.Taglet;
import com.sun.javadoc.Tag;
import java.util.Map;
/**
* Provide an alternate description for the given help system.
*
* @author mhanna
* @version 0.1
*/
public class DescriptionTaglet implements Taglet {
/**
* The key tag for this taglet.
*/
public static final String NAME = "help.description";
/**
* Return the name of this custom tag.
*/
public String getName() {
return NAME;
}
/**
* Will return false since this tag cannot be applied
* to a field.
* @return false since this tag cannot be applied to a field.
*/
public boolean inField() {
return false;
}
/**
* Will return false since this tag cannot be applied
* to a constructor.
* @return false since this tag cannot be applied to a constructor.
*/
public boolean inConstructor() {
return false;
}
/**
* Will return false since this tag cannot be applied
* to a method.
* @return false since this tag cannot be applied to a method.
*/
public boolean inMethod() {
return false;
}
/**
* Will return false since overviews are always named
* by the <code>@WalkerName</code> tag.
* @return false always
*/
public boolean inOverview() {
return true;
}
/**
* Will return true to indicate that packages can be given useful
* description.
* @return true always
*/
public boolean inPackage() {
return true;
}
/**
* Will return false indicating that types cannot be given
* alternate description.
* @return false always.
*/
public boolean inType() {
return false;
}
/**
* Will return false since <code>@todo</code>
* is not an inline tag.
* @return false since <code>@todo</code>
* is not an inline tag.
*/
public boolean isInlineTag() {
return false;
}
/**
* Register this Taglet.
* @param tagletMap the map to register this tag to.
*/
public static void register(Map tagletMap) {
DescriptionTaglet tag = new DescriptionTaglet();
Taglet t = (Taglet)tagletMap.get(tag.getName());
if (t != null) {
tagletMap.remove(tag.getName());
}
tagletMap.put(tag.getName(), tag);
}
/**
* Create a string representation of this tag. Since this tag is only
* used by the help system, don't output any HTML.
*/
public String toString(Tag tag) {
return null;
}
/**
* Create a string representation of this tag. Since this tag is only
* used by the help system, don't output any HTML.
*/
public String toString(Tag[] tags) {
return null;
}
}

View File

@ -0,0 +1,120 @@
package org.broadinstitute.sting.utils.help;
import com.sun.tools.doclets.Taglet;
import com.sun.javadoc.Tag;
import java.util.Map;
/**
* Provide a display name in the help for packages
*
* @author mhanna
* @version 0.1
*/
public class DisplayNameTaglet implements Taglet {
/**
* The display name for this taglet.
*/
public static final String NAME = "help.display.name";
/**
* Return the name of this custom tag.
*/
public String getName() {
return NAME;
}
/**
* Will return false since this tag cannot be applied
* to a field.
* @return false since this tag cannot be applied to a field.
*/
public boolean inField() {
return false;
}
/**
* Will return false since this tag cannot be applied
* to a constructor.
* @return false since this tag cannot be applied to a constructor.
*/
public boolean inConstructor() {
return false;
}
/**
* Will return false since this tag cannot be applied
* to a method.
* @return false since this tag cannot be applied to a method.
*/
public boolean inMethod() {
return false;
}
/**
* Will return false since overviews are always named
* by the <code>@WalkerName</code> tag.
* @return false always
*/
public boolean inOverview() {
return false;
}
/**
* Will return true to indicate that packages can be given useful
* display text.
* @return true always
*/
public boolean inPackage() {
return true;
}
/**
* Will return false indicating that types cannot be given
* alternate display names.
* @return false always.
*/
public boolean inType() {
return false;
}
/**
* Will return false since <code>@todo</code>
* is not an inline tag.
* @return false since <code>@todo</code>
* is not an inline tag.
*/
public boolean isInlineTag() {
return false;
}
/**
* Register this Taglet.
* @param tagletMap the map to register this tag to.
*/
public static void register(Map tagletMap) {
DisplayNameTaglet tag = new DisplayNameTaglet();
Taglet t = (Taglet)tagletMap.get(tag.getName());
if (t != null) {
tagletMap.remove(tag.getName());
}
tagletMap.put(tag.getName(), tag);
}
/**
* Create a string representation of this tag. Since this tag is only
* used by the help system, don't output any HTML.
*/
public String toString(Tag tag) {
return null;
}
/**
* Create a string representation of this tag. Since this tag is only
* used by the help system, don't output any HTML.
*/
public String toString(Tag[] tags) {
return null;
}
}

View File

@ -0,0 +1,113 @@
package org.broadinstitute.sting.utils.help;
import com.sun.javadoc.*;
import java.util.HashSet;
import java.util.Set;
import java.util.Scanner;
import java.io.PrintStream;
import java.io.FileNotFoundException;
import org.broadinstitute.sting.utils.StingException;
/**
* Extracts certain types of javadoc (specifically package and class descriptions) and makes them available
* to applications at runtime.
*
* @author mhanna
* @version 0.1
*/
public class HelpExtractorDoclet {
/**
* Extracts the contents of certain types of javadoc and adds them to an XML file.
* @param rootDoc The documentation root.
* @return Whether the JavaDoc run succeeded.
* @throws FileNotFoundException if output can't be written.
*/
public static boolean start(RootDoc rootDoc) throws FileNotFoundException {
PrintStream out = System.out;
for(String[] options: rootDoc.options()) {
if(options[0].equals("-out"))
out = new PrintStream(options[1]);
}
// Cache packages as we see them, since there's no direct way to iterate over packages.
Set<PackageDoc> packages = new HashSet<PackageDoc>();
for(ClassDoc currentClass: rootDoc.classes()) {
PackageDoc containingPackage = currentClass.containingPackage();
packages.add(containingPackage);
String className = containingPackage.name().length() > 0 ?
String.format("%s.%s",containingPackage.name(),currentClass.name()) :
String.format("%s",currentClass.name());
renderHelpText(className,currentClass,out);
}
for(PackageDoc currentPackage: packages)
renderHelpText(currentPackage.name(),currentPackage,out);
return true;
}
/**
* Validate the given options against options supported by this doclet.
* @param option Option to validate.
* @return Number of potential parameters; 0 if not supported.
*/
public static int optionLength(String option) {
if(option.equals("-out")) {
return 2;
}
return 0;
}
/**
* Renders all the help text required for a given name.
* @param elementName element name to use as the key
* @param element Doc element to process.
* @param out Output stream to which to write.
*/
private static void renderHelpText(String elementName, Doc element, PrintStream out) {
// Extract overrides from the doc tags.
String overrideName = null;
String overrideDescription = element.commentText();
for(Tag tag: element.tags()) {
if(tag.name().equals("@"+DisplayNameTaglet.NAME)) {
if(overrideName != null)
throw new StingException("Only one display name tag can be used per package / walker.");
overrideName = tag.text();
}
else if(tag.name().equals("@"+DescriptionTaglet.NAME))
overrideDescription = tag.text();
}
// Write out an alternate element name, if exists.
if(overrideName != null)
out.printf("%s.%s=%s%n",elementName,DisplayNameTaglet.NAME,overrideName);
// Write out an alternate description, if present.
String description = formatText(overrideDescription);
if(description.length() > 0)
out.printf("%s=%s%n",elementName,description);
}
/**
* Format text for consumption by the properties file.
* @param text Text to format.
* @return Formatted text; string trimmed, newlines removed.
*/
private static String formatText(String text) {
Scanner scanner = new Scanner(text);
StringBuilder output = new StringBuilder();
while(scanner.hasNextLine()) {
if(output.length() > 0)
output.append(' ');
output.append(scanner.nextLine().trim());
}
return output.toString();
}
}

View File

@ -1,6 +1,11 @@
package org.broadinstitute.sting.utils.cmdLine;
package org.broadinstitute.sting.utils.help;
import org.broadinstitute.sting.utils.cmdLine.ArgumentDefinition;
import org.broadinstitute.sting.utils.cmdLine.ArgumentDefinitionGroup;
import org.broadinstitute.sting.utils.cmdLine.ArgumentDefinitions;
import org.broadinstitute.sting.utils.cmdLine.CommandLineProgram;
import org.broadinstitute.sting.utils.TextFormattingUtils;
import org.apache.log4j.Logger;
import java.util.Formatter;
import java.util.List;
@ -9,6 +14,8 @@ import java.util.Iterator;
import java.util.Comparator;
import java.util.Collection;
import java.util.Collections;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
/**
* User: hanna
* Date: May 6, 2009
@ -27,6 +34,9 @@ import java.util.Collections;
*/
public class HelpFormatter {
/** our log, which we want to capture anything from org.broadinstitute.sting */
private static Logger logger = Logger.getRootLogger();
public static final int FIELD_SEPARATION_WIDTH = 3;
/**
@ -209,4 +219,30 @@ public class HelpFormatter {
return argumentGroups;
}
/**
* generateHeaderInformation
* <p/>
* <p/>
* Generate a standard header for the logger
*
* @param applicationDetails details of the application to run.
* @param args the command line arguments passed in
*/
public static void generateHeaderInformation(ApplicationDetails applicationDetails, String[] args) {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
java.util.Date date = new java.util.Date();
logger.info("-------------------------------------------------------");
for (String headerLine : applicationDetails.applicationHeader)
logger.info(headerLine);
String output = "";
for (String str : args) {
output = output + str + " ";
}
logger.info("Program Args: " + output);
logger.info("Date/Time: " + dateFormat.format(date));
logger.info("-------------------------------------------------------");
}
}