[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