Modified: 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
 [UTF-8] Sat Feb 24 15:36:52 2018
@@ -67,7 +67,12 @@ public final class Resources extends Ind
         public static final short AmbiguousName_4 = 15;
 
         /**
-         * Can not get metadata common to “{0}” files. Reason: {1}
+         * Can not create resources based on the content of “{0}” directory.
+         */
+        public static final short CanNotCreateFolderStore_1 = 43;
+
+        /**
+         * Can not get metadata common to “{0}” files. The reason is: {1}
          */
         public static final short CanNotGetCommonMetadata_2 = 39;
 
@@ -97,6 +102,16 @@ public final class Resources extends Ind
         public static final short CanNotReadFile_4 = 3;
 
         /**
+         * Can not remove resource “{1}” from aggregate “{0}”.
+         */
+        public static final short CanNotRemoveResource_2 = 49;
+
+        /**
+         * Can not save resources of type ‘{1}’ in a “{0}” store.
+         */
+        public static final short CanNotStoreResourceType_2 = 41;
+
+        /**
          * This {0} reader is closed.
          */
         public static final short ClosedReader_1 = 4;
@@ -117,6 +132,11 @@ public final class Resources extends Ind
         public static final short ConcurrentWrite_1 = 20;
 
         /**
+         * Whether to allow new data store creation if the source to open does 
not already exist.
+         */
+        public static final short DataStoreCreate = 51;
+
+        /**
          * Character encoding used by the data store.
          */
         public static final short DataStoreEncoding = 29;
@@ -137,6 +157,11 @@ public final class Resources extends Ind
         public static final short DataStoreTimeZone = 32;
 
         /**
+         * Name of the format to use for reading or writing the directory 
content.
+         */
+        public static final short DirectoryContentFormatName = 40;
+
+        /**
          * Content of “{0}” directory.
          */
         public static final short DirectoryContent_1 = 35;
@@ -158,6 +183,16 @@ public final class Resources extends Ind
         public static final short FeatureNotFound_2 = 17;
 
         /**
+         * A {1,choice,0#file|1#directory} already exists at “{0}”.
+         */
+        public static final short FileAlreadyExists_2 = 45;
+
+        /**
+         * The “{0}” file is not a directory of resources.
+         */
+        public static final short FileIsNotAResourceDirectory_1 = 44;
+
+        /**
          * Whether to assemble trajectory fragments (lines in CSV file) in a 
single feature instance.
          */
         public static final short FoliationRepresentation = 38;
@@ -184,16 +219,41 @@ public final class Resources extends Ind
         public static final short InconsistentNameComponents_2 = 10;
 
         /**
+         * Resource “{0}” does not have an identifier.
+         */
+        public static final short MissingResourceIdentifier_1 = 42;
+
+        /**
          * Missing scheme in “{0}” URI.
          */
         public static final short MissingSchemeInURI_1 = 11;
 
         /**
+         * No directory of resources found at “{0}”.
+         */
+        public static final short NoSuchResourceDirectory_1 = 46;
+
+        /**
+         * Resource “{1}” is not part of aggregate “{0}”.
+         */
+        public static final short NoSuchResourceInAggregate_2 = 50;
+
+        /**
+         * Resource “{0}” is not a writable feature set.
+         */
+        public static final short NotAWritableFeatureSet_1 = 47;
+
+        /**
          * Processing executed on {0}.
          */
         public static final short ProcessingExecutedOn_1 = 12;
 
         /**
+         * A resource already exists at “{0}”.
+         */
+        public static final short ResourceAlreadyExists_1 = 48;
+
+        /**
          * More than one resource have the “{1}” identifier in the “{0}” data 
store.
          */
         public static final short ResourceIdentifierCollision_2 = 23;

Modified: 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
 [ISO-8859-1] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
 [ISO-8859-1] Sat Feb 24 15:36:52 2018
@@ -16,35 +16,47 @@
 #
 
 #
-# Resources in this file are for "sis-netcdf" usage only and should not be 
used by any other module.
+# Resources in this file are for "sis-storage" usage only and should not be 
used by any other module.
 # For resources shared by all modules in the Apache SIS project, see 
