Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
 [ISO-8859-1] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
 [ISO-8859-1] Sat Feb 24 15:44:08 2018
@@ -25,29 +25,43 @@
 #   U+00A0 NO-BREAK SPACE         before  :
 #
 AmbiguousName_4                   = Le nom \u00ab\u202f{3}\u202f\u00bb est 
ambigu\u00eb car il peut \u00eatre interpr\u00e9t\u00e9 aussi bien comme 
\u00ab\u202f{1}\u202f\u00bb ou \u00ab\u202f{2}\u202f\u00bb dans le contexte des 
donn\u00e9es de \u00ab\u202f{0}\u202f\u00bb.
+CanNotCreateFolderStore_1         = Ne peut pas cr\u00e9er des ressources 
bas\u00e9es sur le contenu du r\u00e9pertoire \u00ab\u202f{0}\u202f\u00bb.
+CanNotGetCommonMetadata_2         = Ne peut pas obtenir les 
m\u00e9ta-donn\u00e9es communes aux fichiers \u00ab\u202f{0}\u202f\u00bb. La 
raison est\u2008: {1}
 CanNotReadCRS_WKT_1               = Ne peut pas lire le syst\u00e8me de 
r\u00e9f\u00e9rence spatial dans le \u00ab\u202fWell Known Text\u202f\u00bb 
(WKT) de \u00ab\u202f{0}\u202f\u00bb.
 CanNotReadDirectory_1             = Ne peut pas lire le r\u00e9pertoire 
\u00ab\u202f{0}\u202f\u00bb.
 CanNotReadFile_2                  = Ne peut pas lire 
\u00ab\u202f{1}\u202f\u00bb comme un fichier au format {0}.
 CanNotReadFile_3                  = Ne peut pas lire la ligne {2} de 
\u00ab\u202f{1}\u202f\u00bb comme une partie d\u2019un fichier au format {0}.
 CanNotReadFile_4                  = Ne peut pas lire la ligne {2} (apr\u00e8s 
la colonne {3}) de \u00ab\u202f{1}\u202f\u00bb comme une partie d\u2019un 
fichier au format {0}.
+CanNotRemoveResource_2            = Ne peut pas supprimer la ressource 
\u00ab\u202f{1}\u202f\u00bb de l\u2019agr\u00e9gat \u00ab\u202f{0}\u202f\u00bb.
+CanNotStoreResourceType_2         = Ne peut pas enregistrer des ressources de 
type \u2018{1}\u2019 dans un entrep\u00f4t de donn\u00e9es 
\u00ab\u202f{0}\u202f\u00bb.
 ClosedReader_1                    = Ce lecteur {0} est ferm\u00e9.
 ClosedWriter_1                    = Cet encodeur {0} est ferm\u00e9.
 ConcurrentRead_1                  = Une ou plusieurs op\u00e9rations de 
lecture sont en cours sur les donn\u00e9es de \u00ab\u202f{0}\u202f\u00bb.
 ConcurrentWrite_1                 = Une op\u00e9ration d\u2019\u00e9criture 
est en cours sur les donn\u00e9es de \u00ab\u202f{0}\u202f\u00bb.
+DataStoreCreate                   = Indique si l\u2019on autorise la 
cr\u00e9ation d\u2019une nouvelle source de donn\u00e9es si la source \u00e0 
ouvrir n\u2019existe pas d\u00e9j\u00e0.
 DataStoreEncoding                 = Encodage des caract\u00e8res utilis\u00e9 
par la source de donn\u00e9es.
 DataStoreLocale                   = Conventions d\u2019\u00e9criture des dates 
et des nombres.
 DataStoreLocation                 = Chemin (fichier ou URL) vers la source de 
donn\u00e9es.
 DataStoreTimeZone                 = Fuseau horaire des dates dans les 
donn\u00e9es.
 DirectoryContent_1                = Contenu du r\u00e9pertoire 
\u00ab\u202f{0}\u202f\u00bb.
+DirectoryContentFormatName        = Nom du format ou de la source de 
donn\u00e9es \u00e0 utiliser pour lire ou \u00e9crire le contenu du 
r\u00e9pertoire.
 ExcessiveStringSize_3             = La cha\u00eene de caract\u00e8res dans le 
fichier \u00ab\u202f{0}\u202f\u00bb est trop longue. La cha\u00eene fait {2} 
caract\u00e8res alors que la limite est {1}.
 FeatureAlreadyPresent_2           = Une entit\u00e9 nomm\u00e9e 
