sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1780148 [1/2] - in /sis/branches/JDK8: application/sis-console/ application/sis-console/src/main/java/org/apache/sis/console/ application/sis-console/src/test/java/org/apache/sis/console/ core/sis-utility/src/main/java/org/apache/sis/measu...
Date Wed, 25 Jan 2017 08:40:16 GMT
Author: desruisseaux
Date: Wed Jan 25 08:40:16 2017
New Revision: 1780148

URL: http://svn.apache.org/viewvc?rev=1780148&view=rev
Log:
Enable usage of GPX as an output format for the command-line.
Take format version number in account.

Added:
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/FormattedOutputCommand.java
      - copied, changed from r1779817, sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/OutputFormat.java   (with props)
Modified:
    sis/branches/JDK8/application/sis-console/pom.xml
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/AboutCommand.java
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/CRSCommand.java
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/Command.java
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/CommandRunner.java
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/HelpCommand.java
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MimeTypeCommand.java
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/package-info.java
    sis/branches/JDK8/application/sis-console/src/test/java/org/apache/sis/console/HelpCommandTest.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/Version.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/FeatureStore.java
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java
    sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Reader.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Store.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Writer.java
    sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/ReaderTest.java
    sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/WriterTest.java

Modified: sis/branches/JDK8/application/sis-console/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/pom.xml?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/pom.xml (original)
+++ sis/branches/JDK8/application/sis-console/pom.xml Wed Jan 25 08:40:16 2017
@@ -109,7 +109,7 @@ Console application.
       <groupId>org.apache.sis.storage</groupId>
       <artifactId>sis-xmlstore</artifactId>
       <version>${project.version}</version>
-      <scope>runtime</scope>
+      <scope>compile</scope>  <!-- Should be runtime after the hack in FormattedOutputCommand has been fixed. -->
     </dependency>
     <dependency>
       <groupId>org.apache.sis.storage</groupId>