"org.apache.sis.util.resources" package.
 #
 AmbiguousName_4                   = Name \u201c{3}\u201d is ambiguous because 
it can be understood as either \u201c{1}\u201d or \u201c{2}\u201d in the 
context of \u201c{0}\u201d data.
-CanNotGetCommonMetadata_2         = Can not get metadata common to 
\u201c{0}\u201d files. Reason: {1}
+CanNotCreateFolderStore_1         = Can not create resources based on the 
content of \u201c{0}\u201d directory.
+CanNotGetCommonMetadata_2         = Can not get metadata common to 
\u201c{0}\u201d files. The reason is: {1}
 CanNotReadCRS_WKT_1               = Can not read the Coordinate Reference 
System (CRS) Well Known Text (WKT) in \u201c{0}\u201d.
 CanNotReadDirectory_1             = Can not read \u201c{0}\u201d directory.
 CanNotReadFile_2                  = Can not read \u201c{1}\u201d as a file in 
the {0} format.
 CanNotReadFile_3                  = Can not read line {2} of \u201c{1}\u201d 
as part of a file in the {0} format.
 CanNotReadFile_4                  = Can not read line {2} (after column {3}) 
of \u201c{1}\u201d as part of a file in the {0} format.
+CanNotRemoveResource_2            = Can not remove resource \u201c{1}\u201d 
from aggregate \u201c{0}\u201d.
+CanNotStoreResourceType_2         = Can not save resources of type 
\u2018{1}\u2019 in a \u201c{0}\u201d store.
 ClosedReader_1                    = This {0} reader is closed.
 ClosedWriter_1                    = This {0} writer is closed.
 ConcurrentRead_1                  = One or more read operations are in 
progress in the \u201c{0}\u201d data store.
 ConcurrentWrite_1                 = A write operation is in progress in the 
\u201c{0}\u201d data store.
+DataStoreCreate                   = Whether to allow new data store creation 
if the source to open does not already exist.
 DataStoreEncoding                 = Character encoding used by the data store.
 DataStoreLocale                   = Formating conventions of dates and numbers.
 DataStoreLocation                 = Data store location as a file or URL.
 DataStoreTimeZone                 = Timezone of dates in the data store.
 DirectoryContent_1                = Content of \u201c{0}\u201d directory.
+DirectoryContentFormatName        = Name of the format to use for reading or 
writing the directory content.
 FeatureAlreadyPresent_2           = A feature named \u201c{1}\u201d is already 
present in the \u201c{0}\u201d data store.
 FeatureNotFound_2                 = Feature \u201c{1}\u201d has not been found 
