/*
* Options.java
* Copyright (C) 2007 University of Waikato, Hamilton, New Zealand
* @author Richard Kirkby (rkirkby@cs.waikato.ac.nz)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package tr.gov.ulakbim.jDenetX.options;
import tr.gov.ulakbim.jDenetX.AbstractMOAObject;
import tr.gov.ulakbim.jDenetX.core.StringUtils;
import java.util.LinkedList;
import java.util.List;
public class Options extends AbstractMOAObject {
private static final long serialVersionUID = 1L;
protected List<Option> optionList = new LinkedList<Option>();
public void addOption(Option opt) {
if (getOption(opt.getName()) != null) {
throw new IllegalArgumentException("Duplicate option name: "
+ opt.getName());
}
if (getOption(opt.getCLIChar()) != null) {
throw new IllegalArgumentException(
"Duplicate option command line character: "
+ opt.getCLIChar());
}
this.optionList.add(opt);
}
public int numOptions() {
return this.optionList.size();
}
public Option getOption(String optName) {
for (Option option : this.optionList) {
if (optName.equals(option.getName())) {
return option;
}
}
return null;
}
public Option getOption(char cliChar) {
for (Option option : this.optionList) {
if (option.getCLIChar() == cliChar) {
return option;
}
}
return null;
}
public Option[] getOptionArray() {
return this.optionList.toArray(new Option[this.optionList.size()]);
}
public void removeOption(String optName) {
removeOption(getOption(optName));
}
public void removeOption(Option opt) {
this.optionList.remove(opt);
}
public void removeAllOptions() {
this.optionList = new LinkedList<Option>();
}
public void resetToDefaults() {
for (Option option : this.optionList) {
option.resetToDefault();
}
}
public void setViaCLIString(String cliString) {
cliString = cliString.trim();
while (cliString.length() > 0) {
if (cliString.startsWith("-")) {
boolean flagClusterFound = false;
String optionString = null;
int nextSpaceIndex = cliString.indexOf(' ', 1);
Option opt;
if (nextSpaceIndex > 0) {
optionString = cliString.substring(1, nextSpaceIndex);
} else {
optionString = cliString.substring(1, cliString.length());
nextSpaceIndex = cliString.length() - 1;
}
if (optionString.length() == 1) {
opt = getOption(optionString.charAt(0));
} else {
opt = getOption(optionString);
if (opt == null) {
// check for cluster of flags
flagClusterFound = true;
for (int i = 0; i < optionString.length(); i++) {
opt = getOption(optionString.charAt(i));
if (!(opt instanceof FlagOption)) {
flagClusterFound = false;
opt = null;
break;
}
}
if (flagClusterFound) {
for (int i = 0; i < optionString.length(); i++) {
opt = getOption(optionString.charAt(i));
opt.setValueViaCLIString("");
}
cliString = cliString.substring(nextSpaceIndex + 1,
cliString.length());
}
}
}
if (!flagClusterFound) {
if (opt != null) {
String parameters = cliString.substring(
nextSpaceIndex + 1, cliString.length());
if (opt instanceof FlagOption) {
opt.setValueViaCLIString("");
cliString = parameters;
} else {
String[] paramSplit = splitParameterFromRemainingOptions(parameters);
opt.setValueViaCLIString(paramSplit[0]);
cliString = paramSplit[1];
}
} else {
throw new IllegalArgumentException("Unknown option: -"
+ optionString);
}
}
} else {
throw new IllegalArgumentException("Expecting option, found: '"
+ cliString + "'.");
}
cliString = cliString.trim();
}
}
public String getAsCLIString() {
StringBuilder commandLine = new StringBuilder();
for (Option option : this.optionList) {
String value = option.getValueAsCLIString();
if ((value != null) && !value.equals(option.getDefaultCLIString())) {
if (commandLine.length() > 0) {
commandLine.append(" ");
}
commandLine.append("-" + option.getCLIChar());
if (value.length() > 0) {
if (value.indexOf(' ') < 0) {
commandLine.append(" " + value);
} else {
commandLine.append(" (" + value + ")");
}
}
}
}
return commandLine.toString();
}
public String getHelpString() {
StringBuilder sb = new StringBuilder();
getHelp(sb, 0);
return sb.toString();
}
public void getHelp(StringBuilder sb, int indent) {
if (optionList.size() > 0) {
for (Option option : optionList) {
StringUtils.appendIndent(sb, indent);
sb.append('-');
sb.append(option.getCLIChar());
sb.append(' ');
sb.append(option.getName());
String defaultString = option.getDefaultCLIString();
if (defaultString != null && defaultString.length() > 0) {
sb.append(" (default: ");
sb.append(defaultString);
sb.append(')');
}
StringUtils.appendNewline(sb);
StringUtils.appendIndent(sb, indent);
sb.append(option.getPurpose());
StringUtils.appendNewline(sb);
}
} else {
StringUtils.appendIndented(sb, indent, "No options.");
}
}
/**
* Internal method that splits a string into two parts - the parameter for
* the current option, and the remaining options.
*
* @param cliString the command line string, beginning at an option parameter
* @return an array of two strings - the first is the option paramter, the
* second is the remaining cli string
*/
protected static String[] splitParameterFromRemainingOptions(
String cliString) {
String[] paramSplit = new String[2];
cliString = cliString.trim();
if (cliString.startsWith("\"") || cliString.startsWith("'")) {
int endQuoteIndex = cliString.indexOf(cliString.charAt(0), 1);
if (endQuoteIndex < 0) {
throw new IllegalArgumentException(
"Quotes not terminated correctly.");
}
paramSplit[0] = cliString.substring(1, endQuoteIndex);
paramSplit[1] = cliString.substring(endQuoteIndex + 1, cliString
.length());
} else if (cliString.startsWith("(")) {
int bracketsOpen = 1;
int currPos = 1;
int nextCloseIndex = cliString.indexOf(")", currPos);
int nextOpenIndex = cliString.indexOf("(", currPos);
while (bracketsOpen != 0) {
if (nextCloseIndex < 0) {
throw new IllegalArgumentException("Brackets do not match.");
} else if ((nextOpenIndex < 0)
|| (nextCloseIndex < nextOpenIndex)) {
bracketsOpen--;
currPos = nextCloseIndex + 1;
nextCloseIndex = cliString.indexOf(")", currPos);
} else {
bracketsOpen++;
currPos = nextOpenIndex + 1;
nextOpenIndex = cliString.indexOf("(", currPos);
}
}
paramSplit[0] = cliString.substring(1, currPos - 1);
paramSplit[1] = cliString.substring(currPos, cliString.length());
} else {
int firstSpaceIndex = cliString.indexOf(" ", 0);
if (firstSpaceIndex >= 0) {
paramSplit[0] = cliString.substring(0, firstSpaceIndex);
paramSplit[1] = cliString.substring(firstSpaceIndex + 1,
cliString.length());
} else {
paramSplit[0] = cliString;
paramSplit[1] = "";
}
}
return paramSplit;
}
public void getDescription(StringBuilder sb, int indent) {
// TODO Auto-generated method stub
}
}