Options.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;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.flasby.util.Message;
/**
* @author flasbyst
*/
public class Options {
ArrayList<Option> mOptions = new ArrayList<Option>();
Set<String> mSwitchList = new HashSet<String>();
final String mMlsPrefix;
private final Message mMessages;
public Options(Options copy) {
this(copy.mMessages, copy.mMlsPrefix);
}
public Options(Message messages, String mlsPrefix) {
if (mlsPrefix.endsWith(".")) {
mMlsPrefix = mlsPrefix;
} else {
mMlsPrefix = mlsPrefix + ".";
}
mMessages = messages;
}
/**
* returns a new MLS key with the qualifier appended to the prefix defined for this instance. This
* is useful to quickly obtain NLS keys which are specific to this Options instance.
*
* @param qualifier
* @return
*/
public String getMlsKey(String qualifier) {
return mMlsPrefix + qualifier;
}
/**
* add a new Option to this option collection.
*
* @return the option to allow for command chaining.
*/
public Option addOption(Option option) {
if (mSwitchList.contains(option.getOpt()))
throw new RuntimeException("you cant add the same option (" + option.getOpt() + ") twice.");
mOptions.add(option);
mSwitchList.add(option.getOpt());
return option;
}
public OptionList addOption(OptionList option) {
if (mSwitchList.contains(option.getOpt())) {
throw new RuntimeException(
"you cant add the same option twice: "
+ mSwitchList
+ "("
+ mSwitchList.size()
+ ") : '"
+ option.getOpt()
+ "'");
}
mOptions.add(option);
mSwitchList.add(option.getOpt());
return option;
}
public Flag addOption(Flag option) {
if (mSwitchList.contains(option.getOpt()))
throw new RuntimeException("you cant add the same option twice.");
mOptions.add(option);
mSwitchList.add(option.getOpt());
return option;
}
/**
* returns the options set on this collection of options.
*
* @return
*/
public Option[] getOptions() {
Option[] retval = new Option[mOptions.size()];
mOptions.toArray(retval);
return retval;
}
/**
* returns a string suitable for showing to the user as a usage description.
*
* @return the usage string.
*/
public String usage() {
StringBuffer sb = new StringBuffer(CliMessage.MESSAGE.getMLS("org.flasby.cli.usage"));
Iterator<Option> iter = mOptions.iterator();
sb.append(" ").append(CliMessage.MESSAGE.getMLS("org.flasby.cli.application"));
while (iter.hasNext()) {
Option option = iter.next();
sb.append(" ");
if (!option.isMandatory()) sb.append(CliMessage.MESSAGE.getMLS("org.flasby.cli.<"));
if (option.getOpt().length() > 0) {
sb.append("-");
sb.append(option.getOpt());
}
sb.append(" ").append(mMessages.getMLS(option.getDescriptionKey()));
if (!option.isMandatory()) sb.append(CliMessage.MESSAGE.getMLS("org.flasby.cli.>"));
}
iter = mOptions.iterator();
while (iter.hasNext()) {
Option option = iter.next();
sb.append(System.getProperty("line.separator")).append("\t");
if (option.getOpt().length() > 0) sb.append("-");
else sb.append(" ");
sb.append(option.getOpt())
.append(" ")
.append(mMessages.getMLS(option.getDescriptionKey()))
.append(" : ")
.append(
mMessages.getMLS(option.getDescriptionKey() + ".usage", option.getDefaultValue()));
}
return sb.toString();
}
/**
* create an option which is not mandatory and has no defailt value.
*
* @param option
* @param descriptionKey
* @return
*/
public Option create(final char option, final String descriptionKey) {
return createOption(option, descriptionKey, null, false);
}
/**
* create an option which is optional and has a default value.
*
* @param option
* @param descriptionKey
* @param defaultValue
* @return
*/
public Option create(final char option, final String descriptionKey, String defaultValue) {
return createOption(option, descriptionKey, defaultValue, false);
}
/**
* create a new option with control over if the option must be specified. This only makes sense if
* te option is mandatory as you can create option ones usig other methods.
*
* @param option
* @param descriptionKey
* @param isMandatory
* @return
*/
public Option create(final char option, final String descriptionKey, final boolean isMandatory) {
return createOption(option, descriptionKey, null, isMandatory);
}
/**
* create a new option with full control over all possibilities. Notice that creating a mandatory
* option with a default value is not very useful. Think about it.
*
* @param option
* @param descriptionKey
* @param defaultValue
* @param isMandatory
* @return
*/
private Option createOption(
final char option,
final String descriptionKey,
final String defaultValue,
final boolean isMandatory) {
return addOption(
new Option() {
/* (non-Javadoc)
* @see org.flasby.cli.Option#isRequired()
*/
@Override
public boolean isMandatory() {
return isMandatory;
}
@Override
public String getDefaultValue() {
return defaultValue;
}
/* (non-Javadoc)
* @see org.flasby.cli.Option#getDescriptionKey()
*/
@Override
public String getDescriptionKey() {
return mMlsPrefix + descriptionKey;
}
/* (non-Javadoc)
* @see org.flasby.cli.Option#getOpt()
*/
@Override
public String getOpt() {
return "" + option;
}
@Override
public String toString() {
return "opt:" + getOpt() + " key:" + getDescriptionKey();
}
});
}
/**
* create a new option list. Option lists are used where an option can have multiple values.
*
* @param option
* @param descriptionKey
* @return
*/
public OptionList createList(final char option, final String descriptionKey) {
return createList(option, descriptionKey, false);
}
public OptionList createList(
final char option, final String descriptionKey, final boolean isMandatory) {
return addOption(
new OptionList() {
/* (non-Javadoc)
* @see org.flasby.cli.Option#isRequired()
*/
@Override
public boolean isMandatory() {
return isMandatory;
}
/* (non-Javadoc)
* @see org.flasby.cli.Option#getDescriptionKey()
*/
@Override
public String getDescriptionKey() {
return descriptionKey;
}
/* (non-Javadoc)
* @see org.flasby.cli.Option#getOpt()
*/
@Override
public String getOpt() {
return "" + option;
}
@Override
public String toString() {
return "opt:" + getOpt() + " key:" + getDescriptionKey();
}
@Override
public String getDefaultValue() {
return null;
}
});
}
public OptionList create(final String descriptionKey) {
return create(descriptionKey, false, null);
}
public OptionList create(final String descriptionKey, final boolean isMandatory) {
return create(descriptionKey, isMandatory, null);
}
public OptionList create(final String descriptionKey, String defaultValue) {
return create(descriptionKey, false, defaultValue);
}
public OptionList create(final String descriptionKey, final boolean isMandatory, String defaultValue) {
return addOption(
new OptionList() {
/* (non-Javadoc)
* @see org.flasby.cli.Option#isRequired()
*/
@Override
public boolean isMandatory() {
return isMandatory;
}
/* (non-Javadoc)
* @see org.flasby.cli.Option#getDescriptionKey()
*/
@Override
public String getDescriptionKey() {
return mMlsPrefix + descriptionKey;
}
/* (non-Javadoc)
* @see org.flasby.cli.Option#getOpt()
*/
@Override
public String getOpt() {
return "";
}
@Override
public String toString() {
return "opt:" + getOpt() + " key:" + getDescriptionKey();
}
@Override
public String getDefaultValue() {
return defaultValue;
}
});
}
public Flag createFlag(final char flag, final String descriptionKey) {
return addOption(
new Flag() {
@Override
public boolean isMandatory() {
return false;
}
@Override
public String getDefaultValue() {
return null;
}
@Override
public String getDescriptionKey() {
return mMlsPrefix + descriptionKey;
}
@Override
public String getOpt() {
return "" + flag;
}
@Override
public String toString() {
return "flag:" + getOpt() + " key:" + getDescriptionKey();
}
});
}
public Message getMessageBundle() {
return mMessages;
}
@Override
public String toString() {
return "Options [mOptions=" + mOptions + "]";
}
}