in the \u201c{0}\u201d data store.
+FileAlreadyExists_2               = A {1,choice,0#file|1#directory} already 
exists at \u201c{0}\u201d.
+FileIsNotAResourceDirectory_1     = The \u201c{0}\u201d file is not a 
directory of resources.
 FoliationRepresentation           = Whether to assemble trajectory fragments 
(lines in CSV file) in a single feature instance.
 ExcessiveStringSize_3             = Character string in the \u201c{0}\u201d 
file is too long. The string has {2} characters while the limit is {1}.
 IllegalFeatureType_2              = The {0} data store does not accept 
features of type \u201c{1}\u201d.
 IllegalInputTypeForReader_2       = The {0} reader does not accept inputs of 
type \u2018{1}\u2019.
 IllegalOutputTypeForWriter_2      = The {0} writer does not accept outputs of 
type \u2018{1}\u2019.
 InconsistentNameComponents_2      = Components of the \u201c{1}\u201d name are 
inconsistent with those of the name previously binded in \u201c{0}\u201d data 
store.
+MissingResourceIdentifier_1       = Resource \u201c{0}\u201d does not have an 
identifier.
 MissingSchemeInURI_1              = Missing scheme in \u201c{0}\u201d URI.
+NoSuchResourceDirectory_1         = No directory of resources found at 
\u201c{0}\u201d.
+NoSuchResourceInAggregate_2       = Resource \u201c{1}\u201d is not part of 
aggregate \u201c{0}\u201d.
+NotAWritableFeatureSet_1          = Resource \u201c{0}\u201d is not a writable 
feature set.
 ProcessingExecutedOn_1            = Processing executed on {0}.
+ResourceAlreadyExists_1           = A resource already exists at 
\u201c{0}\u201d.
 ResourceIdentifierCollision_2     = More than one resource have the 
\u201c{1}\u201d identifier in the \u201c{0}\u201d data store.
 ResourceNotFound_2                = No resource found for the \u201c{1}\u201d 
identifier in the \u201c{0}\u201d data store.
 ShallBeDeclaredBefore_2           = The \u201c{1}\u201d element must be 
declared before \u201c{0}\u201d.

Modified: 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
 [ISO-8859-1] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
 [ISO-8859-1] Sat Feb 24 15:36:52 2018
@@ -25,31 +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.
-CanNotGetCommonMetadata_2         = Ne peut pas obtenir les 
m\u00e9ta-donn\u00e9es communes aux fichiers \u00ab\u202f{0}\u202f\u00bb. 
Raison\u2008: {1}
+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\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.

Copied: 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/StoreUtilities.java
 (from r1825247, 
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/StoreUtilities.java)
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/StoreUtilities.java?p2=sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/StoreUtilities.java&p1=sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/StoreUtilities.java&r1=1825247&r2=1825249&rev=1825249&view=diff
==============================================================================
--- 
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/StoreUtilities.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/StoreUtilities.java
 [UTF-8] Sat Feb 24 15:36:52 2018
@@ -38,7 +38,7 @@ import org.apache.sis.util.CharSequences
 import org.apache.sis.util.Classes;
 
 // Branch-dependent imports
-import org.opengis.feature.Feature;
+import org.apache.sis.feature.AbstractFeature;
 
 
 /**
@@ -292,7 +292,7 @@ public final class StoreUtilities extend
      */
     public static void copy(final FeatureSet source, final WritableFeatureSet 
target) throws DataStoreException {
         target.updateType(source.getType());
-        try (Stream<Feature> stream = source.features(false)) {
+        try (Stream<AbstractFeature> stream = source.features(false)) {
             target.add(stream.iterator());
         }
     }

Modified: 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java
 [UTF-8] Sat Feb 24 15:36:52 2018
@@ -94,17 +94,24 @@ 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.
@@ -113,6 +120,7 @@ public abstract class URIDataStore exten
         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);
         }
 
@@ -176,6 +184,8 @@ public abstract class URIDataStore exten
         /**
          * 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.
@@ -186,7 +196,7 @@ public abstract class URIDataStore exten
                 throws IllegalOpenParameterException
         {
             ParameterNotFoundException cause = null;
-            try {
+            if (parameters != null) try {
                 final Object location = 
parameters.parameter(LOCATION).getValue();
                 if (location != null) {
                     return new StorageConnector(location);
@@ -202,7 +212,7 @@ public abstract class URIDataStore exten
     /**
      * 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/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java
 [UTF-8] Sat Feb 24 15:36:52 2018
@@ -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/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java
 [UTF-8] Sat Feb 24 15:36:52 2018
@@ -29,7 +29,7 @@ import org.apache.sis.storage.StorageCon
 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;
@@ -48,7 +48,9 @@ import org.apache.sis.util.ArgumentCheck
  * @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.

Modified: 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/FolderStoreProvider.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/FolderStoreProvider.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/FolderStoreProvider.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/FolderStoreProvider.java
 [UTF-8] Sat Feb 24 15:36:52 2018
@@ -16,13 +16,17 @@
  */
 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;
@@ -39,6 +43,9 @@ import org.apache.sis.util.logging.Loggi
 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;
 
 // Branch-dependent imports
@@ -52,15 +59,16 @@ import org.apache.sis.parameter.DefaultP
  *
  * @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.
@@ -78,6 +86,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;
@@ -88,8 +102,9 @@ public final class FolderStoreProvider e
         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);
+        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);
+        PARAMETERS = builder.addName(NAME).createGroup(location, LOCALE, 
TIMEZONE, ENCODING, FORMAT, URIDataStore.Provider.CREATE_PARAM);
     }
 
     /**
@@ -101,8 +116,6 @@ public final class FolderStoreProvider e
 
     /**
      * The unique instance of this provider.
-     *
-     * @see #open(Path)
      */
     public static final FolderStoreProvider INSTANCE = new 