\u00ab\u202f{1}\u202f\u00bb est d\u00e9j\u00e0 pr\u00e9sente dans les 
donn\u00e9es de \u00ab\u202f{0}\u202f\u00bb.
-FeatureNotFound_2                 = L\u2019entit\u00e9 
\u00ab\u202f{1}\u202f\u00bb n\u2019est pas \u00e9t\u00e9 trouv\u00e9e dans les 
donn\u00e9es de \u00ab\u202f{0}\u202f\u00bb.
+FeatureNotFound_2                 = L\u2019entit\u00e9 
\u00ab\u202f{1}\u202f\u00bb n\u2019a pas \u00e9t\u00e9 trouv\u00e9e dans les 
donn\u00e9es de \u00ab\u202f{0}\u202f\u00bb.
+FileAlreadyExists_2               = Un {1,choice,0#fichier|1#r\u00e9pertoire} 
existe d\u00e9j\u00e0 \u00e0 l\u2019emplacement \u00ab\u202f{0}\u202f\u00bb.
+FileIsNotAResourceDirectory_1     = Le fichier \u00ab\u202f{0}\u202f\u00bb 
n\u2019est pas un r\u00e9pertoire de ressources.
+FoliationRepresentation           = Indique s\u2019il faut assembler les 
fragments de trajectoires (lignes dans un fichier CSV) dans une entit\u00e9 
unique.
 IllegalFeatureType_2              = Le format {0} ne stocke pas de 
donn\u00e9es de type \u00ab\u202f{1}\u202f\u00bb.
 IllegalInputTypeForReader_2       = Le lecteur {0} n\u2019accepte pas des 
entr\u00e9s de type \u2018{1}\u2019.
-IllegalOutputTypeForWriter_2      = Le l\u2019encodeur {0} n\u2019accepte pas 
des sorties de type \u2018{1}\u2019.
+IllegalOutputTypeForWriter_2      = L\u2019encodeur {0} n\u2019accepte pas des 
sorties de type \u2018{1}\u2019.
 InconsistentNameComponents_2      = Les \u00e9l\u00e9ments qui composent le 
nom \u00ab\u202f{1}\u202f\u00bb ne sont pas coh\u00e9rents avec ceux du nom qui 
avait \u00e9t\u00e9 pr\u00e9c\u00e9demment li\u00e9 dans les donn\u00e9es de 
\u00ab\u202f{0}\u202f\u00bb.
+MissingResourceIdentifier_1       = La ressource \u00ab\u202f{0}\u202f\u00bb 
n\u2019a pas d\u2019identifiant.
 MissingSchemeInURI_1              = Il manque le sch\u00e9ma dans l\u2019URI 
\u00ab\u202f{0}\u202f\u00bb.
+NoSuchResourceDirectory_1         = Aucun r\u00e9pertoire de ressources 
n\u2019a \u00e9t\u00e9 trouv\u00e9 \u00e0 l\u2019emplacement 
\u00ab\u202f{0}\u202f\u00bb.
+NoSuchResourceInAggregate_2       = La ressource \u00ab\u202f{1}\u202f\u00bb 
n\u2019est pas une partie de l\u2019agr\u00e9gat \u00ab\u202f{0}\u202f\u00bb.
+NotAWritableFeatureSet_1          = La ressource \u00ab\u202f{0}\u202f\u00bb 
n\u2019est pas un ensemble d\u2019entit\u00e9s accessibles en \u00e9criture.
 ProcessingExecutedOn_1            = Traitement ex\u00e9cut\u00e9 sur {0}.
+ResourceAlreadyExists_1           = Une ressource existe d\u00e9j\u00e0 \u00e0 
l\u2019emplacement \u00ab\u202f{0}\u202f\u00bb.
 ResourceIdentifierCollision_2     = Plusieurs ressources utilisent 
l\u2019identifiant \u00ab\u202f{1}\u202f\u00bb dans les donn\u00e9es de 
\u00ab\u202f{0}\u202f\u00bb.
 ResourceNotFound_2                = Aucune ressource n\u2019a \u00e9t\u00e9 
trouv\u00e9e pour l\u2019identifiant \u00ab\u202f{1}\u202f\u00bb dans les 
donn\u00e9es de \u00ab\u202f{0}\u202f\u00bb.
 ShallBeDeclaredBefore_2           = L\u2019\u00e9l\u00e9ment 
\u00ab\u202f{1}\u202f\u00bb doit \u00eatre d\u00e9clar\u00e9 avant 
\u00ab\u202f{0}\u202f\u00bb.

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -17,14 +17,17 @@
 package org.apache.sis.internal.storage;
 
 import java.net.URI;
+import java.nio.charset.Charset;
+import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.parameter.ParameterDescriptorGroup;
-import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.ParameterNotFoundException;
 import org.apache.sis.parameter.ParameterBuilder;
+import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreProvider;
 import org.apache.sis.storage.DataStoreException;
-import org.apache.sis.storage.StorageConnector;
+import org.apache.sis.storage.IllegalOpenParameterException;
 import org.apache.sis.internal.storage.io.IOUtilities;
 
 
@@ -35,7 +38,7 @@ import org.apache.sis.internal.storage.i
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.8
  * @module
  */
@@ -69,12 +72,12 @@ public abstract class URIDataStore exten
 
     /**
      * Creates parameter value group for the current location, if non-null.
-     * This convenience method is used for public {@code DataStore} 
implementations that can not extend
-     * {@code URIDataStore} directly, because this class is internal.
+     * This convenience method is used for {@link 
DataStore#getOpenParameters()} implementations in public
+     * {@code DataStore} that can not extend {@code URIDataStore} directly, 
because this class is internal.
      *
-     * @param provider
-     * @param location
-     * @return
+     * @param  provider  the provider of the data store for which to get open 
parameters.
+     * @param  location  file opened by the data store.
+     * @return parameters to be returned by {@link 
DataStore#getOpenParameters()}.
      *
      * @todo Verify if non-exported classes in JDK9 are hidden from Javadoc, 
like package-private classes.
      *       If true, we could remove this hack and extend {@code 
URIDataStore} even in public classes.
@@ -91,19 +94,35 @@ public abstract class URIDataStore exten
      *
      * @author  Johann Sorel (Geomatys)
      * @author  Martin Desruisseaux (Geomatys)
-     * @version 0.8
+     * @version 1.0
      * @since   0.8
      * @module
      */
     public abstract static class Provider extends DataStoreProvider {
         /**
-         * Description of the location parameter.
+         * Description of the {@value #LOCATION} parameter.
+         */
+        public static final ParameterDescriptor<URI> LOCATION_PARAM;
+
+        /**
+         * Description of the optional {@value #CREATE} parameter, which may 
be present in writable data store.
+         * This parameter is not included in the descriptor created by {@link 
#build(ParameterBuilder)} default
+         * implementation. It is subclass responsibility to add it if desired, 
only if supported.
+         */
+        public static final ParameterDescriptor<Boolean> CREATE_PARAM;
+
+        /**
+         * Description of the optional parameter for character encoding used 
by the data store.
+         * This parameter is not included in the descriptor created by {@link 
#build(ParameterBuilder)}
+         * default implementation. It is subclass responsibility to add it if 
desired.
          */
-        public static final ParameterDescriptor<URI> LOCATION_PARAM = new 
ParameterBuilder()
-                
.setDescription(Resources.formatInternational(Resources.Keys.DataStoreLocation))
-                .addName(LOCATION)
-                .setRequired(true)
-                .create(URI.class, null);
+        public static final ParameterDescriptor<Charset> ENCODING;
+        static {
+            final ParameterBuilder builder = new ParameterBuilder();
+            ENCODING       = 
builder.addName("encoding").setDescription(Resources.formatInternational(Resources.Keys.DataStoreEncoding)).create(Charset.class,
 null);
+            CREATE_PARAM   = builder.addName( CREATE   
).setDescription(Resources.formatInternational(Resources.Keys.DataStoreCreate  
)).create(Boolean.class, null);
+            LOCATION_PARAM = builder.addName( LOCATION 
).setDescription(Resources.formatInternational(Resources.Keys.DataStoreLocation)).setRequired(true).create(URI.class,
 null);
+        }
 
         /**
          * The parameter descriptor to be returned by {@link 
#getOpenParameters()}.
@@ -161,12 +180,39 @@ public abstract class URIDataStore exten
         public static ParameterDescriptorGroup descriptor(final String name) {
             return new 
ParameterBuilder().addName(name).createGroup(LOCATION_PARAM);
         }
+
+        /**
+         * Creates a storage connector initialized to the location declared in 
given parameters.
+         * This convenience method does not set any other parameters.
+         * In particular, reading (or ignoring) the {@value #CREATE} parameter 
is left to callers,
+         * because not all implementations may create data stores with {@link 
java.nio.file.StandardOpenOption}.
+         *
+         * @param  provider    the provider for which to create a storage 
connector (for error messages).
+         * @param  parameters  the parameters to use for creating a storage 
connector.
+         * @return the storage connector initialized to the location specified 
in the parameters.
+         * @throws IllegalOpenParameterException if no {@value #LOCATION} 
parameter has been found.
+         */
+        public static StorageConnector connector(final DataStoreProvider 
provider, final ParameterValueGroup parameters)
+                throws IllegalOpenParameterException
+        {
+            ParameterNotFoundException cause = null;
+            if (parameters != null) try {
+                final Object location = 
parameters.parameter(LOCATION).getValue();
+                if (location != null) {
+                    return new StorageConnector(location);
+                }
+            } catch (ParameterNotFoundException e) {
+                cause = e;
+            }
+            throw new 
IllegalOpenParameterException(Resources.format(Resources.Keys.UndefinedParameter_2,
+                        provider.getShortName(), LOCATION), cause);
+        }
     }
 
     /**
      * Adds the filename (without extension) as the citation title if there is 
no title, or as the identifier otherwise.
      * This method should be invoked last, after {@code DataStore} 
implementation did its best effort for adding a title.
-     * The intend is actually to provide an identifier, but since the title is 
mandatory in ISO 19115 metadata, providing
+     * The intent is actually to provide an identifier, but since the title is 
mandatory in ISO 19115 metadata, providing
      * only an identifier without title would be invalid.
      *
      * @param  builder  where to add the title or identifier.

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -17,16 +17,16 @@
 package org.apache.sis.internal.storage.csv;
 
 import java.util.Collection;
+import java.util.Spliterator;
+import java.util.function.Consumer;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.time.DateTimeException;
 import java.io.IOException;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.util.ObjectConverters;
 import org.apache.sis.util.collection.BackingStoreException;
 
 // Branch-dependent imports
-import java.util.Spliterator;
-import java.util.function.Consumer;
-import java.time.DateTimeException;
 import org.opengis.feature.Feature;
 import org.opengis.feature.PropertyType;
 import org.opengis.feature.AttributeType;
@@ -121,7 +121,7 @@ class FeatureIterator implements Spliter
                     /*
                      * If there is no time columns, then this column may be 
the trajectory (note that allowing
                      * CSV files without time is obviously a departure from 
Moving Features specification.
-                     * The intend is to have a CSV format applicable to other 
features than moving ones).
+                     * The intent is to have a CSV format applicable to other 
features than moving ones).
                      * Fall through in order to process trajectory.
                      */
                 }

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/MovingFeatureIterator.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/MovingFeatureIterator.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/MovingFeatureIterator.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/MovingFeatureIterator.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -18,14 +18,14 @@ package org.apache.sis.internal.storage.
 
 import java.util.Map;
 import java.util.LinkedHashMap;
+import java.util.function.Consumer;
 import java.util.logging.LogRecord;
+import java.time.Instant;
+import java.time.DateTimeException;
 import java.io.IOException;
 import org.apache.sis.internal.feature.MovingFeature;
 
 // Branch-dependent imports
-import java.time.Instant;
-import java.time.DateTimeException;
-import java.util.function.Consumer;
 import org.opengis.feature.Attribute;
 import org.opengis.feature.Feature;
 

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -21,8 +21,12 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
 import java.util.Locale;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
+import java.time.Instant;
+import java.time.DateTimeException;
 import java.io.Reader;
 import java.io.BufferedReader;
 import java.io.LineNumberReader;
@@ -40,6 +44,7 @@ import org.opengis.referencing.crs.Tempo
 import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.feature.DefaultAttributeType;
 import org.apache.sis.feature.DefaultFeatureType;
+import org.apache.sis.feature.FoliationRepresentation;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.internal.referencing.GeodeticObjectBuilder;
@@ -55,6 +60,7 @@ import org.apache.sis.geometry.GeneralEn
 import org.apache.sis.geometry.ImmutableEnvelope;
 import org.apache.sis.metadata.iso.DefaultMetadata;
 import org.apache.sis.metadata.sql.MetadataStoreException;
