As of v2.0 this feature should be considered experimental.
In order to keep your program source free of clutter and to support a large number of possible command line syntaxes, JSAP provides a means to load configurations from XML sources at run time. A new contructor with the signature JSAP(URL xmlJSAPSource) has been introduced to support this. It is now very easy to store a number of JSAP configurations in XML files in the same .jar as your application.
This feature requires the XStream .jar from http://xstream.codehaus.org. XStream is an excellent library that provides a simple means to map objects to/from XML. It is made available under a BSD-style license.
Although a .jar is available with JSAP, XStream is in no way affiliated with Martian Software or the JSAP project. Furthermore, you're virtually guaranteed a more up-to-date version of the .jar if you go straight to their website. As a bonus, codehaus hosts a variety of other great projects worth checking out.
The XML syntax for JSAP configurations is designed to closely mirror the sequence of function calls required to manually instantiate a JSAP.
An Eclipse plug-in for editing JSAP XML files would be very cool. If you're interested in writing one, let me know!
The following example is a reimplementation of the HelloWorld_8 example found earlier in this document.
<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>
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)");
}
} [mlamb@morbo]$ java com.martiansoftware.jsap.examples.Manual_HelloWorld_9 -n 2 --verbose Zoidberg Hello, Zoidberg! Hello, Zoidberg! [mlamb@morbo]$ java com.martiansoftware.jsap.examples.Manual_HelloWorld_9 --verbose:de Farnsworth Guten Tag, Farnsworth! [mlamb@morbo]$ java com.martiansoftware.jsap.examples.Manual_HelloWorld_9 -v:de,en Branigan Guten Tag, Branigan! Hello, Branigan! [mlamb@morbo]$ java com.martiansoftware.jsap.examples.Manual_HelloWorld_9 Horrible_Gelatanous_Blob Hi, Horrible_Gelatanous_Blob!