Source for net.dpml.cli.commandline.WriteableCommandLineImpl

   1: /*
   2:  * Copyright 2004-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.commandline;
  18: 
  19: import java.util.ArrayList;
  20: import java.util.Collections;
  21: import java.util.HashMap;
  22: import java.util.Iterator;
  23: import java.util.List;
  24: import java.util.Map;
  25: import java.util.Properties;
  26: import java.util.Set;
  27: 
  28: import net.dpml.cli.Argument;
  29: import net.dpml.cli.Option;
  30: import net.dpml.cli.WriteableCommandLine;
  31: import net.dpml.cli.resource.ResourceConstants;
  32: import net.dpml.cli.resource.ResourceHelper;
  33: 
  34: /**
  35:  * A WriteableCommandLine implementation allowing Options to write their
  36:  * processed information to a CommandLine.
  37:  *
  38:  * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
  39:  * @version @PROJECT-VERSION@
  40:  */
  41: public class WriteableCommandLineImpl extends CommandLineImpl implements WriteableCommandLine 
  42: {
  43:     private final Properties m_properties = new Properties();
  44:     private final List m_options = new ArrayList();
  45:     private final Map m_nameToOption = new HashMap();
  46:     private final Map m_values = new HashMap();
  47:     private final Map m_switches = new HashMap();
  48:     private final Map m_defaultValues = new HashMap();
  49:     private final Map m_defaultSwitches = new HashMap();
  50:     private final List m_normalised;
  51:     private final Set m_prefixes;
  52: 
  53:     /**
  54:      * Creates a new WriteableCommandLineImpl rooted on the specified Option, to
  55:      * hold the parsed arguments.
  56:      *
  57:      * @param rootOption the CommandLine's root Option
  58:      * @param arguments the arguments this CommandLine represents
  59:      */
  60:     public WriteableCommandLineImpl(
  61:       final Option rootOption, final List arguments )
  62:     {
  63:         m_prefixes = rootOption.getPrefixes();
  64:         m_normalised = arguments;
  65:     }
  66: 
  67:    /**
  68:     * Add an option.
  69:     * @param option the option to add
  70:     */
  71:     public void addOption( Option option )
  72:     {
  73:         m_options.add( option );
  74:         m_nameToOption.put( option.getPreferredName(), option );
  75:         for( Iterator i = option.getTriggers().iterator(); i.hasNext();)
  76:         {
  77:             m_nameToOption.put( i.next(), option );
  78:         }
  79:     }
  80: 
  81:    /**
  82:     * Add an option.
  83:     * @param option the option to add
  84:     * @param value the option value
  85:     */
  86:     public void addValue( final Option option, final Object value )
  87:     {
  88:         if( option instanceof Argument )
  89:         {
  90:             addOption( option );
  91:         }
  92:         List valueList = (List) m_values.get( option );
  93:         if( valueList == null )
  94:         {
  95:             valueList = new ArrayList();
  96:             m_values.put( option, valueList );
  97:         }
  98:         valueList.add( value );
  99:     }
 100: 
 101:    /**
 102:     * Add a switch.
 103:     * @param option the option to add
 104:     * @param value the option value
 105:     */
 106:     public void addSwitch( final Option option, final boolean value )
 107:     {
 108:         addOption( option );
 109:         if( m_switches.containsKey( option ) )
 110:         {
 111:             throw new IllegalStateException(
 112:               ResourceHelper.getResourceHelper().getMessage(
 113:                 ResourceConstants.SWITCH_ALREADY_SET ) );
 114:         } 
 115:         else 
 116:         {
 117:             if( value )
 118:             {
 119:                 m_switches.put( option, Boolean.TRUE );
 120:             }
 121:             else
 122:             {
 123:                 m_switches.put( option, Boolean.FALSE );
 124:             }
 125:         }
 126:     }
 127: 
 128:     /**
 129:      * Detects the presence of an option in this CommandLine.
 130:      * 
 131:      * @param option the Option to search for
 132:      * @return true iff the option is present
 133:      */
 134:     public boolean hasOption( final Option option )
 135:     {
 136:         return m_options.contains( option );
 137:     }
 138: 
 139:     /**
 140:      * Finds the Option with the specified trigger
 141:      * 
 142:      * @param trigger the name of the option to retrieve
 143:      * @return the Option matching the trigger or null if none exists
 144:      */
 145:     public Option getOption( final String trigger )
 146:     {
 147:         return (Option) m_nameToOption.get( trigger );
 148:     }
 149: 
 150:     /**
 151:      * Retrieves the Argument values associated with the specified Option
 152:      * 
 153:      * @param option the Option associated with the values
 154:      * @param defaultValues the result to return if no values are found
 155:      * @return a list of values or defaultValues if none are found
 156:      */
 157:     public List getValues( final Option option, final List defaultValues )
 158:     {
 159:         // First grab the command line values
 160:         List valueList = (List) m_values.get( option );
 161: 
 162:         // Secondly try the defaults supplied to the method
 163:         if( ( valueList == null ) || valueList.isEmpty() )
 164:         {
 165:             valueList = defaultValues;
 166:         }
 167: 
 168:         // Thirdly try the option's default values
 169:         if( ( valueList == null ) || valueList.isEmpty() )
 170:         {
 171:             valueList = (List) m_defaultValues.get( option );
 172:         }
 173: 
 174:         // Finally use an empty list
 175:         if( valueList == null )
 176:         {
 177:             valueList = Collections.EMPTY_LIST;
 178:         }
 179: 
 180:         return valueList;
 181:     }
 182: 
 183:     /**
 184:      * Retrieves the Boolean value associated with the specified Switch
 185:      * 
 186:      * @param option the Option associated with the value
 187:      * @param defaultValue the Boolean to use if none match
 188:      * @return the Boolean associated with option or defaultValue if none exists
 189:      */
 190:     public Boolean getSwitch( final Option option, final Boolean defaultValue )
 191:     {
 192:         // First grab the command line values
 193:         Boolean bool = (Boolean) m_switches.get( option );
 194: 
 195:         // Secondly try the defaults supplied to the method
 196:         if( bool == null )
 197:         {
 198:             bool = defaultValue;
 199:         }
 200: 
 201:         // Thirdly try the option's default values
 202:         if( bool == null )
 203:         {
 204:             bool = (Boolean) m_defaultSwitches.get( option );
 205:         }
 206: 
 207:         return bool;
 208:     }
 209: 
 210:    /**
 211:     * Add a property to the commandline.
 212:     * @param property the property name
 213:     * @param value the property value
 214:     */
 215:     public void addProperty( final String property, final String value )
 216:     {
 217:         m_properties.setProperty( property, value );
 218:     }
 219: 
 220:     /**
 221:      * Retrieves the value associated with the specified property 
 222:      * 
 223:      * @param property the property name to lookup
 224:      * @param defaultValue the value to use if no other is found
 225:      * @return the value of the property or defaultValue
 226:      */
 227:     public String getProperty( final String property, final String defaultValue )
 228:     {
 229:         return m_properties.getProperty( property, defaultValue );
 230:     }
 231: 
 232:     /**
 233:      * Retrieves the set of all property names associated with this CommandLine
 234:      * 
 235:      * @return a none null set of property names 
 236:      */
 237:     public Set getProperties()
 238:     {
 239:         return Collections.unmodifiableSet( m_properties.keySet() );
 240:     }
 241: 
 242:    /**
 243:     * Return true if the trigger argument looks like an option.
 244:     * @param trigger the trigger to evaluate
 245:     * @return true if the trigger looks like an option
 246:     */
 247:     public boolean looksLikeOption( final String trigger )
 248:     {
 249:         for( final Iterator i = m_prefixes.iterator(); i.hasNext();)
 250:         {
 251:             final String prefix = (String) i.next();
 252:             if( trigger.startsWith( prefix ) )
 253:             {
 254:                 return true;
 255:             }
 256:         }
 257:         return false;
 258:     }
 259: 
 260:    /**
 261:     * Return this commandline as a string.
 262:     * @return the string representation
 263:     */
 264:     public String toString() 
 265:     {
 266:         final StringBuffer buffer = new StringBuffer();
 267:         // need to add group header
 268:         for( final Iterator i = m_normalised.iterator(); i.hasNext();) 
 269:         {
 270:             final String arg = ( String ) i.next();
 271:             if( arg.indexOf( ' ' ) >= 0 )
 272:             {
 273:                 buffer.append( "\"" ).append( arg ).append( "\"" );
 274:             } 
 275:             else 
 276:             {
 277:                 buffer.append( arg );
 278:             }
 279:             if( i.hasNext() )
 280:             {
 281:                 buffer.append( ' ' );
 282:             }
 283:         }
 284:         return buffer.toString();
 285:     }
 286: 
 287:     /**
 288:      * Retrieves a list of all Options found in this CommandLine
 289:      * 
 290:      * @return a none null list of Options
 291:      */
 292:     public List getOptions()
 293:     {
 294:         return Collections.unmodifiableList( m_options );
 295:     }
 296: 
 297:     /**
 298:      * Retrieves a list of all Option triggers found in this CommandLine
 299:      * 
 300:      * @return a none null list of Option triggers
 301:      */
 302:     public Set getOptionTriggers()
 303:     {
 304:         return Collections.unmodifiableSet( m_nameToOption.keySet() );
 305:     }
 306: 
 307:    /**
 308:     * Set default values.
 309:     * @param option the option
 310:     * @param defaults a list of defaults
 311:     */
 312:     public void setDefaultValues( final Option option, final List defaults )
 313:     {
 314:         if( defaults == null )
 315:         {
 316:             m_defaultValues.remove( option );
 317:         } 
 318:         else 
 319:         {
 320:             m_defaultValues.put( option, defaults );
 321:         }
 322:     }
 323: 
 324:    /**
 325:     * Set default switch.
 326:     * @param option the option
 327:     * @param defaultSwitch the default switch state
 328:     */
 329:     public void setDefaultSwitch( final Option option, final Boolean defaultSwitch ) 
 330:     {
 331:         if( defaultSwitch == null )
 332:         {
 333:             m_defaultSwitches.remove( defaultSwitch );
 334:         } 
 335:         else 
 336:         {
 337:             m_defaultSwitches.put( option, defaultSwitch );
 338:         }
 339:     }
 340: 
 341:    /**
 342:     * Return the normalized collection.
 343:     * @return the moprmalized collection
 344:     */
 345:     public List getNormalised()
 346:     {
 347:         return Collections.unmodifiableList( m_normalised );
 348:     }
 349: }