FolderStoreProvider();
 
@@ -157,6 +170,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.
@@ -164,12 +179,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;
     }
 
     /**
@@ -186,17 +278,10 @@ public final class FolderStoreProvider e
         connector.setOption(OptionKey.LOCALE,   pg.getValue(LOCALE));
         connector.setOption(OptionKey.TIMEZONE, pg.getValue(TIMEZONE));
         connector.setOption(OptionKey.ENCODING, pg.getValue(ENCODING));
-        return open(connector);
-    }
-
-    /**
-     * 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));
+        final EnumSet<StandardOpenOption> options = 
EnumSet.of(StandardOpenOption.WRITE);
+        if 
(Boolean.TRUE.equals(pg.getValue(URIDataStore.Provider.CREATE_PARAM))) {
+            options.add(StandardOpenOption.CREATE);
+        }
+        return open(connector, pg.getValue(FORMAT), options);
     }
 }

Modified: 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
 [UTF-8] Sat Feb 24 15:36:52 2018
@@ -22,6 +22,8 @@ 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;
@@ -29,8 +31,6 @@ import java.nio.file.DirectoryStream;
 import java.nio.file.DirectoryIteratorException;
 import java.io.IOException;
 import java.io.UncheckedIOException;
-import java.util.logging.Level;
-import java.util.concurrent.ConcurrentHashMap;
 import org.opengis.metadata.Metadata;
 import org.opengis.metadata.maintenance.ScopeCode;
 import org.opengis.parameter.ParameterValueGroup;
@@ -46,6 +46,7 @@ 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;
 
 
@@ -67,36 +68,36 @@ import org.apache.sis.internal.storage.R
  *
  * @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.
@@ -110,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.
@@ -120,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;
     }
 
     /**
@@ -145,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;
     }
 
     /**
@@ -157,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;
     }
 
@@ -202,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.
@@ -228,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);
@@ -259,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());
@@ -268,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.
     }
@@ -294,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/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/package-info.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/package-info.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/package-info.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/package-info.java
 [UTF-8] Sat Feb 24 15:36:52 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/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java
 [UTF-8] Sat Feb 24 15:36:52 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/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java
 [UTF-8] Sat Feb 24 15:36:52 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/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
 [UTF-8] Sat Feb 24 15:36:52 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/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/Aggregate.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/Aggregate.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/Aggregate.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/Aggregate.java
 [UTF-8] Sat Feb 24 15:36:52 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 {@code 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/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
 [UTF-8] Sat Feb 24 15:36:52 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/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
 [UTF-8] Sat Feb 24 15:36:52 2018
@@ -57,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
  */
@@ -69,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() {
@@ -156,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>
      *
@@ -174,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()
      *
@@ -280,6 +312,8 @@ 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

Modified: 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java
 [UTF-8] Sat Feb 24 15:36:52 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/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java
 [UTF-8] Sat Feb 24 15:36:52 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/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureSet.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureSet.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureSet.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureSet.java
 [UTF-8] Sat Feb 24 15:36:52 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.apache.sis.feature.AbstractFeature;
 import org.apache.sis.feature.DefaultFeatureType;
 
@@ -35,7 +31,7 @@ import org.apache.sis.feature.DefaultFea
  * 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<AbstractFeature> 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 AbstractFeature> 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 AbstractFeature> 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 {@code 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 {@code 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 {@code 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 AbstractFeature> filter, 
UnaryOperator<AbstractFeature> updater)
-            throws ReadOnlyStorageException, DataStoreException
-    {
-        throw new ReadOnlyStorageException(this, 
Resources.Keys.StoreIsReadOnly);
-    }
 }

Modified: 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/ReadOnlyStorageException.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/ReadOnlyStorageException.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/ReadOnlyStorageException.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/ReadOnlyStorageException.java
 [UTF-8] Sat Feb 24 15:36:52 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);
-    }
 }