Modified: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/AboutCommand.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/AboutCommand.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/AboutCommand.java [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/AboutCommand.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -59,20 +59,27 @@ import org.apache.sis.internal.util.X364
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.7
+ * @version 0.8
  * @module
  */
 final class AboutCommand extends CommandRunner {
     /**
      * Creates the {@code "about"} sub-command.
+     *
+     * @param  commandIndex  index of the {@code arguments} element containing the {@code "about"} command name, or -1 if none.
+     * @param  arguments     the command-line arguments provided by the user.
+     * @throws InvalidOptionException if an illegal option has been provided, or the option has an illegal value.
      */
-    AboutCommand(final int commandIndex, final String... args) throws InvalidOptionException {
-        super(commandIndex, args, EnumSet.of(Option.LOCALE, Option.TIMEZONE, Option.ENCODING,
+    AboutCommand(final int commandIndex, final String... arguments) throws InvalidOptionException {
+        super(commandIndex, arguments, EnumSet.of(Option.LOCALE, Option.TIMEZONE, Option.ENCODING,
                 Option.BRIEF, Option.VERBOSE, Option.HELP, Option.DEBUG));
     }
 
     /**
      * Prints the information to the output stream.
+     *
+     * @return 0 on success, or an exit code if the command failed for a reason other than an uncaught Java exception.
+     * @throws Exception if an error occurred while executing the sub-command.
      */
     @Override
     public int run() throws Exception {

Modified: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/CRSCommand.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/CRSCommand.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/CRSCommand.java [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/CRSCommand.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -16,14 +16,9 @@
  */
 package org.apache.sis.console;
 
-import java.io.IOException;
-import javax.xml.bind.JAXBException;
 import org.opengis.metadata.Metadata;
-import org.opengis.util.FactoryException;
 import org.opengis.referencing.ReferenceSystem;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.apache.sis.storage.DataStoreException;
-import org.apache.sis.io.wkt.Convention;
 
 
 /**
@@ -32,32 +27,24 @@ import org.apache.sis.io.wkt.Convention;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.7
+ * @version 0.8
  * @module
  */
-final class CRSCommand extends MetadataCommand {
+final class CRSCommand extends FormattedOutputCommand {
     /**
      * Creates the {@code "crs"} sub-command.
      */
     CRSCommand(final int commandIndex, final String... args) throws InvalidOptionException {
-        super(commandIndex, args);
-
-        // Default output format.
-        outputFormat = Format.WKT;
-        convention = Convention.WKT2_SIMPLIFIED;
+        super(commandIndex, args, MetadataCommand.options(), OutputFormat.WKT, OutputFormat.XML);
     }
 
     /**
      * Prints metadata or CRS information.
      *
-     * @throws DataStoreException if an error occurred while reading the file.
-     * @throws JAXBException if an error occurred while producing the XML output.
-     * @throws FactoryException if an error occurred while looking for a CRS identifier.
-     * @throws IOException should never happen, since we are appending to a print writer.
+     * @return 0 on success, or an exit code if the command failed for a reason other than an uncaught Java exception.
      */
     @Override
-    public int run() throws InvalidOptionException, DataStoreException, JAXBException, FactoryException, IOException {
-        parseArguments();
+    public int run() throws Exception {
         final Object metadata = readMetadataOrCRS();
         if (hasUnexpectedFileCount) {
             return Command.INVALID_ARGUMENT_EXIT_CODE;

Modified: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/Command.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/Command.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/Command.java [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/Command.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -71,7 +71,7 @@ import org.apache.sis.util.logging.Monol
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.7
+ * @version 0.8
  * @module
  */
 public final class Command {
@@ -115,11 +115,6 @@ public final class Command {
     public static final int OTHER_ERROR_EXIT_CODE = 199;
 
     /**
-     * The sub-command name.
-     */
-    private final String commandName;
-
-    /**
      * The sub-command to execute.
      */
     private final CommandRunner command;
@@ -153,8 +148,7 @@ public final class Command {
         if (commandName == null) {
             command = new HelpCommand(-1, args);
         } else {
-            commandName = commandName.toLowerCase(Locale.US);
-            switch (commandName) {
+            switch (commandName.toLowerCase(Locale.US)) {
                 case "help":       command = new HelpCommand      (commandIndex, args); break;
                 case "about":      command = new AboutCommand     (commandIndex, args); break;
                 case "mime-type":  command = new MimeTypeCommand  (commandIndex, args); break;
@@ -166,7 +160,6 @@ public final class Command {
                             Errors.Keys.UnknownCommand_1, commandName), commandName);
             }
         }
-        this.commandName = commandName;
         CommandRunner.instance = command;       // For ResourcesDownloader only.
     }
 
@@ -184,7 +177,7 @@ public final class Command {
             return INVALID_OPTION_EXIT_CODE;
         }
         if (command.options.containsKey(Option.HELP)) {
-            command.help(commandName);
+            command.help(command.commandName.toLowerCase(Locale.US));
         } else try {
             return command.run();
         } catch (Exception e) {

Modified: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/CommandRunner.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/CommandRunner.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/CommandRunner.java [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/CommandRunner.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -23,6 +23,7 @@ import java.util.EnumSet;
 import java.util.EnumMap;
 import java.util.TimeZone;
 import java.io.Console;
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.io.OutputStreamWriter;
@@ -34,11 +35,13 @@ import org.apache.sis.internal.util.X364
 
 
 /**
- * Base class of sub-commands.
+ * Base class of all sub-commands.
+ * A subclasses is initialized by the {@link Command} constructor,
+ * then the {@link #run()} method is invoked by {@link Command#run()}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.7
+ * @version 0.8
  * @module
  */
 abstract class CommandRunner {
@@ -58,6 +61,12 @@ abstract class CommandRunner {
     static CommandRunner instance;
 
     /**
+     * The name of this command, as specified by the user on the command-line.
+     * May contain a mix of lower-case and upper-case letters if the user specified the command that way.
+     */
+    protected final String commandName;
+
+    /**
      * The set of legal options for this command.
      *
      * @see #help(String)
@@ -70,8 +79,8 @@ abstract class CommandRunner {
     protected final EnumMap<Option,String> options;
 
     /**
-     * The locale specified by the {@code "--locale"} option. If no such option was
-     * provided, then this field is set to the {@linkplain Locale#getDefault() default locale}.
+     * The locale specified by the {@code "--locale"} option. If no such option was provided,
+     * then this field is set to the {@linkplain Locale#getDefault() default locale}.
      */
     protected final Locale locale;
 
@@ -130,6 +139,7 @@ abstract class CommandRunner {
      * only when a command needs to delegates part of its work to an other command.
      */
     CommandRunner(final CommandRunner parent) {
+        this.commandName  = parent.commandName;
         this.validOptions = parent.validOptions;
         this.options      = parent.options;
         this.locale       = parent.locale;
@@ -149,7 +159,7 @@ abstract class CommandRunner {
      * The argument at index {@code commandIndex} is the name of this command, and will be ignored except for
      * the special {@value #TEST} value which is used only at JUnit testing time.
      *
-     * @param  commandIndex  index of the {@code args} element containing the sub-command name.
+     * @param  commandIndex  index of the {@code arguments} element containing the sub-command name, or -1 if none.
      * @param  arguments     the command-line arguments provided by the user.
      * @param  validOptions  the command-line options allowed by this sub-command.
      * @throws InvalidOptionException if an illegal option has been provided, or the option has an illegal value.
@@ -158,16 +168,15 @@ abstract class CommandRunner {
     protected CommandRunner(final int commandIndex, final String[] arguments, final EnumSet<Option> validOptions)
             throws InvalidOptionException
     {
-        boolean isTest = false;
+        commandName = (commandIndex >= 0) ? arguments[commandIndex] : null;
         this.validOptions = validOptions;
         options = new EnumMap<>(Option.class);
         files = new ArrayList<>(arguments.length);
-        for (int i=0; i<arguments.length; i++) {
-            final String arg = arguments[i];
+        for (int i=0; i < arguments.length; i++) {
             if (i == commandIndex) {
-                isTest = arg.equals(TEST);
                 continue;
             }
+            final String arg = arguments[i];
             if (arg.startsWith(Option.PREFIX)) {
                 final String name = arg.substring(Option.PREFIX.length());
                 final Option option = Option.forLabel(name);
@@ -222,7 +231,7 @@ abstract class CommandRunner {
          * output to a StringBuffer. Otherwise the output will be sent to the java.io.Console if possible,
          * or to the standard output stream otherwise.
          */
-        if (isTest) {
+        if (TEST.equals(commandName)) {
             final StringWriter s = new StringWriter();
             outputBuffer = s.getBuffer();
             out = new PrintWriter(s);
@@ -322,19 +331,22 @@ abstract class CommandRunner {
     }
 
     /**
-     * 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.
+     * 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. The default implementation builds a description
+     * from the texts associated to the given {@code resourceKey} in various resource bundles provided in
+     * this {@code sis-console} module. Subclasses can override if needed.
      *
-     * @param commandName  the command name converted to lower cases.
+     * @param  resourceKey  the key for the resource to print. This is usually {@link #commandName} in lower-cases.
+     * @throws IOException should never happen, because we are writing to a {@code PrintWriter}.
      */
-    protected void help(final String commandName) {
-        new HelpCommand(this).help(false, new String[] {commandName}, validOptions);
+    protected void help(final String resourceKey) throws IOException {
+        new HelpCommand(this).help(false, new String[] {resourceKey}, 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.
+     * @return 0 on success, or an exit code if the command failed for a reason other than an uncaught Java exception.
      * @throws Exception if an error occurred while executing the sub-command.
      */
     public abstract int run() throws Exception;

Copied: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/FormattedOutputCommand.java (from r1779817, sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/FormattedOutputCommand.java?p2=sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/FormattedOutputCommand.java&p1=sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java&r1=1779817&r2=1780148&rev=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/FormattedOutputCommand.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -16,14 +16,13 @@
  */
 package org.apache.sis.console;
 
-import java.util.Collections;
+import java.util.Locale;
 import java.util.EnumSet;
 import java.io.Console;
 import java.io.IOException;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.JAXBException;
 import org.opengis.metadata.Metadata;
-import org.opengis.referencing.ReferenceSystem;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.util.FactoryException;
 import org.apache.sis.io.wkt.WKTFormat;
@@ -31,107 +30,159 @@ import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.io.wkt.Colors;
 import org.apache.sis.metadata.MetadataStandard;
 import org.apache.sis.metadata.ValueExistencePolicy;
-import org.apache.sis.metadata.iso.DefaultMetadata;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStores;
+import org.apache.sis.storage.DataStoreProvider;
 import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.internal.storage.CodeType;
 import org.apache.sis.util.collection.TableColumn;
 import org.apache.sis.util.collection.TreeTable;
 import org.apache.sis.util.collection.TreeTableFormat;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.ArraysExt;
+import org.apache.sis.util.Version;
+import org.apache.sis.measure.Range;
+import org.apache.sis.setup.OptionKey;
 import org.apache.sis.xml.MarshallerPool;
 import org.apache.sis.xml.XML;
 
 
 /**
- * The "metadata" sub-command. This class is also used as the base class of other sub-commands
- * that perform most of their work on the basis of metadata information.
+ * Base class of commands that provided formatted output.
+ * The output format is controlled by {@link OutputFormat} enumeration.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @since   0.3
+ * @since   0.8
  * @version 0.8
  * @module
  */
-class MetadataCommand extends CommandRunner {
+abstract class FormattedOutputCommand extends CommandRunner {
     /**
      * The output format.
      */
-    static enum Format {
-        TEXT, WKT, XML
-    }
+    private final OutputFormat outputFormat;
 
     /**
-     * The output format. Default value can be overridden by {@link #parseArguments()}.
+     * The WKT convention, or {@code null} if it does not apply.
+     * This is slightly redundant to {@link #version}, but specific to the WKT format.
      */
-    Format outputFormat = Format.TEXT;
+    Convention convention;
 
     /**
-     * The WKT convention, or {@code null} if it does not apply.
+     * Desired version of output format, or {@code null} if unspecified.
+     * The format can be specified after the format name, for example {@code "gpx-1.1"}.
      */
-    Convention convention;
+    private Version version;
 
     /**
-     * Sets to {@code true} by {@link #readMetadata()} if the users provided an unexpected number of file arguments.
-     * In such case, the {@link #run()} should terminate with exit code {@link Command#INVALID_ARGUMENT_EXIT_CODE}.
+     * The provider of {@link DataStore} instances capable to write data in the {@link #outputFormat},
+     * or {@code null} if none.
      */
-    boolean hasUnexpectedFileCount;
+    private final DataStoreProvider provider;
 
     /**
-     * Creates the {@code "metadata"} sub-command.
+     * Sets to {@code true} by {@link #readMetadataOrCRS()} if the users provided an unexpected number of file arguments.
+     * In such case, the {@link #run()} should terminate with exit code {@link Command#INVALID_ARGUMENT_EXIT_CODE}.
      */
-    MetadataCommand(final int commandIndex, final String... args) throws InvalidOptionException {
-        super(commandIndex, args, EnumSet.of(Option.FORMAT, Option.LOCALE, Option.TIMEZONE, Option.ENCODING,
-                Option.COLORS, Option.HELP, Option.DEBUG));
-    }
+    boolean hasUnexpectedFileCount;
 
     /**
      * Creates a new sub-command with the given command-line arguments.
-     * This constructor is for {@code MetadataCommand} subclasses only.
+     * This constructor is for {@code MetadataCommand} subclasses.
      *
-     * @param  commandIndex  index of the {@code args} element containing the sub-command name.
-     * @param  arguments     the command-line arguments provided by the user.
-     * @param  validOptions  the command-line options allowed by this sub-command.
+     * @param  commandIndex      index of the {@code arguments} element containing the sub-command name, or -1 if none.
+     * @param  arguments         the command-line arguments provided by the user.
+     * @param  validOptions      the command-line options allowed by this sub-command.
+     * @param  supportedFormats  the output formats to accept. The first format is the default one.
      * @throws InvalidOptionException if an illegal option has been provided, or the option has an illegal value.
      */
-    MetadataCommand(final int commandIndex, final String[] args, final EnumSet<Option> validOptions)
-            throws InvalidOptionException
+    FormattedOutputCommand(final int commandIndex, final String[] arguments, final EnumSet<Option> validOptions,
+            final OutputFormat... supportedFormats) throws InvalidOptionException
     {
-        super(commandIndex, args, validOptions);
-    }
-
-    /**
-     * Parses the command-line arguments and initializes the {@link #outputFormat} and {@link #convention} fields
-     * accordingly.
-     */
-    final void parseArguments() throws InvalidOptionException {
+        super(commandIndex, arguments, validOptions);
+        boolean isVersionSupported = true;
         /*
          * Output format can be either "text" (the default) or "xml".
          * In the case of "crs" sub-command, we accept also WKT variants.
          */
         final String format = options.get(Option.FORMAT);
-        if (format != null && !format.equalsIgnoreCase("text")) {
-            if (format.equalsIgnoreCase("wkt") || format.equalsIgnoreCase("wkt2")) {
-                outputFormat = Format.WKT;
-                convention = Convention.WKT2;
-            } else if (format.equalsIgnoreCase("wkt1")) {
-                outputFormat = Format.WKT;
-                convention = Convention.WKT1;
-            } else if (format.equalsIgnoreCase("xml")) {
-                outputFormat = Format.XML;
-            } else {
+        if (format == null) {
+            outputFormat = supportedFormats[0];
+            convention   = Convention.WKT2_SIMPLIFIED;
+        } else if (format.equalsIgnoreCase("WKT1")) {
+            outputFormat = OutputFormat.WKT;
+            convention   = Convention.WKT1;
+        } else if (format.equalsIgnoreCase("WKT2")) {
+            outputFormat = OutputFormat.WKT;
+            convention   = Convention.WKT2;
+        } else {
+            /*
+             * Separate the format name from its version. We verify right after this block that the format
+             * enumerated value that we get is one of the formats supported by this command. Note that the
+             * error messages in case of unknown and unsupported format are slightly different.
+             */
+            final int s = format.indexOf('-');
+            String fmtEnum = format;
+            if (s > 0) {
+                fmtEnum = format.substring(0, s);
+                version = new Version(format.substring(s+1).trim());
+            }
+            fmtEnum = fmtEnum.toUpperCase(Locale.US);
+            try {
+                outputFormat = OutputFormat.valueOf(fmtEnum);
+            } catch (IllegalArgumentException e) {
                 throw new InvalidOptionException(Errors.format(
-                        Errors.Keys.IllegalOptionValue_2, "format", format), format);
+                        Errors.Keys.IllegalOptionValue_2, "format", format), e, "format");
+            }
+        }
+        if (!ArraysExt.contains(supportedFormats, outputFormat)) {
+            throw new InvalidOptionException(Errors.format(
+                    Errors.Keys.IncompatibleFormat_2, commandName, outputFormat), "format");
+        }
+        /*
+         * At this point the output format is considered valid. Now verify its version number.
+         * For some special cases (e.g. WKT format), this block sets properties that depend on
+         * the version number (e.g. WKT conventions).
+         */
+        provider = outputFormat.provider();
+        switch (outputFormat) {
+            case WKT: {
+                if (convention == null) {
+                    if (version == null || version.equals(Version.valueOf(2))) {
+                        convention = Convention.WKT2;
+                    } else {
+                        convention = Convention.WKT1;
+                        isVersionSupported = version.equals(Version.valueOf(1));
+                    }
+                }
+                break;
+            }
+            default: {
+                if (version != null) {
+                    if (isVersionSupported = (provider != null)) {
+                        final Range<Version> supportedVersions = provider.getSupportedVersions();
+                        isVersionSupported = (supportedVersions != null) && supportedVersions.contains(version);
+                    }
+                }
+                break;
             }
         }
+        if (!isVersionSupported) {
+            throw new InvalidOptionException(Errors.format(
+                    Errors.Keys.UnsupportedFormatVersion_2, outputFormat.name(), version), "format");
+        }
     }
 
     /**
      * If the given argument seems to be an authority code ("URN", "EPSG", "CRS", "AUTO", <i>etc.</i>),
      * delegates to {@link CRS#forCode(String)}. Otherwise reads the metadata using a datastore.
+     * The input format is detected automatically (this is <strong>not</strong> {@link #outputFormat}).
      *
      * @return a {@link Metadata} or {@link CoordinateReferenceSystem} instance, or {@code null} if none.
+     * @throws DataStoreException if an error occurred while reading the file.
+     * @throws FactoryException if an error occurred while looking for a CRS identifier.
      */
     final Object readMetadataOrCRS() throws DataStoreException, FactoryException {
         if (useStandardInput()) {
@@ -154,45 +205,15 @@ class MetadataCommand extends CommandRun
     }
 
     /**
-     * Prints metadata or CRS information.
-     *
-     * @throws DataStoreException if an error occurred while reading the file.
-     * @throws JAXBException if an error occurred while producing the XML output.
-     * @throws FactoryException if an error occurred while looking for a CRS identifier.
-     * @throws IOException should never happen, since we are appending to a print writer.
-     */
-    @Override
-    public int run() throws Exception {
-        parseArguments();
-        if (convention != null) {
-            final String format = outputFormat.name();
-            throw new InvalidOptionException(Errors.format(Errors.Keys.IncompatibleFormat_2, "metadata", format), format);
-        }
-        /*
-         * Read metadata from the data storage only after we verified that the arguments are valid.
-         * The input can be a file given on the command line, or the standard input stream.
-         */
-        Object metadata = readMetadataOrCRS();
-        if (hasUnexpectedFileCount) {
-            return Command.INVALID_ARGUMENT_EXIT_CODE;
-        }
-        if (metadata != null) {
-            if (!(metadata instanceof Metadata)) {
-                final DefaultMetadata md = new DefaultMetadata();
-                md.setReferenceSystemInfo(Collections.singleton((ReferenceSystem) metadata));
-                metadata = md;
-            }
-            format(metadata);
-        }
-        return 0;
-    }
-
-    /**
-     * Format the given metadata or CRS object to the standard output stream.
+     * Formats the given metadata or CRS object to the standard output stream.
      * The format is determined by {@link #outputFormat} and (in WKT case only) {@link #convention}.
+     *
+     * @throws DataStoreException if an error occurred while producing output using a data store.
+     * @throws JAXBException if an error occurred while producing the XML output using JAXB.
+     * @throws IOException should never happen since we are appending to a print writer.
      */
     @SuppressWarnings("UseOfSystemOutOrSystemErr")
-    final void format(final Object object) throws IOException, JAXBException {
+    final void format(final Object object) throws DataStoreException, JAXBException, IOException {
         switch (outputFormat) {
             case TEXT: {
                 final TreeTable tree = MetadataStandard.ISO_19115.asTreeTable(object,
@@ -232,6 +253,28 @@ class MetadataCommand extends CommandRun
                 }
                 break;
             }
+
+            default: {
+                final StorageConnector connector = new StorageConnector(out);
+                connector.setOption(OptionKey.TIMEZONE, timezone);
+                connector.setOption(OptionKey.LOCALE,   locale);
+                connector.setOption(OptionKey.ENCODING, encoding);
+                try (final DataStore store = provider.open(connector)) {
+                    /*
+                     * HACK: API used in this block is currently available only for GPX format,
+                     * but we will generalize to more formats in a future Apache SIS version.
+                     *
+                     * Note: after such generalization is done, revert the xml-store dependency
+                     *       scope in pom.xml from "compile" to "runtime".
+                     */
+                    final org.apache.sis.internal.storage.gpx.Store fs = (org.apache.sis.internal.storage.gpx.Store) store;
+                    if (version != null) {
+                        fs.setVersion(version);
+                    }
+                    fs.write((object instanceof Metadata) ? (Metadata) object : null, null);
+                }
+                break;
+            }
         }
         out.flush();
     }

Modified: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/HelpCommand.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/HelpCommand.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/HelpCommand.java [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/HelpCommand.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -28,7 +28,7 @@ import org.apache.sis.util.resources.Voc
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.7
+ * @version 0.8
  * @module
  */
 final class HelpCommand extends CommandRunner {
@@ -46,8 +46,8 @@ final class HelpCommand extends CommandR
     };
 
     /**
-     * Copies the configuration of the given sub-command. This constructor is used
-     * for printing help about an other command.
+     * Copies the configuration of the given sub-command.
+     * This constructor is used for printing help about another command.
      */
     HelpCommand(final CommandRunner parent) {
         super(parent);
@@ -55,16 +55,23 @@ final class HelpCommand extends CommandR
 
     /**
      * Creates the {@code "help"} sub-command.
+     *
+     * @param  commandIndex  index of the {@code arguments} element containing the {@code "help"} command name, or -1 if none.
+     * @param  arguments     the command-line arguments provided by the user.
+     * @throws InvalidOptionException if an illegal option has been provided, or the option has an illegal value.
      */
-    HelpCommand(final int commandIndex, final String... args) throws InvalidOptionException {
-        super(commandIndex, args, EnumSet.of(Option.LOCALE, Option.ENCODING, Option.HELP, Option.DEBUG));
+    HelpCommand(final int commandIndex, final String... arguments) throws InvalidOptionException {
+        super(commandIndex, arguments, EnumSet.of(Option.LOCALE, Option.ENCODING, Option.HELP, Option.DEBUG));
     }
 
     /**
      * Prints the help instructions.
+     *
+     * @return 0 on success, or an exit code if the command failed for a reason other than a Java exception.
+     * @throws IOException should never happen, because we are writing to a {@code PrintWriter}.
      */
     @Override
-    public int run() {
+    public int run() throws IOException {
         if (hasUnexpectedFileCount(0, 0)) {
             return Command.INVALID_ARGUMENT_EXIT_CODE;
         }
@@ -78,8 +85,9 @@ final class HelpCommand extends CommandR
      * @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.
+     * @throws IOException should never happen, because we are writing to a {@code PrintWriter}.
      */
-    void help(final boolean showHeader, final String[] commandNames, final EnumSet<Option> validOptions) {
+    void help(final boolean showHeader, final String[] commandNames, final EnumSet<Option> validOptions) throws IOException {
         final ResourceBundle commands = ResourceBundle.getBundle("org.apache.sis.console.Commands", locale);
         final ResourceBundle options  = ResourceBundle.getBundle("org.apache.sis.console.Options",  locale);
         final Vocabulary vocabulary = Vocabulary.getResources(locale);
@@ -91,34 +99,30 @@ final class HelpCommand extends CommandR
             out.print(vocabulary.getString(Vocabulary.Keys.Commands));
             out.println(':');
         }
-        try {
-            final TableAppender table = new TableAppender(out, "  ");
-            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();
+        final TableAppender table = new TableAppender(out, "  ");
+        for (final String command : commandNames) {
+            if (showHeader) {
+                table.append("  ");
             }
-            table.flush();
-            out.println();
-            out.print(vocabulary.getString(Vocabulary.Keys.Options));
-            out.println(':');
-            for (final Option option : validOptions) {
-                final String name = option.label();
-                table.append("  ").append(Option.PREFIX).append(name);
-                table.nextColumn();
-                table.append(options.getString(name));
-                table.nextLine();
+            table.append(command);
+            if (!showHeader) {
+                table.append(':');
             }
-            table.flush();
-        } catch (IOException e) {
-            throw new AssertionError(e);            // Should never happen, because we are writing to a PrintWriter.
+            table.nextColumn();
+            table.append(commands.getString(command));
+            table.nextLine();
+        }
+        table.flush();
+        out.println();
+        out.print(vocabulary.getString(Vocabulary.Keys.Options));
+        out.println(':');
+        for (final Option option : validOptions) {
+            final String name = option.label();
+            table.append("  ").append(Option.PREFIX).append(name);
+            table.nextColumn();
+            table.append(options.getString(name));
+            table.nextLine();
         }
+        table.flush();
     }
 }

Modified: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/IdentifierCommand.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -22,8 +22,6 @@ import java.util.Set;
 import java.util.EnumSet;
 import java.util.Collections;
 import java.util.ResourceBundle;
-import java.io.IOException;
-import javax.xml.bind.JAXBException;
 import org.opengis.metadata.Metadata;
 import org.opengis.metadata.Identifier;
 import org.opengis.referencing.NoSuchAuthorityCodeException;
@@ -32,10 +30,9 @@ import org.opengis.referencing.Reference
 import org.apache.sis.internal.util.X364;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.IdentifiedObjects;
-import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.ComparisonMode;
-import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.Workaround;
 import org.apache.sis.util.resources.Vocabulary;
 
 
@@ -44,10 +41,10 @@ import org.apache.sis.util.resources.Voc
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.7
+ * @version 0.8
  * @module
  */
-final class IdentifierCommand extends MetadataCommand {
+final class IdentifierCommand extends FormattedOutputCommand {
     /**
      * The state to write in the left margin before the identifier.
      *
@@ -91,27 +88,31 @@ final class IdentifierCommand extends Me
     }
 
     /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    @Workaround(library="JDK", version="1.7")
+    private static EnumSet<Option> options() {
+        final EnumSet<Option> options = MetadataCommand.options();
+        options.remove(Option.TIMEZONE);
+        options.remove(Option.FORMAT);
+        return options;
+    }
+
+    /**
      * Creates the {@code "identifier"} sub-command.
      */
     IdentifierCommand(final int commandIndex, final String... args) throws InvalidOptionException {
-        super(commandIndex, args);
+        super(commandIndex, args, options(), OutputFormat.TEXT);
     }
 
     /**
      * Prints identifier information.
      *
-     * @throws DataStoreException if an error occurred while reading the file.
-     * @throws JAXBException if an error occurred while producing the XML output.
-     * @throws FactoryException if an error occurred while looking for a CRS identifier.
-     * @throws IOException should never happen, since we are appending to a print writer.
+     * @return 0 on success, or an exit code if the command failed for a reason other than an uncaught Java exception.
      */
     @Override
-    public int run() throws InvalidOptionException, DataStoreException, JAXBException, FactoryException, IOException {
-        parseArguments();
-        if (outputFormat != Format.TEXT) {
-            final String format = outputFormat.name();
-            throw new InvalidOptionException(Errors.format(Errors.Keys.IncompatibleFormat_2, "identifier", format), format);
-        }
+    public int run() throws Exception {
         /*
          * Read metadata from the data storage only after we verified that the arguments are valid.
          * The input can be a file given on the command line, or the standard input stream.

Modified: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -18,156 +18,46 @@ package org.apache.sis.console;
 
 import java.util.Collections;
 import java.util.EnumSet;
-import java.io.Console;
-import java.io.IOException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.JAXBException;
 import org.opengis.metadata.Metadata;
 import org.opengis.referencing.ReferenceSystem;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.util.FactoryException;
-import org.apache.sis.io.wkt.WKTFormat;
-import org.apache.sis.io.wkt.Convention;
-import org.apache.sis.io.wkt.Colors;
-import org.apache.sis.metadata.MetadataStandard;
-import org.apache.sis.metadata.ValueExistencePolicy;
 import org.apache.sis.metadata.iso.DefaultMetadata;
-import org.apache.sis.referencing.CRS;
-import org.apache.sis.storage.DataStore;
-import org.apache.sis.storage.DataStores;
-import org.apache.sis.storage.DataStoreException;
-import org.apache.sis.internal.storage.CodeType;
-import org.apache.sis.util.collection.TableColumn;
-import org.apache.sis.util.collection.TreeTable;
-import org.apache.sis.util.collection.TreeTableFormat;
-import org.apache.sis.util.resources.Errors;
-import org.apache.sis.xml.MarshallerPool;
-import org.apache.sis.xml.XML;
 
 
 /**
- * The "metadata" sub-command. This class is also used as the base class of other sub-commands
- * that perform most of their work on the basis of metadata information.
+ * The "metadata" sub-command.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
  * @version 0.8
  * @module
  */
-class MetadataCommand extends CommandRunner {
+final class MetadataCommand extends FormattedOutputCommand {
     /**
-     * The output format.
+     * Returns valid options for the {@code "metadata"} command.
      */
-    static enum Format {
-        TEXT, WKT, XML
+    static EnumSet<Option> options() {
+        return EnumSet.of(Option.FORMAT, Option.LOCALE, Option.TIMEZONE,
+                Option.ENCODING, Option.COLORS, Option.HELP, Option.DEBUG);
     }
 
     /**
-     * The output format. Default value can be overridden by {@link #parseArguments()}.
-     */
-    Format outputFormat = Format.TEXT;
-
-    /**
-     * The WKT convention, or {@code null} if it does not apply.
-     */
-    Convention convention;
-
-    /**
-     * Sets to {@code true} by {@link #readMetadata()} if the users provided an unexpected number of file arguments.
-     * In such case, the {@link #run()} should terminate with exit code {@link Command#INVALID_ARGUMENT_EXIT_CODE}.
-     */
-    boolean hasUnexpectedFileCount;
-
-    /**
      * Creates the {@code "metadata"} sub-command.
-     */
-    MetadataCommand(final int commandIndex, final String... args) throws InvalidOptionException {
-        super(commandIndex, args, EnumSet.of(Option.FORMAT, Option.LOCALE, Option.TIMEZONE, Option.ENCODING,
-                Option.COLORS, Option.HELP, Option.DEBUG));
-    }
-
-    /**
-     * Creates a new sub-command with the given command-line arguments.
-     * This constructor is for {@code MetadataCommand} subclasses only.
      *
-     * @param  commandIndex  index of the {@code args} element containing the sub-command name.
+     * @param  commandIndex  index of the {@code arguments} element containing the {@code "metadata"} command name, or -1 if none.
      * @param  arguments     the command-line arguments provided by the user.
-     * @param  validOptions  the command-line options allowed by this sub-command.
      * @throws InvalidOptionException if an illegal option has been provided, or the option has an illegal value.
      */
-    MetadataCommand(final int commandIndex, final String[] args, final EnumSet<Option> validOptions)
-            throws InvalidOptionException
-    {
-        super(commandIndex, args, validOptions);
-    }
-
-    /**
-     * Parses the command-line arguments and initializes the {@link #outputFormat} and {@link #convention} fields
-     * accordingly.
-     */
-    final void parseArguments() throws InvalidOptionException {
-        /*
-         * Output format can be either "text" (the default) or "xml".
-         * In the case of "crs" sub-command, we accept also WKT variants.
-         */
-        final String format = options.get(Option.FORMAT);
-        if (format != null && !format.equalsIgnoreCase("text")) {
-            if (format.equalsIgnoreCase("wkt") || format.equalsIgnoreCase("wkt2")) {
-                outputFormat = Format.WKT;
-                convention = Convention.WKT2;
-            } else if (format.equalsIgnoreCase("wkt1")) {
-                outputFormat = Format.WKT;
-                convention = Convention.WKT1;
-            } else if (format.equalsIgnoreCase("xml")) {
-                outputFormat = Format.XML;
-            } else {
-                throw new InvalidOptionException(Errors.format(
-                        Errors.Keys.IllegalOptionValue_2, "format", format), format);
-            }
-        }
-    }
-
-    /**
-     * If the given argument seems to be an authority code ("URN", "EPSG", "CRS", "AUTO", <i>etc.</i>),
-     * delegates to {@link CRS#forCode(String)}. Otherwise reads the metadata using a datastore.
-     *
-     * @return a {@link Metadata} or {@link CoordinateReferenceSystem} instance, or {@code null} if none.
-     */
-    final Object readMetadataOrCRS() throws DataStoreException, FactoryException {
-        if (useStandardInput()) {
-            try (DataStore store = DataStores.open(System.in)) {
-                return store.getMetadata();
-            }
-        } else if (hasUnexpectedFileCount(1, 1)) {
-            hasUnexpectedFileCount = true;
-            return null;
-        } else {
-            final String file = files.get(0);
-            if (CodeType.guess(file).isCRS) {
-                return CRS.forCode(file);
-            } else {
-                try (DataStore store = DataStores.open(file)) {
-                    return store.getMetadata();
-                }
-            }
-        }
+    MetadataCommand(final int commandIndex, final String... arguments) throws InvalidOptionException {
+        super(commandIndex, arguments, options(), OutputFormat.TEXT, OutputFormat.XML, OutputFormat.GPX);
     }
 
     /**
      * Prints metadata or CRS information.
      *
-     * @throws DataStoreException if an error occurred while reading the file.
-     * @throws JAXBException if an error occurred while producing the XML output.
-     * @throws FactoryException if an error occurred while looking for a CRS identifier.
-     * @throws IOException should never happen, since we are appending to a print writer.
+     * @return 0 on success, or an exit code if the command failed for a reason other than an uncaught Java exception.
      */
     @Override
     public int run() throws Exception {
-        parseArguments();
-        if (convention != null) {
-            final String format = outputFormat.name();
-            throw new InvalidOptionException(Errors.format(Errors.Keys.IncompatibleFormat_2, "metadata", format), format);
-        }
         /*
          * Read metadata from the data storage only after we verified that the arguments are valid.
          * The input can be a file given on the command line, or the standard input stream.
@@ -186,65 +76,4 @@ class MetadataCommand extends CommandRun
         }
         return 0;
     }
-
-    /**
-     * Format the given metadata or CRS object to the standard output stream.
-     * The format is determined by {@link #outputFormat} and (in WKT case only) {@link #convention}.
-     */
-    @SuppressWarnings("UseOfSystemOutOrSystemErr")
-    final void format(final Object object) throws IOException, JAXBException {
-        switch (outputFormat) {
-            case TEXT: {
-                final TreeTable tree = MetadataStandard.ISO_19115.asTreeTable(object,
-                        (object instanceof Metadata) ? Metadata.class : null,
-                        ValueExistencePolicy.NON_EMPTY);
-                final TreeTableFormat tf = new TreeTableFormat(locale, timezone);
-                tf.setColumns(TableColumn.NAME, TableColumn.VALUE);
-                tf.format(tree, out);
-                break;
-            }
-
-            case WKT: {
-                final WKTFormat f = new WKTFormat(locale, timezone);
-                if (convention != null) {
-                    f.setConvention(convention);
-                }
-                if (colors) {
-                    f.setColors(Colors.DEFAULT);
-                }
-                f.format(object, out);
-                out.println();
-                break;
-            }
-
-            case XML: {
-                final MarshallerPool pool = new MarshallerPool(null);
-                final Marshaller marshaller = pool.acquireMarshaller();
-                marshaller.setProperty(XML.LOCALE,   locale);
-                marshaller.setProperty(XML.TIMEZONE, timezone);
-                if (isConsole()) {
-                    marshaller.marshal(object, out);
-                } else {
-                    out.flush();
-                    marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding.name());
-                    marshaller.marshal(object, System.out);     // Intentionally use OutputStream instead than Writer.
-                    System.out.flush();
-                }
-                break;
-            }
-        }
-        out.flush();
-    }
-
-    /**
-     * Returns {@code true} if {@link #out} is sending its output to the console.
-     * If not, then we are probably writing to a file or the user specified his own encoding.
-     * In such case, we will send the XML output to an {@code OutputStream} instead than to a
-     * {@code Writer} and let the marshaller apply the encoding itself.
-     */
-    private boolean isConsole() {
-        if (outputBuffer != null) return true;                      // Special case for JUnit tests only.
-        final Console console = System.console();
-        return (console != null) && console.writer() == out;
-    }
 }

Modified: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MimeTypeCommand.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MimeTypeCommand.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MimeTypeCommand.java [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MimeTypeCommand.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -18,14 +18,12 @@ package org.apache.sis.console;
 
 import java.net.URI;
 import java.util.EnumSet;
-import java.io.IOException;
 import java.net.URISyntaxException;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.nio.file.NoSuchFileException;
 import java.nio.file.FileSystemNotFoundException;
 import org.apache.sis.storage.DataStores;
-import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.CharSequences;
 
@@ -41,7 +39,7 @@ import org.apache.sis.util.CharSequences
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.8
  * @module
  *
  * @see Files#probeContentType(Path)
@@ -50,18 +48,23 @@ import org.apache.sis.util.CharSequences
 final class MimeTypeCommand extends CommandRunner {
     /**
      * Creates the {@code "mime-type"} sub-command.
+     *
+     * @param  commandIndex  index of the {@code arguments} element containing the {@code "mime-type"} command name, or -1 if none.
+     * @param  arguments     the command-line arguments provided by the user.
+     * @throws InvalidOptionException if an illegal option has been provided, or the option has an illegal value.
      */
-    MimeTypeCommand(final int commandIndex, final String... args) throws InvalidOptionException {
-        super(commandIndex, args, EnumSet.of(Option.ENCODING, Option.HELP, Option.DEBUG));
+    MimeTypeCommand(final int commandIndex, final String... arguments) throws InvalidOptionException {
+        super(commandIndex, arguments, EnumSet.of(Option.ENCODING, Option.HELP, Option.DEBUG));
     }
 
     /**
      * Prints mime-type information.
      *
-     * @throws IOException if an error occurred while reading the file.
+     * @return 0 on success, or an exit code if the command failed for a reason other than an uncaught Java exception.
+     * @throws Exception if an error occurred while executing the sub-command.
      */
     @Override
-    public int run() throws InvalidOptionException, IOException, DataStoreException, URISyntaxException {
+    public int run() throws Exception {
         if (hasUnexpectedFileCount(1, Integer.MAX_VALUE)) {
             return Command.INVALID_ARGUMENT_EXIT_CODE;
         }

Added: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/OutputFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/OutputFormat.java?rev=1780148&view=auto
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/OutputFormat.java (added)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/OutputFormat.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -0,0 +1,84 @@
+/*
+ * 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.sis.console;
+
+import org.apache.sis.storage.DataStores;
+import org.apache.sis.storage.DataStoreProvider;
+
+
+/**
+ * The output format specified by the user as an option.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.8
+ * @version 0.8
+ * @module
+ *
+ * @see FormattedOutputCommand
+ */
+enum OutputFormat {
+    /**
+     * Arbitrary text, if possible similar to Well Known Text (WKT) but not necessarily.
+     */
+    TEXT(null),
+
+    /**
+     * Well Known Text format, used for geometric objects and Coordinate Reference Systems.
+     */
+    WKT(null),
+
+    /**
+     * Standardized XML format as defined by ISO 19115-3 or by GML.
+     */
+    XML(null),
+
+    /**
+     * XML format used for GPS data exchange.
+     */
+    GPX(org.apache.sis.internal.storage.gpx.StoreProvider.class);
+
+    /**
+     * The provider class for this format.
+     */
+    private final Class<? extends DataStoreProvider> providerClass;
+
+    /**
+     * Creates a new enumeration value.
+     *
+     * @param  provider The provider class for this format.
+     */
+    private OutputFormat(final Class<? extends DataStoreProvider> provider) {
+        providerClass = provider;
+    }
+
+    /**
+     * Returns the data store provider, or {@code null} if none.
+     *
+     * @todo on the JDK9 branch, use the {@code ServiceLoader} API that allows us
+     *       to filter by class without instantiation.
+     */
+    final DataStoreProvider provider() throws InvalidOptionException {
+        if (providerClass != null) {
+            for (final DataStoreProvider provider : DataStores.providers()) {
+                if (providerClass.isInstance(provider)) {
+                    return provider;
+                }
+            }
+        }
+        return null;
+    }
+}

Propchange: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/OutputFormat.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/OutputFormat.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -58,7 +58,6 @@ import org.apache.sis.internal.util.X364
 import org.apache.sis.io.LineAppender;
 import org.apache.sis.io.TableAppender;
 import org.apache.sis.io.wkt.Colors;
-import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.io.wkt.Transliterator;
 import org.apache.sis.io.wkt.WKTFormat;
 import org.apache.sis.io.wkt.Warnings;
@@ -81,10 +80,10 @@ import org.apache.sis.util.CharSequences
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7
- * @version 0.7
+ * @version 0.8
  * @module
  */
-final class TransformCommand extends MetadataCommand {
+final class TransformCommand extends FormattedOutputCommand {
     /**
      * The coordinate operation from the given source CRS to target CRS.
      */
@@ -136,16 +135,19 @@ final class TransformCommand extends Met
     private NumberFormatException errorCause;
 
     /**
+     * Returns valid options for the {@code "transform"} commands.
+     */
+    private static EnumSet<Option> options() {
+        return EnumSet.of(Option.SOURCE_CRS, Option.TARGET_CRS, Option.VERBOSE,
+                Option.LOCALE, Option.TIMEZONE, Option.ENCODING, Option.COLORS, Option.HELP, Option.DEBUG);
+    }
+
+    /**
      * Creates the {@code "transform"} sub-command.
      */
     TransformCommand(final int commandIndex, final String... args) throws InvalidOptionException {
-        super(commandIndex, args, EnumSet.of(Option.SOURCE_CRS, Option.TARGET_CRS, Option.VERBOSE,
-                Option.LOCALE, Option.TIMEZONE, Option.ENCODING, Option.COLORS, Option.HELP, Option.DEBUG));
-
-        // Default output format for CRS.
-        outputFormat = Format.WKT;
-        convention   = Convention.WKT2_SIMPLIFIED;
-        resources    = Vocabulary.getResources(locale);
+        super(commandIndex, args, options(), OutputFormat.WKT, OutputFormat.TEXT);
+        resources = Vocabulary.getResources(locale);
     }
 
     /**
@@ -185,14 +187,11 @@ final class TransformCommand extends Met
 
     /**
      * Transforms coordinates from the files given in argument or from the standard input stream.
+     *
+     * @return 0 on success, or an exit code if the command failed for a reason other than an uncaught Java exception.
      */
     @Override
     public int run() throws Exception {
-        parseArguments();
-        if (outputFormat == Format.XML) {
-            final String format = outputFormat.name();
-            throw new InvalidOptionException(Errors.format(Errors.Keys.IncompatibleFormat_2, "transform", format), format);
-        }
         final CoordinateReferenceSystem sourceCRS = fetchCRS(Option.SOURCE_CRS);
         final CoordinateReferenceSystem targetCRS = fetchCRS(Option.TARGET_CRS);
         /*

Modified: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/package-info.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/package-info.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -48,7 +48,7 @@
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.7
+ * @version 0.8
  * @module
  */
 package org.apache.sis.console;

Modified: sis/branches/JDK8/application/sis-console/src/test/java/org/apache/sis/console/HelpCommandTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/test/java/org/apache/sis/console/HelpCommandTest.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/test/java/org/apache/sis/console/HelpCommandTest.java [UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/test/java/org/apache/sis/console/HelpCommandTest.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.console;
 
+import java.io.IOException;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
@@ -28,7 +29,7 @@ import static org.junit.Assert.*;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.8
  * @module
  */
 @DependsOn(CommandRunnerTest.class)
@@ -37,9 +38,10 @@ public final strictfp class HelpCommandT
      * Tests the sub-command without option.
      *
      * @throws InvalidOptionException should never happen.
+     * @throws IOException should never happen, because we are writing to a {@code PrintWriter}.
      */
     @Test
-    public void testDefault() throws InvalidOptionException {
+    public void testDefault() throws InvalidOptionException, IOException {
         final HelpCommand test = new HelpCommand(0, CommandRunner.TEST);
         test.run();
         final String result = test.outputBuffer.toString();
@@ -57,9 +59,10 @@ public final strictfp class HelpCommandT
      * Shall contain only a subset of {@link #testDefault()}.
      *
      * @throws InvalidOptionException should never happen.
+     * @throws IOException should never happen, because we are writing to a {@code PrintWriter}.
      */
     @Test
-    public void testHelp() throws InvalidOptionException {
+    public void testHelp() throws InvalidOptionException, IOException {
         final HelpCommand test = new HelpCommand(0, CommandRunner.TEST, "--help");
         test.help("help");
         final String result = test.outputBuffer.toString();
@@ -76,9 +79,10 @@ public final strictfp class HelpCommandT
      * Tests the sub-command with the {@code --locale en} option.
      *
      * @throws InvalidOptionException should never happen.
+     * @throws IOException should never happen, because we are writing to a {@code PrintWriter}.
      */
     @Test
-    public void testEnglishLocale() throws InvalidOptionException {
+    public void testEnglishLocale() throws InvalidOptionException, IOException {
         final HelpCommand test = new HelpCommand(0, CommandRunner.TEST, "--help", "--locale", "en");
         test.help("help");
         final String result = test.outputBuffer.toString();
@@ -90,9 +94,10 @@ public final strictfp class HelpCommandT
      * Tests the sub-command with the {@code --locale fr} option.
      *
      * @throws InvalidOptionException should never happen.
+     * @throws IOException should never happen, because we are writing to a {@code PrintWriter}.
      */
     @Test
-    public void testFrenchLocale() throws InvalidOptionException {
+    public void testFrenchLocale() throws InvalidOptionException, IOException {
         final HelpCommand test = new HelpCommand(0, CommandRunner.TEST, "--help", "--locale", "fr");
         test.help("help");
         final String result = test.outputBuffer.toString();

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -182,7 +182,7 @@ public class Range<E extends Comparable<
      * by the {@link #create(Comparable, boolean, Comparable, boolean)} method - otherwise we may
      * get an {@link ArrayStoreException}.
      */
-    @SuppressWarnings({"unchecked","rawtypes"}) // Generic array creation.
+    @SuppressWarnings({"unchecked","rawtypes"})                     // Generic array creation.
     Range<E>[] newArray(final int length) {
         return new Range[length];
     }

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/Version.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/Version.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/Version.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/Version.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -70,7 +70,9 @@ public class Version implements CharSequ
      */
     private static final Version[] CONSTANTS = {
         new Version("1"),
-        new Version("2")
+        new Version("2"),
+        new Version("1.0"),
+        new Version("1.1")
     };
 
     /**

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -378,7 +378,7 @@ public final class Errors extends Indexe
         public static final short IllegalUnicodeCodePoint_2 = 61;
 
         /**
-         * Can not use the “{1}” format with “{0}”.
+         * Can not use the {1} format with “{0}”.
          */
         public static final short IncompatibleFormat_2 = 62;
 

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] Wed Jan 25 08:40:16 2017
@@ -86,7 +86,7 @@ IllegalPropertyValueClass_2       = Prop
 IllegalPropertyValueClass_3       = Expected an instance of \u2018{1}\u2019 for the \u201c{0}\u201d property, but got an instance of \u2018{2}\u2019.
 IllegalRange_2                    = Range [{0} \u2026 {1}] is not valid.
 IllegalUnicodeCodePoint_2         = Value {1} for \u201c{0}\u201d is not a valid Unicode code point.
-IncompatibleFormat_2              = Can not use the \u201c{1}\u201d format with \u201c{0}\u201d.
+IncompatibleFormat_2              = Can not use the {1} format with \u201c{0}\u201d.
 IncompatiblePropertyValue_1       = Property \u201c{0}\u201d has an incompatible value.
 IncompatibleUnit_1                = Unit \u201c{0}\u201d is incompatible with current value.
 IncompatibleUnits_2               = Units \u201c{0}\u201d and \u201c{1}\u201d are incompatible.

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] Wed Jan 25 08:40:16 2017
@@ -83,7 +83,7 @@ IllegalPropertyValueClass_2       = La p
 IllegalPropertyValueClass_3       = Une instance \u2018{1}\u2019 \u00e9tait attendue pour la propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb, mais la valeur donn\u00e9e est une instance de \u2018{2}\u2019.
 IllegalRange_2                    = La plage [{0} \u2026 {1}] n\u2019est pas valide.
 IllegalUnicodeCodePoint_2         = La valeur {1} de \u00ab\u202f{0}\u202f\u00bb n\u2019est pas un code Unicode valide.
-IncompatibleFormat_2              = Le format \u00ab\u202f{1}\u202f\u00bb ne s\u2019applique pas \u00e0 \u00ab\u202f{0}\u202f\u00bb.
+IncompatibleFormat_2              = Le format {1} ne s\u2019applique pas \u00e0 \u00ab\u202f{0}\u202f\u00bb.
 IncompatiblePropertyValue_1       = La valeur de la propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb n\u2019est pas compatible.
 IncompatibleUnit_1                = L\u2019unit\u00e9 \u00ab\u202f{0}\u202f\u00bb n\u2019est pas compatible avec la valeur actuelle.
 IncompatibleUnits_2               = Les unit\u00e9s \u00ab\u202f{0}\u202f\u00bb et \u00ab\u202f{1}\u202f\u00bb ne sont pas compatibles.

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/FeatureStore.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/FeatureStore.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/FeatureStore.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/FeatureStore.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -84,6 +84,8 @@ public abstract class FeatureStore exten
      *
      * @return a stream over all features in the data store.
      * @throws DataStoreException if an error occurred while creating the feature stream.
+     *
+     * @todo a future version of this method will take some kind of {@code Query} or {@code Filter} argument.
      */
-    public abstract Stream<Feature> getFeatures() throws DataStoreException;
+    public abstract Stream<Feature> features() throws DataStoreException;
 }

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -500,8 +500,10 @@ public final class Store extends Feature
             } catch (TransformException e) {
                 throw new DataStoreReferencingException(getLocale(), "CSV", getDisplayName(), source).initCause(e);
             } catch (UnsupportedOperationException e) {
-                // Failed to set the temporal components if the sis-temporal module was
-                // not on the classpath, but the other dimensions still have been set.
+                /*
+                 * Failed to set the temporal components if the sis-temporal module was
+                 * not on the classpath, but the other dimensions still have been set.
+                 */
                 listeners.warning(null, e);
             }
             builder.add(featureType, null);
@@ -543,12 +545,12 @@ public final class Store extends Feature
      * @todo Needs to reset the position when doing another pass on the features.
      */
     @Override
-    public Stream<Feature> getFeatures() {
+    public Stream<Feature> features() {
         return StreamSupport.stream(new Iter(), false);
     }
 
     /**
-     * Implementation of the iterator returned by {@link #getFeatures()}.
+     * Implementation of the iterator returned by {@link #features()}.
      */
     private final class Iter implements Spliterator<Feature> {
         /**
@@ -702,11 +704,17 @@ public final class Store extends Feature
         }
 
         /**
-         * Guarantees that we will not return null element.
+         * Returns the characteristics of the iteration over feature instances.
+         * The iteration is assumed {@link #ORDERED} in the declaration order in the CSV file.
+         * The iteration is {@link #NONNULL} (i.e. {@link #tryAdvance(Consumer)} is not allowed
+         * to return null value) and {@link #IMMUTABLE} (i.e. we do not support modification of
+         * the CSV file while an iteration is in progress).
+         *
+         * @return characteristics of iteration over the features in the CSV file.
          */
         @Override
         public int characteristics() {
-            return NONNULL;
+            return ORDERED | NONNULL | IMMUTABLE;
         }
     }
 

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -20,6 +20,8 @@ import org.opengis.metadata.distribution
 import org.apache.sis.internal.simple.SimpleFormat;
 import org.apache.sis.metadata.iso.citation.DefaultCitation;
 import org.apache.sis.metadata.iso.distribution.DefaultFormat;
+import org.apache.sis.measure.Range;
+import org.apache.sis.util.Version;
 
 
 /**
@@ -117,6 +119,17 @@ public abstract class DataStoreProvider
     }
 
     /**
+     * Returns the range of versions supported by the data store, or {@code null} if unspecified.
+     *
+     * @return the range of supported versions, or {@code null} if unspecified.
+     *
+     * @since 0.8
+     */
+    public Range<Version> getSupportedVersions() {
+        return null;
+    }
+
+    /**
      * Indicates if the given storage appears to be supported by the {@code DataStore}s created by this provider.
      * The most typical return values are:
      *

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -208,18 +208,18 @@ final class DataStoreRegistry {
              */
             if (deferred != null) {
 search:         while (!deferred.isEmpty() && connector.prefetch()) {
-                    for (final Iterator<ProbeProviderPair> it=deferred.iterator(); it.hasNext();) {
+                    for (final Iterator<ProbeProviderPair> it = deferred.iterator(); it.hasNext();) {
                         final ProbeProviderPair p = it.next();
-                        p.probe = provider.probeContent(connector);
+                        p.probe = p.provider.probeContent(connector);
                         if (p.probe.isSupported()) {
                             selected = p;
                             break search;
                         }
                         if (!ProbeResult.INSUFFICIENT_BYTES.equals(p.probe)) {
                             if (ProbeResult.UNDETERMINED.equals(p.probe)) {
-                                selected = p; // To be used only if we don't find a better match.
+                                selected = p;                   // To be used only if we don't find a better match.
                             }
-                            it.remove(); // UNSUPPORTED_* or UNDETERMINED: do not try again those providers.
+                            it.remove();        // UNSUPPORTED_* or UNDETERMINED: do not try again those providers.
                         }
                     }
                 }
@@ -233,7 +233,7 @@ search:         while (!deferred.isEmpty
              */
             if (open && selected != null) {
                 selected.store = selected.provider.open(connector);
-                connector = null; // For preventing it to be closed.
+                connector = null;                                               // For preventing it to be closed.
             }
         } finally {
             if (connector != null && connector != storage) {

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -80,7 +80,7 @@ public final class DataStores extends St
 
     /**
      * Returns the list of data store providers available at this method invocation time.
-     * More providers may be added later if new modules are added on the classpath.
+     * More providers may be added later in a running JVM if new modules are added on the classpath.
      *
      * @return descriptions of available data stores.
      *

Modified: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -90,7 +90,7 @@ public final strictfp class StoreTest ex
     }
 
     /**
-     * Verifies the feature type, then tests {@link Store#getFeatures()}.
+     * Verifies the feature type, then tests {@link Store#features()}.
      *
      * @throws DataStoreException if an error occurred while parsing the data.
      */
@@ -99,7 +99,7 @@ public final strictfp class StoreTest ex
         try (Store store = new Store(null, new StorageConnector(testData()))) {
             verifyFeatureType(store.featureType);
             assertEquals("foliation", Foliation.TIME, store.foliation);
-            final Iterator<Feature> it = store.getFeatures().iterator();
+            final Iterator<Feature> it = store.features().iterator();
             assertPropertyEquals(it.next(), "a", "12:33:51", "12:36:11", new double[] {11, 2, 12, 3},        "walking", 1);
             assertPropertyEquals(it.next(), "b", "12:33:51", "12:36:51", new double[] {10, 2, 11, 3},        "walking", 2);
             assertPropertyEquals(it.next(), "a", "12:36:11", "12:36:51", new double[] {12, 3, 10, 3},        "walking", 2);

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Reader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Reader.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Reader.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Reader.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -163,16 +163,16 @@ final class Reader extends StaxStreamRea
         Version version = null;
         if (ver != null) {
             version = new Version(ver);
-            if (version.compareTo(Store.V1_0, 2) < 0 ||
-                version.compareTo(Store.V1_1, 2) > 0)
+            if (version.compareTo(StoreProvider.V1_0, 2) < 0 ||
+                version.compareTo(StoreProvider.V1_1, 2) > 0)
             {
                 throw new DataStoreContentException(errors().getString(
                         Errors.Keys.UnsupportedFormatVersion_2, owner.getFormatName(), version));
             }
         } else if (namespace != null) {
             switch (namespace) {
-                case Tags.NAMESPACE_V10: version = Store.V1_0; break;
-                case Tags.NAMESPACE_V11: version = Store.V1_1; break;
+                case Tags.NAMESPACE_V10: version = StoreProvider.V1_0; break;
+                case Tags.NAMESPACE_V11: version = StoreProvider.V1_1; break;
             }
         }
         /*

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Store.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Store.java?rev=1780148&r1=1780147&r2=1780148&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Store.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Store.java [UTF-8] Wed Jan 25 08:40:16 2017
@@ -51,16 +51,6 @@ import org.opengis.feature.FeatureType;
  */
 public final class Store extends StaxDataStore {
     /**
-     * The "1.0" version.
-     */
-    static final Version V1_0 = new Version("1.0");
-
-    /**
-     * The "1.1" version.
-     */
-    static final Version V1_1 = new Version("1.1");
-
-    /**
      * Version of the GPX file, or {@code null} if unknown.
      */
     Version version;
@@ -150,9 +140,9 @@ public final class Store extends StaxDat
     @Override
     public synchronized Metadata getMetadata() throws DataStoreException {
         if (metadata == null) try {
-            reader      = new Reader(this);
-            version     = reader.initialize(true);
-            metadata    = reader.getMetadata();
+            reader   = new Reader(this);
+            version  = reader.initialize(true);
+            metadata = reader.getMetadata();
         } catch (DataStoreException e) {
             throw e;
         } catch (URISyntaxException | RuntimeException e) {
@@ -179,11 +169,11 @@ public final class Store extends StaxDat
     /**
      * Returns the stream of features.
      *
-     * @return a stream over all features in the CSV file.
+     * @return a stream over all features in the XML file.
      * @throws DataStoreException if an error occurred while creating the feature stream.
      */
     @Override
-    public synchronized Stream<Feature> getFeatures() throws DataStoreException {
+    public synchronized Stream<Feature> features() throws DataStoreException {
         Reader r = reader;
         reader = null;
         if (r == null) try {



Mime
View raw message