+import org.apache.sis.storage.DataOptionKey;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreContentException;
 import org.apache.sis.storage.DataStoreReferencingException;
@@ -69,10 +75,6 @@ import org.apache.sis.io.InvalidSeekExce
 import org.apache.sis.measure.Units;
 
 // Branch-dependent imports
-import java.time.Instant;
-import java.time.DateTimeException;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
 import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureType;
 import org.opengis.feature.PropertyType;
@@ -84,7 +86,7 @@ import org.opengis.feature.AttributeType
  * See package javadoc for more information on the syntax.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.7
  * @module
  */
@@ -227,12 +229,9 @@ final class Store extends URIDataStore i
      *
      * @param  provider   the factory that created this {@code DataStore} 
instance, or {@code null} if unspecified.
      * @param  connector  information about the storage (URL, stream, 
<i>etc</i>).
-     * @param  immediate  {@code true} for forcing the creation of a distinct 
{@code Feature} instance for each line.
      * @throws DataStoreException if an error occurred while opening the 
stream.
      */
-    public Store(final StoreProvider provider, final StorageConnector 
connector, final boolean immediate)
-            throws DataStoreException
-    {
+    public Store(final StoreProvider provider, final StorageConnector 
connector) throws DataStoreException {
         super(provider, connector);
         final Reader r = connector.getStorageAs(Reader.class);
         connector.closeAllExcept(r);
@@ -242,7 +241,7 @@ final class Store extends URIDataStore i
         }
         source     = (r instanceof BufferedReader) ? (BufferedReader) r : new 
LineNumberReader(r);
         geometries = 
Geometries.implementation(connector.getOption(OptionKey.GEOMETRY_LIBRARY));
-        dissociate = immediate;
+        dissociate = 
FoliationRepresentation.FRAGMENTED.equals(connector.getOption(DataOptionKey.FOLIATION_REPRESENTATION));
         GeneralEnvelope envelope    = null;
         FeatureType     featureType = null;
         Foliation       foliation   = null;

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -16,14 +16,23 @@
  */
 package org.apache.sis.internal.storage.csv;
 
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.apache.sis.parameter.ParameterBuilder;
+import org.apache.sis.parameter.Parameters;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.DataOptionKey;
 import org.apache.sis.storage.ProbeResult;
 import org.apache.sis.storage.StorageConnector;
+import org.apache.sis.feature.FoliationRepresentation;
+import org.apache.sis.internal.storage.Resources;
 import org.apache.sis.internal.storage.Capability;
-import org.apache.sis.internal.storage.Capabilities;
+import org.apache.sis.internal.storage.StoreMetadata;
 import org.apache.sis.internal.storage.URIDataStore;
 import org.apache.sis.internal.storage.wkt.FirstKeywordPeek;
+import org.apache.sis.util.ArgumentChecks;
 
 
 /**
@@ -35,11 +44,13 @@ import org.apache.sis.internal.storage.w
  * the part of the caller. However the {@link Store} instances created by this 
factory are not thread-safe.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.8
  * @module
  */
-@Capabilities(Capability.READ)
+@StoreMetadata(formatName   = StoreProvider.NAME,
+               fileSuffixes = "csv",
+               capabilities = Capability.READ)
 public final class StoreProvider extends URIDataStore.Provider {
     /**
      * The format names for static features and moving features.
@@ -101,6 +112,19 @@ public final class StoreProvider extends
     }
 
     /**
+     * Description of the optional parameter for specifying whether the reader 
should assemble distinct CSV lines
+     * into a single {@code Feature} instance forming a foliation. This is 
ignored if the CSV file does not seem
+     * to contain moving features.
+     */
+    private static final ParameterDescriptor<FoliationRepresentation> 
FOLIATION;
+    static {
+        final ParameterBuilder builder = new ParameterBuilder();
+        FOLIATION = builder.addName("foliation")
+                
.setDescription(Resources.formatInternational(Resources.Keys.FoliationRepresentation))
+                .create(FoliationRepresentation.class, 
FoliationRepresentation.ASSEMBLED);
+    }
+
+    /**
      * Creates a new provider.
      */
     public StoreProvider() {
@@ -138,6 +162,32 @@ public final class StoreProvider extends
      */
     @Override
     public DataStore open(final StorageConnector connector) throws 
DataStoreException {
-        return new Store(this, connector, false);
+        return new Store(this, connector);
+    }
+
+    /**
+     * Returns a CSV {@link Store} implementation from the given parameters.
+     *
+     * @return a data store implementation associated with this provider for 
the given parameters.
+     * @throws DataStoreException if an error occurred while creating the data 
store instance.
+     */
+    @Override
+    public DataStore open(final ParameterValueGroup parameters) throws 
DataStoreException {
+        ArgumentChecks.ensureNonNull("parameter", parameters);
+        final StorageConnector connector = connector(this, parameters);
+        final Parameters pg = Parameters.castOrWrap(parameters);
+        connector.setOption(DataOptionKey.ENCODING, pg.getValue(ENCODING));
+        connector.setOption(DataOptionKey.FOLIATION_REPRESENTATION, 
pg.getValue(FOLIATION));
+        return new Store(this, connector);
+    }
+
+    /**
+     * Invoked by {@link #getOpenParameters()} the first time that a parameter 
descriptor needs to be created.
+     *
+     * @return the parameters descriptor for CSV files.
+     */
+    @Override
+    protected ParameterDescriptorGroup build(final ParameterBuilder builder) {
+        return builder.createGroup(LOCATION_PARAM, ENCODING, FOLIATION);
     }
 }

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/TimeEncoding.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/TimeEncoding.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/TimeEncoding.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/TimeEncoding.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.internal.storage.csv;
 
+import java.time.Instant;
 import javax.measure.Unit;
 import javax.measure.quantity.Time;
 import org.opengis.referencing.datum.TemporalDatum;
@@ -24,9 +25,6 @@ import org.apache.sis.internal.util.Stan
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.measure.Units;
 
-// Branch-dependent imports
-import java.time.Instant;
-
 
 /**
  * Specifies how time is encoded in the CSV file.

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/package-info.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/package-info.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/package-info.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/package-info.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -53,7 +53,7 @@
  * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.7
  * @module
  */

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/FolderStoreProvider.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/FolderStoreProvider.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/FolderStoreProvider.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/FolderStoreProvider.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -16,18 +16,21 @@
  */
 package org.apache.sis.internal.storage.folder;
 
-import java.io.IOException;
+import java.util.EnumSet;
 import java.util.Locale;
 import java.util.TimeZone;
+import java.io.IOException;
 import java.nio.charset.Charset;
-import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.Files;
+import java.nio.file.FileAlreadyExistsException;
 import java.nio.file.FileSystemNotFoundException;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.StandardOpenOption;
 import org.opengis.util.InternationalString;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.parameter.ParameterDescriptorGroup;
-import org.opengis.parameter.ParameterNotFoundException;
 import org.apache.sis.parameter.ParameterBuilder;
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.storage.DataStore;
@@ -35,12 +38,14 @@ import org.apache.sis.storage.DataStoreP
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.storage.ProbeResult;
-import org.apache.sis.storage.IllegalOpenParameterException;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.storage.Resources;
 import org.apache.sis.internal.storage.URIDataStore;
+import org.apache.sis.internal.storage.Capability;
+import org.apache.sis.internal.storage.StoreMetadata;
+import org.apache.sis.internal.storage.StoreUtilities;
 import org.apache.sis.setup.OptionKey;
 
 
@@ -51,15 +56,16 @@ import org.apache.sis.setup.OptionKey;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.8
  * @module
  */
+@StoreMetadata(formatName=FolderStoreProvider.NAME, 
capabilities={Capability.READ, Capability.WRITE})
 public final class FolderStoreProvider extends DataStoreProvider {
     /**
      * A short name or abbreviation for the data format.
      */
-    private static final String NAME = "folder";
+    static final String NAME = "folder";
 
     /**
      * Description of the parameter for formating conventions of dates and 
numbers.
@@ -77,6 +83,12 @@ public final class FolderStoreProvider e
     private static final ParameterDescriptor<Charset> ENCODING;
 
     /**
+     * Description of the parameter for name of format or {@code 
DataStoreProvider}
+     * to use for reading or writing the directory content.
+     */
+    private static final ParameterDescriptor<String> FORMAT;
+
+    /**
      * The group of parameter descriptors to be returned by {@link 
#getOpenParameters()}.
      */
     static final ParameterDescriptorGroup PARAMETERS;
@@ -84,17 +96,23 @@ public final class FolderStoreProvider e
         final ParameterDescriptor<Path> location;
         final ParameterBuilder builder = new ParameterBuilder();
         final InternationalString remark = 
Resources.formatInternational(Resources.Keys.UsedOnlyIfNotEncoded);
+        ENCODING   = annotate(builder, URIDataStore.Provider.ENCODING, remark);
         LOCALE     = builder.addName("locale"  
).setDescription(Resources.formatInternational(Resources.Keys.DataStoreLocale  
)).setRemarks(remark).create(Locale.class,   null);
         TIMEZONE   = 
builder.addName("timezone").setDescription(Resources.formatInternational(Resources.Keys.DataStoreTimeZone)).setRemarks(remark).create(TimeZone.class,
 null);
-        ENCODING   = 
builder.addName("encoding").setDescription(Resources.formatInternational(Resources.Keys.DataStoreEncoding)).setRemarks(remark).create(Charset.class,
  null);
-        location   = builder.addName( LOCATION 
).setDescription(URIDataStore.Provider.LOCATION_PARAM.getDescription())         
 .setRequired(true) .create(Path.class,     null);
-        PARAMETERS = builder.addName( NAME     ).createGroup(location, LOCALE, 
TIMEZONE, ENCODING);
+        FORMAT     = builder.addName("format"  
).setDescription(Resources.formatInternational(Resources.Keys.DirectoryContentFormatName)).create(String.class,
 null);
+        location   = new 
ParameterBuilder(URIDataStore.Provider.LOCATION_PARAM).create(Path.class, null);
+        PARAMETERS = builder.addName(NAME).createGroup(location, LOCALE, 
TIMEZONE, ENCODING, FORMAT, URIDataStore.Provider.CREATE_PARAM);
+    }
+
+    /**
+     * Creates a parameter descriptor equals to the given one except for the 
remarks which are set to the given value.
+     */
+    private static <T> ParameterDescriptor<T> annotate(ParameterBuilder 
builder, ParameterDescriptor<T> e, InternationalString remark) {
+        return 
builder.addName(e.getName()).setDescription(e.getDescription()).setRemarks(remark).create(e.getValueClass(),
 null);
     }
 
     /**
      * The unique instance of this provider.
-     *
-     * @see #open(Path)
      */
     public static final FolderStoreProvider INSTANCE = new 
FolderStoreProvider();
 
@@ -149,6 +167,8 @@ public final class FolderStoreProvider e
 
     /**
      * Returns a data store implementation associated with this provider.
+     * The data store created by this method will try to auto-detect the 
format of every files in the directory.
+     * For exploring only the file of a known format, use {@link 
#open(ParameterValueGroup)} instead.
      *
      * @param  connector  information about the storage (URL, path, 
<i>etc</i>).
      * @return a data store implementation associated with this provider for 
the given storage.
@@ -156,12 +176,89 @@ public final class FolderStoreProvider e
      */
     @Override
     public DataStore open(final StorageConnector connector) throws 
DataStoreException {
+        return open(connector, null, EnumSet.noneOf(StandardOpenOption.class));
+    }
+
+    /**
+     * Shared implementation of public {@code open(…)} methods.
+     * Note that this method may modify the given {@code options} set for its 
own purpose.
+     *
+     * @param  connector  information about the storage (URL, path, 
<i>etc</i>).
+     * @param  format     format name for directory content, or {@code null} 
if unspecified.
+     * @param  options    whether to create a new directory, overwrite 
existing content, <i>etc</i>.
+     */
+    private DataStore open(final StorageConnector connector, final String 
format, final EnumSet<StandardOpenOption> options)
+            throws DataStoreException
+    {
+        /*
+         * Determine now the provider to use for directory content. We do that 
for determining if the component
+         * has write capability. If not, then the WRITE, CREATE and related 
options will be ignored.  If we can
+         * not determine whether the component store has write capabilities 
(i.e. if canWrite(…) returns null),
+         * assume that the answer is "yes".
+         */
+        final DataStoreProvider componentProvider;
+        if (format != null) {
+            componentProvider = 
StoreUtilities.providerByFormatName(format.trim());
+            if 
(Boolean.FALSE.equals(StoreUtilities.canWrite(componentProvider.getClass()))) {
+                options.clear();            // No write capability.
+            }
+        } else {
+            componentProvider = null;
+            options.clear();                // Can not write if we don't know 
the components format.
+        }
+        final Path path = connector.getStorageAs(Path.class);
+        final Store store;
         try {
-            return new Store(this, connector);
+            /*
+             * If the user asked to create a new directory, we need to perform 
this task before
+             * to create the Store (otherwise constructor will fail with 
NoSuchFileException).
+             * In the particular case of CREATE_NEW, we unconditionally 
attempt to create the
+             * directory in order to rely on the atomic check performed by 
Files.createDirectory(…).
+             */
+            boolean isNew = false;
+            if (options.contains(StandardOpenOption.CREATE)) {
+                if (options.contains(StandardOpenOption.CREATE_NEW) || 
Files.notExists(path)) {
+                    Files.createDirectory(path);                        // 
IOException if the directory already exists.
+                    isNew = true;
+                }
+            }
+            if (isNew || (options.contains(StandardOpenOption.WRITE) && 
Files.isWritable(path))) {
+                store = new WritableStore(this, connector, path, 
componentProvider);  // May throw NoSuchFileException.
+            } else {
+                store = new Store(this, connector, path, componentProvider);   
       // May throw NoSuchFileException.
+            }
+            /*
+             * If there is a destructive operation to perform 
(TRUNCATE_EXISTING), do it last only
+             * after we have successfully created the data store. The check 
for directory existence
+             * is also done after creation to be sure to check the path used 
by the store.
+             */
+            if (!Files.isDirectory(path)) {
+                throw new 
DataStoreException(Resources.format(Resources.Keys.FileIsNotAResourceDirectory_1,
 path));
+            }
+            if (options.contains(StandardOpenOption.TRUNCATE_EXISTING)) {
+                WritableStore.deleteRecursively(path, false);
+            }
         } catch (IOException e) {
-            throw new 
DataStoreException(Resources.format(Resources.Keys.CanNotReadDirectory_1,
-                    connector.getStorageName()), e);
+            /*
+             * In case of error, Java FileSystem implementation tries to throw 
a specific exception
+             * (NoSuchFileException or FileAlreadyExistsException), but this 
is not guaranteed.
+             */
+            int isDirectory = 0;
+            final short errorKey;
+            if (e instanceof FileAlreadyExistsException) {
+                if (path != null && Files.isDirectory(path)) {
+                    isDirectory = 1;
+                }
+                errorKey = Resources.Keys.FileAlreadyExists_2;
+            } else if (e instanceof NoSuchFileException) {
+                errorKey = Resources.Keys.NoSuchResourceDirectory_1;
+            } else {
+                errorKey = Resources.Keys.CanNotCreateFolderStore_1;
+            }
+            throw new DataStoreException(Resources.format(errorKey,
+                    (path != null) ? path : connector.getStorageName(), 
isDirectory), e);
         }
+        return store;
     }
 
     /**
@@ -173,32 +270,15 @@ public final class FolderStoreProvider e
     @Override
     public DataStore open(final ParameterValueGroup parameters) throws 
DataStoreException {
         ArgumentChecks.ensureNonNull("parameter", parameters);
-        ParameterNotFoundException cause = null;
-        try {
-            final Object location = parameters.parameter(LOCATION).getValue();
-            if (location != null) {
-                final Parameters pg = Parameters.castOrWrap(parameters);
-                final StorageConnector connector = new 
StorageConnector(location);
-                connector.setOption(OptionKey.LOCALE,   pg.getValue(LOCALE));
-                connector.setOption(OptionKey.TIMEZONE, pg.getValue(TIMEZONE));
-                connector.setOption(OptionKey.ENCODING, pg.getValue(ENCODING));
-                return open(connector);
-            }
-        } catch (ParameterNotFoundException e) {
-            cause = e;
+        final StorageConnector connector = 
URIDataStore.Provider.connector(this, parameters);
+        final Parameters pg = Parameters.castOrWrap(parameters);
+        connector.setOption(OptionKey.LOCALE,   pg.getValue(LOCALE));
+        connector.setOption(OptionKey.TIMEZONE, pg.getValue(TIMEZONE));
+        connector.setOption(OptionKey.ENCODING, pg.getValue(ENCODING));
+        final EnumSet<StandardOpenOption> options = 
EnumSet.of(StandardOpenOption.WRITE);
+        if 
(Boolean.TRUE.equals(pg.getValue(URIDataStore.Provider.CREATE_PARAM))) {
+            options.add(StandardOpenOption.CREATE);
         }
-        throw new 
IllegalOpenParameterException(Resources.format(Resources.Keys.UndefinedParameter_2,
-                getShortName(), LOCATION), cause);
-    }
-
-    /**
-     * Returns a folder data store for the given path.
-     *
-     * @param  path  the directory for which to create a data store.
-     * @return a data store for the given directory.
-     * @throws DataStoreException if an error occurred while creating the data 
store instance.
-     */
-    public static DataStore open(final Path path) throws DataStoreException {
-        return INSTANCE.open(new StorageConnector(path));
+        return open(connector, pg.getValue(FORMAT), options);
     }
 }

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -22,14 +22,15 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Locale;
 import java.util.TimeZone;
+import java.util.logging.Level;
+import java.util.concurrent.ConcurrentHashMap;
 import java.nio.charset.Charset;
 import java.nio.file.Path;
 import java.nio.file.Files;
 import java.nio.file.DirectoryStream;
 import java.nio.file.DirectoryIteratorException;
 import java.io.IOException;
-import java.util.logging.Level;
-import java.util.concurrent.ConcurrentHashMap;
+import java.io.UncheckedIOException;
 import org.opengis.metadata.Metadata;
 import org.opengis.metadata.maintenance.ScopeCode;
 import org.opengis.parameter.ParameterValueGroup;
@@ -45,11 +46,9 @@ import org.apache.sis.storage.Unsupporte
 import org.apache.sis.util.collection.BackingStoreException;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
 import org.apache.sis.internal.storage.MetadataBuilder;
+import org.apache.sis.internal.storage.StoreUtilities;
 import org.apache.sis.internal.storage.Resources;
 
-// Branch-dependent imports
-import java.io.UncheckedIOException;
-
 
 /**
  * A folder store acts as an aggregate of multiple files in a single store.
@@ -69,36 +68,36 @@ import java.io.UncheckedIOException;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.8
  * @module
  */
-final class Store extends DataStore implements Aggregate, 
DirectoryStream.Filter<Path> {
+class Store extends DataStore implements Aggregate, 
DirectoryStream.Filter<Path> {
     /**
      * The {@link FolderStoreProvider#LOCATION} parameter value, or {@code 
null} if none.
      */
-    private final Path location;
+    protected final Path location;
 
     /**
      * Formating conventions of dates and numbers, or {@code null} if 
unspecified.
      */
-    private final Locale locale;
+    protected final Locale locale;
 
     /**
      * Timezone of dates in the data store, or {@code null} if unspecified.
      */
-    private final TimeZone timezone;
+    protected final TimeZone timezone;
 
     /**
      * Character encoding used by the data store, or {@code null} if 
unspecified.
      */
-    private final Charset encoding;
+    protected final Charset encoding;
 
     /**
      * All data stores (including sub-folders) found in the directory 
structure, including the root directory.
      * This is used for avoiding never-ending loop with symbolic links.
      */
-    private final Map<Path,DataStore> children;
+    final Map<Path,DataStore> children;
 
     /**
      * Information about the data store as a whole, created when first needed.
@@ -112,7 +111,14 @@ final class Store extends DataStore impl
      *
      * @see #components()
      */
-    private transient Collection<Resource> components;
+    transient Collection<Resource> components;
+
+    /**
+     * The provider to use for probing the directory content, opening files 
and creating new files.
+     * The provider is determined by the format name specified at construction 
time.
+     * This field is {@code null} if that format name is null.
+     */
+    protected final DataStoreProvider componentProvider;
 
     /**
      * {@code true} if {@link #sharedRepository(Path)} has already been 
invoked for {@link #location} path.
@@ -122,20 +128,30 @@ final class Store extends DataStore impl
 
     /**
      * Creates a new folder store from the given file, path or URI.
+     * The folder store will attempt to open only the files of the given 
format, if non-null.
+     * If a null format is specified, then the folder store will attempt to 
open any file
+     * found in the directory (this may produce confusing results).
      *
      * @param  provider   the factory that created this {@code DataStore} 
instance, or {@code null} if unspecified.
      * @param  connector  information about the storage (URL, stream, 
<i>etc</i>).
-     * @throws DataStoreException if an error occurred while opening the 
stream.
-     */
-    @SuppressWarnings("ThisEscapedInObjectConstruction")    // Okay because 
'folders' does not escape.
-    Store(final DataStoreProvider provider, final StorageConnector connector) 
throws DataStoreException, IOException {
+     * @param  path       the value of {@code 
connector.getStorageAs(Path.class)}.
+     * @param  format     format to use for reading or writing the directory 
content, or {@code null}.
+     * @throws UnsupportedStorageException if the given format name is unknown.
+     * @throws DataStoreException if an error occurred while fetching the 
directory {@link Path}.
+     * @throws IOException if an error occurred while using the directory 
{@code Path}.
+     */
+    @SuppressWarnings("ThisEscapedInObjectConstruction")    // Okay because 
'children' does not escape.
+    Store(final DataStoreProvider provider, final StorageConnector connector, 
final Path path, final DataStoreProvider format)
+            throws DataStoreException, IOException
+    {
         super(provider, connector);
-        location = connector.getStorageAs(Path.class);
+        location = path;
         locale   = connector.getOption(OptionKey.LOCALE);
         timezone = connector.getOption(OptionKey.TIMEZONE);
         encoding = connector.getOption(OptionKey.ENCODING);
         children = new ConcurrentHashMap<>();
-        children.put(location.toRealPath(), this);
+        children.put(path.toRealPath(), this);
+        componentProvider = format;
     }
 
     /**
@@ -147,11 +163,12 @@ final class Store extends DataStore impl
      */
     private Store(final Store parent, final StorageConnector connector) throws 
DataStoreException {
         super(parent, connector);
-        location = connector.getStorageAs(Path.class);
-        locale   = connector.getOption(OptionKey.LOCALE);
-        timezone = connector.getOption(OptionKey.TIMEZONE);
-        encoding = connector.getOption(OptionKey.ENCODING);
-        children = parent.children;
+        location          = connector.getStorageAs(Path.class);
+        locale            = connector.getOption(OptionKey.LOCALE);
+        timezone          = connector.getOption(OptionKey.TIMEZONE);
+        encoding          = connector.getOption(OptionKey.ENCODING);
+        children          = parent.children;
+        componentProvider = parent.componentProvider;
     }
 
     /**
@@ -159,11 +176,13 @@ final class Store extends DataStore impl
      */
     @Override
     public ParameterValueGroup getOpenParameters() {
+        final String format = StoreUtilities.getFormatName(componentProvider);
         final ParameterValueGroup pg = (provider != null ? 
provider.getOpenParameters() : FolderStoreProvider.PARAMETERS).createValue();
-        pg.parameter(FolderStoreProvider.LOCATION).setValue(location);
+        pg.parameter(DataStoreProvider.LOCATION).setValue(location);
         if (locale   != null) pg.parameter("locale"  ).setValue(locale  );
         if (timezone != null) pg.parameter("timezone").setValue(timezone);
         if (encoding != null) pg.parameter("encoding").setValue(encoding);
+        if (format   != null) pg.parameter("format"  ).setValue(format);
         return pg;
     }
 
@@ -204,8 +223,8 @@ final class Store extends DataStore impl
     @SuppressWarnings("ReturnOfCollectionOrArrayField")
     public synchronized Collection<Resource> components() throws 
DataStoreException {
         if (components == null) {
+            final List<DataStore> resources = new ArrayList<>();
             try (DirectoryStream<Path> stream = 
Files.newDirectoryStream(location, this)) {
-                final List<DataStore> resources = new ArrayList<>();
                 for (final Path candidate : stream) {
                     /*
                      * The candidate path may be a symbolic link to a file 
that we have previously read.
@@ -230,7 +249,16 @@ final class Store extends DataStore impl
                         connector.setOption(OptionKey.TIMEZONE, timezone);
                         connector.setOption(OptionKey.ENCODING, encoding);
                         try {
-                            next = DataStores.open(connector);
+                            if (componentProvider == null) {
+                                next = DataStores.open(connector);          // 
May throw UnsupportedStorageException.
+                            } else if 
(componentProvider.probeContent(connector).isSupported()) {
+                                next = componentProvider.open(connector);   // 
Open a file of specified format.
+                            } else if (Files.isDirectory(candidate)) {
+                                next = new Store(this, connector);          // 
Open a sub-directory.
+                            } else {
+                                connector.closeAllExcept(null);             // 
Not the format specified at construction time.
+                                continue;
+                            }
                         } catch (UnsupportedStorageException ex) {
                             if (!Files.isDirectory(candidate)) {
                                 connector.closeAllExcept(null);
@@ -261,7 +289,6 @@ final class Store extends DataStore impl
                     }
                     resources.add(next);
                 }
-                components = UnmodifiableArrayList.wrap(resources.toArray(new 
Resource[resources.size()]));
             } catch (DirectoryIteratorException | UncheckedIOException ex) {
                 // The cause is an IOException (no other type allowed).
                 throw new DataStoreException(canNotRead(), ex.getCause());
@@ -270,6 +297,7 @@ final class Store extends DataStore impl
             } catch (BackingStoreException ex) {
                 throw ex.unwrapOrRethrow(DataStoreException.class);
             }
+            components = UnmodifiableArrayList.wrap(resources.toArray(new 
Resource[resources.size()]));
         }
         return components;              // Safe because unmodifiable list.
     }
@@ -296,12 +324,19 @@ final class Store extends DataStore impl
     }
 
     /**
+     * Returns the resource bundle to use for error message in exceptions.
+     */
+    final Resources messages() {
+        return Resources.forLocale(getLocale());
+    }
+
+    /**
      * Returns a localized string for the given key and value.
      *
      * @param  key  one of the {@link Resources.Keys} constants ending with 
{@code _1} suffix.
      */
-    private String message(final short key, final Object value) {
-        return Resources.forLocale(getLocale()).getString(key, value);
+    final String message(final short key, final Object value) {
+        return messages().getString(key, value);
     }
 
     /**

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/package-info.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/package-info.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/package-info.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/package-info.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -19,7 +19,7 @@
  * {@link org.apache.sis.storage.DataStore} implementation for a folder 
containing an arbitrary amount of data files.
  *
  * @author  Johann Sorel (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.8
  * @module
  */

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/InputStreamAdapter.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/InputStreamAdapter.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/InputStreamAdapter.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/InputStreamAdapter.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -18,10 +18,8 @@ package org.apache.sis.internal.storage.
 
 import java.io.InputStream;
 import java.io.IOException;
-import javax.imageio.stream.ImageInputStream;
-
-// Branch-dependent imports
 import java.io.UncheckedIOException;
+import javax.imageio.stream.ImageInputStream;
 
 
 /**

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/package-info.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/package-info.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/package-info.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/package-info.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -24,7 +24,7 @@
  * may change in incompatible ways in any future version without notice.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.3
  * @module
  */

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -19,7 +19,6 @@ package org.apache.sis.internal.storage.
 import java.util.List;
 import java.util.Arrays;
 import java.util.ArrayList;
-import java.util.logging.LogRecord;
 import java.io.Reader;
 import java.io.IOException;
 import java.text.ParsePosition;
@@ -27,13 +26,13 @@ import java.text.ParseException;
 import org.opengis.metadata.Metadata;
 import org.opengis.referencing.ReferenceSystem;
 import org.apache.sis.internal.storage.Resources;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreContentException;
 import org.apache.sis.storage.UnsupportedStorageException;
 import org.apache.sis.internal.storage.MetadataBuilder;
 import org.apache.sis.internal.storage.URIDataStore;
+import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.setup.GeometryLibrary;
 import org.apache.sis.setup.OptionKey;
 import org.apache.sis.util.CharSequences;
@@ -43,7 +42,7 @@ import org.apache.sis.util.CharSequences
  * A data store which creates data objects from a WKT definition.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.7
  * @module
  */
@@ -144,19 +143,10 @@ final class Store extends URIDataStore {
     }
 
     /**
-     * Reports a warning.
-     */
-    private void log(final LogRecord record) {
-        record.setSourceClassName(Store.class.getName());
-        record.setSourceMethodName("getMetadata");          // Public facade 
for the parse() method.
-        record.setLoggerName(Loggers.WKT);
-        listeners.warning(record);
-    }
-
-    /**
      * Returns the metadata associated to the parsed objects, or {@code null} 
if none.
      * The current implementation retains only instances of {@link 
ReferenceSystem}
-     * and ignore other objects.
+     * and ignore other objects. The identification information {@code 
Citation} is
+     * set to the CRS name and identifier, unless there is ambiguity.
      *
      * @return the metadata associated to the parsed object, or {@code null} 
if none.
      * @throws DataStoreException if an error occurred during the parsing 
process.
@@ -166,13 +156,22 @@ final class Store extends URIDataStore {
         if (metadata == null) {
             parse();
             final MetadataBuilder builder = new MetadataBuilder();
-            builder.addTitle(getDisplayName());
+            String name = null;
+            int count = 0;
             for (final Object object : objects) {
                 if (object instanceof ReferenceSystem) {
-                    builder.addReferenceSystem((ReferenceSystem) object);
+                    final ReferenceSystem rs = (ReferenceSystem) object;
+                    builder.addReferenceSystem(rs);
+                    name = IdentifiedObjects.getName(rs, null);
+                    count++;
+                    builder.addIdentifier(IdentifiedObjects.getIdentifier(rs, 
null), MetadataBuilder.Scope.RESOURCE);
                 }
             }
-            addTitleOrIdentifier(builder);
+            if (count == 1) {                   // Set the citation title only 
if non-ambiguous.
+                builder.addTitle(name);
+            } else {
+                addTitleOrIdentifier(builder);
+            }
             metadata = builder.build(true);
         }
         return metadata;

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -24,7 +24,7 @@ import org.apache.sis.storage.DataStoreE
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.storage.ProbeResult;
 import org.apache.sis.internal.storage.Capability;
-import org.apache.sis.internal.storage.Capabilities;
+import org.apache.sis.internal.storage.StoreMetadata;
 import org.apache.sis.internal.storage.URIDataStore;
 import org.apache.sis.internal.metadata.WKTKeywords;
 import org.apache.sis.util.Version;
@@ -34,11 +34,13 @@ import org.apache.sis.util.Version;
  * The provider of WKT {@link Store} instances.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.7
  * @module
  */
-@Capabilities(Capability.READ)
+@StoreMetadata(formatName   = StoreProvider.NAME,
+               fileSuffixes = "prj",
+               capabilities = Capability.READ)
 public final class StoreProvider extends URIDataStore.Provider {
     /**
      * The format name.

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -20,7 +20,7 @@ import org.apache.sis.xml.Namespaces;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.StorageConnector;
-import org.apache.sis.internal.storage.Capabilities;
+import org.apache.sis.internal.storage.StoreMetadata;
 import org.apache.sis.internal.storage.Capability;
 
 
@@ -28,11 +28,13 @@ import org.apache.sis.internal.storage.C
  * The provider of {@link Store} instances.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.4
  * @module
  */
-@Capabilities(Capability.READ)
+@StoreMetadata(formatName   = StoreProvider.NAME,
+               fileSuffixes = "xml",
+               capabilities = Capability.READ)
 public final class StoreProvider extends AbstractProvider {
     /**
      * The format name.

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/Aggregate.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/Aggregate.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/Aggregate.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/Aggregate.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -17,10 +17,6 @@
 package org.apache.sis.storage;
 
 import java.util.Collection;
-import org.opengis.metadata.Metadata;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.apache.sis.internal.storage.Resources;
-
 
 /**
  * A collection of resources. An aggregate can have two or more components.
@@ -58,7 +54,7 @@ import org.apache.sis.internal.storage.R
  * associated resources} with an {@link 
org.opengis.metadata.identification.AssociationType#IS_COMPOSED_OF} relation.
  *
  * @author  Johann Sorel (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.8
  * @module
  */
@@ -90,47 +86,4 @@ public interface Aggregate extends Resou
      * @throws DataStoreException if an error occurred while fetching the 
components.
      */
     Collection<Resource> components() throws DataStoreException;
-
-    /**
-     * Adds a new {@code Resource} in this {@code Aggregate}.
-     * The given {@link Resource} will be copied, and the <cite>effectively 
added</cite> resource returned.
-     * The effectively added resource may differ from the given resource in 
many aspects.
-     * The possible changes may include the followings but not only:
-     * <ul>
-     *  <li>types and properties names</li>
-     *  <li>{@link CoordinateReferenceSystem}</li>
-     *  <li>{@link Metadata}</li>
-     * </ul>
-     *
-     * <div class="note"><b>Warning:</b>
-     * copying informations between stores may produce differences in many 
aspects.
-     * The range of changes depends both on the original {@link Resource} 
structure
-     * and the target {@code Resource} structure. If the differences are too 
large,
-     * then this {@code Aggregate} may throw an exception.
-     * </div>
-     *
-     * <p>The default implementation throws {@link 
ReadOnlyStorageException}.</p>
-     *
-     * @param  resource  the resource to copy in this {@code Aggregate}.
-     * @return the effectively added resource. May be {@code resource} itself 
if it has been added verbatim.
-     * @throws ReadOnlyStorageException if this instance does not support 
write operations.
-     * @throws DataStoreException if the given resource can not be stored in 
this {@code Aggregate} for another reason.
-     */
-    default Resource add(Resource resource) throws ReadOnlyStorageException, 
DataStoreException {
-        throw new ReadOnlyStorageException(this, 
Resources.Keys.StoreIsReadOnly);
-    }
-
-    /**
-     * Removes a {@code Resource} from this {@code Aggregate}.
-     * This operation is destructive: the {@link Resource} and it's related 
data will be removed.
-     *
-     * <p>The default implementation throws {@link 
ReadOnlyStorageException}.</p>
-     *
-     * @param  resource  child resource to remove, should not be null.
-     * @throws ReadOnlyStorageException if this instance does not support 
write operations.
-     * @throws DataStoreException if the given resource could not be removed 
for another reason.
-     */
-    default void remove(Resource resource) throws ReadOnlyStorageException, 
DataStoreException {
-        throw new ReadOnlyStorageException(this, 
Resources.Keys.StoreIsReadOnly);
-    }
 }

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -47,7 +47,7 @@ import org.apache.sis.internal.util.Cita
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  *
  * @see DataStores#open(Object)
  *

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -18,10 +18,9 @@ package org.apache.sis.storage;
 
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptorGroup;
-import org.opengis.parameter.ParameterNotFoundException;
 import org.opengis.metadata.distribution.Format;
 import org.apache.sis.internal.simple.SimpleFormat;
-import org.apache.sis.internal.storage.Resources;
+import org.apache.sis.internal.storage.URIDataStore;
 import org.apache.sis.metadata.iso.citation.DefaultCitation;
 import org.apache.sis.metadata.iso.distribution.DefaultFormat;
 import org.apache.sis.measure.Range;
@@ -58,7 +57,7 @@ import org.apache.sis.util.Version;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.3
  * @module
  */
@@ -70,16 +69,45 @@ public abstract class DataStoreProvider
      *
      * <p>Implementors are encouraged to define a parameter with this name
      * to ensure a common and consistent definition among providers.
-     * The parameter should be defined as mandatory and declared with a 
well-known Java class such as
+     * The parameter should be defined as mandatory and typed with a 
well-known Java class such as
      * {@link java.net.URI}, {@link java.nio.file.Path}, JDBC {@linkplain 
javax.sql.DataSource}, <i>etc</i>.
      * The type should have a compact textual representation, for 
serialization in XML or configuration files.
      * Consequently {@link java.io.InputStream} and {@link 
java.nio.channels.Channel} should be avoided.</p>
      *
+     * @see #CREATE
      * @see #getOpenParameters()
      */
     public static final String LOCATION = "location";
 
     /**
+     * Name of the parameter that specifies whether to allow creation of a new 
{@code DataStore} if none exist
+     * at the given location. A parameter named {@value} may be included in 
the group of parameters returned by
+     * {@link #getOpenParameters()} if the data store supports write 
operations. The parameter value is often a
+     * {@link Boolean} and the default value should be {@link Boolean#FALSE} 
or equivalent.
+     *
+     * <p>Implementors are encouraged to define an <em>optional</em> parameter 
with this name in complement to the
+     * {@value #LOCATION} parameter <em>only if</em> write operations are 
supported. If this parameter value is not
+     * set or is set to {@code false}, then the {@link 
#open(ParameterValueGroup)} method should fail if no file or
+     * database exists at the URL or path given by the {@value #LOCATION} 
parameter. Otherwise if this parameter is
+     * set to {@code true}, then the {@code open(…)} method may create files, 
a directory or a database at the given
+     * location.</p>
+     *
+     * <div class="note"><b>Relationship with standard file open options</b>
+     * <p>For data stores on file systems, a <code>{@value} = true</code> 
parameter value is equivalent to opening a file
+     * with {@link java.nio.file.StandardOpenOption#CREATE} and {@link 
java.nio.file.StandardOpenOption#APPEND APPEND}.
+     * The other file standard options like {@link 
java.nio.file.StandardOpenOption#CREATE_NEW CREATE_NEW} and
+     * {@link java.nio.file.StandardOpenOption#TRUNCATE_EXISTING 
TRUNCATE_EXISTING} should not be accessible through
+     * this {@value} parameter. The reason is that {@link ParameterValueGroup} 
may be used for storing parameters
+     * permanently (for example in a configuration file or in a database) for 
reopening the same {@link DataStore}
+     * many times. File options designed for being used only once like {@code 
CREATE_NEW} and {@code TRUNCATE_EXISTING}
+     * are incompatible with this usage.</p></div>
+     *
+     * @see #LOCATION
+     * @see #getOpenParameters()
+     */
+    public static final String CREATE = "create";
+
+    /**
      * Creates a new provider.
      */
     protected DataStoreProvider() {
@@ -157,7 +185,8 @@ public abstract class DataStoreProvider
      * from a path or URL, together with additional information like character 
encoding.
      *
      * <p>Implementors are responsible for declaring all parameters and 
whether they are mandatory or optional.
-     * It is recommended to define at least a parameter named {@value 
#LOCATION}.
+     * It is recommended to define at least a parameter named {@value 
#LOCATION}, completed by {@value #CREATE}
+     * if the data store supports write operations.
      * That parameter will be recognized by the default {@code 
DataStoreProvider} methods and used whenever a
      * {@link StorageConnector} is required.</p>
      *
@@ -175,6 +204,8 @@ public abstract class DataStoreProvider
      *
      * @return description of the parameters required or accepted for opening 
a {@link DataStore}.
      *
+     * @see #LOCATION
+     * @see #CREATE
      * @see #open(ParameterValueGroup)
      * @see DataStore#getOpenParameters()
      *
@@ -281,24 +312,14 @@ public abstract class DataStoreProvider
      * @return a data store implementation associated with this provider for 
the given parameters.
      * @throws DataStoreException if an error occurred while creating the data 
store instance.
      *
+     * @see #LOCATION
+     * @see #CREATE
      * @see #getOpenParameters()
      *
      * @since 0.8
      */
     public DataStore open(final ParameterValueGroup parameters) throws 
DataStoreException {
         ArgumentChecks.ensureNonNull("parameter", parameters);
-        ParameterNotFoundException cause = null;
-        Object location;
-        try {
-            location = parameters.parameter(LOCATION).getValue();
-        } catch (ParameterNotFoundException e) {
-            location = null;
-            cause = e;
-        }
-        if (location == null) {
-            throw new 
IllegalOpenParameterException(Resources.format(Resources.Keys.UndefinedParameter_2,
-                    getShortName(), LOCATION), cause);
-        }
-        return open(new StorageConnector(location));
+        return open(URIDataStore.Provider.connector(this, parameters));
     }
 }

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -18,7 +18,7 @@ package org.apache.sis.storage;
 
 import java.util.List;
 import java.util.LinkedList;
-import java.util.Collection;
+import java.util.Set;
 import java.util.Iterator;
 import java.util.ServiceLoader;
 import org.apache.sis.internal.storage.Resources;
@@ -41,7 +41,7 @@ import org.apache.sis.util.ArgumentCheck
  * on the part of the caller.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.4
  * @module
  */
@@ -80,7 +80,7 @@ final class DataStoreRegistry {
      *
      * @since 0.8
      */
-    public Collection<DataStoreProvider> providers() {
+    public Set<DataStoreProvider> providers() {
         synchronized (loader) {
             final Iterator<DataStoreProvider> providers = loader.iterator();
             return new LazySet<>(new Iterator<DataStoreProvider>() {

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -28,7 +28,8 @@ import org.apache.sis.internal.system.Sy
  * but can also be any other objects documented in the {@link 
StorageConnector} class.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @author  Johann Sorel (Geomatys)
+ * @version 1.0
  * @since   0.4
  * @module
  */
@@ -79,7 +80,7 @@ public final class DataStores extends St
     }
 
     /**
-     * Returns the list of data store providers available at this method 
invocation time.
+     * Returns the set of data store providers available at this method 
invocation time.
      * 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/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureSet.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureSet.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureSet.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureSet.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -16,13 +16,9 @@
  */
 package org.apache.sis.storage;
 
-import java.util.Iterator;
-import org.apache.sis.internal.storage.Resources;
+import java.util.stream.Stream;
 
 // Branch-dependent imports
-import java.util.function.Predicate;
-import java.util.function.UnaryOperator;
-import java.util.stream.Stream;
 import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureType;
 
@@ -35,7 +31,7 @@ import org.opengis.feature.FeatureType;
  * are also allowed.
  *
  * @author  Johann Sorel (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.8
  * @module
  */
@@ -140,63 +136,4 @@ public interface FeatureSet extends Data
      * @throws DataStoreException if an error occurred while creating the 
stream.
      */
     Stream<Feature> features(boolean parallel) throws DataStoreException;
-
-    /**
-     * Inserts new features in this {@code FeatureSet}.
-     * Any feature already present in the {@link FeatureSet} will remain 
unmodified.
-     *
-     * <div class="note"><b>API note:</b>
-     * this method expects an {@link Iterator} rather then a {@link 
java.util.stream.Stream} for easing
-     * inter-operability with various API. Implementing a custom {@link 
Iterator} requires less effort
-     * than implementing a {@link Stream}. On the other side if the user has a 
{@link Stream},
-     * obtaining an {@link Iterator} can be done by a call to {@link 
Stream#iterator()}.</div>
-     *
-     * <p>The default implementation throws {@link 
ReadOnlyStorageException}.</p>
-     *
-     * @param  features features to insert in this {@code FeatureSet}.
-     * @throws ReadOnlyStorageException if this instance does not support 
write operations.
-     * @throws DataStoreException if another error occurred while storing new 
features.
-     */
-    default void add(Iterator<? extends Feature> features) throws 
ReadOnlyStorageException, DataStoreException {
-        throw new ReadOnlyStorageException(this, 
Resources.Keys.StoreIsReadOnly);
-    }
-
-    /**
-     * Removes all features from this {@code FeatureSet} which matches the 
given predicate.
-     *
-     * <p>The default implementation throws {@link 
ReadOnlyStorageException}.</p>
-     *
-     * @param  filter  a predicate which returns true for resources to be 
removed.
-     * @return {@code true} if any elements were removed.
-     * @throws ReadOnlyStorageException if this instance does not support 
write operations.
-     * @throws DataStoreException if another error occurred while removing 
features.
-     */
-    default boolean removeIf(Predicate<? super Feature> filter) throws 
ReadOnlyStorageException, DataStoreException {
-        throw new ReadOnlyStorageException(this, 
Resources.Keys.StoreIsReadOnly);
-    }
-
-    /**
-     * Updates all features from this {@code FeatureSet} which matches the 
given predicate.
-     * For each {@link Feature} instance matching the given {@link Predicate},
-     * the <code>{@linkplain UnaryOperator#apply 
UnaryOperator.apply(Feature)}</code> method will be invoked.
-     * {@code UnaryOperator}s are free to modify the given {@code Feature} 
<i>in-place</i> or to return a
-     * different feature instance. Two behaviors are possible:
-     * <ul>
-     *   <li>If the operator returns a non-null {@link Feature}, then the 
modified feature is stored
-     *       in replacement of the previous feature (not necessarily at the 
same location).</li>
-     *   <li>If the operator returns {@code null}, then the feature will be 
removed from the {@code FeatureSet}.</li>
-     * </ul>
-     *
-     * <p>The default implementation throws {@link 
ReadOnlyStorageException}.</p>
-     *
-     * @param  filter   a predicate which returns true for resources to be 
updated.
-     * @param  updater  operation called for each matching {@link Feature}.
-     * @throws ReadOnlyStorageException if this instance does not support 
write operations.
-     * @throws DataStoreException if another error occurred while replacing 
features.
-     */
-    default void replaceIf(Predicate<? super Feature> filter, 
UnaryOperator<Feature> updater)
-            throws ReadOnlyStorageException, DataStoreException
-    {
-        throw new ReadOnlyStorageException(this, 
Resources.Keys.StoreIsReadOnly);
-    }
 }

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/ReadOnlyStorageException.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/ReadOnlyStorageException.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/ReadOnlyStorageException.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/ReadOnlyStorageException.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -16,17 +16,15 @@
  */
 package org.apache.sis.storage;
 
-import org.apache.sis.util.Localized;
-
 
 /**
  * Thrown when a {@code DataStore} can not perform a write operations.
- * This exception may occur either because:
- *
- * <ul>
- *   <li>the data store does not support write operations, or</li>
- *   <li>write operations are supported but the channel is read-only.</li>
- * </ul>
+ * If a data store does not support any write operation, then it should not 
implement
+ * {@link WritableAggregate} or {@link WritableFeatureSet} interface.
+ * But in some situations, a data store may implement a {@code Writable*} 
interface
+ * and nevertheless be unable to perform a write operation, for example 
because the
+ * underlying {@link java.nio.channels.Channel} is read-only or part of the 
file is
+ * locked by another process.
  *
  * @author  Johann Sorel (Geomatys)
  * @version 0.8
@@ -74,15 +72,4 @@ public class ReadOnlyStorageException ex
     public ReadOnlyStorageException(final String message, final Throwable 
cause) {
         super(message, cause);
     }
-
-    /**
-     * Creates a new exception which will format a localized message in the 
resource locale.
-     *
-     * @param originator  the instance throwing this exception, or {@code 
null} if unknown.
-     * @param key         one of {@link 
org.apache.sis.internal.storage.Resources.Keys} constants.
-     * @param parameters  parameters to use for formatting the messages.
-     */
-    ReadOnlyStorageException(final Resource originator, final short key, final 
Object... parameters) {
-        super((originator instanceof Localized) ? ((Localized) 
originator).getLocale() : null, key, parameters);
-    }
 }

Modified: 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/package-info.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/package-info.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/package-info.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/package-info.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -26,7 +26,7 @@
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.3
  * @module
  */

Modified: 
sis/branches/JDK9/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java?rev=1825252&r1=1825251&r2=1825252&view=diff
==============================================================================
--- 
sis/branches/JDK9/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java
 [UTF-8] (original)
+++ 
sis/branches/JDK9/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java
 [UTF-8] Sat Feb 24 15:44:08 2018
@@ -18,12 +18,15 @@ package org.apache.sis.internal.storage.
 
 import java.util.Arrays;
 import java.util.Iterator;
+import java.time.Instant;
 import java.io.StringReader;
 import org.opengis.metadata.Metadata;
 import org.opengis.metadata.extent.Extent;
 import org.opengis.metadata.extent.GeographicBoundingBox;
+import org.apache.sis.feature.FoliationRepresentation;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.StorageConnector;
+import org.apache.sis.storage.DataOptionKey;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 import com.esri.core.geometry.Point2D;
@@ -35,7 +38,6 @@ import static org.apache.sis.test.TestUt
 import static org.apache.sis.test.TestUtilities.getSingleton;
 
 // Branch-dependent imports
-import java.time.Instant;
 import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureType;
 import org.opengis.feature.PropertyType;
@@ -46,7 +48,7 @@ import org.opengis.feature.AttributeType
  * Tests {@link Store}.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.7
  * @module
  */
@@ -79,6 +81,15 @@ public final strictfp class StoreTest ex
     }
 
     /**
+     * Opens a CSV store on the test data for reading the lines as-is, without 
assembling them in a single trajectory.
+     */
+    private static Store open() throws DataStoreException {
+        StorageConnector connector = new StorageConnector(testData());
+        connector.setOption(DataOptionKey.FOLIATION_REPRESENTATION, 
FoliationRepresentation.FRAGMENTED);
+        return new Store(null, connector);
+    }
+
+    /**
      * Tests {@link Store#getMetadata()}.
      *
      * @throws DataStoreException if an error occurred while parsing the data.
@@ -86,7 +97,7 @@ public final strictfp class StoreTest ex
     @Test
     public void testGetMetadata() throws DataStoreException {
         final Metadata metadata;
-        try (Store store = new Store(null, new StorageConnector(testData()), 
true)) {
+        try (Store store = open()) {
             metadata = store.getMetadata();
         }
         final Extent extent = 
getSingleton(getSingleton(metadata.getIdentificationInfo()).getExtents());
@@ -105,7 +116,7 @@ public final strictfp class StoreTest ex
      */
     @Test
     public void testStaticFeatures() throws DataStoreException {
-        try (Store store = new Store(null, new StorageConnector(testData()), 
true)) {
+        try (Store store = open()) {
             verifyFeatureType(store.featureType, double[].class, 1);
             assertEquals("foliation", Foliation.TIME, store.foliation);
             final Iterator<Feature> it = store.features(false).iterator();
@@ -134,7 +145,7 @@ public final strictfp class StoreTest ex
     @Test
     public void testMovingFeatures() throws DataStoreException {
         isMovingFeature = true;
-        try (Store store = new Store(null, new StorageConnector(testData()), 
false)) {
+        try (Store store = new Store(null, new StorageConnector(testData()))) {
             verifyFeatureType(store.featureType, Polyline.class, 
Integer.MAX_VALUE);
             assertEquals("foliation", Foliation.TIME, store.foliation);
             final Iterator<Feature> it = store.features(false).iterator();


Reply via email to