Copied: 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/WritableFeatureSet.java
 (from r1825247, 
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/WritableFeatureSet.java)
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/WritableFeatureSet.java?p2=sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/WritableFeatureSet.java&p1=sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/WritableFeatureSet.java&r1=1825247&r2=1825249&rev=1825249&view=diff
==============================================================================
--- 
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/storage/WritableFeatureSet.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/WritableFeatureSet.java
 [UTF-8] Sat Feb 24 15:36:52 2018
@@ -22,8 +22,8 @@ import java.util.function.Predicate;
 import java.util.function.UnaryOperator;
 
 // Branch-dependent imports
-import org.opengis.feature.Feature;
-import org.opengis.feature.FeatureType;
+import org.apache.sis.feature.AbstractFeature;
+import org.apache.sis.feature.DefaultFeatureType;
 
 
 /**
@@ -49,7 +49,7 @@ public interface WritableFeatureSet exte
      * @throws IllegalFeatureTypeException if the given type is not compatible 
with the types supported by the store.
      * @throws DataStoreException if another error occurred while changing the 
feature type.
      */
-    void updateType(FeatureType newType) throws IllegalFeatureTypeException, 
DataStoreException;
+    void updateType(DefaultFeatureType newType) throws 
IllegalFeatureTypeException, DataStoreException;
 
     /**
      * Inserts new features in this {@code FeatureSet}.
@@ -64,7 +64,7 @@ public interface WritableFeatureSet exte
      * @param  features features to insert in this {@code FeatureSet}.
      * @throws DataStoreException if another error occurred while storing new 
features.
      */
-    void add(Iterator<? extends Feature> features) throws DataStoreException;
+    void add(Iterator<? extends AbstractFeature> features) throws 
DataStoreException;
 
     /**
      * Removes all features from this {@code FeatureSet} which matches the 
given predicate.
@@ -73,24 +73,24 @@ public interface WritableFeatureSet exte
      * @return {@code true} if any elements were removed.
      * @throws DataStoreException if another error occurred while removing 
features.
      */
-    boolean removeIf(Predicate<? super Feature> filter) throws 
DataStoreException;
+    boolean removeIf(Predicate<? super AbstractFeature> filter) throws 
DataStoreException;
 
     /**
      * Updates all features from this {@code FeatureSet} which matches the 
given predicate.
-     * For each {@link Feature} instance matching the given {@link Predicate},
+     * For each {@code 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
+     *   <li>If the operator returns a non-null {@code 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>
      *
      * @param  filter   a predicate which returns true for resources to be 
updated.
-     * @param  updater  operation called for each matching {@link Feature}.
+     * @param  updater  operation called for each matching {@code Feature}.
      * @throws DataStoreException if another error occurred while replacing 
features.
      */
-    void replaceIf(Predicate<? super Feature> filter, UnaryOperator<Feature> 
updater)
+    void replaceIf(Predicate<? super AbstractFeature> filter, 
UnaryOperator<AbstractFeature> updater)
             throws DataStoreException;
 }

Modified: 
sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/folder/StoreTest.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/folder/StoreTest.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/folder/StoreTest.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/folder/StoreTest.java
 [UTF-8] Sat Feb 24 15:36:52 2018
@@ -24,6 +24,7 @@ import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
+import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.metadata.identification.Identification;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.storage.Aggregate;
@@ -42,7 +43,7 @@ import static org.junit.Assume.assumeTru
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.8
  * @module
  */
@@ -68,9 +69,32 @@ public final strictfp class StoreTest ex
      */
     @Test
     public void testComponents() throws URISyntaxException, 
