sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1492284 - in /sis/trunk: ./ application/sis-console/ application/sis-console/src/main/java/org/apache/sis/console/ application/sis-console/src/main/resources/org/apache/sis/console/ application/sis-console/src/test/java/org/apache/sis/cons...
Date Wed, 12 Jun 2013 16:56:59 GMT
Author: desruisseaux
Date: Wed Jun 12 16:56:59 2013
New Revision: 1492284

URL: http://svn.apache.org/r1492284
Log:
Merge from the JDK6 branch.

Added:
    sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java
      - copied unchanged from r1492278, sis/branches/JDK6/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java
    sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/package-info.java
      - copied unchanged from r1492278, sis/branches/JDK6/application/sis-console/src/main/java/org/apache/sis/console/package-info.java
    sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands_fr.properties
      - copied unchanged from r1492278, sis/branches/JDK6/application/sis-console/src/main/resources/org/apache/sis/console/Commands_fr.properties
    sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties
      - copied unchanged from r1492278, sis/branches/JDK6/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties
    sis/trunk/application/sis-console/src/test/java/org/apache/sis/console/AboutSCTest.java
      - copied unchanged from r1492278, sis/branches/JDK6/application/sis-console/src/test/java/org/apache/sis/console/AboutSCTest.java
    sis/trunk/application/sis-console/src/test/java/org/apache/sis/console/HelpSCTest.java
      - copied unchanged from r1492278, sis/branches/JDK6/application/sis-console/src/test/java/org/apache/sis/console/HelpSCTest.java
    sis/trunk/application/sis-console/src/test/java/org/apache/sis/console/MetadataSCTest.java
      - copied, changed from r1492278, sis/branches/JDK6/application/sis-console/src/test/java/org/apache/sis/console/MetadataSCTest.java
    sis/trunk/application/sis-console/src/test/java/org/apache/sis/console/SubCommandTest.java
      - copied unchanged from r1492278, sis/branches/JDK6/application/sis-console/src/test/java/org/apache/sis/console/SubCommandTest.java
    sis/trunk/application/sis-console/src/test/java/org/apache/sis/test/
      - copied from r1492278, sis/branches/JDK6/application/sis-console/src/test/java/org/apache/sis/test/
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/
      - copied from r1492278, sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/system/
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/logging/MonolineFormatter.java
      - copied unchanged from r1492278, sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/logging/MonolineFormatter.java
Modified:
    sis/trunk/   (props changed)
    sis/trunk/application/sis-console/pom.xml
    sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/AboutSC.java
    sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Command.java
    sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/HelpSC.java
    sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Option.java
    sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/SubCommand.java
    sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands.properties
    sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/StandardCharsets.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/setup/About.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
    sis/trunk/pom.xml

Propchange: sis/trunk/
------------------------------------------------------------------------------
  Merged /sis/branches/JDK7:r1491742-1492271
  Merged /sis/branches/JDK6:r1491744-1492278

Modified: sis/trunk/application/sis-console/pom.xml
URL: http://svn.apache.org/viewvc/sis/trunk/application/sis-console/pom.xml?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/application/sis-console/pom.xml (original)
+++ sis/trunk/application/sis-console/pom.xml Wed Jun 12 16:56:59 2013
@@ -89,7 +89,7 @@ Console application.
         <configuration>
           <instructions>
             <Export-Package>
-              org.apache.sis.cli
+              org.apache.sis.console
             </Export-Package>
             <Main-Class>org.apache.sis.console.Command</Main-Class>
           </instructions>
@@ -98,4 +98,17 @@ Console application.
     </plugins>
   </build>
 
+
+  <!-- ===========================================================
+           Dependencies
+       =========================================================== -->
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.sis.storage</groupId>
+      <artifactId>sis-netcdf</artifactId>
+      <version>${project.version}</version>
+      <!-- TODO: use test or runtime scope -->
+    </dependency>
+  </dependencies>
+
 </project>

Modified: sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/AboutSC.java
URL: http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/AboutSC.java?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/AboutSC.java [UTF-8]
(original)
+++ sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/AboutSC.java [UTF-8]
Wed Jun 12 16:56:59 2013
@@ -19,6 +19,7 @@ package org.apache.sis.console;
 import java.util.EnumSet;
 import org.apache.sis.setup.About;
 import org.apache.sis.util.Version;
+import org.apache.sis.util.resources.Vocabulary;
 
 
 /**
@@ -41,25 +42,31 @@ final class AboutSC extends SubCommand {
      * Creates the {@code "about"} sub-command.
      */
     AboutSC(final int commandIndex, final String... args) throws InvalidOptionException {
-        super(commandIndex, args, EnumSet.of(Option.LOCALE, Option.ENCODING, Option.BRIEF,
Option.VERBOSE));
+        super(commandIndex, args, EnumSet.of(Option.LOCALE, Option.TIMEZONE, Option.ENCODING,
+                Option.BRIEF, Option.VERBOSE, Option.HELP));
     }
 
     /**
      * Prints the information to the output stream.
      */
     @Override
