Frames | No Frames |
1: /* 2: * Copyright 2003-2005 The Apache Software Foundation 3: * Copyright 2005 Stephen McConnell 4: * 5: * Licensed under the Apache License, Version 2.0 (the "License"); 6: * you may not use this file except in compliance with the License. 7: * You may obtain a copy of the License at 8: * 9: * http://www.apache.org/licenses/LICENSE-2.0 10: * 11: * Unless required by applicable law or agreed to in writing, software 12: * distributed under the License is distributed on an "AS IS" BASIS, 13: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14: * See the License for the specific language governing permissions and 15: * limitations under the License. 16: */ 17: package net.dpml.cli.option; 18: 19: import java.util.Collections; 20: import java.util.Comparator; 21: import java.util.List; 22: import java.util.ListIterator; 23: import java.util.Set; 24: 25: import net.dpml.cli.DisplaySetting; 26: import net.dpml.cli.HelpLine; 27: import net.dpml.cli.OptionException; 28: import net.dpml.cli.WriteableCommandLine; 29: import net.dpml.cli.resource.ResourceConstants; 30: 31: /** 32: * Handles the java style "-Dprop=value" opions 33: * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a> 34: * @version @PROJECT-VERSION@ 35: */ 36: public class PropertyOption extends OptionImpl 37: { 38: /** 39: * The default property option name. 40: */ 41: public static final String DEFAULT_OPTION_STRING = "-D"; 42: 43: /** 44: * The default property option description. 45: */ 46: public static final String DEFAULT_DESCRIPTION = "Set property values."; 47: 48: /** 49: * A default PropertyOption instance 50: */ 51: public static final PropertyOption INSTANCE = new PropertyOption(); 52: 53: private final String m_optionString; 54: private final String m_description; 55: private final Set m_prefixes; 56: 57: /** 58: * Creates a new PropertyOption using the default settings of a "-D" trigger 59: * and an id of 'D' 60: */ 61: public PropertyOption() 62: { 63: this( DEFAULT_OPTION_STRING, DEFAULT_DESCRIPTION, 'D' ); 64: } 65: 66: /** 67: * Creates a new PropertyOption using the specified parameters 68: * @param optionString the trigger for the Option 69: * @param description the description of the Option 70: * @param id the id of the Option 71: */ 72: public PropertyOption( 73: final String optionString, final String description, final int id ) 74: { 75: super( id, false ); 76: m_optionString = optionString; 77: m_description = description; 78: m_prefixes = Collections.singleton( optionString ); 79: } 80: 81: /** 82: * Indicates whether this Option will be able to process the particular 83: * argument. 84: * 85: * @param commandLine the CommandLine object to store defaults in 86: * @param argument the argument to be tested 87: * @return true if the argument can be processed by this Option 88: */ 89: public boolean canProcess( 90: final WriteableCommandLine commandLine, final String argument ) 91: { 92: return ( argument != null ) 93: && argument.startsWith( m_optionString ) 94: && ( argument.length() > m_optionString.length() ); 95: } 96: 97: /** 98: * Identifies the argument prefixes that should be considered options. This 99: * is used to identify whether a given string looks like an option or an 100: * argument value. Typically an option would return the set [--,-] while 101: * switches might offer [-,+]. 102: * 103: * The returned Set must not be null. 104: * 105: * @return The set of prefixes for this Option 106: */ 107: public Set getPrefixes() 108: { 109: return m_prefixes; 110: } 111: 112: /** 113: * Processes String arguments into a CommandLine. 114: * 115: * The iterator will initially point at the first argument to be processed 116: * and at the end of the method should point to the first argument not 117: * processed. This method MUST process at least one argument from the 118: * ListIterator. 119: * 120: * @param commandLine the CommandLine object to store results in 121: * @param arguments the arguments to process 122: * @throws OptionException if any problems occur 123: */ 124: public void process( 125: final WriteableCommandLine commandLine, final ListIterator arguments ) 126: throws OptionException 127: { 128: final String arg = (String) arguments.next(); 129: 130: if( !canProcess( commandLine, arg ) ) 131: { 132: throw new OptionException( 133: this, 134: ResourceConstants.UNEXPECTED_TOKEN, 135: arg ); 136: } 137: 138: final int propertyStart = m_optionString.length(); 139: final int equalsIndex = arg.indexOf( '=', propertyStart ); 140: final String property; 141: final String value; 142: 143: if( equalsIndex < 0 ) 144: { 145: property = arg.substring( propertyStart ); 146: value = "true"; 147: } 148: else 149: { 150: property = arg.substring( propertyStart, equalsIndex ); 151: value = arg.substring( equalsIndex + 1 ); 152: } 153: commandLine.addProperty( property, value ); 154: } 155: 156: /** 157: * Identifies the argument prefixes that should trigger this option. This 158: * is used to decide which of many Options should be tried when processing 159: * a given argument string. 160: * 161: * The returned Set must not be null. 162: * 163: * @return The set of triggers for this Option 164: */ 165: public Set getTriggers() 166: { 167: return Collections.singleton( m_optionString ); 168: } 169: 170: /** 171: * Checks that the supplied CommandLine is valid with respect to this 172: * option. 173: * 174: * @param commandLine the CommandLine to check. 175: * @throws OptionException if the CommandLine is not valid. 176: */ 177: public void validate( WriteableCommandLine commandLine ) throws OptionException 178: { 179: // PropertyOption needs no validation 180: } 181: 182: /** 183: * Appends usage information to the specified StringBuffer 184: * 185: * @param buffer the buffer to append to 186: * @param helpSettings a set of display settings @see DisplaySetting 187: * @param comp a comparator used to sort the Options 188: */ 189: public void appendUsage( 190: final StringBuffer buffer, final Set helpSettings, final Comparator comp ) 191: { 192: final boolean display = helpSettings.contains( DisplaySetting.DISPLAY_PROPERTY_OPTION ); 193: final boolean bracketed = helpSettings.contains( DisplaySetting.DISPLAY_ARGUMENT_BRACKETED ); 194: 195: if( display ) 196: { 197: buffer.append( m_optionString ); 198: if( bracketed ) 199: { 200: buffer.append( '<' ); 201: } 202: buffer.append( "property" ); 203: if( bracketed ) 204: { 205: buffer.append( '>' ); 206: } 207: buffer.append( "=" ); 208: if( bracketed ) 209: { 210: buffer.append( '<' ); 211: } 212: buffer.append( "value" ); 213: if( bracketed ) 214: { 215: buffer.append( '>' ); 216: } 217: } 218: } 219: 220: /** 221: * The preferred name of an option is used for generating help and usage 222: * information. 223: * 224: * @return The preferred name of the option 225: */ 226: public String getPreferredName() 227: { 228: return m_optionString; 229: } 230: 231: /** 232: * Returns a description of the option. This string is used to build help 233: * messages as in the HelpFormatter. 234: * 235: * @see net.dpml.cli.util.HelpFormatter 236: * @return a description of the option. 237: */ 238: public String getDescription() 239: { 240: return m_description; 241: } 242: 243: /** 244: * Builds up a list of HelpLineImpl instances to be presented by HelpFormatter. 245: * 246: * @see HelpLine 247: * @see net.dpml.cli.util.HelpFormatter 248: * @param depth the initial indent depth 249: * @param helpSettings the HelpSettings that should be applied 250: * @param comp a comparator used to sort options when applicable. 251: * @return a List of HelpLineImpl objects 252: */ 253: public List helpLines( 254: final int depth, final Set helpSettings, final Comparator comp ) 255: { 256: if( helpSettings.contains( DisplaySetting.DISPLAY_PROPERTY_OPTION ) ) 257: { 258: final HelpLine helpLine = new HelpLineImpl( this, depth ); 259: return Collections.singletonList( helpLine ); 260: } 261: else 262: { 263: return Collections.EMPTY_LIST; 264: } 265: } 266: }