CommandLineImpl.java
/*******************************************************************************
* Copyright (c) 2004, 2013 Steve Flasby
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* <ul>
* <li>Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.</li>
* <li>Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.</li>
* </ul>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*
* Created on 16-Jul-2004
*
*/
package org.flasby.cli.impl;
import java.util.ArrayList;
import java.util.HashMap;
import org.flasby.cli.CommandLine;
import org.flasby.cli.Flag;
import org.flasby.cli.MissingRequiredOptionException;
import org.flasby.cli.Option;
import org.flasby.cli.OptionList;
import org.flasby.cli.Options;
import org.flasby.cli.UnknownArgumentException;
/**
*
* @author flasbyst
*
*/
public class CommandLineImpl implements CommandLine {
private final HashMap<String,ArrayList<String>> mProvidedOptions = new HashMap<String,ArrayList<String>>();
private final HashMap<String,Option> mRequiredOptions = new HashMap<String,Option>();
private final HashMap<String,Option> mAllOptions = new HashMap<String,Option>();
private String mOption = "";
private final Options mOptions;
private final ArrayList<String> mDefaultOption = new ArrayList<String>();
private ArrayList<String> mCurrentOption = mDefaultOption;
public CommandLineImpl(final Options options, String[] args) throws UnknownArgumentException, MissingRequiredOptionException {
mOptions=new Options(options);
for (int i = 0; i < options.getOptions().length; i++) {
Option option = options.getOptions()[i];
mAllOptions.put(option.getOpt(), option);
if ( option.isMandatory() ) {
mRequiredOptions.put( option.getOpt(), option );
}
}
for (String arg2 : args) {
String arg = arg2;
if ("-".equals(arg)) {
// Process default argument
mCurrentOption = mDefaultOption;
mOption = "";
} else if (arg.startsWith("-")) {
if ( arg.length()>2 ) {
burst( arg.substring(1) );
} else {
// process the option
if ( ! process(arg.substring(1)) ){
// Its a flag & does NOT require a value
mCurrentOption = mDefaultOption;
mOption = "";
}
}
} else {
// Its a parameter value, add it to the current param, if any
mCurrentOption.add( arg );
process( mOption );
// Value is processed, reset the processor
mCurrentOption = mDefaultOption;
mOption = "";
}
}
checkRequiredOptions();
}
private void checkRequiredOptions() throws MissingRequiredOptionException {
if ( mRequiredOptions.size()>0 ) {
throw new MissingRequiredOptionException(
mRequiredOptions.values().iterator().next(),
mOptions
);
}
}
private void burst( String args ) throws UnknownArgumentException {
for (int i = 0; i < args.length(); i++) {
process( args.substring( i, i+1 ) );
}
}
/**
*
* @param arg
* @return true is an argument is required. That is, its not a Flag
* @throws UnknownArgumentException
*/
private boolean process( String arg ) throws UnknownArgumentException {
mOption = arg;
Option opt = mAllOptions.get( arg );
if ( opt==null ) {
throw new UnknownArgumentException( "-"+arg,mOptions );
}
mRequiredOptions.remove( opt.getOpt() );
ArrayList<String> values = mProvidedOptions.get( opt.getOpt() );
if ( values == null ) {
values = new ArrayList<String>();
}
mProvidedOptions.put( opt.getOpt(), values );
mCurrentOption = values;
return ! (opt instanceof Flag);
}
/*
* (non-Javadoc)
*
* @see org.flasby.cli.CommandLine#wasProvided(org.flasby.cli.Option)
*/
@Override
public boolean wasProvided(Option option) {
return mProvidedOptions.containsKey(option.getOpt());
}
/*
* (non-Javadoc)
*
* @see org.flasby.cli.CommandLine#getOptionValues(org.flasby.cli.Option)
*/
@Override
public String[] getValues(OptionList option) {
if (!wasProvided(option)) {
return new String[0];
}
ArrayList<String> l = mProvidedOptions.get(option.getOpt());
String[] retval = new String[l.size()];
l.toArray(retval);
return retval;
}
/*
* (non-Javadoc)
*
* @see org.flasby.cli.CommandLine#getOptionValue(org.flasby.cli.Option)
*/
@Override
public String getValue(Option option) {
if (!wasProvided(option)) {
return option.getDefaultValue();
}
ArrayList<String> l = mProvidedOptions.get(option.getOpt());
if ( l.size() == 0 ) {
// No value, maybe it should be a default?
String[] defaults = getDefaultValues();
if ( defaults.length > 0 ) {
return defaults[0];
}
return null;
}
return l.get(0);
}
@Override
public boolean getValue(Flag flag) {
return wasProvided(flag);
}
/* (non-Javadoc)
* @see org.flasby.cli.CommandLine#wasDefaultProvided()
*/
@Override
public boolean wasDefaultProvided() {
return mDefaultOption.size()>0;
}
/* (non-Javadoc)
* @see org.flasby.cli.CommandLine#getDefaultValue()
*/
@Override
public String getDefaultValue() {
String[] retval = getDefaultValues();
if (retval.length == 0) {
return null;
}
return retval[0];
}
/* (non-Javadoc)
* @see org.flasby.cli.CommandLine#getDefaultValues()
*/
@Override
public String[] getDefaultValues() {
if (!wasDefaultProvided()) {
return new String[0];
}
String[] retval = new String[mDefaultOption.size()];
mDefaultOption.toArray(retval);
return retval;
}
@Override
public Options getOptions(){
return new Options(mOptions);
}
}