-    public void run() {
+    public int run() {
+        if (hasUnexpectedFileCount(0, 0)) {
+            return Command.INVALID_ARGUMENT_EXIT_CODE;
+        }
         final String configuration;
         if (options.containsKey(Option.BRIEF)) {
-            configuration = "Apache SIS version " + Version.SIS;
+            configuration = Vocabulary.getResources(locale).getString(
+                    Vocabulary.Keys.Version_2, "Apache SIS", Version.SIS);
         } else {
             final EnumSet<About> sections = EnumSet.allOf(About.class);
             if (!options.containsKey(Option.VERBOSE)) {
                 sections.remove(About.LIBRARIES);
             }
-            configuration = About.configuration(sections, locale).toString();
+            configuration = About.configuration(sections, locale, timezone).toString();
         }
         out.println(configuration);
         out.flush();
+        return 0;
     }
 }

Modified: sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Command.java
URL: http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Command.java?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Command.java [UTF-8]
(original)
+++ sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Command.java [UTF-8]
Wed Jun 12 16:56:59 2013
@@ -20,42 +20,70 @@ import java.util.Locale;
 import java.io.Console;
 import java.io.PrintStream;
 import java.io.PrintWriter;
+import java.io.IOException;
+import java.sql.SQLException;
+import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.util.Exceptions;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.logging.Logging;
+import org.apache.sis.util.logging.MonolineFormatter;
 
 
 /**
- * Command line interface for Apache SIS.
- * The main method can be invoked from the command-line as below
- * (the filename needs to be completed with the actual version number):
+ * Command line interface for Apache SIS. The {@link #main(String[])} method accepts the
following commands:
  *
- * {@preformat java
- *     java -jar target/binaries/sis-console.jar
- * }
+ * <ul>
+ *   <li>{@code help}     - Show a help overview.</li>
+ *   <li>{@code about}    - Show information about Apache SIS and system configuration.</li>
+ *   <li>{@code metadata} - Show metadata information for the given file.</li>
+ * </ul>
  *
- * "{@code target/binaries}" is the default location where SIS JAR files are grouped together
- * with their dependencies after a Maven build. This directory can be replaced by any path
to
- * a directory providing the required dependencies.
+ * Each command can accepts an arbitrary amount of the following options:
+ *
+ * <ul>
+ *   <li>{@code --locale}   - The locale to use for the command output.</li>
+ *   <li>{@code --timezone} - The timezone for the dates to be formatted.</li>
+ *   <li>{@code --encoding} - The encoding to use for the command output.</li>
+ *   <li>{@code --colors}   - Whether colorized output shall be enabled.</li>
+ *   <li>{@code --brief}    - Whether the output should contains only brief information.</li>
+ *   <li>{@code --verbose}  - Whether the output should contains more detailed information.</li>
+ *   <li>{@code --help}     - Lists the options available for a specific command.</li>
+ * </ul>
+ *
+ * The {@code --locale}, {@code --timezone} and {@code --encoding} options apply to the command
output sent
+ * to the {@linkplain System#out standard output stream}, but usually do not apply to the
error messages sent
+ * to the {@linkplain System#err standard error stream}. The reason is that command output
may be targeted to
+ * a client, while the error messages are usually for the operator.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
  * @version 0.3
  * @module
  */
