Miscellaneous cleanup. Better display of help output. Better exception subtyping. More thought-out access routines.
git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@608 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
parent
5be75e0ae6
commit
62e7e46754
|
|
@ -9,6 +9,7 @@ import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by IntelliJ IDEA.
|
* Created by IntelliJ IDEA.
|
||||||
|
|
@ -34,23 +35,28 @@ class ArgumentDefinitions implements Iterable<ArgumentDefinition> {
|
||||||
private Set<ArgumentDefinition> argumentDefinitions = new HashSet<ArgumentDefinition>();
|
private Set<ArgumentDefinition> argumentDefinitions = new HashSet<ArgumentDefinition>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an argument to the this argument definition list.
|
* The groupings of argument definitions. Used mainly for help output.
|
||||||
* @param argument The argument to add.
|
|
||||||
* @param sourceClass Class where the argument was defined.
|
|
||||||
* @param sourceField Field in which the argument was defined.
|
|
||||||
*/
|
*/
|
||||||
public void add( Argument argument, Class sourceClass, Field sourceField ) {
|
private Set<ArgumentDefinitionGroup> argumentDefinitionGroups = new HashSet<ArgumentDefinitionGroup>();
|
||||||
ArgumentDefinition definition = new ArgumentDefinition( argument, sourceClass, sourceField );
|
|
||||||
if( definition.fullName.length() == 0 ) {
|
/**
|
||||||
throw new IllegalArgumentException( "Argument cannot have 0-length fullname." );
|
* Adds an argument to the this argument definition list.
|
||||||
|
* @param argumentDefinitionGroup The group of arguments to add.
|
||||||
|
*/
|
||||||
|
public void add( ArgumentDefinitionGroup argumentDefinitionGroup ) {
|
||||||
|
for( ArgumentDefinition definition: argumentDefinitionGroup ) {
|
||||||
|
// Do some basic validation before adding the definition.
|
||||||
|
if( definition.fullName.length() == 0 )
|
||||||
|
throw new IllegalArgumentException( "Argument cannot have 0-length fullname." );
|
||||||
|
if( hasArgumentDefinition( definition.fullName, FullNameDefinitionMatcher ) )
|
||||||
|
throw new StingException("Duplicate definition of argument with full name: " + definition.fullName);
|
||||||
|
if( hasArgumentDefinition( definition.shortName, ShortNameDefinitionMatcher ) )
|
||||||
|
throw new StingException("Duplicate definition of argument with short name: " + definition.shortName);
|
||||||
|
|
||||||
|
argumentDefinitions.add( definition );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( hasArgumentDefinition( definition.fullName, FullNameDefinitionMatcher ) )
|
argumentDefinitionGroups.add( argumentDefinitionGroup );
|
||||||
throw new StingException("Duplicate definition of argument with full name: " + definition.fullName);
|
|
||||||
if( hasArgumentDefinition( definition.shortName, ShortNameDefinitionMatcher ) )
|
|
||||||
throw new StingException("Duplicate definition of argument with short name: " + definition.shortName);
|
|
||||||
|
|
||||||
argumentDefinitions.add( definition );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -96,9 +102,17 @@ class ArgumentDefinitions implements Iterable<ArgumentDefinition> {
|
||||||
return selectedArgumentDefinitions;
|
return selectedArgumentDefinitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of the available argument groups.
|
||||||
|
* @return All the argument groups that have been added.
|
||||||
|
*/
|
||||||
|
Collection<ArgumentDefinitionGroup> getArgumentDefinitionGroups() {
|
||||||
|
return argumentDefinitionGroups;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterates through all command-line arguments.
|
* Iterates through all command-line arguments.
|
||||||
* @return
|
* @return an iterator over command-line arguments.
|
||||||
*/
|
*/
|
||||||
public Iterator<ArgumentDefinition> iterator() {
|
public Iterator<ArgumentDefinition> iterator() {
|
||||||
return argumentDefinitions.iterator();
|
return argumentDefinitions.iterator();
|
||||||
|
|
@ -107,7 +121,7 @@ class ArgumentDefinitions implements Iterable<ArgumentDefinition> {
|
||||||
/**
|
/**
|
||||||
* Match the full name of a definition.
|
* Match the full name of a definition.
|
||||||
*/
|
*/
|
||||||
public static DefinitionMatcher FullNameDefinitionMatcher = new DefinitionMatcher() {
|
static DefinitionMatcher FullNameDefinitionMatcher = new DefinitionMatcher() {
|
||||||
public boolean matches( ArgumentDefinition definition, Object key ) {
|
public boolean matches( ArgumentDefinition definition, Object key ) {
|
||||||
if( definition.fullName == null )
|
if( definition.fullName == null )
|
||||||
return key == null;
|
return key == null;
|
||||||
|
|
@ -119,7 +133,7 @@ class ArgumentDefinitions implements Iterable<ArgumentDefinition> {
|
||||||
/**
|
/**
|
||||||
* Match the short name of a definition.
|
* Match the short name of a definition.
|
||||||
*/
|
*/
|
||||||
public static DefinitionMatcher ShortNameDefinitionMatcher = new DefinitionMatcher() {
|
static DefinitionMatcher ShortNameDefinitionMatcher = new DefinitionMatcher() {
|
||||||
public boolean matches( ArgumentDefinition definition, Object key ) {
|
public boolean matches( ArgumentDefinition definition, Object key ) {
|
||||||
if( definition.shortName == null )
|
if( definition.shortName == null )
|
||||||
return key == null;
|
return key == null;
|
||||||
|
|
@ -128,7 +142,7 @@ class ArgumentDefinitions implements Iterable<ArgumentDefinition> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static AliasProvider ShortNameAliasProvider = new AliasProvider() {
|
static AliasProvider ShortNameAliasProvider = new AliasProvider() {
|
||||||
/**
|
/**
|
||||||
* Short names can come in the form -Ofoo.txt, -O foo.txt, or -out (multi-character short name).
|
* Short names can come in the form -Ofoo.txt, -O foo.txt, or -out (multi-character short name).
|
||||||
* Given the argument name and built-in provided, see if these can be formed into some other argument
|
* Given the argument name and built-in provided, see if these can be formed into some other argument
|
||||||
|
|
@ -159,7 +173,7 @@ class ArgumentDefinitions implements Iterable<ArgumentDefinition> {
|
||||||
/**
|
/**
|
||||||
* Find all required definitions.
|
* Find all required definitions.
|
||||||
*/
|
*/
|
||||||
public static DefinitionMatcher RequiredDefinitionMatcher = new DefinitionMatcher() {
|
static DefinitionMatcher RequiredDefinitionMatcher = new DefinitionMatcher() {
|
||||||
public boolean matches( ArgumentDefinition definition, Object key ) {
|
public boolean matches( ArgumentDefinition definition, Object key ) {
|
||||||
if( !(key instanceof Boolean) )
|
if( !(key instanceof Boolean) )
|
||||||
throw new IllegalArgumentException("RequiredDefinitionMatcher requires boolean key");
|
throw new IllegalArgumentException("RequiredDefinitionMatcher requires boolean key");
|
||||||
|
|
@ -168,6 +182,34 @@ 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 Collection<ArgumentDefinition> argumentDefinitions;
|
||||||
|
|
||||||
|
public ArgumentDefinitionGroup( String groupName, Collection<ArgumentDefinition> argumentDefinitions ) {
|
||||||
|
this.groupName = groupName;
|
||||||
|
this.argumentDefinitions = Collections.unmodifiableCollection( argumentDefinitions );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterate over the arguments in an argument definition group.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Iterator<ArgumentDefinition> iterator() {
|
||||||
|
return argumentDefinitions.iterator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A specific argument definition. Maps one-to-one with a field in some class.
|
* A specific argument definition. Maps one-to-one with a field in some class.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,6 @@ public abstract class CommandLineProgram {
|
||||||
required=false)
|
required=false)
|
||||||
protected Boolean debugMode = false;
|
protected Boolean debugMode = false;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* our logging output patterns
|
* our logging output patterns
|
||||||
*/
|
*/
|
||||||
|
|
@ -145,7 +144,7 @@ public abstract class CommandLineProgram {
|
||||||
|
|
||||||
Class[] argumentSources = clp.getArgumentSources();
|
Class[] argumentSources = clp.getArgumentSources();
|
||||||
for( Class argumentSource: argumentSources )
|
for( Class argumentSource: argumentSources )
|
||||||
parser.addArgumentSource( argumentSource );
|
parser.addArgumentSource( clp.getArgumentSourceName(argumentSource), argumentSource );
|
||||||
parser.parse(args);
|
parser.parse(args);
|
||||||
parser.validate();
|
parser.validate();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,20 @@
|
||||||
package org.broadinstitute.sting.utils.cmdLine;
|
package org.broadinstitute.sting.utils.cmdLine;
|
||||||
|
|
||||||
|
import org.broadinstitute.sting.utils.StingException;
|
||||||
|
|
||||||
import java.util.Formatter;
|
import java.util.Formatter;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Formattable;
|
import java.util.Formattable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
/**
|
/**
|
||||||
|
|
@ -37,21 +46,67 @@ public class HelpFormatter {
|
||||||
* @param argumentDefinitions Argument definitions for which help should be printed.
|
* @param argumentDefinitions Argument definitions for which help should be printed.
|
||||||
*/
|
*/
|
||||||
public void printHelp( ArgumentDefinitions argumentDefinitions ) {
|
public void printHelp( ArgumentDefinitions argumentDefinitions ) {
|
||||||
System.out.printf("%s%n%n%s%n", getSynopsis(argumentDefinitions), getDetailed(argumentDefinitions) );
|
SortedSet<ArgumentDefinition> mainArguments = getMainArguments( argumentDefinitions );
|
||||||
|
Map<String,SortedSet<ArgumentDefinition>> pluginsByGroup = getPluginArguments( argumentDefinitions );
|
||||||
|
|
||||||
|
System.out.printf("%s%s%n",
|
||||||
|
getSynopsis(mainArguments,pluginsByGroup),
|
||||||
|
getDetailed(mainArguments,pluginsByGroup) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a sorted set of the command-line arguments for the main application from the ArgumentDefinitions object.
|
||||||
|
* @param argumentDefinitions Predefined argument definitions.
|
||||||
|
* @return A list of argument definitions.
|
||||||
|
*/
|
||||||
|
private SortedSet<ArgumentDefinition> getMainArguments( ArgumentDefinitions argumentDefinitions ) {
|
||||||
|
for( ArgumentDefinitionGroup argumentGroup: argumentDefinitions.getArgumentDefinitionGroups() ) {
|
||||||
|
// A null groupName is the signal that these are the application's main arguments.
|
||||||
|
if( argumentGroup.groupName == null ){
|
||||||
|
SortedSet<ArgumentDefinition> sortedDefinitions = new TreeSet<ArgumentDefinition>( new ArgumentDefinitionComparator() );
|
||||||
|
sortedDefinitions.addAll( argumentGroup.argumentDefinitions );
|
||||||
|
return sortedDefinitions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new StingException( "Unable to retrieve main command-line arguments." );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a sorted set of the command-line arguments for application plugin objects.
|
||||||
|
* @param argumentDefinitions Predefined argument definitions.
|
||||||
|
* @return A map of argument group name -> a list of argument definitions.
|
||||||
|
*/
|
||||||
|
private Map<String,SortedSet<ArgumentDefinition>> getPluginArguments( ArgumentDefinitions argumentDefinitions ) {
|
||||||
|
Map<String,SortedSet<ArgumentDefinition>> pluginsByGroup = new HashMap<String,SortedSet<ArgumentDefinition>>();
|
||||||
|
for( ArgumentDefinitionGroup argumentGroup: argumentDefinitions.getArgumentDefinitionGroups() ) {
|
||||||
|
// A null groupName is the signal that these are the application's main arguments.
|
||||||
|
if( argumentGroup.groupName == null )
|
||||||
|
continue;
|
||||||
|
SortedSet<ArgumentDefinition> sortedDefinitions = new TreeSet<ArgumentDefinition>( new ArgumentDefinitionComparator() );
|
||||||
|
sortedDefinitions.addAll( argumentGroup.argumentDefinitions );
|
||||||
|
pluginsByGroup.put( argumentGroup.groupName, sortedDefinitions );
|
||||||
|
}
|
||||||
|
return pluginsByGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the synopsis: the actual command to run.
|
* Gets the synopsis: the actual command to run.
|
||||||
* @param argumentDefinitions Argument definitions for which help should be printed.
|
* @param mainArguments Main program arguments.
|
||||||
|
* @praam pluginArgumentGroups Groups of plugin arguments
|
||||||
* @return A synopsis line.
|
* @return A synopsis line.
|
||||||
*/
|
*/
|
||||||
private String getSynopsis( ArgumentDefinitions argumentDefinitions ) {
|
private String getSynopsis( SortedSet<ArgumentDefinition> mainArguments, Map<String,SortedSet<ArgumentDefinition>> pluginArgumentGroups ) {
|
||||||
// Build out the synopsis all as one long line.
|
// Build out the synopsis all as one long line.
|
||||||
StringBuilder lineBuilder = new StringBuilder();
|
StringBuilder lineBuilder = new StringBuilder();
|
||||||
Formatter lineFormatter = new Formatter( lineBuilder );
|
Formatter lineFormatter = new Formatter( lineBuilder );
|
||||||
|
|
||||||
lineFormatter.format("java -jar dist/GenomeAnalysisTK.jar");
|
lineFormatter.format("java -jar dist/GenomeAnalysisTK.jar");
|
||||||
|
|
||||||
|
List<ArgumentDefinition> argumentDefinitions = new ArrayList<ArgumentDefinition>();
|
||||||
|
argumentDefinitions.addAll( mainArguments );
|
||||||
|
for( SortedSet pluginArguments: pluginArgumentGroups.values() )
|
||||||
|
argumentDefinitions.addAll( pluginArguments );
|
||||||
|
|
||||||
for( ArgumentDefinition argumentDefinition: argumentDefinitions ) {
|
for( ArgumentDefinition argumentDefinition: argumentDefinitions ) {
|
||||||
lineFormatter.format(" ");
|
lineFormatter.format(" ");
|
||||||
if( !argumentDefinition.required ) lineFormatter.format("[");
|
if( !argumentDefinition.required ) lineFormatter.format("[");
|
||||||
|
|
@ -82,21 +137,34 @@ public class HelpFormatter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets detailed output about each argument type.
|
* Gets detailed output about each argument type.
|
||||||
* @param argumentDefinitions Argument definitions for which help should be printed.
|
* @param mainArguments Main program arguments.
|
||||||
|
* @param pluginArgumentGroups Groups of plugin arguments
|
||||||
* @return Detailed text about all arguments.
|
* @return Detailed text about all arguments.
|
||||||
*/
|
*/
|
||||||
private String getDetailed( ArgumentDefinitions argumentDefinitions ) {
|
private String getDetailed( SortedSet<ArgumentDefinition> mainArguments, Map<String,SortedSet<ArgumentDefinition>> pluginArgumentGroups ) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
builder.append( getDetailForGroup( mainArguments ) );
|
||||||
|
|
||||||
|
for( String groupName: pluginArgumentGroups.keySet() ) {
|
||||||
|
builder.append( String.format("Arguments for %s:%n", groupName ) );
|
||||||
|
builder.append( getDetailForGroup( pluginArgumentGroups.get(groupName) ) );
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDetailForGroup( SortedSet<ArgumentDefinition> argumentDefinitions ) {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
Formatter formatter = new Formatter( builder );
|
Formatter formatter = new Formatter( builder );
|
||||||
|
|
||||||
// Try to fit the entire argument definition across the screen, but impose an arbitrary cap of 3/4 *
|
// Try to fit the entire argument definition across the screen, but impose an arbitrary cap of 3/4 *
|
||||||
// LINE_WIDTH in case the length of the arguments gets out of control.
|
// LINE_WIDTH in case the length of the arguments gets out of control.
|
||||||
int argWidth = Math.min( findLongestArgumentCallingInfo(argumentDefinitions), (LINE_WIDTH*3)/4 - ARG_DOC_SEPARATION_WIDTH );
|
int argWidth = Math.min( findLongestArgumentCallingInfo(argumentDefinitions), (LINE_WIDTH*3)/4 - ARG_DOC_SEPARATION_WIDTH );
|
||||||
int docWidth = LINE_WIDTH - argWidth - ARG_DOC_SEPARATION_WIDTH;
|
int docWidth = LINE_WIDTH - argWidth - ARG_DOC_SEPARATION_WIDTH;
|
||||||
|
|
||||||
for( ArgumentDefinition argumentDefinition: argumentDefinitions ) {
|
for( ArgumentDefinition argumentDefinition: argumentDefinitions ) {
|
||||||
Iterator<String> wordWrappedArgs = wordWrap( getArgumentCallingInfo(argumentDefinition), argWidth ).iterator();
|
Iterator<String> wordWrappedArgs = wordWrap( getArgumentCallingInfo(argumentDefinition), argWidth ).iterator();
|
||||||
Iterator<String> wordWrappedDoc = wordWrap( argumentDefinition.doc, docWidth ).iterator();
|
Iterator<String> wordWrappedDoc = wordWrap( argumentDefinition.doc, docWidth ).iterator();
|
||||||
|
|
||||||
while( wordWrappedArgs.hasNext() || wordWrappedDoc.hasNext() ) {
|
while( wordWrappedArgs.hasNext() || wordWrappedDoc.hasNext() ) {
|
||||||
String arg = wordWrappedArgs.hasNext() ? wordWrappedArgs.next() : "";
|
String arg = wordWrappedArgs.hasNext() ? wordWrappedArgs.next() : "";
|
||||||
|
|
@ -135,7 +203,7 @@ public class HelpFormatter {
|
||||||
* @param argumentDefinitions argument definitions to inspect.
|
* @param argumentDefinitions argument definitions to inspect.
|
||||||
* @return longest argument length.
|
* @return longest argument length.
|
||||||
*/
|
*/
|
||||||
private int findLongestArgumentCallingInfo( ArgumentDefinitions argumentDefinitions ) {
|
private int findLongestArgumentCallingInfo( Collection<ArgumentDefinition> argumentDefinitions ) {
|
||||||
int longest = 0;
|
int longest = 0;
|
||||||
for( ArgumentDefinition argumentDefinition: argumentDefinitions ) {
|
for( ArgumentDefinition argumentDefinition: argumentDefinitions ) {
|
||||||
String argumentText = getArgumentCallingInfo( argumentDefinition );
|
String argumentText = getArgumentCallingInfo( argumentDefinition );
|
||||||
|
|
@ -167,4 +235,23 @@ public class HelpFormatter {
|
||||||
}
|
}
|
||||||
return wrapped;
|
return wrapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A comparator to reorder arguments in alphabetical order.
|
||||||
|
*/
|
||||||
|
private class ArgumentDefinitionComparator implements Comparator<ArgumentDefinition> {
|
||||||
|
public int compare( ArgumentDefinition lhs, ArgumentDefinition rhs ) {
|
||||||
|
if( lhs.shortName == null && rhs.shortName == null )
|
||||||
|
return lhs.fullName.compareTo( rhs.fullName );
|
||||||
|
// short names always come before long names.
|
||||||
|
else if ( lhs.shortName == null )
|
||||||
|
return -1;
|
||||||
|
else if ( rhs.shortName == null )
|
||||||
|
return 1;
|
||||||
|
else if ( lhs.shortName.equals(rhs.shortName) )
|
||||||
|
return lhs.fullName.compareTo( rhs.fullName );
|
||||||
|
else
|
||||||
|
return lhs.shortName.compareTo( rhs.shortName );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,21 +66,33 @@ public class ParsingEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an argument source. Argument sources are expected to have
|
* Add a main argument source. Argument sources are expected to have
|
||||||
* any number of fields with an @Argument annotation attached.
|
* any number of fields with an @Argument annotation attached.
|
||||||
* @param source An argument source from which to extract
|
* @param source An argument source from which to extract command-line arguments.
|
||||||
* command-line arguments.
|
|
||||||
*/
|
*/
|
||||||
public void addArgumentSource( Class source ) {
|
public void addArgumentSource( Class source ) {
|
||||||
do {
|
addArgumentSource(null, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an argument source. Argument sources are expected to have
|
||||||
|
* any number of fields with an @Argument annotation attached.
|
||||||
|
* @param sourceName name for this argument source. 'Null' indicates that this source should be treated
|
||||||
|
* as the main module.
|
||||||
|
* @param source An argument source from which to extract command-line arguments.
|
||||||
|
*/
|
||||||
|
public void addArgumentSource( String sourceName, Class source ) {
|
||||||
|
Collection<ArgumentDefinition> argumentsFromSource = new ArrayList<ArgumentDefinition>();
|
||||||
|
while( source != null ) {
|
||||||
Field[] fields = source.getDeclaredFields();
|
Field[] fields = source.getDeclaredFields();
|
||||||
for( Field field: fields ) {
|
for( Field field: fields ) {
|
||||||
Argument argument = field.getAnnotation(Argument.class);
|
Argument argument = field.getAnnotation(Argument.class);
|
||||||
if(argument != null)
|
if(argument != null)
|
||||||
argumentDefinitions.add( argument, source, field );
|
argumentsFromSource.add( new ArgumentDefinition(argument,source,field) );
|
||||||
}
|
}
|
||||||
source = source.getSuperclass();
|
source = source.getSuperclass();
|
||||||
} while( source != null );
|
}
|
||||||
|
argumentDefinitions.add( new ArgumentDefinitionGroup(sourceName, argumentsFromSource) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -456,10 +468,19 @@ public class ParsingEngine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic class for handling misc parsing exceptions.
|
||||||
|
*/
|
||||||
|
class ParseException extends StingException {
|
||||||
|
public ParseException( String message ) {
|
||||||
|
super( message );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An exception indicating that some required arguments are missing.
|
* An exception indicating that some required arguments are missing.
|
||||||
*/
|
*/
|
||||||
class MissingArgumentException extends StingException {
|
class MissingArgumentException extends ParseException {
|
||||||
public MissingArgumentException( Collection<ArgumentDefinition> missingArguments ) {
|
public MissingArgumentException( Collection<ArgumentDefinition> missingArguments ) {
|
||||||
super( formatArguments(missingArguments) );
|
super( formatArguments(missingArguments) );
|
||||||
}
|
}
|
||||||
|
|
@ -467,17 +488,11 @@ class MissingArgumentException extends StingException {
|
||||||
private static String formatArguments( Collection<ArgumentDefinition> missingArguments ) {
|
private static String formatArguments( Collection<ArgumentDefinition> missingArguments ) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for( ArgumentDefinition missingArgument: missingArguments )
|
for( ArgumentDefinition missingArgument: missingArguments )
|
||||||
sb.append( String.format("Argument with name '%s' is missing.", missingArgument.fullName) );
|
sb.append( String.format("Argument with name '%s' is missing.%n", missingArgument.fullName) );
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ParseException extends StingException {
|
|
||||||
public ParseException( String message ) {
|
|
||||||
super( message );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An exception for undefined arguments.
|
* An exception for undefined arguments.
|
||||||
*/
|
*/
|
||||||
|
|
@ -489,7 +504,7 @@ class InvalidArgumentException extends ParseException {
|
||||||
private static String formatArguments( Collection<ArgumentMatch> invalidArguments ) {
|
private static String formatArguments( Collection<ArgumentMatch> invalidArguments ) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for( ArgumentMatch invalidArgument: invalidArguments )
|
for( ArgumentMatch invalidArgument: invalidArguments )
|
||||||
sb.append( String.format("Argument with name '%s' isn't defined.", invalidArgument.label) );
|
sb.append( String.format("Argument with name '%s' isn't defined.%n", invalidArgument.label) );
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -506,7 +521,7 @@ class InvalidArgumentValueException extends ParseException {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for( int index: invalidValues.indices.keySet() )
|
for( int index: invalidValues.indices.keySet() )
|
||||||
for( String value: invalidValues.indices.get(index) )
|
for( String value: invalidValues.indices.get(index) )
|
||||||
sb.append( String.format("Invalid argument value '%s' at position %d", value, index) );
|
sb.append( String.format("Invalid argument value '%s' at position %d.%n", value, index) );
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue