2009-07-13 09:42:13 +08:00
|
|
|
/*
|
2010-04-20 07:00:08 +08:00
|
|
|
* Copyright (c) 2010 The Broad Institute
|
2010-04-20 23:26:32 +08:00
|
|
|
*
|
2009-07-13 09:42:13 +08:00
|
|
|
* Permission is hereby granted, free of charge, to any person
|
|
|
|
|
* obtaining a copy of this software and associated documentation
|
2010-04-20 23:26:32 +08:00
|
|
|
* files (the "Software"), to deal in the Software without
|
2009-07-13 09:42:13 +08:00
|
|
|
* restriction, including without limitation the rights to use,
|
|
|
|
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
|
* copies of the Software, and to permit persons to whom the
|
|
|
|
|
* Software is furnished to do so, subject to the following
|
|
|
|
|
* conditions:
|
2010-04-20 23:26:32 +08:00
|
|
|
*
|
2009-07-13 09:42:13 +08:00
|
|
|
* The above copyright notice and this permission notice shall be
|
|
|
|
|
* included in all copies or substantial portions of the Software.
|
|
|
|
|
*
|
2010-04-20 23:26:32 +08:00
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
2009-07-13 09:42:13 +08:00
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
|
|
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
|
|
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
|
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
2010-04-20 07:00:08 +08:00
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
|
|
|
|
|
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
2009-07-13 09:42:13 +08:00
|
|
|
*/
|
|
|
|
|
|
2010-04-20 07:00:08 +08:00
|
|
|
package org.broadinstitute.sting.commandline;
|
2009-07-13 09:42:13 +08:00
|
|
|
|
2010-08-22 22:27:05 +08:00
|
|
|
import org.broadinstitute.sting.utils.StingException;
|
|
|
|
|
|
2009-07-13 09:42:13 +08:00
|
|
|
import java.lang.reflect.Field;
|
2010-08-10 00:42:48 +08:00
|
|
|
import java.util.Arrays;
|
2009-07-25 03:44:04 +08:00
|
|
|
import java.util.List;
|
2009-07-13 09:42:13 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Describes the source field which defines a command-line argument.
|
|
|
|
|
* A parsed-object version of the command-line argument will be
|
|
|
|
|
* injected into an object containing this field.
|
|
|
|
|
*
|
|
|
|
|
* @author mhanna
|
|
|
|
|
* @version 0.1
|
|
|
|
|
*/
|
|
|
|
|
public class ArgumentSource {
|
|
|
|
|
/**
|
2010-08-10 00:42:48 +08:00
|
|
|
* Field into which to inject command-line arguments.
|
2009-07-13 09:42:13 +08:00
|
|
|
*/
|
2010-08-10 00:42:48 +08:00
|
|
|
public final Field[] parentFields;
|
2009-07-13 09:42:13 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Field into which to inject command-line arguments.
|
|
|
|
|
*/
|
|
|
|
|
public final Field field;
|
|
|
|
|
|
2009-12-30 00:46:24 +08:00
|
|
|
/**
|
|
|
|
|
* Type descriptor to use when parsing new argument types.
|
|
|
|
|
*/
|
|
|
|
|
private final ArgumentTypeDescriptor typeDescriptor;
|
|
|
|
|
|
2009-07-13 09:42:13 +08:00
|
|
|
/**
|
|
|
|
|
* Create a new command-line argument target.
|
2010-08-10 00:42:48 +08:00
|
|
|
* @param field Field containing the argument. Field must be annotated with 'Input' or 'Output'.
|
|
|
|
|
*/
|
|
|
|
|
public ArgumentSource( Field field ) {
|
|
|
|
|
this(new Field[0], field);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create a new command-line argument target.
|
|
|
|
|
* @param parentFields Parent fields containing the the field. Field must be annotated with 'ArgumentCollection'.
|
|
|
|
|
* @param field Field containing the argument. Field must be annotated with 'Input' or 'Output'.
|
2009-07-13 09:42:13 +08:00
|
|
|
*/
|
2010-08-10 00:42:48 +08:00
|
|
|
public ArgumentSource( Field[] parentFields, Field field ) {
|
2010-08-22 22:27:05 +08:00
|
|
|
this(parentFields,field,ArgumentTypeDescriptor.create(field.getType()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create a new command-line argument target.
|
|
|
|
|
* @param parentFields Parent fields containing the the field. Field must be annotated with 'ArgumentCollection'.
|
|
|
|
|
* @param field Field containing the argument. Field must be annotated with 'Input' or 'Output'.
|
|
|
|
|
* @param typeDescriptor custom type descriptor to use when parsing.
|
|
|
|
|
*/
|
|
|
|
|
private ArgumentSource( Field[] parentFields, Field field, ArgumentTypeDescriptor typeDescriptor) {
|
2010-08-10 00:42:48 +08:00
|
|
|
this.parentFields = parentFields;
|
2009-07-13 09:42:13 +08:00
|
|
|
this.field = field;
|
2010-08-22 22:27:05 +08:00
|
|
|
this.typeDescriptor = typeDescriptor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Somewhat hackish copy constructor to track fields with a custom type descriptor.
|
|
|
|
|
* TODO: Separate type descriptor from ArgumentSource in general usage.
|
|
|
|
|
* @param typeDescriptor New type descriptor for the object.
|
|
|
|
|
*/
|
|
|
|
|
public ArgumentSource copyWithCustomTypeDescriptor(final ArgumentTypeDescriptor typeDescriptor) {
|
|
|
|
|
return new ArgumentSource(parentFields,field,typeDescriptor);
|
2009-07-13 09:42:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* True if this argument source equals other.
|
|
|
|
|
* @param other Another object, possibly an argument source, to test for equality. Any object can
|
|
|
|
|
* be tested, but only instances of ArgumentSource will result in equals returning true.
|
|
|
|
|
* @return True if this argument source matches other. False otherwise.
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public boolean equals( Object other ) {
|
|
|
|
|
if( other == null )
|
|
|
|
|
return false;
|
|
|
|
|
if( !(other instanceof ArgumentSource) )
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
ArgumentSource otherArgumentSource = (ArgumentSource)other;
|
2010-08-10 00:42:48 +08:00
|
|
|
return this.field == otherArgumentSource.field && Arrays.equals(this.parentFields, otherArgumentSource.parentFields);
|
2009-07-13 09:42:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns an appropriate hash code for this argument source.
|
|
|
|
|
* @return A uniformly distributed hashcode representing this argument source.
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public int hashCode() {
|
2010-08-10 00:42:48 +08:00
|
|
|
return field.hashCode();
|
2009-07-13 09:42:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2009-07-25 03:44:04 +08:00
|
|
|
* Generate a list of all argument definitions to which this argument source maps.
|
|
|
|
|
* @return A non-null, non-empty list of argument definitions.
|
2009-07-13 09:42:13 +08:00
|
|
|
*/
|
2009-07-25 03:44:04 +08:00
|
|
|
public List<ArgumentDefinition> createArgumentDefinitions() {
|
2009-08-23 08:56:02 +08:00
|
|
|
return typeDescriptor.createArgumentDefinitions( this );
|
2009-07-13 09:42:13 +08:00
|
|
|
}
|
|
|
|
|
|
2009-12-30 00:46:24 +08:00
|
|
|
/**
|
|
|
|
|
* This argument type descriptor wants to override any default value the user might have specified.
|
|
|
|
|
* @return True if this descriptor wants to override any default the user specified. False otherwise.
|
|
|
|
|
*/
|
|
|
|
|
public boolean overridesDefault() {
|
2010-08-22 22:27:05 +08:00
|
|
|
return typeDescriptor.createsTypeDefault(this,field.getType());
|
2009-12-30 00:46:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Provides the default value for the command-line argument.
|
|
|
|
|
* @return Default value to load into the object.
|
|
|
|
|
*/
|
2010-08-22 22:27:05 +08:00
|
|
|
public Object createDefault() {
|
|
|
|
|
return typeDescriptor.createTypeDefault(this,field.getType());
|
2009-12-30 00:46:24 +08:00
|
|
|
}
|
|
|
|
|
|
2009-07-13 09:42:13 +08:00
|
|
|
/**
|
2009-09-30 06:23:19 +08:00
|
|
|
* Parses the specified value based on the specified type.
|
2009-07-25 06:15:57 +08:00
|
|
|
* @param values String representation of all values passed.
|
2009-09-30 06:23:19 +08:00
|
|
|
* @return the parsed value of the object.
|
2009-07-13 09:42:13 +08:00
|
|
|
*/
|
2010-08-10 00:42:48 +08:00
|
|
|
public Object parse( ArgumentMatches values ) {
|
|
|
|
|
return typeDescriptor.parse( this, values );
|
2009-07-13 09:42:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns true if the argument is a flag (a 0-valued argument).
|
|
|
|
|
* @return True if argument is a flag; false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
public boolean isFlag() {
|
|
|
|
|
return (field.getType() == Boolean.class) || (field.getType() == Boolean.TYPE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Can this argument support multiple values, or just one?
|
|
|
|
|
* @return True if the argument supports multiple values.
|
|
|
|
|
*/
|
|
|
|
|
public boolean isMultiValued() {
|
2010-08-10 00:42:48 +08:00
|
|
|
return typeDescriptor.isMultiValued( this );
|
2009-07-13 09:42:13 +08:00
|
|
|
}
|
2009-09-30 06:23:19 +08:00
|
|
|
|
2010-08-05 10:26:46 +08:00
|
|
|
/**
|
|
|
|
|
* Should the given class be hidden from the command-line argument system.
|
|
|
|
|
* @return True if so. False otherwise.
|
|
|
|
|
*/
|
|
|
|
|
public boolean isHidden() {
|
2010-08-23 05:01:44 +08:00
|
|
|
return field.isAnnotationPresent(Hidden.class) || field.isAnnotationPresent(Deprecated.class);
|
2010-08-05 10:26:46 +08:00
|
|
|
}
|
|
|
|
|
|
2010-08-22 22:27:05 +08:00
|
|
|
/**
|
|
|
|
|
* Is this command-line argument dependent on some primitive argument types?
|
|
|
|
|
* @return True if this command-line argument depends on other arguments; false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
public boolean isDependent() {
|
|
|
|
|
return typeDescriptor instanceof MultiplexArgumentTypeDescriptor;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-23 05:01:44 +08:00
|
|
|
/**
|
|
|
|
|
* Returns whether the field has been deprecated and should no longer be used.
|
|
|
|
|
* @return True if field has been deprecated.
|
|
|
|
|
*/
|
|
|
|
|
public boolean isDeprecated() {
|
|
|
|
|
return field.isAnnotationPresent(Deprecated.class);
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-22 22:27:05 +08:00
|
|
|
/**
|
|
|
|
|
* Builds out a new type descriptor for the given dependent argument as a function
|
|
|
|
|
* of the containing object.
|
|
|
|
|
* @param containingObject The containing object.
|
|
|
|
|
* @return An argument type descriptor for the custom derivative field.
|
|
|
|
|
*/
|
|
|
|
|
public MultiplexArgumentTypeDescriptor createDependentTypeDescriptor(Object containingObject) {
|
|
|
|
|
if(!isDependent())
|
|
|
|
|
throw new StingException("Field " + field.getName() + " is independent; no dependent type descriptor can be derived.");
|
|
|
|
|
return ((MultiplexArgumentTypeDescriptor)typeDescriptor).createCustomTypeDescriptor(this,containingObject);
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-30 06:23:19 +08:00
|
|
|
/**
|
|
|
|
|
* Gets a string representation of the argument source for debugging.
|
|
|
|
|
* @return String representation of the argument source.
|
|
|
|
|
*/
|
|
|
|
|
public String toString() {
|
2010-08-10 00:42:48 +08:00
|
|
|
return field.getDeclaringClass().getSimpleName() + ": " + field.getName();
|
2009-09-30 06:23:19 +08:00
|
|
|
}
|
2009-07-13 09:42:13 +08:00
|
|
|
}
|