[jsap] 03/04: Imported Upstream version 2.1
Emmanuel Bourg
ebourg-guest at moszumanska.debian.org
Thu Sep 3 13:07:45 UTC 2015
This is an automated email from the git hooks/post-receive script.
ebourg-guest pushed a commit to annotated tag debian/2.1-1
in repository jsap.
commit b0e2edba5508187f7fed3a5d005639d999467254
Author: Guillaume Turri <guillaume.turri at gmail.com>
Date: Thu Sep 3 10:04:53 2015 +0200
Imported Upstream version 2.1
---
CHANGELOG.TXT | 52 +
LICENSE.TXT | 31 +
build.xml | 320 +++++
src/doc/CHANGELOG.TXT | 52 +
src/doc/manual.css | 61 +
.../martiansoftware/jsap/CommandLineTokenizer.java | 110 ++
.../com/martiansoftware/jsap/DefaultSource.java | 30 +
src/java/com/martiansoftware/jsap/Defaults.java | 147 +++
.../com/martiansoftware/jsap/ExceptionMap.java | 52 +
src/java/com/martiansoftware/jsap/Flagged.java | 65 +
.../com/martiansoftware/jsap/FlaggedOption.java | 314 +++++
src/java/com/martiansoftware/jsap/IDMap.java | 108 ++
.../jsap/IllegalMultipleDeclarationException.java | 48 +
src/java/com/martiansoftware/jsap/JSAP.java | 862 ++++++++++++
.../com/martiansoftware/jsap/JSAPException.java | 55 +
src/java/com/martiansoftware/jsap/JSAPResult.java | 1382 ++++++++++++++++++++
src/java/com/martiansoftware/jsap/Option.java | 238 ++++
src/java/com/martiansoftware/jsap/Parameter.java | 264 ++++
.../com/martiansoftware/jsap/ParseException.java | 52 +
src/java/com/martiansoftware/jsap/Parser.java | 471 +++++++
.../martiansoftware/jsap/PropertyStringParser.java | 87 ++
.../com/martiansoftware/jsap/QualifiedSwitch.java | 229 ++++
.../jsap/RequiredParameterMissingException.java | 42 +
src/java/com/martiansoftware/jsap/SimpleJSAP.java | 167 +++
.../com/martiansoftware/jsap/StringParser.java | 78 ++
src/java/com/martiansoftware/jsap/Switch.java | 204 +++
.../com/martiansoftware/jsap/SyntaxException.java | 25 +
src/java/com/martiansoftware/jsap/TestAll.java | 40 +
.../jsap/TestCommandLineTokenizer.java | 184 +++
.../com/martiansoftware/jsap/TestDefaults.java | 213 +++
.../martiansoftware/jsap/TestFlaggedOption.java | 54 +
.../jsap/TestJSAPConfiguration.java | 117 ++
src/java/com/martiansoftware/jsap/TestOption.java | 71 +
src/java/com/martiansoftware/jsap/TestParser.java | 118 ++
src/java/com/martiansoftware/jsap/TestSwitch.java | 100 ++
.../com/martiansoftware/jsap/TestUsageString.java | 77 ++
.../com/martiansoftware/jsap/UnflaggedOption.java | 240 ++++
.../martiansoftware/jsap/UnknownFlagException.java | 47 +
.../jsap/UnspecifiedParameterException.java | 38 +
.../com/martiansoftware/jsap/ant/DefaultValue.java | 40 +
.../jsap/ant/FlaggedOptionConfiguration.java | 158 +++
.../com/martiansoftware/jsap/ant/JSAPAntTask.java | 545 ++++++++
.../jsap/ant/OptionConfiguration.java | 299 +++++
.../jsap/ant/ParameterConfiguration.java | 149 +++
.../martiansoftware/jsap/ant/ParserProperty.java | 62 +
.../jsap/ant/SwitchConfiguration.java | 117 ++
.../jsap/ant/UnflaggedOptionConfiguration.java | 104 ++
.../jsap/defaultsources/PropertyDefaultSource.java | 234 ++++
.../jsap/defaultsources/TestAll.java | 25 +
.../defaultsources/TestPropertyDefaultSource.java | 73 ++
.../martiansoftware/jsap/examples/Example1.java | 42 +
.../jsap/examples/Manual_HelloWorld_1.java | 10 +
.../jsap/examples/Manual_HelloWorld_2.java | 40 +
.../jsap/examples/Manual_HelloWorld_3.java | 48 +
.../jsap/examples/Manual_HelloWorld_4.java | 65 +
.../jsap/examples/Manual_HelloWorld_5.java | 70 +
.../jsap/examples/Manual_HelloWorld_6.java | 72 +
.../jsap/examples/Manual_HelloWorld_7.java | 83 ++
.../jsap/examples/Manual_HelloWorld_8.java | 91 ++
.../jsap/examples/Manual_HelloWorld_9.java | 75 ++
.../jsap/examples/Manual_HelloWorld_9.jsap | 38 +
.../jsap/examples/Manual_HelloWorld_Simple.java | 55 +
.../jsap/stringparsers/BigDecimalStringParser.java | 74 ++
.../jsap/stringparsers/BigIntegerStringParser.java | 73 ++
.../jsap/stringparsers/BooleanStringParser.java | 114 ++
.../jsap/stringparsers/ByteStringParser.java | 69 +
.../jsap/stringparsers/CharacterStringParser.java | 70 +
.../jsap/stringparsers/ClassStringParser.java | 77 ++
.../jsap/stringparsers/ColorStringParser.java | 272 ++++
.../jsap/stringparsers/DateStringParser.java | 118 ++
.../jsap/stringparsers/DoubleStringParser.java | 73 ++
.../jsap/stringparsers/EnumeratedStringParser.java | 220 ++++
.../jsap/stringparsers/FileStringParser.java | 126 ++
.../jsap/stringparsers/FloatStringParser.java | 75 ++
.../jsap/stringparsers/ForNameStringParser.java | 62 +
.../stringparsers/InetAddressStringParser.java | 75 ++
.../jsap/stringparsers/IntSizeStringParser.java | 43 +
.../jsap/stringparsers/IntegerStringParser.java | 70 +
.../jsap/stringparsers/LongSizeStringParser.java | 120 ++
.../jsap/stringparsers/LongStringParser.java | 69 +
.../jsap/stringparsers/PackageStringParser.java | 69 +
.../jsap/stringparsers/ShortStringParser.java | 73 ++
.../jsap/stringparsers/StringStringParser.java | 56 +
.../jsap/stringparsers/TestAll.java | 30 +
.../jsap/stringparsers/TestColorStringParser.java | 123 ++
.../jsap/stringparsers/TestLongStringParser.java | 45 +
.../jsap/stringparsers/URLStringParser.java | 76 ++
.../martiansoftware/jsap/xml/FlaggedConfig.java | 41 +
.../jsap/xml/FlaggedOptionConfig.java | 91 ++
.../com/martiansoftware/jsap/xml/JSAPConfig.java | 78 ++
.../com/martiansoftware/jsap/xml/JSAPXStream.java | 30 +
.../martiansoftware/jsap/xml/ParameterConfig.java | 74 ++
.../com/martiansoftware/jsap/xml/Property.java | 35 +
.../jsap/xml/QualifiedSwitchConfig.java | 29 +
.../jsap/xml/StringParserConfig.java | 63 +
.../com/martiansoftware/jsap/xml/SwitchConfig.java | 27 +
.../com/martiansoftware/jsap/xml/TryDumpXML.java | 51 +
.../com/martiansoftware/jsap/xml/TryLoadXML.java | 21 +
.../jsap/xml/UnflaggedOptionConfig.java | 95 ++
.../com/martiansoftware/jsap/xml/silly-example.xml | 47 +
src/java/com/martiansoftware/util/StringUtils.java | 91 ++
101 files changed, 12385 insertions(+)
diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT
new file mode 100644
index 0000000..868c695
--- /dev/null
+++ b/CHANGELOG.TXT
@@ -0,0 +1,52 @@
+v2.0a (July 23, 2005)
+
+ * Fixed an embarrassing bug that resulted in unexpected characters
+ in auto-generated help output.
+
+ * Fixed bugs in FileStringParser that prevented enforcement of
+ mustExist(), mustBeFile(), and mustBeDirectory()
+
+v2.0 (June 21, 2005)
+
+ * Fixed setHelp() methods to return a reference to "this", consistent
+ with other setters.
+
+ * New layout for option help to avoid problems with excessively long
+ option descriptions
+
+ * Added constructors with built-in help text setters.
+
+ * Added SimpleJSAP class to speed up common configurations.
+
+ * Added unbreakable spaces between flags and arguments in auto-generated
+ usage text.
+
+ * Added IntSizeStringParser and LongSizeStringParser to allow numeric
+ parameters with SI suffixes (e.g., "10K" returns an Integer or Long
+ with value 10,000. Currently supported suffixes include K, M, G, T,
+ P, Ki, Mi, Gi, Ti, Pi.
+
+ * Added ForNameStringParser that takes a class name and returns an object
+ constructed via class.forName().
+
+ * Added singleton instances of most StringParsers to avoid unnecessary
+ object creation. Singletons are available as public static fields of
+ JSAP, e.g., JSAP.BIG_DECIMAL_PARSER.
+
+ * Default values for parameters are now indicated in auto-generated help.
+
+ * Added no-space short options, a la GNU getopt. "-b5" is equivalent to
+ "-b 5"
+
+ * Several minor bugfixes and documentation corrections.
+
+ * Added JSAPResult.contains(String id) to determine if the result contains
+ any values at all (including default values) for the specified parameter.
+
+ * Added JSAPResult.userSpecified(String id) to determine if the result
+ contains a USER-SPECIFIED value (i.e., not including default values)
+ for the specified parameter.
+
+ * Added XML support for JSAP configuration (experimental).
+
+ * Brought JIRA bug tracker online at http://jira.martiansoftware.com.
\ No newline at end of file
diff --git a/LICENSE.TXT b/LICENSE.TXT
new file mode 100644
index 0000000..7992529
--- /dev/null
+++ b/LICENSE.TXT
@@ -0,0 +1,31 @@
+JSAP - Java Simple Argument Parser
+Copyright (c) 2002-2004, Martian Software, Inc.
+
+
+LICENSE
+-------
+JSAP is licensed under the Lesser GNU Public License.
+A copy of this license is available at
+http://www.fsf.org/licenses/licenses.html#LGPL
+
+Alternate licensing terms may be obtained by contacting
+the author: http://www.martiansoftware.com/contact.html
+
+
+JAVA LGPL CLARIFICATION
+-----------------------
+JSAP is Free Software. The LGPL license is sufficiently
+flexible to allow the use of JSAP in both open source
+and commercial projects. Using JSAP (by importing JSAP's
+public interfaces in your Java code), and extending JSAP
+(by subclassing) are considered by the authors of JSAP
+to be dynamic linking. Hence our interpretation of the
+LGPL is that the use of the unmodified JSAP source or
+binary, or the rebundling of unmodified JSAP classes into
+your program's .jar file, does not affect the license of
+your application code.
+
+If you modify JSAP and redistribute your modifications,
+the LGPL applies.
+
+(based upon similar clarification at http://www.hibernate.org/ )
diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..50dd0f7
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,320 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+==========================================================================
+
+JSAP build file
+
+Author:
+ Marty Lamb
+ http://www.martiansoftware.com/contact.html
+
+Legal:
+ Copyright (c) 2002-2006, Martian Software, Inc.
+ This file is made available under the LGPL as described in the accompanying
+ LICENSE.TXT file.
+
+==============================================================================
+
+-->
+<project basedir="." default="help" name="jsap">
+
+
+
+ <!-- PROPERTIES ***************************************************************************************** -->
+
+ <!-- Basics -->
+ <property name="name" value="JSAP" />
+ <property name="version" value="2.1"/>
+ <property name="year" value="2002-2006"/>
+
+ <!-- Documentation -->
+ <property name="j2se.apiurl" value="http://java.sun.com/j2se/1.4/docs/api/"/>
+ <property name="xstream.apiurl" value="http://xstream.codehaus.org/javadoc/"/>
+
+ <!-- Directories -->
+ <property name="buildfile" value="build.xml"/>
+ <property name="src" value="src"/>
+ <property name="javasrc" value="${src}/java"/>
+ <property name="build" value="build"/>
+ <property name="doc" value="doc"/>
+ <property name="javadoc" value="${doc}/javadoc"/>
+ <property name="javadoc.tmp.src" value="${javadoc}/tmpsrc"/>
+ <property name="dist" value="dist"/>
+ <property name="lib" value="lib"/>
+
+ <!-- Special Tasks -->
+ <taskdef
+ name="snip"
+ classname="com.martiansoftware.snip.Snip"
+ classpath="${lib}/snip-0.11.jar"/>
+
+ <taskdef
+ name="rundoc"
+ classname="com.martiansoftware.rundoc.RunDoc"
+ classpath="${lib}/rundoc-0.11.jar"/>
+
+ <!-- Special Files -->
+ <property name="testFiles" value="**/Test*" />
+ <property name="exampleFiles" value="com/martiansoftware/jsap/examples/" />
+ <property name="manualFiles" value="manual" />
+ <property name="jsapXmlFiles" value="**/*.jsap" />
+
+ <property name="jarname" value="${name}-${version}.jar" />
+
+ <!-- Administrivia -->
+ <property name="url" value="http://www.martiansoftware.com/jsap" />
+ <property name="copyrightowners" value="Martian Software, Inc." />
+ <property name="copyright.html" value="Copyright © ${year}, ${copyrightowners}. All Rights Reserved." />
+ <property name="updates.html" value="For the latest version and documentation, please visit <a href='${url}'>${url}</a>" />
+ <!-- END OF PROPERTIES ********************************************************************************** -->
+
+ <!-- required for build to work in eclipse -->
+ <target name="eclipse-setcompiler" if="eclipse.running">
+ <property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter" />
+ </target>
+
+ <!-- ensure required directories exist -->
+ <target name="init" depends="eclipse-setcompiler">
+ <mkdir dir="${build}"/>
+ <mkdir dir="${javadoc}"/>
+ <mkdir dir="${dist}"/>
+ <!-- Who knows... we might need this for something. -->
+ <tstamp/>
+ </target>
+
+ <!-- jars required for build -->
+ <path id="lib.class.path">
+ <pathelement location="${lib}/ant.jar"/>
+ <pathelement location="${lib}/junit.jar"/>
+ <pathelement location="${lib}/xstream-1.1.2.jar"/>
+ </path>
+
+ <!-- print target list -->
+ <target name="help">
+ <echo>
+
+----------------------------------------------------------------------
+
+Targets:
+
+ clean - delete all intermediate & compiled files
+ compile-api - compiles the JSAP API
+ compile-tests - compiles the JSAP API and JUnit test cases
+ compile-all - compiles the JSAP API, JUnit test cases, and examples
+ test - compiles the JSAP API and tests it
+ jar - compiles the JSAP API and builds JSAP.jar
+ javadoc - compiles the JSAP API and generates javadoc documentation
+ dist - compiles the JSAP API, builds the jar file, runs javadoc, and
+ creates source and binary distribution files.
+
+----------------------------------------------------------------------
+ </echo>
+ </target>
+
+ <!-- delete all intermediate files -->
+ <target name="clean" depends="init">
+ <delete dir="${build}" verbose="true"/>
+ <delete dir="${javadoc}" verbose="true"/>
+ <delete dir="${dist}" verbose="true"/>
+ <mkdir dir="${build}"/>
+ <mkdir dir="${javadoc}"/>
+ <mkdir dir="${dist}"/>
+ </target>
+
+ <!-- compile the JSAP API -->
+ <target name="compile-api" depends="init" >
+ <javac target="1.4" source="1.4" destdir="${build}" srcdir="${javasrc}">
+<!-- <exclude name="${testFiles}" />
+ <exclude name="${exampleFiles}" /> -->
+ <classpath refid="lib.class.path" />
+ </javac>
+ <copy todir="${build}">
+ <fileset dir="${javasrc}">
+ <include name="${jsapXmlFiles}" />
+ </fileset>
+ </copy>
+ </target>
+
+ <!-- compile the JSAP API and JUnit tests -->
+ <target name="compile-tests" depends="init" >
+ <javac target="1.4" source="1.4" destdir="${build}" srcdir="${javasrc}">
+<!-- <exclude name="${exampleFiles}" /> -->
+ <classpath refid="lib.class.path" />
+ </javac>
+ <copy todir="${build}">
+ <fileset dir="${javasrc}">
+ <include name="${testConfFiles}" />
+ </fileset>
+ </copy>
+ </target>
+
+ <!-- compile the JSAP API, JUnit tests, and examples -->
+ <target name="compile-all" depends="init" >
+ <javac target="1.4" source="1.4" destdir="${build}" srcdir="${javasrc}">
+ <classpath refid="lib.class.path" />
+ </javac>
+ </target>
+
+ <!-- run the JUnit tests -->
+ <target name="test" depends="compile-tests" >
+ <junit printsummary="on">
+ <test name="com.martiansoftware.jsap.TestAll"/>
+ <formatter type="plain" usefile="false"/>
+ <classpath refid="lib.class.path" />
+ <classpath>
+ <pathelement location="${build}"/>
+ </classpath>
+ </junit>
+ </target>
+
+ <!-- make the jar -->
+ <target name="jar" depends="clean,test">
+ <mkdir dir="${dist}"/>
+ <jar basedir="${build}" jarfile="${dist}/${jarname}">
+ <exclude name="${testFiles}" />
+ <exclude name="${exampleFiles}" />
+ <exclude name="${manualFiles}" />
+ </jar>
+ </target>
+
+ <!-- generate javadocs -->
+ <target name="javadoc" depends="compile-api">
+ <delete dir="${javadoc}"/>
+ <mkdir dir="${javadoc}"/>
+
+ <javadoc
+ public="true"
+ destdir="${javadoc}"
+ sourcepath="${javasrc}"
+ packagenames="com.martiansoftware.*"
+ windowtitle="JSAP: the Java Simple Argument Parser"
+ classpathref="lib.class.path">
+
+ <link href="${j2se.apiurl}"/>
+ <link href="${xstream.apiurl}"/>
+ <bottom>${copyright.html}<br>${updates.html}</bottom>
+
+ </javadoc>
+ </target>
+
+ <!-- generate manual -->
+ <target name="manual" depends="compile-all">
+ <snip xmlsafe="true">
+ <fileset dir="${javasrc}" includes="**/*.java" />
+ <fileset dir="${javasrc}" includes="**/*.jsap" />
+ </snip>
+ <mkdir dir="${build}/manual"/>
+ <copy encoding="ISO-8859-1" outputencoding="ISO-8859-1" overwrite="true" verbose="true" file="${src}/doc/manual.xml" todir="${build}/manual">
+ <filterset>
+ <filter token="Manual_HelloWorld_1" value="${snip.Manual_HelloWorld_1}"/>
+ <filter token="Manual_HelloWorld_2" value="${snip.Manual_HelloWorld_2}"/>
+ <filter token="Manual_HelloWorld_3" value="${snip.Manual_HelloWorld_3}"/>
+ <filter token="Manual_HelloWorld_4" value="${snip.Manual_HelloWorld_4}"/>
+ <filter token="Manual_HelloWorld_5" value="${snip.Manual_HelloWorld_5}"/>
+ <filter token="Manual_HelloWorld_6" value="${snip.Manual_HelloWorld_6}"/>
+ <filter token="Manual_HelloWorld_7" value="${snip.Manual_HelloWorld_7}"/>
+ <filter token="Manual_HelloWorld_8" value="${snip.Manual_HelloWorld_8}"/>
+ <filter token="Manual_HelloWorld_9" value="${snip.Manual_HelloWorld_9}"/>
+ <filter token="Manual_HelloWorld_Simple" value="${snip.Manual_HelloWorld_Simple}"/>
+ <filter token="Manual_HelloWorld_9_jsap" value="${snip.Manual_HelloWorld_9_jsap}"/>
+ </filterset>
+ </copy>
+
+ <rundoc prompt="[mlamb at morbo]$ " format="docbook">
+ <fileset file="${build}/manual/manual.xml"/>
+ <env key="CLASSPATH" value="${build}:${lib}/xstream-1.1.2.jar"/>
+ <env key="LANG" value="en_US.iso88591"/>
+ </rundoc>
+
+ <!-- anyone want to write a non-platform-specific task to do this? -->
+ <exec dir="${build}/manual" executable="xmlto">
+ <arg value="html"/>
+ <arg value="manual.xml"/>
+ </exec>
+
+ <replace encoding="ISO-8859-1" dir="${build}/manual" includes="*.html"
+ token="<head>"
+ value="<head><link rel='stylesheet' type='text/css' href='manual.css'/>" />
+
+ <replace encoding="ISO-8859-1" dir="${build}/manual" includes="*.html"
+ token="	"
+ value=" " />
+
+ <replace encoding="ISO-8859-1" dir="${build}/manual" includes="*.html"
+ token="Â"
+ value="" />
+
+ <replace encoding="ISO-8859-1" dir="${build}/manual" includes="*.html"
+ token=" "
+ value=" " />
+
+ <copy overwrite="true" verbose="true" todir="${doc}">
+ <fileset dir="${build}/manual" includes="*.html"/>
+ </copy>
+ <copy overwrite="true" verbose="true" file="${src}/doc/manual.css" todir="${doc}"/>
+
+ </target>
+
+ <!-- build distributable files -->
+ <target name="dist" depends="jar,javadoc,manual">
+
+ <!-- copy files to a temp directory for packaging -->
+ <property name="distimage" value="${dist}/${name}-${version}"/>
+ <property name="distimage.short" value="${name}-${version}"/>
+ <delete dir="${distimage}" />
+ <mkdir dir="${distimage}" />
+ <copy todir="${distimage}" file="${buildfile}" />
+ <copy todir="${distimage}" file="LICENSE.TXT" />
+ <copy todir="${distimage}" file="src/doc/CHANGELOG.TXT" />
+
+ <!-- copy source files into temp directory -->
+ <mkdir dir="${distimage}/${src}"/>
+ <copy todir="${distimage}/${src}">
+ <fileset dir="${src}" />
+ </copy>
+
+ <!-- copy jar files into temp directory -->
+ <mkdir dir="${distimage}/${lib}"/>
+ <copy todir="${distimage}/${lib}" file="${dist}/${jarname}" />
+ <copy todir="${distimage}/${lib}">
+ <fileset dir="${lib}" />
+ </copy>
+
+ <!-- copy documentation into temp directory -->
+ <mkdir dir="${distimage}/${doc}"/>
+ <copy todir="${distimage}/${doc}">
+ <fileset dir="${doc}">
+ <exclude name="**/src/**"/>
+ </fileset>
+ </copy>
+
+ <!-- make the source zip file -->
+ <zip destfile="${dist}/${name}-${version}-src.zip" basedir="${dist}" includes="${distimage.short}/**" update="false" />
+ <tar tarfile="${dist}/${name}-${version}-src.tar" basedir="${dist}" includes="${distimage.short}/**"/>
+ <gzip zipfile="${dist}/${name}-${version}-src.tar.gz" src="${dist}/${name}-${version}-src.tar"/>
+
+ <!-- delete the buildfile, source files and development libaries from the temp directory. -->
+ <!-- the binary distribution file should just contain the jar and the documentation. -->
+ <delete file="${distimage}/${buildfile}" />
+ <delete dir="${distimage}/${src}" />
+ <delete>
+ <fileset dir="${distimage}/${lib}" excludes="${jarname}" />
+ </delete>
+
+ <!-- make the binary zip file -->
+ <zip destfile="${dist}/${name}-${version}.zip" basedir="${dist}" includes="${distimage.short}/**" update="false" />
+ <tar tarfile="${dist}/${name}-${version}.tar" basedir="${dist}" includes="${distimage.short}/**"/>
+ <gzip zipfile="${dist}/${name}-${version}.tar.gz" src="${distimage}.tar"/>
+
+ <!-- delete the tar files that are now gzipped -->
+ <delete>
+ <fileset dir="${dist}" includes="*.tar" />
+ </delete>
+<!-- <delete dir="${distimage}"/> -->
+ </target>
+
+ <!-- build distributable files from scratch -->
+ <target name="cleandist" depends="clean, dist">
+ </target>
+
+</project>
diff --git a/src/doc/CHANGELOG.TXT b/src/doc/CHANGELOG.TXT
new file mode 100644
index 0000000..868c695
--- /dev/null
+++ b/src/doc/CHANGELOG.TXT
@@ -0,0 +1,52 @@
+v2.0a (July 23, 2005)
+
+ * Fixed an embarrassing bug that resulted in unexpected characters
+ in auto-generated help output.
+
+ * Fixed bugs in FileStringParser that prevented enforcement of
+ mustExist(), mustBeFile(), and mustBeDirectory()
+
+v2.0 (June 21, 2005)
+
+ * Fixed setHelp() methods to return a reference to "this", consistent
+ with other setters.
+
+ * New layout for option help to avoid problems with excessively long
+ option descriptions
+
+ * Added constructors with built-in help text setters.
+
+ * Added SimpleJSAP class to speed up common configurations.
+
+ * Added unbreakable spaces between flags and arguments in auto-generated
+ usage text.
+
+ * Added IntSizeStringParser and LongSizeStringParser to allow numeric
+ parameters with SI suffixes (e.g., "10K" returns an Integer or Long
+ with value 10,000. Currently supported suffixes include K, M, G, T,
+ P, Ki, Mi, Gi, Ti, Pi.
+
+ * Added ForNameStringParser that takes a class name and returns an object
+ constructed via class.forName().
+
+ * Added singleton instances of most StringParsers to avoid unnecessary
+ object creation. Singletons are available as public static fields of
+ JSAP, e.g., JSAP.BIG_DECIMAL_PARSER.
+
+ * Default values for parameters are now indicated in auto-generated help.
+
+ * Added no-space short options, a la GNU getopt. "-b5" is equivalent to
+ "-b 5"
+
+ * Several minor bugfixes and documentation corrections.
+
+ * Added JSAPResult.contains(String id) to determine if the result contains
+ any values at all (including default values) for the specified parameter.
+
+ * Added JSAPResult.userSpecified(String id) to determine if the result
+ contains a USER-SPECIFIED value (i.e., not including default values)
+ for the specified parameter.
+
+ * Added XML support for JSAP configuration (experimental).
+
+ * Brought JIRA bug tracker online at http://jira.martiansoftware.com.
\ No newline at end of file
diff --git a/src/doc/manual.css b/src/doc/manual.css
new file mode 100644
index 0000000..86fe0fa
--- /dev/null
+++ b/src/doc/manual.css
@@ -0,0 +1,61 @@
+body { background-image: url("/images/wave.png"); color: black; background: white; }
+
+.blue { color: #33275b; background: white }
+.green { color: #80c254; background: white; }
+.green-on-blue { color: #80c254; background: #33275b; }
+
+a:link { color: #33275b; }
+a:link img, a:visited img { border-style: none }
+a:visited { color: #33275b; }
+
+pre.programlisting {
+ font-size: 9pt;
+ margin: 1em 1em 1em 1em;
+ padding: 0 1em 0 1em;
+ border: 1px solid #80c254;
+ font-family: courier, monospace;
+ color: #33275b;
+ background: #ffffff;
+}
+
+pre.screen {
+ font-size: 9pt;
+ white-space:pre;
+ padding: 0 1em 0 1em;
+ border: 1px solid #80c254;
+ font-family: courier, monospace;
+ color: #ffffff;
+ background: #000000;
+}
+
+b.command {
+ white-space: normal;
+}
+
+div.tip, div.note, div.caution, div.warning {
+ background-repeat: no-repeat;
+ background: #e3f4b0;
+ border: 1px solid #80c254;
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+div.tip h3.title, div.note h3.title, div.caution h3.title, div.warning h3.title {
+ color: #33275b;
+ font-family: helvetica, sans-serif;
+ margin-left: 1em;
+ margin-right: 1em;
+ margin-top: 0.5em;
+}
+
+div.tip p, div.note p, div.caution p, div.warning p {
+ color: #33275b;
+ margin-left: 1em;
+ margin-right: 1em;
+}
+
+p {margin: 0 0 1em; font-family: Book Antiqua, New York, New Century Schoolbook, Times New Roman, Times, serif; }
+li { font-family: Book Antiqua, New York, New Century Schoolbook, Times New Roman, Times, serif; }
+h1 { margin: 1em 0 0; font-size: 150%; font-family: helvetica, sans-serif; color: #33275b; background: white; font-weight: normal; border-bottom: 2px solid #80c254 }
+h2 { margin: 2em 0 0; font-size: 125%; font-family: helvetica, sans-serif; color: #33275b; background: white; font-weight: normal; border-bottom: 2px solid #80c254 }
+hr { color: #80c254; background: white; }
diff --git a/src/java/com/martiansoftware/jsap/CommandLineTokenizer.java b/src/java/com/martiansoftware/jsap/CommandLineTokenizer.java
new file mode 100644
index 0000000..0af56fd
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/CommandLineTokenizer.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import java.util.List;
+/**
+ * <p>A utility class to parse a command line contained in a single String into
+ * an array of argument tokens, much as the JVM (or more accurately, your
+ * operating system) does before calling your programs' <code>public static
+ * void main(String[] args)</code>
+ * methods.</p>
+ *
+ * <p>This class has been developed to parse the command line in the same way
+ * that MS Windows 2000 does. Arguments containing spaces should be enclosed
+ * in quotes. Quotes that should be in the argument string should be escaped
+ * with a preceding backslash ('\') character. Backslash characters that
+ * should be in the argument string should also be escaped with a preceding
+ * backslash character.</p>
+ *
+ * Whenever <code>JSAP.parse(String)</code> is called, the specified String is
+ * tokenized by this class, then forwarded to <code>JSAP.parse(String[])</code>
+ * for further processing.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.JSAP#parse(String)
+ * @see com.martiansoftware.jsap.JSAP#parse(String[])
+ */
+public class CommandLineTokenizer {
+
+ /**
+ * Hide the constructor.
+ */
+ private CommandLineTokenizer() {
+ }
+
+ /**
+ * Goofy internal utility to avoid duplicated code. If the specified
+ * StringBuffer is not empty, its contents are appended to the resulting
+ * array (temporarily stored in the specified ArrayList). The StringBuffer
+ * is then emptied in order to begin storing the next argument.
+ * @param resultBuffer the List temporarily storing the resulting
+ * argument array.
+ * @param buf the StringBuffer storing the current argument.
+ */
+ private static void appendToBuffer(
+ List resultBuffer,
+ StringBuffer buf) {
+ if (buf.length() > 0) {
+ resultBuffer.add(buf.toString());
+ buf.setLength(0);
+ }
+ }
+
+ /**
+ * Parses the specified command line into an array of individual arguments.
+ * Arguments containing spaces should be enclosed in quotes.
+ * Quotes that should be in the argument string should be escaped with a
+ * preceding backslash ('\') character. Backslash characters that should
+ * be in the argument string should also be escaped with a preceding
+ * backslash character.
+ * @param commandLine the command line to parse
+ * @return an argument array representing the specified command line.
+ */
+ public static String[] tokenize(String commandLine) {
+ List resultBuffer = new java.util.ArrayList();
+
+ if (commandLine != null) {
+ int z = commandLine.length();
+ boolean insideQuotes = false;
+ StringBuffer buf = new StringBuffer();
+
+ for (int i = 0; i < z; ++i) {
+ char c = commandLine.charAt(i);
+ if (c == '"') {
+ appendToBuffer(resultBuffer, buf);
+ insideQuotes = !insideQuotes;
+ } else if (c == '\\') {
+ if ((z > i + 1)
+ && ((commandLine.charAt(i + 1) == '"')
+ || (commandLine.charAt(i + 1) == '\\'))) {
+ buf.append(commandLine.charAt(i + 1));
+ ++i;
+ } else {
+ buf.append("\\");
+ }
+ } else {
+ if (insideQuotes) {
+ buf.append(c);
+ } else {
+ if (Character.isWhitespace(c)) {
+ appendToBuffer(resultBuffer, buf);
+ } else {
+ buf.append(c);
+ }
+ }
+ }
+ }
+ appendToBuffer(resultBuffer, buf);
+
+ }
+
+ String[] result = new String[resultBuffer.size()];
+ return ((String[]) resultBuffer.toArray(result));
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/DefaultSource.java b/src/java/com/martiansoftware/jsap/DefaultSource.java
new file mode 100644
index 0000000..b17a200
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/DefaultSource.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+/**
+ * An interface describing an object as being able to produce a set of default
+ * values.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.Defaults
+ */
+public interface DefaultSource {
+
+ /**
+ * Returns a set of default values given the configuration described by the
+ * specified IDMap. Any encountered exceptions are stored in the specified
+ * JSAPResult.
+ * @param idMap an IDMap containing JSAP configuration information.
+ * @param exceptionMap the ExceptionMap object within which any Exceptions
+ * will be returned.
+ * @return a set of default values given the configuration described by the
+ * specified IDMap.
+ * @see com.martiansoftware.jsap.ExceptionMap#addException(String,Exception)
+ */
+ Defaults getDefaults(IDMap idMap, ExceptionMap exceptionMap);
+
+}
diff --git a/src/java/com/martiansoftware/jsap/Defaults.java b/src/java/com/martiansoftware/jsap/Defaults.java
new file mode 100644
index 0000000..6b6a180
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/Defaults.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * Stores a collection of default values, associated with their respective
+ * parameters by the parameters' unique IDs.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class Defaults {
+
+ /**
+ * Hashmap associating arrays of Strings (containing default values) with
+ * parameter IDs.
+ */
+ private HashMap defaults = null;
+
+ /**
+ * Creates a new, empty Defaults object.
+ */
+ public Defaults() {
+ defaults = new HashMap();
+ }
+
+ /**
+ * Sets a single default value for the parameter with the specified ID.
+ * This replaces any default values currently associated with the specified
+ * parameter if any exist.
+ * @param paramID the unique ID of the parameter for which the specified
+ * value is the default.
+ * @param defaultValue the new default value for the specified parameter.
+ */
+ public void setDefault(String paramID, String defaultValue) {
+ String[] newArray = new String[1];
+ newArray[0] = defaultValue;
+ setDefault(paramID, newArray);
+ }
+
+ /**
+ * Sets an array of default values for the parameter with the specified ID.
+ * These replace any default values currently associated with the specified
+ * parameter if any exist.
+ * @param paramID the unique ID of the parameter for which the specified
+ * values are the defaults.
+ * @param defaultValue the new default values for the specified parameter.
+ */
+ public void setDefault(String paramID, String[] defaultValue) {
+ defaults.put(paramID, defaultValue);
+ }
+
+ /**
+ * Adds a single default value to any that might already be defined for the
+ * parameter with the the specified ID.
+ * @param paramID the unique ID of the parameter for which the specified
+ * value is an additional default.
+ * @param defaultValue the default value to add to the specified parameter.
+ */
+ public void addDefault(String paramID, String defaultValue) {
+ String[] newArray = new String[1];
+ newArray[0] = defaultValue;
+ addDefault(paramID, newArray);
+ }
+
+ /**
+ * Adds an array of default values to any that might already be defined for
+ * the parameter with the the specified ID.
+ * @param paramID the unique ID of the parameter for which the specified
+ * value is an additional default.
+ * @param defaultValue the default values to add to the specified parameter.
+ */
+ public void addDefault(String paramID, String[] defaultValue) {
+ String[] curDefault = getDefault(paramID);
+ if (curDefault == null) {
+ curDefault = new String[0];
+ }
+ String[] newDefault =
+ new String[curDefault.length + defaultValue.length];
+ int index = 0;
+ for (int i = 0; i < curDefault.length; ++i) {
+ newDefault[index] = curDefault[i];
+ ++index;
+ }
+ for (int i = 0; i < defaultValue.length; ++i) {
+ newDefault[index] = defaultValue[i];
+ ++index;
+ }
+ setDefault(paramID, newDefault);
+ }
+
+ /**
+ * Sets a single default value for the parameter with the specified ID if
+ * and only if the specified parameter currently has no default values.
+ * @param paramID the unique ID of the parameter for which the specified
+ * value is the default.
+ * @param defaultValue the new default value for the specified parameter.
+ */
+ protected void setDefaultIfNeeded(String paramID, String defaultValue) {
+ if (!defaults.containsKey(paramID)) {
+ setDefault(paramID, defaultValue);
+ }
+ }
+
+ /**
+ * Sets an array of default values for the parameter with the specified ID
+ * if and only if the specified parameter currently has no default values.
+ * @param paramID the unique ID of the parameter for which the specified
+ * value is the default.
+ * @param defaultValue the new default values for the specified parameter.
+ */
+ protected void setDefaultIfNeeded(String paramID, String[] defaultValue) {
+ if (!defaults.containsKey(paramID)) {
+ setDefault(paramID, defaultValue);
+ }
+ }
+
+ /**
+ * Returns an array of the default values defined for the parameter with
+ * the specified ID, or null if no default values are defined.
+ * @param paramID the unique ID of the parameter for which default values
+ * are desired.
+ * @return an array of the default values defined for the parameter with
+ * the specified ID, or null if no default values are defined.
+ */
+ public String[] getDefault(String paramID) {
+ return ((String[]) defaults.get(paramID));
+ }
+
+ /**
+ * Returns an Iterator over the unique IDs of all parameters with defaults
+ * defined in this Defaults object.
+ * @return an Iterator over the unique IDs of all parameters with defaults
+ * defined in this Defaults object.
+ * @see java.util.Iterator
+ */
+ public Iterator idIterator() {
+ return (defaults.keySet().iterator());
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/ExceptionMap.java b/src/java/com/martiansoftware/jsap/ExceptionMap.java
new file mode 100644
index 0000000..d04eb4f
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/ExceptionMap.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+/**
+ * A class for aggregating exceptions thrown by JSAP's parsing process. This
+ * class is necessary as it is desirable to have information regarding ALL of
+ * the reasons for a failed parse rather than just the FIRST reason.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public interface ExceptionMap {
+
+ /**
+ * Adds the specified exception to the exception map. Exceptions are
+ * keyed by the ID of the parameters with which they are associated.
+ * "General" exceptions not associated with a particular parameter have a
+ * null key.
+ * @param id the unique ID of the parameter with which the specified values
+ * are associated.
+ * @param exception the exception to associate with the specified key.
+ */
+ void addException(String id, Exception exception);
+
+ /**
+ * Returns the first exception associated with the specified parameter ID.
+ * "General" exceptions can be retrieved with a null id. If no exceptions
+ * are associated with the specified parameter ID, null is returned.
+ * @param id the unique ID of the parameter for which the first exception
+ * is requested
+ * @return the first exception associated with the specified ID, or null if
+ * no exceptions are associated with the specified ID.
+ */
+ Exception getException(String id);
+
+ /**
+ * Returns an array of ALL exceptions associated with the specified
+ * parameter ID. If no exceptions are associated with the specified
+ * parameter ID, an empty (zero-length) array is returned.
+ * @param id the unique ID of the parameter for which the exceptions are
+ * requested.
+ * @return an array of ALL exceptions associated with the specified
+ * parameter ID,
+ * or an empty (zero-length) array if no exceptions are associated with the
+ * specified parameter ID.
+ */
+ Exception[] getExceptionArray(String id);
+
+}
diff --git a/src/java/com/martiansoftware/jsap/Flagged.java b/src/java/com/martiansoftware/jsap/Flagged.java
new file mode 100644
index 0000000..1f2503c
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/Flagged.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+/**
+ * <p>Marks an argument as being "flagged" - that is, as having its value on the
+ * command line preceded by an indicator. Flagged arguments can be preceded by
+ * a "short flag," a hyphen followed by a single character, or a "long flag,"
+ * two hyphens followed by a word.</p>
+ *
+ * <p>For example, a short flag 'i' marking an option as meaning "input file"
+ * might result in a command line that contains the substring "-i myfile.txt" or
+ * "-i=myfile.txt", whereas the same option with a long flag of "inputfile"
+ * might contain a substring such as "--inputfile myfile.txt" or
+ * "--inputfile=myfile.txt"</p>
+ *
+ * Note that the setter methods setShortFlag() and setLongFlag() are not
+ * part of this Interface. This is because including them would prevent the
+ * setShortFlag() and setLongFlag() methods in FlaggedOption and Switch from
+ * returning references to themselves, which is inconvenient and inconsistent
+ * with the rest of the API.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.Switch
+ * @see com.martiansoftware.jsap.FlaggedOption
+ */
+public interface Flagged {
+
+ // /**
+ // * Sets the short flag for this object.
+ // * @param shortFlag the new short flag for this object.
+ // * @return the modified Flagged object.
+ // */
+ // Flagged setShortFlag(char shortFlag);
+
+ /**
+ * Returns the short flag for this object in the form of a char.
+ * @return the short flag for this object in the form of a char.
+ */
+ char getShortFlag();
+
+ /**
+ * Returns the short flag for this object in the form of a Character.
+ * @return the short flag for this object in the form of a Character.
+ */
+ Character getShortFlagCharacter();
+
+ // /**
+ // * Sets the long flag for this object.
+ // * @param longFlag the new long flag for this object.
+ // * @return the modified Flagged object.
+ // */
+ // Flagged setLongFlag(String longFlag);
+
+ /**
+ * Returns the long flag for this object.
+ * @return the long flag for this object.
+ */
+ String getLongFlag();
+
+}
diff --git a/src/java/com/martiansoftware/jsap/FlaggedOption.java b/src/java/com/martiansoftware/jsap/FlaggedOption.java
new file mode 100644
index 0000000..0a220e6
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/FlaggedOption.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+/**
+ * An option that implements the Flagged interface. A flagged option is
+ * preceded by a short flag or a long flag; i.e. "-n 5" or "--number 5".
+ * FlaggedOptions also provide an additional features over unflagged
+ * options, namely the ability to be declared more than once in a command line
+ * (e.g., "-n 5 -n 10"). This is not possible with unflagged options, as they
+ * are never declared.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.Flagged
+ * @see com.martiansoftware.jsap.Option
+ */
+public class FlaggedOption extends Option implements Flagged {
+
+ /**
+ * The current short flag for this FlaggedOption. Default is
+ * JSAP.NO_SHORTFLAG.
+ */
+ private char shortFlag = JSAP.NO_SHORTFLAG;
+
+ /**
+ * The current long flag for this FlaggedOption. Default is
+ * JSAP.NO_LONGLAG.
+ */
+ private String longFlag = JSAP.NO_LONGFLAG;
+
+ /**
+ * If true, this FlaggedOption may be declared more than once on a
+ * command line.
+ * Default is JSAP.NO_MULTIPLEDECLARATIONS.
+ */
+ private boolean allowMultipleDeclarations = JSAP.NO_MULTIPLEDECLARATIONS;
+
+ /**
+ * Creates a new FlaggedOption with the specified unique ID.
+ * @param id the unique ID for this FlaggedOption.
+ */
+ public FlaggedOption(String id) {
+ super(id);
+ }
+
+ /**
+ * A shortcut constructor that creates a new FlaggedOption and configures
+ * its most commonly used settings, including help.
+ * @param id the unique ID for this FlaggedOption.
+ * @param stringParser the StringParser this FlaggedOption should use.
+ * @param defaultValue the default value for this FlaggedOption (may be
+ * null).
+ * @param required if true, this FlaggedOption is required.
+ * @param shortFlag the short flag for this option (may be set to
+ * JSAP.NO_SHORTFLAG for none).
+ * @param longFlag the long flag for this option (may be set to
+ * JSAP.NO_LONGFLAG for none).
+ * @param help the help text for this option (may be set to {@link JSAP#NO_HELP} for none).
+ */
+ public FlaggedOption(
+ String id,
+ StringParser stringParser,
+ String defaultValue,
+ boolean required,
+ char shortFlag,
+ String longFlag,
+ String help) {
+ this(id);
+ setStringParser(stringParser);
+ setDefault(defaultValue);
+ setShortFlag(shortFlag);
+ setLongFlag(longFlag);
+ setRequired(required);
+ setHelp(help);
+ }
+
+ /**
+ * A shortcut constructor that creates a new FlaggedOption and configures
+ * its most commonly used settings.
+ * @param id the unique ID for this FlaggedOption.
+ * @param stringParser the StringParser this FlaggedOption should use.
+ * @param defaultValue the default value for this FlaggedOption (may be
+ * null).
+ * @param required if true, this FlaggedOption is required.
+ * @param shortFlag the short flag for this option (may be set to
+ * JSAP.NO_SHORTFLAG for none).
+ * @param longFlag the long flag for this option (may be set to
+ * JSAP.NO_LONGFLAG for none).
+ */
+ public FlaggedOption(
+ String id,
+ StringParser stringParser,
+ String defaultValue,
+ boolean required,
+ char shortFlag,
+ String longFlag) {
+ this(id, stringParser, defaultValue, required, shortFlag, longFlag, JSAP.NO_HELP);
+ }
+
+
+ /**
+ * Sets the short flag for this FlaggedOption. To use no short flag at all,
+ * set the value to JSAP.NO_SHORTFLAG.
+ * @param shortFlag the short flag for this FlaggedOption.
+ * @return the modified FlaggedOption
+ */
+ public FlaggedOption setShortFlag(char shortFlag) {
+ enforceParameterLock();
+ this.shortFlag = shortFlag;
+ return (this);
+ }
+
+ /**
+ * Returns the short flag for this FlaggedOption. If this FlaggedOption
+ * has no short flag, the
+ * return value will be equal to JSAP.NO_SHORTFLAG.
+ * @return the short flag for this FlaggedOption. If this FlaggedOption
+ * has no short flag, the
+ * return value will be equal to JSAP.NO_SHORTFLAG.
+ */
+ public char getShortFlag() {
+ return (shortFlag);
+ }
+
+ /**
+ * Returns the short flag for this FlaggedOption. If this FlaggedOption
+ * has no short flag, the
+ * return value will be null.
+ * @return the short flag for this FlaggedOption. If this FlaggedOption
+ * has no short flag, the
+ * return value will be null.
+ */
+ public Character getShortFlagCharacter() {
+ return (
+ (shortFlag == JSAP.NO_SHORTFLAG) ? null : new Character(shortFlag));
+ }
+
+ /**
+ * Sets the long flag for this FlaggedOption. To use no long flag at all,
+ * set the value to JSAP.NO_LONGFLAG.
+ * @param longFlag the long flag for this FlaggedOption.
+ * @return the modified FlaggedOption
+ */
+ public FlaggedOption setLongFlag(String longFlag) {
+ enforceParameterLock();
+ this.longFlag = longFlag;
+ return (this);
+ }
+
+ /**
+ * Sets the name that will be displayed when getSyntax() is called
+ * @param usageName the name to use, or null if the id should be used (default)
+ * @return the modified FlaggedOption
+ */
+ public FlaggedOption setUsageName(String usageName) {
+ _setUsageName(usageName);
+ return (this);
+ }
+
+ /**
+ * Returns the long flag for this FlaggedOption. If this FlaggedOption has
+ * no long flag, the return
+ * value will be equal to JSAP.NO_LONGFLAG.
+ * @return the long flag for this FlaggedOption. If this FlaggedOption has
+ * no long flag, the return
+ * value will be equal to JSAP.NO_LONGFLAG.
+ */
+ public String getLongFlag() {
+ return (longFlag);
+ }
+
+ /**
+ * <p>Sets this FlaggedOption to allow or disallow multiple declarations.
+ * If multiple declarations are allowed,
+ * the flag may be specified multiple times on the command line (e.g.,
+ * "-n 5 -n 10"). All of the results
+ * are aggregated in the resulting JSAPResult.</p>
+ *
+ * <p>Default behavior is to disallow multiple declarations.</p>
+ * @param allowMultipleDeclarations if true, multiple declarations are
+ * allowed.
+ * @return the modified FlaggedOption
+ */
+ public FlaggedOption setAllowMultipleDeclarations(
+ boolean allowMultipleDeclarations) {
+ enforceParameterLock();
+ this.allowMultipleDeclarations = allowMultipleDeclarations;
+ return (this);
+ }
+
+ /**
+ * Returns a boolean indicating whether multiple declarations are allowed
+ * for this FlaggedOption.
+ * @return a boolean indicating whether multiple declarations are allowed
+ * for this FlaggedOption.
+ * @see #setAllowMultipleDeclarations(boolean)
+ */
+ public boolean allowMultipleDeclarations() {
+ return (allowMultipleDeclarations);
+ }
+
+ /**
+ * Returns syntax instructions for this FlaggedOption.
+ * @return syntax instructions for this FlaggedOption based upon its current
+ * configuration.
+ */
+ public String getSyntax() {
+ StringBuffer result = new StringBuffer();
+ if (!required()) {
+ result.append("[");
+ }
+
+ if ((getLongFlag() != JSAP.NO_LONGFLAG)
+ || (getShortFlag() != JSAP.NO_SHORTFLAG)) {
+ if (getLongFlag() == JSAP.NO_LONGFLAG) {
+ result.append("-" + getShortFlag() + JSAP.SYNTAX_SPACECHAR);
+ } else if (getShortFlag() == JSAP.NO_SHORTFLAG) {
+ result.append("--" + getLongFlag() + JSAP.SYNTAX_SPACECHAR);
+ } else {
+ result.append(
+ "(-" + getShortFlag() + "|--" + getLongFlag() + ")" + JSAP.SYNTAX_SPACECHAR);
+ }
+ }
+ String un = getUsageName();
+ char sep = this.getListSeparator();
+ if (this.isList()) {
+ result.append(
+ un + "1" + sep + un + "2" + sep + "..." + sep + un + "N ");
+ } else {
+ result.append("<" + getUsageName() + ">");
+ }
+ if (!required()) {
+ result.append("]");
+ }
+ return (result.toString());
+ }
+
+ /**
+ * Sets whether this FlaggedOption is a list. Default behavior is
+ * JSAP.NOT_LIST.
+ * @param isList if true, this Option is a list.
+ * @return the modified FlaggedOption
+ */
+ public FlaggedOption setList(boolean isList) {
+ super.internalSetList(isList);
+ return (this);
+ }
+
+ /**
+ * Sets the list separator character for this FlaggedOption. The default
+ * list separator is JSAP.DEFAULT_LISTSEPARATOR.
+ * @param listSeparator the list separator for this Option.
+ * @return the modified FlaggedOption
+ */
+ public FlaggedOption setListSeparator(char listSeparator) {
+ super.internalSetListSeparator(listSeparator);
+ return (this);
+ }
+
+ /**
+ * Sets whether this FlaggedOption is required. Default is
+ * JSAP.NOT_REQUIRED.
+ * @param required if true, this Option will be required.
+ * @return the modified FlaggedOption
+ */
+ public FlaggedOption setRequired(boolean required) {
+ super.internalSetRequired(required);
+ return (this);
+ }
+
+ /**
+ * Sets one or more default values for this parameter. This method
+ * should be used whenever a parameter has more than one default
+ * value.
+ * @param defaultValues the default values for this parameter.
+ * @see #setDefault(String)
+ */
+ public FlaggedOption setDefault(String[] defaultValues) {
+ _setDefault(defaultValues);
+ return (this);
+ }
+
+ /**
+ * Sets a default value for this parameter. The default is specified
+ * as a String, and is parsed as a single value specified on the
+ * command line. In other words, default values for "list"
+ * parameters or parameters allowing multiple declarations should be
+ * set using setDefault(String[]), as JSAP
+ * would otherwise treat the entire list of values as a single value.
+ *
+ * @param defaultValue the default value for this parameter.
+ * @see #setDefault(String)
+ */
+ public FlaggedOption setDefault(String defaultValue) {
+ _setDefault(defaultValue);
+ return (this);
+ }
+
+ /**
+ * Sets the StringParser to which this FlaggedOption's parse() method
+ * should delegate.
+ * @param stringParser the StringParser to which this Option's parse()
+ * method should delegate.
+ * @see com.martiansoftware.jsap.StringParser
+ * @return the modified FlaggedOption
+ */
+ public FlaggedOption setStringParser(StringParser stringParser) {
+ super.internalSetStringParser(stringParser);
+ return (this);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/IDMap.java b/src/java/com/martiansoftware/jsap/IDMap.java
new file mode 100644
index 0000000..5e0326d
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/IDMap.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A utility class to allow lookups of parameter IDs by short flag or long flag.
+ * This class is used by DefaultSource in order to populate Defaults objects.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.Flagged
+ * @see com.martiansoftware.jsap.DefaultSource
+ * @see com.martiansoftware.jsap.Defaults
+ */
+public class IDMap {
+
+ /**
+ * A list of the unique IDs of all the parameters stored in this IDMap.
+ */
+ private List ids = null;
+
+ /**
+ * A Map associating short flags with parameter IDs.
+ */
+ private Map byShortFlag = null;
+
+ /**
+ * A Map associating long flags with parameter IDs.
+ */
+ private Map byLongFlag = null;
+
+ /**
+ * Creates a new IDMap.
+ * @param ids a List of the unique IDs of all the parameters to store
+ * in this IDMap.
+ * @param byShortFlag a Map with keys equal to the short flags of the
+ * parameters (as Character objects),
+ * and values equal to the unique IDs of the parameters associated with
+ * those short flags.
+ * @param byLongFlag a Map with keys equal to the long flags of the
+ * parameters (as Strings),
+ * and values equal to the unique IDs of the parameters associated with
+ * those short flags.
+ */
+ public IDMap(List ids, Map byShortFlag, Map byLongFlag) {
+ this.ids = new java.util.ArrayList(ids);
+ this.byShortFlag = new java.util.HashMap(byShortFlag);
+ this.byLongFlag = new java.util.HashMap(byLongFlag);
+ }
+
+ /**
+ * Returns an Iterator over all parameter IDs stored in this IDMap.
+ * @return an Iterator over all parameter IDs stored in this IDMap.
+ * @see java.util.Iterator
+ */
+ public Iterator idIterator() {
+ return (ids.iterator());
+ }
+
+ /**
+ * Returns true if the specified ID is stored in this IDMap, false if not.
+ * @param id the id to search for in this IDMap
+ * @return true if the specified ID is stored in this IDMap, false if not.
+ */
+ public boolean idExists(String id) {
+ return (ids.contains(id));
+ }
+
+ /**
+ * Returns the unique ID of the parameter with the specified short flag, or
+ * null if the specified short flag is not defined in this IDMap.
+ * @param c the short flag to search for in this IDMap.
+ * @return the unique ID of the parameter with the specified short flag, or
+ * null if the specified short flag is not defined in this IDMap.
+ */
+ public String getIDByShortFlag(Character c) {
+ return ((String) byShortFlag.get(c));
+ }
+
+ /**
+ * Returns the unique ID of the parameter with the specified short flag, or
+ * null if the specified short flag is not defined in this IDMap.
+ * @param c the short flag to search for in this IDMap.
+ * @return the unique ID of the parameter with the specified short flag, or
+ * null if the specified short flag is not defined in this IDMap.
+ */
+ public String getIDByShortFlag(char c) {
+ return (getIDByShortFlag(new Character(c)));
+ }
+
+ /**
+ * Returns the unique ID of the parameter with the specified long flag, or
+ * null if the specified long flag is not defined in this IDMap.
+ * @param s the long flag to search for in this IDMap.
+ * @return the unique ID of the parameter with the specified long flag, or
+ * null if the specified long flag is not defined in this IDMap.
+ */
+ public String getIDByLongFlag(String s) {
+ return ((String) byLongFlag.get(s));
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/IllegalMultipleDeclarationException.java b/src/java/com/martiansoftware/jsap/IllegalMultipleDeclarationException.java
new file mode 100644
index 0000000..d8a7247
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/IllegalMultipleDeclarationException.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+/**
+ * An exception indicating that a parameter has illegally been declared multiple
+ * times.
+ *
+ * @see
+ * com.martiansoftware.jsap.FlaggedOption#setAllowMultipleDeclarations(boolean)
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.Flagged
+ * @see com.martiansoftware.jsap.Option
+ */
+public class IllegalMultipleDeclarationException extends JSAPException {
+
+ /**
+ * The unique ID of the parameter that was illegally declared more than
+ * once.
+ */
+ private String id = null;
+
+ /**
+ * Creates a new IllegalMultipleDeclarationException referencing the
+ * specified parameter.
+ * @param paramID the unique ID of the parameter that was illegally declared
+ * more than once.
+ */
+ public IllegalMultipleDeclarationException(String paramID) {
+ super("Parameter '" + paramID + "' cannot be declared more than once.");
+ this.id = paramID;
+ }
+
+ /**
+ * Returns the unique ID of the parameter that was illegally declared more
+ * than once.
+ * @return the unique ID of the parameter that was illegally declared more
+ * than once.
+ */
+ public String getID() {
+ return (this.id);
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/JSAP.java b/src/java/com/martiansoftware/jsap/JSAP.java
new file mode 100644
index 0000000..0b6162d
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/JSAP.java
@@ -0,0 +1,862 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Map;
+import java.util.List;
+import java.util.Iterator;
+
+import com.martiansoftware.jsap.stringparsers.BigDecimalStringParser;
+import com.martiansoftware.jsap.stringparsers.BigIntegerStringParser;
+import com.martiansoftware.jsap.stringparsers.BooleanStringParser;
+import com.martiansoftware.jsap.stringparsers.ByteStringParser;
+import com.martiansoftware.jsap.stringparsers.CharacterStringParser;
+import com.martiansoftware.jsap.stringparsers.ClassStringParser;
+import com.martiansoftware.jsap.stringparsers.ColorStringParser;
+import com.martiansoftware.jsap.stringparsers.DoubleStringParser;
+import com.martiansoftware.jsap.stringparsers.FloatStringParser;
+import com.martiansoftware.jsap.stringparsers.InetAddressStringParser;
+import com.martiansoftware.jsap.stringparsers.IntSizeStringParser;
+import com.martiansoftware.jsap.stringparsers.IntegerStringParser;
+import com.martiansoftware.jsap.stringparsers.LongSizeStringParser;
+import com.martiansoftware.jsap.stringparsers.LongStringParser;
+import com.martiansoftware.jsap.stringparsers.PackageStringParser;
+import com.martiansoftware.jsap.stringparsers.ShortStringParser;
+import com.martiansoftware.jsap.stringparsers.StringStringParser;
+import com.martiansoftware.jsap.stringparsers.URLStringParser;
+import com.martiansoftware.jsap.xml.JSAPConfig;
+import com.martiansoftware.util.StringUtils;
+
+/**
+ * The core class of the JSAP (Java Simple Argument Parser) API.
+ *
+ * <p>A JSAP is responsible for converting an array of Strings, typically
+ * received from a command line in the main class' main() method, into a
+ * collection of Objects that are retrievable by a unique ID assigned by the
+ * developer.</p>
+ *
+ * <p>Before a JSAP parses a command line, it is configured with the Switches,
+ * FlaggedOptions, and UnflaggedOptions it will accept. As a result, the
+ * developer can rest assured that if no Exceptions are thrown by the JSAP's
+ * parse() method, the entire command line was parsed successfully.</p>
+ *
+ * <p>For example, to parse a command line with the syntax "[--verbose]
+ * {-n|--number} Mynumber", the following code could be used:</p.
+ *
+ * <code><pre>
+ * JSAP myJSAP = new JSAP();
+ * myJSAP.registerParameter( new Switch( "verboseSwitch", JSAP.NO_SHORTFLAG,
+ * "verbose" ) );
+ * myJSAP.registerParameter( new FlaggedOption( "numberOption", new
+ * IntegerStringParser(), JSAP.NO_DEFAULT,
+ * JSAP.NOT_REQUIRED, 'n', "number" ) );
+ * JSAPResult result = myJSAP.parse(args);
+ * </pre></code>
+ *
+ * <p>The results of the parse could then be obtained with:</p>
+ *
+ * <code><pre>
+ * int n = result.getInt("numberOption");
+ * boolean isVerbose = result.getBoolean("verboseSwitch");
+ * </pre></code>
+ *
+ * <h3>Generating a JSAP from ANT</h3>
+ * <p>If you don't want to register all your parameters manually as shown
+ * above, the JSAP API provides a custom ANT task that will generate a
+ * custom JSAP subclass to suit your needs. See
+ * com.martiansoftware.jsap.ant.JSAPAntTask for details.</p>
+ * <p>See the accompanying documentation for examples and further information.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @author Klaus Berg (bug fixes in help generation)
+ * @author Wolfram Esser (contributed code for custom line separators in help)
+ * @see com.martiansoftware.jsap.ant.JSAPAntTask
+ */
+public class JSAP {
+
+ /**
+ * Map of this JSAP's AbstractParameters keyed on their unique ID.
+ */
+ private Map paramsByID = null;
+
+ /**
+ * Map of this JSAP's AbstractParameters keyed on their short flag.
+ */
+ private Map paramsByShortFlag = null;
+
+ /**
+ * Map of this JSAP's AbstractParameters keyed on their long flag.
+ */
+ private Map paramsByLongFlag = null;
+
+ /**
+ * List of this JSAP's UnflaggedOptions, in order of declaration.
+ */
+ private List unflaggedOptions = null;
+
+ /**
+ * List of all of this JSAP's AbstractParameters, in order of
+ * declaration.
+ */
+ private List paramsByDeclarationOrder = null;
+
+ /**
+ * List of all of this JSAP's DefaultSources, in order of declaration.
+ */
+ private List defaultSources = null;
+
+ /**
+ * If not null, overrides the automatic usage info.
+ */
+ private String usage = null;
+
+ /**
+ * If not null, overrides the automatic help info.
+ */
+ private String help = null;
+
+ /**
+ * Does not have a short flag.
+ *
+ * @see com.martiansoftware.jsap.FlaggedOption
+ * @see com.martiansoftware.jsap.UnflaggedOption
+ */
+ public static final char NO_SHORTFLAG = '\0';
+
+ /**
+ * Does not have a long flag.
+ *
+ * @see com.martiansoftware.jsap.FlaggedOption
+ * @see com.martiansoftware.jsap.UnflaggedOption
+ */
+ public static final String NO_LONGFLAG = null;
+
+ /**
+ * The default separator for list parameters (equivalent to
+ * java.io.File.pathSeparatorChar)
+ *
+ * @see FlaggedOption#setListSeparator(char)
+ */
+ public static final char DEFAULT_LISTSEPARATOR =
+ java.io.File.pathSeparatorChar;
+
+ /**
+ * The default separator between parameters in generated help (a newline
+ * by default)
+ */
+ public static final String DEFAULT_PARAM_HELP_SEPARATOR = "\n";
+
+ /**
+ * The parameter is required.
+ *
+ * @see FlaggedOption#setRequired(boolean)
+ */
+ public static final boolean REQUIRED = true;
+
+ /**
+ * The parameter is not required.
+ *
+ * @see FlaggedOption#setRequired(boolean)
+ */
+ public static final boolean NOT_REQUIRED = false;
+
+ /**
+ * The parameter is a list.
+ *
+ * @see FlaggedOption#setList(boolean)
+ */
+ public static final boolean LIST = true;
+
+ /**
+ * The parameter is not a list.
+ *
+ * @see FlaggedOption#setList(boolean)
+ */
+ public static final boolean NOT_LIST = false;
+
+ /**
+ * The parameter allows multiple declarations.
+ *
+ * @see FlaggedOption#setAllowMultipleDeclarations(boolean)
+ */
+ public static final boolean MULTIPLEDECLARATIONS = true;
+
+ /**
+ * The parameter does not allow multiple declarations.
+ *
+ * @see FlaggedOption#setAllowMultipleDeclarations(boolean)
+ */
+ public static final boolean NO_MULTIPLEDECLARATIONS = false;
+
+ /**
+ * The parameter consumes the command line.
+ *
+ * @see com.martiansoftware.jsap.UnflaggedOption#setGreedy(boolean)
+ */
+ public static final boolean GREEDY = true;
+
+ /**
+ * The parameter does not consume the command line.
+ *
+ * @see com.martiansoftware.jsap.UnflaggedOption#setGreedy(boolean)
+ */
+ public static final boolean NOT_GREEDY = false;
+
+ /** The parameter has no default value.
+ */
+ public static final String NO_DEFAULT = null;
+
+ /**
+ * The parameter has no help text.
+ *
+ * @see com.martiansoftware.jsap.Parameter#setHelp(String)
+ */
+ public static final String NO_HELP = null;
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.BigDecimalStringParser}.
+ */
+
+ public static final BigDecimalStringParser BIGDECIMAL_PARSER = BigDecimalStringParser.getParser();
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.BigIntegerStringParser}.
+ */
+
+ public static final BigIntegerStringParser BIGINTEGER_PARSER = BigIntegerStringParser.getParser();
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.BooleanStringParser}.
+ */
+
+ public static final BooleanStringParser BOOLEAN_PARSER = BooleanStringParser.getParser();
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.ByteStringParser}.
+ */
+
+ public static final ByteStringParser BYTE_PARSER = ByteStringParser.getParser();
+
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.CharacterStringParser}.
+ */
+
+ public static final CharacterStringParser CHARACTER_PARSER = CharacterStringParser.getParser();
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.ClassStringParser}.
+ */
+
+ public static final ClassStringParser CLASS_PARSER = ClassStringParser.getParser();
+
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.ColorStringParser}.
+ */
+
+ public static final ColorStringParser COLOR_PARSER = ColorStringParser.getParser();
+
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.DoubleStringParser}.
+ */
+
+ public static final DoubleStringParser DOUBLE_PARSER = DoubleStringParser.getParser();
+
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.FloatStringParser}.
+ */
+
+ public static final FloatStringParser FLOAT_PARSER = FloatStringParser.getParser();
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.InetAddressStringParser}.
+ */
+
+ public static final InetAddressStringParser INETADDRESS_PARSER = InetAddressStringParser.getParser();
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.IntegerStringParser}.
+ */
+
+ public static final IntegerStringParser INTEGER_PARSER = IntegerStringParser.getParser();
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.IntSizeStringParser}.
+ */
+
+ public static final IntSizeStringParser INTSIZE_PARSER = IntSizeStringParser.getParser();
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.LongSizeStringParser}.
+ */
+
+ public static final LongSizeStringParser LONGSIZE_PARSER = LongSizeStringParser.getParser();
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.LongStringParser}.
+ */
+
+ public static final LongStringParser LONG_PARSER = LongStringParser.getParser();
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.PackageStringParser}.
+ */
+
+ public static final PackageStringParser PACKAGE_PARSER = PackageStringParser.getParser();
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.ShortStringParser}.
+ */
+
+ public static final ShortStringParser SHORT_PARSER = ShortStringParser.getParser();
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.StringStringParser}.
+ */
+
+ public static final StringStringParser STRING_PARSER = StringStringParser.getParser();
+
+ /**
+ * The only instance of a {@link com.martiansoftware.jsap.stringparsers.URLStringParser}.
+ */
+
+ public static final URLStringParser URL_PARSER = URLStringParser.getParser();
+
+ /**
+ * The default screen width used for formatting help.
+ */
+ public static final int DEFAULT_SCREENWIDTH = 80;
+
+ /**
+ * Temporary fix for bad console encodings screwing up non-breaking spaces.
+ */
+ static char SYNTAX_SPACECHAR = ' ';
+
+ static {
+ if (Boolean.valueOf(System.getProperty("com.martiansoftware.jsap.usenbsp", "false")).booleanValue()) {
+ SYNTAX_SPACECHAR = '\u00a0';
+ }
+ }
+
+ /**
+ * Creates a new JSAP with an empty configuration. It must be configured
+ * with registerParameter() before its parse() methods may be called.
+ */
+ public JSAP() {
+ init();
+ }
+
+ /**
+ * Creates a new JSAP configured as specified in the referenced xml.
+ * @param jsapXML reference to xml representation of the JSAP configuration
+ * @throws IOException if an I/O error occurs
+ * @throws JSAPException if the configuration is not valid
+ */
+ public JSAP(URL jsapXML) throws IOException, JSAPException {
+ init();
+ JSAPConfig.configure(this, jsapXML);
+ }
+
+ /**
+ * Creates a new JSAP configured as specified in the referenced xml.
+ * @param resourceName name of the resource (accessible via this JSAP's classloader)
+ * containing the xml representation of the JSAP configuration
+ * @throws IOException if an I/O error occurs
+ * @throws JSAPException if the configuration is not valid
+ */
+ public JSAP(String resourceName) throws IOException, JSAPException {
+ this(JSAP.class.getClassLoader().getResource(resourceName));
+ }
+
+ private void init() {
+ paramsByID = new java.util.HashMap();
+ paramsByShortFlag = new java.util.HashMap();
+ paramsByLongFlag = new java.util.HashMap();
+ unflaggedOptions = new java.util.ArrayList();
+ paramsByDeclarationOrder = new java.util.ArrayList();
+ defaultSources = new java.util.ArrayList();
+ }
+
+ /**
+ * Sets the usage string manually, overriding the automatically-
+ * generated String. To remove the override, call setUsage(null).
+ * @param usage the manually-set usage string.
+ */
+ public void setUsage(String usage) {
+ this.usage = usage;
+ }
+
+ /**
+ * Sets the help string manually, overriding the automatically-
+ * generated String. To remove the override, call setHelp(null).
+ * @param help the manualy-set help string.
+ */
+ public void setHelp(String help) {
+ this.help = help;
+ }
+
+ /**
+ * A shortcut method for calling getHelp(80, "\n").
+ * @see #getHelp(int,String)
+ * @return the same as gethelp(80, "\n")
+ */
+ public String getHelp() {
+ return (getHelp(DEFAULT_SCREENWIDTH, DEFAULT_PARAM_HELP_SEPARATOR));
+ }
+
+ /**
+ * A shortcut method for calling getHelp(screenWidth, "\n").
+ * @param screenWidth the screen width for which to format the help.
+ * @see #getHelp(int,String)
+ * @return the same as gethelp(screenWidth, "\n")
+ */
+ public String getHelp(int screenWidth) {
+ return (getHelp(screenWidth, DEFAULT_PARAM_HELP_SEPARATOR));
+ }
+
+ /**
+ * If the help text has been manually set, this method simply
+ * returns it, ignoring the screenWidth parameter. Otherwise,
+ * an automatically-formatted help message is returned, tailored
+ * to the specified screen width.
+ * @param screenWidth the screen width (in characters) for which
+ * the help text will be formatted. If zero, help will not be
+ * line-wrapped.
+ * @return complete help text for this JSAP.
+ */
+ public String getHelp(int screenWidth, String paramSeparator) {
+ String result = help;
+ if (result == null) {
+ StringBuffer buf = new StringBuffer();
+
+ // We'll wrap at screenWidth - 8
+ int wrapWidth = screenWidth - 8;
+
+ // now loop through all the params again and display their help info
+ for (Iterator i = paramsByDeclarationOrder.iterator();
+ i.hasNext();) {
+ Parameter param = (Parameter) i.next();
+ StringBuffer defaultText = new StringBuffer();
+ String[] defaultValue = param.getDefault();
+ if ( !(param instanceof Switch) && defaultValue != null ) {
+ defaultText.append(" (default: ");
+ for(int j = 0; j < defaultValue.length; j++ ) {
+ if (j > 0) defaultText.append( ", " );
+ defaultText.append(defaultValue[ j ]);
+ }
+ defaultText.append(")");
+ }
+ Iterator helpInfo =
+ StringUtils
+ .wrapToList(param.getHelp() + defaultText, wrapWidth)
+ .iterator();
+
+ buf.append(" "); // the two leading spaces
+ buf.append(param.getSyntax());
+ buf.append("\n");
+
+ while (helpInfo.hasNext()) {
+ buf.append(" ");
+ buf.append( helpInfo.next() );
+ buf.append("\n");
+ }
+ if (i.hasNext()) {
+ buf.append(paramSeparator);
+ }
+ }
+ result = buf.toString();
+ }
+ return (result);
+ }
+
+ /**
+ * Returns an automatically generated usage description based upon this
+ * JSAP's current configuration.
+ *
+ * @return an automatically generated usage description based upon this
+ * JSAP's current configuration.
+ */
+ public String getUsage() {
+ String result = usage;
+ if (result == null) {
+ StringBuffer buf = new StringBuffer();
+ for (Iterator i = paramsByDeclarationOrder.iterator();
+ i.hasNext();) {
+ Parameter param = (Parameter) i.next();
+ if (buf.length() > 0) {
+ buf.append(" ");
+ }
+ buf.append(param.getSyntax());
+ }
+ result = buf.toString();
+ }
+ return (result);
+ }
+
+ /**
+ * Returns an automatically generated usage description based upon this
+ * JSAP's current configuration. This returns exactly the same result
+ * as getUsage().
+ *
+ * @return an automatically generated usage description based upon this
+ * JSAP's current configuration.
+ */
+ public String toString() {
+ return (getUsage());
+ }
+
+ /**
+ * Returns an IDMap associating long and short flags with their associated
+ * parameters' IDs, and allowing the listing of IDs. This is probably only
+ * useful for developers creating their own DefaultSource classes.
+ * @return an IDMap based upon this JSAP's current configuration.
+ */
+ public IDMap getIDMap() {
+ List ids = new java.util.ArrayList(paramsByDeclarationOrder.size());
+ for (Iterator i = paramsByDeclarationOrder.iterator(); i.hasNext();) {
+ Parameter param = (Parameter) i.next();
+ ids.add(param.getID());
+ }
+
+ Map byShortFlag = new java.util.HashMap();
+ for (Iterator i = paramsByShortFlag.keySet().iterator();
+ i.hasNext();) {
+ Character c = (Character) i.next();
+ byShortFlag.put(
+ c,
+ ((Parameter) paramsByShortFlag.get(c)).getID());
+ }
+
+ Map byLongFlag = new java.util.HashMap();
+ for (Iterator i = paramsByLongFlag.keySet().iterator(); i.hasNext();) {
+ String s = (String) i.next();
+ byLongFlag.put(
+ s,
+ ((Parameter) paramsByLongFlag.get(s)).getID());
+ }
+
+ return (new IDMap(ids, byShortFlag, byLongFlag));
+ }
+
+ /**
+ * Returns the requested Switch, FlaggedOption, or UnflaggedOption with the
+ * specified ID. Depending upon what you intend to do with the result, it
+ * may be necessary to re-cast the result as a Switch, FlaggedOption, or
+ * UnflaggedOption as appropriate.
+ *
+ * @param id the ID of the requested Switch, FlaggedOption, or
+ * UnflaggedOption.
+ * @return the requested Switch, FlaggedOption, or UnflaggedOption, or null
+ * if no Parameter with the specified ID is defined in this JSAP.
+ */
+ public Parameter getByID(String id) {
+ return ((Parameter) paramsByID.get(id));
+ }
+
+ /**
+ * Returns the requested Switch or FlaggedOption with the specified long
+ * flag. Depending upon what you intend to do with the result, it may be
+ * necessary to re-cast the result as a Switch or FlaggedOption as
+ * appropriate.
+ *
+ * @param longFlag the long flag of the requested Switch or FlaggedOption.
+ * @return the requested Switch or FlaggedOption, or null if no Flagged
+ * object with the specified long flag is defined in this JSAP.
+ */
+ public Flagged getByLongFlag(String longFlag) {
+ return ((Flagged) paramsByLongFlag.get(longFlag));
+ }
+
+ /**
+ * Returns the requested Switch or FlaggedOption with the specified short
+ * flag. Depending upon what you intend to do with the result, it may be
+ * necessary to re-cast the result as a Switch or FlaggedOption as
+ * appropriate.
+ *
+ * @param shortFlag the short flag of the requested Switch or FlaggedOption.
+ * @return the requested Switch or FlaggedOption, or null if no Flagged
+ * object with the specified short flag is defined in this JSAP.
+ */
+ public Flagged getByShortFlag(Character shortFlag) {
+ return ((Flagged) paramsByShortFlag.get(shortFlag));
+ }
+
+ /**
+ * Returns the requested Switch or FlaggedOption with the specified short
+ * flag. Depending upon what you intend to do with the result, it may be
+ * necessary to re-cast the result as a Switch or FlaggedOption as
+ * appropriate.
+ *
+ * @param shortFlag the short flag of the requested Switch or FlaggedOption.
+ * @return the requested Switch or FlaggedOption, or null if no Flagged
+ * object with the specified short flag is defined in this JSAP.
+ */
+ public Flagged getByShortFlag(char shortFlag) {
+ return (getByShortFlag(new Character(shortFlag)));
+ }
+
+ /**
+ * Returns an Iterator over all UnflaggedOptions currently registered with
+ * this JSAP.
+ *
+ * @return an Iterator over all UnflaggedOptions currently registered with
+ * this JSAP.
+ * @see java.util.Iterator
+ */
+ public Iterator getUnflaggedOptionsIterator() {
+ return (unflaggedOptions.iterator());
+ }
+
+ /**
+ * Registers a new DefaultSource with this JSAP, at the end of the current
+ * DefaultSource chain, but before the defaults defined within the
+ * AbstractParameters themselves.
+ *
+ * @param ds the DefaultSource to append to the DefaultSource chain.
+ * @see com.martiansoftware.jsap.DefaultSource
+ */
+ public void registerDefaultSource(DefaultSource ds) {
+ defaultSources.add(ds);
+ }
+
+ /**
+ * Removes the specified DefaultSource from this JSAP's DefaultSource chain.
+ * If this specified DefaultSource is not currently in this JSAP's
+ * DefaultSource chain, this method does nothing.
+ *
+ * @param ds the DefaultSource to remove from the DefaultSource chain.
+ */
+ public void unregisterDefaultSource(DefaultSource ds) {
+ defaultSources.remove(ds);
+ }
+
+ /**
+ * Returns a Defaults object representing the default values defined within
+ * this JSAP's AbstractParameters themselves.
+ *
+ * @return a Defaults object representing the default values defined within
+ * this JSAP's AbstractParameters themselves.
+ */
+ private Defaults getSystemDefaults() {
+ Defaults defaults = new Defaults();
+ for (Iterator i = paramsByDeclarationOrder.iterator(); i.hasNext();) {
+ Parameter param = (Parameter) i.next();
+ defaults.setDefault(param.getID(), param.getDefault());
+ }
+ return (defaults);
+ }
+
+ /**
+ * Merges the specified Defaults objects, only copying Default values from
+ * the source to the destination if they are NOT currently defined in the
+ * destination.
+ *
+ * @param dest the destination Defaults object into which the source should
+ * be merged.
+ * @param src the source Defaults object.
+ */
+ private void combineDefaults(Defaults dest, Defaults src) {
+ if (src != null) {
+ for (Iterator i = src.idIterator(); i.hasNext();) {
+ String paramID = (String) i.next();
+ dest.setDefaultIfNeeded(paramID, src.getDefault(paramID));
+ }
+ }
+ }
+
+ /**
+ * Returns a Defaults object representing the merged Defaults of every
+ * DefaultSource in the DefaultSource chain and the default values specified
+ * in the AbstractParameters themselves.
+ *
+ * @param exceptionMap the ExceptionMap object within which any encountered
+ * exceptions will be returned.
+ * @return a Defaults object representing the Defaults of the entire JSAP.
+ * @see com.martiansoftware.jsap.DefaultSource#getDefaults(IDMap, ExceptionMap)
+ */
+ protected Defaults getDefaults(ExceptionMap exceptionMap) {
+ Defaults defaults = new Defaults();
+ IDMap idMap = getIDMap();
+ for (Iterator dsi = defaultSources.iterator(); dsi.hasNext();) {
+ DefaultSource ds = (DefaultSource) dsi.next();
+ combineDefaults(defaults, ds.getDefaults(idMap, exceptionMap));
+ }
+ combineDefaults(defaults, getSystemDefaults());
+ return (defaults);
+ }
+
+ /**
+ * Registers the specified Parameter (i.e., Switch, FlaggedOption,
+ * or UnflaggedOption) with this JSAP.
+ *
+ * <p>Registering an Parameter <b>locks</b> the parameter.
+ * Attempting to change its properties (ID, flags, etc.) while it is locked
+ * will result in a JSAPException. To unlock an Parameter, it must
+ * be unregistered from the JSAP.
+ *
+ * @param param the Parameter to register.
+ * @throws JSAPException if this Parameter cannot be added. Possible
+ * reasons include:
+ * <ul>
+ * <li>Another Parameter with the same ID has already been
+ * registered.</li>
+ * <li>You are attempting to register a Switch or FlaggedOption with
+ * neither a short nor long flag.</li>
+ * <li>You are attempting to register a Switch or FlaggedOption with a long
+ * or short flag that is already
+ * defined in this JSAP.</li>
+ * <li>You are attempting to register a second greedy UnflaggedOption</li>
+ * </ul>
+ */
+ public void registerParameter(Parameter param)
+ throws JSAPException {
+ String paramID = param.getID();
+
+ if (paramsByID.containsKey(paramID)) {
+ throw (
+ new JSAPException(
+ "A parameter with ID '"
+ + paramID
+ + "' has already been registered."));
+ }
+
+ if (param instanceof Flagged) {
+ Flagged f = (Flagged) param;
+ if ((f.getShortFlagCharacter() == null)
+ && (f.getLongFlag() == null)) {
+ throw (
+ new JSAPException(
+ "FlaggedOption '"
+ + paramID
+ + "' has no flags defined."));
+ }
+ if (paramsByShortFlag.containsKey(f.getShortFlagCharacter())) {
+ throw (
+ new JSAPException(
+ "A parameter with short flag '"
+ + f.getShortFlag()
+ + "' has already been registered."));
+ }
+ if (paramsByLongFlag.containsKey(f.getLongFlag())) {
+ throw (
+ new JSAPException(
+ "A parameter with long flag '"
+ + f.getLongFlag()
+ + "' has already been registered."));
+ }
+ } else {
+ if ((unflaggedOptions.size() > 0)
+ && (((UnflaggedOption) unflaggedOptions
+ .get(unflaggedOptions.size() - 1))
+ .isGreedy())) {
+ throw (
+ new JSAPException(
+ "A greedy unflagged option has already been registered;"
+ + " option '"
+ + paramID
+ + "' will never be reached."));
+ }
+ }
+
+ if (param instanceof Option) {
+ ((Option) param).register();
+ }
+
+ // if we got this far, it's safe to insert it.
+ param.setLocked(true);
+ paramsByID.put(paramID, param);
+ paramsByDeclarationOrder.add(param);
+ if (param instanceof Flagged) {
+ Flagged f = (Flagged) param;
+ if (f.getShortFlagCharacter() != null) {
+ paramsByShortFlag.put(f.getShortFlagCharacter(), param);
+ }
+ if (f.getLongFlag() != null) {
+ paramsByLongFlag.put(f.getLongFlag(), param);
+ }
+ } else if (param instanceof Option) {
+ unflaggedOptions.add(param);
+ }
+ }
+
+ /**
+ * Unregisters the specified Parameter (i.e., Switch, FlaggedOption,
+ * or UnflaggedOption) from this JSAP. Unregistering an Parameter
+ * also unlocks it, allowing changes to its properties (ID, flags, etc.).
+ *
+ * @param param the Parameter to unregister from this JSAP.
+ */
+ public void unregisterParameter(Parameter param) {
+ if (paramsByID.containsKey(param.getID())) {
+
+ if (param instanceof Option) {
+ ((Option) param).unregister();
+ }
+
+ paramsByID.remove(param.getID());
+ paramsByDeclarationOrder.remove(param);
+ if (param instanceof Flagged) {
+ Flagged f = (Flagged) param;
+ paramsByShortFlag.remove(f.getShortFlagCharacter());
+ paramsByLongFlag.remove(f.getLongFlag());
+ } else if (param instanceof UnflaggedOption) {
+ unflaggedOptions.remove(param);
+ }
+ param.setLocked(false);
+ }
+ }
+
+ /**
+ * Parses the specified command line array. If no Exception is thrown, the
+ * entire command line has been parsed successfully, and its results have
+ * been successfully instantiated.
+ *
+ * @param args An array of command line arguments to parse. This array is
+ * typically provided in the application's main class' main() method.
+ * @return a JSAPResult containing the resulting Objects.
+ */
+ public JSAPResult parse(String[] args) {
+ Parser p = new Parser(this, args);
+ return (p.parse());
+ }
+
+ /**
+ * Parses the specified command line. The specified command line is first
+ * parsed into an array, much like the operating system does for the JVM
+ * prior to calling your application's main class' main() method. If no
+ * Exception is thrown, the entire command line has been parsed
+ * successfully, and its results have been successfully instantiated.
+ *
+ * @param cmdLine An array of command line arguments to parse. This array
+ * is typically provided in the application's main class' main() method.
+ * @return a JSAPResult containing the resulting Objects.
+ */
+ public JSAPResult parse(String cmdLine) {
+ String[] args = CommandLineTokenizer.tokenize(cmdLine);
+ return (parse(args));
+ }
+
+ /**
+ * Unregisters all registered AbstractParameters, allowing them to perform
+ * their cleanup.
+ */
+ public void finalize() {
+ Parameter[] params =
+ (Parameter[]) paramsByDeclarationOrder.toArray(
+ new Parameter[0]);
+ int paramCount = params.length;
+ for (int i = 0; i < paramCount; ++i) {
+ unregisterParameter(params[i]);
+ }
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/JSAPException.java b/src/java/com/martiansoftware/jsap/JSAPException.java
new file mode 100644
index 0000000..d2fb0c1
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/JSAPException.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+/**
+ * The base class for all of JSAP's exceptions. A JSAPException can
+ * encapsulate another Exception, which can be obtained via the getRootCause()
+ * method. This is useful in cases where subclasses might need to
+ * throw an exception that JSAP is not expecting, such as an IOException while
+ * loading a DefaultSource. The subclass can in these cases throw a new
+ * JSAPException encapsulating the IOException.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.Flagged
+ * @see com.martiansoftware.jsap.Option
+ */
+public class JSAPException extends Exception {
+
+ /**
+ * Creates a new JSAPException.
+ */
+ public JSAPException() {
+ super();
+ }
+
+ /**
+ * Creates a new JSAPException with the specified message.
+ * @param msg the message for this JSAPException.
+ */
+ public JSAPException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Creates a new JSAPException encapsulating the specified Throwable.
+ * @param cause the Throwable to encapsulate.
+ */
+ public JSAPException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Creates a new JSAPException with the specified message encapsulating
+ * the specified Throwable.
+ * @param msg the message for this JSAPException.
+ * @param cause the Throwable to encapsulate.
+ */
+ public JSAPException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/JSAPResult.java b/src/java/com/martiansoftware/jsap/JSAPResult.java
new file mode 100644
index 0000000..6123def
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/JSAPResult.java
@@ -0,0 +1,1382 @@
+ /*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import java.util.Map;
+import java.io.File;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.URL;
+import java.awt.Color;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/** Encapsulates the results of JSAP's parse() methods. The most basic means of
+ * obtaining a parse result from a JSAPResult is the {@link #getObject(String)}
+ * method, but a number of getXXX() methods are provided
+ * to make your code more readable and to avoid re-casting.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class JSAPResult implements ExceptionMap {
+
+ /**
+ * Contains all of the results, as a Map of Lists keyed by
+ * parameter ID.
+ */
+ private Map allResults = null;
+
+ /**
+ * Contains a map of the QualifiedSwitch IDs with Booleans
+ * indicating whether they were present.
+ */
+ private Map qualifiedSwitches = null;
+
+ /**
+ * Contains all of the exceptions, as a Map of Lists, keyed by
+ * parameter ID.
+ * "General" exceptions that are not associated with a specific parameter
+ * have a null
+ * key.
+ */
+ private Map allExceptions = null;
+
+ /**
+ * A chronological listing of all of the exceptions thrown during parsing.
+ */
+ private List chronologicalErrorMessages = null;
+
+ /**
+ * A set containing the IDs of parameters supplied by the user
+ * (as opposed to default values)
+ */
+ private Set userSpecifiedIDs = null;
+
+ /**
+ * If true, any values "add"ed to this JSAPResult came from the
+ * user, and not from any default values.
+ */
+ private boolean valuesFromUser = false;
+
+ /**
+ * Creates new JSAPResult
+ */
+ protected JSAPResult() {
+ allResults = new java.util.HashMap();
+ allExceptions = new java.util.HashMap();
+ chronologicalErrorMessages = new java.util.LinkedList();
+ qualifiedSwitches = new java.util.HashMap();
+ userSpecifiedIDs = new java.util.HashSet();
+ }
+
+ /**
+ * Sets internal flag indicating sources of subsequent values
+ * added to this JSAPResult
+ * @param valuesFromUser if true, values subsequently added to
+ * this JSAPResult originated from the user.
+ */
+ void setValuesFromUser(boolean valuesFromUser) {
+ this.valuesFromUser = valuesFromUser;
+ }
+
+ /**
+ * Returns true if this JSAPResult contains any results for
+ * the specified id. Note that these results may be default
+ * values, and thus contains(id) might return true even when
+ * the user has not herself supplied the parameter.
+ *
+ * <P>This is just a means to see if there are values to retrieve.
+ *
+ * @param id the ID to check
+ * @return true if there are any values in this JSAPResult associated
+ * with the specified ID.
+ */
+ public boolean contains(String id) {
+ return (allResults.containsKey(id));
+ }
+
+ /**
+ * Returns true if this JSAPResult contains any <i>user-specified</i>
+ * values for the specified id. If this JSAPResult contains default values
+ * (or no values) for the specified id, this method returns false.
+ *
+ * @param id the ID to check
+ * @return indication of whether the user specified a value for the specified id.
+ */
+ public boolean userSpecified(String id) {
+ return (userSpecifiedIDs.contains(id));
+ }
+
+ /**
+ * Adds the specified values to any existing values already associated with
+ * the specified id, if any.
+ * @param id the unique ID of the parameter with which the specified values
+ * are associated.
+ * @param values a List containing the additional values to associate
+ * with the specified ID.
+ */
+ protected void add(String id, List values) {
+ List al = null;
+ if (allResults.containsKey(id)) {
+ al = (List) allResults.get(id);
+ } else {
+ al = new java.util.ArrayList();
+ allResults.put(id, al);
+ }
+ al.addAll(values);
+ if (valuesFromUser) {
+ userSpecifiedIDs.add(id);
+ }
+ }
+
+ /**
+ * Adds the specified exception to the exception map. Exceptions are
+ * keyed by the ID of the parameters with which they are associated.
+ * "General"
+ * exceptions not associated with a particular parameter have a null key.
+ * @param id the unique ID of the parameter with which the specified values
+ * are associated.
+ * @param exception the exception to associate with the specified key.
+ * @see com.martiansoftware.jsap.ExceptionMap#addException(String,Exception)
+ */
+ public void addException(String id, Exception exception) {
+ List el = null;
+ if (allExceptions.containsKey(id)) {
+ el = (List) allExceptions.get(id);
+ } else {
+ el = new java.util.ArrayList();
+ allExceptions.put(id, el);
+ }
+ el.add(exception);
+ chronologicalErrorMessages.add(exception.getMessage());
+ }
+
+ /**
+ * Returns the <b>first</b> object associated with the specified ID. If
+ * more than one object is
+ * expected, call getObjectArray() instead.
+ * @param id the unique ID of the parameter for which the first value is
+ * requested
+ * @return the <b>first</b> object associated with the specified ID. If
+ * more than one object is
+ * expected, call getObjectArray() instead.
+ */
+ public Object getObject(String id) {
+ Object result = null;
+ List al = (List) allResults.get(id);
+ if ((al != null) && (al.size() > 0)) {
+ result = al.get(0);
+ }
+ return (result);
+ }
+
+ /**
+ * Returns all values associated with the specified ID. If no values are
+ * currently associated with
+ * the specified ID, an empty (zero-length) array is returned.
+ * @param id the unique ID of the parameter for which the values are
+ * requested
+ * @return all values associated with the specified ID. If no values are
+ * currently associated with
+ * the specified ID, an empty (zero-length) array is returned.
+ */
+ public Object[] getObjectArray(String id) {
+ List al = (List) allResults.get(id);
+ if (al == null) {
+ al = new java.util.ArrayList(0);
+ }
+ return (al.toArray());
+ }
+
+ /**
+ * Returns an array containing all of the values associated with the
+ * specified ID. The runtime type
+ * of the returned array is that of the specified array. If the list fits
+ * in the specified array,
+ * it is returned therein. Otherwise, a new array is allocated with the
+ * runtime type of the specified
+ * array and the size of this list..
+ * @param id the unique ID of the parameter for which the values are
+ * requested
+ * @param a the array into which the elements of the list are to be
+ * stored, if it is big enough;
+ * otherwise, a new array of the same runtime type is allocated for this
+ * purpose.
+ * @return an array containing all of the values associated with the
+ * specified ID. The runtime type
+ * of the returned array is that of the specified array. If the list fits
+ * in the specified array,
+ * it is returned therein. Otherwise, a new array is allocated with the
+ * runtime type of the specified
+ * array and the size of this list..
+ */
+ public Object[] getObjectArray(String id, Object[] a) {
+ List al = (List) allResults.get(id);
+ if (al == null) {
+ al = new java.util.ArrayList();
+ }
+ return (al.toArray(a));
+ }
+
+ /**
+ * Returns the first boolean value associated with the specified id.
+ * @param id the id of the boolean value to retrieve
+ * @return the boolean value associated with the specified id.
+ * @see #getBoolean(String, boolean)
+ * @see #getBooleanArray(String)
+ */
+ public boolean getBoolean(String id) {
+ Boolean b = (Boolean) qualifiedSwitches.get(id);
+ if (b == null) {
+ if (! contains(id)) throw new UnspecifiedParameterException(id);
+ b = (Boolean) getObject(id);
+ }
+ return (b.booleanValue());
+ }
+
+ /**
+ * Returns the first boolean value associated with the specified id. If
+ * the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Boolean, the specified default value is returned.
+ * @param id the id of the boolean value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type
+ * java.lang.Boolean.
+ * @return the first boolean value associated with the specified id. If
+ * the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Boolean, the specified default value is returned.
+ * @see #getBoolean(String)
+ * @see #getBooleanArray(String)
+ */
+ public boolean getBoolean(String id, boolean defaultValue) {
+ Boolean b = (Boolean) qualifiedSwitches.get(id);
+ if (b == null) {
+ b = (Boolean) getObject(id);
+ }
+ return ((b == null) ? defaultValue : b.booleanValue());
+ }
+
+ /**
+ * Returns an array of boolean values associated with the specified id. If
+ * the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the boolean value(s) to return.
+ * @return an array containing the boolean value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getBoolean(String)
+ * @see #getBoolean(String,boolean)
+ */
+ public boolean[] getBooleanArray(String id) {
+ Boolean[] tmp = (Boolean[]) getObjectArray(id, new Boolean[0]);
+ int tmplength = tmp.length;
+ boolean[] result = new boolean[tmplength];
+ for (int i = 0; i < tmplength; ++i) {
+ result[i] = tmp[i].booleanValue();
+ }
+ return (result);
+ }
+
+ /**
+ * Returns the first integer value associated with the specified id.
+ * @param id the id of the integer value to retrieve
+ * @return the integer value associated with the specified id.
+ * @see #getInt(String,int)
+ * @see #getIntArray(String)
+ */
+ public int getInt(String id) {
+ if (! contains(id)) throw new UnspecifiedParameterException(id);
+ return (((Integer) getObject(id)).intValue());
+ }
+
+ /**
+ * Returns the first integer value associated with the specified id. If
+ * the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Integer, the specified default value is returned.
+ * @param id the id of the boolean value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type
+ * java.lang.Integer.
+ * @return the first integer value associated with the specified id. If
+ * the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Integer, the specified default value is returned.
+ * @see #getInt(String)
+ * @see #getIntArray(String)
+ */
+ public int getInt(String id, int defaultValue) {
+ Integer result = (Integer) getObject(id);
+ return ((result == null) ? defaultValue : result.intValue());
+ }
+ // KPB<<<<<<
+ /**
+ * Returns the string value associated with the specified ID for QualifiedSwitches.
+ *
+ * @param id the unique ID of the parameter for which the value is requested
+ * @return the value for the QualifiedSwitch associated with the specified ID
+ * or null is no such value is present or the ID does not belong
+ * to a QualifiedSwitch
+ */
+ public String getQualifiedSwitchValue(String id) {
+ Object result = null;
+ List al = (List) allResults.get(id);
+ if ((al != null) && (al.size() == 2)) {
+ result = al.get(1);
+ }
+ return(String)result;
+ }
+ // KPB<<<<<
+
+ /**
+ * Returns an array of integer values associated with the specified id.
+ * If the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the integer value(s) to return.
+ * @return an array containing the integer value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getInt(String)
+ * @see #getInt(String,int)
+ */
+ public int[] getIntArray(String id) {
+ Integer[] tmp = (Integer[]) getObjectArray(id, new Integer[0]);
+ int tmplength = tmp.length;
+ int[] result = new int[tmplength];
+ for (int i = 0; i < tmplength; ++i) {
+ result[i] = tmp[i].intValue();
+ }
+ return (result);
+ }
+
+ /**
+ * Returns the first long value associated with the specified id.
+ * @param id the id of the long value to retrieve
+ * @return the long value associated with the specified id.
+ * @see #getLong(String,long)
+ * @see #getLongArray(String)
+ */
+ public long getLong(String id) {
+ if (! contains(id)) throw new UnspecifiedParameterException(id);
+ return (((Long) getObject(id)).longValue());
+ }
+
+ /**
+ * Returns the first long value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Long, the specified default value is returned.
+ * @param id the id of the long value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type
+ * java.lang.Long.
+ * @return the first long value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Long, the specified default value is returned.
+ * @see #getLong(String)
+ * @see #getLongArray(String)
+ */
+ public long getLong(String id, long defaultValue) {
+ Long result = (Long) getObject(id);
+ return ((result == null) ? defaultValue : result.longValue());
+ }
+
+ /**
+ * Returns an array of long values associated with the specified id. If
+ * the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the long value(s) to return.
+ * @return an array containing the long value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getLong(String)
+ * @see #getLong(String,long)
+ */
+ public long[] getLongArray(String id) {
+ Long[] tmp = (Long[]) getObjectArray(id, new Long[0]);
+ int tmplength = tmp.length;
+ long[] result = new long[tmplength];
+ for (int i = 0; i < tmplength; ++i) {
+ result[i] = tmp[i].longValue();
+ }
+ return (result);
+ }
+
+ // public Iterator iterator(String id) {
+ // Object[] o = getObjectArray(id, new Object[0]);
+ // }
+
+ /**
+ * Returns the first byte value associated with the specified id.
+ * @param id the id of the byte value to retrieve
+ * @return the byte value associated with the specified id.
+ * @see #getByte(String,byte)
+ * @see #getByteArray(String)
+ */
+ public byte getByte(String id) {
+ if (! contains(id)) throw new UnspecifiedParameterException(id);
+ return (((Byte) getObject(id)).byteValue());
+ }
+
+ /**
+ * Returns the first byte value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Byte, the specified default value is returned.
+ * @param id the id of the byte value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type
+ * java.lang.Byte.
+ * @return the first byte value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Byte, the specified default value is returned.
+ * @see #getByte(String)
+ * @see #getByteArray(String)
+ */
+ public byte getByte(String id, byte defaultValue) {
+ Byte result = (Byte) getObject(id);
+ return ((result == null) ? defaultValue : result.byteValue());
+ }
+
+ /**
+ * Returns an array of byte values associated with the specified id. If
+ * the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the byte value(s) to return.
+ * @return an array containing the byte value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getByte(String)
+ * @see #getByte(String,byte)
+ */
+ public byte[] getByteArray(String id) {
+ Byte[] tmp = (Byte[]) getObjectArray(id, new Byte[0]);
+ int tmplength = tmp.length;
+ byte[] result = new byte[tmplength];
+ for (int i = 0; i < tmplength; ++i) {
+ result[i] = tmp[i].byteValue();
+ }
+ return (result);
+ }
+
+ /**
+ * Returns the first char value associated with the specified id.
+ * @param id the id of the char value to retrieve
+ * @return the char value associated with the specified id.
+ * @see #getChar(String,char)
+ * @see #getCharArray(String)
+ */
+ public char getChar(String id) {
+ if (! contains(id)) throw new UnspecifiedParameterException(id);
+ return (((Character) getObject(id)).charValue());
+ }
+
+ /**
+ * Returns the first char value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Character, the specified default value is returned.
+ * @param id the id of the char value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type
+ * java.lang.Character.
+ * @return the first char value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Character, the specified default value is returned.
+ * @see #getChar(String)
+ * @see #getCharArray(String)
+ */
+ public char getChar(String id, char defaultValue) {
+ Character result = (Character) getObject(id);
+ return ((result == null) ? defaultValue : result.charValue());
+ }
+
+ /**
+ * Returns an array of char values associated with the specified id. If
+ * the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the char value(s) to return.
+ * @return an array containing the char value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getChar(String)
+ * @see #getChar(String,char)
+ */
+ public char[] getCharArray(String id) {
+ Character[] tmp = (Character[]) getObjectArray(id, new Character[0]);
+ int tmplength = tmp.length;
+ char[] result = new char[tmplength];
+ for (int i = 0; i < tmplength; ++i) {
+ result[i] = tmp[i].charValue();
+ }
+ return (result);
+ }
+
+ /**
+ * Returns the first short value associated with the specified id.
+ * @param id the id of the short value to retrieve
+ * @return the short value associated with the specified id.
+ * @see #getShort(String,short)
+ * @see #getShortArray(String)
+ */
+ public short getShort(String id) {
+ if (! contains(id)) throw new UnspecifiedParameterException(id);
+ return (((Short) getObject(id)).shortValue());
+ }
+
+ /**
+ * Returns the first short value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Short, the specified default value is returned.
+ * @param id the id of the short value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type
+ * java.lang.Short.
+ * @return the first short value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Short, the specified default value is returned.
+ * @see #getShort(String)
+ * @see #getShortArray(String)
+ */
+ public short getShort(String id, short defaultValue) {
+ Short result = (Short) getObject(id);
+ return ((result == null) ? defaultValue : result.shortValue());
+ }
+
+ /**
+ * Returns an array of short values associated with the specified id. If
+ * the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the short value(s) to return.
+ * @return an array containing the short value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getShort(String)
+ * @see #getShort(String,short)
+ */
+ public short[] getShortArray(String id) {
+ Short[] tmp = (Short[]) getObjectArray(id, new Short[0]);
+ int tmplength = tmp.length;
+ short[] result = new short[tmplength];
+ for (int i = 0; i < tmplength; ++i) {
+ result[i] = tmp[i].shortValue();
+ }
+ return (result);
+ }
+
+ /**
+ * Returns the first double value associated with the specified id.
+ * @param id the id of the double value to retrieve
+ * @return the double value associated with the specified id.
+ * @see #getDouble(String,double)
+ * @see #getDoubleArray(String)
+ */
+ public double getDouble(String id) {
+ if (! contains(id)) throw new UnspecifiedParameterException(id);
+ return (((Double) getObject(id)).doubleValue());
+ }
+
+ /**
+ * Returns the first double value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Double, the specified default value is returned.
+ * @param id the id of the double value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type
+ * java.lang.Double.
+ * @return the first double value associated with the specified id. If
+ * the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Double, the specified default value is returned.
+ * @see #getDouble(String)
+ * @see #getDoubleArray(String)
+ */
+ public double getDouble(String id, double defaultValue) {
+ Double result = (Double) getObject(id);
+ return ((result == null) ? defaultValue : result.doubleValue());
+ }
+
+ /**
+ * Returns an array of double values associated with the specified id. If
+ * the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the double value(s) to return.
+ * @return an array containing the double value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getDouble(String)
+ * @see #getDouble(String,double)
+ */
+ public double[] getDoubleArray(String id) {
+ Double[] tmp = (Double[]) getObjectArray(id, new Double[0]);
+ int tmplength = tmp.length;
+ double[] result = new double[tmplength];
+ for (int i = 0; i < tmplength; ++i) {
+ result[i] = tmp[i].doubleValue();
+ }
+ return (result);
+ }
+
+ /**
+ * Returns the first float value associated with the specified id.
+ * @param id the id of the float value to retrieve
+ * @return the float value associated with the specified id.
+ * @see #getFloat(String,float)
+ * @see #getFloatArray(String)
+ */
+ public float getFloat(String id) {
+ if (! contains(id)) throw new UnspecifiedParameterException(id);
+ return (((Float) getObject(id)).floatValue());
+ }
+
+ /**
+ * Returns the first float value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Float, the specified default value is returned.
+ * @param id the id of the float value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type
+ * java.lang.Float.
+ * @return the first float value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Float, the specified default value is returned.
+ * @see #getFloat(String)
+ * @see #getFloatArray(String)
+ */
+ public float getFloat(String id, float defaultValue) {
+ Float result = (Float) getObject(id);
+ return ((result == null) ? defaultValue : result.floatValue());
+ }
+
+ /**
+ * Returns an array of float values associated with the specified id. If
+ * the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the float value(s) to return.
+ * @return an array containing the float value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getFloat(String)
+ * @see #getFloat(String,float)
+ */
+ public float[] getFloatArray(String id) {
+ Float[] tmp = (Float[]) getObjectArray(id, new Float[0]);
+ int tmplength = tmp.length;
+ float[] result = new float[tmplength];
+ for (int i = 0; i < tmplength; ++i) {
+ result[i] = tmp[i].floatValue();
+ }
+ return (result);
+ }
+
+ /**
+ * Returns the first String value associated with the specified id.
+ * @param id the id of the String value to retrieve
+ * @return the String value associated with the specified id.
+ * @see #getString(String,String)
+ * @see #getStringArray(String)
+ */
+ public String getString(String id) {
+ return ((String) getObject(id));
+ }
+
+ /**
+ * Returns the first String value associated with the specified id. If
+ * the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.String, the specified default value is returned.
+ * @param id the id of the String value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type
+ * java.lang.String.
+ * @return the first String value associated with the specified id. If
+ * the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.String, the specified default value is returned.
+ * @see #getString(String)
+ * @see #getStringArray(String)
+ */
+ public String getString(String id, String defaultValue) {
+ String result = (String) getObject(id);
+ return ((result == null) ? defaultValue : result);
+ }
+
+ /**
+ * Returns an array of String values associated with the specified id.
+ * If the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the String value(s) to return.
+ * @return an array containing the String value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getString(String)
+ * @see #getString(String,String)
+ */
+ public String[] getStringArray(String id) {
+ return ((String[]) getObjectArray(id, new String[0]));
+ }
+
+ /**
+ * Returns the first BigDecimal value associated with the specified id.
+ * @param id the id of the BigDecimal value to retrieve
+ * @return the BigDecimal value associated with the specified id.
+ * @see #getBigDecimal(String, BigDecimal)
+ * @see #getBigDecimalArray(String)
+ * @see java.math.BigDecimal
+ */
+ public BigDecimal getBigDecimal(String id) {
+ return ((BigDecimal) getObject(id));
+ }
+
+ /**
+ * Returns the first BigDecimal value associated with the specified id.
+ * If the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.math.BigDecimal, the specified default value is returned.
+ * @param id the id of the BigDecimal value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type
+ * java.math.BigDecimal.
+ * @return the first BigDecimal value associated with the specified id.
+ * If the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.BigDecimal, the specified default value is returned.
+ * @see #getBigDecimal(String)
+ * @see #getBigDecimalArray(String)
+ * @see java.math.BigDecimal
+ */
+ public BigDecimal getBigDecimal(String id, BigDecimal defaultValue) {
+ BigDecimal result = (BigDecimal) getObject(id);
+ return ((result == null) ? defaultValue : result);
+ }
+
+ /**
+ * Returns an array of BigDecimal values associated with the specified id.
+ * If the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the BigDecimal value(s) to return.
+ * @return an array containing the BigDecimal value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getBigDecimal(String)
+ * @see #getBigDecimal(String,BigDecimal)
+ * @see java.math.BigDecimal
+ */
+ public BigDecimal[] getBigDecimalArray(String id) {
+ return ((BigDecimal[]) getObjectArray(id, new BigDecimal[0]));
+ }
+
+ /**
+ * Returns the first BigInteger value associated with the specified id.
+ * @param id the id of the BigInteger value to retrieve
+ * @return the BigInteger value associated with the specified id.
+ * @see #getBigInteger(String, BigInteger)
+ * @see #getBigIntegerArray(String)
+ * @see java.math.BigInteger
+ */
+ public BigInteger getBigInteger(String id) {
+ return ((BigInteger) getObject(id));
+ }
+
+ /**
+ * Returns the first BigInteger value associated with the specified id.
+ * If the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.math.BigInteger, the specified default value is returned.
+ * @param id the id of the BigInteger value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are not
+ * of type
+ * java.math.BigInteger.
+ * @return the first boolean value associated with the specified id. If
+ * the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.BigInteger, the specified default value is returned.
+ * @see #getBigInteger(String)
+ * @see #getBigIntegerArray(String)
+ * @see java.math.BigInteger
+ */
+ public BigInteger getBigInteger(String id, BigInteger defaultValue) {
+ BigInteger result = (BigInteger) getObject(id);
+ return ((result == null) ? defaultValue : result);
+ }
+
+ /**
+ * Returns an array of BigInteger values associated with the specified id.
+ * If the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the BigInteger value(s) to return.
+ * @return an array containing the BigInteger value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getBigInteger(String)
+ * @see #getBigInteger(String,BigInteger)
+ * @see java.math.BigInteger
+ */
+ public BigInteger[] getBigIntegerArray(String id) {
+ return ((BigInteger[]) getObjectArray(id, new BigInteger[0]));
+ }
+
+ /**
+ * Returns the first Class value associated with the specified id.
+ * @param id the id of the Class value to retrieve
+ * @return the Class value associated with the specified id.
+ * @see #getClass(String, Class)
+ * @see #getClassArray(String)
+ * @see java.lang.Class
+ */
+ public Class getClass(String id) {
+ return ((Class) getObject(id));
+ }
+
+ /**
+ * Returns the first Class value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Class, the specified default value is returned.
+ * @param id the id of the Class value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type
+ * java.lang.Class.
+ * @return the first Class value associated with the specified id. If
+ * the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Class, the specified default value is returned.
+ * @see #getClass(String)
+ * @see #getClassArray(String)
+ * @see java.lang.Class
+ */
+ public Class getClass(String id, Class defaultValue) {
+ Class result = (Class) getObject(id);
+ return ((result == null) ? defaultValue : result);
+ }
+
+ /**
+ * Returns an array of Class values associated with the specified id.
+ * If the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the Class value(s) to return.
+ * @return an array containing the Class value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getClass(String)
+ * @see #getClass(String,Class)
+ * @see java.lang.Class
+ */
+ public Class[] getClassArray(String id) {
+ return ((Class[]) getObjectArray(id, new Class[0]));
+ }
+
+ /**
+ * Returns the first InetAddress value associated with the specified id.
+ * @param id the id of the InetAddress value to retrieve
+ * @return the InetAddress value associated with the specified id.
+ * @see #getInetAddress(String, InetAddress)
+ * @see #getInetAddressArray(String)
+ * @see java.net.InetAddress
+ */
+ public InetAddress getInetAddress(String id) {
+ return ((InetAddress) getObject(id));
+ }
+
+ /**
+ * Returns the first InetAddress value associated with the specified id.
+ * If the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.net.InetAddress, the specified default value is returned.
+ * @param id the id of the InetAddress value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type java.net.InetAddress.
+ * @return the first InetAddress value associated with the specified id.
+ * If the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.InetAddress, the specified default value is returned.
+ * @see #getInetAddress(String)
+ * @see #getInetAddressArray(String)
+ * @see java.net.InetAddress
+ */
+ public InetAddress getInetAddress(String id, InetAddress defaultValue) {
+ InetAddress result = (InetAddress) getObject(id);
+ return ((result == null) ? defaultValue : result);
+ }
+
+ /**
+ * Returns an array of InetAddress values associated with the specified id.
+ * If the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the InetAddress value(s) to return.
+ * @return an array containing the InetAddress value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getInetAddress(String)
+ * @see #getInetAddress(String,InetAddress)
+ * @see java.net.InetAddress
+ */
+ public InetAddress[] getInetAddressArray(String id) {
+ return ((InetAddress[]) getObjectArray(id, new InetAddress[0]));
+ }
+
+ /**
+ * Returns the first Package value associated with the specified id.
+ * @param id the id of the Package value to retrieve
+ * @return the Package value associated with the specified id.
+ * @see #getPackage(String, Package)
+ * @see #getPackageArray(String)
+ * @see java.lang.Package
+ */
+ public Package getPackage(String id) {
+ return ((Package) getObject(id));
+ }
+
+ /**
+ * Returns the first Package value associated with the specified id. If
+ * the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Package, the specified default value is returned.
+ * @param id the id of the Package value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type
+ * java.lang.Package.
+ * @return the first Package value associated with the specified id. If
+ * the specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.lang.Package, the specified default value is returned.
+ * @see #getPackage(String)
+ * @see #getPackageArray(String)
+ * @see java.lang.Package
+ */
+ public Package getPackage(String id, Package defaultValue) {
+ Package result = (Package) getObject(id);
+ return ((result == null) ? defaultValue : result);
+ }
+
+ /**
+ * Returns an array of Package values associated with the specified id. If
+ * the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the Package value(s) to return.
+ * @return an array containing the Package value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getPackage(String)
+ * @see #getPackage(String,Package)
+ * @see java.lang.Package
+ */
+ public Package[] getPackageArray(String id) {
+ return ((Package[]) getObjectArray(id, new Package[0]));
+ }
+
+ /**
+ * Returns the first URL value associated with the specified id.
+ * @param id the id of the URL value to retrieve
+ * @return the URL value associated with the specified id.
+ * @see #getURL(String,URL)
+ * @see #getURLArray(String)
+ * @see java.net.URL
+ */
+ public URL getURL(String id) {
+ return ((URL) getObject(id));
+ }
+
+ /**
+ * Returns the first URL value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.net.URL, the specified default value is returned.
+ * @param id the id of the URL value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type
+ * java.net.URL.
+ * @return the first URL value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.net.URL, the specified default value is returned.
+ * @see #getURL(String)
+ * @see #getURLArray(String)
+ * @see java.net.URL
+ */
+ public URL getURL(String id, URL defaultValue) {
+ URL result = (URL) getObject(id);
+ return ((result == null) ? defaultValue : result);
+ }
+
+ /**
+ * Returns an array of URL values associated with the specified id. If the
+ * specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the URL value(s) to return.
+ * @return an array containing the URL value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getURL(String)
+ * @see #getURL(String,URL)
+ * @see java.net.URL
+ */
+ public URL[] getURLArray(String id) {
+ return ((URL[]) getObjectArray(id, new URL[0]));
+ }
+
+ /**
+ * Returns the first Color value associated with the specified id.
+ * @param id the id of the Color value to retrieve
+ * @return the Color value associated with the specified id.
+ * @see #getColor(String,Color)
+ * @see #getColorArray(String)
+ * @see java.awt.Color
+ */
+ public Color getColor(String id) {
+ return ((Color) getObject(id));
+ }
+
+ /**
+ * Returns the first File value associated with the specified id.
+ * @param id the id of the File value to retrieve
+ * @return the File value associated with the specified id.
+ * @see #getFile(String,File)
+ * @see #getFileArray(String)
+ * @see java.io.File
+ */
+ public File getFile(String id) {
+ return ((File) getObject(id));
+ }
+
+ /**
+ * Returns the first Color value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.awt.Color, the specified default value is returned.
+ * @param id the id of the Color value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type
+ * java.lang.Color.
+ * @return the first Color value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.awt.Color, the specified default value is returned.
+ * @see #getColor(String)
+ * @see #getColorArray(String)
+ * @see java.awt.Color
+ */
+ public Color getColor(String id, Color defaultValue) {
+ Color result = (Color) getObject(id);
+ return ((result == null) ? defaultValue : result);
+ }
+
+ /**
+ * Returns the first File value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.io.File, the specified default value is returned.
+ * @param id the id of the File value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are
+ * not of type
+ * java.io.File.
+ * @return the first File value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.io.File, the specified default value is returned.
+ * @see #getFile(String)
+ * @see #getFileArray(String)
+ * @see java.io.File
+ */
+ public File getFile(String id, File defaultValue) {
+ File result = (File) getObject(id);
+ return ((result == null) ? defaultValue : result);
+ }
+
+ /**
+ * Returns an array of Color values associated with the specified id. If
+ * the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the Color value(s) to return.
+ * @return an array containing the Color value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getColor(String)
+ * @see #getColor(String,Color)
+ * @see java.awt.Color
+ */
+ public Color[] getColorArray(String id) {
+ return ((Color[]) getObjectArray(id, new Color[0]));
+ }
+
+ /**
+ * Returns an array of File values associated with the specified id. If
+ * the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the File value(s) to return.
+ * @return an array containing the File value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getFile(String)
+ * @see #getFile(String,File)
+ * @see java.io.File
+ */
+ public File[] getFileArray(String id) {
+ return ((File[]) getObjectArray(id, new File[0]));
+ }
+ /**
+ * Returns the first Date value associated with the specified id.
+ * @param id the id of the Date value to retrieve
+ * @return the Date value associated with the specified id.
+ * @see #getDate(String,Date)
+ * @see #getDateArray(String)
+ * @see java.util.Date
+ */
+ public Date getDate(String id) {
+ return ((Date) getObject(id));
+ }
+
+ /**
+ * Returns the first Date value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.util.Date, the specified default value is returned.
+ * @param id the id of the Date value to retrieve
+ * @param defaultValue the value to return if the specified id does not
+ * exist within this
+ * JSAPResult, or if the object(s) associated with the specified id are not
+ * of type
+ * java.util.Date.
+ * @return the first Date value associated with the specified id. If the
+ * specified id does not
+ * exist within this JSAPResult, or if the object(s) associated with the
+ * specified id are not of
+ * type java.util.Date, the specified default value is returned.
+ * @see #getDate(String)
+ * @see #getDateArray(String)
+ * @see java.util.Date
+ */
+ public Date getDate(String id, Date defaultValue) {
+ Date result = (Date) getObject(id);
+ return ((result == null) ? defaultValue : result);
+ }
+
+ /**
+ * Returns an array of Date values associated with the specified id. If
+ * the specified id does
+ * not exist within this JSAPResult, this method returns an empty array
+ * (i.e., array.length==0).
+ * @param id the id of the Date value(s) to return.
+ * @return an array containing the Date value(s) associated with the
+ * specified id, or an
+ * empty array if the specified id does not exist within this JSAPResult.
+ * @see #getDate(String)
+ * @see #getDate(String,Date)
+ * @see java.util.Date
+ */
+ public Date[] getDateArray(String id) {
+ return ((Date[]) getObjectArray(id, new Date[0]));
+ }
+
+ /**
+ * Returns the first exception associated with the specified parameter ID.
+ * "General"
+ * exceptions can be retrieved with a null id. If no exceptions are
+ * associated
+ * with the specified parameter ID, null is returned.
+ * @param id the unique ID of the parameter for which the first exception
+ * is requested
+ * @return the first exception associated with the specified ID, or null
+ * if no
+ * exceptions are associated with the specified ID.
+ * @see com.martiansoftware.jsap.ExceptionMap#getException(String)
+ */
+ public Exception getException(String id) {
+ Exception result = null;
+ List el = (List) allExceptions.get(id);
+ if ((el != null) && (el.size() > 0)) {
+ result = (Exception) el.get(0);
+ }
+ return (result);
+ }
+
+ /**
+ * Returns an array of ALL exceptions associated with the specified
+ * parameter ID.
+ * If no exceptions are associated with the specified parameter ID, an empty
+ * (zero-length) array is returned.
+ * @param id the unique ID of the parameter for which the exceptions are
+ * requested.
+ * @return an array of ALL exceptions associated with the specified
+ * parameter ID,
+ * or an empty (zero-length) array if no exceptions are associated with the
+ * specified parameter ID.
+ * @see com.martiansoftware.jsap.ExceptionMap#getExceptionArray(String)
+ */
+ public Exception[] getExceptionArray(String id) {
+ Exception[] result = new Exception[0];
+ List el = (List) allExceptions.get(id);
+ if (el != null) {
+ result = (Exception[]) el.toArray(result);
+ }
+ return (result);
+ }
+
+ /**
+ * Returns an Iterator ovar ALL exceptions associated with the specified
+ * parameter ID.
+ * If no exceptions are associated with the specified parameter ID, an empty
+ * iterator (NOT null) is returned.
+ * @param id the unique ID of the parameter for which the exceptions are
+ * requested.
+ * @return an Iterator over ALL exceptions associated with the specified
+ * parameter ID
+ */
+ public Iterator getExceptionIterator(String id) {
+ List el = (List) allExceptions.get(id);
+ if (el == null) {
+ el = new java.util.ArrayList();
+ }
+ return (el.iterator());
+ }
+
+ /**
+ * Returns an iterator over all error messages generated during parsing.
+ * If no errors occured, the iterator will be empty.
+ * @return an iterator over all error messages generated during parsing.
+ */
+ public Iterator getErrorMessageIterator() {
+ return (chronologicalErrorMessages.iterator());
+ }
+
+ /**
+ * Returns an Iterator over the IDs of all parameters with associated
+ * exceptions (which can in turn be obtained via
+ * getExceptionIterator(String)).
+ * General exceptions not associated with any particular parameter are
+ * associated with the null ID, so null may be returned by this Iterator.
+ *
+ * @return an Iterator over the IDs of all parameters with associated
+ * exceptions.
+ */
+ public Iterator getBadParameterIDIterator() {
+ return (allExceptions.keySet().iterator());
+ }
+
+ /**
+ * Returns a boolean indicating whether the parse that produced this
+ * JSAPResult
+ * was successful. If this method returns false, detailed information
+ * regarding
+ * the reasons for the failed parse can be obtained via the getException()
+ * methods.
+ * @return a boolean indicating whether the parse that produced this
+ * JSAPResult
+ * was successful.
+ */
+ public boolean success() {
+ return (allExceptions.size() == 0);
+ }
+
+ /**
+ * Informs the JSAPResult of a QualifiedSwitch (necessary
+ * for getBoolean() to work properly for QualifiedSwitches)
+ * @param qsid the ID of the QualifiedSwitch
+ * @param present boolean indicating whether the QualifiedSwitch is present
+ */
+ void registerQualifiedSwitch(String qsid, boolean present) {
+ qualifiedSwitches.put(qsid, new Boolean(present));
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/Option.java b/src/java/com/martiansoftware/jsap/Option.java
new file mode 100644
index 0000000..e881fbc
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/Option.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import java.util.List;
+
+/**
+ * The base class from which FlaggedOption and UnflaggedOption are derived.
+ * An Option is a Parameter
+ * that requires some information (unlike a Switch whose mere presence is
+ * significant).<br>
+ * <br>
+ * Options may be declared as lists, or multiple values separated by a
+ * delimiting character. An example of
+ * a list option might be a classpath, which is a collection of paths separated
+ * by a ":" on *nix systems and
+ * a ";" on DOS/Windows systems. JSAP automatically separates list options
+ * into multiple tokens before calling
+ * their StringParsers' parse() method.
+ *
+ * <p>The default list separator is JSAP.DEFAULT_LISTSEPARATOR, which is defined
+ * as the platform's path separator
+ * character (":" on *nix and ";" on DOS/Windows as described above).
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.Flagged
+ * @see com.martiansoftware.jsap.Option
+ */
+public abstract class Option extends Parameter {
+
+ /**
+ * Boolean indicating whether this option is a list. Default is
+ * JSAP.NOT_LIST.
+ */
+ private boolean isList = JSAP.NOT_LIST;
+
+ /**
+ * Boolean indicating whether this option is required. Default is
+ * JSAP.NOT_REQUIRED.
+ */
+ private boolean required = JSAP.NOT_REQUIRED;
+
+ /**
+ * The current list separator character. Default is
+ * JSAP.DEFAULT_LISTSEPARATOR.
+ */
+ private char listSeparator = JSAP.DEFAULT_LISTSEPARATOR;
+
+ /**
+ * The current StringParser. Default is null, although a
+ * StringStringParser will be created if necessary
+ * when this Option's parse() method is called.
+ */
+ private StringParser stringParser = null;
+
+ /**
+ * Creates a new Option with the specified unique ID.
+ * @param id the unique ID for this Option.
+ */
+ public Option(String id) {
+ super(id);
+ }
+
+ /**
+ * Sets whether this Option is a list. Default behavior is JSAP.NOT_LIST.
+ * @param isList if true, this Option is a list.
+ */
+ protected final void internalSetList(boolean isList) {
+ enforceParameterLock();
+ this.isList = isList;
+ }
+
+ /**
+ * Returns a boolean indicating whether this Option is a list.
+ * @return a boolean indicating whether this Option is a list.
+ */
+ public final boolean isList() {
+ return (isList);
+ }
+
+ /**
+ * Sets the list separator character for this Option. The default list
+ * separator is JSAP.DEFAULT_LISTSEPARATOR.
+ * @param listSeparator the list separator for this Option.
+ */
+ protected final void internalSetListSeparator(char listSeparator) {
+ enforceParameterLock();
+ this.listSeparator = listSeparator;
+ }
+
+ /**
+ * Returns the current list separator character for this Option.
+ * @return the current list separator character for this Option.
+ */
+ public final char getListSeparator() {
+ return (listSeparator);
+ }
+
+ /**
+ * Sets whether this Option is required. Default is JSAP.NOT_REQUIRED.
+ * @param required if true, this Option will be required.
+ */
+ protected final void internalSetRequired(boolean required) {
+ enforceParameterLock();
+ this.required = required;
+ }
+
+ /**
+ * Returns a boolean indicating whether this Option is required.
+ * @return a boolean indicating whether this Option is required.
+ */
+ public final boolean required() {
+ return (required);
+ }
+
+ /**
+ * Sets the StringParser to which this Option's parse() method should
+ * delegate.
+ * @param stringParser the StringParser to which this Option's parse()
+ * method should delegate.
+ * @see com.martiansoftware.jsap.StringParser
+ */
+ protected final void internalSetStringParser(StringParser stringParser) {
+ enforceParameterLock();
+ this.stringParser = stringParser;
+ }
+
+ /**
+ * Returns the StringParser to which this Option will delegate calls to its
+ * parse() method, or null if
+ * no StringParser is currently defined.
+ * @return the StringParser to which this Option will delegate calls to its
+ * parse() method, or null if
+ * no StringParser is currently defined.
+ */
+ public final StringParser getStringParser() {
+ return (stringParser);
+ }
+
+ /**
+ * Delegates the parsing of a single argument to the current StringParser,
+ * and stores the result in the
+ * specified List. List options are broken into multiple arguments,
+ * resulting in multiple calls
+ * to this method.
+ * @param result the List to which the result should be appended.
+ * @param argToParse the argument to parse.
+ * @throws ParseException if the specified argument cannot be parsed.
+ */
+ private void storeParseResult(List result, String argToParse)
+ throws ParseException {
+ if (argToParse == null) return;
+ Object parseResult = getStringParser().parse(argToParse);
+ if (parseResult != null) {
+ result.add(parseResult);
+ }
+ }
+
+ /**
+ * Parses the specified argument, returning the results in an ArrayList.
+ * List options are tokenized
+ * before the parse call is delegated to the StringParser.
+ * @param arg the argument to parse.
+ * @return a List of objects resulting from the parse.
+ * @throws ParseException if the specified argument (or one of its tokens,
+ * in the case of a list) cannot
+ * be parsed.
+ */
+ protected final List parse(String arg) throws ParseException {
+ List result = new java.util.ArrayList();
+ if (getStringParser() == null) {
+ boolean wasLocked = this.locked();
+ setLocked(false);
+ internalSetStringParser( JSAP.STRING_PARSER );
+ setLocked(wasLocked);
+ }
+
+ if ((arg == null)
+ || !isList()) { // handle null arguments and non-list arguments
+ storeParseResult(result, arg);
+ } else {
+ StringBuffer subarg = new StringBuffer();
+ int arglen = arg.length();
+ for (int index = 0; index < arglen; ++index) {
+ char c = arg.charAt(index);
+ if (c == getListSeparator()) {
+ // parse the subargument stored so far...
+ storeParseResult(result, subarg.toString());
+ subarg.setLength(0);
+ } else {
+ subarg.append(c);
+ if (index == arglen - 1) {
+ // needed to parse the last subargument
+ storeParseResult(result, subarg.toString());
+ }
+ }
+ }
+ }
+ return (result);
+ }
+
+ /**
+ * Informs this Option's StringParser that this Option is being registered
+ * with a JSAP. If the StringParser requires any setup not taken care of
+ * in its constructor, it should override StringParser.setUp().
+ * @throws JSAPException if the underlying StringParser throws it.
+ * @see com.martiansoftware.jsap.StringParser#setUp()
+ */
+ protected void register() throws JSAPException {
+ StringParser stringParser = getStringParser();
+ try {
+ if (stringParser != null) {
+ stringParser.setUp();
+ }
+ } catch (Exception e) {
+ throw (new JSAPException(e.getMessage(), e));
+ }
+ }
+
+ /**
+ * Informs this Option's StringParser that this Option is being
+ * unregistered
+ * from a JSAP. If the StringParser requires any cleanup, it should
+ * ovverride
+ * StringParser.tearDown().
+ * @see com.martiansoftware.jsap.StringParser#tearDown()
+ */
+ protected void unregister() {
+ StringParser stringParser = getStringParser();
+ if (stringParser != null) {
+ stringParser.tearDown();
+ }
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/Parameter.java b/src/java/com/martiansoftware/jsap/Parameter.java
new file mode 100644
index 0000000..0b0bf35
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/Parameter.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import java.util.List;
+
+
+/**
+ * <p>Top-level abstraction of a <b>parameter</b>. A <b>parameter</b> consists
+ * of one or more <b>arguments</b> (command line tokens) that have a special
+ * meaning when taken together.
+ * For example, a command-line switch "-v" is a parameter consisting of a single
+ * argument, whereas a command-line option "--file somefile.txt" is a parameter
+ * consisting of two arguments. Some parameters can be quite large, such as an
+ * option for a file compression utility that allows you to specify any number
+ * of files to comporess.</p>
+ *
+ * <p>This is an abstract class. See its subclasses {@link com.martiansoftware.jsap.Switch},
+ * {@link com.martiansoftware.jsap.FlaggedOption}, and {@link com.martiansoftware.jsap.UnflaggedOption}
+ * for details on the various types of parameters. Functionality common to all three
+ * types of Parameters is described below.</p>
+ *
+ * <p>Each parameter has a unique ID assigned in its constructor. This ID is
+ * used to retrieve values from the parser after the command line is parsed.
+ * You can set the ID to any String value you wish, although in general you'll
+ * want them to be brief and descriptive to provide a degree of documentation.
+ * A "-h" switch, for example, might have the ID "help".
+ * The calling program can then determine if the user specified the -h switch on
+ * the command line with the simple call <code>getBoolean("help")</code> against
+ * the JSAPResult object produced by JSAP.parse().
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.Switch
+ * @see com.martiansoftware.jsap.FlaggedOption
+ * @see com.martiansoftware.jsap.UnflaggedOption
+ * @see com.martiansoftware.jsap.JSAPResult#getBoolean(String)
+ * @see com.martiansoftware.jsap.JSAP#parse(String[])
+ */
+
+public abstract class Parameter {
+
+ /**
+ * This parameter's unique ID.
+ */
+ private String id = null;
+
+ /**
+ * The name to use for this AbstractParameter when generating
+ * usage information. If null, the id will be used.
+ */
+ private String usageName = null;
+
+ /**
+ * If true, this parameter is "locked" (i.e., cannot be modified).
+ * Parameters are locked when they are stored in a JSAPConfiguration.
+ */
+ private boolean locked = false;
+
+ /**
+ * The default values for this parameter. Multiple default values
+ * are permitted to accommodate parameters that allow lists or
+ * multiple declarations.
+ */
+ private String[] defaultValue = null;
+
+ /**
+ * This parameter's help text.
+ */
+ private String help = null;
+
+ /**
+ * Creates a new Parameter. Subclasses should call this
+ * constructor.
+ *
+ * @param id The ID for this argument. All arguments MUST have
+ * a unique ID.
+ */
+ public Parameter(String id) {
+ this.id = id;
+ }
+
+ /**
+ * Returns this parameter's unique ID.
+ *
+ * @return this parameter's unique ID.
+ */
+ public String getID() {
+ return (id);
+ }
+
+ /**
+ * Locks or unlocks this parameter. Locked parameters cannot be
+ * modified. This is necessary because the JSAP object with
+ * which parameters are registered performs certain validation
+ * routines at the time of registration. See
+ * JSAP.registerParameter(Parameter) for more information.
+ *
+ * @param locked if <code>TRUE</code>, locks this parameter. if
+ * <code>FALSE</code>, unlocks it.
+ * @see
+ * com.martiansoftware.jsap.JSAP#registerParameter(Parameter)
+ */
+ protected final void setLocked(boolean locked) {
+ this.locked = locked;
+ }
+
+ /**
+ * Returns a boolean indicating whether this parameter is locked.
+ *
+ * @return a boolean indicating whether this parameter is currently
+ * locked.
+ */
+ protected final boolean locked() {
+ return (locked);
+ }
+
+ /**
+ * Helper method that can be called by any methods that modify this
+ * parameter (or its subclasses).
+ * If the parameter is currently locked, an IllegalStateException
+ * is thrown.
+ */
+ protected final void enforceParameterLock() {
+ if (locked) {
+ throw (
+ new IllegalStateException(
+ "Parameter '" + getID() + "' may not be changed."));
+ }
+ }
+
+ /**
+ * Sets a default value for this parameter. The default is specified
+ * as a String, and is parsed as a single value specified on the
+ * command line. In other words, default values for "list"
+ * parameters or parameters allowing multiple declarations should be
+ * set using setDefault(String[]), as JSAP
+ * would otherwise treat the entire list of values as a single value.
+ *
+ * @param defaultValue the default value for this parameter.
+ */
+ protected final void _setDefault(String defaultValue) {
+ if (defaultValue == JSAP.NO_DEFAULT) {
+ this.defaultValue = null;
+ } else {
+ this.defaultValue = new String[1];
+ this.defaultValue[0] = defaultValue;
+ }
+ }
+
+ /**
+ * Sets one or more default values for this parameter. This method
+ * should be used whenever a parameter has more than one default
+ * value.
+ * @param defaultValues the default values for this parameter.
+ */
+ protected final void _setDefault(String[] defaultValues) {
+ this.defaultValue = defaultValues;
+ }
+
+ /**
+ * Adds a single default value to any currently defined for this
+ * parameter.
+ * @param defaultValue the default value to add to this parameter.
+ */
+ public final void addDefault(String defaultValue) {
+ if (defaultValue != JSAP.NO_DEFAULT) {
+ if (this.defaultValue == null) {
+ this.defaultValue = new String[0];
+ }
+ int defaultValueCount = this.defaultValue.length + 1;
+ String[] newDefaultValue = new String[defaultValueCount];
+ for (int i = 0; i < defaultValueCount - 1; ++i) {
+ newDefaultValue[i] = this.defaultValue[i];
+ }
+ newDefaultValue[defaultValueCount - 1] = defaultValue;
+ this.defaultValue = newDefaultValue;
+ }
+ }
+
+ /**
+ * Sets the name of this AbstractParameter for the purposes of
+ * usage information. If null, the id will be used.
+ * @param usageName the usage name for this AbstractParameter
+ */
+ protected final void _setUsageName(String usageName) {
+ this.usageName = usageName;
+ }
+
+ /**
+ * Returns the name of this AbstractParameter for the purposes of
+ * usage information. The returned value is by default the id of
+ * this parameter, but can be overridden via setUsageName(String).
+ * @return the name of this AbstractParameter for the purposes of
+ * usage information.
+ */
+ public final String getUsageName() {
+ return (usageName == null ? id : usageName);
+ }
+
+ /**
+ * Returns an array of default values for this parameter, or
+ * null if no default values have been defined.
+ * @return an array of default values for this parameter, or
+ * null if no default values have been defined.
+ */
+ public final String[] getDefault() {
+ return (this.defaultValue);
+ }
+
+ /**
+ * Returns an ArrayList of values resulting from the parsing
+ * of the specified argument. Multiple values may be returned
+ * if the arg is a list (such as a PATH or CLASSPATH variable),
+ * or if the semantics of the parameter type otherwise represent
+ * multiple values.
+ *
+ * @param arg the argument to parse.
+ * @return a List of values resulting from the parse.
+ * @throws ParseException if the specified argument cannot be parsed.
+ */
+ protected abstract List parse(String arg) throws ParseException;
+
+ /**
+ * A convenience method for automatically generating syntax
+ * information based upon a JSAP configuration. A call to
+ * JSAP.getSyntax() returns a String built by calling getSyntax() on
+ * every parameter registered to a JSAP in the order in which they
+ * were registered. This method does not provide a help
+ * description (see getHelp()), but rather the syntax for this
+ * parameter.
+ * @return usage information for this parameter.
+ */
+ public abstract String getSyntax();
+
+ /**
+ * Deprecated - use getSyntax()
+ * @return deprecated - use getSyntax()
+ * @deprecated use getSyntax() instead
+ */
+ public final String getUsage() {
+ return (getSyntax());
+ }
+
+ /**
+ * Returns a description of the option's usage.
+ * @return a textual description of this option's usage
+ */
+ public final String getHelp() {
+ return (help == null ? "" : help);
+ }
+
+ /**
+ * Sets the help text for this parameter.
+ * @param help the help text for this parameter.
+ */
+ public final Parameter setHelp(String help) {
+ this.help = help;
+ return this;
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/ParseException.java b/src/java/com/martiansoftware/jsap/ParseException.java
new file mode 100644
index 0000000..d83e76e
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/ParseException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+/**
+ * A JSAPException subclass notifying the application of a parse error.
+ * Additional information
+ * in the form of an exception may be encapsulated in this object, as in other
+ * JSAPExceptions.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.JSAPException
+ */
+public class ParseException extends JSAPException {
+
+ /**
+ * Creates a new ParseException.
+ */
+ public ParseException() {
+ super();
+ }
+
+ /**
+ * Creates a new ParseException with the specified message.
+ * @param msg the message for this ParseException.
+ */
+ public ParseException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Creates a new ParseException encapsulating the specified Throwable.
+ * @param cause the Throwable to encapsulate.
+ */
+ public ParseException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Creates a new ParseException with the specified message encapsulating the
+ * specified Throwable.
+ * @param msg the message for this ParseException.
+ * @param cause the Throwable to encapsulate.
+ */
+ public ParseException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/Parser.java b/src/java/com/martiansoftware/jsap/Parser.java
new file mode 100644
index 0000000..485e8c4
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/Parser.java
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+/*
+ * 09/26/2002 ML : Modified parseShortForm() and parseLongForm() to allow
+ * options that begin with a minus sign. Previous
+ * behavior assumed that the minus sign indicated another
+ * flag and therefore no value for the current option.
+ */
+package com.martiansoftware.jsap;
+
+import java.util.Iterator;
+
+/**
+ * The class that performs the actual parsing on a set of arguments. This is
+ * created and managed by a JSAP;
+ * developers should never need to access this class directly.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.JSAP
+ */
+class Parser {
+
+ /**
+ * A reference to the JSAP for which this Parser is working.
+ */
+ private JSAP config = null;
+
+ /**
+ * An Iterator through the declared unflagged options, in order of their
+ * declaration.
+ */
+ private Iterator unflaggedOptions = null;
+
+ /**
+ * A reference to the currently expected UnflaggedOption.
+ */
+ private UnflaggedOption curUnflaggedOption = null;
+
+ /**
+ * The array of arguments to parse.
+ */
+ private String[] args = null;
+
+ /**
+ * Boolean indicating whether this Parser has already been run (a parser
+ * can only run once).
+ */
+ private boolean parsed = false;
+
+ /**
+ * The result of the parse.
+ */
+ private JSAPResult result = null;
+
+ /**
+ * Creates a new Parser for the specified JSAP and argument list.
+ * @param config the JSAP for which this Parser is working.
+ * @param args the arguments to parse.
+ */
+ public Parser(JSAP config, String[] args) {
+ this.config = config;
+ this.args = args;
+ this.parsed = false;
+ this.result = new JSAPResult();
+ this.unflaggedOptions = config.getUnflaggedOptionsIterator();
+ advanceUnflaggedOption();
+
+ }
+
+ /**
+ * Advances the current UnflaggedOption pointer to the next UnflaggedOption
+ * (by declaration order).
+ * If there are no more expected UnflaggedOptions, the current
+ * UnflaggedOption pointer is set to null.
+ */
+ private void advanceUnflaggedOption() {
+ if (unflaggedOptions.hasNext()) {
+ curUnflaggedOption = (UnflaggedOption) unflaggedOptions.next();
+ }
+ else {
+ curUnflaggedOption = null;
+ }
+ }
+
+ /**
+ * Instructs the specified parameter to parse the specified value, and
+ * stores the results in the working
+ * JSAPResult. Any ParseExceptions or IllegalMultipleDeclarationExceptions
+ * that are encountered
+ * are associated with the specified parameter.
+ * @param param the parameter to parse the value
+ * @param valueToParse the value to parse
+ */
+ private void processParameter(Parameter param,
+ String valueToParse) {
+
+ // if this argument has already been parsed at least once...
+ if (result.getObject(param.getID()) != null) {
+ if (((param instanceof FlaggedOption)
+ && (!((FlaggedOption) param).allowMultipleDeclarations()))
+ || (param instanceof Switch)
+ || (param instanceof QualifiedSwitch)
+ || ((param instanceof UnflaggedOption)
+ && (!((UnflaggedOption) param).isGreedy()))) {
+ result.addException(param.getID(),
+ new IllegalMultipleDeclarationException(param.getID()));
+ }
+ }
+
+ if (param instanceof QualifiedSwitch) {
+ result.registerQualifiedSwitch(param.getID(), true);
+ }
+
+ try {
+ result.add(param.getID(), param.parse(valueToParse));
+ }
+ catch (ParseException pe) {
+ result.addException(param.getID(), pe);
+ }
+ }
+
+ /**
+ * Parses the next argument in the array.
+ *
+ * @param args the array containing the arguments
+ * @param index the index of the next argument to parse
+ * @return the index of the next argument to parse
+ */
+ private int parseArg(String[] args, int index) {
+ if (args[index].startsWith("--") && !args[index].equals("--")) {
+ return(parseLongForm(args, index));
+ }
+ else if (args[index].startsWith("-") && !args[index].equals("-") && !args[index].equals("--")) {
+ return(parseShortForm(args, index));
+ }
+ else {
+ return(parseUnflaggedOption(args, index));
+ }
+ }
+
+ /**
+ * Processes the default values for this parser's JSAP, and stores their
+ * values in the
+ * working JSAPResult
+ */
+ private void processDefaults() {
+ Defaults defaults = config.getDefaults(result);
+ for (Iterator i = defaults.idIterator(); i.hasNext();) {
+ String paramID = (String) i.next();
+ if (result.getObject(paramID) == null) {
+ String[] paramValues = defaults.getDefault(paramID);
+ if (paramValues != null) {
+ int z = paramValues.length;
+ for (int index = 0; index < z; ++index) {
+ processParameter(
+ config.getByID(paramID),
+ paramValues[index]);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks the current JSAPResult against the JSAP's configuration, and
+ * stores a
+ * RequiredParameterMissingException in the JSAPResult for any missing
+ * parameters.
+ */
+ private void enforceRequirements() {
+ IDMap idMap = config.getIDMap();
+ for (Iterator i = idMap.idIterator(); i.hasNext();) {
+ String id = (String) i.next();
+ Object o = config.getByID(id);
+ if (o instanceof Option) {
+ Option option = (Option) o;
+ if (option.required() && (result.getObject(id) == null)) {
+
+ if (result.getException(id) == null) {
+ result.addException(option.getID(),
+ new RequiredParameterMissingException(id));
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Runs the parser.
+ * @return a JSAPResult representing the parsed data.
+ */
+ public JSAPResult parse() {
+ if (parsed) {
+ result.addException(null,
+ new JSAPException("This Parser has already run."));
+ }
+ else {
+ result.setValuesFromUser(true);
+ preregisterQualifiedSwitches();
+ int z = args.length;
+ int i = 0;
+ while (i < z) {
+ i = parseArg(args, i);
+ }
+ result.setValuesFromUser(false);
+ processDefaults();
+ enforceRequirements();
+ this.parsed = true;
+ }
+ return(result);
+ }
+
+ /**
+ * Loops through all parameters, informing the JSAPResult
+ * of any QualifiedSwitches so it can assume they're not present.
+ */
+ private void preregisterQualifiedSwitches() {
+ for (Iterator iter = config.getIDMap().idIterator(); iter.hasNext();) {
+ String thisID = (String) iter.next();
+ Parameter param = config.getByID(thisID);
+ if (param instanceof QualifiedSwitch) {
+ result.registerQualifiedSwitch(thisID, false);
+ }
+ }
+
+ }
+ /**
+ * Parses the long form of an Option or Switch (i.e., preceded by a double
+ * hyphen).
+ *
+ * @param args the argument array being parsed
+ * @param index the index of the current argument to parse
+ * @return the index of the next argument to parse
+ */
+ private int parseLongForm(String[] args, int index) {
+ int equalsIndex = args[index].indexOf('=');
+ int colonIndex = args[index].indexOf(':'); // KPB
+ String paramFlag = null;
+ String paramEquals = null;
+ // KPB<<<<<<
+ String paramColon = null;
+ // if no equals sign and no colon for QualifiedSwitches, this whole argument is the long flag
+ if (equalsIndex == -1 && colonIndex == -1) {
+ paramFlag = args[index].substring(2);
+ }
+ if (equalsIndex != -1) {
+ // there's a value assignment in this argument, too; possible colons are taken as part of the value
+ paramFlag = args[index].substring(2, equalsIndex);
+ paramEquals = args[index].substring(equalsIndex + 1);
+ }
+ if (equalsIndex == -1 && colonIndex != -1) {
+ // we have a QualifiedSwitch
+ paramFlag = args[index].substring(2, colonIndex);
+ paramColon = args[index].substring(colonIndex); // parameter starts with ':'
+ }
+ // <<<<<<KPB
+ ++index;
+
+ // we'll need to reference the appropriate parameter both as a Flagged
+ // and as
+ // an Parameter down below.
+ Flagged option = config.getByLongFlag(paramFlag);
+ Parameter param = (Parameter) option;
+
+ // unknown long flag
+ if (option == null) {
+ result.addException(null, new UnknownFlagException(paramFlag));
+ }
+ else {
+ // if it's a switch, first check to make sure no value is specified.
+ if (option instanceof Switch) {
+ if (equalsIndex != -1) {
+ result.addException(param.getID(),
+ new SyntaxException("Switch \""
+ + paramFlag
+ + "\" does not take any parameters."));
+ }
+ else {
+ processParameter(param, null);
+ }
+ } else if (param instanceof QualifiedSwitch) {
+ String paramValue = null;
+ if (colonIndex == -1) {
+ processParameter(param, null);
+ } else {
+ processParameter(param, args[index-1].substring(colonIndex + 1));
+ }
+
+ } else {
+ // it's an option
+ if (equalsIndex == -1) {
+ // no "=" supplied on command line, so next item must
+ // contain the value
+
+// ML: Changed this and the corresponding line in
+// parseShortForm. Longer version (commented below) would
+// not allow values that begin with a minus sign.
+// if ((index >= args.length) || args[index].startsWith("-")) {
+ if (index >= args.length) {
+ result.addException(param.getID(),
+ new SyntaxException("No value specified for option \""
+ + paramFlag + "\""));
+ }
+ else {
+ paramEquals = args[index];
+ ++index;
+ processParameter(param, paramEquals);
+ }
+ }
+ else {
+ processParameter(param, paramEquals);
+ }
+ }
+ }
+ return(index);
+ }
+
+ /**
+ * Parses the short form of an Option or Switch (i.e., preceded by a single
+ * hyphen).
+ *
+ * @param args the argument array being parsed
+ * @param index the index of the current argument to parse
+ * @return the index of the next argument to parse
+ */
+ private int parseShortForm(String[] args, int index) {
+ Character paramFlag = null;
+ int equalsIndex = args[index].indexOf('=');
+ int parseTo = args[index].length();
+ if (equalsIndex != -1) {
+ parseTo = equalsIndex;
+ }
+
+ // loop through all the single characters up to the equals sign (if
+ // there is one) or the end
+ // of the argument
+ for (int charPos = 1; charPos < parseTo; ++charPos) {
+
+ // paramFlag is the single short character used as a flag.
+ // multiple flags might exist here,
+ // which is why we're looping through them.
+ paramFlag = new Character(args[index].charAt(charPos));
+
+ // we'll need to reference the appropriate parameter both as a
+ // Flagged and as
+ // an Parameter down below.
+ Flagged option = config.getByShortFlag(paramFlag);
+ Parameter param = (Parameter) option;
+
+ // unknown flag
+ if (option == null) {
+ result.addException(null, new UnknownFlagException(paramFlag));
+ }
+ else {
+ // flag is a switch. if it is, first check to make sure a value
+ // isn't specified,
+ // then process it.
+ if (option instanceof Switch) {
+ if (charPos == (equalsIndex - 1)) {
+ result.addException(param.getID(),
+ new SyntaxException("Switch \""
+ + paramFlag
+ + "\" does not take any parameters."));
+ } else {
+// // KPB-start
+// // Qualified switches have a format like "-o:value"
+// if (parseTo >= "-o:".length() && args[index].charAt(charPos+1) == ':') {
+// // we have a QualifiedSwitch
+// processParameter(param, args[index].substring(charPos+1));
+// break; // args[index] completely parsed, so get out of loop
+// }
+// else {
+ processParameter(param, null);
+// }
+// //>>>>>KPB
+ }
+ // flag is not a switch, so we first check to make sure there IS
+ // a value specified.
+ } else if(option instanceof QualifiedSwitch) {
+ // flag is a QualifiedSwitch.
+ if ((args[index].length() > (charPos + 1))
+ && args[index].charAt(charPos+1) == ':') {
+ // the QualifiedSwitch is, in fact, qualified
+ processParameter(param, args[index].substring(charPos+2));// ':' must be part of the argument
+ break; // args[index] completely parsed, so get out of loop
+ }
+ else {
+ processParameter(param, null);
+ }
+
+ } else {
+ // it's an option
+ String paramEquals = null;
+
+ /* We now allow stuff like -b12.
+ *
+ * if (charPos != (parseTo - 1)) {
+ result.addException(param.getID(),
+ new SyntaxException("No value specified for option \""
+ + paramFlag + "\"."));
+ }
+ else {*/
+
+ // if there's an equals sign, the value is whatever is
+ // on the right
+ if (equalsIndex != -1) {
+ paramEquals =
+ args[index].substring(equalsIndex + 1);
+ processParameter(param, paramEquals);
+ }
+ else {
+ if (charPos < parseTo - 1) {
+ // the value is just after the short option (no space)
+ paramEquals = args[index].substring(charPos + 1, parseTo);
+ processParameter(param, paramEquals);
+ break;
+ }
+ else {
+ // otherwise, it's the next argument.
+ ++index;
+
+ // ML: Changed this and the corresponding line in
+ // parseLongForm. Longer version (commented below) would
+ // not allow values that begin with a minus sign.
+ // if ((index >= args.length)
+ // || args[index].startsWith("-")) {
+ if (index >= args.length) {
+ result.addException(param.getID(),
+ new SyntaxException(
+ "No value specified for option \""
+ + paramFlag + "\"."));
+ }
+ else {
+ paramEquals = args[index];
+ processParameter(param, paramEquals);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ++index;
+ return(index);
+ }
+
+ /**
+ * Parses the unflagged form of an Option (i.e., preceded by a no hyphens).
+ *
+ * @param args the argument array being parsed
+ * @param index the index of the current argument to parse
+ * @return the index of the next argument to parse
+ */
+ private int parseUnflaggedOption(String[] args, int index) {
+ if (curUnflaggedOption != null) {
+ processParameter(curUnflaggedOption, args[index]);
+ if (!curUnflaggedOption.isGreedy()) {
+ advanceUnflaggedOption();
+ }
+ }
+ else {
+ result.addException(null, new JSAPException("Unexpected argument: "
+ + args[index]));
+ }
+ return(index + 1);
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/PropertyStringParser.java b/src/java/com/martiansoftware/jsap/PropertyStringParser.java
new file mode 100644
index 0000000..33747f4
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/PropertyStringParser.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import java.util.Properties;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} subclass that provides a means for setting/getting properties.
+ * This
+ * is intended to support StringParsers that might requires some configuration,
+ * such
+ * as DateStringParser (which needs a format String).
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see com.martiansoftware.jsap.stringparsers.DateStringParser
+ */
+public abstract class PropertyStringParser extends StringParser {
+
+ /**
+ * This PropertyStringParser's properties.
+ */
+ private Properties properties = null;
+
+ /**
+ * Replaces all properties in this PropertyStringParser with the
+ * specified Properties.
+ * @param properties the new properties for this PropertyStringParser.
+ */
+ private void setProperties(Properties properties) {
+ this.properties = properties;
+ }
+
+ /**
+ * Returns the internal Properties object. If none is currently defined, a
+ * new Properties object is created.
+ * @return the internal Properties object. If none is currently defined, a
+ * new Properties object is created.
+ */
+ private Properties getProperties() {
+ if (properties == null) {
+ setProperties(new Properties());
+ }
+ return (properties);
+ }
+
+ /**
+ * Sets the property with the specified key to the specified value.
+ * @param key the key of the property to set.
+ * @param value the value to associated with the specified key.
+ * @see java.util.Properties#setProperty(String,String)
+ */
+ public void setProperty(String key, String value) {
+ Properties properties = getProperties();
+ properties.setProperty(key, value);
+ }
+
+ /**
+ * Returns the property associated with the specified key, or null if no
+ * such
+ * property exists.
+ * @param key the key of the desired property
+ * @return the property associated with the specified key, or null if no
+ * such
+ * property exists.
+ */
+ public String getProperty(String key) {
+ return (getProperties().getProperty(key));
+ }
+
+ /**
+ * Returns the property associated with the specified key, or the specified
+ * default value if no such property exists.
+ * @param key the key of the desired property
+ * @param defaultValue the default value to return if no such property exists
+ * @return the requested property, or the specified default value if no such property exists.
+ */
+ public String getProperty(String key, String defaultValue) {
+ String result = getProperty(key);
+ return (result == null ? defaultValue : result);
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/QualifiedSwitch.java b/src/java/com/martiansoftware/jsap/QualifiedSwitch.java
new file mode 100644
index 0000000..207c0a3
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/QualifiedSwitch.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import com.martiansoftware.jsap.FlaggedOption;
+
+/**
+ * A QualifiedSwitch is a parameter that has something in common with a Switch,
+ * i.e., its presence or absence is significant, but different from a "pure"
+ * Switch it can have an additional value (or values) prefixed by a ':' sign
+ * that qualifies the Switch - making it behave like a FlaggedOption if a value
+ * is specified.
+ * <p>
+ * QualifiedSwitch in fact extends FlaggedOption, providing all of its
+ * functionality including the ability to use any StringParser to parse its
+ * optional value(s).
+ * Values are retrieved from the JSAPResult in the same manner they would
+ * be retrieved for an equivalent FlaggedOption.
+ * <p>
+ * Additionally, the QualifiedSwitch's presence on the command line can be
+ * determined via JSAPResult.getBoolean(id). This presents a small challenge
+ * in the unlikely event that you're also using a BooleanStringParser with
+ * the QualifiedSwitch; if you are, JSAPResult.getBoolean(id) will <b>not</b>
+ * return the optional values, but will still signify the QualifiedSwitch's
+ * presence. Boolean optional values can be retrieved via
+ * JSAPResult.getBooleanArray(id). The first boolean in the array will be the
+ * first optionally specified boolean value qualifying the switch.
+ * <p>
+ * The following are some examples of a QualifiedSwitch's use:
+ * <ul>
+ * <li><b>-s:value</b> is a QualifiedSwitch with only one qualifying value.</li>
+ * <li><b>-s</b> has no qualifying value.</li>
+ * <li><b>--qswitch:a,b,c</b> (configured with <code>setList(true)</code>
+ * and <code>setListSeparator(',')</code>) has three qualifying values.</li>
+ * </ul>
+ * <p>
+ * Please note that QualifiedSwitch is currently <b>experimental</b>, although
+ * it has no known problems.
+ * <p>
+ * QualifiedSwitch and its supporting code in other JSAP classes was generously
+ * contributed to JSAP by Klaus P. Berg of Siemens AG, Munich, Germany.
+ * @since 1.03
+ * @author Klaus P. Berg, Siemens AG, Munich, Germany
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+ /* ML - switched superclass from Switch to FlaggedOption */
+public final class QualifiedSwitch extends FlaggedOption {
+
+ /**
+ * The current short flag for this UnflaggedOption.
+ * Default is JSAP.NO_SHORTFLAG.
+ */
+// private char shortFlag = JSAP.NO_SHORTFLAG;
+
+ /**
+ * The current long flag for this UnflaggedOption.
+ *Default is JSAP.NO_LONGFLAG.
+ */
+// private String longFlag = JSAP.NO_LONGFLAG;
+
+// private String qualifyingValues; // the qualifying values that are allowed for the switch
+// boolean checkEnumeratedValues = false; // tells the parser if the qualifyingValues are enumerated values
+
+
+ /**
+ * A shortcut constructor that creates a new QualifiedSwitch and configures
+ * its most commonly used settings, including help.
+ * @param id the unique ID for this FlaggedOption.
+ * @param stringParser the StringParser this FlaggedOption should use.
+ * @param defaultValue the default value for this FlaggedOption (may be
+ * null).
+ * @param required if true, this FlaggedOption is required.
+ * @param shortFlag the short flag for this option (may be set to
+ * JSAP.NO_SHORTFLAG for none).
+ * @param longFlag the long flag for this option (may be set to
+ * JSAP.NO_LONGFLAG for none).
+ * @param help the help text for this option (may be set to {@link JSAP#NO_HELP} for none).
+ */
+ public QualifiedSwitch(
+ String id,
+ StringParser stringParser,
+ String defaultValue,
+ boolean required,
+ char shortFlag,
+ String longFlag,
+ String help) {
+
+ super(id, stringParser, defaultValue, required, shortFlag, longFlag, help);
+ }
+
+ /**
+ * A shortcut constructor that creates a new QualifiedSwitch and configures
+ * its most commonly used settings.
+ * @param id the unique ID for this FlaggedOption.
+ * @param stringParser the StringParser this FlaggedOption should use.
+ * @param defaultValue the default value for this FlaggedOption (may be
+ * null).
+ * @param required if true, this FlaggedOption is required.
+ * @param shortFlag the short flag for this option (may be set to
+ * JSAP.NO_SHORTFLAG for none).
+ * @param longFlag the long flag for this option (may be set to
+ * JSAP.NO_LONGFLAG for none).
+ */
+ public QualifiedSwitch(
+ String id,
+ StringParser stringParser,
+ String defaultValue,
+ boolean required,
+ char shortFlag,
+ String longFlag) {
+
+ super(id, stringParser, defaultValue, required, shortFlag, longFlag);
+ }
+
+
+ /**
+ * A shortcut constructor that creates a new QualifiedSwitch
+ *
+ * @param id the unique ID for this QualifiedSwitch.
+ */
+ public QualifiedSwitch(String id) {
+ super(id);
+ }
+
+ /**
+ * Returns syntax instructions for this QualifiedSwitch.
+ * @return syntax instructions for this QualifiedSwitch based upon its current
+ * configuration.
+ */
+ public String getSyntax() {
+ StringBuffer result = new StringBuffer();
+ if (!required()) {
+ result.append("[");
+ }
+
+ if ((getLongFlag() != JSAP.NO_LONGFLAG)
+ || (getShortFlag() != JSAP.NO_SHORTFLAG)) {
+ if (getLongFlag() == JSAP.NO_LONGFLAG) {
+ result.append("-" + getShortFlag());
+ } else if (getShortFlag() == JSAP.NO_SHORTFLAG) {
+ result.append("--" + getLongFlag());
+ } else {
+ result.append(
+ "(-" + getShortFlag() + "|--" + getLongFlag() + ")");
+ }
+ }
+ result.append("[:");
+ String un = getUsageName();
+ char sep = this.getListSeparator();
+ if (this.isList()) {
+ result.append(
+ un + "1" + sep + un + "2" + sep + "..." + sep + un + "N ");
+ } else {
+ result.append("<" + un + ">");
+ }
+ if (!required()) {
+ result.append("]");
+ }
+ result.append("]");
+ return (result.toString());
+ }
+
+
+
+ /**
+ * Creates a new QualifiedSwitchValuesParser to which it delegates the parsing of
+ * the specified argument.
+ * The result is as follows:
+ * <ul>
+ * <li>ArrayList[0] contains a single Boolean that tells the
+ * user whether this QualifiedSwitch is present or not.
+ * <li>ArrayList[1] is a string that contains the qualifying value.
+ * </ul>
+ *
+ * @param arg the argument to parse.
+ * @return an ArrayList containing the parse results.
+ * @throws ParseException if the specified parameter cannot be parsed.
+ */
+// protected final List parse(String arg) throws ParseException {
+// List result = new java.util.ArrayList();
+// if (arg != null && arg.startsWith(":")) {
+// result.add(Boolean.TRUE); // flag is present
+// if (checkEnumeratedValues) {
+// result.add((new EnumeratedStringParser(qualifyingValues)).parse(arg.substring(1))); // ad the value allowed
+// }
+// else {
+// result.add((new StringStringParser()).parse(arg.substring(1))); // add arbitrary string value
+// }
+// }
+// else {
+// result.add((new BooleanStringParser()).parse(arg));
+// }
+// return result;
+// }
+
+// /**
+// * Returns usage instructions for this Switch.
+// * @return usage instructions for this Switch based upon its current
+// * configuration.
+// */
+// public String getSyntax() {
+// StringBuffer buf = new StringBuffer();
+// boolean shortFlag = false;
+// buf.append("[");
+// if (getShortFlag() != JSAP.NO_SHORTFLAG) {
+// buf.append("-" + getShortFlag());
+// shortFlag = true;
+// }
+// if (getLongFlag() != JSAP.NO_LONGFLAG) {
+// if (shortFlag) {
+// buf.append("|");
+// }
+// buf.append("--" + getLongFlag());
+// }
+// buf.append("[:");
+// if (checkEnumeratedValues) {
+// buf.append(qualifyingValues.replace(';', '|'));
+// }
+// else {
+// buf.append(qualifyingValues);
+// }
+// buf.append("]]");
+// return(buf.toString());
+// }
+}
diff --git a/src/java/com/martiansoftware/jsap/RequiredParameterMissingException.java b/src/java/com/martiansoftware/jsap/RequiredParameterMissingException.java
new file mode 100644
index 0000000..5d934a3
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/RequiredParameterMissingException.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+/**
+ * An exception indicating that a required parameter was missing from the
+ * supplied arguments and defaults.
+ *
+ * @see FlaggedOption#setAllowMultipleDeclarations(boolean)
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.Option#required()
+ */
+public class RequiredParameterMissingException extends JSAPException {
+
+ /**
+ * The unique ID of the parameter that was missing.
+ */
+ private String id = null;
+
+ /**
+ * Creates a new RequiredParameterMissingException referencing the
+ * specified parameter.
+ * @param paramID the unique ID of the parameter that was missing.
+ */
+ public RequiredParameterMissingException(String paramID) {
+ super("Parameter '" + paramID + "' is required.");
+ this.id = paramID;
+ }
+
+ /**
+ * Returns the unique ID of the parameter that was missing.
+ * @return the unique ID of the parameter that was missing.
+ */
+ public String getID() {
+ return (this.id);
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/SimpleJSAP.java b/src/java/com/martiansoftware/jsap/SimpleJSAP.java
new file mode 100644
index 0000000..7f25182
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/SimpleJSAP.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.martiansoftware.util.StringUtils;
+
+/** A simple interface to {@link com.martiansoftware.jsap.JSAP} that handles directly help,
+ * explanation and an array of parameters.
+ *
+ * <P>More precisely, instances of this class behave exactly like those of
+ * {@link com.martiansoftware.jsap.JSAP}, but additionally require a command name, an explanation
+ * (a wordy description) and an array of parameters (which will be registered automatically).
+ * A switch activated by <samp>--help</samp> is always
+ * registered under the ID <samp>help</samp>.
+ *
+ * <p>A message will be automatically printed upon invocation
+ * of the <code>parse()</code> methods if an error occurs, or if the help switch is detected. In this
+ * case, {@link #messagePrinted()} will return true, and the caller may check this condition
+ * to stop its actions.
+ *
+ * <P>The screen width used to format the help text may be set using {@link #setScreenWidth(int)}.
+ * The formatter will preserve newlines.
+ * <i>Note: as of 2.0a non-breaking spaces are temporarily disabled until some console encoding
+ * issues have been worked out. - ML</i>
+ *
+ * @author Sebastiano Vigna
+ */
+public class SimpleJSAP extends JSAP {
+
+ /** The screen witdh used for formatting. */
+ private int screenWidth = DEFAULT_SCREENWIDTH;
+
+ /** A wordy explanation. */
+ private String explanation;
+
+ /** True if the last parsing caused the help text to be printed. */
+ private boolean messagePrinted;
+
+ /** The name of the command that will appear in the help message. */
+ final private String name;
+
+ /** Creates a new simple JSAP with default screen width.
+ *
+ * @param name the name of the command for which help will be printed.
+ * @param explanation a wordy explanation of the command, or <code>null</code> for no explanation.
+ * @param parameter an array of parameters, which will be registered for you, or <code>null</code>.
+ */
+
+ public SimpleJSAP( final String name, final String explanation, final Parameter[] parameter ) throws JSAPException {
+ super();
+
+ this.name = name;
+ this.explanation = explanation;
+
+ final Switch help = new Switch( "help", JSAP.NO_SHORTFLAG, "help" );
+ help.setHelp( "Prints this help message." );
+ this.registerParameter( help );
+
+ if ( parameter != null )
+ for( int i = 0; i < parameter.length; i++ ) this.registerParameter( parameter[ i ] );
+ }
+
+ /** Creates a new simple JSAP with default screen width.
+ *
+ * @param name the name of the command for which help will be printed.
+ * @param explanation a wordy explanation of the command, or <code>null</code> for no explanation.
+ */
+
+ public SimpleJSAP( final String name, final String explanation ) throws JSAPException {
+ this( name, explanation, null );
+ }
+
+ /** Creates a new simple JSAP with a help switch, no explanation and default screen width.
+ *
+ * @param name the name of the command for which help will be printed.
+ */
+
+ public SimpleJSAP( final String name ) throws JSAPException {
+ this( name, null );
+ }
+
+ public JSAPResult parse( String arg ) {
+ JSAPResult jsapResult = super.parse( arg );
+ messagePrinted = printMessageIfUnsuccessfulOrHelpRequired( jsapResult );
+ return jsapResult;
+ }
+
+ public JSAPResult parse( String[] arg ) {
+ JSAPResult jsapResult = super.parse( arg );
+ messagePrinted = printMessageIfUnsuccessfulOrHelpRequired( jsapResult );
+ return jsapResult;
+ }
+
+ /** Checks the given JSAP result for errors or help requests and acts accordingly.
+ *
+ * @param jsapResult the result of a JSAP parsing.
+ * @return true if some message has been printed (i.e., if there was an error or a help request).
+ */
+
+ private boolean printMessageIfUnsuccessfulOrHelpRequired( final JSAPResult jsapResult ) {
+ if ( ! ( jsapResult.success() ) || jsapResult.getBoolean( "help" ) ) {
+
+ // To avoid spurious missing argument errors we never print errors if help is required.
+ if ( ! jsapResult.getBoolean( "help" ) ) {
+ for ( Iterator err = jsapResult.getErrorMessageIterator(); err.hasNext(); )
+ System.err.println( "Error: " + err.next() );
+
+ return true;
+ }
+ System.err.println();
+ System.err.println( "Usage:" );
+
+ List l = StringUtils.wrapToList( name + " " + getUsage(), screenWidth );
+ for( Iterator i = l.iterator(); i.hasNext(); ) System.err.println( " " + i.next().toString() );
+
+ if ( explanation != null ) {
+ System.err.println();
+ l = StringUtils.wrapToList( explanation, screenWidth );
+ for( Iterator i = l.iterator(); i.hasNext(); ) System.err.println( i.next() );
+ }
+
+ System.err.println();
+ System.err.println();
+ System.err.println( getHelp( screenWidth ) );
+ return true;
+ }
+
+ return false;
+ }
+
+ /** Returns the current screen width.
+ *
+ * <P>This value will be passed to {@link com.martiansoftware.jsap.JSAP#getHelp(int)}, and used
+ * to format the explanation.
+ *
+ * @return the current screen width.
+ */
+ public int getScreenWidth() {
+ return screenWidth;
+ }
+
+ /** Sets the screen width.
+ * @param screenWidth the new screen width.
+ * @return this simple JSAP.
+ */
+
+ public SimpleJSAP setScreenWidth( final int screenWidth ) {
+ this.screenWidth = screenWidth;
+ return this;
+ }
+
+ /** Returns true if the last parsing caused the a message to be printed.
+ *
+ * @return true if the last parsing caused a message to be printed.
+ */
+
+ public boolean messagePrinted() {
+ return messagePrinted;
+ }
+}
\ No newline at end of file
diff --git a/src/java/com/martiansoftware/jsap/StringParser.java b/src/java/com/martiansoftware/jsap/StringParser.java
new file mode 100644
index 0000000..2d998d7
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/StringParser.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+/**
+ * Class responsible for converting Strings into Objects. Each subclass of
+ * StringParser
+ * is capable of parsing a String into a different class of object. <b>To
+ * extend JSAP to
+ * recognize new data types, a new StringParser must be created for the new
+ * type.</b><br>
+ * <br>
+ * "List" options (such as your environment's PATH and CLASSPATH variables)
+ * that contain
+ * multiple values are split into individual value tokens prior to the calling
+ * of the
+ * StringParser's parse() method. For example, if you had a StringStringParser
+ * parsing
+ * your PATH environment variable, that StringStringParser's parse() method
+ * would be
+ * called once for each item in the list. As a result, each StringParser only
+ * needs
+ * to know how to create an object based upon a single, simple token.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public abstract class StringParser {
+
+ /**
+ * Performs any initialization not handled by this StringParser's
+ * constructor.
+ * The contract for this method is that it will be called AT LEAST once
+ * before
+ * this object's parse() method is called.<br><br>
+ * In the JSAP API, this method is called every time an Option containing
+ * this StringParser is
+ * registered with a JSAP. If there is an initialization error, this method
+ * should throw a JSAPException to prevent the Option from being registered.
+ * @throws Exception if an initialization error occurs that should prevent
+ * the Option containing this StringParser from being registered.
+ */
+ public void setUp() throws Exception {
+ }
+
+ /**
+ * Performs any cleanup necessary for this StringParser. The contract for
+ * this method is that it MAY be called at any time after the setUp method
+ * has been called. It may be called more than once.<br>
+ * <br>
+ * In the JSAP API, this method is called every
+ * time an Option containing this StringParser is unregistered from a JSAP.
+ * During
+ * finalization, any registered Options are unregistered from a JSAP.
+ */
+ public void tearDown() {
+ }
+
+ /**
+ * Parses the specified argument into an Object of the appropriate type.
+ * If
+ * the specified argument cannot be converted into the desired Object, a
+ * ParseException
+ * should be thrown.<br>
+ * <br>
+ * <b>Note:</b> this method MAY BE CALLED with a <b>null</b> argument.
+ * Take this
+ * into consideration when subclassing!
+ * @param arg the argument to convert to an Object of class appropriate to
+ * the StringParser subclass.
+ * @return the Object resulting from the parsed argument.
+ * @throws ParseException if the specified argument cannot be parsed.
+ */
+ public abstract Object parse(String arg) throws ParseException;
+
+}
diff --git a/src/java/com/martiansoftware/jsap/Switch.java b/src/java/com/martiansoftware/jsap/Switch.java
new file mode 100644
index 0000000..9300b43
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/Switch.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import java.util.List;
+
+import com.martiansoftware.jsap.stringparsers.BooleanStringParser;
+
+/**
+ * A Switch is a parameter whose presence alone is significant; another
+ * commonly used term for a Switch is "Flag".
+ * Switches use a {@link com.martiansoftware.jsap.stringparsers.BooleanStringParser}
+ * internally, so their results can be
+ * obtained from a JSAPResult using
+ * the getBoolean() methods.
+ *
+ * <p>An example of a command line using a Switch is "dosomething -v", where
+ * "-v" might mean "verbose."
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.Flagged
+ * @see com.martiansoftware.jsap.stringparsers.BooleanStringParser
+ */
+public class Switch extends Parameter implements Flagged {
+
+ /**
+ * The current short flag for this UnflaggedOption. Default is
+ * JSAP.NO_SHORTFLAG.
+ */
+ private char shortFlag = JSAP.NO_SHORTFLAG;
+
+ /**
+ * The current long flag for this UnflaggedOption. Default is
+ * JSAP.NO_LONGFLAG.
+ */
+ private String longFlag = JSAP.NO_LONGFLAG;
+
+ /**
+ * Creates a new Switch with the specified unique ID.
+ * @param id the unique ID for this Switch.
+ */
+ public Switch(String id) {
+ super(id);
+ setDefault("FALSE");
+ }
+
+ /**
+ * A shortcut constructor that creates a new Switch and configures all of
+ * its settings, including help.
+ * @param id the unique ID for this Switch.
+ * @param shortFlag the short flag for this Switch (may be set to
+ * JSAP.NO_SHORTFLAG for none).
+ * @param longFlag the long flag for this Switch (may be set to
+ * JSAP.NO_LONGFLAG for none).
+ * @param help the help text for this Switch (may be set to {@link JSAP#NO_HELP}for none).
+ * */
+ public Switch(String id, char shortFlag, String longFlag, String help) {
+ this(id);
+ setShortFlag(shortFlag);
+ setLongFlag(longFlag);
+ setHelp(help);
+ }
+
+ /**
+ * A shortcut constructor that creates a new Switch and configures all of
+ * its settings.
+ * @param id the unique ID for this Switch.
+ * @param shortFlag the short flag for this Switch (may be set to
+ * JSAP.NO_SHORTFLAG for none).
+ * @param longFlag the long flag for this Switch (may be set to
+ * JSAP.NO_LONGFLAG for none).
+ * */
+ public Switch(String id, char shortFlag, String longFlag) {
+ this(id, shortFlag, longFlag, JSAP.NO_HELP);
+ }
+
+ /**
+ * Sets the short flag for this Switch. To use no short flag at all, set
+ * the value to JSAP.NO_SHORTFLAG.
+ * @param shortFlag the short flag for this Switch.
+ * @return the modified Switch
+ */
+ public Switch setShortFlag(char shortFlag) {
+ enforceParameterLock();
+ this.shortFlag = shortFlag;
+ return (this);
+ }
+
+ /**
+ * Returns the short flag for this Switch. If this Switch has no short
+ * flag, the
+ * return value will be equal to JSAP.NO_SHORTFLAG.
+ * @return the short flag for this Switch. If this Switch has no short
+ * flag, the
+ * return value will be equal to JSAP.NO_SHORTFLAG.
+ */
+ public char getShortFlag() {
+ return (shortFlag);
+ }
+
+ /**
+ * Returns the short flag for this Switch. If this Switch has no short
+ * flag, the
+ * return value will be null.
+ * @return the short flag for this Switch. If this Switch has no short
+ * flag, the
+ * return value will be null.
+ */
+ public Character getShortFlagCharacter() {
+ return ((shortFlag == '\0') ? null : new Character(shortFlag));
+ }
+
+ /**
+ * Sets the long flag for this Switch. To use no long flag at all, set
+ * the value to JSAP.NO_LONGFLAG.
+ * @param longFlag the long flag for this Switch.
+ * @return the modified Switch
+ */
+ public Switch setLongFlag(String longFlag) {
+ enforceParameterLock();
+ this.longFlag = longFlag;
+ return (this);
+ }
+
+ /**
+ * Returns the long flag for this Switch. If this Switch has no long flag,
+ * the return
+ * value will be equal to JSAP.NO_LONGFLAG.
+ * @return the long flag for this FlaggedOption. If this FlaggedOption has
+ * no long flag, the return
+ * value will be equal to JSAP.NO_LONGFLAG.
+ */
+ public String getLongFlag() {
+ return (longFlag);
+ }
+
+ /**
+ * Creates a new BooleanStringParser to which it delegates the parsing of
+ * the specified argument.
+ * The result is always a single Boolean.
+ * @param arg the argument to parse.
+ * @return an ArrayList containing a single Boolean.
+ * @throws ParseException if the specified parameter cannot be parsed.
+ */
+ protected List parse(String arg) throws ParseException {
+ List result = new java.util.ArrayList(1);
+ result.add((BooleanStringParser.getParser()).parse(arg));
+ return (result);
+ }
+
+ /**
+ * Returns usage instructions for this Switch.
+ * @return usage instructions for this Switch based upon its current
+ * configuration.
+ */
+ public String getSyntax() {
+ StringBuffer buf = new StringBuffer();
+ boolean shortFlag = false;
+ buf.append("[");
+ if (getShortFlag() != JSAP.NO_SHORTFLAG) {
+ buf.append("-" + getShortFlag());
+ shortFlag = true;
+ }
+ if (getLongFlag() != JSAP.NO_LONGFLAG) {
+ if (shortFlag) {
+ buf.append("|");
+ }
+ buf.append("--" + getLongFlag());
+ }
+ buf.append("]");
+ return (buf.toString());
+ }
+
+ /**
+ * Sets a default value for this parameter. The default is specified
+ * as a String, and is parsed as a single value specified on the
+ * command line. In other words, default values for "list"
+ * parameters or parameters allowing multiple declarations should be
+ * set using setDefault(String[]), as JSAP
+ * would otherwise treat the entire list of values as a single value.
+ *
+ * @param defaultValue the default value for this parameter.
+ * @see #setDefault(String)
+ */
+ public Switch setDefault(String defaultValue) {
+ _setDefault(defaultValue);
+ return (this);
+ }
+
+ /**
+ * Sets one or more default values for this parameter. This method
+ * should be used whenever a parameter has more than one default
+ * value.
+ * @param defaultValues the default values for this parameter.
+ * @see #setDefault(String)
+ */
+ public Switch setDefault(String[] defaultValues) {
+ _setDefault(defaultValues);
+ return (this);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/SyntaxException.java b/src/java/com/martiansoftware/jsap/SyntaxException.java
new file mode 100644
index 0000000..966ccb9
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/SyntaxException.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+/**
+ * An exception indicating that a syntax error was encountered in the argument
+ * list.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class SyntaxException extends JSAPException {
+
+ /**
+ * Creates a new SyntaxException with the specified message.
+ * @param msg a description of the syntax problem.
+ */
+ public SyntaxException(String msg) {
+ super(msg);
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/TestAll.java b/src/java/com/martiansoftware/jsap/TestAll.java
new file mode 100644
index 0000000..41108d9
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/TestAll.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Runs all of the JSAP tests, including those in sub-packages.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class TestAll extends TestCase {
+
+ /**
+ * Returns a collection of all the JSAP tests, including those in
+ * subpackages.
+ * @return a collection of all the JSAP tests, including those in
+ * subpackages.
+ */
+ public static Test suite() {
+ TestSuite suite = new TestSuite("All JUnit Tests");
+ suite.addTest(TestSwitch.suite());
+ suite.addTest(TestOption.suite());
+ suite.addTest(TestFlaggedOption.suite());
+ suite.addTest(TestJSAPConfiguration.suite());
+ suite.addTest(TestParser.suite());
+ suite.addTest(TestDefaults.suite());
+ suite.addTest(TestCommandLineTokenizer.suite());
+ suite.addTest(TestUsageString.suite());
+ suite.addTest(com.martiansoftware.jsap.stringparsers.TestAll.suite());
+ suite.addTest(com.martiansoftware.jsap.defaultsources.TestAll.suite());
+ return (suite);
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/TestCommandLineTokenizer.java b/src/java/com/martiansoftware/jsap/TestCommandLineTokenizer.java
new file mode 100644
index 0000000..a7414a6
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/TestCommandLineTokenizer.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * This junit TestCase runs a barrage of tests against the CommandLineTokenizer.
+ * This TestCase is unusual for this project in that it contains a main()
+ * method;
+ * this method is used to generate test methods to paste into this class.
+ * @see CommandLineTokenizer
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class TestCommandLineTokenizer extends TestCase {
+
+ /**
+ * Creates and returns a new Test based upon this class.
+ * @return a new Test based upon this class.
+ */
+ public static Test suite() {
+ return (new TestSuite(TestCommandLineTokenizer.class));
+ }
+
+ /**
+ * Tests for correct parsing of [this is a test].
+ */
+ public void test1() {
+ String cmdLine = "this is a test";
+ String[] tokens = CommandLineTokenizer.tokenize(cmdLine);
+
+ assertEquals(4, tokens.length);
+
+ assertEquals("this", tokens[0]);
+ assertEquals("is", tokens[1]);
+ assertEquals("a", tokens[2]);
+ assertEquals("test", tokens[3]);
+ }
+
+ /**
+ * Tests for corect parsing of [this is a "test"]
+ */
+ public void test2() {
+ String cmdLine = "";
+ String[] tokens = CommandLineTokenizer.tokenize("this is a \"test\"");
+
+ assertEquals(4, tokens.length);
+
+ assertEquals("this", tokens[0]);
+ assertEquals("is", tokens[1]);
+ assertEquals("a", tokens[2]);
+ assertEquals("test", tokens[3]);
+ }
+
+ /**
+ * Tests for correct parsing of ["this is a test"]
+ */
+ public void test3() {
+ String cmdLine = "\"this is a test\"";
+ String[] tokens = CommandLineTokenizer.tokenize(cmdLine);
+
+ assertEquals(1, tokens.length);
+
+ assertEquals("this is a test", tokens[0]);
+ }
+
+ /**
+ * Tests for correct parsing of [this is a "test]
+ */
+ public void test4() {
+ String cmdLine = "this is a \"test";
+ String[] tokens = CommandLineTokenizer.tokenize(cmdLine);
+
+ assertEquals(4, tokens.length);
+
+ assertEquals("this", tokens[0]);
+ assertEquals("is", tokens[1]);
+ assertEquals("a", tokens[2]);
+ assertEquals("test", tokens[3]);
+ }
+
+ /**
+ * Tests for correct parsing of [thi\s is a \"test]
+ */
+ public void test5() {
+ String cmdLine = "thi\\s is a \\\"test";
+ String[] tokens = CommandLineTokenizer.tokenize(cmdLine);
+
+ assertEquals(4, tokens.length);
+
+ assertEquals("thi\\s", tokens[0]);
+ assertEquals("is", tokens[1]);
+ assertEquals("a", tokens[2]);
+ assertEquals("\"test", tokens[3]);
+ }
+
+ /**
+ * Tests for correct parsing of [thi\s is a \"test\\]
+ */
+ public void test6() {
+ String cmdLine = "thi\\s is a \\\"test\\";
+ String[] tokens = CommandLineTokenizer.tokenize(cmdLine);
+
+ assertEquals(4, tokens.length);
+
+ assertEquals("thi\\s", tokens[0]);
+ assertEquals("is", tokens[1]);
+ assertEquals("a", tokens[2]);
+ assertEquals("\"test\\", tokens[3]);
+ }
+
+ /**
+ * Tests for correct parsing of [thi\s is a \"test\\\"]
+ */
+ public void test7() {
+ String cmdLine = "thi\\s is a \\\"test\\\\\"";
+ String[] tokens = CommandLineTokenizer.tokenize(cmdLine);
+
+ assertEquals(4, tokens.length);
+
+ assertEquals("thi\\s", tokens[0]);
+ assertEquals("is", tokens[1]);
+ assertEquals("a", tokens[2]);
+ assertEquals("\"test\\", tokens[3]);
+ }
+
+ /**
+ * Tests for correct parsing of a null command line.
+ */
+ public void test8() {
+ String[] tokens = CommandLineTokenizer.tokenize(null);
+ assertEquals(0, tokens.length);
+ }
+
+ /**
+ * Tests for correct parsing of a whitespace-only command line.
+ */
+ public void test9() {
+ String cmdLine = " \t\t \t ";
+ String[] tokens = CommandLineTokenizer.tokenize(cmdLine);
+ assertEquals(0, tokens.length);
+ }
+
+ /**
+ * Tests for correct parsing of ["this is a test]
+ */
+ public void test10() {
+ String cmdLine = "\"this is a test";
+ String[] tokens = CommandLineTokenizer.tokenize(cmdLine);
+
+ assertEquals(1, tokens.length);
+
+ assertEquals("this is a test", tokens[0]);
+ }
+
+ /**
+ * A helper method to write additional test cases based upon the specified
+ * argument array.
+ * @param args the argument array that CommandLineTokenizer.tokenize()
+ * should produce.
+ */
+ public static void main(String[] args) {
+
+ System.out.println("public void testXXX(){");
+ System.out.println("\tString cmdLine = \"\";");
+ System.out.println(
+ "\tString[] tokens = CommandLineTokenizer.tokenize(cmdLine);");
+ System.out.println("\n");
+ System.out.println(
+ "\tassertEquals(" + args.length + ", tokens.length);\n");
+ for (int i = 0; i < args.length; ++i) {
+ System.out.println(
+ "\tassertEquals(\"" + args[i] + "\", tokens[" + i + "]);");
+ }
+ System.out.println("}");
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/TestDefaults.java b/src/java/com/martiansoftware/jsap/TestDefaults.java
new file mode 100644
index 0000000..7b22c5a
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/TestDefaults.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Properties;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import com.martiansoftware.jsap.defaultsources.PropertyDefaultSource;
+
+/**
+ * Tests JSAP's handling of default values.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class TestDefaults extends TestCase {
+
+ /**
+ * JSAP object created in setUp()
+ */
+ private JSAP jsap = null;
+
+ /**
+ * Returns the tests defined in this class.
+ * @return the tests defined in this class.
+ */
+ public static Test suite() {
+ return (new TestSuite(TestDefaults.class));
+ }
+
+ /**
+ * Ensures that the setUp() method was successful.
+ */
+ public void testConfig() {
+ Switch b = (Switch) jsap.getByID("b");
+ assertNotNull(b);
+ Switch b2 = (Switch) jsap.getByShortFlag('b');
+ assertNotNull(b2);
+ assertEquals(b, b2);
+ }
+
+ /**
+ * Tests the parameter-level defaults.
+ */
+ public void testSimpleDefault() {
+ assertNotNull(jsap);
+
+ String[] args = { "-a", "2a 2b 2c" };
+ JSAPResult result = null;
+
+ result = jsap.parse(args);
+ assertEquals(true, result.success());
+
+ assertEquals(true, result.getBoolean("a"));
+ assertEquals("field1-default", result.getString("field1"));
+ assertEquals(false, result.getBoolean("b"));
+
+ // attempt to throw a ClassCastException
+ try {
+ String s = result.getString("a");
+ fail("Switch returned a String [" + s + "]");
+ } catch (Exception e) {
+ // this is normal
+ }
+ }
+
+ /**
+ * Another test of parameter-level defaults.
+ */
+ public void testDefaults2() {
+ assertNotNull(jsap);
+ String[] args = { "-b", "--field1", "HELLO" };
+ JSAPResult result = null;
+ result = jsap.parse(args);
+ assertEquals(true, result.success());
+ assertEquals(false, result.getBoolean("a"));
+ assertEquals(true, result.getBoolean("b"));
+ assertEquals("HELLO", result.getString("field1"));
+ assertEquals(0, result.getObjectArray("field2").length);
+ }
+
+ /**
+ * Tests JSAP's enforcing of required parameters.
+ */
+ public void testRequired() {
+ FlaggedOption requiredOption = new FlaggedOption("required");
+ requiredOption.setRequired(true);
+ requiredOption.setLongFlag("required");
+ try {
+ jsap.registerParameter(requiredOption);
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+ String[] args = { "-b", "--field1", "HELLO" };
+
+ JSAPResult result = null;
+
+ result = jsap.parse(args);
+ assertEquals(
+ "Required field not provided, but no exception thrown.",
+ false,
+ result.success());
+
+ String[] args2 =
+ { "-b", "--field1", "HELLO", "--required", "requiredinfo" };
+
+ result = jsap.parse(args2);
+ assertEquals(true, result.success());
+ assertNotNull(result);
+ assertEquals(false, result.getBoolean("a"));
+ assertEquals(true, result.getBoolean("b"));
+ assertEquals("HELLO", result.getString("field1"));
+ assertEquals(0, result.getObjectArray("field2").length);
+ assertEquals("requiredinfo", result.getString("required"));
+
+ jsap.unregisterParameter(requiredOption);
+ requiredOption.setDefault("required_default");
+ try {
+ jsap.registerParameter(requiredOption);
+ } catch (JSAPException e) {
+ fail(e.getMessage());
+ }
+ result = null;
+ result = jsap.parse(args);
+ assertEquals(true, result.success());
+ assertEquals("required_default", result.getString("required"));
+
+ }
+
+ /**
+ * Tests a single level of property defaults.
+ */
+ public void testOneLevelDefaults() {
+ try {
+ File propertyTest = File.createTempFile("jsap-", ".properties");
+ OutputStream out =
+ new BufferedOutputStream(new FileOutputStream(propertyTest));
+ Properties properties = new Properties();
+ properties.setProperty("field1", "FromPropertyFile");
+ properties.setProperty("a", "true");
+ properties.store(
+ out,
+ "JUnit test for " + this.getClass().getName());
+ out.close();
+ PropertyDefaultSource pds =
+ new PropertyDefaultSource(propertyTest.getAbsolutePath(), true);
+
+ jsap.registerDefaultSource(pds);
+
+ JSAPResult result = null;
+ String[] args = { "-b", "--field1", "HELLO" };
+ result = jsap.parse(args);
+ assertEquals(true, result.success());
+ assertNotNull(result);
+ assertEquals("HELLO", result.getString("field1"));
+
+ String[] args2 = { "-b" };
+ result = jsap.parse(args2);
+ assertEquals(true, result.success());
+
+ assertNotNull(result);
+ assertEquals("FromPropertyFile", result.getString("field1"));
+ assertEquals(true, result.getBoolean("a"));
+ } catch (IOException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Configures the JSAP object for the tests.
+ * @throws JSAPException if the JSAP object cannot be instantiated.
+ */
+ public void setUp() throws JSAPException {
+ // set up a command line parser for the syntax
+ // [-a] [-b] [--field1 field1] [field2 field3 field4]
+ jsap = new JSAP();
+
+ Switch a = new Switch("a");
+ a.setShortFlag('a');
+ jsap.registerParameter(a);
+
+ Switch b = new Switch("b");
+ b.setShortFlag('b');
+ jsap.registerParameter(b);
+
+ FlaggedOption field1 = new FlaggedOption("field1");
+ field1.setLongFlag("field1");
+ field1.setDefault("field1-default");
+ jsap.registerParameter(field1);
+
+ UnflaggedOption field2 = new UnflaggedOption("field2");
+ field2.setGreedy(true);
+ jsap.registerParameter(field2);
+ }
+
+ /**
+ * Cleans up the JSAP object.
+ */
+ public void tearDown() {
+ jsap = null;
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/TestFlaggedOption.java b/src/java/com/martiansoftware/jsap/TestFlaggedOption.java
new file mode 100644
index 0000000..f34d5b5
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/TestFlaggedOption.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class TestFlaggedOption extends TestCase {
+
+ /**
+ * Creates a TestCase with the specified name.
+ * @param name the name for this TestCase.
+ */
+ public TestFlaggedOption(String name) {
+ super(name);
+ }
+
+ /**
+ * Returns a suite of all tests defined in this class.
+ * @return a suite of all tests defined in this class.
+ */
+ public static Test suite() {
+ return (new TestSuite(TestFlaggedOption.class));
+ }
+
+ /**
+ * Tests the ability to set/get short flags.
+ */
+ public void testShortFlag() {
+ FlaggedOption option = new FlaggedOption("testOption");
+ option.setShortFlag('x');
+ assertEquals('x', option.getShortFlag());
+ assertEquals(new Character('x'), option.getShortFlagCharacter());
+ }
+
+ /**
+ * Tests the ability to set/get long flags.
+ */
+ public void testLongFlag() {
+ FlaggedOption option = new FlaggedOption("testOption");
+ option.setLongFlag("test");
+ assertEquals("test", option.getLongFlag());
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/TestJSAPConfiguration.java b/src/java/com/martiansoftware/jsap/TestJSAPConfiguration.java
new file mode 100644
index 0000000..c17e799
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/TestJSAPConfiguration.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Tests the JSAPConfiguration class
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class TestJSAPConfiguration extends TestCase {
+
+ /**
+ * Returns a suite of tests defined by this class.
+ * @return a suite of tests defined by this class.
+ */
+ public static Test suite() {
+ return (new TestSuite(TestJSAPConfiguration.class));
+ }
+
+ /**
+ * Tests various configuration situations, such as changing properties of
+ * registered
+ * parameters, retrieving parameters, etc.
+ */
+ public void testConfigurationGymnastics() {
+ JSAP config = new JSAP();
+ FlaggedOption option = new FlaggedOption("testOption");
+
+ // this registration should fail - it's a flagged option with no flags
+ try {
+ config.registerParameter(option);
+ fail("Successfully registered a FlaggedOption with no flags!");
+ } catch (JSAPException e) {
+ // this is normal
+ }
+
+ option.setShortFlag('t');
+ option.setLongFlag("test");
+
+ // this registration should go fine
+ try {
+ config.registerParameter(option);
+ } catch (JSAPException e) {
+ fail(e.getMessage());
+ }
+
+ // the option is now locked, so it should be immutable
+ try {
+ option.setRequired(true);
+ fail("locked option was changed!");
+ } catch (Exception e) {
+ // this is normal
+ }
+
+ // duplicate registration should fail
+ try {
+ config.registerParameter(option);
+ fail("Registered the same option ID twice.");
+ } catch (JSAPException e) {
+ // this is normal
+ }
+
+ // this registration should work
+ FlaggedOption option2 = new FlaggedOption("test2");
+ option2.setShortFlag('2');
+ try {
+ config.registerParameter(option2);
+ } catch (JSAPException e) {
+ fail(e.getMessage());
+ }
+
+ // registering a duplicate shortflag should fail
+ FlaggedOption option3 = new FlaggedOption("test3");
+ option3.setShortFlag('2');
+ try {
+ config.registerParameter(option3);
+ fail("Registered the same short flag twice.");
+ } catch (JSAPException e) {
+ // this is normal
+ }
+
+ FlaggedOption option2b = (FlaggedOption) config.getByShortFlag('2');
+ assertEquals(option2, option2b);
+
+ FlaggedOption optionb = (FlaggedOption) config.getByLongFlag("test");
+ assertEquals(option, optionb);
+
+ FlaggedOption nulloption =
+ (FlaggedOption) config.getByLongFlag("nosuchflag");
+ assertNull(nulloption);
+
+ config.unregisterParameter(option);
+ try {
+ option.setRequired(true);
+ } catch (Exception e) {
+ fail("Unable to modify unlocked option.");
+ }
+
+ optionb = (FlaggedOption) config.getByLongFlag("test");
+ assertNull(optionb);
+
+ try {
+ config.registerParameter(option);
+ } catch (Exception e) {
+ fail("Unable to register arg that was previously unregistered.");
+ }
+
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/TestOption.java b/src/java/com/martiansoftware/jsap/TestOption.java
new file mode 100644
index 0000000..dca483e
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/TestOption.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import com.martiansoftware.jsap.stringparsers.StringStringParser;
+
+/**
+ * Tests the Option class
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class TestOption extends TestCase {
+
+ /**
+ * Returns a suite of tests defined by this class.
+ * @return a suite of tests defined by this class.
+ */
+ public static Test suite() {
+ return (new TestSuite(TestOption.class));
+ }
+
+ /**
+ * Tests the various setters and getters on an option.
+ */
+ public void testSettersAndGetters() {
+ FlaggedOption option = new FlaggedOption("testOption");
+
+ assertEquals("testOption", option.getID());
+ option.setList(true);
+ assertEquals(true, option.isList());
+ option.setListSeparator('W');
+ assertEquals('W', option.getListSeparator());
+ option.setAllowMultipleDeclarations(true);
+ assertEquals(true, option.allowMultipleDeclarations());
+ option.setRequired(true);
+ assertEquals(true, option.required());
+ assertNull(option.getStringParser());
+ StringStringParser sop = StringStringParser.getParser();
+ option.setStringParser(sop);
+ assertEquals(sop, option.getStringParser());
+ }
+
+ /**
+ * Tests the ability to parse via the option's parse() method.
+ */
+ public void testParsing() {
+ FlaggedOption option = new FlaggedOption("testOption");
+
+ option.setListSeparator(' ');
+ option.setList(true);
+ List parseResult = null;
+
+ try {
+ parseResult = option.parse("this is a test");
+ } catch (JSAPException e) {
+ fail(e.getMessage());
+ }
+ assertEquals(4, parseResult.size());
+ assertEquals("this", parseResult.get(0));
+ assertEquals("test", parseResult.get(3));
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/TestParser.java b/src/java/com/martiansoftware/jsap/TestParser.java
new file mode 100644
index 0000000..b4abc75
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/TestParser.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import com.martiansoftware.jsap.stringparsers.IntegerStringParser;
+import com.martiansoftware.jsap.stringparsers.StringStringParser;
+
+/**
+ * Tests the Parser class.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class TestParser extends TestCase {
+
+ /**
+ * Returns a suite of tests defined by this class.
+ * @return a suite of tests defined by this class.
+ */
+ public static Test suite() {
+ return (new TestSuite(TestParser.class));
+ }
+
+ /**
+ * Tests the ability to parse when allowMultipleDeclarations is set to true.
+ */
+ public void testMultipleDeclarations() {
+ FlaggedOption opt = new FlaggedOption("flagged");
+ opt.setShortFlag('f');
+ opt.setLongFlag("longflag");
+ JSAP jsap = new JSAP();
+
+ try {
+ jsap.registerParameter(opt);
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+
+ String[] args = { "-f", "testone" };
+ JSAPResult result = null;
+ try {
+ result = jsap.parse(args);
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+
+ assertEquals("testone", (String) result.getObject("flagged"));
+
+ String[] args2 = { "-f", "testone", "-f", "testtwo" };
+ result = jsap.parse(args2);
+ assertEquals(false, result.success());
+
+ jsap.unregisterParameter(opt);
+ opt.setAllowMultipleDeclarations(true);
+
+ try {
+ jsap.registerParameter(opt);
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+
+ try {
+ result = jsap.parse(args2);
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+
+ String[] testresult =
+ (String[]) result.getObjectArray("flagged", new String[0]);
+ assertEquals(2, testresult.length);
+ assertEquals("testone", testresult[0]);
+ assertEquals("testtwo", testresult[1]);
+ }
+
+ /**
+ * Tests the parser with both a String and an Integer option.
+ */
+ public void testParser() {
+ FlaggedOption opt = new FlaggedOption("flagged");
+ opt.setShortFlag('f');
+ opt.setLongFlag("longflag");
+ opt.setStringParser(StringStringParser.getParser());
+ JSAP jsap = new JSAP();
+
+ FlaggedOption opt2 = new FlaggedOption("flaggedInteger");
+ opt2.setLongFlag("integer");
+ opt2.setStringParser(IntegerStringParser.getParser());
+
+ try {
+ jsap.registerParameter(opt);
+ jsap.registerParameter(opt2);
+ } catch (JSAPException je) {
+ fail(je.getMessage());
+ }
+
+ String[] args = { "-f", "myflagthing", "--integer", "42" };
+
+ JSAPResult result = null;
+ try {
+ result = jsap.parse(args);
+ } catch (Exception je2) {
+ je2.printStackTrace();
+ fail(je2.getMessage());
+ }
+
+ assertEquals("myflagthing", (String) result.getObject("flagged"));
+ assertEquals(
+ 42,
+ ((Integer) result.getObject("flaggedInteger")).intValue());
+
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/TestSwitch.java b/src/java/com/martiansoftware/jsap/TestSwitch.java
new file mode 100644
index 0000000..af383b1
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/TestSwitch.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Tests the Switch class.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class TestSwitch extends TestCase {
+
+ /**
+ * Creates a new test case with the specified name.
+ * @param name the name for this test case.
+ */
+ public TestSwitch(String name) {
+ super(name);
+ }
+
+ /**
+ * Returns a suite of tests defined by this class
+ * @return a suite of tests defined by this class
+ */
+ public static Test suite() {
+ return (new TestSuite(TestSwitch.class));
+ }
+
+ /**
+ * Tests the ability to retrieve the Switch's ID.
+ */
+ public void testID() {
+ Switch mySwitch = new Switch("mySwitch");
+ assertEquals("mySwitch", mySwitch.getID());
+ }
+
+ /**
+ * Tests the ability to set/get the Switch's short flag.
+ */
+ public void testShortFlag() {
+ Switch mySwitch = new Switch("mySwitch");
+ mySwitch.setShortFlag('c');
+ assertEquals('c', mySwitch.getShortFlag());
+ assertEquals(new Character('c'), mySwitch.getShortFlagCharacter());
+ }
+
+ /**
+ * Tests the ability to set/get the Switch's long flag.
+ */
+ public void testLongFlag() {
+ Switch mySwitch = new Switch("mySwitch");
+ mySwitch.setLongFlag("thisIsMyLongFlag");
+ assertEquals("thisIsMyLongFlag", mySwitch.getLongFlag());
+ }
+
+ /**
+ * Utility method to ensure that the specified List contains a single,
+ * true boolean.
+ * @param a the List to test.
+ */
+ private void ensureTrueList(List a) {
+ assertNotNull(a);
+ assertEquals(1, a.size());
+ assertEquals(a.get(0), new Boolean(true));
+ }
+
+ /**
+ * Utility method to ensure that the specified List contains a single,
+ * false boolean.
+ * @param a the List to test.
+ */
+ private void ensureFalseList(List a) {
+ assertNotNull(a);
+ assertEquals(1, a.size());
+ assertEquals(a.get(0), new Boolean(false));
+ }
+
+ /**
+ * Tests the parsing ability of the Switch.
+ */
+ public void testSwitchParse() {
+ try {
+ Switch mySwitch = new Switch("mySwitch");
+ ensureTrueList(mySwitch.parse(null));
+ ensureTrueList(mySwitch.parse("true"));
+ ensureFalseList(mySwitch.parse("false"));
+ } catch (JSAPException e) {
+ fail(e.getMessage());
+ }
+
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/TestUsageString.java b/src/java/com/martiansoftware/jsap/TestUsageString.java
new file mode 100644
index 0000000..659a627
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/TestUsageString.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Tests the ability to automatically create usage information.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class TestUsageString extends TestCase {
+
+ /**
+ * Creates a new TestCase with the specified name.
+ * @param arg0 the name for this TestCase.
+ */
+ public TestUsageString(String arg0) {
+ super(arg0);
+ }
+
+ /**
+ * Returns a suite of tests defined by this class.
+ * @return a suite of tests defined by this class.
+ */
+ public static Test suite() {
+ return (new TestSuite(TestUsageString.class));
+ }
+
+ /**
+ * Tests usage info for a single option, both required and not required.
+ */
+ public void testUsage1() {
+ JSAP config = new JSAP();
+
+ FlaggedOption opt1 = new FlaggedOption("flaggedOption");
+ opt1.setShortFlag('f');
+ opt1.setLongFlag("flagged");
+ opt1.setRequired(JSAP.REQUIRED);
+ try {
+ config.registerParameter(opt1);
+ } catch (JSAPException e) {
+ fail("Unable to register opt1");
+ }
+ assertEquals("(-f|--flagged)" + JSAP.SYNTAX_SPACECHAR + "<flaggedOption>", config.getUsage());
+
+ config.unregisterParameter(opt1);
+ opt1.setRequired(JSAP.NOT_REQUIRED);
+ try {
+ config.registerParameter(opt1);
+ } catch (JSAPException e) {
+ fail("Unable to register opt1");
+ }
+ assertEquals("[(-f|--flagged)" + JSAP.SYNTAX_SPACECHAR + "<flaggedOption>]", config.getUsage());
+ }
+
+ /**
+ * Tests usage info for a Switch.
+ */
+ public void testUsage2() {
+ JSAP config = new JSAP();
+ Switch sw = new Switch("testSwitch");
+ sw.setShortFlag('s');
+ sw.setLongFlag("switch");
+ try {
+ config.registerParameter(sw);
+ } catch (JSAPException e) {
+ fail("Unable to register sw");
+ }
+ assertEquals("[-s|--switch]", config.getUsage());
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/UnflaggedOption.java b/src/java/com/martiansoftware/jsap/UnflaggedOption.java
new file mode 100644
index 0000000..ade8876
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/UnflaggedOption.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+/**
+ * An option whose meaning is derived from its <i>position in the argument
+ * list</i> rather than a flag
+ * that precedes it. UnflaggedOptions allow the parsing of command lines
+ * without flags, such as
+ * "compressfiles destinationFile file1 file2 file3 file4 ...", where
+ * "destinationFile" is the name of the
+ * file to create, and file1 through file 4 (and beyond) are the names of the
+ * files to compress. The JSAP
+ * that supports this command line has only two options defined: the first
+ * accepts a single destination file,
+ * and the second is "greedy," consuming the remaining unflagged options.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.FlaggedOption
+ * @see com.martiansoftware.jsap.Option
+ */
+public final class UnflaggedOption extends Option {
+
+ /**
+ * Boolean indicating whether or not this UnflaggedOption is greedy.
+ * Default is JSAP.NOT_GREEDY.
+ */
+ private boolean greedy = JSAP.NOT_GREEDY;
+
+ /**
+ * Creates a new UnflaggedOption with the specified unique ID.
+ * @param id the unique ID for this UnflaggedOption.
+ */
+ public UnflaggedOption(String id) {
+ super(id);
+ }
+
+ /**
+ * A shortcut constructor that creates a new UnflaggedOption and configures
+ * its most commonly used settings.
+ * @param id the unique ID for this UnflaggedOption
+ * @param stringParser the StringParser this UnflaggedOption should use.
+ * @param defaultValue the default value for this UnflaggedOption (may be
+ * null).
+ * @param required if true, this UnflaggedOption is required.
+ * @param greedy if true, this UnflaggedOption is greedy.
+ * @param help the help text for this option (may be set to {@link JSAP#NO_HELP} for none).
+ * */
+ public UnflaggedOption(
+ String id,
+ StringParser stringParser,
+ String defaultValue,
+ boolean required,
+ boolean greedy,
+ String help) {
+ this(id);
+ setStringParser(stringParser);
+ setDefault(defaultValue);
+ setRequired(required);
+ setGreedy(greedy);
+ setHelp(help);
+ }
+
+ /**
+ * A shortcut constructor that creates a new UnflaggedOption and configures
+ * its most commonly used settings.
+ * @param id the unique ID for this UnflaggedOption
+ * @param stringParser the StringParser this UnflaggedOption should use.
+ * @param defaultValue the default value for this UnflaggedOption (may be
+ * null).
+ * @param required if true, this UnflaggedOption is required.
+ * @param greedy if true, this UnflaggedOption is greedy.
+ * */
+ public UnflaggedOption(
+ String id,
+ StringParser stringParser,
+ String defaultValue,
+ boolean required,
+ boolean greedy) {
+ this(id);
+ setStringParser(stringParser);
+ setDefault(defaultValue);
+ setRequired(required);
+ setGreedy(greedy);
+ }
+
+ /**
+ * A shortcut constructor that creates a new non-greedy UnflaggedOption with no default value
+ * and configures its most commonly used settings.
+ *
+ * @param id the unique ID for this UnflaggedOption
+ * @param stringParser the StringParser this UnflaggedOption should use.
+ * @param required if true, this UnflaggedOption is required.
+ * @param help the help text for this option (may be set to {@link JSAP#NO_HELP} for none).
+ */
+ public UnflaggedOption(
+ String id,
+ StringParser stringParser,
+ boolean required,
+ String help) {
+ this(id);
+ setStringParser(stringParser);
+ setRequired(required);
+ setGreedy(JSAP.NOT_GREEDY);
+ setHelp(help);
+ }
+
+ /**
+ * Sets whether this UnflaggedOption is greedy. A greedy UnflaggedOption
+ * consumes all the remaining
+ * UnflaggedOptions from the argument list. As a result, only one greedy
+ * UnflaggedOption may be registered with
+ * a JSAP, and it must be the last UnflaggedOption registered.
+ * @param greedy if true, this UnflaggedOption will be greedy.
+ * @return the modified UnflaggedOption
+ */
+ public UnflaggedOption setGreedy(boolean greedy) {
+ enforceParameterLock();
+ this.greedy = greedy;
+ return (this);
+ }
+
+ /**
+ * Sets the name that will be displayed when getUsage() is called
+ * @param usageName the name to use, or null if the id should be used (default)
+ * @return the modified UnflaggedOption
+ */
+ public UnflaggedOption setUsageName(String usageName) {
+ _setUsageName(usageName);
+ return (this);
+ }
+
+ /**
+ * Returns a boolean indicating whether this UnflaggedOption is greedy.
+ * @return a boolean indicating whether this UnflaggedOption is greedy.
+ */
+ public boolean isGreedy() {
+ return (greedy);
+ }
+
+ /**
+ * Returns syntax instructions for this FlaggedOption.
+ * @return syntax instructions for this FlaggedOption based upon its current
+ * configuration.
+ */
+ public String getSyntax() {
+ StringBuffer result = new StringBuffer();
+ if (!required()) {
+ result.append("[");
+ }
+
+ String un = getUsageName();
+ if (this.isGreedy()) {
+ result.append(un + "1" + JSAP.SYNTAX_SPACECHAR + un + "2" + JSAP.SYNTAX_SPACECHAR + "..." + JSAP.SYNTAX_SPACECHAR + un + "N");
+ } else {
+ result.append("<" + un + ">");
+ }
+ if (!required()) {
+ result.append("]");
+ }
+ return (result.toString());
+ }
+
+ /**
+ * Sets whether this UnflaggedOption is a list. Default behavior is
+ * JSAP.NOT_LIST.
+ * @param isList if true, this Option is a list.
+ * @return the modified UnflaggedOption
+ */
+ public UnflaggedOption setList(boolean isList) {
+ super.internalSetList(isList);
+ return (this);
+ }
+
+ /**
+ * Sets the list separator character for this UnflaggedOption. The default
+ * list separator is JSAP.DEFAULT_LISTSEPARATOR.
+ * @param listSeparator the list separator for this Option.
+ * @return the modified UnflaggedOption
+ */
+ public UnflaggedOption setListSeparator(char listSeparator) {
+ super.internalSetListSeparator(listSeparator);
+ return (this);
+ }
+
+ /**
+ * Sets whether this UnflaggedOption is required. Default is
+ * JSAP.NOT_REQUIRED.
+ * @param required if true, this Option will be required.
+ * @return the modified UnflaggedOption
+ */
+ public UnflaggedOption setRequired(boolean required) {
+ super.internalSetRequired(required);
+ return (this);
+ }
+
+ /**
+ * Sets the StringParser to which this UnflaggedOption's parse() method
+ * should delegate.
+ * @param stringParser the StringParser to which this Option's parse()
+ * method should delegate.
+ * @see com.martiansoftware.jsap.StringParser
+ * @return the modified UnflaggedOption
+ */
+ public UnflaggedOption setStringParser(StringParser stringParser) {
+ super.internalSetStringParser(stringParser);
+ return (this);
+ }
+
+ /**
+ * Sets a default value for this parameter. The default is specified
+ * as a String, and is parsed as a single value specified on the
+ * command line. In other words, default values for "list"
+ * parameters or parameters allowing multiple declarations should be
+ * set using setDefault(String[]), as JSAP
+ * would otherwise treat the entire list of values as a single value.
+ *
+ * @param defaultValue the default value for this parameter.
+ * @see #setDefault(String)
+ */
+ public UnflaggedOption setDefault(String defaultValue) {
+ _setDefault(defaultValue);
+ return (this);
+ }
+
+ /**
+ * Sets one or more default values for this parameter. This method
+ * should be used whenever a parameter has more than one default
+ * value.
+ * @param defaultValues the default values for this parameter.
+ * @see #setDefault(String)
+ */
+ public UnflaggedOption setDefault(String[] defaultValues) {
+ _setDefault(defaultValues);
+ return (this);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/UnknownFlagException.java b/src/java/com/martiansoftware/jsap/UnknownFlagException.java
new file mode 100644
index 0000000..2308487
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/UnknownFlagException.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+package com.martiansoftware.jsap;
+
+/**
+ * An exception indicating that a unknown flag has been specified.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.Flagged
+ */
+public class UnknownFlagException extends JSAPException {
+
+ /**
+ * The unknown flag that was encountered.
+ */
+ private String flag = null;
+
+ /**
+ * Creates a new UnknownFlagException referencing the specified parameter.
+ * @param flag the unknown flag that was encountered.
+ */
+ public UnknownFlagException(String flag) {
+ super("Unknown flag '" + flag + "'.");
+ this.flag = flag;
+ }
+
+ /**
+ * Creates a new UnknownFlagException referencing the specified parameter.
+ * @param flag the unknown flag that was encountered.
+ */
+ public UnknownFlagException(Character flag) {
+ super("Unknown flag '" + flag + "'.");
+ this.flag = flag.toString();
+ }
+
+ /**
+ * Returns the unknown flag that was encountered.
+ * @return the unknown flag that was encountered.
+ */
+ public String getFlag() {
+ return (this.flag);
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/UnspecifiedParameterException.java b/src/java/com/martiansoftware/jsap/UnspecifiedParameterException.java
new file mode 100644
index 0000000..23ab8c7
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/UnspecifiedParameterException.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap;
+
+/** An exception thrown when an argument that requires a conversion
+ * (e.g., an integer) has no associated value, but it is retrieved
+ * by means of a type-specified method (e.g., {@link com.martiansoftware.jsap.JSAPResult#getInt(String)}).
+ *
+ * @author Sebastiano Vigna
+ */
+public class UnspecifiedParameterException extends RuntimeException {
+
+ /**
+ * The unique ID of the parameter whose retrieval was attempted.
+ */
+ private String id = null;
+
+ /** Creates a new {@link UnspecifiedParameterException} referencing the
+ * specified parameter.
+ * @param paramID the unique ID of the parameter whose retrieval was attempted.
+ */
+ public UnspecifiedParameterException(String paramID) {
+ super("Parameter '" + paramID + "' has no associated value.");
+ this.id = paramID;
+ }
+
+ /**
+ * Returns the unique ID of the parameter whose retrieval was attempted.
+ * @return the unique ID of the parameter whose retrieval was attempted.
+ */
+ public String getID() {
+ return (this.id);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/ant/DefaultValue.java b/src/java/com/martiansoftware/jsap/ant/DefaultValue.java
new file mode 100644
index 0000000..e453ffd
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/ant/DefaultValue.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.ant;
+
+/**
+ * Provides a means of specifying default values for the jsap task containing
+ * <default> elements.
+ * For detailed information on using the jsap task, see the documentation for
+ * JSAPAntTask.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see JSAPAntTask
+ */
+public class DefaultValue {
+
+ /**
+ * The default value.
+ */
+ private String value = null;
+
+ /**
+ * Sets the default value.
+ * @param text the default value.
+ */
+ public void addText(String text) {
+ this.value = text;
+ }
+
+ /**
+ * Returns the default value.
+ * @return the default value.
+ */
+ public String getValue() {
+ return (value);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/ant/FlaggedOptionConfiguration.java b/src/java/com/martiansoftware/jsap/ant/FlaggedOptionConfiguration.java
new file mode 100644
index 0000000..a65b324
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/ant/FlaggedOptionConfiguration.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.ant;
+
+import java.io.PrintStream;
+
+import com.martiansoftware.jsap.Parameter;
+import com.martiansoftware.jsap.FlaggedOption;
+import com.martiansoftware.jsap.JSAP;
+
+/**
+ * Stores/provides configuration data for flaggedoptions nested inside a jsap
+ * ant task.
+ * For detailed information on using the jsap task, see the documentation for
+ * JSAPAntTask.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see JSAPAntTask
+ * @see com.martiansoftware.jsap.FlaggedOption
+ */
+
+public class FlaggedOptionConfiguration extends OptionConfiguration {
+
+ /**
+ * The short flag for this option.
+ */
+ private char shortFlag = JSAP.NO_SHORTFLAG;
+
+ /**
+ * The long flag for this option.
+ */
+ private String longFlag = JSAP.NO_LONGFLAG;
+
+ /**
+ * If true, this option may be declared multiple times on a single command
+ * line.
+ */
+ private boolean allowMultipleDeclarations = JSAP.NO_MULTIPLEDECLARATIONS;
+
+ /**
+ * If true, the allowMultipleDeclarations field has been set by the user.
+ */
+ private boolean declaredAllowMultipleDeclarations = false;
+
+ /**
+ * Creates a new FlaggedOptionConfiguration.
+ */
+ public FlaggedOptionConfiguration() {
+ super();
+ }
+
+ /**
+ * Sets the short flag for this option.
+ * @param shortFlag the short flag for this option.
+ */
+ public void setShortflag(char shortFlag) {
+ this.shortFlag = shortFlag;
+ }
+
+ /**
+ * Returns the short flag for this option.
+ * @return the short flag for this option.
+ */
+ public char getShortflag() {
+ return (shortFlag);
+ }
+
+ /**
+ * Sets the long flag for this option.
+ * @param longFlag the long flag for this option.
+ */
+ public void setLongflag(String longFlag) {
+ this.longFlag = longFlag;
+ }
+
+ /**
+ * Returns the long flag for this option.
+ * @return the long flag for this option.
+ */
+ public String getLongflag() {
+ return (longFlag);
+ }
+
+ /**
+ * Specifies whether this option can be declared multiple times on the same
+ * command line.
+ * @param allowMultipleDeclarations if true, this option can be declared
+ * multiple times on the same
+ * command line.
+ */
+ public void setAllowmultipledeclarations(
+ boolean allowMultipleDeclarations) {
+
+ this.allowMultipleDeclarations = allowMultipleDeclarations;
+ declaredAllowMultipleDeclarations = true;
+ }
+
+ /**
+ * Returns a FlaggedOption preconfigured according to this configuration.
+ * @return a FlaggedOption preconfigured according to this configuration.
+ */
+ public Parameter getParameter() {
+ FlaggedOption result = new FlaggedOption(this.getId());
+
+ result.setShortFlag(this.getShortflag());
+ result.setLongFlag(this.getLongflag());
+ result.setRequired(this.getRequired());
+ result.setList(this.getIslist());
+ if (this.declaredListSeparator()) {
+ result.setListSeparator(this.getListseparator());
+ }
+ if (this.declaredAllowMultipleDeclarations) {
+ result.setAllowMultipleDeclarations(this.allowMultipleDeclarations);
+ }
+ setupStringParser(result);
+ result.setDefault(this.getDefaults());
+ return (result);
+ }
+
+ /**
+ * Creates source code for a java method that will instantiate a
+ * FlaggedOption matching this
+ * configuration.
+ * @param methodName the name of the method to create
+ * @param out the PrintStream to which the java source for the method
+ * should be written.
+ */
+ public void createMethod(String methodName, PrintStream out) {
+
+ out.println(" private FlaggedOption " + methodName + "() {");
+ out.println(
+ " FlaggedOption result = new FlaggedOption(\""
+ + this.getId()
+ + "\");");
+ if (getShortflag() != JSAP.NO_SHORTFLAG) {
+ out.println(
+ " result.setShortFlag('" + getShortflag() + "');");
+ }
+ if (getLongflag() != JSAP.NO_LONGFLAG) {
+ out.println(
+ " result.setLongFlag(\"" + getLongflag() + "\");");
+ }
+ if (this.declaredAllowMultipleDeclarations) {
+ out.println(
+ " result.setAllowMultipleDeclarations("
+ + (allowMultipleDeclarations ? "true" : "false")
+ + ");");
+ }
+ super.createParentStatements("result", out);
+ out.println(" return (result);");
+ out.println(" }");
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/ant/JSAPAntTask.java b/src/java/com/martiansoftware/jsap/ant/JSAPAntTask.java
new file mode 100644
index 0000000..3632ed4
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/ant/JSAPAntTask.java
@@ -0,0 +1,545 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.ant;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.JSAPException;
+
+/**
+ * <p>An ANT task that generates a custom subclass of JSAP to simplify its use
+ * in
+ * a program. Rather than create all of the Switches, FlaggedOptions, and
+ * UnflaggedOptions and registering each with the JSAP, the developer does not
+ * need to do anything but instantiate the custom JSAP produced by this task.
+ * </p>
+ *
+ * <p>To use this task, you must first declare it in your ANT build file with a
+ * <taskdef> tag, as follows:</p>
+ *
+ * <p><code>
+ * <taskdef name="jsap" classname="com.martiansoftware.jsap.ant.JSAPAntTask"
+ * classpath="${lib}/[jsap jarfile]"/>
+ * </code></p>
+ *
+ * <p>Note that this <code>taskdef</code> must be placed in your build file
+ * BEFORE your jsap task. The
+ * <code>classpath</code> attribute in the above example assumes that
+ * [jsap jarfile] is the name of the JSAP jarfile you're using, and
+ * is in the directory referenced by the ANT "lib" property.</p>
+ *
+ * <p>Once declared, the jsap task can be used as many times as you wish. The
+ * jsap
+ * task supports the following attributes:</p>
+ * <ul>
+ * <li><b>srcdir</b> (required): the source directory below which the generated
+ * JSAP source code should be placed.</li>
+ * <li><b>classname</b> (required): the fully-qualified classname of the JSAP to
+ * generate.</li>
+ * <li><b>public</b> (optional): "true" or "false" (default false). If true,
+ * the
+ * generated class will be declared public.</li>
+ * </ul>
+ *
+ * <p>The jsap task supports the following nested elements:</p>
+ *
+ * <ul>
+ * <li><b>switch</b> - declares a Switch (com.martiansoftware.jsap.Switch).</li>
+ * <li><b>flaggedoption</b> - declares a FlaggedOption
+ * (com.martiansoftware.jsap.FlaggedOption).</li>
+ * <li><b>unflaggedoption</b> - declares an UnflaggedOption
+ * (com.martiansoftware.jsap.UnflaggedOption).</li>
+ * </ul>
+ *
+ * <p>These nested elements support the following attributes:</p>
+ *
+ * <center>
+ * <table width="95%" border="1" cellpadding="0" cellspacing="0">
+ * <tr>
+ * <td align="center"><b>Attribute</b></td>
+ * <td align="center"><b>Description</b></td>
+ * <td align="center"><b>switch</b></td>
+ * <td align="center"><b>flaggedoption</b></td>
+ * <td align="center"><b>unflaggedoption</b></td>
+ * <td align="center"><b>qualifiedswitch</b></td>
+ * </tr>
+ * <tr>
+ * <td align="center"><b>id</b></td>
+ * <td align="left">Unique id for this parameter. This must be unique among
+ * all parameters defined in this ANT task.</td>
+ * <td align="center">Required</td>
+ * <td align="center">Required</td>
+ * <td align="center">Required</td>
+ * <td align="center">Required</td>
+ * </tr>
+ * <tr>
+ * <td align="center"><b>shortflag</b></td>
+ * <td align="left">Short flag for this parameter. Only the first character
+ * of this attribute is read by the jsap task. This must be unique among all
+ * short
+ * flags defined in this ANT task.</td>
+ * <td align="left">Either <b>shortflag</b> or <b>longflag</b> is required.
+ * Both may be specified.</td>
+ * <td align="left">Either <b>shortflag</b> or <b>longflag</b> is required.
+ * Both may be specified.</td>
+ * <td align="center">N/A</td>
+ * <td align="left">Either <b>shortflag</b> or <b>longflag</b> is required.
+ * Both may be specified.</td>
+ * </tr>
+ * <tr>
+ * <td align="center"><b>longflag</b></td>
+ * <td align="left">Long flag for this parameter. This must be unique among
+ * all long flags defined in this ANT task.</td>
+ * <td align="left">Either <b>shortflag</b> or <b>longflag</b> is required.
+ * Both may be specified.</td>
+ * <td align="left">Either <b>shortflag</b> or <b>longflag</b> is required.
+ * Both may be specified.</td>
+ * <td align="center">N/A</td>
+ * <td align="left">Either <b>shortflag</b> or <b>longflag</b> is required.
+ * Both may be specified.</td>
+ * </tr>
+ * <tr>
+ * <td align="center"><b>required</b></td>
+ * <td align="left">"true" or "false" (default false). Indicates whether the
+ * specified parameter is required.</td>
+ * <td align="center">N/A</td>
+ * <td align="center">Optional</td>
+ * <td align="center">Optional</td>
+ * <td align="center">Optional</td>
+ * </tr>
+ * <tr>
+ * <td align="center"><b>islist</b></td>
+ * <td align="left">"true" or "false" (default false). Indicates whether the
+ * specified parameter can be supplied as a list of values separated by a
+ * delimiter
+ * character.</td>
+ * <td align="center">N/A</td>
+ * <td align="center">Optional</td>
+ * <td align="center">Optional</td>
+ * <td align="center">Optional</td>
+ * </tr>
+ * <tr>
+ * <td align="center"><b>listseparator</b></td>
+ * <td align="left">Specifies the delimiter character to use for list
+ * parameters.
+ * Default is JSAP.DEFAULT_LISTSEPARATOR</td>
+ * <td align="center">N/A</td>
+ * <td align="center">Optional</td>
+ * <td align="center">Optional</td>
+ * <td align="center">Optional</td>
+ * </tr>
+ * <tr>
+ * <td align="center"><b>stringparser</b></td>
+ * <td align="left">Specifies the subclass of
+ * com.martiansoftware.jsap.StringParser
+ * to be used in parsing this parameter's values. If the specified class name
+ * contains
+ * no "dot" characters, it is assumed to be in the package
+ * com.martiansoftware.jsap.stringparsers.
+ * Default value is
+ * com.martiansoftware.jsap.stringparsers.StringStringParser.</td>
+ * <td align="center">N/A</td>
+ * <td align="center">Optional</td>
+ * <td align="center">Optional</td>
+ * <td align="center">Optional</td>
+ * </tr>
+ * <tr>
+ * <td align="center"><b>greedy</b></td>
+ * <td align="left">"true" or "false" (default false). Specifies whether the
+ * unflaggedoption should be "greedy"; that is, should consume all remaining
+ * unflagged arguments from the command line.</td>
+ * <td align="center">N/A</td>
+ * <td align="center">N/A</td>
+ * <td align="center">Optional</td>
+ * <td align="center">N/A</td>
+ * </tr>
+ * </table>
+ * </center>
+ *
+ * <p>All of these nested elements support multiple nested
+ * <code><default></code>
+ * elements. The text content of these tags is used as a default value for the
+ * parameter containing the tag.<p>
+ *
+ * <p>Finally, the <flaggedoption> and <unflaggedoption> support
+ * multiple
+ * nested <property> elements, with similar syntax to ANT's
+ * <property>
+ * elements. These properties are set within the parameter's StringParser,
+ * assuming
+ * it is a subclass of com.martiansoftware.jsap.PropertyStringParser.</p>
+ *
+ * <h2>Example</h2>
+ *
+ * <pre>
+* & lt;taskdef name = "jsap" classname = "com.martiansoftware.jsap.ant.JSAPAntTask"
+ * classpath="${build}"/>
+ *
+ * <target name="createExampleAntJSAP">
+ *
+ * <jsap srcdir="${src}"
+ * classname="com.martiansoftware.jsap.examples.ExampleAntJSAP">
+ *
+ * <!-- create a switch flagged by "v" or "verbose" -->
+ * <switch id="verbose" shortflag="v" longflag="verbose"/>
+ *
+ * <!-- create a required flaggedoption looking for an integer,
+ * flagged by "n" (e.g. "-n 5") -->
+ * <flaggedoption id="num" required="true" shortflag="n"
+ * stringparser="IntegerStringParser">
+ * <default>5</default>
+ * </flaggedoption>
+ *
+ * <!-- create an unflaggedoption that reads all of the unflagged
+ * arguments from the
+ * command line -->
+ * <unflaggedoption id="files" greedy="true" />
+ *
+ * <!-- create a flaggedoption looking for a Date in "MM/DD/YY"
+ * format, flagged by "d"
+ * or "date", defaulting to Christmas, 2002. -->
+ * <flaggedoption id="date" shortflag="d" longflag="date"
+ * stringparser="DateStringParser">
+ * <property name="format" value="MM/DD/YYYY"/>
+ * <default>12/25/2002</default>
+ * </flaggedoption>
+ *
+ * </jsap>
+ *
+ * </target>
+ *</pre>
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.JSAP
+ * @see com.martiansoftware.jsap.Parameter
+ * @see com.martiansoftware.jsap.Switch
+ * @see com.martiansoftware.jsap.FlaggedOption
+ * @see com.martiansoftware.jsap.UnflaggedOption
+ * @see com.martiansoftware.jsap.StringParser
+ * @see com.martiansoftware.jsap.PropertyStringParser
+ */
+public class JSAPAntTask extends Task {
+
+ /**
+ * if true, the generated JSAP class should be declared public.
+ */
+ private boolean isPublic = false;
+
+ /**
+ * the top-level directory holding the source code (probably has a "com"
+ * subdirectory, etc.)
+ */
+ private File srcDir = null;
+
+ /**
+ * the FULL class name of the JSAP subclass to create (i.e.,
+ * "fullpackage.Class").
+ */
+ private String className = null;
+
+ /**
+ * A Vector containing all of the nested parameter configurations, in
+ * declaration order.
+ */
+ private Vector parameterConfigs = null;
+
+ /**
+ * A "Test JSAP" that is instantiated to validate the configuration before
+ * the class file is
+ * generated.
+ */
+ private JSAP jsap = null;
+
+ /**
+ * If true, this JSAP uses FlaggedOptions (used for import statements).
+ */
+ private boolean containsFlaggedOptions = false;
+
+ /**
+ * If true, this JSAP uses UnflaggedOptions (used for import statements).
+ */
+ private boolean containsUnflaggedOptions = false;
+
+ /**
+ * If true, this JSAP uses Switches (used for import statements).
+ */
+ private boolean containsSwitches = false;
+
+ /**
+ * If true, this JSAP's StringParser has properties.
+ */
+ private boolean hasProperties = false;
+
+ /**
+ * Creates a new JSAPAntTask. One JSAPAntTask is created for each
+ * <jsap> section in an
+ * ant built file.
+ */
+ public JSAPAntTask() {
+ parameterConfigs = new Vector();
+ }
+
+ /**
+ * Sets whether the generated JSAP should be declared public. Default is
+ * false.
+ * @param isPublic if true, the generated JSAP will be declared public.
+ */
+ public void setPublic(boolean isPublic) {
+ this.isPublic = isPublic;
+ }
+
+ /**
+ * Sets the top-level source directory under which the generated JSAP class
+ * file should be written.
+ * @param srcDir the top-level source directory under which the generated
+ * JSAP class file should be written.
+ */
+ public void setSrcdir(File srcDir) {
+ this.srcDir = srcDir;
+ }
+
+ /**
+ * Sets the full classname for the generated JSAP.
+ * @param className the full classname for the generated JSAP.
+ */
+ public void setClassname(String className) {
+ this.className = className.trim();
+ }
+
+ /**
+ * Adds a nested FlaggedOptionConfiguration to the generated JSAP.
+ * @param flaggedOptionConfig the nested FlaggedOptionConfiguration to add
+ * to the generated JSAP.
+ */
+ public void addConfiguredFlaggedoption(FlaggedOptionConfiguration flaggedOptionConfig) {
+ containsFlaggedOptions = true;
+ parameterConfigs.add(flaggedOptionConfig);
+ }
+
+ /**
+ * Adds a nested UnflaggedOptionConfiguration to the generated JSAP.
+ * @param unflaggedOptionConfig the nested UnflaggedOptionConfiguration to
+ * add to the generated JSAP.
+ */
+ public void addConfiguredUnflaggedoption(UnflaggedOptionConfiguration unflaggedOptionConfig) {
+ containsUnflaggedOptions = true;
+ parameterConfigs.add(unflaggedOptionConfig);
+ }
+
+ /**
+ * Adds a nested SwitchConfiguration to the generated JSAP.
+ * @param switchConfig the nested SwitchConfiguration to add to the
+ * generated JSAP.
+ */
+ public void addConfiguredSwitch(SwitchConfiguration switchConfig) {
+ containsSwitches = true;
+ parameterConfigs.add(switchConfig);
+ }
+
+ /**
+ * Builds a JSAP that conforms to the configuration in the build file. If
+ * all of the specified
+ * parameters can successfully be registered with the JSAP, the java file
+ * will be written.
+ * @throws JSAPException if there are any problems with the specified
+ * configuration.
+ */
+ private void buildJSAP() throws JSAPException {
+ JSAP jsap = new JSAP();
+ for (Enumeration e = parameterConfigs.elements();
+ e.hasMoreElements();
+ ) {
+
+ ParameterConfiguration pc =
+ (ParameterConfiguration) e.nextElement();
+
+ if (pc.hasProperties()) {
+ hasProperties = true;
+ }
+ jsap.registerParameter(pc.getParameter());
+ }
+ }
+
+ /**
+ * Generates a JSAP java file that implements the specified configuration.
+ * @throws IOException if an I/O error occurs.
+ */
+ private void writeJSAP() throws IOException {
+ int lastDotPos = className.lastIndexOf(".");
+ String packageName = "";
+ String shortClassName = className;
+ if (lastDotPos > -1) {
+ packageName = className.substring(0, lastDotPos);
+ shortClassName = className.substring(lastDotPos + 1);
+ }
+
+ System.out.println("package name: [" + packageName + "]");
+ System.out.println("shortClassName: [" + shortClassName + "]");
+
+ File classFileDir =
+ new File(
+ srcDir.getCanonicalPath()
+ + File.separatorChar
+ + packageName.replace('.', File.separatorChar));
+
+ File classFile = new File(classFileDir, shortClassName + ".java");
+
+ System.out.println(
+ "Creating directory \"" + classFileDir.toString() + "\"");
+ classFileDir.mkdirs();
+ System.out.println("Creating JSAP class file \"" + classFile + "\"");
+ classFile.createNewFile();
+ System.out.println("Created");
+ PrintStream out =
+ new PrintStream(
+ new BufferedOutputStream(new FileOutputStream(classFile)));
+
+ createJavaFile(shortClassName, packageName, out);
+ out.close();
+ }
+
+ /**
+ * Simple utility to capitalize the first letter of the specified String.
+ * @param s the String to represent in proper case.
+ * @return the specified String with the first letter capitalized.
+ */
+ private String properCase(String s) {
+ String result = null;
+ if (s != null) {
+ if (s.length() < 2) {
+ result = s.toUpperCase();
+ } else {
+ result = s.toUpperCase().charAt(0) + s.substring(1);
+ }
+ }
+ return (result);
+ }
+
+ /**
+ * Writes java source code for a JSAP subclass that implements the
+ * configuration specified in the
+ * ant build file.
+ * @param shortClassName the name of the JSAP subclass, sans package name.
+ * @param packageName the name of the package to contain the generated JSAP
+ * subclass.
+ * @param out the PrintStream to which the java source should be written.
+ * @throws IOException if an I/O error occurs.
+ */
+ private void createJavaFile(
+ String shortClassName,
+ String packageName,
+ PrintStream out)
+ throws IOException {
+ if (packageName.length() > 0) {
+ out.println("package " + packageName + ";");
+ out.println();
+ }
+ out.println(" /*");
+ out.println(" * THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT");
+ out.println(" */");
+ out.println();
+ out.println("import com.martiansoftware.jsap.JSAP;");
+ out.println("import com.martiansoftware.jsap.JSAPException;");
+ if (containsSwitches) {
+ out.println("import com.martiansoftware.jsap.Switch;");
+ }
+ if (containsFlaggedOptions) {
+ out.println("import com.martiansoftware.jsap.FlaggedOption;");
+ }
+ if (containsUnflaggedOptions) {
+ out.println("import com.martiansoftware.jsap.UnflaggedOption;");
+ }
+ if (hasProperties) {
+ out.println(
+ "import com.martiansoftware.jsap.PropertyStringParser;");
+ }
+ out.println();
+
+ if (isPublic) {
+ out.print("public ");
+ }
+ out.println("class " + shortClassName + " extends JSAP {");
+ out.println();
+
+ out.println(" public " + shortClassName + "() {");
+ out.println(" super();");
+ out.println(" try {");
+ out.println(" init();");
+ out.println(" } catch (JSAPException e) {");
+ out.println(
+ " throw(new IllegalStateException(e.getMessage()));");
+ out.println(" }");
+ out.println(" }");
+ out.println();
+ out.println(" private void init() throws JSAPException {");
+ for (Enumeration e1 = parameterConfigs.elements();
+ e1.hasMoreElements();
+ ) {
+
+ ParameterConfiguration pc =
+ (ParameterConfiguration) e1.nextElement();
+
+ out.println(
+ " this.registerParameter( create"
+ + properCase(pc.getId())
+ + "() );");
+ }
+ out.println(" }");
+ out.println();
+ for (Enumeration e1 = parameterConfigs.elements();
+ e1.hasMoreElements();
+ ) {
+
+ ParameterConfiguration pc =
+ (ParameterConfiguration) e1.nextElement();
+
+ pc.createMethod("create" + properCase(pc.getId()), out);
+ out.println();
+ }
+ out.println("}");
+ }
+
+ /**
+ * Validates the JSAP configuration and, if successful, writes the java
+ * source code for a JSAP subclass
+ * that implements the configuration specified in the ant build file.
+ * @throws BuildException if unsuccessful for any reason.
+ */
+ public void execute() throws BuildException {
+ if (srcDir == null) {
+ throw (new BuildException("srcdir is required."));
+ }
+ if ((className == null) || (className.length() == 0)) {
+ throw (new BuildException("classname is required."));
+ }
+ if (!srcDir.isDirectory()) {
+ throw (new BuildException("srcdir must be a directory."));
+ }
+ System.out.println("srcDir=[" + srcDir + "]");
+ System.out.println("className=[" + className + "]");
+ System.out.println("public=" + isPublic);
+
+ try {
+ buildJSAP();
+ writeJSAP();
+ } catch (Exception e) {
+ throw (new BuildException(e.getMessage()));
+ }
+
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/ant/OptionConfiguration.java b/src/java/com/martiansoftware/jsap/ant/OptionConfiguration.java
new file mode 100644
index 0000000..81b8663
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/ant/OptionConfiguration.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.ant;
+
+import java.io.PrintStream;
+import java.util.Vector;
+
+import com.martiansoftware.jsap.FlaggedOption;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.Option;
+import com.martiansoftware.jsap.PropertyStringParser;
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.UnflaggedOption;
+
+/**
+ * Stores/provides configuration data common to both flaggedoptions and
+ * unflaggedoptions nested inside a jsap ant task.
+ * For detailed information on using the jsap task, see the documentation for
+ * JSAPAntTask.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see JSAPAntTask
+ */
+
+public abstract class OptionConfiguration extends ParameterConfiguration {
+
+ /**
+ * If true, this option is required.
+ */
+ private boolean required = JSAP.NOT_REQUIRED;
+
+ /**
+ * Stores any properties for this option's StringParser (if it's a
+ * PropertyStringParser)
+ */
+ private Vector parserProperties = null;
+
+ /**
+ * If true, this option stores a list of values.
+ */
+ private boolean isList = JSAP.NOT_LIST;
+
+ /**
+ * If this option is a list, this is the list separator token.
+ */
+ private char listSeparator = JSAP.DEFAULT_LISTSEPARATOR;
+
+ /**
+ * If this is true, the user has specified a list separator token.
+ */
+ private boolean declaredListSeparator = false;
+
+ /**
+ * The name of the StringParser for this option.
+ */
+ private String stringParser = null;
+
+ /**
+ * Creates a new OptionConfiguration.
+ */
+ public OptionConfiguration() {
+ super();
+ parserProperties = new Vector();
+ }
+
+ /**
+ * Sets the StringParser for this option.
+ * @param stringParser the StringParser for this option.
+ */
+ public void setStringparser(String stringParser) {
+ this.stringParser = stringParser;
+ }
+
+ /**
+ * Returns the classname of the StringParser for this option. If the
+ * current StringParser name
+ * does not contains any "dot"
+ * characters, it is prefixed with "com.martiansoftware.jsap.stringparsers."
+ * prior to returning.
+ * @return the classname of the StringParser for this option.
+ */
+ public String getStringparser() {
+ String result = null;
+ if (stringParser != null) {
+ if (stringParser.indexOf(".") == -1) {
+ result =
+ "com.martiansoftware.jsap.stringparsers." + stringParser;
+ } else {
+ result = stringParser;
+ }
+ }
+ return (result);
+ }
+
+ /**
+ * Sets whether this option is required.
+ * @param required if true, this option is required.
+ */
+ public void setRequired(boolean required) {
+ this.required = required;
+ }
+
+ /**
+ * Returns a boolean indicating whether this option is required.
+ * @return a boolean indicating whether this option is required.
+ */
+ public boolean getRequired() {
+ return (required);
+ }
+
+ /**
+ * Sets whether this option is a list.
+ * @param isList if true, this option is a list.
+ */
+ public void setIslist(boolean isList) {
+ this.isList = isList;
+ }
+
+ /**
+ * Returns a boolean indicating whether this option is a list.
+ * @return a boolean indicating whether this option is a list.
+ */
+ public boolean getIslist() {
+ return (isList);
+ }
+
+ /**
+ * Sets the list separator for this option, if it is a list.
+ * @param listSeparator the list separator character for this option, if it
+ * is a list.
+ */
+ public void setListseparator(char listSeparator) {
+ declaredListSeparator = true;
+ this.listSeparator = listSeparator;
+ }
+
+ /**
+ * Returns the list separator character for this option.
+ * @return the list separator character for this option.
+ */
+ public char getListseparator() {
+ return (listSeparator);
+ }
+
+ /**
+ * Returns a boolean indicating whether the list separator character has
+ * been specified by the user.
+ * @return a boolean indicating whether the list separator character has
+ * been specified by the user.
+ */
+ public boolean declaredListSeparator() {
+ return (declaredListSeparator);
+ }
+
+ /**
+ * Adds a property to the current list of properties for this option's
+ * PropertyStringParser.
+ * @param p the property to add.
+ */
+ public void addConfiguredProperty(ParserProperty p) {
+ parserProperties.add(p);
+ }
+
+ /**
+ * Returns an array of ParserProperties for this option's
+ * PropertyStringParser, or null if no ParserProperties
+ * are defined.
+ * @return an array of ParserProperties for this option's
+ * PropertyStringParser, or null if no ParserProperties
+ * are defined.
+ */
+ public ParserProperty[] getParserProperties() {
+ ParserProperty[] result = null;
+ if (parserProperties.size() > 0) {
+ result =
+ (ParserProperty[]) parserProperties.toArray(
+ new ParserProperty[0]);
+ }
+ return (result);
+ }
+
+ /**
+ * Returns a boolean indicating whether any ParserProperties are defined.
+ * @return a boolean indicating whether any ParserProperties are defined.
+ */
+ public boolean hasProperties() {
+ ParserProperty[] props = getParserProperties();
+ return ((props != null) && (props.length > 0));
+ }
+
+ /**
+ * Instantiates and configures A {@link com.martiansoftware.jsap.StringParser} according to this
+ * configuration, and provides it to the
+ * specified Option.
+ * @param option the Option that should use the configured StringParser.
+ */
+ protected void setupStringParser(Option option) {
+ if (this.getStringparser() != null) {
+ try {
+ StringParser sp =
+ (StringParser) Class
+ .forName(this.getStringparser())
+ .newInstance();
+ if (option instanceof FlaggedOption) {
+ ((FlaggedOption) option).setStringParser(sp);
+ } else {
+ ((UnflaggedOption) option).setStringParser(sp);
+ }
+ } catch (Exception e) {
+ throw (
+ new IllegalArgumentException(
+ "Unable to instantiate \""
+ + this.getStringparser()
+ + "\""));
+ }
+ }
+
+ if (this.hasProperties()) {
+ try {
+ PropertyStringParser psp =
+ (PropertyStringParser) option.getStringParser();
+ ParserProperty[] props = this.getParserProperties();
+ for (int i = 0; i < props.length; ++i) {
+ psp.setProperty(props[i].getName(), props[i].getValue());
+ }
+ } catch (Exception e) {
+ throw (
+ new IllegalArgumentException(
+ "Option \""
+ + option.getID()
+ + "\": "
+ + option.getStringParser().getClass().getName()
+ + " is not an instance of "
+ + "com.martiansoftware.jsap.PropertyParser."));
+ }
+ }
+ }
+
+ /**
+ * Creates java source code to configure an option as specified in this
+ * object. These methods are called
+ * by both UnflaggedOptionConfiguration and FlaggedOptionConfiguration.
+ * @param objName the name of the object in the generated source code
+ * @param out a PrintStream to which the source code should be written
+ */
+ protected void createParentStatements(String objName, PrintStream out) {
+ super.createParentStatements(objName, out);
+ out.println(
+ " "
+ + objName
+ + ".setList("
+ + (getIslist() ? "true" : "false")
+ + ");");
+ out.println(
+ " "
+ + objName
+ + ".setRequired("
+ + (getRequired() ? "true" : "false")
+ + ");");
+ if (getStringparser() != null) {
+ out.println(
+ " "
+ + objName
+ + ".setStringParser( new "
+ + getStringparser()
+ + "() );");
+ }
+ if (hasProperties()) {
+ ParserProperty[] props = getParserProperties();
+ out.println();
+ out.println(
+ " PropertyStringParser psp = (PropertyStringParser) "
+ + objName
+ + ".getStringParser();");
+ for (int i = 0; i < props.length; ++i) {
+ out.println(
+ " psp.setProperty(\""
+ + props[i].getName()
+ + "\", \""
+ + props[i].getValue()
+ + "\");");
+ }
+ out.println();
+ }
+ if (declaredListSeparator()) {
+ out.println(
+ " "
+ + objName
+ + ".setListSeparator('"
+ + getListseparator()
+ + "');");
+ }
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/ant/ParameterConfiguration.java b/src/java/com/martiansoftware/jsap/ant/ParameterConfiguration.java
new file mode 100644
index 0000000..6e81344
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/ant/ParameterConfiguration.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.ant;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Vector;
+
+import com.martiansoftware.jsap.Parameter;
+
+/**
+ * Stores/provides configuration data common to switches, flaggedoptions, and
+ * unflaggedoptions
+ * nested inside a jsap ant task.
+ * For detailed information on using the jsap task, see the documentation for
+ * JSAPAntTask.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see JSAPAntTask
+ */
+public abstract class ParameterConfiguration {
+
+ /**
+ * The unique ID for this parameter.
+ */
+ private String id = null;
+
+ /**
+ * The set of default values for this parameter.
+ */
+ private Vector defaults = null;
+
+ /**
+ * Creates a new ParameterConfiguration.
+ */
+ public ParameterConfiguration() {
+ defaults = new Vector();
+ }
+
+ /**
+ * Returns an Parameter (String, FlaggedOption, or UnflaggedOption)
+ * configured according
+ * to the settings contained within this object.
+ * @return an Parameter (String, FlaggedOption, or UnflaggedOption)
+ * configured according
+ * to the settings contained within this object.
+ */
+ public abstract Parameter getParameter();
+
+ /**
+ * Sets the unique ID for this parameter.
+ * @param id ths unique ID for this parameter.
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * Returns the unique ID for this parameter.
+ * @return the unique ID for this parameter.
+ */
+ public String getId() {
+ return (id);
+ }
+
+ /**
+ * Adds a default value to the current list of default values for this
+ * parameter.
+ * @param defaultValue the default value to add to the current list of
+ * default values for this parameter.
+ */
+ public void setDefault(String defaultValue) {
+ defaults.add(defaultValue);
+ }
+
+ /**
+ * Adds a configured default value to the current list of default values
+ * for this parameter.
+ * @param defaultValue the configured default value to add to the current
+ * list of default
+ * values for this parameter.
+ */
+ public void addConfiguredDefault(DefaultValue defaultValue) {
+ defaults.add(defaultValue.getValue());
+ }
+
+ /**
+ * Returns an array of this parameter's default values, or a zero-length
+ * array if none exist.
+ * @return an array of this parameter's default values, or a zero-length
+ * array if none exist.
+ */
+ public String[] getDefaults() {
+ return (
+ (defaults.size() == 0)
+ ? null
+ : ((String[]) defaults.toArray(new String[0])));
+ }
+
+ /**
+ * Creates java source code statements to configure an Parameter as
+ * specified in this object.
+ * @param objName the name of the object in the java source code
+ * @param out the PrintStream to which the source code should be written
+ */
+ protected void createParentStatements(String objName, PrintStream out) {
+
+ String[] defaults = getDefaults();
+ if (defaults != null) {
+ for (int i = 0; i < defaults.length; ++i) {
+ out.println(
+ " "
+ + objName
+ + ".addDefault(\""
+ + defaults[i]
+ + "\");");
+ }
+ }
+ }
+
+ /**
+ * Returns a boolean indicating whether this parameter has any properties
+ * associated with its
+ * StringParser. This method always returns false; it may be overridden by
+ * subclasses.
+ * @return a boolean indicating whether this parameter has any properties
+ * associated with its
+ * StringParser.
+ */
+ public boolean hasProperties() {
+ return (false);
+ }
+
+ /**
+ * Creates source code for a java method that creates a parameter matching
+ * this object's configuration.
+ * @param methodName the name of the java method to generate.
+ * @param out the PrintStream to which the generated source code should be
+ * written.
+ * @throws IOException if any are thrown by PrintStream.
+ */
+ public abstract void createMethod(String methodName, PrintStream out)
+ throws IOException;
+
+}
diff --git a/src/java/com/martiansoftware/jsap/ant/ParserProperty.java b/src/java/com/martiansoftware/jsap/ant/ParserProperty.java
new file mode 100644
index 0000000..85016a5
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/ant/ParserProperty.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.ant;
+
+/**
+ * Stores/provides a single name/value pair for a PropertyStringParser
+ * For detailed information on using the jsap task, see the documentation for
+ * JSAPAntTask.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see JSAPAntTask
+ * @see com.martiansoftware.jsap.PropertyStringParser
+ */
+public class ParserProperty {
+
+ /**
+ * The name of this property.
+ */
+ private String name = null;
+
+ /**
+ * The value of this property.
+ */
+ private String value = null;
+
+ /**
+ * Sets the name of this property.
+ * @param name the name of this property.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns the name of this property.
+ * @return the name of this property.
+ */
+ public String getName() {
+ return (name);
+ }
+
+ /**
+ * Sets the value of this property.
+ * @param value the value of this property.
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Returns the value of this property.
+ * @return the value of this property.
+ */
+ public String getValue() {
+ return (value);
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/ant/SwitchConfiguration.java b/src/java/com/martiansoftware/jsap/ant/SwitchConfiguration.java
new file mode 100644
index 0000000..654d4dc
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/ant/SwitchConfiguration.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.ant;
+
+import java.io.PrintStream;
+
+import com.martiansoftware.jsap.Parameter;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.Switch;
+
+/**
+ * Stores/provides configuration data for switches nested inside a jsap ant
+ * task.
+ * For detailed information on using the jsap task, see the documentation for
+ * JSAPAntTask.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see JSAPAntTask
+ * @see com.martiansoftware.jsap.Switch
+ */
+
+public class SwitchConfiguration extends ParameterConfiguration {
+
+ /**
+ * The short flag for this switch.
+ */
+ private char shortFlag = JSAP.NO_SHORTFLAG;
+
+ /**
+ * The long flag for this switch.
+ */
+ private String longFlag = JSAP.NO_LONGFLAG;
+
+ /**
+ * Creates a new SwitchConfiguration.
+ */
+ public SwitchConfiguration() {
+ super();
+ }
+
+ /**
+ * Sets the short flag for this switch.
+ * @param shortFlag the short flag for this switch.
+ */
+ public void setShortflag(char shortFlag) {
+ this.shortFlag = shortFlag;
+ }
+
+ /**
+ * Returns the short flag for this switch.
+ * @return the short flag for this switch.
+ */
+ public char getShortflag() {
+ return (shortFlag);
+ }
+
+ /**
+ * Sets the long flag for this switch.
+ * @param longFlag the long flag for this switch.
+ */
+ public void setLongflag(String longFlag) {
+ this.longFlag = longFlag;
+ }
+
+ /**
+ * Returns the long flag for this switch.
+ * @return the long flag for this switch.
+ */
+ public String getLongflag() {
+ return (longFlag);
+ }
+
+ /**
+ * Returns a Switch configured according to this configuration.
+ * @return a Switch configured according to this configuration.
+ */
+ public Parameter getParameter() {
+ Switch result = new Switch(this.getId());
+ result.setShortFlag(this.getShortflag());
+ result.setLongFlag(this.getLongflag());
+ result.setDefault(this.getDefaults());
+ return (result);
+ }
+
+ /**
+ * Creates java source code for a method that will instantiate and configure
+ * a Switch
+ * according to this configuration.
+ * @param methodName the name of the method to generate
+ * @param out the PrintStream to which the generated java will be written
+ */
+ public void createMethod(String methodName, PrintStream out) {
+
+ out.println(" private Switch " + methodName + "() {");
+ out.println(
+ " Switch result = new Switch(\"" + this.getId() + "\");");
+
+ if (getShortflag() != JSAP.NO_SHORTFLAG) {
+ out.println(
+ " result.setShortFlag('" + getShortflag() + "');");
+ }
+
+ if (getLongflag() != JSAP.NO_LONGFLAG) {
+ out.println(
+ " result.setLongFlag(\"" + getLongflag() + "\");");
+ }
+
+ super.createParentStatements("result", out);
+ out.println(" return (result);");
+ out.println(" }");
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/ant/UnflaggedOptionConfiguration.java b/src/java/com/martiansoftware/jsap/ant/UnflaggedOptionConfiguration.java
new file mode 100644
index 0000000..86c9ac6
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/ant/UnflaggedOptionConfiguration.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.ant;
+
+import java.io.PrintStream;
+
+import com.martiansoftware.jsap.Parameter;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.UnflaggedOption;
+
+/**
+ * Stores/provides configuration data for unflaggedoptions nested inside a jsap
+ * ant task.
+ * For detailed information on using the jsap task, see the documentation for
+ * JSAPAntTask.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see JSAPAntTask
+ * @see com.martiansoftware.jsap.UnflaggedOption
+ */
+
+public class UnflaggedOptionConfiguration extends OptionConfiguration {
+
+ /**
+ * If true, this unflaggedoption should be greedy.
+ * (i.e., should consume the remaining unflaggedoptions from the command
+ * line.
+ */
+ private boolean greedy = JSAP.NOT_GREEDY;
+
+ /**
+ * Creates a new UnflaggedOptionConfiguration.
+ */
+ public UnflaggedOptionConfiguration() {
+ super();
+ }
+
+ /**
+ * Sets whether this UnflaggedOption should be greedy.
+ * (i.e., should consume the remaining unflaggedoptions from the command
+ * line.
+ * @param greedy if true, this UnflaggedOption should be greedy.
+ */
+ public void setGreedy(boolean greedy) {
+ this.greedy = greedy;
+ }
+
+ /**
+ * Returns a boolean indicating whether this UnflaggedOption is greedy.
+ * @return a boolean indicating whether this UnflaggedOption is greedy.
+ */
+ public boolean getGreedy() {
+ return (greedy);
+ }
+
+ /**
+ * Returns an UnflaggedOption configured according to this configuration.
+ * @return an UnflaggedOption configured according to this configuration.
+ */
+ public Parameter getParameter() {
+ UnflaggedOption result = new UnflaggedOption(this.getId());
+
+ result.setRequired(this.getRequired());
+ result.setList(this.getIslist());
+ if (this.declaredListSeparator()) {
+ result.setListSeparator(this.getListseparator());
+ }
+ result.setGreedy(this.getGreedy());
+ result.setDefault(this.getDefaults());
+ setupStringParser(result);
+ return (result);
+ }
+
+ /**
+ * Creates java source code for a method that instantiates an
+ * UnflaggedOption and
+ * configures it according to this configuration.
+ * @param methodName the name of the method to generate
+ * @param out the PrintStream to which the java source code will be written.
+ */
+ public void createMethod(String methodName, PrintStream out)
+ {
+
+ out.println(" private UnflaggedOption " + methodName + "() {");
+ out.println(
+ " UnflaggedOption result = new UnflaggedOption(\""
+ + this.getId()
+ + "\");");
+
+ out.println(
+ " result.setGreedy("
+ + (getGreedy() ? "true" : "false")
+ + ");");
+
+ super.createParentStatements("result", out);
+ out.println(" return (result);");
+ out.println(" }");
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/defaultsources/PropertyDefaultSource.java b/src/java/com/martiansoftware/jsap/defaultsources/PropertyDefaultSource.java
new file mode 100644
index 0000000..25688c8
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/defaultsources/PropertyDefaultSource.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.defaultsources;
+
+import com.martiansoftware.jsap.DefaultSource;
+import com.martiansoftware.jsap.Defaults;
+import com.martiansoftware.jsap.IDMap;
+import com.martiansoftware.jsap.JSAPException;
+import com.martiansoftware.jsap.ExceptionMap;
+
+import java.io.InputStream;
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.util.Properties;
+import java.util.Enumeration;
+import java.io.IOException;
+
+/**
+ *
+ * <p>A DefaultSource with values defined in a java.util.Properties object.
+ * In order to determine which parameter
+ * a value is associated with, each property key is first compared to each
+ * parameter's unique ID. Failing a
+ * match, each parameter's long flag is checked, and finally the short flags
+ * are checked. A PropertyDefaultSource
+ * may contain a mix of IDs, long flags, and short flags.</p>
+ *
+ * <p>A PropertyDefaultSource is also incredibly useful as a configuration file
+ * loader. Multiple PropertyDefaultSources
+ * can be chained together in a JSAP in order to prioritize their entries
+ * (e.g., load "~/myproject.conf" first, then
+ * "/etc/myproject.conf").</p>
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.DefaultSource
+ * @see java.util.Properties
+ */
+public class PropertyDefaultSource implements DefaultSource {
+
+ /**
+ * If true, this PropertyDefaultSource is being loaded from a file.
+ * @see PropertyDefaultSource#PropertyDefaultSource(String,boolean)
+ */
+ private boolean loadFromFile = false;
+
+ /**
+ * If true, this PropertyDefaultSource is being loaded from a Properties
+ * object.
+ * @see PropertyDefaultSource#PropertyDefaultSource(Properties)
+ * @see java.util.Properties
+ */
+ private boolean loadFromProperties = false;
+
+ /**
+ * If true, this PropertyDefaultSource is being loaded from an InputStream.
+ * @see PropertyDefaultSource#PropertyDefaultSource(InputStream,boolean)
+ * @see java.io.InputStream
+ */
+ private boolean loadFromInputStream = false;
+
+ /**
+ * The InputStream from which the PropertyDefaultSource will be loaded, if
+ * any.
+ */
+ private InputStream in = null;
+
+ /**
+ * The name of the file from which the PropertyDefaultSource will be
+ * loaded, if any.
+ */
+ private String propertyFileName = null;
+
+ /**
+ * If true, any encountered IOExceptions will be thrown. Default is true.
+ */
+ private boolean throwIOExceptions = true;
+
+ /**
+ * The Properties object containing the default values.
+ */
+ private Properties properties = null;
+
+ /**
+ * Indicates whether we have already loaded the Properties.
+ */
+ private boolean loaded = false;
+
+ /**
+ * Creates a new PropertyDefaultSource by loading the specified file. The
+ * file is loaded when the JSAP
+ * requests the defaults from this object.
+ * @param propertyFileName the name of the properties file containing the
+ * default values.
+ * @param throwIOExceptions if true, any encountered IOExceptions will be
+ * re-thrown. Set this to false
+ * if you want to ignore any exceptions (e.g., specified file does not
+ * exist).
+ */
+ public PropertyDefaultSource(
+ String propertyFileName,
+ boolean throwIOExceptions) {
+ this.loadFromFile = true;
+ this.propertyFileName = propertyFileName;
+ this.throwIOExceptions = throwIOExceptions;
+ }
+
+ /**
+ * Creates a new PropertyDefaultSource based upon the specified Properties
+ * object.
+ * @param properties the Properties object containing the default values.
+ */
+ public PropertyDefaultSource(Properties properties) {
+ this.loadFromProperties = true;
+ this.properties = properties;
+ loaded = true;
+ }
+
+ /**
+ * Creates a new PropertyDefaultSource based upon the specified InputStream.
+ * @param in the InputStream containing the Properties.
+ * @param throwIOExceptions if true, any encountered IOExceptions will be
+ * re-thrown.
+ */
+ public PropertyDefaultSource(InputStream in, boolean throwIOExceptions) {
+ this.loadFromInputStream = true;
+ this.in = in;
+ this.throwIOExceptions = throwIOExceptions;
+ }
+
+ /**
+ * Returns the properties for this PropertyDefaultSource. If necessary,
+ * the properties are loaded first
+ * from a file or InputStream as specified by the constructor.
+ * @return the properties for this PropertyDefaultSource.
+ * @throws IOException if an I/O exception occurs, AND this
+ * PropertyDefaultSource is configured to throw
+ * IOExceptions.
+ */
+ private Properties getProperties() throws IOException {
+ if (!loaded) {
+ try {
+ if (loadFromFile) {
+ in =
+ new BufferedInputStream(
+ new FileInputStream(propertyFileName));
+ }
+ Properties properties = new Properties();
+ properties.load(in);
+ in.close();
+ in = null;
+ this.properties = properties;
+ loaded = true;
+ } catch (IOException e) {
+ if (throwIOExceptions) {
+ throw (e);
+ }
+ }
+ }
+ Properties result = this.properties;
+ if (result == null) {
+ this.properties = new Properties();
+ result = this.properties;
+ loaded = true;
+ }
+ return (result);
+ }
+
+ /**
+ * Returns a Defaults object based upon this PropertyDefaultSource's
+ * properties and the specified IDMap.
+ * In order to determine which parameter
+ * a value is associated with, each property key is first compared to each
+ * parameter's unique ID. Failing a
+ * match, each parameter's long flag is checked, and finally the short
+ * flags are checked. A
+ * PropertyDefaultSource may contain a mix of IDs, long flags, and short
+ * flags.
+ * @param idMap the IDMap containing the current JSAP configuration.
+ * @param exceptionMap the ExceptionMap object within which any encountered
+ * exceptions will be thrown.
+ * @return a Defaults object based upon this PropertyDefaultSource's
+ * properties and the specified IDMap.
+ */
+ public Defaults getDefaults(IDMap idMap, ExceptionMap exceptionMap) {
+ Defaults defaults = new Defaults();
+ try {
+ Properties properties = getProperties();
+ for (Enumeration enumeration = properties.propertyNames();
+ enumeration.hasMoreElements();
+ ) {
+
+ String thisName = (String) enumeration.nextElement();
+ if (idMap.idExists(thisName)) {
+ defaults.addDefault(
+ thisName,
+ properties.getProperty(thisName));
+ } else {
+ String paramID = idMap.getIDByLongFlag(thisName);
+ if (paramID != null) {
+ defaults.addDefault(
+ paramID,
+ properties.getProperty(thisName));
+ } else if (thisName.length() == 1) {
+ paramID = idMap.getIDByShortFlag(thisName.charAt(0));
+ if (paramID != null) {
+ defaults.addDefault(
+ paramID,
+ properties.getProperty(thisName));
+ } else {
+ exceptionMap.addException(
+ null,
+ new JSAPException(
+ "Unknown parameter: " + thisName));
+ }
+ } else {
+ exceptionMap.addException(
+ null,
+ new JSAPException(
+ "Unknown parameter: " + thisName));
+ }
+ }
+ }
+ } catch (IOException ioe) {
+ exceptionMap.addException(
+ null,
+ new JSAPException("Unable to load properties.", ioe));
+ }
+ return (defaults);
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/defaultsources/TestAll.java b/src/java/com/martiansoftware/jsap/defaultsources/TestAll.java
new file mode 100644
index 0000000..5c7ad4d
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/defaultsources/TestAll.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.defaultsources;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class TestAll {
+
+ public static Test suite() {
+ TestSuite suite =
+ new TestSuite("Test for com.martiansoftware.jsap.defaultsources");
+ //$JUnit-BEGIN$
+ suite.addTest(new TestSuite(TestPropertyDefaultSource.class));
+ //$JUnit-END$
+ return suite;
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/defaultsources/TestPropertyDefaultSource.java b/src/java/com/martiansoftware/jsap/defaultsources/TestPropertyDefaultSource.java
new file mode 100644
index 0000000..fbb5aa2
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/defaultsources/TestPropertyDefaultSource.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.defaultsources;
+
+import junit.framework.TestCase;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.JSAPResult;
+import com.martiansoftware.jsap.FlaggedOption;
+import com.martiansoftware.jsap.UnflaggedOption;
+import com.martiansoftware.jsap.Switch;
+import com.martiansoftware.jsap.stringparsers.StringStringParser;
+import java.util.Properties;
+
+/**
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class TestPropertyDefaultSource extends TestCase {
+
+ public void testUnexpectedProperties() {
+ JSAP jsap = new JSAP();
+ try {
+ jsap.registerParameter(
+ new FlaggedOption(
+ "testflagged",
+ StringStringParser.getParser(),
+ JSAP.NO_DEFAULT,
+ JSAP.NOT_REQUIRED,
+ 'f',
+ "flagged"));
+ jsap.registerParameter(
+ new UnflaggedOption(
+ "testunflagged",
+ StringStringParser.getParser(),
+ JSAP.NO_DEFAULT,
+ JSAP.NOT_REQUIRED,
+ JSAP.NOT_GREEDY));
+ jsap.registerParameter(new Switch("testswitch", 's', "switch"));
+ } catch (Throwable t) {
+ fail(t.getMessage());
+ }
+
+ Properties p = new Properties();
+ p.setProperty("s", "true");
+ p.setProperty("flagged", "My Flagged Value");
+ PropertyDefaultSource pds = new PropertyDefaultSource(p);
+ jsap.registerDefaultSource(pds);
+
+ JSAPResult result = jsap.parse("");
+ assertTrue(result.success());
+
+ assertEquals(result.getBoolean("testswitch"), true);
+ assertEquals(result.getString("testflagged"), "My Flagged Value");
+
+ p.setProperty("unexpected", "jsap won't know what to do with this");
+ result = jsap.parse("");
+ assertFalse(result.success());
+
+ /*
+ for (java.util.Iterator i1 = result.getBadParameterIDIterator(); i1.hasNext(); ) {
+ String badID = (String) i1.next();
+ for (java.util.Iterator i2 = result.getExceptionIterator(badID); i2.hasNext(); ) {
+ Exception e = (Exception) i2.next();
+ System.out.println(e.getMessage());
+ }
+ }*/
+
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/examples/Example1.java b/src/java/com/martiansoftware/jsap/examples/Example1.java
new file mode 100644
index 0000000..bc498df
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/examples/Example1.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.examples;
+
+import com.martiansoftware.jsap.FlaggedOption;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.Switch;
+import com.martiansoftware.jsap.UnflaggedOption;
+
+/**
+ * @author mlamb
+ *
+ * To change the template for this generated type comment go to
+ * Window>Preferences>Java>Code Generation>Code and Comments
+ */
+public class Example1 {
+
+ public static void main(String[] args) throws Exception {
+ JSAP jsap = new JSAP();
+
+ FlaggedOption f1 = new FlaggedOption("myflagged");
+ f1.setShortFlag('f').setLongFlag("flagged").setRequired(true).setHelp(
+ "do flagged stuff");
+ jsap.registerParameter(f1);
+
+ UnflaggedOption f2 = new UnflaggedOption("myunflagged");
+ f2.setGreedy(JSAP.GREEDY).setHelp("input files");
+ jsap.registerParameter(f2);
+
+ Switch sw1 = new Switch("myswitch");
+ sw1.setLongFlag("verbose").setHelp(
+ "display extra logging information.");
+ jsap.registerParameter(sw1);
+
+ System.out.println("Usage: Example1 " + jsap.getUsage());
+ System.out.println(jsap.getHelp());
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_1.java b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_1.java
new file mode 100644
index 0000000..0ca7f94
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_1.java
@@ -0,0 +1,10 @@
+package com.martiansoftware.jsap.examples;
+
+// @@snip:Manual_HelloWorld_1@@
+public class Manual_HelloWorld_1 {
+
+ public static void main(String[] args){
+ System.out.println("Hello, World!");
+ }
+}
+// @@endSnip@@
\ No newline at end of file
diff --git a/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_2.java b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_2.java
new file mode 100644
index 0000000..1704cb7
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_2.java
@@ -0,0 +1,40 @@
+package com.martiansoftware.jsap.examples;
+
+import com.martiansoftware.jsap.FlaggedOption;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.JSAPResult;
+
+public class Manual_HelloWorld_2 {
+
+ /**
+ * Repeats the "Hello World" text multiple times.
+ * @param args the command line.
+ * @throws Exception for reasons made clear later in the manual.
+ */
+ // @@snip:Manual_HelloWorld_2@@
+ public static void main(String[] args) throws Exception {
+ JSAP jsap = new JSAP();
+
+ // create a flagged option we'll access using the id "count".
+ // it's going to be an integer, with a default value of 1.
+ // it's required (which has no effect since there's a default value)
+ // its short flag is "n", so a command line containing "-n 5"
+ // will print our message five times.
+ // it has no long flag.
+ FlaggedOption opt1 = new FlaggedOption("count")
+ .setStringParser(JSAP.INTEGER_PARSER)
+ .setDefault("1")
+ .setRequired(true)
+ .setShortFlag('n')
+ .setLongFlag(JSAP.NO_LONGFLAG);
+
+ jsap.registerParameter(opt1);
+
+ JSAPResult config = jsap.parse(args);
+
+ for (int i = 0; i < config.getInt("count"); ++i) {
+ System.out.println("Hello, World!");
+ }
+ }
+ // @@endSnip@@
+}
diff --git a/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_3.java b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_3.java
new file mode 100644
index 0000000..46974ed
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_3.java
@@ -0,0 +1,48 @@
+package com.martiansoftware.jsap.examples;
+
+import com.martiansoftware.jsap.FlaggedOption;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.JSAPResult;
+import com.martiansoftware.jsap.Switch;
+
+
+public class Manual_HelloWorld_3 {
+
+ /**
+ * Repeats the "Hello World" text multiple times.
+ * Decides whether to say "Hi" or "Hello" depending upon verbose switch.
+ * @param args the command line.
+ * @throws Exception for reasons made clear later in the manual.
+ */
+ // @@snip:Manual_HelloWorld_3@@
+ public static void main(String[] args) throws Exception {
+ JSAP jsap = new JSAP();
+
+ FlaggedOption opt1 = new FlaggedOption("count")
+ .setStringParser(JSAP.INTEGER_PARSER)
+ .setDefault("1")
+ .setRequired(true)
+ .setShortFlag('n')
+ .setLongFlag(JSAP.NO_LONGFLAG);
+
+ jsap.registerParameter(opt1);
+
+ // create a switch we'll access using the id "verbose".
+ // it has the short flag "-v" and the long flag "--verbose"
+ // this will govern whether we say "Hi" or "Hello".
+ Switch sw1 = new Switch("verbose")
+ .setShortFlag('v')
+ .setLongFlag("verbose");
+
+ jsap.registerParameter(sw1);
+
+ JSAPResult config = jsap.parse(args);
+
+ for (int i = 0; i < config.getInt("count"); ++i) {
+ System.out.println((config.getBoolean("verbose") ? "Hello" : "Hi")
+ + ", World!");
+ }
+
+ }
+ // @@endSnip@@
+}
\ No newline at end of file
diff --git a/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_4.java b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_4.java
new file mode 100644
index 0000000..e0b4b23
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_4.java
@@ -0,0 +1,65 @@
+package com.martiansoftware.jsap.examples;
+
+import com.martiansoftware.jsap.FlaggedOption;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.JSAPResult;
+import com.martiansoftware.jsap.Switch;
+import com.martiansoftware.jsap.UnflaggedOption;
+
+public class Manual_HelloWorld_4 {
+
+ /**
+ * Repeats the "Hello World" text multiple times. Decides whether to say
+ * "Hi" or "Hello" depending upon verbose switch.
+ *
+ * @param args the command line.
+ * @throws Exception for reasons made clear later in the manual.
+ */
+ // @@snip:Manual_HelloWorld_4@@
+ public static void main(String[] args) throws Exception {
+ JSAP jsap = new JSAP();
+
+ FlaggedOption opt1 = new FlaggedOption("count")
+ .setStringParser(JSAP.INTEGER_PARSER)
+ .setDefault("1")
+ .setRequired(true)
+ .setShortFlag('n')
+ .setLongFlag(JSAP.NO_LONGFLAG);
+
+ jsap.registerParameter(opt1);
+
+ Switch sw1 = new Switch("verbose")
+ .setShortFlag('v')
+ .setLongFlag("verbose");
+
+ jsap.registerParameter(sw1);
+
+ // Create an unflagged option called "names" that we'll use to
+ // say hello to particular people.
+ // To make it more interesting, we'll make it "greedy", so
+ // it consumes all remaining unflagged tokens on the command line
+ // as multiple values
+ UnflaggedOption opt2 = new UnflaggedOption("name")
+ .setStringParser(JSAP.STRING_PARSER)
+ .setDefault("World")
+ .setRequired(false)
+ .setGreedy(true);
+
+ jsap.registerParameter(opt2);
+
+ JSAPResult config = jsap.parse(args);
+
+ String[] names = config.getStringArray("name");
+ for (int i = 0; i < config.getInt("count"); ++i) {
+ for (int j = 0; j < names.length; ++j) {
+ System.out.println(
+ (config.getBoolean("verbose") ? "Hello" : "Hi")
+ + ", "
+ + names[j]
+ + "!");
+ }
+ }
+ }
+ // @@endSnip@@
+
+}
\ No newline at end of file
diff --git a/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_5.java b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_5.java
new file mode 100644
index 0000000..9f64996
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_5.java
@@ -0,0 +1,70 @@
+package com.martiansoftware.jsap.examples;
+
+import com.martiansoftware.jsap.FlaggedOption;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.JSAPResult;
+import com.martiansoftware.jsap.Switch;
+import com.martiansoftware.jsap.UnflaggedOption;
+
+public class Manual_HelloWorld_5 {
+
+ /**
+ * Repeats the "Hello World" text multiple times.
+ * Decides whether to say "Hi" or "Hello" depending upon verbose switch.
+ * @param args the command line.
+ * @throws Exception for reasons made clear later in the manual.
+ */
+ // @@snip:Manual_HelloWorld_5@@
+ public static void main(String[] args) throws Exception {
+ JSAP jsap = new JSAP();
+
+ FlaggedOption opt1 = new FlaggedOption("count")
+ .setStringParser(JSAP.INTEGER_PARSER)
+ .setDefault("1")
+ .setRequired(true)
+ .setShortFlag('n')
+ .setLongFlag(JSAP.NO_LONGFLAG);
+
+ jsap.registerParameter(opt1);
+
+ Switch sw1 = new Switch("verbose")
+ .setShortFlag('v')
+ .setLongFlag("verbose");
+
+ jsap.registerParameter(sw1);
+
+ UnflaggedOption opt2 = new UnflaggedOption("name")
+ .setStringParser(JSAP.STRING_PARSER)
+ .setDefault("World")
+ .setRequired(true)
+ .setGreedy(true);
+
+ jsap.registerParameter(opt2);
+
+ JSAPResult config = jsap.parse(args);
+
+ // check whether the command line was valid, and if it wasn't,
+ // display usage information and exit.
+ if (!config.success()) {
+ System.err.println();
+ System.err.println("Usage: java "
+ + Manual_HelloWorld_5.class.getName());
+ System.err.println(" "
+ + jsap.getUsage());
+ System.err.println();
+ System.exit(1);
+ }
+
+ String[] names = config.getStringArray("name");
+ for (int i = 0; i < config.getInt("count"); ++i) {
+ for (int j = 0; j < names.length; ++j) {
+ System.out.println((config.getBoolean("verbose") ? "Hello" : "Hi")
+ + ", "
+ + names[j]
+ + "!");
+ }
+ }
+ }
+ // @@endSnip@@
+
+}
\ No newline at end of file
diff --git a/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_6.java b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_6.java
new file mode 100644
index 0000000..c9931a4
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_6.java
@@ -0,0 +1,72 @@
+package com.martiansoftware.jsap.examples;
+
+import com.martiansoftware.jsap.FlaggedOption;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.JSAPResult;
+import com.martiansoftware.jsap.Switch;
+import com.martiansoftware.jsap.UnflaggedOption;
+
+public class Manual_HelloWorld_6 {
+
+ /**
+ * Repeats the "Hello World" text multiple times.
+ * Decides whether to say "Hi" or "Hello" depending upon verbose switch.
+ * @param args the command line.
+ * @throws Exception for reasons made clear later in the manual.
+ */
+ // @@snip:Manual_HelloWorld_6@@
+ public static void main(String[] args) throws Exception {
+ JSAP jsap = new JSAP();
+
+ FlaggedOption opt1 = new FlaggedOption("count")
+ .setStringParser(JSAP.INTEGER_PARSER)
+ .setDefault("1")
+ .setRequired(true)
+ .setShortFlag('n')
+ .setLongFlag(JSAP.NO_LONGFLAG);
+
+ opt1.setHelp("The number of times to say hello.");
+ jsap.registerParameter(opt1);
+
+ Switch sw1 = new Switch("verbose")
+ .setShortFlag('v')
+ .setLongFlag("verbose");
+ sw1.setHelp("Requests verbose output.");
+ jsap.registerParameter(sw1);
+
+ UnflaggedOption opt2 = new UnflaggedOption("name")
+ .setStringParser(JSAP.STRING_PARSER)
+ .setDefault("World")
+ .setRequired(true)
+ .setGreedy(true);
+
+ opt2.setHelp("One or more names of people you would like to greet.");
+ jsap.registerParameter(opt2);
+
+ JSAPResult config = jsap.parse(args);
+
+ if (!config.success()) {
+ System.err.println();
+ System.err.println("Usage: java "
+ + Manual_HelloWorld_6.class.getName());
+ System.err.println(" "
+ + jsap.getUsage());
+ System.err.println();
+ // show full help as well
+ System.err.println(jsap.getHelp());
+ System.exit(1);
+ }
+
+ String[] names = config.getStringArray("name");
+ for (int i = 0; i < config.getInt("count"); ++i) {
+ for (int j = 0; j < names.length; ++j) {
+ System.out.println((config.getBoolean("verbose") ? "Hello" : "Hi")
+ + ", "
+ + names[j]
+ + "!");
+ }
+ }
+ }
+ // @@endSnip@@
+
+}
\ No newline at end of file
diff --git a/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_7.java b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_7.java
new file mode 100644
index 0000000..314ffd5
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_7.java
@@ -0,0 +1,83 @@
+package com.martiansoftware.jsap.examples;
+
+import com.martiansoftware.jsap.FlaggedOption;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.JSAPResult;
+import com.martiansoftware.jsap.Switch;
+import com.martiansoftware.jsap.UnflaggedOption;
+
+public class Manual_HelloWorld_7 {
+
+ /**
+ * Repeats the "Hello World" text multiple times.
+ * Decides whether to say "Hi" or "Hello" depending upon verbose switch.
+ * @param args the command line.
+ * @throws Exception for reasons made clear later in the manual.
+ */
+ // @@snip:Manual_HelloWorld_7@@
+ public static void main(String[] args) throws Exception {
+ JSAP jsap = new JSAP();
+
+ FlaggedOption opt1 = new FlaggedOption("count")
+ .setStringParser(JSAP.INTEGER_PARSER)
+ .setDefault("1")
+ .setRequired(true)
+ .setShortFlag('n')
+ .setLongFlag(JSAP.NO_LONGFLAG);
+
+ opt1.setHelp("The number of times to say hello.");
+ jsap.registerParameter(opt1);
+
+ Switch sw1 = new Switch("verbose")
+ .setShortFlag('v')
+ .setLongFlag("verbose");
+
+ sw1.setHelp("Requests verbose output.");
+ jsap.registerParameter(sw1);
+
+ UnflaggedOption opt2 = new UnflaggedOption("name")
+ .setStringParser(JSAP.STRING_PARSER)
+ .setDefault("World")
+ .setRequired(true)
+ .setGreedy(true);
+
+ opt2.setHelp("One or more names of people you would like to greet.");
+ jsap.registerParameter(opt2);
+
+ JSAPResult config = jsap.parse(args);
+
+ if (!config.success()) {
+
+ System.err.println();
+
+ // print out specific error messages describing the problems
+ // with the command line, THEN print usage, THEN print full
+ // help. This is called "beating the user with a clue stick."
+ for (java.util.Iterator errs = config.getErrorMessageIterator();
+ errs.hasNext();) {
+ System.err.println("Error: " + errs.next());
+ }
+
+ System.err.println();
+ System.err.println("Usage: java "
+ + Manual_HelloWorld_7.class.getName());
+ System.err.println(" "
+ + jsap.getUsage());
+ System.err.println();
+ System.err.println(jsap.getHelp());
+ System.exit(1);
+ }
+
+ String[] names = config.getStringArray("name");
+ for (int i = 0; i < config.getInt("count"); ++i) {
+ for (int j = 0; j < names.length; ++j) {
+ System.out.println((config.getBoolean("verbose") ? "Hello" : "Hi")
+ + ", "
+ + names[j]
+ + "!");
+ }
+ }
+ }
+ // @@endSnip@@
+
+}
\ No newline at end of file
diff --git a/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_8.java b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_8.java
new file mode 100644
index 0000000..6b6ab7f
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_8.java
@@ -0,0 +1,91 @@
+package com.martiansoftware.jsap.examples;
+
+import com.martiansoftware.jsap.FlaggedOption;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.JSAPResult;
+import com.martiansoftware.jsap.QualifiedSwitch;
+import com.martiansoftware.jsap.UnflaggedOption;
+
+public class Manual_HelloWorld_8 {
+
+ /**
+ * Repeats the "Hello World" text multiple times.
+ * Decides whether to say "Hi" or "Hello" depending upon verbose switch.
+ * Uses the new QualifiedSwitch to set the language of verbosity
+ * @param args the command line.
+ * @throws Exception for reasons made clear later in the manual.
+ */
+ // @@snip:Manual_HelloWorld_8@@
+ public static void main(String[] args) throws Exception {
+ JSAP jsap = new JSAP();
+
+ FlaggedOption opt1 = new FlaggedOption("count")
+ .setStringParser(JSAP.INTEGER_PARSER)
+ .setDefault("1")
+ .setRequired(true)
+ .setShortFlag('n')
+ .setLongFlag(JSAP.NO_LONGFLAG);
+
+ opt1.setHelp("The number of times to say hello.");
+ jsap.registerParameter(opt1);
+
+ QualifiedSwitch sw1 = (QualifiedSwitch)
+ (new QualifiedSwitch("verbose")
+ .setShortFlag('v')
+ .setLongFlag("verbose")
+ .setList(true)
+ .setListSeparator(','));
+
+ sw1.setHelp("Requests verbose output.");
+ jsap.registerParameter(sw1);
+
+ UnflaggedOption opt2 = new UnflaggedOption("name")
+ .setStringParser(JSAP.STRING_PARSER)
+ .setDefault("World")
+ .setRequired(true)
+ .setGreedy(true);
+
+ opt2.setHelp("One or more names of people you would like to greet.");
+ jsap.registerParameter(opt2);
+
+ JSAPResult config = jsap.parse(args);
+
+ if (!config.success()) {
+
+ System.err.println();
+
+ // print out specific error messages describing the problems
+ // with the command line, THEN print usage, THEN print full
+ // help. This is called "beating the user with a clue stick."
+ for (java.util.Iterator errs = config.getErrorMessageIterator();
+ errs.hasNext();) {
+ System.err.println("Error: " + errs.next());
+ }
+
+ System.err.println();
+ System.err.println("Usage: java "
+ + Manual_HelloWorld_8.class.getName());
+ System.err.println(" "
+ + jsap.getUsage());
+ System.err.println();
+ System.err.println(jsap.getHelp());
+ System.exit(1);
+ }
+
+ String[] names = config.getStringArray("name");
+ String[] languages = config.getStringArray("verbose");
+ for (int i = 0; i < languages.length; ++i) {
+ System.out.println("language=" + languages[i]);
+ }
+ for (int i = 0; i < config.getInt("count"); ++i) {
+ for (int j = 0; j < names.length; ++j) {
+ System.out.println((config.getBoolean("verbose") ? "Hello" : "Hi")
+ + ", "
+ + names[j]
+ + "!");
+ }
+ }
+ }
+ // @@endSnip@@
+
+}
\ No newline at end of file
diff --git a/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_9.java b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_9.java
new file mode 100644
index 0000000..6f58b9f
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_9.java
@@ -0,0 +1,75 @@
+/*
+ * Created on Sep 4, 2004
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+package com.martiansoftware.jsap.examples;
+
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.JSAPResult;
+
+/**
+ * A reimplementation of Manual_HelloWorld_8 that loads the JSAP
+ * configuration from an XML file.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class Manual_HelloWorld_9 {
+
+ // @@snip:Manual_HelloWorld_9@@
+ public static void main(String[] args) throws Exception {
+ JSAP jsap = new JSAP(Manual_HelloWorld_9.class.getResource("Manual_HelloWorld_9.jsap"));
+
+ JSAPResult config = jsap.parse(args);
+
+ if (!config.success()) {
+
+ System.err.println();
+
+ // print out specific error messages describing the problems
+ // with the command line, THEN print usage, THEN print full
+ // help. This is called "beating the user with a clue stick."
+ for (java.util.Iterator errs = config.getErrorMessageIterator();
+ errs.hasNext();) {
+ System.err.println("Error: " + errs.next());
+ }
+
+ System.err.println();
+ System.err.println("Usage: java "
+ + Manual_HelloWorld_9.class.getName());
+ System.err.println(" "
+ + jsap.getUsage());
+ System.err.println();
+ System.err.println(jsap.getHelp());
+ System.exit(1);
+ }
+
+ String[] names = config.getStringArray("name");
+ String[] languages = config.getStringArray("verbose");
+ if (languages.length == 0) languages = new String[] {"en"};
+
+ for (int lang = 0; lang < languages.length; ++lang) {
+ for (int i = 0; i < config.getInt("count"); ++i) {
+ for (int j = 0; j < names.length; ++j) {
+ System.out.println((config.getBoolean("verbose") ? getVerboseHello(languages[lang]) : "Hi")
+ + ", "
+ + names[j]
+ + "!");
+ }
+ }
+ }
+ }
+
+ private static String getVerboseHello(String language) {
+ if ((language == null) || "en".equalsIgnoreCase(language)) {
+ return("Hello");
+ } else if ("de".equalsIgnoreCase(language)) {
+ return("Guten Tag");
+ } else {
+ return("(Barely audible grunt)");
+ }
+ }
+ // @@endSnip@@
+
+}
diff --git a/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_9.jsap b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_9.jsap
new file mode 100644
index 0000000..3b514c6
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_9.jsap
@@ -0,0 +1,38 @@
+<!-- @@snip:Manual_HelloWorld_9_jsap@@ -->
+<jsap>
+ <parameters>
+ <flaggedOption>
+ <id>count</id>
+ <stringParser>
+ <classname>IntegerStringParser</classname>
+ </stringParser>
+ <required>true</required>
+ <shortFlag>n</shortFlag>
+ <defaults>
+ <string>1</string>
+ </defaults>
+ <help>The number of times to say hello (default=1).</help>
+ </flaggedOption>
+
+ <qualifiedSwitch>
+ <id>verbose</id>
+ <shortFlag>v</shortFlag>
+ <longFlag>verbose</longFlag>
+ <list>true</list>
+ <listSeparator>,</listSeparator>
+ <help>Requests verbose output.</help>
+ </qualifiedSwitch>
+
+ <unflaggedOption>
+ <id>name</id>
+ <defaults>
+ <string>World</string>
+ </defaults>
+ <required>true</required>
+ <greedy>true</greedy>
+ <help>One or more names of people you would like to greet.</help>
+ </unflaggedOption>
+
+ </parameters>
+</jsap>
+<!-- @@endSnip@@ -->
diff --git a/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_Simple.java b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_Simple.java
new file mode 100644
index 0000000..d215437
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/examples/Manual_HelloWorld_Simple.java
@@ -0,0 +1,55 @@
+package com.martiansoftware.jsap.examples;
+
+import com.martiansoftware.jsap.FlaggedOption;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.JSAPResult;
+import com.martiansoftware.jsap.Parameter;
+import com.martiansoftware.jsap.QualifiedSwitch;
+import com.martiansoftware.jsap.SimpleJSAP;
+import com.martiansoftware.jsap.UnflaggedOption;
+
+public class Manual_HelloWorld_Simple {
+
+ /**
+ * Repeats the "Hello World" text multiple times.
+ * Decides whether to say "Hi" or "Hello" depending upon verbose switch.
+ * Uses the new QualifiedSwitch to set the language of verbosity
+ * Uses SimpleJSAP
+ * @param args the command line.
+ * @throws Exception for reasons made clear later in the manual.
+ */
+ // @@snip:Manual_HelloWorld_Simple@@
+ public static void main(String[] args) throws Exception {
+ SimpleJSAP jsap = new SimpleJSAP(
+ "MyProgram",
+ "Repeats \"Hello, world!\" multiple times",
+ new Parameter[] {
+ new FlaggedOption( "count", JSAP.INTEGER_PARSER, "1", JSAP.REQUIRED, 'n', JSAP.NO_LONGFLAG,
+ "The number of times to say hello." ),
+ new QualifiedSwitch( "verbose", JSAP.STRING_PARSER, JSAP.NO_DEFAULT, JSAP.NOT_REQUIRED, 'v', "verbose",
+ "Requests verbose output." ).setList( true ).setListSeparator( ',' ),
+ new UnflaggedOption( "name", JSAP.STRING_PARSER, "World", JSAP.REQUIRED, JSAP.GREEDY,
+ "One or more names of people you would like to greet." )
+ }
+ );
+
+ JSAPResult config = jsap.parse(args);
+ if ( jsap.messagePrinted() ) System.exit( 1 );
+
+ String[] names = config.getStringArray("name");
+ String[] languages = config.getStringArray("verbose");
+ for (int i = 0; i < languages.length; ++i) {
+ System.out.println("language=" + languages[i]);
+ }
+ for (int i = 0; i < config.getInt("count"); ++i) {
+ for (int j = 0; j < names.length; ++j) {
+ System.out.println((config.getBoolean("verbose") ? "Hello" : "Hi")
+ + ", "
+ + names[j]
+ + "!");
+ }
+ }
+ }
+ // @@endSnip@@
+
+}
\ No newline at end of file
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/BigDecimalStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/BigDecimalStringParser.java
new file mode 100644
index 0000000..cbfdc2c
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/BigDecimalStringParser.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.ParseException;
+import java.math.BigDecimal;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing BigDecimals. The parse() method delegates the
+ * actual
+ * parsing to BigDecimal's constructor.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.math.BigDecimal
+ */
+public class BigDecimalStringParser extends StringParser {
+
+ private static final BigDecimalStringParser INSTANCE = new BigDecimalStringParser();
+
+ /** Returns a {@link BigDecimalStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#BIGDECIMAL_PARSER}.
+ *
+ * @return a {@link BigDecimalStringParser}.
+ */
+
+ public static BigDecimalStringParser getParser() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a new BigDecimalStringParser.
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#BIGDECIMAL_PARSER}.
+ */
+ public BigDecimalStringParser() {
+ super();
+ }
+
+ /**
+ * Parses the specified argument into a BigDecimal. This method simply
+ * delegates
+ * the parsing to <code>new BigDecimal(String)</code>. If BigDecimal
+ * throws a
+ * NumberFormatException, it is encapsulated into a ParseException and
+ * re-thrown.
+ *
+ * @param arg the argument to parse
+ * @return a BigDecimal object with the value contained in the specified
+ * argument.
+ * @throws ParseException if <code>new BigDecimal(arg)</code> throws a
+ * NumberFormatException.
+ * @see BigDecimal
+ * @see com.martiansoftware.jsap.StringParser#parse(String)
+ */
+ public Object parse(String arg) throws ParseException {
+ BigDecimal result = null;
+ try {
+ result = new BigDecimal(arg);
+ } catch (NumberFormatException e) {
+ throw (
+ new ParseException(
+ "Unable to convert '" + arg + "' to a BigDecimal.",
+ e));
+ }
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/BigIntegerStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/BigIntegerStringParser.java
new file mode 100644
index 0000000..870e796
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/BigIntegerStringParser.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.ParseException;
+import java.math.BigInteger;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing BigIntegers. The parse() method delegates the
+ * actual
+ * parsing to BigInteger's constructor.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.math.BigInteger
+ */
+public class BigIntegerStringParser extends StringParser {
+
+ private static final BigIntegerStringParser INSTANCE = new BigIntegerStringParser();
+
+ /** Returns a {@link BigIntegerStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#BIGINTEGER_PARSER}.
+ *
+ * @return a {@link BigIntegerStringParser}.
+ */
+ public static BigIntegerStringParser getParser() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a new BigIntegerStringParser.
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#BIGINTEGER_PARSER}.
+ */
+ public BigIntegerStringParser() {
+ super();
+ }
+
+ /**
+ * Parses the specified argument into a BigInteger. This method simply
+ * delegates
+ * the parsing to <code>new BigInteger(String)</code>. If BigInteger
+ * throws a
+ * NumberFormatException, it is encapsulated into a ParseException and
+ * re-thrown.
+ *
+ * @param arg the argument to parse
+ * @return a BigInteger object with the value contained in the specified
+ * argument.
+ * @throws ParseException if <code>new BigInteger(arg)</code> throws a
+ * NumberFormatException.
+ * @see BigInteger
+ * @see com.martiansoftware.jsap.StringParser#parse(String)
+ */
+ public Object parse(String arg) throws ParseException {
+ BigInteger result = null;
+ try {
+ result = new BigInteger(arg);
+ } catch (NumberFormatException e) {
+ throw (
+ new ParseException(
+ "Unable to convert '" + arg + "' to a BigInteger.",
+ e));
+ }
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/BooleanStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/BooleanStringParser.java
new file mode 100644
index 0000000..1265667
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/BooleanStringParser.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.ParseException;
+
+/**
+ * <p>A {@link com.martiansoftware.jsap.StringParser} for parsing Booleans. This StringParser is also used
+ * internally
+ * by the Switch class.</p>
+ *
+ * <p>When parsing, the following arguments are interpreted as TRUE:
+ * <ul>
+ * <li>null</i>
+ * <li>"t" (case-insensitive)</li>
+ * <li>"true" (case-insensitive)</li>
+ * <li>"y" (case-insensitive)</li>
+ * <li>"yes" (case-insensitive)</li>
+ * <li>"1"</li>
+ * </ul>
+ * <p>The following arguments are interpreted as FALSE:
+ * <ul>
+ * <li>"f" (case-insensitive)</li>
+ * <li>"false" (case-insensitive)</li>
+ * <li>"n" (case-insensitive)</li>
+ * <li>"no" (case-insensitive)</li>
+ * <li>"0"</li>
+ * </ul>
+ *
+ * <p>All other input throws a ParseException.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.lang.Boolean
+ */
+public class BooleanStringParser extends StringParser {
+
+ private static final BooleanStringParser INSTANCE = new BooleanStringParser();
+
+ /** Returns a {@link BooleanStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#BOOLEAN_PARSER}.
+ *
+ * @return a {@link BooleanStringParser}.
+ */
+
+ public static BooleanStringParser getParser() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a new BooleanStringParser
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#BOOLEAN_PARSER}.
+ */
+ public BooleanStringParser() {
+ super();
+ }
+
+ /**
+ * Converts the specified argument into a Boolean.
+ *
+ * <p>When parsing, the following arguments are interpreted as TRUE:
+ * <ul>
+ * <li>null</i>
+ * <li>"t" (case-insensitive)</li>
+ * <li>"true" (case-insensitive)</li>
+ * <li>"y" (case-insensitive)</li>
+ * <li>"yes" (case-insensitive)</li>
+ * <li>"1"</li>
+ * <ul>
+ * <p>The following arguments are interpreted as FALSE:
+ * <ul>
+ * <li>"f" (case-insensitive)</li>
+ * <li>"false" (case-insensitive)</li>
+ * <li>"n" (case-insensitive)</li>
+ * <li>"no" (case-insensitive)</li>
+ * <li>"0"</li>
+ * </ul>
+ *
+ * <p>All other input throws a ParseException.
+ * @param arg the argument to convert to a Boolean.
+ * @return a Boolean as described above.
+ * @throws ParseException if none of the above cases are matched.
+ */
+ public Object parse(String arg) throws ParseException {
+ boolean result = false;
+ if ((arg == null)
+ || arg.equalsIgnoreCase("t")
+ || arg.equalsIgnoreCase("true")
+ || arg.equalsIgnoreCase("y")
+ || arg.equalsIgnoreCase("yes")
+ || arg.equals("1")) {
+ result = true;
+ } else if (
+ arg.equalsIgnoreCase("f")
+ || arg.equalsIgnoreCase("false")
+ || arg.equalsIgnoreCase("n")
+ || arg.equalsIgnoreCase("no")
+ || arg.equals("0")) {
+ result = false;
+ } else {
+ throw (
+ new ParseException(
+ "Unable to convert '" + arg + "' to a boolean value."));
+ }
+ return (new Boolean(result));
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/ByteStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/ByteStringParser.java
new file mode 100644
index 0000000..9541f5d
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/ByteStringParser.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.ParseException;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing Bytes. The parse() method delegates the actual
+ * parsing to Byte.decode(String).
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.lang.Byte
+ */
+public class ByteStringParser extends StringParser {
+
+ private static final ByteStringParser INSTANCE = new ByteStringParser();
+
+ /** Returns a {@link ByteStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#BYTE_PARSER}.
+ *
+ * @return a {@link ByteStringParser}.
+ */
+
+ public static ByteStringParser getParser() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a new ByteStringParser.
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#BYTE_PARSER}.
+ */
+ public ByteStringParser() {
+ super();
+ }
+
+ /**
+ * Parses the specified argument into a Byte. This method simply delegates
+ * the parsing to <code>Byte.decode(String)</code>. If Byte throws a
+ * NumberFormatException, it is encapsulated into a ParseException and
+ * re-thrown.
+ *
+ * @param arg the argument to parse
+ * @return a Byte object with the value contained in the specified argument.
+ * @throws ParseException if <code>Byte.decode(arg)</code> throws a
+ * NumberFormatException.
+ * @see java.lang.Byte
+ * @see com.martiansoftware.jsap.StringParser#parse(String)
+ */
+ public Object parse(String arg) throws ParseException {
+ Byte result = null;
+ try {
+ result = Byte.decode(arg);
+ } catch (NumberFormatException e) {
+ throw (
+ new ParseException(
+ "Unable to convert '" + arg + "' to a Byte.",
+ e));
+ }
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/CharacterStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/CharacterStringParser.java
new file mode 100644
index 0000000..06ac73f
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/CharacterStringParser.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.ParseException;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing Characters. The parse() method requires an
+ * argument of length exactly
+ * equal to 1 in order to perform the conversion; otherwise, a ParseException
+ * is thrown.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.lang.Character
+ */
+public class CharacterStringParser extends StringParser {
+
+ private static final CharacterStringParser INSTANCE = new CharacterStringParser();
+
+ /** Returns a {@link CharacterStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#CHARACTER_PARSER}.
+ *
+ * @return a {@link CharacterStringParser}.
+ */
+
+ public static CharacterStringParser getParser() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a new CharacterStringParser.
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#CHARACTER_PARSER}.
+ */
+ public CharacterStringParser() {
+ super();
+ }
+
+ /**
+ * Parses the specified argument into a Character. The conversion is
+ * performed by
+ * checking that the specified argument is exactly 1 character long, then
+ * encapsulating
+ * that char in a Character object. If the specified argument is not
+ * exactly 1 character long,
+ * a ParseException is thrown.
+ *
+ * @param arg the argument to parse
+ * @return a Character object with the value contained in the specified
+ * argument.
+ * @throws ParseException if ( (arg==null) || (arg.length()!=1) )
+ * @see java.lang.Character
+ * @see com.martiansoftware.jsap.StringParser#parse(String)
+ */
+ public Object parse(String arg) throws ParseException {
+ if ((arg == null) || (arg.length() != 1)) {
+ throw (
+ new ParseException(
+ "Unable to convert '" + arg + "' to a Character."));
+ }
+ return (new Character(arg.charAt(0)));
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/ClassStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/ClassStringParser.java
new file mode 100644
index 0000000..8a85585
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/ClassStringParser.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.ParseException;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing Class objects. The parse(arg) method calls
+ * Class.forName(arg) and returns
+ * the result. If any exceptions are thrown by Class.forName(), they are
+ * encapsulated in a ParseException
+ * and re-thrown.
+ *
+ * <p><b>Note:</b> The Class.forName() call attempts to load the class from the
+ * same ClassLoader that loaded
+ * this StringParser.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.lang.Class
+ */
+public class ClassStringParser extends StringParser {
+
+ private static final ClassStringParser INSTANCE = new ClassStringParser();
+
+ /** Returns a {@link ClassStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#CLASS_PARSER}.
+ *
+ * @return a {@link ClassStringParser}.
+ */
+
+ public static ClassStringParser getParser() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a new ClassStringParser.
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#CLASS_PARSER}.
+ */
+ public ClassStringParser() {
+ super();
+ }
+
+ /**
+ * Parses the specified argument into a Class object. This method calls
+ * Class.forName(), passing
+ * the specified argument as the name of the class to load, and returns
+ * the resulting Class object.
+ * If an exception is thrown by Class.forName(), it is encapsulated in a
+ * ParseException and re-thrown.
+ *
+ * @param arg the argument to parse
+ * @return a Class object representing the class named by the specified
+ * argument.
+ * @throws ParseException if <code>Class.forName(arg)</code> throws an
+ * exception.
+ * @see java.lang.Class
+ * @see com.martiansoftware.jsap.StringParser#parse(String)
+ */
+ public Object parse(String arg) throws ParseException {
+ Class result = null;
+ try {
+ result = Class.forName(arg);
+ } catch (Exception e) {
+ throw (
+ new ParseException("Unable to locate class '" + arg + "'.", e));
+ }
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/ColorStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/ColorStringParser.java
new file mode 100644
index 0000000..cd10409
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/ColorStringParser.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.ParseException;
+import com.martiansoftware.jsap.StringParser;
+
+import java.awt.Color;
+import java.util.StringTokenizer;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing java.awt.Color objects. Color information can be
+ * specified in a variety
+ * of formats:
+ *
+ * <ul>
+ * <li>RGB, as integers in the range 0-255, separated by commas
+ * (e.g., "123,45,6")</li>
+ * <li>RGB, as floats in the range 0.0-1.0, separated by commas
+ * (e.g., "0.123,0.45,0.6")</li>
+ * <li>RGB, as hexadecimal strings following the '#' character
+ * (e.g., "#1234ef")</li>
+ * <li>By name, as matching the names of the color fields of java.awt.Color
+ * (case-insensitive). (e.g., "black")</li>
+ * <li>RGBAlpha, as integers in the range 0-255, separated by commas
+ * (e.g., "123,45,6,128")</li>
+ * <li>RGBAlpha, as floats in the range 0.0-1.0, separated by commas
+ * (e.g., "0.123,0.45,0.6,.5")</li>
+ * <li>RGBAlpha, as hexadecimal strings following the '#' character
+ * (e.g., "#1234efab")</li>
+ * </ul>
+ *
+ * If the specified argument does not match any of these formats, a
+ * ParseException is thrown.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.awt.Color
+ */
+public class ColorStringParser extends StringParser {
+
+ private static final ColorStringParser INSTANCE = new ColorStringParser();
+
+ /** Returns a {@link ColorStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#COLOR_PARSER}.
+ *
+ * @return a {@link ColorStringParser}.
+ */
+
+ public static ColorStringParser getParser() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a new ColorStringParser.
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#COLOR_PARSER}.
+ */
+ public ColorStringParser() {
+ super();
+ }
+
+ /**
+ * Simple utility for creating ParseExceptions, as there are so many
+ * opportunities to throw them.
+ * @param s the ParseException's message.
+ * @return a new ParseException with the specified message.
+ */
+ private ParseException colorException(String s) {
+ return (
+ new ParseException("Unable to convert '" + s + "' to a Color."));
+ }
+
+ /**
+ * Parses a hexadecimal String into a Color.
+ * @param hexString the hexadecimal String to parse.
+ * @return a Color object based upon the specified color string.
+ * @throws ParseException if the specified String cannot be interpreted as
+ * a Color.
+ */
+ private Color parseHexColor(String hexString) throws ParseException {
+ Color result = null;
+ int hexLength = hexString.length();
+ if ((hexLength != 7) && (hexLength != 9)) {
+ throw (colorException(hexString));
+ }
+ try {
+ int red = Integer.parseInt(hexString.substring(1, 3), 16);
+ int green = Integer.parseInt(hexString.substring(3, 5), 16);
+ int blue = Integer.parseInt(hexString.substring(5, 7), 16);
+ if (hexLength == 7) {
+ result = new Color(red, green, blue);
+ } else {
+ int alpha = Integer.parseInt(hexString.substring(7, 9), 16);
+ result = new Color(red, green, blue, alpha);
+ }
+ } catch (NumberFormatException e) {
+ throw (colorException(hexString));
+ }
+ return (result);
+ }
+
+ /**
+ * Parses a 3- or 4-tuple of comma-separated floats into a Color.
+ * @param floatString the String to parse.
+ * @return a Color object based upon the specified String.
+ * @throws ParseException if the specified String cannot be interpreted as
+ * a Color.
+ */
+ private Color parseFloatTuple(String floatString) throws ParseException {
+ String[] tuple = tupleToArray(floatString);
+ Color result = null;
+ try {
+ float red = Float.parseFloat(tuple[0]);
+ float green = Float.parseFloat(tuple[1]);
+ float blue = Float.parseFloat(tuple[2]);
+ if (tuple.length == 3) {
+ result = new Color(red, green, blue);
+ } else {
+ float alpha = Float.parseFloat(tuple[3]);
+ result = new Color(red, green, blue, alpha);
+ }
+ } catch (NumberFormatException e) {
+ throw (colorException(floatString));
+ }
+ return (result);
+ }
+
+ /**
+ * Parses a 3- or 4-tuple of comma-separated integers into a Color.
+ * @param intString the String to parse.
+ * @return a Color object based upon the specified color String.
+ * @throws ParseException if the specified String cannot be interpreted as
+ * a Color.
+ */
+ private Color parseIntTuple(String intString) throws ParseException {
+ String[] tuple = tupleToArray(intString);
+ Color result = null;
+ try {
+ int red = Integer.parseInt(tuple[0]);
+ int green = Integer.parseInt(tuple[1]);
+ int blue = Integer.parseInt(tuple[2]);
+ if (tuple.length == 3) {
+ result = new Color(red, green, blue);
+ } else {
+ int alpha = Integer.parseInt(tuple[3]);
+ result = new Color(red, green, blue, alpha);
+ }
+ } catch (NumberFormatException e) {
+ throw (colorException(intString));
+ }
+ return (result);
+ }
+
+ /**
+ * Parses a String into a Color by name (names lifted from java.awt.Color).
+ * @param colorName the name of the desired Color.
+ * @return a Color object based upon the specified color name.
+ * @throws ParseException if the specified String is not a valid color name.
+ */
+ private Color parseColorName(String colorName) throws ParseException {
+ Color result = null;
+ if (colorName.equalsIgnoreCase("black")) {
+ result = Color.black;
+ } else if (colorName.equalsIgnoreCase("blue")) {
+ result = Color.blue;
+ } else if (colorName.equalsIgnoreCase("cyan")) {
+ result = Color.cyan;
+ } else if (colorName.equalsIgnoreCase("gray")) {
+ result = Color.gray;
+ } else if (colorName.equalsIgnoreCase("green")) {
+ result = Color.green;
+ } else if (colorName.equalsIgnoreCase("lightGray")) {
+ result = Color.lightGray;
+ } else if (colorName.equalsIgnoreCase("magenta")) {
+ result = Color.magenta;
+ } else if (colorName.equalsIgnoreCase("orange")) {
+ result = Color.orange;
+ } else if (colorName.equalsIgnoreCase("pink")) {
+ result = Color.pink;
+ } else if (colorName.equalsIgnoreCase("red")) {
+ result = Color.red;
+ } else if (colorName.equalsIgnoreCase("white")) {
+ result = Color.white;
+ } else if (colorName.equalsIgnoreCase("yellow")) {
+ result = Color.yellow;
+ } else {
+ throw (colorException(colorName));
+ }
+ return (result);
+ }
+
+ /**
+ * Parses a 3- or 4-tuple, comma separated, to an array.
+ * @param s the String to be parsed to an array.
+ * @return the parsed String as a 3- or 4-element array of Strings.
+ * @throws ParseException if the specified String contains fewer than 3 or
+ * more than 4 elements.
+ */
+ private String[] tupleToArray(String s) throws ParseException {
+ String[] result = null;
+ StringTokenizer tokenizer = new StringTokenizer(s, ",", true);
+ int tokenCount = tokenizer.countTokens();
+ if (tokenCount == 5) {
+ result = new String[3];
+ } else if (tokenCount == 7) {
+ result = new String[4];
+ } else {
+ throw (colorException(s));
+ }
+ result[0] = tokenizer.nextToken();
+ tokenizer.nextToken();
+ result[1] = tokenizer.nextToken();
+ tokenizer.nextToken();
+ result[2] = tokenizer.nextToken();
+ if (tokenCount == 7) {
+ tokenizer.nextToken();
+ result[3] = tokenizer.nextToken();
+ }
+ return (result);
+ }
+
+ /**
+ * Parses java.awt.Color objects from Strings. Color information can be
+ * specified in a variety
+ * of formats:
+ *
+ * <ul>
+ * <li>RGB, as integers in the range 0-255, separated by commas
+ * (e.g., "123,45,6")</li>
+ * <li>RGB, as floats in the range 0.0-1.0, separated by commas
+ * (e.g., "0.123,0.45,0.6")</li>
+ * <li>RGB, as hexadecimal strings following the '#' character
+ * (e.g., "#1234ef")</li>
+ * <li>By name, as matching the names of the color fields of java.awt.Color
+ * (case-insensitive).
+ * (e.g., "black")</li>
+ * <li>RGBAlpha, as integers in the range 0-255, separated by commas
+ * (e.g., "123,45,6,128")</li>
+ * <li>RGBAlpha, as floats in the range 0.0-1.0, separated by commas
+ * (e.g., "0.123,0.45,0.6,.5")</li>
+ * <li>RGBAlpha, as hexadecimal strings following the '#' character
+ * (e.g., "#1234efab")</li>
+ * </ul>
+ *
+ * If the specified argument does not match any of these formats, a
+ * ParseException is thrown.
+ * @param arg the String to convert to a Color object.
+ * @return the Color specified by arg.
+ * @throws ParseException if arg cannot be interpreted as a Color as
+ * described above.
+ */
+ public Object parse(String arg) throws ParseException {
+ Color result = null;
+ if (arg.charAt(0) == '#') {
+ result = parseHexColor(arg);
+ } else if (arg.indexOf(".") >= 0) {
+ result = parseFloatTuple(arg);
+ } else if (arg.indexOf(",") >= 0) {
+ result = parseIntTuple(arg);
+ } else {
+ result = parseColorName(arg);
+ }
+ return (result);
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/DateStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/DateStringParser.java
new file mode 100644
index 0000000..b8cfbdc
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/DateStringParser.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.ParseException;
+import com.martiansoftware.jsap.PropertyStringParser;
+
+import java.util.Date;
+import java.text.SimpleDateFormat;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing java.util.Date objects. By default, arguments
+ * are parsed using the
+ * java.text.SimpleDateFormat for the default locale. The format can be
+ * overridden using this StringParser's
+ * setProperties() method, supplying a java.util.Properties object with a
+ * property key named "format".
+ * The value associated with the "format" property is used to create a new
+ * java.text.SimpleDateFormat
+ * to parse the argument.
+ *
+ * <p>A ParseException is thrown if a SimpleDateFormat cannot be constructed with
+ * the specified format, or if the SimpleDateFormat throws a
+ * java.text.ParseException during parsing.
+ *
+ * <p>The SimpleDateFormat object is instantiated when an option referencing this
+ * DateStringParser is
+ * registered with a JSAP object.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.util.Date
+ * @see java.text.SimpleDateFormat
+ */
+public class DateStringParser extends PropertyStringParser {
+
+ /**
+ * The SimpleDateFormat used to do the parsing.
+ */
+ private SimpleDateFormat format = null;
+
+ /** Returns a {@link DateStringParser}.
+ *
+ * @return a {@link DateStringParser}.
+ */
+
+ public static DateStringParser getParser() {
+ return new DateStringParser();
+ }
+
+ /**
+ * Creates a new DateStringParser.
+ * @deprecated Use {@link #getParser()}.
+ */
+ public DateStringParser() {
+ super();
+ }
+
+ /**
+ * Instantiates the SimpleDateFormat to use for parsing.
+ * @throws ParseException if a SimpleDateFormat cannot be instantiated with
+ * the contents of the
+ * "format" property.
+ */
+ public void setUp() throws ParseException {
+ String formatString = this.getProperty("format");
+ if (formatString == null) {
+ format = new SimpleDateFormat();
+ } else {
+ try {
+ format = new SimpleDateFormat(formatString);
+ }
+ catch( RuntimeException e ) {
+ throw new ParseException( e );
+ }
+ }
+ }
+
+ /**
+ * Destroys the SimpleDateFormat used for parsing.
+ */
+ public void tearDown() {
+ format = null;
+ }
+
+ /**
+ * Parses the specified argument using either the java.text.SimpleDateFormat
+ * for the current locale
+ * (by default) or a java.text.SimpleDateFormat as defined by this
+ * PropertyStringParser's "format"
+ * property.
+ *
+ * If the specified argument cannot be parsed by the current format, a
+ * ParseException is thrown.
+ *
+ * @param arg the argument to convert to a Date.
+ * @return a Date as described above.
+ * @throws ParseException if the specified argument cannot be parsed by the
+ * current format..
+ */
+ public Object parse(String arg) throws ParseException {
+ Date result = null;
+ try {
+ result = format.parse(arg);
+ } catch (java.text.ParseException e) {
+ throw (
+ new ParseException(
+ "Unable to convert '" + arg + "' to a Date.",
+ e));
+ }
+ return (result);
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/DoubleStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/DoubleStringParser.java
new file mode 100644
index 0000000..81f88b8
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/DoubleStringParser.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.ParseException;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing Doubles. The parse() method delegates the actual
+ * parsing to new Double(String). If a NumberFormatException is thrown by new
+ * Double(String), it
+ * is encapsulated in a ParseException and re-thrown.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.lang.Double
+ */
+public class DoubleStringParser extends StringParser {
+
+ private static final DoubleStringParser INSTANCE = new DoubleStringParser();
+
+ /** Returns a {@link DoubleStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#DOUBLE_PARSER}.
+ *
+ * @return a {@link DoubleStringParser}.
+ */
+
+ public static DoubleStringParser getParser() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a new DoubleStringParser.
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#DOUBLE_PARSER}.
+ */
+ public DoubleStringParser() {
+ super();
+ }
+
+ /**
+ * Parses the specified argument into a Double. This method simply
+ * delegates the actual
+ * parsing to new Double(String). If a NumberFormatException is thrown by
+ * new Double(String), it
+ * is encapsulated in a ParseException and re-thrown.
+ *
+ * @param arg the argument to parse
+ * @return a Double object with the value contained in the specified
+ * argument.
+ * @throws ParseException if <code>new Double(arg)</code> throws a
+ * NumberFormatException.
+ * @see java.lang.Double
+ * @see com.martiansoftware.jsap.StringParser#parse(String)
+ */
+ public Object parse(String arg) throws ParseException {
+ Double result = null;
+ try {
+ result = new Double(arg);
+ } catch (NumberFormatException e) {
+ throw (
+ new ParseException(
+ "Unable to convert '" + arg + "' to a Double.",
+ e));
+ }
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/EnumeratedStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/EnumeratedStringParser.java
new file mode 100644
index 0000000..6e17328
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/EnumeratedStringParser.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import java.util.Arrays;
+import java.util.StringTokenizer;
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.ParseException;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} that enforces a limited set of String options for its
+ * values.
+ * These values are provided in the constructor together with one or two parameters
+ * that control the processing of these values.
+ *
+ * <p>EnumeratedStringParser was generously
+ * contributed to JSAP by Klaus-Peter Berg of Siemens AG, Munich, Germany.
+ * @since 1.03
+ * @author Klaus-Peter Berg, Siemens AG, Munich, Germany
+ * @version 2.0
+ */
+public class EnumeratedStringParser extends StringParser {
+
+ /**
+ * char used to separate enumerated values when they are supplied
+ * to the constructor
+ */
+ public static final char CONSTRUCTOR_VALUE_SEPARATOR = ';';
+
+
+ private String[] validOptionValuesArray = null;
+ private boolean isCaseSensitive;
+ private boolean checkOptionChars;
+
+ /**
+ * Returns an EnumeratedParameterParser.
+ *
+ * @param validOptionValues a string that contains valid values for an option
+ * in the format "value_1;value_2;..;value_n"; spaces between values are allowed
+ * to make things more readable, e.g., "value_1; value_2";
+ * option values have to be constructed using Java identifier characters
+ * if the checkOptionChars parameter tells the parser to do this.
+ * @param caseSensitive tells the parser whether the option value is case sensitive
+ * @param checkOptionChars tells the parser whether to check for Java identifier conformant characters.
+ * @throws IllegalArgumentException if the option value string has wrong format
+ * or is empty
+ */
+ public static EnumeratedStringParser getParser( String validOptionValues, boolean caseSensitive, boolean checkOptionChars ) throws IllegalArgumentException {
+ return new EnumeratedStringParser( validOptionValues, caseSensitive, checkOptionChars );
+ }
+
+ /**
+ * Constructs a new instance of EnumeratedParameterParser.
+ *
+ * @param validOptionValues a string that contains valid values for an option
+ * in the format "value_1;value_2;..;value_n"; spaces between values are allowed
+ * to make things more readable, e.g., "value_1; value_2";
+ * option values have to be constructed using Java identifier characters
+ * if the checkOptionChars parameter tells the parser to do this.
+ * @param caseSensitive tells the parser whether the option value is case sensitive
+ * @param checkOptionChars tells the parser whether to check for Java identifier conformant characters.
+ * @throws IllegalArgumentException if the option value string has wrong format
+ * or is empty
+ * @deprecated use {@link #getParser(String, boolean, boolean)}.
+ */
+ public EnumeratedStringParser(String validOptionValues, boolean caseSensitive, boolean checkOptionChars) throws IllegalArgumentException {
+ if (validOptionValues == null) {
+ throw new IllegalArgumentException("EnumeratedStringParser validOptions parameter is null");
+ }
+ if (validOptionValues.length() == 0) {
+ throw new IllegalArgumentException("EnumeratedStringParser validOptions parameter is empty");
+ }
+
+ this.isCaseSensitive = caseSensitive;
+ this.checkOptionChars = checkOptionChars;
+ if (validOptionValues.indexOf(CONSTRUCTOR_VALUE_SEPARATOR) == -1) {
+ validOptionValuesArray = new String[1]; // we assume to have only one valid option value
+ if (isValidOptionName(validOptionValues)) {
+ validOptionValuesArray[0] = validOptionValues;
+ }
+ else {
+ throw new IllegalArgumentException("Wrong character in EnumeratedStringParser option value: "+validOptionValues
+ + "\nsee EnumeratedStringParser javadoc for more information");
+ }
+ }
+ else {
+ StringTokenizer stok = new StringTokenizer(validOptionValues, ";");
+ validOptionValuesArray = new String[stok.countTokens()];
+ int i = 0;
+ while (stok.hasMoreTokens()) {
+ String value = stok.nextToken().trim();
+ if (!isCaseSensitive) {
+ value = value.toLowerCase();
+ }
+ if (isValidOptionName(value)) {
+ validOptionValuesArray[i++] = value;
+ }
+ else {
+ throw new IllegalArgumentException("Wrong character in EnumeratedStringParser option value: "+value
+ + "\nsee EnumeratedStringParser javadoc for more information");
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Returns an EnumeratedParameterParser with parameter "checkOptionChars" set to true.
+ *
+ * @param validOptionValues a string that contains valid values for an option
+ * in the format "value_1;value_2;..;value_n"; spaces between values are allowed
+ * to make things more readable, e.g., "value_1; value_2";
+ * option values have to be constructed using Java identifier characters.
+ * @param caseSensitive tells the parser wether the option value is case sensitive
+ * @throws IllegalArgumentException if the option value string has wrong format
+ * or is empty
+ */
+ public static EnumeratedStringParser getParser(String validOptionValues, boolean caseSensitive) throws IllegalArgumentException {
+ return new EnumeratedStringParser( validOptionValues, caseSensitive, true );
+ }
+
+ /**
+ * Constructs a new instance of EnumeratedStringParser.
+ * @deprecated use {@link #getParser(String, boolean)}.
+ *
+ */
+ public EnumeratedStringParser(String validOptionValues, boolean caseSensitive) throws IllegalArgumentException {
+ this(validOptionValues, caseSensitive, true);
+ }
+
+
+ /**
+ * Returns an EnumeratedParameterParser with parameter
+ * "caseSensitive" set to false and "checkOptionChars" set to true.
+ * All command line arguments for this parser and the values provided
+ * by the user in the returned parser are converted to lower case.
+ *
+ * @param validOptionValues a string that contains valid values for an option
+ * in the format "value_1;value_2;..;value_n"; spaces between values are allowed
+ * to make things more readable, e.g., "value_1; value_2";
+ * option values have to be constructed using Java identifier characters.
+ * @throws IllegalArgumentException if the option value string has wrong format
+ * or is empty
+ */
+ public static EnumeratedStringParser getParser(String validOptionValues) throws IllegalArgumentException {
+ return new EnumeratedStringParser( validOptionValues, false, true );
+ }
+
+
+ /**
+ * Constructs a new instance of EnumeratedStringParser.
+ * @deprecated use {@link #getParser(String)}.
+ */
+ public EnumeratedStringParser(String validOptionValues) throws IllegalArgumentException {
+ this(validOptionValues, false, true);
+ }
+
+ /**
+ * Parses the specified argument, making sure it matches one of the valid
+ * options supplied to its constructor.
+ * If the specified argument is not a valid option,
+ * a ParseException is thrown.
+ *
+ * @param arg the argument to parse
+ * @return the String resulting from the parsed argument.
+ * @throws ParseException if the specified argument cannot be parsed.
+ */
+ public Object parse(String arg) throws ParseException {
+ if (arg == null) {
+ return null;
+ }
+ if (!isCaseSensitive) {
+ arg = arg.toLowerCase();
+ }
+ if (!isValidOptionName(arg)) {
+ throw new ParseException("Wrong character in command line option value for enumerated option: '" + arg + "'"
+ +"\nallowed are alphanumeric characters + '$' and '_' sign only",
+ new IllegalArgumentException());
+ }
+ // we cannot use Arrays.binarySearch() because strings cannot be
+ // sorted according to the required natural order!
+ if (Arrays.asList(validOptionValuesArray).contains(arg)) {
+ return arg;
+ }
+ else {
+ throw new ParseException("Option has wrong value '" + arg + "'"
+ + "; valid values are: "+Arrays.asList(validOptionValuesArray), new IllegalArgumentException());
+ }
+ }
+
+ /**
+ * Check for valid enumerated option values ("names").
+ * Allowed are Java identifier chars, i.e., alphanumeric chars + '$' + _' signs.
+ * If you need a different validation scheme you can override this method
+ * when subclassig EnumeratedStringParser.
+ *
+ * @param name the option value to check
+ *
+ * @return true, if the value contains only valid chars, false otherwise
+ */
+ protected boolean isValidOptionName(String name) {
+ if (!checkOptionChars) {
+ return true;
+ }
+ for (int i=0; i<name.length(); i++) {
+ char c = name.charAt(i);
+ if (Character.isJavaIdentifierPart(c)) {
+ continue;
+ }
+ else {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/FileStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/FileStringParser.java
new file mode 100644
index 0000000..bb2b515
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/FileStringParser.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.PropertyStringParser;
+import com.martiansoftware.jsap.ParseException;
+import java.io.File;
+
+/**
+ * A StringParser for parsing {@link File} objects. The parse() method
+ * delegates the actual
+ * parsing to <code>new File(String)</code>. If <code>new File(String)</code>
+ * throws a NullPointerException, it is encapsulated in a ParseException and
+ * re-thrown.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @author Edward Glen (edward at glencomm.com) (modified URLStringParser)
+ * @author Eric Sword (made setters return "this", fixed bug triggered when
+ * file does not exist)
+ * @since 1.4
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.net.URL
+ */
+public class FileStringParser extends PropertyStringParser {
+
+ public static final String MUSTBEFILE = "mustBeFile";
+ public static final String MUSTBEDIRECTORY = "mustBeDirectory";
+ public static final String MUSTEXIST = "mustExist";
+
+ private boolean mustExist = false;
+ private boolean mustBeDirectory = false;
+ private boolean mustBeFile = false;
+
+ /** Creates a new FileStringParser.
+ * @deprecated use {@link #getParser()}.
+ */
+ public FileStringParser() {
+ super();
+ }
+
+ /** Returns a new {@link FileStringParser}.
+ * @return a new {@link FileStringParser}.
+ */
+ public static FileStringParser getParser() {
+ return new FileStringParser();
+ }
+
+ public void setUp() throws ParseException {
+ BooleanStringParser bool = JSAP.BOOLEAN_PARSER;
+ setMustExist(((Boolean) bool.parse(getProperty(MUSTEXIST, (new Boolean(mustExist)).toString()))).booleanValue());
+ setMustBeDirectory(((Boolean) bool.parse(getProperty(MUSTBEDIRECTORY, (new Boolean(mustBeDirectory)).toString()))).booleanValue());
+ setMustBeFile(((Boolean) bool.parse(getProperty(MUSTBEFILE, (new Boolean(mustBeFile)).toString()))).booleanValue());
+ }
+
+ public FileStringParser setMustBeDirectory(boolean mustBeDirectory) {
+ this.mustBeDirectory = mustBeDirectory;
+ return this;
+ }
+
+ public FileStringParser setMustBeFile(boolean mustBeFile) {
+ this.mustBeFile = mustBeFile;
+ return this;
+ }
+
+ public FileStringParser setMustExist(boolean mustExist) {
+ this.mustExist = mustExist;
+ return this;
+ }
+
+ public boolean mustBeDirectory() {
+ return (mustBeDirectory);
+ }
+
+ public boolean mustBeFile() {
+ return (mustBeFile);
+ }
+
+ public boolean mustExist() {
+ return (mustExist);
+ }
+
+ public void tearDown() {
+ }
+
+ /**
+ * Parses the specified argument into a File. This method delegates the
+ * actual
+ * parsing to <code>new File(arg)</code>. If <code>new File(arg)</code>
+ * throws a NullPointerException, it is encapsulated in a ParseException
+ * and re-thrown.
+ *
+ * @param arg the argument to parse
+ * @return a File as specified by arg.
+ * @throws ParseException if <code>new File(arg)</code> throws a
+ * NullPointerException.
+ * @see java.io File
+ * @see com.martiansoftware.jsap.StringParser#parse(String)
+ */
+ public Object parse(String arg) throws ParseException {
+ File result = null;
+ try {
+ result = new File(arg);
+
+ if (mustExist() && !result.exists()) {
+ throw (new ParseException(result + " does not exist."));
+ }
+ if (mustBeDirectory() && result.exists() && !result.isDirectory()) {
+ throw (new ParseException(result + " is not a directory."));
+ }
+ if (mustBeFile() && result.exists() && result.isDirectory()) {
+ throw (new ParseException(result + " is not a file."));
+ }
+ } catch (NullPointerException e) {
+ throw (
+ new ParseException(
+ "No File given to parse",
+ e));
+ }
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/FloatStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/FloatStringParser.java
new file mode 100644
index 0000000..d338247
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/FloatStringParser.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.ParseException;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing Floats. The <code>parse()</code> method delegates
+ * the actual
+ * parsing to <code>new Float(String)</code>. If <code>new Float(String)</code>
+ * throws a NumberFormatException, it
+ * is encapsulated in a ParseException and re-thrown.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.lang.Float
+ */
+public class FloatStringParser extends StringParser {
+
+ private static final FloatStringParser INSTANCE = new FloatStringParser();
+
+ /** Returns a {@link FloatStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#FLOAT_PARSER}.
+ *
+ * @return a {@link FloatStringParser}.
+ */
+
+ public static FloatStringParser getParser() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a new FloatStringParser.
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#FLOAT_PARSER}.
+ */
+ public FloatStringParser() {
+ super();
+ }
+
+ /**
+ * Parses the specified argument into a Float. This method delegates the
+ * actual
+ * parsing to new Float(String). If new Float(String) throws a
+ * NumberFormatException, it
+ * is encapsulated in a ParseException and re-thrown.
+ *
+ * @param arg the argument to parse
+ * @return a Float object with the value contained in the specified
+ * argument.
+ * @throws ParseException if <code>new Float(arg)</code> throws a
+ * NumberFormatException.
+ * @see java.lang.Float
+ * @see com.martiansoftware.jsap.StringParser#parse(String)
+ */
+ public Object parse(String arg) throws ParseException {
+ Float result = null;
+ try {
+ result = new Float(arg);
+ } catch (NumberFormatException e) {
+ throw (
+ new ParseException(
+ "Unable to convert '" + arg + "' to a Float.",
+ e));
+ }
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/ForNameStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/ForNameStringParser.java
new file mode 100644
index 0000000..300e7d7
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/ForNameStringParser.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import java.lang.reflect.Method;
+
+import com.martiansoftware.jsap.ParseException;
+import com.martiansoftware.jsap.StringParser;
+
+
+/** A {@link com.martiansoftware.jsap.StringParser} that passes the
+ * argument to a static method of signature <code>forName(String)</code> of a specified class.
+ *
+ * <P>Note that, for instance, this parser can be used with {@link java.lang.Class} (resulting in a
+ * string parser identical to {@link com.martiansoftware.jsap.stringparsers.ClassStringParser}),
+ * but also {@link java.nio.charset.Charset}, and more generally, any class using the <code>forName(String)</code>
+ * convention.
+ *
+ * @author Sebastiano Vigna
+ */
+
+public class ForNameStringParser extends StringParser {
+
+ /** The class array describing the parameters (a string) of <code>forName</code>. */
+ private final static Class[] PARAMETERS = new Class[] { String.class };
+
+ /** The class given to the constructor. */
+ private final Class klass;
+ /** The <code>forName(String)</code> static method of {@link #klass}. */
+ private final Method forName;
+
+ private ForNameStringParser( final Class klass ) throws SecurityException, NoSuchMethodException {
+ this.klass = klass;
+ forName = klass.getMethod( "forName", PARAMETERS );
+ }
+
+ /** Returns a class <code>forName()</code> string parser.
+ *
+ * <p>When required to parse an argument, the returned string parser will return the
+ * object obtain by means of a call to a static method of <code>klass</code> of signature
+ * <code>forName(String)</code>.
+ *
+ * @param klass a class with a static method of signature <code>forName(String)</code>.
+ */
+
+ public static ForNameStringParser getParser( final Class klass ) throws SecurityException, NoSuchMethodException {
+ return new ForNameStringParser( klass );
+ }
+
+ public Object parse( String arg ) throws ParseException {
+ try {
+ return forName.invoke( klass, new Object[] { arg } );
+ }
+ catch ( Exception e ) {
+ throw new ParseException ( e );
+ }
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/InetAddressStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/InetAddressStringParser.java
new file mode 100644
index 0000000..9340845
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/InetAddressStringParser.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.ParseException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing java.net.InetAddress objects. The parse() method
+ * delegates the actual
+ * parsing to <code>InetAddress.getByName(String)</code>. If
+ * <code>InetAddress.getByName()</code>
+ * throws an UnknownHostException, it is encapsulated in a ParseException and
+ * re-thrown.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.net.InetAddress
+ */
+public class InetAddressStringParser extends StringParser {
+
+ private static final InetAddressStringParser INSTANCE = new InetAddressStringParser();
+
+ /** Returns a {@link InetAddressStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#INETADDRESS_PARSER}.
+ *
+ * @return a {@link InetAddressStringParser}.
+ */
+
+ public static InetAddressStringParser getParser() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a new InetAddressStringParser.
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#INETADDRESS_PARSER}.
+ */
+ public InetAddressStringParser() {
+ super();
+ }
+
+ /**
+ * Parses the specified argument into an InetAddress. This method
+ * delegates the actual
+ * parsing to <code>InetAddress.getByName(arg)</code>. If
+ * <code>InetAddress.getByName(arg)</code>
+ * throws an UnknownHostException, it is encapsulated in a ParseException
+ * and re-thrown.
+ *
+ * @param arg the argument to parse
+ * @return an InetAddress object representing the specified address.
+ * @throws ParseException if <code>InetAddress.getByName(arg)</code> throws
+ * an UnknownHostException.
+ * @see java.net InetAddress
+ * @see com.martiansoftware.jsap.StringParser#parse(String)
+ */
+ public Object parse(String arg) throws ParseException {
+ InetAddress result = null;
+ try {
+ result = InetAddress.getByName(arg);
+ } catch (UnknownHostException e) {
+ throw (new ParseException("Unknown host: " + arg, e));
+ }
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/IntSizeStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/IntSizeStringParser.java
new file mode 100644
index 0000000..6305a9e
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/IntSizeStringParser.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.ParseException;
+import com.martiansoftware.jsap.StringParser;
+
+/** A {@link com.martiansoftware.jsap.StringParser} that works like {@link LongSizeStringParser}, but
+ * additionally checks that the result is not larger than {@link Integer#MAX_VALUE}.
+ *
+ * @author Sebastiano Vigna
+ */
+
+public class IntSizeStringParser extends StringParser {
+
+ /** The only instance of this parser. Aliased to <code>JSAP.INT_SIZE_PARSER</code>. */
+ final static IntSizeStringParser INSTANCE = new IntSizeStringParser();
+
+ private IntSizeStringParser() {}
+
+
+ /** Returns the only instance of an {@link IntSizeStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#INTSIZE_PARSER}.
+ *
+ * @return the only instance of an {@link IntSizeStringParser}.
+ */
+ public static IntSizeStringParser getParser() {
+ return INSTANCE;
+ }
+
+ public Object parse( String arg ) throws ParseException {
+ final long size = LongSizeStringParser.parseSize( arg );
+ if ( size > Integer.MAX_VALUE ) throw new ParseException( "Integer size '" + arg + "' is too big." );
+ return new Integer( (int)size );
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/IntegerStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/IntegerStringParser.java
new file mode 100644
index 0000000..ee815f8
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/IntegerStringParser.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.ParseException;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing Integers. The parse() method delegates the actual
+ * parsing to Integer.decode(String).
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.lang.Integer
+ */
+public class IntegerStringParser extends StringParser {
+
+ private static final IntegerStringParser INSTANCE = new IntegerStringParser();
+
+ /** Returns a {@link IntegerStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#INTEGER_PARSER}.
+ *
+ * @return a {@link IntegerStringParser}.
+ */
+ public static IntegerStringParser getParser() {
+ return new IntegerStringParser();
+ }
+
+ /**
+ * Creates a new IntegerStringParser.
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#INTEGER_PARSER}.
+ */
+ public IntegerStringParser() {
+ super();
+ }
+
+ /**
+ * Parses the specified argument into an Integer. This method delegates
+ * the parsing to <code>Integer.decode(arg)</code>. If
+ * <code>Integer.decode()</code> throws a
+ * NumberFormatException, it is encapsulated into a ParseException and
+ * re-thrown.
+ *
+ * @param arg the argument to parse
+ * @return an Integer object with the value contained in the specified
+ * argument.
+ * @throws ParseException if <code>Integer.decode(arg)</code> throws a
+ * NumberFormatException.
+ * @see java.lang.Integer
+ * @see com.martiansoftware.jsap.StringParser#parse(String)
+ */
+ public Object parse(String arg) throws ParseException {
+ Integer result = null;
+ try {
+ result = Integer.decode(arg);
+ } catch (NumberFormatException nfe) {
+ throw (
+ new ParseException(
+ "Unable to convert '" + arg + "' to an Integer.",
+ nfe));
+ }
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/LongSizeStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/LongSizeStringParser.java
new file mode 100644
index 0000000..ea7c8df
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/LongSizeStringParser.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.martiansoftware.jsap.ParseException;
+import com.martiansoftware.jsap.StringParser;
+
+/** A {@link com.martiansoftware.jsap.StringParser} that lets the user specify sizes with an optional unit.
+ *
+ * <P>This parser will parse its argument using {@link #parseSize(CharSequence)}.
+ *
+ * @author Sebastiano Vigna
+ * @see com.martiansoftware.jsap.stringparsers.IntSizeStringParser
+ */
+
+public class LongSizeStringParser extends StringParser {
+
+ /** The regular expression used to parse the size specification. */
+ private static final Pattern PARSE_SIZE_REGEX = Pattern.compile( "((#|0x|0X)?[0-9A-Fa-f]+)([KMGTP]i?)?" );
+
+ /** The big integer used to check that the result is smaller than {@link Long#MAX_VALUE}. */
+ private static final BigInteger LONG_MAX_VALUE = new BigInteger( Long.toString( Long.MAX_VALUE ) );
+
+ /** A map from units to their size. */
+ private static final HashMap UNIT2SIZE = new HashMap();
+
+ /** The only instance of this parser. Aliased to <code>JSAP.LONG_SIZE_PARSER</code>. */
+ final static LongSizeStringParser INSTANCE = new LongSizeStringParser();
+
+ private LongSizeStringParser() {}
+
+ /** Returns the only instance of a {@link LongSizeStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#LONGSIZE_PARSER}.
+ *
+ * @return the only instance of a {@link LongSizeStringParser}.
+ */
+ public static LongSizeStringParser getParser() {
+ return INSTANCE;
+ }
+
+
+ public Object parse( String arg ) throws ParseException {
+ return new Long( parseSize( arg ) );
+ }
+
+ static {
+ UNIT2SIZE.put( "K", new Long( (long)1E3 ) );
+ UNIT2SIZE.put( "M", new Long( (long)1E6 ) );
+ UNIT2SIZE.put( "G", new Long( (long)1E9 ) );
+ UNIT2SIZE.put( "T", new Long( (long)1E12 ) );
+ UNIT2SIZE.put( "P", new Long( (long)1E15 ) );
+ UNIT2SIZE.put( "Ki", new Long( 1L << 10 ) );
+ UNIT2SIZE.put( "Mi", new Long( 1L << 20 ) );
+ UNIT2SIZE.put( "Gi", new Long( 1L << 30 ) );
+ UNIT2SIZE.put( "Ti", new Long( 1L << 40 ) );
+ UNIT2SIZE.put( "Pi", new Long( 1L << 50 ) );
+ }
+
+ /** Parses a size specified using units (e.g., K, Ki, M, Mi,…).
+ *
+ * <P>The argument must be in the form <var>number</var> [<var>unit</var>] (with
+ * no space inbetween). <var>number</var> is anything accepted by {@link Long#decode(java.lang.String)},
+ * which allows, besides decimal numbers, hexadecimal numbers prefixed by <code>0x</code>, <code>0X</code> or <code>#</code>,
+ * and octal numbers prefixed by <code>0</code>.
+ * <var>unit</var> may be one of K (10<sup>3</sup>), Ki (2<sup>10</sup>), M (10<sup>6</sup>), Mi (2<sup>20</sup>),
+ * G (10<sup>9</sup>), Gi (2<sup>30</sup>), T (10<sup>12</sup>), Ti (2<sup>40</sup>),
+ * P (10<sup>15</sup>), Pi (2<sup>50</sup>). Thus, for instance, <samp>1Ki</samp> is
+ * 1024, whereas <samp>9M</samp> is nine millions and <code>0x10Pi</code> is 18014398509481984.
+ * Note that in the number part case does not matter, but in the unit part it does.
+ *
+ * @param s a size specified as above.
+ * @return the corresponding unitless size.
+ * @throws ParseException if <code>s</code> is malformed, <var>number</var> is negative or
+ * the resulting size is larger than {@link Long#MAX_VALUE}.
+ */
+
+ public static long parseSize( final CharSequence s ) throws ParseException {
+ final Matcher m = PARSE_SIZE_REGEX.matcher( s );
+ if ( ! m.matches() ) throw new ParseException( "Invalid size specification '" + s + "'." );
+
+ final String unit = m.group( 3 );
+
+ BigInteger unitSize = BigInteger.ONE;
+
+ if ( unit != null ) {
+ Long unitSizeObj = (Long)UNIT2SIZE.get( unit );
+ if ( unitSizeObj == null ) throw new ParseException( "Invalid unit specification '" + unit + "'." );
+ unitSize = new BigInteger( unitSizeObj.toString() );
+ }
+
+ final String number = m.group( 1 );
+ final Long size;
+
+ try {
+ size = Long.decode( number );
+ if ( size.longValue() < 0 ) throw new ParseException( "Sizes cannot be negative." );
+ }
+ catch( NumberFormatException e ) {
+ throw new ParseException( "Invalid number '" + number + "'." );
+ }
+
+ BigInteger result = new BigInteger( size.toString() ).multiply( unitSize );
+
+ if ( result.compareTo( LONG_MAX_VALUE ) > 0 ) throw new ParseException( "Size '" + s + "' is too big." );
+
+ return Long.parseLong( result.toString() );
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/LongStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/LongStringParser.java
new file mode 100644
index 0000000..d2b9b25
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/LongStringParser.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.ParseException;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing Longs. The parse() method delegates the actual
+ * parsing to <code>Long.decode(String)</code>.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.lang.Long
+ */
+public class LongStringParser extends StringParser {
+
+ private static final LongStringParser INSTANCE = new LongStringParser();
+
+ /** Returns a {@link LongStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#LONG_PARSER}.
+ *
+ * @return a {@link LongStringParser}.
+ */
+ public static LongStringParser getParser() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a new LongStringParser.
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#LONG_PARSER}.
+ */
+ public LongStringParser() {
+ super();
+ }
+
+ /**
+ * Parses the specified argument into a Long. This method delegates
+ * the parsing to <code>Long.decode(arg)</code>. If
+ * <code>Long.decode()</code> throws a
+ * NumberFormatException, it is encapsulated into a ParseException and
+ * re-thrown.
+ *
+ * @param arg the argument to parse
+ * @return a Long object with the value contained in the specified argument.
+ * @throws ParseException if <code>Long.decode(arg)</code> throws a
+ * NumberFormatException.
+ * @see java.lang.Long
+ * @see com.martiansoftware.jsap.StringParser#parse(String)
+ */
+ public Object parse(String arg) throws ParseException {
+ Long result = null;
+ try {
+ result = Long.decode(arg);
+ } catch (NumberFormatException e) {
+ throw (
+ new ParseException(
+ "Unable to convert '" + arg + "' to a Long.",
+ e));
+ }
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/PackageStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/PackageStringParser.java
new file mode 100644
index 0000000..233b3c0
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/PackageStringParser.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.ParseException;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing Packages. The parse() method delegates the actual
+ * parsing to <code>Package.getPackage(String)</code>, and returns the resulting
+ * Package object.
+ * If <code>Package.getPackage()</code> returns null, a ParseException is
+ * thrown.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.lang.Package
+ */
+public class PackageStringParser extends StringParser {
+
+ private static final PackageStringParser INSTANCE = new PackageStringParser();
+
+ /** Returns a {@link PackageStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#PACKAGE_PARSER}.
+ *
+ * @return a {@link PackageStringParser}.
+ */
+ public static PackageStringParser getParser() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a new PackageStringParser
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#PACKAGE_PARSER}.
+ */
+ public PackageStringParser() {
+ super();
+ }
+
+ /**
+ * Parses the specified argument into a Package object. This method
+ * delegates the
+ * parsing to <code>Package.getPackage(String)</code>, and returns the
+ * resulting Package object.
+ * If <code>Package.getPackage()</code> returns null, a ParseException is
+ * thrown.
+ *
+ * @param arg the argument to parse
+ * @return a Package object representing the specified package.
+ * @throws ParseException if <code>Package.getPackage(arg)</code> returns
+ * null.
+ * @see java.lang.Package
+ * @see com.martiansoftware.jsap.StringParser#parse(String)
+ */
+ public Object parse(String arg) throws ParseException {
+ Package result = Package.getPackage(arg);
+ if (result == null) {
+ throw (
+ new ParseException("Unable to locate Package '" + arg + "'."));
+ }
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/ShortStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/ShortStringParser.java
new file mode 100644
index 0000000..400fbda
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/ShortStringParser.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.ParseException;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing Shorts. The parse() method delegates the actual
+ * parsing to <code>Short.decode(String)</code>. If <code>Short.decode()</code>
+ * throws a
+ * NumberFormatException, it is encapsulated in a ParseException and re-thrown.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.math.BigDecimal
+ */
+public class ShortStringParser extends StringParser {
+
+ private static final ShortStringParser INSTANCE = new ShortStringParser();
+
+ /** Returns a {@link ShortStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#SHORT_PARSER}.
+ *
+ * @return a {@link ShortStringParser}.
+ */
+
+ public static ShortStringParser getParser() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a new ShortStringParser.
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#SHORT_PARSER}.
+ */
+ public ShortStringParser() {
+ super();
+ }
+
+ /**
+ * Parses the specified argument into a Short. This method delegates the
+ * parsing to <code>Short.decode(String)</code>. If
+ * <code>Short.decode()</code> throws a
+ * NumberFormatException, it is encapsulated in a ParseException and
+ * re-thrown.
+ *
+ * @param arg the argument to parse
+ * @return a Short object with the value contained in the specified
+ * argument.
+ * @throws ParseException if <code>Short.decode(arg)</code> throws a
+ * NumberFormatException.
+ * @see java.lang.Short
+ * @see com.martiansoftware.jsap.StringParser#parse(String)
+ */
+ public Object parse(String arg) throws ParseException {
+ Short result = null;
+ try {
+ result = Short.decode(arg);
+ } catch (NumberFormatException e) {
+ throw (
+ new ParseException(
+ "Unable to convert '" + arg + "' to a Short.",
+ e));
+ }
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/StringStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/StringStringParser.java
new file mode 100644
index 0000000..b9970b2
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/StringStringParser.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.StringParser;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing Strings. This is the simplest possible
+ * StringParser, simply returning
+ * the specified argument in all cases. This class never throws a
+ * ParseException under any circumstances.
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.lang.String
+ */
+public class StringStringParser extends StringParser {
+
+ private static final StringStringParser INSTANCE = new StringStringParser();
+
+ /** Returns a {@link StringStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#STRING_PARSER}.
+ *
+ * @return a {@link StringStringParser}.
+ */
+
+ public static StringStringParser getParser() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a new StringStringParser.
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#STRING_PARSER}.
+ */
+ public StringStringParser() {
+ super();
+ }
+
+ /**
+ * Returns the specified argument as a String.
+ *
+ * @param arg the argument to parse
+ * @return the specified argument as a String.
+ * @see java.lang.String
+ * @see com.martiansoftware.jsap.StringParser#parse(String)
+ */
+ public Object parse(String arg) {
+ return (arg);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/TestAll.java b/src/java/com/martiansoftware/jsap/stringparsers/TestAll.java
new file mode 100644
index 0000000..2ff506c
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/TestAll.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Contains all of the tests in the stringparsers package.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class TestAll {
+
+ /**
+ * Returns a suite of all tests in the stringparsers package.
+ * @return a suite of all tests in the stringparsers package.
+ */
+ public static Test suite() {
+ TestSuite suite =
+ new TestSuite("Test for com.martiansoftware.jsap.stringparsers");
+ suite.addTest(new TestSuite(TestColorStringParser.class));
+ suite.addTest(new TestSuite(TestLongStringParser.class));
+ return suite;
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/TestColorStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/TestColorStringParser.java
new file mode 100644
index 0000000..b0c625a
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/TestColorStringParser.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import junit.framework.TestCase;
+import java.awt.Color;
+import com.martiansoftware.jsap.JSAPException;
+
+/**
+ * A series of tests for the ColorStringParser
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.stringparsers.ColorStringParser
+ */
+public class TestColorStringParser extends TestCase {
+
+ /**
+ * Constructor for TestColorStringParser.
+ * @param arg0 name of this test
+ */
+ public TestColorStringParser(String arg0) {
+ super(arg0);
+ }
+
+ /**
+ * Tests the ability to parse tuples of integers representing RGB values.
+ */
+ public void testIntegerRGB() {
+
+ Color c = new Color(12, 34, 56);
+ ColorStringParser parser = ColorStringParser.getParser();
+
+ Color result = null;
+ try {
+ result = (Color) parser.parse("12,34,56");
+ } catch (JSAPException e) {
+ fail("12,34,56");
+ }
+ assertEquals(c, result);
+
+ try {
+ result = (Color) parser.parse("12,34,56,");
+ fail("12,34,56,");
+ } catch (JSAPException e) {
+ // this is normal behavior
+ }
+
+ try {
+ result = (Color) parser.parse("12,3b,56");
+ fail("12,3b,56");
+ } catch (JSAPException e) {
+ // this is normal behavior
+ }
+
+ }
+
+ /**
+ * Tests the ability to parse tuples of floats representing RGB values.
+ */
+ public void testFloatRGB() {
+ Color c = new Color(0.12f, 0.34f, 0.56f);
+ ColorStringParser parser = ColorStringParser.getParser();
+
+ Color result = null;
+ try {
+ result = (Color) parser.parse("0.12,.34,00.56");
+ } catch (JSAPException e) {
+ fail("0.12,.34,00.56");
+ }
+ assertEquals(c, result);
+
+ try {
+ result = (Color) parser.parse("0.12,.34");
+ fail("0.12,.34");
+ } catch (JSAPException e) {
+ // this is normal behavior
+ }
+ }
+
+ /**
+ * Tests the ability to parse hexadecimal strings as RGB values.
+ */
+ public void testHexRGB() {
+ Color c = new Color(255, 255, 255);
+ ColorStringParser parser = ColorStringParser.getParser();
+
+ Color result = null;
+ try {
+ result = (Color) parser.parse("#fFFfFF");
+ } catch (JSAPException e) {
+ fail("#fFFfFF");
+ }
+ assertEquals(c, result);
+ }
+
+ /**
+ * Tests the ability to parse color names as in java.awt.Color fields.
+ */
+ public void testByName() {
+ Color c = new Color(255, 255, 255);
+ ColorStringParser parser = ColorStringParser.getParser();
+
+ Color result = null;
+ try {
+ result = (Color) parser.parse("white");
+ } catch (JSAPException e) {
+ fail("white");
+ }
+ assertEquals(c, result);
+
+ try {
+ result = (Color) parser.parse("offwhite");
+ fail("offwhite");
+ } catch (JSAPException e) {
+ // this is normal behavior
+ }
+
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/TestLongStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/TestLongStringParser.java
new file mode 100644
index 0000000..e33d1df
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/TestLongStringParser.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.JSAPException;
+
+import junit.framework.TestCase;
+/**
+ * A series of tests for the LongStringParser
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.stringparsers.ColorStringParser
+ */
+public class TestLongStringParser extends TestCase {
+
+ /**
+ * Constructor for TestLongStringParser.
+ * @param arg0 name of this test
+ */
+ public TestLongStringParser(String arg0) {
+ super(arg0);
+ }
+
+ /**
+ * Tests the ability to parse tuples of integers representing RGB values.
+ */
+ public void testBasicParse() {
+
+ LongStringParser lsp = LongStringParser.getParser();
+
+ assertEquals(456, Long.decode("456").longValue());
+ try {
+ Long result = (Long) lsp.parse("123");
+ assertEquals(123, result.longValue());
+ } catch (JSAPException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/stringparsers/URLStringParser.java b/src/java/com/martiansoftware/jsap/stringparsers/URLStringParser.java
new file mode 100644
index 0000000..28f3ce4
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/stringparsers/URLStringParser.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.jsap.stringparsers;
+
+import com.martiansoftware.jsap.StringParser;
+import com.martiansoftware.jsap.ParseException;
+import java.net.URL;
+import java.net.MalformedURLException;
+
+/**
+ * A {@link com.martiansoftware.jsap.StringParser} for parsing java.net.URL objects. The parse() method
+ * delegates the actual
+ * parsing to <code>new URL(String)</code>. If <code>new URL()</code>
+ * throws a MalformedURLException, it is encapsulated in a ParseException and
+ * re-thrown.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @see com.martiansoftware.jsap.StringParser
+ * @see java.net.URL
+ */
+public class URLStringParser extends StringParser {
+
+ private static final URLStringParser INSTANCE = new URLStringParser();
+
+ /** Returns a {@link URLStringParser}.
+ *
+ * <p>Convenient access to the only instance returned by
+ * this method is available through
+ * {@link com.martiansoftware.jsap.JSAP#URL_PARSER}.
+ *
+ * @return a {@link URLStringParser}.
+ */
+
+ public static URLStringParser getParser() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a new URLStringParser.
+ * @deprecated Use {@link #getParser()} or, even better, {@link com.martiansoftware.jsap.JSAP#URL_PARSER}.
+ */
+ public URLStringParser() {
+ super();
+ }
+
+ /**
+ * Parses the specified argument into a URL. This method delegates the
+ * actual
+ * parsing to <code>new URL(arg)</code>. If <code>new URL(arg)</code>
+ * throws a MalformedURLException, it is encapsulated in a ParseException
+ * and re-thrown.
+ *
+ * @param arg the argument to parse
+ * @return a URL as specified by arg.
+ * @throws ParseException if <code>new URL(arg)</code> throws a
+ * MalformedURLException.
+ * @see java.net URL
+ * @see com.martiansoftware.jsap.StringParser#parse(String)
+ */
+ public Object parse(String arg) throws ParseException {
+ URL result = null;
+ try {
+ result = new URL(arg);
+ } catch (MalformedURLException e) {
+ throw (
+ new ParseException(
+ "Unable to convert '" + arg + "' to a URL.",
+ e));
+ }
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/xml/FlaggedConfig.java b/src/java/com/martiansoftware/jsap/xml/FlaggedConfig.java
new file mode 100644
index 0000000..4cccf2b
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/xml/FlaggedConfig.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+package com.martiansoftware.jsap.xml;
+
+import com.martiansoftware.jsap.JSAP;
+
+/**
+ * Provides support for loading JSAP configurations at runtime
+ * via an xml file. You don't need to access this class directly;
+ * instead, use JSAP's constructors that support xml.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+abstract class FlaggedConfig extends ParameterConfig {
+
+ private char shortFlag = JSAP.NO_SHORTFLAG;
+ private String longFlag = JSAP.NO_LONGFLAG;
+
+ public String getLongFlag() {
+ return longFlag;
+ }
+
+ public void setLongFlag(String longFlag) {
+ this.longFlag = longFlag;
+ }
+
+ public char getShortFlag() {
+ return shortFlag;
+ }
+
+ public void setShortFlag(char shortFlag) {
+ this.shortFlag = shortFlag;
+ }
+
+ protected void configure(com.martiansoftware.jsap.FlaggedOption option) {
+ super.configure(option);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/xml/FlaggedOptionConfig.java b/src/java/com/martiansoftware/jsap/xml/FlaggedOptionConfig.java
new file mode 100644
index 0000000..a75f2bd
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/xml/FlaggedOptionConfig.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+package com.martiansoftware.jsap.xml;
+
+import com.martiansoftware.jsap.FlaggedOption;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.Parameter;
+
+/**
+ * Provides support for loading JSAP configurations at runtime
+ * via an xml file. You don't need to access this class directly;
+ * instead, use JSAP's constructors that support xml.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+class FlaggedOptionConfig extends FlaggedConfig {
+
+ private boolean allowMultipleDeclarations = JSAP.NO_MULTIPLEDECLARATIONS;
+ private boolean list = JSAP.NOT_LIST;
+ private char listSeparator = JSAP.DEFAULT_LISTSEPARATOR;
+ private StringParserConfig stringParser = null;
+ private boolean required = JSAP.NOT_REQUIRED;
+ public FlaggedOptionConfig() {
+ super();
+ }
+
+ public boolean allowMultipleDeclarations() {
+ return allowMultipleDeclarations;
+ }
+
+ public void setAllowMultipleDeclarations(boolean allowMultipleDeclarations) {
+ this.allowMultipleDeclarations = allowMultipleDeclarations;
+ }
+
+ public boolean isList() {
+ return list;
+ }
+
+ public void setList(boolean list) {
+ this.list = list;
+ }
+
+ public char getListSeparator() {
+ return listSeparator;
+ }
+
+ public void setListSeparator(char listSeparator) {
+ this.listSeparator = listSeparator;
+ }
+
+ public boolean isRequired() {
+ return required;
+ }
+
+ public void setRequired(boolean required) {
+ this.required = required;
+ }
+
+ public StringParserConfig getStringParser() {
+ return stringParser;
+ }
+
+ public void setStringParser(StringParserConfig stringParser) {
+ this.stringParser = stringParser;
+ }
+
+ protected void configure(FlaggedOption option) {
+ super.configure(option);
+ option.setUsageName(getUsageName());
+
+ option.setShortFlag(getShortFlag());
+ option.setLongFlag(getLongFlag());
+ option.setAllowMultipleDeclarations(allowMultipleDeclarations());
+ option.setListSeparator(getListSeparator());
+ option.setList(isList());
+ option.setRequired(isRequired());
+
+ if (stringParser != null) {
+ option.setStringParser(stringParser.getConfiguredStringParser());
+ }
+ }
+
+ public Parameter getConfiguredParameter() {
+ FlaggedOption result = new FlaggedOption(getId());
+ configure(result);
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/xml/JSAPConfig.java b/src/java/com/martiansoftware/jsap/xml/JSAPConfig.java
new file mode 100644
index 0000000..7222936
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/xml/JSAPConfig.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+package com.martiansoftware.jsap.xml;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Iterator;
+
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.JSAPException;
+
+/**
+ * Provides support for loading JSAP configurations at runtime
+ * via an xml file. You don't need to access this class directly;
+ * instead, use JSAP's constructors that support xml.
+ *
+ * @see com.martiansoftware.jsap.JSAP#JSAP(URL)
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class JSAPConfig {
+
+ private java.util.List parameters = new java.util.ArrayList();
+ private String help = null;
+ private String usage = null;
+
+ /**
+ * Loads a JSAP configuration from the xml at the specified URL, and configures
+ * the specified JSAP object accordingly
+ * @param jsapToConfigure the JSAP to configure
+ * @param jsapXML the configuration
+ * @throws IOException if an I/O error occurs
+ * @throws JSAPException if the configuration is not valid
+ */
+ public static void configure(JSAP jsapToConfigure, URL jsapXML) throws IOException, JSAPException {
+ JSAPXStream jsx = new JSAPXStream();
+ InputStreamReader in = new InputStreamReader(jsapXML.openStream());
+
+ JSAPConfig config = (JSAPConfig) jsx.fromXML(in);
+ in.close();
+
+ for (Iterator i = config.parameters(); i.hasNext();) {
+ ParameterConfig cfg = (ParameterConfig) i.next();
+ jsapToConfigure.registerParameter(cfg.getConfiguredParameter());
+ }
+ jsapToConfigure.setHelp(config.getHelp());
+ jsapToConfigure.setUsage(config.getUsage());
+ }
+
+ public String getHelp() {
+ return help;
+ }
+
+ public void setHelp(String help) {
+ this.help = help;
+ }
+
+ public String getUsage() {
+ return usage;
+ }
+
+ public void setUsage(String usage) {
+ this.usage = usage;
+ }
+
+ public void addParameter(ParameterConfig config) {
+ parameters.add(config);
+ }
+
+ public Iterator parameters() {
+ return (parameters.iterator());
+ }
+
+
+}
diff --git a/src/java/com/martiansoftware/jsap/xml/JSAPXStream.java b/src/java/com/martiansoftware/jsap/xml/JSAPXStream.java
new file mode 100644
index 0000000..5f19a37
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/xml/JSAPXStream.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+package com.martiansoftware.jsap.xml;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+
+/**
+ * Provides support for loading JSAP configurations at runtime
+ * via an xml file. You don't need to access this class directly;
+ * instead, use JSAP's constructors that support xml.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+class JSAPXStream extends XStream {
+
+ public JSAPXStream() {
+ super(new DomDriver());
+ alias("jsap", JSAPConfig.class);
+ alias("flaggedOption", FlaggedOptionConfig.class);
+ alias("unflaggedOption", UnflaggedOptionConfig.class);
+ alias("property", Property.class);
+ alias("qualifiedSwitch", QualifiedSwitchConfig.class);
+ alias("switch", SwitchConfig.class);
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/xml/ParameterConfig.java b/src/java/com/martiansoftware/jsap/xml/ParameterConfig.java
new file mode 100644
index 0000000..4fdfa97
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/xml/ParameterConfig.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+package com.martiansoftware.jsap.xml;
+
+import com.martiansoftware.jsap.Parameter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Provides support for loading JSAP configurations at runtime
+ * via an xml file. You don't need to access this class directly;
+ * instead, use JSAP's constructors that support xml.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+abstract class ParameterConfig {
+
+ private String id = null;
+ private String help = null;
+ private String usageName = null;
+ private java.util.List defaults = null;
+
+ public ParameterConfig() {
+ defaults = new ArrayList();
+ }
+
+ public void addDefault(String defaultValue) {
+ getDefaults().add(defaultValue);
+ }
+
+ public List getDefaults() {
+ if (defaults == null) {
+ defaults = new ArrayList();
+ }
+ return (defaults);
+ }
+
+ public String getHelp() {
+ return help;
+ }
+
+ public void setHelp(String help) {
+ this.help = help;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getUsageName() {
+ return usageName;
+ }
+
+ public void setUsageName(String usageName) {
+ this.usageName = usageName;
+ }
+
+ protected void configure(Parameter param) {
+ param.setHelp(getHelp());
+ for (Iterator i = getDefaults().iterator(); i.hasNext();) {
+ String def = (String) i.next();
+ param.addDefault(def);
+ }
+ }
+ public abstract Parameter getConfiguredParameter();
+}
diff --git a/src/java/com/martiansoftware/jsap/xml/Property.java b/src/java/com/martiansoftware/jsap/xml/Property.java
new file mode 100644
index 0000000..8708b83
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/xml/Property.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+package com.martiansoftware.jsap.xml;
+
+/**
+ * Provides support for loading JSAP configurations at runtime
+ * via an xml file. You don't need to access this class directly;
+ * instead, use JSAP's constructors that support xml.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+class Property {
+
+ private String name = null;
+ private String value = null;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/xml/QualifiedSwitchConfig.java b/src/java/com/martiansoftware/jsap/xml/QualifiedSwitchConfig.java
new file mode 100644
index 0000000..d03daaa
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/xml/QualifiedSwitchConfig.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+package com.martiansoftware.jsap.xml;
+
+import com.martiansoftware.jsap.Parameter;
+import com.martiansoftware.jsap.QualifiedSwitch;
+
+/**
+ * Provides support for loading JSAP configurations at runtime
+ * via an xml file. You don't need to access this class directly;
+ * instead, use JSAP's constructors that support xml.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+class QualifiedSwitchConfig extends FlaggedOptionConfig {
+
+ protected void configure(QualifiedSwitch qs) {
+ super.configure(qs);
+ }
+
+ public Parameter getConfiguredParameter() {
+ QualifiedSwitch result = new QualifiedSwitch(getId());
+ configure(result);
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/xml/StringParserConfig.java b/src/java/com/martiansoftware/jsap/xml/StringParserConfig.java
new file mode 100644
index 0000000..502af0b
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/xml/StringParserConfig.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+package com.martiansoftware.jsap.xml;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.martiansoftware.jsap.PropertyStringParser;
+import com.martiansoftware.jsap.StringParser;
+
+/**
+ * Provides support for loading JSAP configurations at runtime
+ * via an xml file. You don't need to access this class directly;
+ * instead, use JSAP's constructors that support xml.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+class StringParserConfig {
+
+ String classname = null;
+ List properties = null;
+
+ public String getClassname() {
+ return classname;
+ }
+
+ public void setClassname(String classname) {
+ this.classname = classname;
+ }
+
+ public List getProperties() {
+ return properties;
+ }
+
+ public void setProperties(List properties) {
+ this.properties = properties;
+ }
+
+ public StringParser getConfiguredStringParser() {
+ try {
+ StringParser result = null;
+ if (classname.indexOf('.') >= 0) {
+ result = (StringParser) Class.forName(classname).newInstance();
+ } else {
+ result = (StringParser) Class.forName("com.martiansoftware.jsap.stringparsers." + classname).newInstance();
+ }
+ if ((properties != null) && (properties.size() > 0)) {
+ PropertyStringParser p = (PropertyStringParser) result;
+ for (Iterator i = properties.iterator(); i.hasNext(); ) {
+ Property property = (Property) i.next();
+ p.setProperty(property.getName(), property.getValue());
+ }
+ }
+ return (result);
+ } catch (Throwable t) {
+ throw (new RuntimeException("Unable to create StringParser " + classname + ": " + t.getMessage(), t));
+ }
+ }
+
+}
diff --git a/src/java/com/martiansoftware/jsap/xml/SwitchConfig.java b/src/java/com/martiansoftware/jsap/xml/SwitchConfig.java
new file mode 100644
index 0000000..6def319
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/xml/SwitchConfig.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+package com.martiansoftware.jsap.xml;
+
+import com.martiansoftware.jsap.Parameter;
+import com.martiansoftware.jsap.Switch;
+
+/**
+ * Provides support for loading JSAP configurations at runtime
+ * via an xml file. You don't need to access this class directly;
+ * instead, use JSAP's constructors that support xml.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+class SwitchConfig extends FlaggedConfig {
+
+ public Parameter getConfiguredParameter() {
+ Switch result = new Switch(getId());
+ super.configure(result);
+ result.setShortFlag(getShortFlag());
+ result.setLongFlag(getLongFlag());
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/xml/TryDumpXML.java b/src/java/com/martiansoftware/jsap/xml/TryDumpXML.java
new file mode 100644
index 0000000..7bdd9c9
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/xml/TryDumpXML.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+package com.martiansoftware.jsap.xml;
+
+import java.util.ArrayList;
+
+/**
+ * Sends a JSAPConfig to System.out as xml (for test purposes)
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class TryDumpXML {
+
+ public static void main(String[] args) throws Exception {
+ JSAPXStream jsx = new JSAPXStream();
+ JSAPConfig jc = new JSAPConfig();
+
+ FlaggedOptionConfig foc = new FlaggedOptionConfig();
+ foc.setId("flagged");
+ foc.setShortFlag('f');
+ foc.setHelp("This flag does something, but I'm not sure what.");
+ jc.addParameter(foc);
+
+ UnflaggedOptionConfig uoc = new UnflaggedOptionConfig();
+ uoc.setId("unflagged");
+ uoc.setGreedy(true);
+ StringParserConfig spc = new StringParserConfig();
+ spc.setClassname("DateStringParser");
+ ArrayList props = new java.util.ArrayList();
+ Property p = new Property();
+ p.setName("DateFormat");
+ p.setValue("MM/dd/yyyy");
+ props.add(p);
+ p = new Property();
+ p.setName("Another Property");
+ p.setValue("123");
+ props.add(p);
+ spc.setProperties(props);
+ uoc.setStringParser(spc);
+
+ jc.addParameter(uoc);
+ System.out.println(jsx.toXML(jc));
+
+// JSAP jsap = jc.getJSAP();
+// JSAPResult result = jsap.parse("-f abc");
+// System.out.println(result.getString("flagged"));
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/xml/TryLoadXML.java b/src/java/com/martiansoftware/jsap/xml/TryLoadXML.java
new file mode 100644
index 0000000..6f3bd54
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/xml/TryLoadXML.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+package com.martiansoftware.jsap.xml;
+
+import com.martiansoftware.jsap.JSAP;
+
+/**
+ * Loads a silly example JSAP from xml and displays its help message
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public class TryLoadXML {
+
+ public static void main(String[] args) throws Exception {
+ JSAP jsap = new JSAP("com/martiansoftware/jsap/xml/silly-example.xml");
+ System.out.println(jsap.getHelp());
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/xml/UnflaggedOptionConfig.java b/src/java/com/martiansoftware/jsap/xml/UnflaggedOptionConfig.java
new file mode 100644
index 0000000..74ec96e
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/xml/UnflaggedOptionConfig.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+package com.martiansoftware.jsap.xml;
+
+import com.martiansoftware.jsap.Parameter;
+import com.martiansoftware.jsap.UnflaggedOption;
+import com.martiansoftware.jsap.JSAP;
+
+/**
+ * Provides support for loading JSAP configurations at runtime
+ * via an xml file. You don't need to access this class directly;
+ * instead, use JSAP's constructors that support xml.
+ *
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+class UnflaggedOptionConfig extends ParameterConfig {
+
+ private boolean greedy = JSAP.NOT_GREEDY;
+ private boolean list = JSAP.NOT_LIST;
+ private char listSeparator = JSAP.DEFAULT_LISTSEPARATOR;
+ private StringParserConfig stringParser = null;
+ private boolean required = JSAP.NOT_REQUIRED;
+ private String usageName = null;
+
+ public UnflaggedOptionConfig() {
+ super();
+ }
+
+ public boolean isGreedy() {
+ return greedy;
+ }
+
+ public void setGreedy(boolean greedy) {
+ this.greedy = greedy;
+ }
+
+ public boolean isList() {
+ return list;
+ }
+
+ public void setList(boolean list) {
+ this.list = list;
+ }
+
+ public char getListSeparator() {
+ return listSeparator;
+ }
+
+ public void setListSeparator(char listSeparator) {
+ this.listSeparator = listSeparator;
+ }
+
+ public boolean isRequired() {
+ return required;
+ }
+
+ public void setRequired(boolean required) {
+ this.required = required;
+ }
+
+ public StringParserConfig getStringParser() {
+ return stringParser;
+ }
+
+ public void setStringParser(StringParserConfig stringParser) {
+ this.stringParser = stringParser;
+ }
+
+ public String getUsageName() {
+ return usageName;
+ }
+
+ public void setUsageName(String usageName) {
+ this.usageName = usageName;
+ }
+
+ public Parameter getConfiguredParameter() {
+ UnflaggedOption result = new UnflaggedOption(getId());
+ super.configure(result);
+ result.setGreedy(isGreedy());
+ result.setListSeparator(getListSeparator());
+ result.setList(isList());
+ result.setRequired(isRequired());
+ result.setUsageName(getUsageName());
+
+ if (stringParser != null) {
+ result.setStringParser(stringParser.getConfiguredStringParser());
+ }
+
+ return (result);
+ }
+}
diff --git a/src/java/com/martiansoftware/jsap/xml/silly-example.xml b/src/java/com/martiansoftware/jsap/xml/silly-example.xml
new file mode 100644
index 0000000..ca6e60d
--- /dev/null
+++ b/src/java/com/martiansoftware/jsap/xml/silly-example.xml
@@ -0,0 +1,47 @@
+<jsap>
+ <parameters>
+ <flaggedOption>
+ <allowMultipleDeclarations>false</allowMultipleDeclarations>
+ <list>false</list>
+ <listSeparator>:</listSeparator>
+ <required>false</required>
+ <shortFlag>f</shortFlag>
+ <id>flagged</id>
+ <help>This flag does something, but I'm not sure what.</help>
+ <defaults/>
+ </flaggedOption>
+ <switch>
+ <longFlag>exampleSwitch</longFlag>
+ <id>exampleswitch</id>
+ <help>This is just a switch.</help>
+ </switch>
+ <qualifiedSwitch>
+ <shortFlag>q</shortFlag>
+ <id>qualified</id>
+ <help>An example qualified switch</help>
+ <allowMultipleDeclarations>true</allowMultipleDeclarations>
+ </qualifiedSwitch>
+ <unflaggedOption>
+ <help>Greedy unflagged option that uses a DateStringParser.</help>
+ <greedy>true</greedy>
+ <list>false</list>
+ <listSeparator>:</listSeparator>
+ <stringParser>
+ <classname>DateStringParser</classname>
+ <properties>
+ <property>
+ <name>DateFormat</name>
+ <value>MM/dd/yyyy</value>
+ </property>
+ <property>
+ <name>Another Property</name>
+ <value>123</value>
+ </property>
+ </properties>
+ </stringParser>
+ <required>false</required>
+ <id>unflagged</id>
+ <defaults/>
+ </unflaggedOption>
+ </parameters>
+</jsap>
diff --git a/src/java/com/martiansoftware/util/StringUtils.java b/src/java/com/martiansoftware/util/StringUtils.java
new file mode 100644
index 0000000..eff4f74
--- /dev/null
+++ b/src/java/com/martiansoftware/util/StringUtils.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2002-2004, Martian Software, Inc.
+ * This file is made available under the LGPL as described in the accompanying
+ * LICENSE.TXT file.
+ */
+
+package com.martiansoftware.util;
+
+import java.util.List;
+
+/**
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ */
+public final class StringUtils {
+
+ public static String noNull(String s) {
+ return (s == null ? "" : s);
+ }
+
+ public static String padRight(String s, int padCount) {
+ if (padCount < 0) {
+ throw (new IllegalArgumentException("padCount must be >= 0"));
+ }
+ StringBuffer buf = new StringBuffer(noNull(s));
+ for (int i = 0; i < padCount; ++i) {
+ buf.append(' ');
+ }
+ return (buf.toString());
+ }
+
+ public static String padRightToWidth(String s, int desiredWidth) {
+ String result = noNull(s);
+ if (result.length() < desiredWidth) {
+ result = padRight(result, desiredWidth - result.length());
+ }
+ return (result);
+ }
+
+ public static List wrapToList(String s, int width) {
+ List result = new java.util.LinkedList();
+ if ((s != null) && (s.length() > 0)) {
+ StringBuffer buf = new StringBuffer();
+ int lastSpaceBufIndex = -1;
+ for (int i = 0; i < s.length(); ++i) {
+ char c = s.charAt(i);
+ if (c == '\n') {
+ result.add(buf.toString());
+ buf.setLength(0);
+ lastSpaceBufIndex = -1;
+ } else {
+ if (c == ' ') {
+ if (buf.length() >= width - 1) {
+ result.add(buf.toString());
+ buf.setLength(0);
+ lastSpaceBufIndex = -1;
+ }
+ if (buf.length() > 0) {
+ lastSpaceBufIndex = buf.length();
+ buf.append(c);
+ }
+ } else {
+ if (buf.length() >= width) {
+ if (lastSpaceBufIndex != -1) {
+ result.add(buf.substring(0, lastSpaceBufIndex));
+ buf.delete(0, lastSpaceBufIndex + 1);
+ lastSpaceBufIndex = -1;
+ }
+ }
+ buf.append(c);
+ }
+ }
+ }
+ if (buf.length() > 0) {
+ result.add(buf.toString());
+ }
+ }
+ return (result);
+ }
+
+ public static void main(String[] args) {
+ String s =
+ "This is\n a test that I would like to word wrap at 15 characters.";
+
+ System.out.println("123456789012345");
+ List l = wrapToList(s, 15);
+ for (java.util.Iterator i = l.iterator(); i.hasNext();) {
+ String s1 = (String) i.next();
+ System.out.println(s1 + "|");
+ }
+ }
+}
\ No newline at end of file
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jsap.git
More information about the pkg-java-commits
mailing list