-public class Command implements Runnable {
+public final class Command {
     /**
      * The code given to {@link System#exit(int)} when the program failed because of a unknown
sub-command.
      */
     public static final int INVALID_COMMAND_EXIT_CODE = 1;
 
     /**
-     * The code given to {@link System#exit(int)} when the program failed because of an illegal
user argument.
+     * The code given to {@link System#exit(int)} when the program failed because of a unknown
option.
+     * The set of valid options depend on the sub-command to execute.
      */
     public static final int INVALID_OPTION_EXIT_CODE = 2;
 
     /**
+     * The code given to {@link System#exit(int)} when the program failed because of an illegal
user argument.
+     * The user arguments are everything which is not a command name or an option. They are
typically file names,
+     * but can occasionally be other types like URL.
+     */
+    public static final int INVALID_ARGUMENT_EXIT_CODE = 3;
+
+    /**
      * The code given to {@link System#exit(int)} when a file given in argument uses an unknown
file format.
      */
-    public static final int UNKNOWN_STORAGE_EXIT_CODE = 10;
+    public static final int UNKNOWN_STORAGE_EXIT_CODE = 4;
 
     /**
      * The code given to {@link System#exit(int)} when the program failed because of an {@link
java.io.IOException}.
@@ -68,6 +96,17 @@ public class Command implements Runnable
     public static final int SQL_EXCEPTION_EXIT_CODE = 101;
 
     /**
+     * The code given to {@link System#exit(int)} when the program failed for a reason
+     * other than the ones enumerated in the above constants.
+     */
+    public static final int OTHER_ERROR_EXIT_CODE = 199;
+
+    /**
+     * The sub-command name.
+     */
+    private final String commandName;
+
+    /**
      * The sub-command to execute.
      */
     private final SubCommand command;
@@ -106,19 +145,58 @@ public class Command implements Runnable
         if (commandName == null) {
             command = new HelpSC(-1, args);
         } else {
-                 if (commandName.equalsIgnoreCase("about")) command = new AboutSC(commandIndex,
args);
-            else if (commandName.equalsIgnoreCase("help"))  command = new HelpSC (commandIndex,
args);
+            commandName = commandName.toLowerCase(Locale.US);
+                 if (commandName.equals("about"))    command = new AboutSC   (commandIndex,
args);
+            else if (commandName.equals("help"))     command = new HelpSC    (commandIndex,
args);
+            else if (commandName.equals("metadata")) command = new MetadataSC(commandIndex,
args);
             else throw new InvalidCommandException(Errors.format(
                         Errors.Keys.UnknownCommand_1, commandName), commandName);
         }
+        this.commandName = commandName;
+    }
+
+    /**
+     * Runs the command. If an exception occurs, then the exception message is sent to the
error output stream
+     * before to be thrown. Callers can map the exception to a {@linkplain System#exit(int)
system exit code}
+     * by the {@link #exitCodeFor(Throwable)} method.
+     *
+     * @return 0 on success, or an exit code if the command failed for a reason other than
a Java exception.
+     * @throws Exception If an error occurred during the command execution. This is typically,
but not limited, to
+     *         {@link IOException}, {@link SQLException}, {@link DataStoreException} or {@link
TransformException}.
+     */
+    public int run() throws Exception {
+        if (command.hasContradictoryOptions(Option.BRIEF, Option.VERBOSE)) {
+            return INVALID_OPTION_EXIT_CODE;
+        }
+        if (command.options.containsKey(Option.HELP)) {
+            command.help(commandName);
+        } else try {
+            return command.run();
+        } catch (Exception e) {
+            command.out.flush();
+            command.err.println(Exceptions.formatChainedMessages(command.locale, null, e));
+            throw e;
+        }
+        return 0;
     }
 
     /**
-     * Runs the command.
+     * Returns the exit code for the given exception, or 0 if unknown. This method iterates
through the
+     * {@linkplain Throwable#getCause() causes} until an exception matching a {@code *_EXIT_CODE}
+     * constant is found.
+     *
+     * @param  cause The exception for which to get the exit code.
+     * @return The exit code as one of the {@code *_EXIT_CODE} constant, or {@link #OTHER_ERROR_EXIT_CODE}
if unknown.
      */
-    @Override
-    public void run() {
-        command.run();
+    public static int exitCodeFor(Throwable cause) {
+        while (cause != null) {
+            if (cause instanceof InvalidCommandException) return INVALID_COMMAND_EXIT_CODE;
+            if (cause instanceof InvalidOptionException)  return INVALID_OPTION_EXIT_CODE;
+            if (cause instanceof IOException)             return IO_EXCEPTION_EXIT_CODE;
+            if (cause instanceof SQLException)            return SQL_EXCEPTION_EXIT_CODE;
+            cause = cause.getCause();
+        }
+        return OTHER_ERROR_EXIT_CODE;
     }
 
     /**
@@ -144,6 +222,7 @@ public class Command implements Runnable
      * @param args Command-line options.
      */
     public static void main(final String[] args) {
+        MonolineFormatter.configureConsoleHandler(Logging.getLogger(""), null);
         final Command c;
         try {
             c = new Command(args);
@@ -156,6 +235,14 @@ public class Command implements Runnable
             System.exit(INVALID_OPTION_EXIT_CODE);
             return;
         }
-        c.run();
+        int status;
+        try {
+            status = c.run();
+        } catch (Exception e) {
+            status = exitCodeFor(e);
+        }
+        if (status != 0) {
+            System.exit(status);
+        }
     }
 }

Modified: sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/HelpSC.java
URL: http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/HelpSC.java?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/HelpSC.java [UTF-8]
(original)
+++ sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/HelpSC.java [UTF-8]
Wed Jun 12 16:56:59 2013
@@ -38,30 +38,66 @@ final class HelpSC extends SubCommand {
      */
     private static final String[] COMMANDS = {
         "help",
-        "about"
+        "about",
+        "metadata"
     };
 
     /**
+     * Copies the configuration of the given sub-command. This constructor is used
+     * for printing help about an other command.
+     */
+    HelpSC(final SubCommand parent) {
+        super(parent);
+    }
+
+    /**
      * Creates the {@code "help"} sub-command.
      */
     HelpSC(final int commandIndex, final String... args) throws InvalidOptionException {
-        super(commandIndex, args, EnumSet.of(Option.LOCALE, Option.ENCODING));
+        super(commandIndex, args, EnumSet.of(Option.LOCALE, Option.ENCODING, Option.HELP));
     }
 
     /**
      * Prints the help instructions.
      */
     @Override
-    public void run() {
+    public int run() {
+        if (hasUnexpectedFileCount(0, 0)) {
+            return Command.INVALID_ARGUMENT_EXIT_CODE;
+        }
+        help(true, COMMANDS, EnumSet.allOf(Option.class));
+        return 0;
+    }
+
+    /**
+     * Implementation of {@link #run()}, also shared by {@link SubCommand#help(String)}.
+     *
+     * @param showHeader   {@code true} for printing the "Apache SIS" header.
+     * @param commandNames The names of the commands to list.
+     * @param validOptions The options to list.
+     */
+    void help(final boolean showHeader, final String[] commandNames, final EnumSet<Option>
validOptions) {
         final ResourceBundle commands = ResourceBundle.getBundle("org.apache.sis.console.Commands",
locale);
-        final ResourceBundle options  = ResourceBundle.getBundle("org.apache.sis.console.Options",
locale);
+        final ResourceBundle options  = ResourceBundle.getBundle("org.apache.sis.console.Options",
 locale);
         final Vocabulary vocabulary = Vocabulary.getResources(locale);
-        out.print(vocabulary.getString(Vocabulary.Keys.Commands));
-        out.println(':');
+        if (showHeader) {
+            out.print("Apache SIS, ");
+            out.println(commands.getString("SIS"));
+            out.println(commands.getString("Usage"));
+            out.println();
+            out.print(vocabulary.getString(Vocabulary.Keys.Commands));
+            out.println(':');
+        }
         try {
             final TableAppender table = new TableAppender(out, "  ");
-            for (final String command : COMMANDS) {
-                table.append(' ').append(command);
+            for (final String command : commandNames) {
+                if (showHeader) {
+                    table.append("  ");
+                }
+                table.append(command);
+                if (!showHeader) {
+                    table.append(':');
+                }
                 table.nextColumn();
                 table.append(commands.getString(command));
                 table.nextLine();
@@ -70,9 +106,9 @@ final class HelpSC extends SubCommand {
             out.println();
             out.print(vocabulary.getString(Vocabulary.Keys.Options));
             out.println(':');
-            for (final Option option : Option.values()) {
+            for (final Option option : validOptions) {
                 final String name = option.name().toLowerCase(Locale.US);
-                table.append(' ').append(Option.PREFIX).append(name);
+                table.append("  ").append(Option.PREFIX).append(name);
                 table.nextColumn();
                 table.append(options.getString(name));
                 table.nextLine();

Modified: sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Option.java
URL: http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Option.java?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Option.java [UTF-8]
(original)
+++ sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/Option.java [UTF-8]
Wed Jun 12 16:56:59 2013
@@ -35,14 +35,14 @@ enum Option {
     LOCALE(true),
 
     /**
-     * The encoding for the output produced by the command.
+     * The timezone for the dates to be formatted.
      */
-    ENCODING(true),
+    TIMEZONE(true),
 
     /**
-     * The timezone for the dates to be formatted.
+     * The encoding for the output produced by the command.
      */
-    TIMEZONE(true),
+    ENCODING(true),
 
     /**
      * Whether colorized output shall be enabled.
@@ -59,7 +59,12 @@ enum Option {
      * Whether the output should contains more detailed information.
      * This option expects no value.
      */
-    VERBOSE(false);
+    VERBOSE(false),
+
+    /**
+     * Lists the options accepted by a command.
+     */
+    HELP(false);
 
     /**
      * The prefix to prepend to option names.

Modified: sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/SubCommand.java
URL: http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/SubCommand.java?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/SubCommand.java
[UTF-8] (original)
+++ sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/SubCommand.java
[UTF-8] Wed Jun 12 16:56:59 2013
@@ -16,9 +16,12 @@
  */
 package org.apache.sis.console;
 
+import java.util.List;
+import java.util.ArrayList;
 import java.util.Locale;
 import java.util.EnumSet;
 import java.util.EnumMap;
+import java.util.TimeZone;
 import java.io.Console;
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -37,7 +40,7 @@ import org.apache.sis.internal.util.X364
  * @version 0.3
  * @module
  */
-abstract class SubCommand implements Runnable {
+abstract class SubCommand {
     /**
      * Special value for {@code arguments[commandIndex]} meaning that this sub-command is
created
      * for JUnit test purpose.
@@ -47,6 +50,13 @@ abstract class SubCommand implements Run
     static final String TEST = "TEST";
 
     /**
+     * The set of legal options for this command.
+     *
+     * @see #help(String)
+     */
+    private final EnumSet<Option> validOptions;
+
+    /**
      * The command-line options allowed by this sub-command, together with their values.
      */
     protected final EnumMap<Option,String> options;
@@ -58,6 +68,12 @@ abstract class SubCommand implements Run
     protected final Locale locale;
 
     /**
+     * The locale specified by the {@code "--timezone"} option. If no such option was provided,
+     * then this field is left to {@code null}.
+     */
+    protected final TimeZone timezone;
+
+    /**
      * The encoding specified by the {@code "--encoding"} option. If no such option was provided,
      * then this field is set to the {@linkplain Charset#defaultCharset() default charset}.
      */
@@ -91,6 +107,29 @@ abstract class SubCommand implements Run
     final StringBuffer outputBuffer;
 
     /**
+     * Any remaining parameters that are not command name or option.
+     * They are typically file names, but can occasionally be other types like URL.
+     */
+    protected final List<String> files;
+
+    /**
+     * Copies the configuration of the given sub-command. This constructor is used
+     * only when a command needs to delegates part of its work to an other command.
+     */
+    SubCommand(final SubCommand parent) {
+        this.validOptions = parent.validOptions;
+        this.options      = parent.options;
+        this.locale       = parent.locale;
+        this.timezone     = parent.timezone;
+        this.encoding     = parent.encoding;
+        this.colors       = parent.colors;
+        this.out          = parent.out;
+        this.err          = parent.err;
+        this.outputBuffer = parent.outputBuffer;
+        this.files        = parent.files;
+    }
+
+    /**
      * Creates a new sub-command with the given command-line arguments.
      * The {@code arguments} array is the same array than the one given to the {@code main(String[])}
method.
      * The argument at index {@code commandIndex} is the name of this command, and will be
ignored except for
@@ -105,7 +144,9 @@ abstract class SubCommand implements Run
             throws InvalidOptionException
     {
         boolean isTest = false;
+        this.validOptions = validOptions;
         options = new EnumMap<Option,String>(Option.class);
+        files = new ArrayList<String>(arguments.length);
         for (int i=0; i<arguments.length; i++) {
             final String arg = arguments[i];
             if (i == commandIndex) {
@@ -134,6 +175,8 @@ abstract class SubCommand implements Run
                     throw new InvalidOptionException(Errors.format(Errors.Keys.DuplicatedOption_1,
name), name);
                 }
                 options.put(option, value);
+            } else {
+                files.add(arg);
             }
         }
         /*
@@ -147,6 +190,9 @@ abstract class SubCommand implements Run
             value = options.get(option = Option.LOCALE);
             locale = (value != null) ? Locales.parse(value) : Locale.getDefault();
 
+            value = options.get(option = Option.TIMEZONE);
+            timezone = (value != null) ? TimeZone.getTimeZone(value) : null;
+
             value = options.get(option = Option.ENCODING);
             explicitEncoding = (value != null);
             encoding = explicitEncoding ? Charset.forName(value) : Charset.defaultCharset();
@@ -184,8 +230,68 @@ abstract class SubCommand implements Run
     }
 
     /**
+     * Checks if the user-provided {@linkplain #options} contains mutually exclusive options.
+     * If an inconsistency is found, then this method prints an error message to {@link #err}
+     * and returns {@code true}.
+     *
+     * <p>An example of a pair of mutually exclusive options is {@code --brief} and
{@code --verbose}.</p>
+     *
+     * @param  exclusive Pairs of mutually exclusive options.
+     * @return {@code true} if two mutually exclusive options exist.
+     */
+    final boolean hasContradictoryOptions(final Option... exclusive) {
+        for (int i=0; i<exclusive.length;) {
+            final Option o1 = exclusive[i++];
+            final Option o2 = exclusive[i++];
+            if (options.containsKey(o1) && options.containsKey(o2)) {
+                err.println(Errors.format(Errors.Keys.MutuallyExclusiveOptions_2,
+                        o1.name().toLowerCase(Locale.US),
+                        o2.name().toLowerCase(Locale.US)));
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks the size of the {@link #files} list. If the list has an unexpected size,
+     * then this method prints an error message to {@link #err} and returns {@code true}.
+     *
+     * @param  min Minimal number of files.
+     * @param  max Maximum number of files.
+     * @return {@code true} if the list size is not in the expected bounds.
+     */
+    final boolean hasUnexpectedFileCount(final int min, final int max) {
+        final int size = files.size();
+        final int expected, key;
+        if (size < min) {
+            expected = min;
+            key = Errors.Keys.TooFewArguments_2;
+        } else if (size > max) {
+            expected = max;
+            key = Errors.Keys.TooManyArguments_2;
+        } else {
+            return false;
+        }
+        err.println(Errors.format(key, expected, size));
+        return true;
+    }
+
+    /**
+     * Shows the help instructions for a specific command. This method is invoked
+     * instead of {@link #run()} if the the user provided the {@code --help} option.
+     *
+     * @param commandName The command name converted to lower cases.
+     */
+    protected void help(final String commandName) {
+        new HelpSC(this).help(false, new String[] {commandName}, validOptions);
+    }
+
+    /**
      * Executes the sub-command.
+     *
+     * @return 0 on success, or an exit code if the command failed for a reason other than
a Java exception.
+     * @throws Exception If an error occurred while executing the sub-command.
      */
-    @Override
-    public abstract void run();
+    public abstract int run() throws Exception;
 }

Modified: sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands.properties
URL: http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands.properties?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands.properties
[ISO-8859-1] (original)
+++ sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Commands.properties
[ISO-8859-1] Wed Jun 12 16:56:59 2013
@@ -1,3 +1,7 @@
 # Licensed to the Apache Software Foundation (ASF) under one or more contributor license
agreements.
-about=Show information about the Apache SIS version and configuration.
+SIS=Spatial Information System
+Usage=Usage: sis <command> [options] [files]
+
 help=Show a help overview.
+about=Show information about Apache SIS and system configuration.
+metadata=Show metadata information for the given file.

Modified: sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties
URL: http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties
[ISO-8859-1] (original)
+++ sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties
[ISO-8859-1] Wed Jun 12 16:56:59 2013
@@ -1,7 +1,8 @@
 # Licensed to the Apache Software Foundation (ASF) under one or more contributor license
agreements.
-locale=The locale for the output produced by the command.
-encoding=The encoding for the output produced by the command.
+locale=The locale to use for the command output.
 timezone=The timezone for the dates to be formatted.
+encoding=The encoding to use for the command output.
 colors=Whether colorized output shall be enabled.
 brief=Whether the output should contains only brief information.
 verbose=Whether the output should contains more detailed information.
+help=Lists the options available for a specific command.

Copied: sis/trunk/application/sis-console/src/test/java/org/apache/sis/console/MetadataSCTest.java
(from r1492278, sis/branches/JDK6/application/sis-console/src/test/java/org/apache/sis/console/MetadataSCTest.java)
URL: http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/test/java/org/apache/sis/console/MetadataSCTest.java?p2=sis/trunk/application/sis-console/src/test/java/org/apache/sis/console/MetadataSCTest.java&p1=sis/branches/JDK6/application/sis-console/src/test/java/org/apache/sis/console/MetadataSCTest.java&r1=1492278&r2=1492284&rev=1492284&view=diff
==============================================================================
--- sis/branches/JDK6/application/sis-console/src/test/java/org/apache/sis/console/MetadataSCTest.java
[UTF-8] (original)
+++ sis/trunk/application/sis-console/src/test/java/org/apache/sis/console/MetadataSCTest.java
[UTF-8] Wed Jun 12 16:56:59 2013
@@ -17,10 +17,10 @@
 package org.apache.sis.console;
 
 import java.net.URL;
-import org.opengis.wrapper.netcdf.IOTestCase;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
+import org.junit.Ignore;
 
 import static org.junit.Assert.*;
 
@@ -41,9 +41,10 @@ public final strictfp class MetadataSCTe
      * @throws Exception Should never happen.
      */
     @Test
+    @Ignore("Requires GeoAPI 3.1")
     public void testNetCDF() throws Exception {
-        final URL url = IOTestCase.class.getResource(IOTestCase.NCEP);
-        assertNotNull(IOTestCase.NCEP, url);
+        final URL url = MetadataSCTest.class.getResource("NCEP-SST.nc");
+        assertNotNull("NCEP-SST.nc", url);
         final MetadataSC test = new MetadataSC(0, SubCommand.TEST, url.toString());
         test.run();
         final String result = test.outputBuffer.toString();

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/StandardCharsets.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/StandardCharsets.java?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/StandardCharsets.java
[UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/StandardCharsets.java
[UTF-8] Wed Jun 12 16:56:59 2013
@@ -39,4 +39,9 @@ public final class StandardCharsets {
      * Eight-bit UCS Transformation Format.
      */
     public static final Charset UTF_8 = Charset.forName("UTF-8");
+
+    /**
+     * Sixteen-bit UCS Transformation Format.
+     */
+    public static final Charset UTF_16 = Charset.forName("UTF-16");
 }

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/setup/About.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/setup/About.java?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/setup/About.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/setup/About.java [UTF-8] Wed Jun
12 16:56:59 2013
@@ -139,17 +139,18 @@ public enum About {
      * @return Configuration information, as a tree for grouping some configuration by sections.
      */
     public static TreeTable configuration(final Locale locale) {
-        return configuration(EnumSet.allOf(About.class), locale);
+        return configuration(EnumSet.allOf(About.class), locale, null);
     }
 
     /**
      * Returns a subset of the information about the current Apache SIS running environment.
      *
      * @param  sections The section for which information are desired.
-     * @param  locale The locale to use for formatting the texts in the tree.
+     * @param  locale   The locale to use for formatting the texts in the tree.
+     * @param  timezone The timezone to use for formatting the dates, or {@code null} for
the default.
      * @return Configuration information, as a tree for grouping some configuration by sections.
      */
-    public static TreeTable configuration(final Set<About> sections, final Locale locale)
{
+    public static TreeTable configuration(final Set<About> sections, final Locale locale,
final TimeZone timezone) {
         ArgumentChecks.ensureNonNull("sections", sections);
         ArgumentChecks.ensureNonNull("locale", locale);
         String userHome = null;
@@ -234,7 +235,11 @@ fill:   for (int i=0; ; i++) {
                 case 5: {
                     if (sections.contains(LOCALIZATION)) {
                         nameKey = Vocabulary.Keys.CurrentDateTime;
-                        value = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG,
locale).format(now);
+                        final DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG,
DateFormat.LONG, locale);
+                        if (timezone != null) {
+                            df.setTimeZone(timezone);
+                        }
+                        value = df.format(now);
                     }
                     break;
                 }

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8]
(original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8]
Wed Jun 12 16:56:59 2013
@@ -321,6 +321,11 @@ public final class Errors extends Indexe
         public static final int MissingValueInColumn_1 = 77;
 
         /**
+         * Options “{0}” and “{1}” are mutually exclusive.
+         */
+        public static final int MutuallyExclusiveOptions_2 = 103;
+
+        /**
          * Argument ‘{0}’ shall not be negative. The given value was {1}.
          */
         public static final int NegativeArgument_2 = 8;
@@ -461,6 +466,16 @@ public final class Errors extends Indexe
         public static final int StreamIsForwardOnly_1 = 95;
 
         /**
+         * Expected at least {0} argument{0,choice,1#|2#s}, but got {1}.
+         */
+        public static final int TooFewArguments_2 = 104;
+
+        /**
+         * Expected at most {0} argument{0,choice,1#|2#s}, but got {1}.
+         */
+        public static final int TooManyArguments_2 = 105;
+
+        /**
          * Ordering between “{0}” and “{1}” elements is undefined.
          */
         public static final int UndefinedOrderingForElements_2 = 70;

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
[ISO-8859-1] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
[ISO-8859-1] Wed Jun 12 16:56:59 2013
@@ -75,6 +75,7 @@ MissingRequiredModule_1         = This o
 MissingValueForOption_1         = Missing value for option \u201c{0}\u201d.
 MissingValueForProperty_1       = Missing value for property \u201c{0}\u201d.
 MissingValueInColumn_1          = Missing value in the \u201c{0}\u201d column.
+MutuallyExclusiveOptions_2      = Options \u201c{0}\u201d and \u201c{1}\u201d are mutually
exclusive.
 NegativeArgument_2              = Argument \u2018{0}\u2019 shall not be negative. The given
value was {1}.
 NegativeArrayLength_1           = Can not create a \u201c{0}\u201d array of negative length.
 NodeChildOfItself_1             = Node \u201c{0}\u201d can not be a child of itself.
@@ -104,6 +105,8 @@ RecursiveCreateCallForKey_1     = Recurs
 RequireDecimalSeparator         = A decimal separator is required.
 StalledThread_1                 = Thread \u201c{0}\u201d seems stalled.
 StreamIsForwardOnly_1           = Can not move backward in the \u201c{0}\u201d stream.
+TooFewArguments_2               = Expected at least {0} argument{0,choice,1#|2#s}, but got
{1}.
+TooManyArguments_2              = Expected at most {0} argument{0,choice,1#|2#s}, but got
{1}.
 UndefinedOrderingForElements_2  = Ordering between \u201c{0}\u201d and \u201c{1}\u201d elements
is undefined.
 UnexpectedChange_1              = Unexpected change in \u2018{0}\u2019.
 UnexpectedEndOfFile_1           = Unexpected end of file while reading \u201c{0}\u201d.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
[ISO-8859-1] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
[ISO-8859-1] Wed Jun 12 16:56:59 2013
@@ -65,6 +65,7 @@ MissingRequiredModule_1         = Cette 
 MissingValueForOption_1         = Aucune valeur n\u2019a \u00e9t\u00e9 d\u00e9finie pour
l\u2019option \u201c{0}\u201d.
 MissingValueForProperty_1       = Aucune valeur n\u2019a \u00e9t\u00e9 d\u00e9finie pour
la propri\u00e9t\u00e9 \u201c{0}\u201d.
 MissingValueInColumn_1          = Il manque une valeur dans la colonne \u201c{0}\u201d.
+MutuallyExclusiveOptions_2      = Les options \u201c{0}\u201d et \u201c{1}\u201d sont mutuellement
exclusives.
 NegativeArgument_2              = L\u2019argument \u2018{0}\u2019 ne doit pas \u00eatre n\u00e9gatif.
La valeur donn\u00e9e \u00e9tait {1}.
 NegativeArrayLength_1           = Ne peut pas cr\u00e9er un tableau \u201c{0}\u201d de longueur
n\u00e9gative.
 NodeChildOfItself_1             = Le n\u0153ud \u201c{0}\u201d ne peut pas \u00eatre un enfant
de lui-m\u00eame.
@@ -93,6 +94,8 @@ RecursiveCreateCallForKey_1     = Appel 
 RequireDecimalSeparator         = Un s\u00e9parateur d\u00e9cimal est requis.
 StalledThread_1                 = La t\u00e2che \u201c{0}\u201d semble bloqu\u00e9e.
 StreamIsForwardOnly_1           = Ne peut pas reculer dans le flux de donn\u00e9es \u201c{0}\u201d.
+TooFewArguments_2               = Au moins {0} argument{0,choice,1# \u00e9tait attendu|2#s
\u00e9taient attendus}, mais seulement {1} {1,choice,1#a \u00e9t\u00e9 sp\u00e9cifi\u00e9|2#ont
\u00e9t\u00e9 sp\u00e9cifi\u00e9s}.
+TooManyArguments_2              = Au plus {0} argument{0,choice,1# \u00e9tait attendu|2#s
\u00e9taient attendus}, mais {1} {1,choice,1#a \u00e9t\u00e9 sp\u00e9cifi\u00e9|2#ont \u00e9t\u00e9
sp\u00e9cifi\u00e9s}.
 UndefinedOrderingForElements_2  = L\u2019ordre entre les \u00e9l\u00e9ments \u201c{0}\u201d
et \u201c{1}\u201d n\u2019est pas d\u00e9fini.
 UnexpectedChange_1              = Changement inattendu dans \u2018{0}\u2019.
 UnexpectedEndOfFile_1           = Fin de fichier inattendue lors de la lecture de \u201c{0}\u201d.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
[UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
[UTF-8] Wed Jun 12 16:56:59 2013
@@ -70,7 +70,7 @@ public class IndexedResourceBundle exten
 
     /**
      * The path of the binary file containing resources, or {@code null} if there is no resources
-     * of if the resources have already been loaded. The resources may be a file or an entry
in a
+     * or if the resources have already been loaded. The resources may be a file or an entry
in a
      * JAR file.
      */
     private URL resources;

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
[UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
[UTF-8] Wed Jun 12 16:56:59 2013
@@ -300,6 +300,11 @@ public final class Vocabulary extends In
         public static final int Variables = 47;
 
         /**
+         * {0} version {1}
+         */
+        public static final int Version_2 = 50;
+
+        /**
          * Versions
          */
         public static final int Versions = 15;

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
[ISO-8859-1] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
[ISO-8859-1] Wed Jun 12 16:56:59 2013
@@ -63,4 +63,5 @@ Untitled           = Untitled
 UserHome           = User home directory
 Value              = Value
 Variables          = Variables
+Version_2          = {0} version {1}
 Versions           = Versions

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
[ISO-8859-1] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
[ISO-8859-1] Wed Jun 12 16:56:59 2013
@@ -63,4 +63,5 @@ Untitled           = Sans titre
 UserHome           = R\u00e9pertoire de l'utilisateur
 Value              = Valeur
 Variables          = Variables
+Version_2          = {0} version {1}
 Versions           = Versions

Modified: sis/trunk/pom.xml
URL: http://svn.apache.org/viewvc/sis/trunk/pom.xml?rev=1492284&r1=1492283&r2=1492284&view=diff
==============================================================================
--- sis/trunk/pom.xml (original)
+++ sis/trunk/pom.xml Wed Jun 12 16:56:59 2013
@@ -599,6 +599,10 @@ Apache SIS is a free software, Java lang
               <packages>org.apache.sis.test*</packages>
             </group>
             <group>
+              <title>Applications</title>
+              <packages>org.apache.sis.console*:org.apache.sis.services*</packages>
+            </group>
+            <group>
               <title>Data storage</title>
               <packages>org.apache.sis.storage*:org.apache.sis.index*</packages>
             </group>
@@ -608,7 +612,7 @@ Apache SIS is a free software, Java lang
             </group>
             <group>
               <title>Referencing</title>
-              <packages>org.apache.sis.core*:org.apache.sis.distance*:org.apache.sis.referencing*:org.apache.sis.parameter*</packages>
+              <packages>org.apache.sis.referencing*:org.apache.sis.parameter*</packages>
             </group>
             <group>
               <title>Metadata</title>
@@ -616,7 +620,7 @@ Apache SIS is a free software, Java lang
             </group>
             <group>
               <title>Utilities</title>
-              <packages>org.apache.sis.math*:org.apache.sis.measure*:org.apache.sis.util*:org.apache.sis.io*:org.apache.sis.xml*</packages>
+              <packages>org.apache.sis.math*:org.apache.sis.measure*:org.apache.sis.util*:org.apache.sis.io*:org.apache.sis.xml*:org.apache.sis.setup*</packages>
             </group>
           </groups>
 



Mime
View raw message