DataStoreException, IOException {
+        final Set<String> identifiers = new 
HashSet<>(Arrays.asList("EPSG:4326", "Sample 1", "Sample 2", "Sample 3", 
"data4"));
+        final Path path = testDirectory();
+        try (Store store = new Store(null, new StorageConnector(path), path, 
null)) {
+            assertEquals("Wrong number of data stores.", 4, 
store.components().size());
+            verifyContent(store, identifiers);
+        }
+        if (!identifiers.isEmpty()) {
+            fail("Missing resources: " + identifiers);
+        }
+    }
+
+    /**
+     * Verifies that specifying a format effectively restricts the number of 
resources to be found.
+     *
+     * @throws URISyntaxException if the URL to test data can not be converted 
to a path of the file system.
+     * @throws DataStoreException if an error occurred while reading the 
resources.
+     * @throws IOException if an I/O error occurs.
+     */
+    @Test
+    public void testSearchProviderParameter() throws URISyntaxException, 
DataStoreException, IOException {
         final Set<String> identifiers = new HashSet<>(Arrays.asList("Sample 
1", "Sample 2", "Sample 3", "data4"));
-        try (Store store = new Store(null, new 
StorageConnector(testDirectory()))) {
-            assertEquals("Expected three data stores.", 3, 
store.components().size());
+        final ParameterValueGroup params = 
FolderStoreProvider.PARAMETERS.createValue();
+        params.parameter("location").setValue(testDirectory());
+        params.parameter("format").setValue("XML");
+        try (Store store = (Store) FolderStoreProvider.INSTANCE.open(params)) {
+            assertEquals("Expected one less data store.", 3, 
store.components().size());
             verifyContent(store, identifiers);
         }
         if (!identifiers.isEmpty()) {

Modified: 
sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/storage/StorageConnectorTest.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/storage/StorageConnectorTest.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/storage/StorageConnectorTest.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/storage/StorageConnectorTest.java
 [UTF-8] Sat Feb 24 15:36:52 2018
@@ -191,7 +191,7 @@ public final strictfp class StorageConne
         final byte[] sample = new byte[32];
         data.readFully(sample);
         /*
-         * Request again the InputStream and read the same amount of bytes 
than above. The intend of this test
+         * Request again the InputStream and read the same amount of bytes 
than above. The intent of this test
          * is to verify that StorageConnector has reseted the InputStream 
position before to return it.
          * Note that this test requires InputStream implementations supporting 
mark/reset operations
          * (which is the case when the resource is an ordinary file, not an 
entry inside a JAR file),

Modified: 
sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/GroupAsPolylineOperation.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/GroupAsPolylineOperation.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/GroupAsPolylineOperation.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/GroupAsPolylineOperation.java
 [UTF-8] Sat Feb 24 15:36:52 2018
@@ -137,7 +137,7 @@ final class GroupAsPolylineOperation ext
      * The attribute resulting from execution if the {@link 
GroupAsPolylineOperation}.
      * The value is computed when first requested, then cached for this {@code 
Result} instance only.
      * Note that the cache is not used when {@code apply(Feature, 
ParameterValueGroup)} is invoked,
-     * causing a new value to be computed again. The intend is to behave as if 
the operation has been
+     * causing a new value to be computed again. The intent is to behave as if 
the operation has been
      * executed at {@code apply(…)} invocation time, even if we deferred the 
actual execution.
      *
      * @param  <G>  the root geometry class (implementation-dependent).

Modified: 
sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Link.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Link.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Link.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Link.java
 [UTF-8] Sat Feb 24 15:36:52 2018
@@ -99,7 +99,7 @@ public final class Link implements Onlin
 
     /**
      * Invoked by JAXB after unmarshalling. If the {@linkplain #uri} is not 
set but the {@link #text} looks
-     * like a URI, uses that text. The intend is to handle link that should 
have been defined like below:
+     * like a URI, uses that text. The intent is to handle link that should 
have been defined like below:
      *
      * {@preformat xml
      *   <link href="http://some.site.org";>

Modified: 
sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java?rev=1825249&r1=1825248&r2=1825249&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java
 [UTF-8] Sat Feb 24 15:36:52 2018
@@ -22,7 +22,7 @@ import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.StorageConnector;
 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.xml.stream.StaxDataStoreProvider;
 import org.apache.sis.measure.Range;
 import org.apache.sis.util.Version;
@@ -34,11 +34,13 @@ import org.apache.sis.util.Version;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.8
  * @module
  */
-@Capabilities({Capability.READ, Capability.WRITE})
+@StoreMetadata(formatName   = "GPX",
+               fileSuffixes = "xml",
+               capabilities = {Capability.READ, Capability.WRITE})
 public final class StoreProvider extends StaxDataStoreProvider {
     /**
      * The "1.0" version.


Reply via email to