You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ds...@apache.org on 2009/08/20 19:03:07 UTC
svn commit: r806255 [1/3] - in /felix/trunk/sigil/common/runtime: ./
src/org/apache/felix/sigil/common/runtime/
src/org/apache/felix/sigil/common/runtime/cli/
src/org/apache/felix/sigil/common/runtime/io/
Author: dsavage
Date: Thu Aug 20 17:03:06 2009
New Revision: 806255
URL: http://svn.apache.org/viewvc?rev=806255&view=rev
Log:
add interalised commons cli classes (to prevent making "real" impls global classes)
remove commons io dependency
various fixes/tweeks to core functionality
Added:
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Runtime.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/AlreadySelectedException.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/BasicParser.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/CommandLine.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/CommandLineParser.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/GnuParser.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/HelpFormatter.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/MissingArgumentException.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/MissingOptionException.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/Option.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/OptionBuilder.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/OptionGroup.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/OptionValidator.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/Options.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/ParseException.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/Parser.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/PatternOptionBuilder.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/PosixParser.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/TypeHandler.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/UnrecognizedOptionException.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/Util.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/overview.html
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/package.html
Modified:
felix/trunk/sigil/common/runtime/sigil.properties
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Client.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Main.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Server.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/io/Action.java
felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/io/UpdateAction.java
Modified: felix/trunk/sigil/common/runtime/sigil.properties
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/common/runtime/sigil.properties?rev=806255&r1=806254&r2=806255&view=diff
==============================================================================
--- felix/trunk/sigil/common/runtime/sigil.properties (original)
+++ felix/trunk/sigil/common/runtime/sigil.properties Thu Aug 20 17:03:06 2009
@@ -5,19 +5,15 @@
org.apache.felix.sigil.common.runtime, \
-contents: \
- org.apache.felix.sigil.common.runtime.*, \
- org.apache.commons.cli.*, \
- org.apache.commons.io.*, \
- org.osgi.framework.launch,\
+ org.apache.felix.sigil.common.runtime.*, \
+ org.osgi.framework.launch, \
-exports: \
org.apache.felix.sigil.common.runtime, \
-imports: \
- org.apache.commons.cli;version=1.2.0;resolve=compile, \
- org.apache.commons.io.input;version=1.4.0;resolve=compile, \
org.osgi.framework;resolve=compile, \
- org.osgi.framework.launch;version=1.0.0;resolve=compile, \
+ org.osgi.framework.launch;resolve=compile;version=1.0.0, \
header;Main-Class: org.apache.felix.sigil.common.runtime.Main
Modified: felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Client.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Client.java?rev=806255&r1=806254&r2=806255&view=diff
==============================================================================
--- felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Client.java (original)
+++ felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Client.java Thu Aug 20 17:03:06 2009
@@ -38,6 +38,9 @@
import org.apache.felix.sigil.common.runtime.io.UpdateAction.Update;
import org.osgi.framework.BundleException;
+import static org.apache.felix.sigil.common.runtime.Runtime.PORT_PROPERTY;
+import static org.apache.felix.sigil.common.runtime.Runtime.ADDRESS_PROPERTY;
+
/**
* @author dave
@@ -45,9 +48,6 @@
*/
public class Client
{
- public static final String PORT_PROPERTY = "port";
- public static final String ADDRESS_PROPERTY = "address";
-
private Socket socket;
private DataInputStream in;
private DataOutputStream out;
@@ -57,33 +57,16 @@
{
}
- public static void main(String[] args) throws IOException, BundleException {
- Client cl = new Client();
- Properties props = new Properties();
- props.put( ADDRESS_PROPERTY, "localhost" );
- props.put( PORT_PROPERTY, "9090" );
- cl.connect( props );
- System.out.println( cl.status() );
- long id = cl.install( "file:/Users/dave/.m2/repository/org/apache/felix/org.apache.felix.log/1.1.0-SNAPSHOT/org.apache.felix.log-1.1.0-SNAPSHOT.jar" );
- System.out.println( cl.status() );
- cl.start( id );
- System.out.println( cl.status() );
-
- id = cl.install( "file:/Users/dave/.m2/repository/org/apache/felix/org.apache.felix.shell/1.3.0-SNAPSHOT/org.apache.felix.shell-1.3.0-SNAPSHOT.jar" );
- cl.start( id );
-
- id = cl.install( "file:/Users/dave/.m2/repository/org/apache/felix/org.apache.felix.shell.tui/1.3.0-SNAPSHOT/org.apache.felix.shell.tui-1.3.0-SNAPSHOT.jar" );
- cl.start( id );
-
- System.out.println( cl.status() );
- }
-
-
public void connect(Properties props) throws IOException
{
String v = props.getProperty( ADDRESS_PROPERTY );
InetAddress address = v == null ? null : InetAddress.getByName( v );
int port = Integer.parseInt( props.getProperty( PORT_PROPERTY, "0" ) );
+
+ if ( port < 1 ) {
+ throw new IOException( "Missing or invalid port" );
+ }
+
InetSocketAddress endpoint = new InetSocketAddress(address, port);
socket = new Socket();
@@ -92,42 +75,53 @@
Main.log( "Connected to " + endpoint );
in = new DataInputStream( socket.getInputStream() );
- out = new DataOutputStream( socket.getOutputStream() );
+ out = new DataOutputStream( socket.getOutputStream() );
}
-
- public void close() throws IOException
+ public boolean isConnected() {
+ return socket != null;
+ }
+
+ public void disconnect() throws IOException
{
socket.close();
+ socket = null;
+ in = null;
+ out = null;
}
public long install( String url ) throws IOException, BundleException
{
+ if ( socket == null ) throw new IllegalStateException( "Not connected" );
return new InstallAction( in, out ).client( url );
}
public void start( long bundle ) throws IOException, BundleException
{
+ if ( socket == null ) throw new IllegalStateException( "Not connected" );
new StartAction( in, out ).client( bundle );
}
public void stop( long bundle ) throws IOException, BundleException
{
+ if ( socket == null ) throw new IllegalStateException( "Not connected" );
new StopAction( in, out ).client( bundle );
}
public void uninstall( long bundle ) throws IOException, BundleException
{
+ if ( socket == null ) throw new IllegalStateException( "Not connected" );
new UninstallAction( in, out ).client( bundle );
}
public void update( long bundle ) throws IOException, BundleException
{
+ if ( socket == null ) throw new IllegalStateException( "Not connected" );
Update update = new UpdateAction.Update(bundle, null);
new UpdateAction( in, out ).client(update);
}
@@ -135,6 +129,7 @@
public void update( long bundle, String url ) throws IOException, BundleException
{
+ if ( socket == null ) throw new IllegalStateException( "Not connected" );
Update update = new UpdateAction.Update(bundle, url);
new UpdateAction( in, out ).client(update);
}
@@ -142,6 +137,7 @@
public Map<Long, String> status() throws IOException, BundleException
{
+ if ( socket == null ) throw new IllegalStateException( "Not connected" );
return new StatusAction( in, out ).client();
}
}
Modified: felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Main.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Main.java?rev=806255&r1=806254&r2=806255&view=diff
==============================================================================
--- felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Main.java (original)
+++ felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Main.java Thu Aug 20 17:03:06 2009
@@ -20,21 +20,24 @@
package org.apache.felix.sigil.common.runtime;
+import static org.apache.felix.sigil.common.runtime.Runtime.ADDRESS_PROPERTY;
+import static org.apache.felix.sigil.common.runtime.Runtime.PORT_PROPERTY;
+
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
-import java.net.InetAddress;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Properties;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.Parser;
-import org.apache.commons.cli.PosixParser;
+import org.apache.felix.sigil.common.runtime.cli.CommandLine;
+import org.apache.felix.sigil.common.runtime.cli.HelpFormatter;
+import org.apache.felix.sigil.common.runtime.cli.Options;
+import org.apache.felix.sigil.common.runtime.cli.ParseException;
+import org.apache.felix.sigil.common.runtime.cli.Parser;
+import org.apache.felix.sigil.common.runtime.cli.PosixParser;
import org.osgi.framework.BundleException;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;
@@ -54,6 +57,7 @@
options.addOption( "p", "port", true, "Port to launch server on (0 implies auto allocate) [default 0]" );
options.addOption( "a", "address", true, "Address to bind server to [default all]" );
options.addOption( "c", "clean", false, "Clean bundle cache directory on init" );
+ options.addOption( "s", "startLevel", true, "Start level for framework" );
}
@@ -76,6 +80,7 @@
framework = factory.newFramework( config );
framework.init();
+ framework.start();
Server server = launch( cl );
@@ -160,7 +165,11 @@
{
HashMap<String, String> config = new HashMap<String, String>();
if ( cl.hasOption( 'c' ))
- config.put( "org.osgi.framework.storage.clean", "onFirstInit" );
+ config.put( "org.osgi.framework.storage.clean", "onFirstInit" );
+
+ if ( cl.hasOption( 's' ) )
+ config.put( "org.osgi.framework.startlevel.beginning", cl.getOptionValue( 's' ) );
+
return config;
}
@@ -168,10 +177,10 @@
private static Server launch( CommandLine line ) throws IOException
{
Server server = new Server( framework );
- String v = line.getOptionValue( 'a' );
- InetAddress addr = v == null ? null : InetAddress.getByName( v );
- int port = Integer.parseInt( line.getOptionValue( 'p', "0" ) );
- server.start( addr, port );
+ Properties props = new Properties();
+ props.put( ADDRESS_PROPERTY, line.getOptionValue( 'a' ) );
+ props.put( PORT_PROPERTY, line.getOptionValue( 'p' ) );
+ server.start( props );
return server;
}
Added: felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Runtime.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Runtime.java?rev=806255&view=auto
==============================================================================
--- felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Runtime.java (added)
+++ felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Runtime.java Thu Aug 20 17:03:06 2009
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.sigil.common.runtime;
+
+public class Runtime
+{
+ public static final String PORT_PROPERTY = "port";
+ public static final String ADDRESS_PROPERTY = "address";
+}
Modified: felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Server.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Server.java?rev=806255&r1=806254&r2=806255&view=diff
==============================================================================
--- felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Server.java (original)
+++ felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Server.java Thu Aug 20 17:03:06 2009
@@ -28,6 +28,7 @@
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
+import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -41,6 +42,8 @@
import org.apache.felix.sigil.common.runtime.io.UpdateAction;
import org.osgi.framework.launch.Framework;
+import static org.apache.felix.sigil.common.runtime.Runtime.ADDRESS_PROPERTY;
+import static org.apache.felix.sigil.common.runtime.Runtime.PORT_PROPERTY;
import static org.apache.felix.sigil.common.runtime.io.Constants.*;
@@ -63,11 +66,15 @@
}
- public void start( InetAddress inetAddress, int port ) throws IOException
+ public void start( Properties props ) throws IOException
{
final ServerSocket socket = new ServerSocket();
- InetSocketAddress socketAddress = new InetSocketAddress(inetAddress, port);
+ String v = props.getProperty( ADDRESS_PROPERTY );
+ InetAddress address = v == null ? null : InetAddress.getByName( v );
+ int port = Integer.parseInt( props.getProperty( PORT_PROPERTY, "0" ) );
+
+ InetSocketAddress socketAddress = new InetSocketAddress(address, port);
socket.bind( socketAddress );
Main.log( "Started server listening on " + socket.getLocalSocketAddress() + ":" + socket.getLocalPort() );
Added: felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/AlreadySelectedException.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/AlreadySelectedException.java?rev=806255&view=auto
==============================================================================
--- felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/AlreadySelectedException.java (added)
+++ felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/AlreadySelectedException.java Thu Aug 20 17:03:06 2009
@@ -0,0 +1,83 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.felix.sigil.common.runtime.cli;
+
+/**
+ * Thrown when more than one option in an option group
+ * has been provided.
+ *
+ * @author John Keyes ( john at integralsource.com )
+ * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ */
+public class AlreadySelectedException extends ParseException
+{
+ /** The option group selected. */
+ private OptionGroup group;
+
+ /** The option that triggered the exception. */
+ private Option option;
+
+ /**
+ * Construct a new <code>AlreadySelectedException</code>
+ * with the specified detail message.
+ *
+ * @param message the detail message
+ */
+ public AlreadySelectedException(String message)
+ {
+ super(message);
+ }
+
+ /**
+ * Construct a new <code>AlreadySelectedException</code>
+ * for the specified option group.
+ *
+ * @param group the option group already selected
+ * @param option the option that triggered the exception
+ * @since 1.2
+ */
+ public AlreadySelectedException(OptionGroup group, Option option)
+ {
+ this("The option '" + option.getKey() + "' was specified but an option from this group "
+ + "has already been selected: '" + group.getSelected() + "'");
+ this.group = group;
+ this.option = option;
+ }
+
+ /**
+ * Returns the option group where another option has been selected.
+ *
+ * @return the related option group
+ * @since 1.2
+ */
+ public OptionGroup getOptionGroup()
+ {
+ return group;
+ }
+
+ /**
+ * Returns the option that was added to the group and triggered the exception.
+ *
+ * @return the related option
+ * @since 1.2
+ */
+ public Option getOption()
+ {
+ return option;
+ }
+}
Added: felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/BasicParser.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/BasicParser.java?rev=806255&view=auto
==============================================================================
--- felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/BasicParser.java (added)
+++ felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/BasicParser.java Thu Aug 20 17:03:06 2009
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.felix.sigil.common.runtime.cli;
+
+/**
+ * The class BasicParser provides a very simple implementation of
+ * the {@link Parser#flatten(Options,String[],boolean) flatten} method.
+ *
+ * @author John Keyes (john at integralsource.com)
+ * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ */
+public class BasicParser extends Parser
+{
+ /**
+ * <p>A simple implementation of {@link Parser}'s abstract
+ * {@link Parser#flatten(Options, String[], boolean) flatten} method.</p>
+ *
+ * <p><b>Note:</b> <code>options</code> and <code>stopAtNonOption</code>
+ * are not used in this <code>flatten</code> method.</p>
+ *
+ * @param options The command line {@link Options}
+ * @param arguments The command line arguments to be parsed
+ * @param stopAtNonOption Specifies whether to stop flattening
+ * when an non option is found.
+ * @return The <code>arguments</code> String array.
+ */
+ protected String[] flatten(Options options, String[] arguments, boolean stopAtNonOption)
+ {
+ // just echo the arguments
+ return arguments;
+ }
+}
Added: felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/CommandLine.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/CommandLine.java?rev=806255&view=auto
==============================================================================
--- felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/CommandLine.java (added)
+++ felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/CommandLine.java Thu Aug 20 17:03:06 2009
@@ -0,0 +1,385 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.felix.sigil.common.runtime.cli;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * Represents list of arguments parsed against a {@link Options} descriptor.
+ *
+ * <p>It allows querying of a boolean {@link #hasOption(String opt)},
+ * in addition to retrieving the {@link #getOptionValue(String opt)}
+ * for options requiring arguments.</p>
+ *
+ * <p>Additionally, any left-over or unrecognized arguments,
+ * are available for further processing.</p>
+ *
+ * @author bob mcwhirter (bob @ werken.com)
+ * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
+ * @author John Keyes (john at integralsource.com)
+ * @version $Revision: 735247 $, $Date: 2009-01-17 00:23:35 -0800 (Sat, 17 Jan 2009) $
+ */
+public class CommandLine implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ /** the unrecognised options/arguments */
+ private List args = new LinkedList();
+
+ /** the processed options */
+ private List options = new ArrayList();
+
+ /**
+ * Creates a command line.
+ */
+ CommandLine()
+ {
+ // nothing to do
+ }
+
+ /**
+ * Query to see if an option has been set.
+ *
+ * @param opt Short name of the option
+ * @return true if set, false if not
+ */
+ public boolean hasOption(String opt)
+ {
+ return options.contains(resolveOption(opt));
+ }
+
+ /**
+ * Query to see if an option has been set.
+ *
+ * @param opt character name of the option
+ * @return true if set, false if not
+ */
+ public boolean hasOption(char opt)
+ {
+ return hasOption(String.valueOf(opt));
+ }
+
+ /**
+ * Return the <code>Object</code> type of this <code>Option</code>.
+ *
+ * @param opt the name of the option
+ * @return the type of this <code>Option</code>
+ * @deprecated due to System.err message. Instead use getParsedOptionValue(String)
+ */
+ public Object getOptionObject(String opt)
+ {
+ try {
+ return getParsedOptionValue(opt);
+ } catch(ParseException pe) {
+ System.err.println("Exception found converting " + opt + " to desired type: " +
+ pe.getMessage() );
+ return null;
+ }
+ }
+
+ /**
+ * Return a version of this <code>Option</code> converted to a particular type.
+ *
+ * @param opt the name of the option
+ * @return the value parsed into a particluar object
+ * @throws ParseException if there are problems turning the option value into the desired type
+ * @see PatternOptionBuilder
+ */
+ public Object getParsedOptionValue(String opt)
+ throws ParseException
+ {
+ String res = getOptionValue(opt);
+
+ Option option = resolveOption(opt);
+ if (option == null)
+ {
+ return null;
+ }
+
+ Object type = option.getType();
+
+ return (res == null) ? null : TypeHandler.createValue(res, type);
+ }
+
+ /**
+ * Return the <code>Object</code> type of this <code>Option</code>.
+ *
+ * @param opt the name of the option
+ * @return the type of opt
+ */
+ public Object getOptionObject(char opt)
+ {
+ return getOptionObject(String.valueOf(opt));
+ }
+
+ /**
+ * Retrieve the argument, if any, of this option.
+ *
+ * @param opt the name of the option
+ * @return Value of the argument if option is set, and has an argument,
+ * otherwise null.
+ */
+ public String getOptionValue(String opt)
+ {
+ String[] values = getOptionValues(opt);
+
+ return (values == null) ? null : values[0];
+ }
+
+ /**
+ * Retrieve the argument, if any, of this option.
+ *
+ * @param opt the character name of the option
+ * @return Value of the argument if option is set, and has an argument,
+ * otherwise null.
+ */
+ public String getOptionValue(char opt)
+ {
+ return getOptionValue(String.valueOf(opt));
+ }
+
+ /**
+ * Retrieves the array of values, if any, of an option.
+ *
+ * @param opt string name of the option
+ * @return Values of the argument if option is set, and has an argument,
+ * otherwise null.
+ */
+ public String[] getOptionValues(String opt)
+ {
+ List values = new ArrayList();
+
+ for (Iterator it = options.iterator(); it.hasNext();)
+ {
+ Option option = (Option) it.next();
+ if (opt.equals(option.getOpt()) || opt.equals(option.getLongOpt()))
+ {
+ values.addAll(option.getValuesList());
+ }
+ }
+
+ return values.isEmpty() ? null : (String[]) values.toArray(new String[values.size()]);
+ }
+
+ /**
+ * Retrieves the option object given the long or short option as a String
+ *
+ * @param opt short or long name of the option
+ * @return Canonicalized option
+ */
+ private Option resolveOption(String opt)
+ {
+ opt = Util.stripLeadingHyphens(opt);
+ for (Iterator it = options.iterator(); it.hasNext();)
+ {
+ Option option = (Option) it.next();
+ if (opt.equals(option.getOpt()))
+ {
+ return option;
+ }
+
+ if (opt.equals(option.getLongOpt()))
+ {
+ return option;
+ }
+
+ }
+ return null;
+ }
+
+ /**
+ * Retrieves the array of values, if any, of an option.
+ *
+ * @param opt character name of the option
+ * @return Values of the argument if option is set, and has an argument,
+ * otherwise null.
+ */
+ public String[] getOptionValues(char opt)
+ {
+ return getOptionValues(String.valueOf(opt));
+ }
+
+ /**
+ * Retrieve the argument, if any, of an option.
+ *
+ * @param opt name of the option
+ * @param defaultValue is the default value to be returned if the option
+ * is not specified
+ * @return Value of the argument if option is set, and has an argument,
+ * otherwise <code>defaultValue</code>.
+ */
+ public String getOptionValue(String opt, String defaultValue)
+ {
+ String answer = getOptionValue(opt);
+
+ return (answer != null) ? answer : defaultValue;
+ }
+
+ /**
+ * Retrieve the argument, if any, of an option.
+ *
+ * @param opt character name of the option
+ * @param defaultValue is the default value to be returned if the option
+ * is not specified
+ * @return Value of the argument if option is set, and has an argument,
+ * otherwise <code>defaultValue</code>.
+ */
+ public String getOptionValue(char opt, String defaultValue)
+ {
+ return getOptionValue(String.valueOf(opt), defaultValue);
+ }
+
+ /**
+ * Retrieve the map of values associated to the option. This is convenient
+ * for options specifying Java properties like <tt>-Dparam1=value1
+ * -Dparam2=value2</tt>. The first argument of the option is the key, and
+ * the 2nd argument is the value. If the option has only one argument
+ * (<tt>-Dfoo</tt>) it is considered as a boolean flag and the value is
+ * <tt>"true"</tt>.
+ *
+ * @param opt name of the option
+ * @return The Properties mapped by the option, never <tt>null</tt>
+ * even if the option doesn't exists
+ * @since 1.2
+ */
+ public Properties getOptionProperties(String opt)
+ {
+ Properties props = new Properties();
+
+ for (Iterator it = options.iterator(); it.hasNext();)
+ {
+ Option option = (Option) it.next();
+
+ if (opt.equals(option.getOpt()) || opt.equals(option.getLongOpt()))
+ {
+ List values = option.getValuesList();
+ if (values.size() >= 2)
+ {
+ // use the first 2 arguments as the key/value pair
+ props.put(values.get(0), values.get(1));
+ }
+ else if (values.size() == 1)
+ {
+ // no explicit value, handle it as a boolean
+ props.put(values.get(0), "true");
+ }
+ }
+ }
+
+ return props;
+ }
+
+ /**
+ * Retrieve any left-over non-recognized options and arguments
+ *
+ * @return remaining items passed in but not parsed as an array
+ */
+ public String[] getArgs()
+ {
+ String[] answer = new String[args.size()];
+
+ args.toArray(answer);
+
+ return answer;
+ }
+
+ /**
+ * Retrieve any left-over non-recognized options and arguments
+ *
+ * @return remaining items passed in but not parsed as a <code>List</code>.
+ */
+ public List getArgList()
+ {
+ return args;
+ }
+
+ /**
+ * jkeyes
+ * - commented out until it is implemented properly
+ * <p>Dump state, suitable for debugging.</p>
+ *
+ * @return Stringified form of this object
+ */
+
+ /*
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ buf.append("[ CommandLine: [ options: ");
+ buf.append(options.toString());
+ buf.append(" ] [ args: ");
+ buf.append(args.toString());
+ buf.append(" ] ]");
+
+ return buf.toString();
+ }
+ */
+
+ /**
+ * Add left-over unrecognized option/argument.
+ *
+ * @param arg the unrecognised option/argument.
+ */
+ void addArg(String arg)
+ {
+ args.add(arg);
+ }
+
+ /**
+ * Add an option to the command line. The values of the option are stored.
+ *
+ * @param opt the processed option
+ */
+ void addOption(Option opt)
+ {
+ options.add(opt);
+ }
+
+ /**
+ * Returns an iterator over the Option members of CommandLine.
+ *
+ * @return an <code>Iterator</code> over the processed {@link Option}
+ * members of this {@link CommandLine}
+ */
+ public Iterator iterator()
+ {
+ return options.iterator();
+ }
+
+ /**
+ * Returns an array of the processed {@link Option}s.
+ *
+ * @return an array of the processed {@link Option}s.
+ */
+ public Option[] getOptions()
+ {
+ Collection processed = options;
+
+ // reinitialise array
+ Option[] optionsArray = new Option[processed.size()];
+
+ // return the array
+ return (Option[]) processed.toArray(optionsArray);
+ }
+}
Added: felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/CommandLineParser.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/CommandLineParser.java?rev=806255&view=auto
==============================================================================
--- felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/CommandLineParser.java (added)
+++ felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/CommandLineParser.java Thu Aug 20 17:03:06 2009
@@ -0,0 +1,94 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.felix.sigil.common.runtime.cli;
+
+/**
+ * A class that implements the <code>CommandLineParser</code> interface
+ * can parse a String array according to the {@link Options} specified
+ * and return a {@link CommandLine}.
+ *
+ * @author John Keyes (john at integralsource.com)
+ * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ */
+public interface CommandLineParser
+{
+ /**
+ * Parse the arguments according to the specified options.
+ *
+ * @param options the specified Options
+ * @param arguments the command line arguments
+ * @return the list of atomic option and value tokens
+ *
+ * @throws ParseException if there are any problems encountered
+ * while parsing the command line tokens.
+ */
+ CommandLine parse(Options options, String[] arguments) throws ParseException;
+
+ /**
+ * Parse the arguments according to the specified options and
+ * properties.
+ *
+ * @param options the specified Options
+ * @param arguments the command line arguments
+ * @param properties command line option name-value pairs
+ * @return the list of atomic option and value tokens
+ *
+ * @throws ParseException if there are any problems encountered
+ * while parsing the command line tokens.
+ */
+ /* To maintain binary compatibility, this is commented out.
+ It is still in the abstract Parser class, so most users will
+ still reap the benefit.
+ CommandLine parse(Options options, String[] arguments, Properties properties)
+ throws ParseException;
+ */
+
+ /**
+ * Parse the arguments according to the specified options.
+ *
+ * @param options the specified Options
+ * @param arguments the command line arguments
+ * @param stopAtNonOption specifies whether to continue parsing the
+ * arguments if a non option is encountered.
+ *
+ * @return the list of atomic option and value tokens
+ * @throws ParseException if there are any problems encountered
+ * while parsing the command line tokens.
+ */
+ CommandLine parse(Options options, String[] arguments, boolean stopAtNonOption) throws ParseException;
+
+ /**
+ * Parse the arguments according to the specified options and
+ * properties.
+ *
+ * @param options the specified Options
+ * @param arguments the command line arguments
+ * @param properties command line option name-value pairs
+ * @param stopAtNonOption specifies whether to continue parsing the
+ *
+ * @return the list of atomic option and value tokens
+ * @throws ParseException if there are any problems encountered
+ * while parsing the command line tokens.
+ */
+ /* To maintain binary compatibility, this is commented out.
+ It is still in the abstract Parser class, so most users will
+ still reap the benefit.
+ CommandLine parse(Options options, String[] arguments, Properties properties, boolean stopAtNonOption)
+ throws ParseException;
+ */
+}
Added: felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/GnuParser.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/GnuParser.java?rev=806255&view=auto
==============================================================================
--- felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/GnuParser.java (added)
+++ felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/GnuParser.java Thu Aug 20 17:03:06 2009
@@ -0,0 +1,113 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.felix.sigil.common.runtime.cli;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class GnuParser provides an implementation of the
+ * {@link Parser#flatten(Options, String[], boolean) flatten} method.
+ *
+ * @author John Keyes (john at integralsource.com)
+ * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ */
+public class GnuParser extends Parser
+{
+ /**
+ * This flatten method does so using the following rules:
+ * <ol>
+ * <li>If an {@link Option} exists for the first character of
+ * the <code>arguments</code> entry <b>AND</b> an {@link Option}
+ * does not exist for the whole <code>argument</code> then
+ * add the first character as an option to the processed tokens
+ * list e.g. "-D" and add the rest of the entry to the also.</li>
+ * <li>Otherwise just add the token to the processed tokens list.</li>
+ * </ol>
+ *
+ * @param options The Options to parse the arguments by.
+ * @param arguments The arguments that have to be flattened.
+ * @param stopAtNonOption specifies whether to stop flattening when
+ * a non option has been encountered
+ * @return a String array of the flattened arguments
+ */
+ protected String[] flatten(Options options, String[] arguments, boolean stopAtNonOption)
+ {
+ List tokens = new ArrayList();
+
+ boolean eatTheRest = false;
+
+ for (int i = 0; i < arguments.length; i++)
+ {
+ String arg = arguments[i];
+
+ if ("--".equals(arg))
+ {
+ eatTheRest = true;
+ tokens.add("--");
+ }
+ else if ("-".equals(arg))
+ {
+ tokens.add("-");
+ }
+ else if (arg.startsWith("-"))
+ {
+ String opt = Util.stripLeadingHyphens(arg);
+
+ if (options.hasOption(opt))
+ {
+ tokens.add(arg);
+ }
+ else
+ {
+ if (opt.indexOf('=') != -1 && options.hasOption(opt.substring(0, opt.indexOf('='))))
+ {
+ // the format is --foo=value or -foo=value
+ tokens.add(arg.substring(0, arg.indexOf('='))); // --foo
+ tokens.add(arg.substring(arg.indexOf('=') + 1)); // value
+ }
+ else if (options.hasOption(arg.substring(0, 2)))
+ {
+ // the format is a special properties option (-Dproperty=value)
+ tokens.add(arg.substring(0, 2)); // -D
+ tokens.add(arg.substring(2)); // property=value
+ }
+ else
+ {
+ eatTheRest = stopAtNonOption;
+ tokens.add(arg);
+ }
+ }
+ }
+ else
+ {
+ tokens.add(arg);
+ }
+
+ if (eatTheRest)
+ {
+ for (i++; i < arguments.length; i++)
+ {
+ tokens.add(arguments[i]);
+ }
+ }
+ }
+
+ return (String[]) tokens.toArray(new String[tokens.size()]);
+ }
+}
Added: felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/HelpFormatter.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/HelpFormatter.java?rev=806255&view=auto
==============================================================================
--- felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/HelpFormatter.java (added)
+++ felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/HelpFormatter.java Thu Aug 20 17:03:06 2009
@@ -0,0 +1,984 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.felix.sigil.common.runtime.cli;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A formatter of help messages for the current command line options
+ *
+ * @author Slawek Zachcial
+ * @author John Keyes (john at integralsource.com)
+ * @version $Revision: 751120 $, $Date: 2009-03-06 14:45:57 -0800 (Fri, 06 Mar 2009) $
+ */
+public class HelpFormatter
+{
+ // --------------------------------------------------------------- Constants
+
+ /** default number of characters per line */
+ public static final int DEFAULT_WIDTH = 74;
+
+ /** default padding to the left of each line */
+ public static final int DEFAULT_LEFT_PAD = 1;
+
+ /**
+ * the number of characters of padding to be prefixed
+ * to each description line
+ */
+ public static final int DEFAULT_DESC_PAD = 3;
+
+ /** the string to display at the beginning of the usage statement */
+ public static final String DEFAULT_SYNTAX_PREFIX = "usage: ";
+
+ /** default prefix for shortOpts */
+ public static final String DEFAULT_OPT_PREFIX = "-";
+
+ /** default prefix for long Option */
+ public static final String DEFAULT_LONG_OPT_PREFIX = "--";
+
+ /** default name for an argument */
+ public static final String DEFAULT_ARG_NAME = "arg";
+
+ // -------------------------------------------------------------- Attributes
+
+ /**
+ * number of characters per line
+ *
+ * @deprecated Scope will be made private for next major version
+ * - use get/setWidth methods instead.
+ */
+ public int defaultWidth = DEFAULT_WIDTH;
+
+ /**
+ * amount of padding to the left of each line
+ *
+ * @deprecated Scope will be made private for next major version
+ * - use get/setLeftPadding methods instead.
+ */
+ public int defaultLeftPad = DEFAULT_LEFT_PAD;
+
+ /**
+ * the number of characters of padding to be prefixed
+ * to each description line
+ *
+ * @deprecated Scope will be made private for next major version
+ * - use get/setDescPadding methods instead.
+ */
+ public int defaultDescPad = DEFAULT_DESC_PAD;
+
+ /**
+ * the string to display at the begining of the usage statement
+ *
+ * @deprecated Scope will be made private for next major version
+ * - use get/setSyntaxPrefix methods instead.
+ */
+ public String defaultSyntaxPrefix = DEFAULT_SYNTAX_PREFIX;
+
+ /**
+ * the new line string
+ *
+ * @deprecated Scope will be made private for next major version
+ * - use get/setNewLine methods instead.
+ */
+ public String defaultNewLine = System.getProperty("line.separator");
+
+ /**
+ * the shortOpt prefix
+ *
+ * @deprecated Scope will be made private for next major version
+ * - use get/setOptPrefix methods instead.
+ */
+ public String defaultOptPrefix = DEFAULT_OPT_PREFIX;
+
+ /**
+ * the long Opt prefix
+ *
+ * @deprecated Scope will be made private for next major version
+ * - use get/setLongOptPrefix methods instead.
+ */
+ public String defaultLongOptPrefix = DEFAULT_LONG_OPT_PREFIX;
+
+ /**
+ * the name of the argument
+ *
+ * @deprecated Scope will be made private for next major version
+ * - use get/setArgName methods instead.
+ */
+ public String defaultArgName = DEFAULT_ARG_NAME;
+
+ /**
+ * Comparator used to sort the options when they output in help text
+ *
+ * Defaults to case-insensitive alphabetical sorting by option key
+ */
+ protected Comparator optionComparator = new OptionComparator();
+
+ /**
+ * Sets the 'width'.
+ *
+ * @param width the new value of 'width'
+ */
+ public void setWidth(int width)
+ {
+ this.defaultWidth = width;
+ }
+
+ /**
+ * Returns the 'width'.
+ *
+ * @return the 'width'
+ */
+ public int getWidth()
+ {
+ return defaultWidth;
+ }
+
+ /**
+ * Sets the 'leftPadding'.
+ *
+ * @param padding the new value of 'leftPadding'
+ */
+ public void setLeftPadding(int padding)
+ {
+ this.defaultLeftPad = padding;
+ }
+
+ /**
+ * Returns the 'leftPadding'.
+ *
+ * @return the 'leftPadding'
+ */
+ public int getLeftPadding()
+ {
+ return defaultLeftPad;
+ }
+
+ /**
+ * Sets the 'descPadding'.
+ *
+ * @param padding the new value of 'descPadding'
+ */
+ public void setDescPadding(int padding)
+ {
+ this.defaultDescPad = padding;
+ }
+
+ /**
+ * Returns the 'descPadding'.
+ *
+ * @return the 'descPadding'
+ */
+ public int getDescPadding()
+ {
+ return defaultDescPad;
+ }
+
+ /**
+ * Sets the 'syntaxPrefix'.
+ *
+ * @param prefix the new value of 'syntaxPrefix'
+ */
+ public void setSyntaxPrefix(String prefix)
+ {
+ this.defaultSyntaxPrefix = prefix;
+ }
+
+ /**
+ * Returns the 'syntaxPrefix'.
+ *
+ * @return the 'syntaxPrefix'
+ */
+ public String getSyntaxPrefix()
+ {
+ return defaultSyntaxPrefix;
+ }
+
+ /**
+ * Sets the 'newLine'.
+ *
+ * @param newline the new value of 'newLine'
+ */
+ public void setNewLine(String newline)
+ {
+ this.defaultNewLine = newline;
+ }
+
+ /**
+ * Returns the 'newLine'.
+ *
+ * @return the 'newLine'
+ */
+ public String getNewLine()
+ {
+ return defaultNewLine;
+ }
+
+ /**
+ * Sets the 'optPrefix'.
+ *
+ * @param prefix the new value of 'optPrefix'
+ */
+ public void setOptPrefix(String prefix)
+ {
+ this.defaultOptPrefix = prefix;
+ }
+
+ /**
+ * Returns the 'optPrefix'.
+ *
+ * @return the 'optPrefix'
+ */
+ public String getOptPrefix()
+ {
+ return defaultOptPrefix;
+ }
+
+ /**
+ * Sets the 'longOptPrefix'.
+ *
+ * @param prefix the new value of 'longOptPrefix'
+ */
+ public void setLongOptPrefix(String prefix)
+ {
+ this.defaultLongOptPrefix = prefix;
+ }
+
+ /**
+ * Returns the 'longOptPrefix'.
+ *
+ * @return the 'longOptPrefix'
+ */
+ public String getLongOptPrefix()
+ {
+ return defaultLongOptPrefix;
+ }
+
+ /**
+ * Sets the 'argName'.
+ *
+ * @param name the new value of 'argName'
+ */
+ public void setArgName(String name)
+ {
+ this.defaultArgName = name;
+ }
+
+ /**
+ * Returns the 'argName'.
+ *
+ * @return the 'argName'
+ */
+ public String getArgName()
+ {
+ return defaultArgName;
+ }
+
+ /**
+ * Comparator used to sort the options when they output in help text
+ *
+ * Defaults to case-insensitive alphabetical sorting by option key
+ */
+ public Comparator getOptionComparator()
+ {
+ return optionComparator;
+ }
+
+ /**
+ * Set the comparator used to sort the options when they output in help text
+ *
+ * Passing in a null parameter will set the ordering to the default mode
+ */
+ public void setOptionComparator(Comparator comparator)
+ {
+ if (comparator == null)
+ {
+ this.optionComparator = new OptionComparator();
+ }
+ else
+ {
+ this.optionComparator = comparator;
+ }
+ }
+
+ /**
+ * Print the help for <code>options</code> with the specified
+ * command line syntax. This method prints help information to
+ * System.out.
+ *
+ * @param cmdLineSyntax the syntax for this application
+ * @param options the Options instance
+ */
+ public void printHelp(String cmdLineSyntax, Options options)
+ {
+ printHelp(defaultWidth, cmdLineSyntax, null, options, null, false);
+ }
+
+ /**
+ * Print the help for <code>options</code> with the specified
+ * command line syntax. This method prints help information to
+ * System.out.
+ *
+ * @param cmdLineSyntax the syntax for this application
+ * @param options the Options instance
+ * @param autoUsage whether to print an automatically generated
+ * usage statement
+ */
+ public void printHelp(String cmdLineSyntax, Options options, boolean autoUsage)
+ {
+ printHelp(defaultWidth, cmdLineSyntax, null, options, null, autoUsage);
+ }
+
+ /**
+ * Print the help for <code>options</code> with the specified
+ * command line syntax. This method prints help information to
+ * System.out.
+ *
+ * @param cmdLineSyntax the syntax for this application
+ * @param header the banner to display at the begining of the help
+ * @param options the Options instance
+ * @param footer the banner to display at the end of the help
+ */
+ public void printHelp(String cmdLineSyntax, String header, Options options, String footer)
+ {
+ printHelp(cmdLineSyntax, header, options, footer, false);
+ }
+
+ /**
+ * Print the help for <code>options</code> with the specified
+ * command line syntax. This method prints help information to
+ * System.out.
+ *
+ * @param cmdLineSyntax the syntax for this application
+ * @param header the banner to display at the begining of the help
+ * @param options the Options instance
+ * @param footer the banner to display at the end of the help
+ * @param autoUsage whether to print an automatically generated
+ * usage statement
+ */
+ public void printHelp(String cmdLineSyntax, String header, Options options, String footer, boolean autoUsage)
+ {
+ printHelp(defaultWidth, cmdLineSyntax, header, options, footer, autoUsage);
+ }
+
+ /**
+ * Print the help for <code>options</code> with the specified
+ * command line syntax. This method prints help information to
+ * System.out.
+ *
+ * @param width the number of characters to be displayed on each line
+ * @param cmdLineSyntax the syntax for this application
+ * @param header the banner to display at the beginning of the help
+ * @param options the Options instance
+ * @param footer the banner to display at the end of the help
+ */
+ public void printHelp(int width, String cmdLineSyntax, String header, Options options, String footer)
+ {
+ printHelp(width, cmdLineSyntax, header, options, footer, false);
+ }
+
+ /**
+ * Print the help for <code>options</code> with the specified
+ * command line syntax. This method prints help information to
+ * System.out.
+ *
+ * @param width the number of characters to be displayed on each line
+ * @param cmdLineSyntax the syntax for this application
+ * @param header the banner to display at the begining of the help
+ * @param options the Options instance
+ * @param footer the banner to display at the end of the help
+ * @param autoUsage whether to print an automatically generated
+ * usage statement
+ */
+ public void printHelp(int width, String cmdLineSyntax, String header,
+ Options options, String footer, boolean autoUsage)
+ {
+ PrintWriter pw = new PrintWriter(System.out);
+
+ printHelp(pw, width, cmdLineSyntax, header, options, defaultLeftPad, defaultDescPad, footer, autoUsage);
+ pw.flush();
+ }
+
+ /**
+ * Print the help for <code>options</code> with the specified
+ * command line syntax.
+ *
+ * @param pw the writer to which the help will be written
+ * @param width the number of characters to be displayed on each line
+ * @param cmdLineSyntax the syntax for this application
+ * @param header the banner to display at the begining of the help
+ * @param options the Options instance
+ * @param leftPad the number of characters of padding to be prefixed
+ * to each line
+ * @param descPad the number of characters of padding to be prefixed
+ * to each description line
+ * @param footer the banner to display at the end of the help
+ *
+ * @throws IllegalStateException if there is no room to print a line
+ */
+ public void printHelp(PrintWriter pw, int width, String cmdLineSyntax,
+ String header, Options options, int leftPad,
+ int descPad, String footer)
+ {
+ printHelp(pw, width, cmdLineSyntax, header, options, leftPad, descPad, footer, false);
+ }
+
+
+ /**
+ * Print the help for <code>options</code> with the specified
+ * command line syntax.
+ *
+ * @param pw the writer to which the help will be written
+ * @param width the number of characters to be displayed on each line
+ * @param cmdLineSyntax the syntax for this application
+ * @param header the banner to display at the begining of the help
+ * @param options the Options instance
+ * @param leftPad the number of characters of padding to be prefixed
+ * to each line
+ * @param descPad the number of characters of padding to be prefixed
+ * to each description line
+ * @param footer the banner to display at the end of the help
+ * @param autoUsage whether to print an automatically generated
+ * usage statement
+ *
+ * @throws IllegalStateException if there is no room to print a line
+ */
+ public void printHelp(PrintWriter pw, int width, String cmdLineSyntax,
+ String header, Options options, int leftPad,
+ int descPad, String footer, boolean autoUsage)
+ {
+ if ((cmdLineSyntax == null) || (cmdLineSyntax.length() == 0))
+ {
+ throw new IllegalArgumentException("cmdLineSyntax not provided");
+ }
+
+ if (autoUsage)
+ {
+ printUsage(pw, width, cmdLineSyntax, options);
+ }
+ else
+ {
+ printUsage(pw, width, cmdLineSyntax);
+ }
+
+ if ((header != null) && (header.trim().length() > 0))
+ {
+ printWrapped(pw, width, header);
+ }
+
+ printOptions(pw, width, options, leftPad, descPad);
+
+ if ((footer != null) && (footer.trim().length() > 0))
+ {
+ printWrapped(pw, width, footer);
+ }
+ }
+
+ /**
+ * <p>Prints the usage statement for the specified application.</p>
+ *
+ * @param pw The PrintWriter to print the usage statement
+ * @param width The number of characters to display per line
+ * @param app The application name
+ * @param options The command line Options
+ *
+ */
+ public void printUsage(PrintWriter pw, int width, String app, Options options)
+ {
+ // initialise the string buffer
+ StringBuffer buff = new StringBuffer(defaultSyntaxPrefix).append(app).append(" ");
+
+ // create a list for processed option groups
+ final Collection processedGroups = new ArrayList();
+
+ // temp variable
+ Option option;
+
+ List optList = new ArrayList(options.getOptions());
+ Collections.sort(optList, getOptionComparator());
+ // iterate over the options
+ for (Iterator i = optList.iterator(); i.hasNext();)
+ {
+ // get the next Option
+ option = (Option) i.next();
+
+ // check if the option is part of an OptionGroup
+ OptionGroup group = options.getOptionGroup(option);
+
+ // if the option is part of a group
+ if (group != null)
+ {
+ // and if the group has not already been processed
+ if (!processedGroups.contains(group))
+ {
+ // add the group to the processed list
+ processedGroups.add(group);
+
+
+ // add the usage clause
+ appendOptionGroup(buff, group);
+ }
+
+ // otherwise the option was displayed in the group
+ // previously so ignore it.
+ }
+
+ // if the Option is not part of an OptionGroup
+ else
+ {
+ appendOption(buff, option, option.isRequired());
+ }
+
+ if (i.hasNext())
+ {
+ buff.append(" ");
+ }
+ }
+
+
+ // call printWrapped
+ printWrapped(pw, width, buff.toString().indexOf(' ') + 1, buff.toString());
+ }
+
+ /**
+ * Appends the usage clause for an OptionGroup to a StringBuffer.
+ * The clause is wrapped in square brackets if the group is required.
+ * The display of the options is handled by appendOption
+ * @param buff the StringBuffer to append to
+ * @param group the group to append
+ * @see #appendOption(StringBuffer,Option,boolean)
+ */
+ private void appendOptionGroup(final StringBuffer buff, final OptionGroup group)
+ {
+ if (!group.isRequired())
+ {
+ buff.append("[");
+ }
+
+ List optList = new ArrayList(group.getOptions());
+ Collections.sort(optList, getOptionComparator());
+ // for each option in the OptionGroup
+ for (Iterator i = optList.iterator(); i.hasNext();)
+ {
+ // whether the option is required or not is handled at group level
+ appendOption(buff, (Option) i.next(), true);
+
+ if (i.hasNext())
+ {
+ buff.append(" | ");
+ }
+ }
+
+ if (!group.isRequired())
+ {
+ buff.append("]");
+ }
+ }
+
+ /**
+ * Appends the usage clause for an Option to a StringBuffer.
+ *
+ * @param buff the StringBuffer to append to
+ * @param option the Option to append
+ * @param required whether the Option is required or not
+ */
+ private static void appendOption(final StringBuffer buff, final Option option, final boolean required)
+ {
+ if (!required)
+ {
+ buff.append("[");
+ }
+
+ if (option.getOpt() != null)
+ {
+ buff.append("-").append(option.getOpt());
+ }
+ else
+ {
+ buff.append("--").append(option.getLongOpt());
+ }
+
+ // if the Option has a value
+ if (option.hasArg() && option.hasArgName())
+ {
+ buff.append(" <").append(option.getArgName()).append(">");
+ }
+
+ // if the Option is not a required option
+ if (!required)
+ {
+ buff.append("]");
+ }
+ }
+
+ /**
+ * Print the cmdLineSyntax to the specified writer, using the
+ * specified width.
+ *
+ * @param pw The printWriter to write the help to
+ * @param width The number of characters per line for the usage statement.
+ * @param cmdLineSyntax The usage statement.
+ */
+ public void printUsage(PrintWriter pw, int width, String cmdLineSyntax)
+ {
+ int argPos = cmdLineSyntax.indexOf(' ') + 1;
+
+ printWrapped(pw, width, defaultSyntaxPrefix.length() + argPos, defaultSyntaxPrefix + cmdLineSyntax);
+ }
+
+ /**
+ * <p>Print the help for the specified Options to the specified writer,
+ * using the specified width, left padding and description padding.</p>
+ *
+ * @param pw The printWriter to write the help to
+ * @param width The number of characters to display per line
+ * @param options The command line Options
+ * @param leftPad the number of characters of padding to be prefixed
+ * to each line
+ * @param descPad the number of characters of padding to be prefixed
+ * to each description line
+ */
+ public void printOptions(PrintWriter pw, int width, Options options,
+ int leftPad, int descPad)
+ {
+ StringBuffer sb = new StringBuffer();
+
+ renderOptions(sb, width, options, leftPad, descPad);
+ pw.println(sb.toString());
+ }
+
+ /**
+ * Print the specified text to the specified PrintWriter.
+ *
+ * @param pw The printWriter to write the help to
+ * @param width The number of characters to display per line
+ * @param text The text to be written to the PrintWriter
+ */
+ public void printWrapped(PrintWriter pw, int width, String text)
+ {
+ printWrapped(pw, width, 0, text);
+ }
+
+ /**
+ * Print the specified text to the specified PrintWriter.
+ *
+ * @param pw The printWriter to write the help to
+ * @param width The number of characters to display per line
+ * @param nextLineTabStop The position on the next line for the first tab.
+ * @param text The text to be written to the PrintWriter
+ */
+ public void printWrapped(PrintWriter pw, int width, int nextLineTabStop, String text)
+ {
+ StringBuffer sb = new StringBuffer(text.length());
+
+ renderWrappedText(sb, width, nextLineTabStop, text);
+ pw.println(sb.toString());
+ }
+
+ // --------------------------------------------------------------- Protected
+
+ /**
+ * Render the specified Options and return the rendered Options
+ * in a StringBuffer.
+ *
+ * @param sb The StringBuffer to place the rendered Options into.
+ * @param width The number of characters to display per line
+ * @param options The command line Options
+ * @param leftPad the number of characters of padding to be prefixed
+ * to each line
+ * @param descPad the number of characters of padding to be prefixed
+ * to each description line
+ *
+ * @return the StringBuffer with the rendered Options contents.
+ */
+ protected StringBuffer renderOptions(StringBuffer sb, int width, Options options, int leftPad, int descPad)
+ {
+ final String lpad = createPadding(leftPad);
+ final String dpad = createPadding(descPad);
+
+ // first create list containing only <lpad>-a,--aaa where
+ // -a is opt and --aaa is long opt; in parallel look for
+ // the longest opt string this list will be then used to
+ // sort options ascending
+ int max = 0;
+ StringBuffer optBuf;
+ List prefixList = new ArrayList();
+
+ List optList = options.helpOptions();
+
+ Collections.sort(optList, getOptionComparator());
+
+ for (Iterator i = optList.iterator(); i.hasNext();)
+ {
+ Option option = (Option) i.next();
+ optBuf = new StringBuffer(8);
+
+ if (option.getOpt() == null)
+ {
+ optBuf.append(lpad).append(" " + defaultLongOptPrefix).append(option.getLongOpt());
+ }
+ else
+ {
+ optBuf.append(lpad).append(defaultOptPrefix).append(option.getOpt());
+
+ if (option.hasLongOpt())
+ {
+ optBuf.append(',').append(defaultLongOptPrefix).append(option.getLongOpt());
+ }
+ }
+
+ if (option.hasArg())
+ {
+ if (option.hasArgName())
+ {
+ optBuf.append(" <").append(option.getArgName()).append(">");
+ }
+ else
+ {
+ optBuf.append(' ');
+ }
+ }
+
+ prefixList.add(optBuf);
+ max = (optBuf.length() > max) ? optBuf.length() : max;
+ }
+
+ int x = 0;
+
+ for (Iterator i = optList.iterator(); i.hasNext();)
+ {
+ Option option = (Option) i.next();
+ optBuf = new StringBuffer(prefixList.get(x++).toString());
+
+ if (optBuf.length() < max)
+ {
+ optBuf.append(createPadding(max - optBuf.length()));
+ }
+
+ optBuf.append(dpad);
+
+ int nextLineTabStop = max + descPad;
+
+ if (option.getDescription() != null)
+ {
+ optBuf.append(option.getDescription());
+ }
+
+ renderWrappedText(sb, width, nextLineTabStop, optBuf.toString());
+
+ if (i.hasNext())
+ {
+ sb.append(defaultNewLine);
+ }
+ }
+
+ return sb;
+ }
+
+ /**
+ * Render the specified text and return the rendered Options
+ * in a StringBuffer.
+ *
+ * @param sb The StringBuffer to place the rendered text into.
+ * @param width The number of characters to display per line
+ * @param nextLineTabStop The position on the next line for the first tab.
+ * @param text The text to be rendered.
+ *
+ * @return the StringBuffer with the rendered Options contents.
+ */
+ protected StringBuffer renderWrappedText(StringBuffer sb, int width,
+ int nextLineTabStop, String text)
+ {
+ int pos = findWrapPos(text, width, 0);
+
+ if (pos == -1)
+ {
+ sb.append(rtrim(text));
+
+ return sb;
+ }
+ sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine);
+
+ if (nextLineTabStop >= width)
+ {
+ // stops infinite loop happening
+ nextLineTabStop = 1;
+ }
+
+ // all following lines must be padded with nextLineTabStop space
+ // characters
+ final String padding = createPadding(nextLineTabStop);
+
+ while (true)
+ {
+ text = padding + text.substring(pos).trim();
+ pos = findWrapPos(text, width, 0);
+
+ if (pos == -1)
+ {
+ sb.append(text);
+
+ return sb;
+ }
+
+ if ( (text.length() > width) && (pos == nextLineTabStop - 1) )
+ {
+ pos = width;
+ }
+
+ sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine);
+ }
+ }
+
+ /**
+ * Finds the next text wrap position after <code>startPos</code> for the
+ * text in <code>text</code> with the column width <code>width</code>.
+ * The wrap point is the last postion before startPos+width having a
+ * whitespace character (space, \n, \r).
+ *
+ * @param text The text being searched for the wrap position
+ * @param width width of the wrapped text
+ * @param startPos position from which to start the lookup whitespace
+ * character
+ * @return postion on which the text must be wrapped or -1 if the wrap
+ * position is at the end of the text
+ */
+ protected int findWrapPos(String text, int width, int startPos)
+ {
+ int pos = -1;
+
+ // the line ends before the max wrap pos or a new line char found
+ if (((pos = text.indexOf('\n', startPos)) != -1 && pos <= width)
+ || ((pos = text.indexOf('\t', startPos)) != -1 && pos <= width))
+ {
+ return pos + 1;
+ }
+ else if (startPos + width >= text.length())
+ {
+ return -1;
+ }
+
+
+ // look for the last whitespace character before startPos+width
+ pos = startPos + width;
+
+ char c;
+
+ while ((pos >= startPos) && ((c = text.charAt(pos)) != ' ')
+ && (c != '\n') && (c != '\r'))
+ {
+ --pos;
+ }
+
+ // if we found it - just return
+ if (pos > startPos)
+ {
+ return pos;
+ }
+
+ // must look for the first whitespace chearacter after startPos
+ // + width
+ pos = startPos + width;
+
+ while ((pos <= text.length()) && ((c = text.charAt(pos)) != ' ')
+ && (c != '\n') && (c != '\r'))
+ {
+ ++pos;
+ }
+
+ return (pos == text.length()) ? (-1) : pos;
+ }
+
+ /**
+ * Return a String of padding of length <code>len</code>.
+ *
+ * @param len The length of the String of padding to create.
+ *
+ * @return The String of padding
+ */
+ protected String createPadding(int len)
+ {
+ StringBuffer sb = new StringBuffer(len);
+
+ for (int i = 0; i < len; ++i)
+ {
+ sb.append(' ');
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Remove the trailing whitespace from the specified String.
+ *
+ * @param s The String to remove the trailing padding from.
+ *
+ * @return The String of without the trailing padding
+ */
+ protected String rtrim(String s)
+ {
+ if ((s == null) || (s.length() == 0))
+ {
+ return s;
+ }
+
+ int pos = s.length();
+
+ while ((pos > 0) && Character.isWhitespace(s.charAt(pos - 1)))
+ {
+ --pos;
+ }
+
+ return s.substring(0, pos);
+ }
+
+ // ------------------------------------------------------ Package protected
+ // ---------------------------------------------------------------- Private
+ // ---------------------------------------------------------- Inner classes
+ /**
+ * This class implements the <code>Comparator</code> interface
+ * for comparing Options.
+ */
+ private static class OptionComparator implements Comparator
+ {
+
+ /**
+ * Compares its two arguments for order. Returns a negative
+ * integer, zero, or a positive integer as the first argument
+ * is less than, equal to, or greater than the second.
+ *
+ * @param o1 The first Option to be compared.
+ * @param o2 The second Option to be compared.
+ * @return a negative integer, zero, or a positive integer as
+ * the first argument is less than, equal to, or greater than the
+ * second.
+ */
+ public int compare(Object o1, Object o2)
+ {
+ Option opt1 = (Option) o1;
+ Option opt2 = (Option) o2;
+
+ return opt1.getKey().compareToIgnoreCase(opt2.getKey());
+ }
+ }
+}
Added: felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/MissingArgumentException.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/MissingArgumentException.java?rev=806255&view=auto
==============================================================================
--- felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/MissingArgumentException.java (added)
+++ felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/MissingArgumentException.java Thu Aug 20 17:03:06 2009
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.felix.sigil.common.runtime.cli;
+
+/**
+ * Thrown when an option requiring an argument
+ * is not provided with an argument.
+ *
+ * @author John Keyes (john at integralsource.com)
+ * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ */
+public class MissingArgumentException extends ParseException
+{
+ /** The option requiring additional arguments */
+ private Option option;
+
+ /**
+ * Construct a new <code>MissingArgumentException</code>
+ * with the specified detail message.
+ *
+ * @param message the detail message
+ */
+ public MissingArgumentException(String message)
+ {
+ super(message);
+ }
+
+ /**
+ * Construct a new <code>MissingArgumentException</code>
+ * with the specified detail message.
+ *
+ * @param option the option requiring an argument
+ * @since 1.2
+ */
+ public MissingArgumentException(Option option)
+ {
+ this("Missing argument for option: " + option.getKey());
+ this.option = option;
+ }
+
+ /**
+ * Return the option requiring an argument that wasn't provided
+ * on the command line.
+ *
+ * @return the related option
+ * @since 1.2
+ */
+ public Option getOption()
+ {
+ return option;
+ }
+}
Added: felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/MissingOptionException.java
URL: http://svn.apache.org/viewvc/felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/MissingOptionException.java?rev=806255&view=auto
==============================================================================
--- felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/MissingOptionException.java (added)
+++ felix/trunk/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/cli/MissingOptionException.java Thu Aug 20 17:03:06 2009
@@ -0,0 +1,93 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.felix.sigil.common.runtime.cli;
+
+import java.util.List;
+import java.util.Iterator;
+
+/**
+ * Thrown when a required option has not been provided.
+ *
+ * @author John Keyes ( john at integralsource.com )
+ * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
+ */
+public class MissingOptionException extends ParseException
+{
+ /** The list of missing options */
+ private List missingOptions;
+
+ /**
+ * Construct a new <code>MissingSelectedException</code>
+ * with the specified detail message.
+ *
+ * @param message the detail message
+ */
+ public MissingOptionException(String message)
+ {
+ super(message);
+ }
+
+ /**
+ * Constructs a new <code>MissingSelectedException</code> with the
+ * specified list of missing options.
+ *
+ * @param missingOptions the list of missing options
+ * @since 1.2
+ */
+ public MissingOptionException(List missingOptions)
+ {
+ this(createMessage(missingOptions));
+ this.missingOptions = missingOptions;
+ }
+
+ /**
+ * Return the list of options (as strings) missing in the command line parsed.
+ *
+ * @return the missing options
+ * @since 1.2
+ */
+ public List getMissingOptions()
+ {
+ return missingOptions;
+ }
+
+ /**
+ * Build the exception message from the specified list of options.
+ *
+ * @param missingOptions
+ * @since 1.2
+ */
+ private static String createMessage(List missingOptions)
+ {
+ StringBuffer buff = new StringBuffer("Missing required option");
+ buff.append(missingOptions.size() == 1 ? "" : "s");
+ buff.append(": ");
+
+ Iterator it = missingOptions.iterator();
+ while (it.hasNext())
+ {
+ buff.append(it.next());
+ if (it.hasNext())
+ {
+ buff.append(", ");
+ }
+ }
+
+ return buff.toString();
+ }
+}