[jsword-svn] r1786 - in trunk/common/src/main/java/org/crosswire/common: . options
dmsmith at www.crosswire.org
dmsmith at www.crosswire.org
Fri Apr 4 14:31:05 MST 2008
Author: dmsmith
Date: 2008-04-04 14:31:04 -0700 (Fri, 04 Apr 2008)
New Revision: 1786
Added:
trunk/common/src/main/java/org/crosswire/common/options/
trunk/common/src/main/java/org/crosswire/common/options/ArgumentType.java
trunk/common/src/main/java/org/crosswire/common/options/DataType.java
trunk/common/src/main/java/org/crosswire/common/options/GetOptions.java
trunk/common/src/main/java/org/crosswire/common/options/Option.java
trunk/common/src/main/java/org/crosswire/common/options/OptionList.java
Log:
Added the start of an unencumbered implementation of Getopt.
Added: trunk/common/src/main/java/org/crosswire/common/options/ArgumentType.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/options/ArgumentType.java (rev 0)
+++ trunk/common/src/main/java/org/crosswire/common/options/ArgumentType.java 2008-04-04 21:31:04 UTC (rev 1786)
@@ -0,0 +1,119 @@
+/**
+ * Distribution License:
+ * JSword is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License, version 2.1 as published by
+ * the Free Software Foundation. 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 Lesser General Public License for more details.
+ *
+ * The License is available on the internet at:
+ * http://www.gnu.org/copyleft/lgpl.html
+ * or by writing to:
+ * Free Software Foundation, Inc.
+ * 59 Temple Place - Suite 330
+ * Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2008
+ * The copyright to this program is held by it's authors.
+ *
+ * ID: $Id: org.eclipse.jdt.ui.prefs 1178 2006-11-06 12:48:02Z dmsmith $
+ */
+
+package org.crosswire.common.options;
+
+import java.io.Serializable;
+
+/**
+ * An ArgumentType indicates whether and/or how an Option is followed by an argument.
+ *
+ * @see gnu.lgpl.License for license details.<br>
+ * The copyright to this program is held by it's authors.
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ */
+public class ArgumentType implements Serializable
+{
+ /**
+ * The option is not followed by an argument.
+ */
+ public static final ArgumentType NO_ARGUMENT = new ArgumentType("NO"); //$NON-NLS-1$
+
+ /**
+ * The option is followed by an argument.
+ */
+ public static final ArgumentType REQUIRED_ARGUMENT = new ArgumentType("Required"); //$NON-NLS-1$
+
+ /**
+ * The option may be followed by an argument.
+ */
+ public static final ArgumentType OPTIONAL_ARGUMENT = new ArgumentType("Optional"); //$NON-NLS-1$
+
+ /**
+ * @param name The name of the DataType
+ */
+ protected ArgumentType(String name)
+ {
+ this.name = name;
+ }
+
+ /**
+ * Lookup method to convert from a String
+ */
+ public static ArgumentType fromString(String name)
+ {
+ for (int i = 0; i < VALUES.length; i++)
+ {
+ ArgumentType o = VALUES[i];
+ if (o.name.equalsIgnoreCase(name))
+ {
+ return o;
+ }
+ }
+ // cannot get here
+ assert false;
+ return null;
+ }
+
+ /**
+ * Lookup method to convert from an integer
+ */
+ public static ArgumentType fromInteger(int i)
+ {
+ return VALUES[i];
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ return name;
+ }
+
+ /**
+ * The name of the DataType
+ */
+ private String name;
+
+ // Support for serialization
+ private static int nextObj;
+ private final int obj = nextObj++;
+
+ Object readResolve()
+ {
+ return VALUES[obj];
+ }
+
+ private static final ArgumentType[] VALUES =
+ {
+ NO_ARGUMENT,
+ REQUIRED_ARGUMENT,
+ OPTIONAL_ARGUMENT
+ };
+
+ /**
+ * Serialization ID
+ */
+ private static final long serialVersionUID = 3256727260177708345L;
+
+}
Added: trunk/common/src/main/java/org/crosswire/common/options/DataType.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/options/DataType.java (rev 0)
+++ trunk/common/src/main/java/org/crosswire/common/options/DataType.java 2008-04-04 21:31:04 UTC (rev 1786)
@@ -0,0 +1,165 @@
+/**
+ * Distribution License:
+ * JSword is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License, version 2.1 as published by
+ * the Free Software Foundation. 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 Lesser General Public License for more details.
+ *
+ * The License is available on the internet at:
+ * http://www.gnu.org/copyleft/lgpl.html
+ * or by writing to:
+ * Free Software Foundation, Inc.
+ * 59 Temple Place - Suite 330
+ * Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2008
+ * The copyright to this program is held by it's authors.
+ *
+ * ID: $Id: org.eclipse.jdt.ui.prefs 1178 2006-11-06 12:48:02Z dmsmith $
+ */
+
+package org.crosswire.common.options;
+
+import java.io.Serializable;
+
+import org.crosswire.common.util.Convert;
+
+/**
+ * A DataType provides the ability to marshal a String value to an object.
+ *
+ * @see gnu.lgpl.License for license details.<br>
+ * The copyright to this program is held by it's authors.
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ */
+public abstract class DataType implements Serializable
+{
+ /**
+ * A string argument.
+ */
+ public static final DataType STRING = new DataType("String") //$NON-NLS-1$
+ {
+ /* (non-Javadoc)
+ * @see org.crosswire.common.options.DataType#convertFromString(java.lang.String)
+ */
+ public Object convertFromString(String value)
+ {
+ return value;
+ }
+
+ /**
+ * Serialization ID
+ */
+ private static final long serialVersionUID = -2521783846509171308L;
+ };
+
+ /**
+ * An integer argument.
+ */
+ public static final DataType INTEGER = new DataType("Integer") //$NON-NLS-1$
+ {
+ /* (non-Javadoc)
+ * @see org.crosswire.common.options.DataType#convertFromString(java.lang.String)
+ */
+ public Object convertFromString(String value)
+ {
+ return new Integer(Convert.string2Int(value));
+ }
+
+ /**
+ * Serialization ID
+ */
+ private static final long serialVersionUID = -2521783846509171308L;
+ };
+
+ /**
+ * An boolean argument that allows various values for 'true'.
+ */
+ public static final DataType BOOLEAN = new DataType("Boolean") //$NON-NLS-1$
+ {
+ /* (non-Javadoc)
+ * @see org.crosswire.common.options.DataType#convertFromString(java.lang.String)
+ */
+ public Object convertFromString(String value)
+ {
+ return Boolean.valueOf(Convert.string2Boolean(value));
+ }
+
+ /**
+ * Serialization ID
+ */
+ private static final long serialVersionUID = -2521783846509171308L;
+ };
+
+ /**
+ * @param name The name of the DataType
+ */
+ protected DataType(String name)
+ {
+ this.name = name;
+ }
+
+ /**
+ * Convert a String to an Arguments expected value.
+ */
+ public abstract Object convertFromString(String input);
+
+ /**
+ * Lookup method to convert from a String
+ */
+ public static DataType fromString(String name)
+ {
+ for (int i = 0; i < VALUES.length; i++)
+ {
+ DataType o = VALUES[i];
+ if (o.name.equalsIgnoreCase(name))
+ {
+ return o;
+ }
+ }
+ // cannot get here
+ assert false;
+ return null;
+ }
+
+ /**
+ * Lookup method to convert from an integer
+ */
+ public static DataType fromInteger(int i)
+ {
+ return VALUES[i];
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ return name;
+ }
+
+ /**
+ * The name of the DataType
+ */
+ private String name;
+
+ // Support for serialization
+ private static int nextObj;
+ private final int obj = nextObj++;
+
+ Object readResolve()
+ {
+ return VALUES[obj];
+ }
+
+ private static final DataType[] VALUES =
+ {
+ };
+
+ /**
+ * Serialization ID
+ */
+ private static final long serialVersionUID = 3256727260177708345L;
+
+}
Added: trunk/common/src/main/java/org/crosswire/common/options/GetOptions.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/options/GetOptions.java (rev 0)
+++ trunk/common/src/main/java/org/crosswire/common/options/GetOptions.java 2008-04-04 21:31:04 UTC (rev 1786)
@@ -0,0 +1,80 @@
+/**
+ * Distribution License:
+ * JSword is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License, version 2.1 as published by
+ * the Free Software Foundation. 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 Lesser General Public License for more details.
+ *
+ * The License is available on the internet at:
+ * http://www.gnu.org/copyleft/lgpl.html
+ * or by writing to:
+ * Free Software Foundation, Inc.
+ * 59 Temple Place - Suite 330
+ * Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2008
+ * The copyright to this program is held by it's authors.
+ *
+ * ID: $Id: org.eclipse.jdt.ui.prefs 1178 2006-11-06 12:48:02Z dmsmith $
+ */
+
+package org.crosswire.common.options;
+
+/**
+ * GetOptions parses an argument list for requested arguments given by an
+ * OptionList.<br/>
+ *
+ * This supports short and long options:<br/>
+ * Short Options have the following characteristics.
+ * <ul>
+ * <li>A single dash, '-', starts a flag or a flag sequence. An example of a
+ * flag is '-c' and a flag sequence is '-xyz'.</li>
+ * <li>A flag may have a required argument. The flag may or may not be
+ * separated by a space from it's argument. For example, both -fbar and -f bar
+ * are acceptable.</li>
+ * <li>A flag may have an optional argument. The flag must not be separated by
+ * a space from it's optional argument. For example, -fbar is acceptable
+ * provides bar as the argument, but -f bar has bar as a non-option argument.</li>
+ * <li>These rules can combine. For example, -xyzfoo can be the same as -x -y
+ * -z foo</li>
+ * <li>If an Option expects an argument, then that argument can have a leading
+ * '-'. That is, if -x requires an option then the argument -y can be given as
+ * -x-y or -x -y.</li>
+ * </ul>
+ *
+ * Long Options have the following characteristics:
+ * <ul>
+ * <li>A double dash '--' starts a single flag. For example --print. Note, a
+ * long option is typically descriptive, but can be a single character.</li>
+ * <li>An argument may be given in one of two ways --file=filename or --file
+ * filename. That is, separated by an '=' sign or whitespace.</li>
+ * <li>
+ * <ul>
+ * Note:
+ * <ul>
+ * <li>Options can be repeated. What that means is up to the program.</li>
+ * <li>The '--' sequence terminates argument processing.</li>
+ * <li>A '-' by itself is not a flag.</li>
+ * <li>Unrecognized flags are an error.</li>
+ * <li>Unrecognized arguments are moved after the processed flags.</li>
+ * </ul>
+ *
+ * @see gnu.lgpl.License for license details.<br>
+ * The copyright to this program is held by it's authors.
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ */
+public class GetOptions
+{
+ public GetOptions(String programName, String[] args, OptionList options)
+ {
+ this.programName = programName;
+ this.args = args;
+ this.options = options;
+ }
+
+ private String programName;
+ private String[] args;
+ private OptionList options;
+}
Added: trunk/common/src/main/java/org/crosswire/common/options/Option.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/options/Option.java (rev 0)
+++ trunk/common/src/main/java/org/crosswire/common/options/Option.java 2008-04-04 21:31:04 UTC (rev 1786)
@@ -0,0 +1,223 @@
+/**
+ * Distribution License:
+ * JSword is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License, version 2.1 as published by
+ * the Free Software Foundation. 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 Lesser General Public License for more details.
+ *
+ * The License is available on the internet at:
+ * http://www.gnu.org/copyleft/lgpl.html
+ * or by writing to:
+ * Free Software Foundation, Inc.
+ * 59 Temple Place - Suite 330
+ * Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2008
+ * The copyright to this program is held by it's authors.
+ *
+ * ID: $Id: org.eclipse.jdt.ui.prefs 1178 2006-11-06 12:48:02Z dmsmith $
+ */
+
+package org.crosswire.common.options;
+
+/**
+ * An Option is representation of a single named parameter. An Option has a
+ * short, or a long name, or both.
+ * <p>
+ * It's inspiration was for command-line argument processing, but it can be used
+ * for any other purpose.
+ * </p>
+ * <ul>
+ * <li>An Option has a description, suitable for a usage statement.</li>
+ * <li>An Option's argument can be optional, required or unexpected. Default is NO_ARGUMENT.</li>
+ * <li>An Option can have an argument of a type. Default is DataType.BOOLEAN.</li>
+ * <li>An Option can have short name consisting of a single character.</li>
+ * <li>An Option can have a long name given by any string. What is allowed in
+ * the long name is dependent upon usage, but typically does not allow spaces.</li>
+ * <li>An Option can have a default value. Default is no default value.</li>
+ * </ul>
+ *
+ * @see gnu.lgpl.License for license details.<br>
+ * The copyright to this program is held by it's authors.
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ */
+public class Option
+{
+ /**
+ * Create a BOOLEAN Option with a short name, having no default value.
+ *
+ * @param description the description
+ * @param shortName the short name
+ */
+ public Option(String description, char shortName)
+ {
+ this(description, ArgumentType.NO_ARGUMENT, DataType.BOOLEAN, shortName, null, null);
+ }
+
+ /**
+ * Create a BOOLEAN Option with a long name, having no default value.
+ *
+ * @param description the description
+ * @param longName the long name
+ */
+ public Option(String description, String longName)
+ {
+ this(description, ArgumentType.NO_ARGUMENT, DataType.BOOLEAN, '\u0000', longName, null);
+ }
+
+ /**
+ * Create a BOOLEAN Option with both short and long names, having no default
+ * value.
+ *
+ * @param description the description
+ * @param shortName the short name
+ * @param longName the long name
+ */
+ public Option(String description, char shortName, String longName)
+ {
+ this(description, ArgumentType.NO_ARGUMENT, DataType.BOOLEAN, shortName, longName, null);
+ }
+
+ /**
+ * Create an Option with both short and long names of a given DataType
+ * having a default value.
+ *
+ * @param description the description
+ * @param shortName the short name
+ * @param longName the long name
+ * @param defaultValue the default value for this Option
+ */
+ public Option(String description, char shortName, String longName, String defaultValue)
+ {
+ this(description, ArgumentType.NO_ARGUMENT, DataType.BOOLEAN, shortName, longName, defaultValue);
+ }
+
+ /**
+ * Create an Option with a short name, having no default value.
+ *
+ * @param description the description
+ * @param argumentType the type of the argument
+ * @param dataType the type of argument's data
+ * @param shortName the short name
+ */
+ public Option(String description, ArgumentType argumentType, DataType dataType, char shortName)
+ {
+ this(description, argumentType, dataType, shortName, null, null);
+ }
+
+ /**
+ * Create an Option with a long name, having no default value.
+ *
+ * @param description the description
+ * @param argumentType the type of the argument
+ * @param dataType the type of argument's data
+ * @param longName the long name
+ */
+ public Option(String description, ArgumentType argumentType, DataType dataType, String longName)
+ {
+ this(description, argumentType, dataType, '\u0000', longName, null);
+ }
+
+ /**
+ * Create an Option with both short and long names, having no default value.
+ *
+ * @param description the description
+ * @param argumentType the type of the argument
+ * @param dataType the type of argument's data
+ * @param shortName the short name
+ * @param longName the long name
+ */
+ public Option(String description, ArgumentType argumentType, DataType dataType, char shortName, String longName)
+ {
+ this(description, argumentType, dataType, shortName, longName, null);
+ }
+
+ /**
+ * Create an Option with both short and long names of a given DataType
+ * having a default value.
+ *
+ * @param description the description
+ * @param argumentType the type of the argument
+ * @param dataType the type of argument's data
+ * @param shortName the short name
+ * @param longName the long name
+ * @param defaultValue the default value for this Option
+ */
+ public Option(String description, ArgumentType argumentType, DataType dataType, char shortName, String longName, String defaultValue)
+ {
+ this.description = description;
+ this.argumentType = argumentType;
+ this.dataType = dataType;
+ this.shortName = shortName;
+ this.longName = longName;
+ this.defaultValue = defaultValue;
+ }
+
+ /**
+ * The description provides a brief explanation of the option.
+ *
+ * @return the description
+ */
+ public String getDescription()
+ {
+ return description;
+ }
+
+ /**
+ * The short name of an Option is the single character by which this Option
+ * is known. If it is not set then there is no short name for this Option.
+ *
+ * @return the shortName
+ */
+ public char getShortName()
+ {
+ return shortName;
+ }
+
+ /**
+ * The long name of an Option is the single character by which this Option
+ * is known. If it is not set then there is no long name for this Option.
+ *
+ * @return the longName
+ */
+ public String getLongName()
+ {
+ return longName;
+ }
+
+ /**
+ * The ArgumentType indicates this Option's ability to use a following
+ * argument.
+ *
+ * @return the argumentType
+ */
+ public ArgumentType getArgumentType()
+ {
+ return argumentType;
+ }
+
+ /**
+ * @return the dataType
+ */
+ public DataType getDataType()
+ {
+ return dataType;
+ }
+
+ /**
+ * @return the defaultValue
+ */
+ public String getDefaultValue()
+ {
+ return defaultValue;
+ }
+
+ private String description;
+ private char shortName;
+ private String longName;
+ private DataType dataType;
+ private ArgumentType argumentType;
+ private String defaultValue;
+}
Added: trunk/common/src/main/java/org/crosswire/common/options/OptionList.java
===================================================================
--- trunk/common/src/main/java/org/crosswire/common/options/OptionList.java (rev 0)
+++ trunk/common/src/main/java/org/crosswire/common/options/OptionList.java 2008-04-04 21:31:04 UTC (rev 1786)
@@ -0,0 +1,158 @@
+/**
+ * Distribution License:
+ * JSword is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License, version 2.1 as published by
+ * the Free Software Foundation. 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 Lesser General Public License for more details.
+ *
+ * The License is available on the internet at:
+ * http://www.gnu.org/copyleft/lgpl.html
+ * or by writing to:
+ * Free Software Foundation, Inc.
+ * 59 Temple Place - Suite 330
+ * Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2008
+ * The copyright to this program is held by it's authors.
+ *
+ * ID: $Id: org.eclipse.jdt.ui.prefs 1178 2006-11-06 12:48:02Z dmsmith $
+ */
+
+package org.crosswire.common.options;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An OptionList contains an ordered set of Options. The primary ability of an
+ * OptionList is to find the matches for an Option.
+ *
+ * @see gnu.lgpl.License for license details.<br>
+ * The copyright to this program is held by it's authors.
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ */
+public class OptionList
+{
+ public OptionList()
+ {
+ longOptions = new LinkedHashMap();
+ }
+
+ /**
+ * Adds an Option to the end of this OptionList. It is an error with
+ * "undefined" behavior for an Option's short or long name to already be
+ * known.
+ *
+ * @param option
+ */
+ public void add(Option option)
+ {
+ char shortName = option.getShortName();
+ String longName = option.getLongName();
+ if (shortName != '\u0000')
+ {
+ String optionName = Character.toString(shortName);
+ assert !shortOptions.containsKey(optionName) : optionName + " already present"; //$NON-NLS-1$
+ shortOptions.put(optionName, option);
+ }
+
+ if (longName != null)
+ {
+ assert !longOptions.containsKey(longName) : longName + " already present"; //$NON-NLS-1$
+ longOptions.put(longName, option);
+ }
+ }
+
+ /**
+ * Get a list of Options that match the Option's long name. Return all
+ * Options where the key is a prefix of its long name. If there is an exact
+ * match then it is at the head of the list. It is up to the program to
+ * decide how to handle ambiguity.
+ *
+ * @param key the input to match
+ * @return a list of all matches, or an empty list
+ */
+ public List getLongOptions(String key)
+ {
+ List matches = new ArrayList();
+ if (longOptions.containsKey(key))
+ {
+ matches.add(longOptions.get(key));
+ }
+
+ Iterator iter = longOptions.entrySet().iterator();
+ while (iter.hasNext())
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ String entryKey = (String) entry.getKey();
+ Object entryValue = entry.getValue();
+ if (entryKey.startsWith(key) && !matches.contains(entryValue))
+ {
+ matches.add(entryValue);
+ }
+ }
+
+ return matches;
+ }
+
+ /**
+ * Get the Option that matches the key on the Option's short name.
+ *
+ * @param key the input to match
+ * @return the matching Option, null otherwise.
+ */
+ public Option getShortOption(char key)
+ {
+ Character keyChar = new Character(key);
+ Option match = null;
+ if (shortOptions.containsKey(keyChar))
+ {
+ match = (Option) shortOptions.get(keyChar);
+ }
+
+ return match;
+ }
+
+ /**
+ * Get a list of Options that match the Option's short or long name.
+ * Obviously, if the key is longer than a single character it won't match a
+ * short name. Return all Options where the key is a prefix of its long
+ * name. If there is an exact match then it is at the head of the list. It
+ * is up to the program to decide how to handle ambiguity.
+ *
+ * @param key the input to match
+ * @return a list of all matches, or an empty list
+ */
+ public List getOptions(String key)
+ {
+ List matches = new ArrayList();
+ if (key.length() == 1)
+ {
+ Option match = getShortOption(key.charAt(0));
+ if (match != null)
+ {
+ matches.add(match);
+ }
+ }
+
+ Iterator iter = getLongOptions(key).iterator();
+ while (iter.hasNext())
+ {
+ Option match = (Option) iter.next();
+ if ( !matches.contains(match))
+ {
+ matches.add(match);
+ }
+ }
+
+ return matches;
+ }
+
+ private Map shortOptions;
+ private Map longOptions;
+}
More information about the jsword-svn
mailing list