Modified: 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.internal.netcdf.ucar;
 
+import java.io.File;
 import java.util.Date;
 import java.util.List;
 import java.util.EnumSet;
@@ -44,11 +45,13 @@ import org.apache.sis.internal.netcdf.De
 import org.apache.sis.internal.netcdf.Variable;
 import org.apache.sis.internal.netcdf.GridGeometry;
 import org.apache.sis.internal.netcdf.DiscreteSampling;
+import org.apache.sis.setup.GeometryLibrary;
 import org.apache.sis.storage.DataStore;
+import org.apache.sis.storage.DataStoreException;
 
 
 /**
- * Provides NetCDF decoding services based on the NetCDF library.
+ * Provides netCDF decoding services based on the netCDF library.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 0.8
@@ -57,7 +60,7 @@ import org.apache.sis.storage.DataStore;
  */
 public final class DecoderWrapper extends Decoder implements CancelTask {
     /**
-     * The NetCDF file to read.
+     * The netCDF file to read.
      * This file is set at construction time.
      *
      * <p>This {@code DecoderWrapper} class does <strong>not</strong> close 
this file.
@@ -95,39 +98,54 @@ public final class DecoderWrapper extend
     private transient GridGeometry[] geometries;
 
     /**
-     * Creates a new decoder for the given NetCDF file. While this constructor 
accepts arbitrary
+     * Creates a new decoder for the given netCDF file. While this constructor 
accepts arbitrary
      * {@link NetcdfFile} instance, the {@link NetcdfDataset} subclass is 
necessary in order to
      * get coordinate system information.
      *
+     * @param geomlib    the library for geometric objects, or {@code null} 
for the default.
+     * @param file       the netCDF file from which to read data.
      * @param listeners  where to send the warnings.
-     * @param file       the NetCDF file from which to read data.
      */
-    public DecoderWrapper(final WarningListeners<DataStore> listeners, final 
NetcdfFile file) {
-        super(listeners);
+    public DecoderWrapper(final NetcdfFile file, final GeometryLibrary 
geomlib, final WarningListeners<DataStore> listeners) {
+        super(geomlib, listeners);
         this.file = file;
     }
 
     /**
      * Creates a new decoder for the given filename.
      *
+     * @param  geomlib    the library for geometric objects, or {@code null} 
for the default.
+     * @param  filename   the name of the netCDF file from which to read data.
      * @param  listeners  where to send the warnings.
-     * @param  filename   the name of the NetCDF file from which to read data.
-     * @throws IOException if an error occurred while opening the NetCDF file.
+     * @throws IOException if an error occurred while opening the netCDF file.
      */
     @SuppressWarnings("ThisEscapedInObjectConstruction")
-    public DecoderWrapper(final WarningListeners<DataStore> listeners, final 
String filename) throws IOException {
-        super(listeners);
+    public DecoderWrapper(final String filename, final GeometryLibrary 
geomlib, final WarningListeners<DataStore> listeners)
+            throws IOException
+    {
+        super(geomlib, listeners);
         file = NetcdfDataset.openDataset(filename, false, this);
     }
 
     /**
-     * Returns a filename for information purpose only. This is used for 
formatting error messages.
+     * Returns a filename for formatting error message and for information 
purpose.
+     * The filename should not contain path.
      *
      * @return a filename to report in warning or error messages.
      */
     @Override
     public String getFilename() {
-        return file.getLocation();
+        String filename = file.getLocation();
+        if (filename != null) {
+            int s = filename.lastIndexOf(File.separatorChar);
+            if (s < 0 && File.separatorChar != '/') {
+                s = filename.lastIndexOf('/');
+            }
+            if (s >= 0) {
+                filename = filename.substring(s+1);
+            }
+        }
+        return filename;
     }
 
     /**
@@ -154,7 +172,7 @@ public final class DecoderWrapper extend
     /**
      * Returns the path which is currently set. The array returned by this 
method may be only
      * a subset of the array given to {@link #setSearchPath(String[])} since 
only the name of
-     * groups which have been found in the NetCDF file are returned by this 
method.
+     * groups which have been found in the netCDF file are returned by this 
method.
      *
      * @return the current search path.
      */
@@ -181,7 +199,7 @@ public final class DecoderWrapper extend
     }
 
     /**
-     * Returns the NetCDF attribute of the given name in the given group, or 
{@code null} if none.
+     * Returns the netCDF attribute of the given name in the given group, or 
{@code null} if none.
      * This method is invoked for every global and group attributes to be read 
by this class (but
      * not {@linkplain ucar.nc2.VariableSimpleIF variable} attributes), thus 
providing a single point
      * where we can filter the attributes to be read - if we want to do that 
in a future version.
@@ -323,7 +341,7 @@ public final class DecoderWrapper extend
     }
 
     /**
-     * Returns all variables found in the NetCDF file.
+     * Returns all variables found in the netCDF file.
      * This method returns a direct reference to an internal array - do not 
modify.
      *
      * @return all variables, or an empty array if none.
@@ -346,10 +364,11 @@ public final class DecoderWrapper extend
      *
      * @return {@inheritDoc}
      * @throws IOException if an I/O operation was necessary but failed.
+     * @throws DataStoreException if the library of geometric objects is not 
available.
      */
     @Override
     @SuppressWarnings("null")
-    public DiscreteSampling[] getDiscreteSampling() throws IOException {
+    public DiscreteSampling[] getDiscreteSampling() throws IOException, 
DataStoreException {
         if (features == null && file instanceof NetcdfDataset) {
             features = FeatureDatasetFactoryManager.wrap(null, (NetcdfDataset) 
file, this,
                     new Formatter(new LogAdapter(listeners), 
listeners.getLocale()));
@@ -359,14 +378,18 @@ public final class DecoderWrapper extend
             fc = ((FeatureDatasetPoint) 
features).getPointFeatureCollectionList();
         }
         final FeaturesWrapper[] wrappers = new FeaturesWrapper[(fc != null) ? 
fc.size() : 0];
-        for (int i=0; i<wrappers.length; i++) {
-            wrappers[i] = new FeaturesWrapper(fc.get(i));
+        try {
+            for (int i=0; i<wrappers.length; i++) {
+                wrappers[i] = new FeaturesWrapper(fc.get(i), geomlib, 
listeners);
+            }
+        } catch (IllegalArgumentException e) {
+            throw new DataStoreException(e.getLocalizedMessage(), e);
         }
         return wrappers;
     }
 
     /**
-     * Returns all grid geometries (related to coordinate systems) found in 
the NetCDF file.
+     * Returns all grid geometries (related to coordinate systems) found in 
the netCDF file.
      * This method returns a direct reference to an internal array - do not 
modify.
      *
      * @return all grid geometries, or an empty array if none.
@@ -394,7 +417,7 @@ public final class DecoderWrapper extend
     }
 
     /**
-     * Invoked by the UCAR NetCDF library for checking if the reading process 
has been canceled.
+     * Invoked by the UCAR netCDF library for checking if the reading process 
has been canceled.
      * This method returns the {@link #canceled} flag.
      *
      * @return the {@link #canceled} flag.
@@ -415,7 +438,7 @@ public final class DecoderWrapper extend
     }
 
     /**
-     * Invoked by the UCAR NetCDF library when an error occurred.
+     * Invoked by the UCAR netCDF library when an error occurred.
      *
      * @param  message  the error message.
      */
@@ -425,7 +448,7 @@ public final class DecoderWrapper extend
     }
 
     /**
-     * Closes the NetCDF file.
+     * Closes the netCDF file.
      *
      * @throws IOException if an error occurred while closing the file.
      */

Modified: 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/FeaturesWrapper.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/FeaturesWrapper.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/FeaturesWrapper.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/FeaturesWrapper.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -16,12 +16,16 @@
  */
 package org.apache.sis.internal.netcdf.ucar;
 
+import org.apache.sis.storage.DataStore;
+import org.apache.sis.setup.GeometryLibrary;
 import org.apache.sis.internal.netcdf.DiscreteSampling;
+import org.apache.sis.util.logging.WarningListeners;
 import ucar.nc2.ft.FeatureCollection;
 
 // Branch-dependent imports
 import org.apache.sis.internal.jdk8.Stream;
 import org.apache.sis.feature.AbstractFeature;
+import org.apache.sis.feature.DefaultFeatureType;
 
 
 /**
@@ -40,17 +44,26 @@ final class FeaturesWrapper extends Disc
 
     /**
      * Creates a new discrete sampling parser.
+     *
+     * @param  factory    the library for geometric objects, or {@code null} 
for the default.
+     * @param  listeners  the set of registered warning listeners for the data 
store.
+     * @throws IllegalArgumentException if the given library is non-null but 
not available.
      */
-    FeaturesWrapper(final FeatureCollection features) {
+    FeaturesWrapper(final FeatureCollection features, final GeometryLibrary 
factory, final WarningListeners<DataStore> listeners) {
+        super(factory, listeners);
         this.features = features;
     }
 
+    @Override
+    public DefaultFeatureType getType() {
+        throw new UnsupportedOperationException();      // TODO
+    }
 
     /**
      * Returns the stream of features.
      */
     @Override
-    public Stream<AbstractFeature> features() {
+    public Stream<AbstractFeature> features(boolean parallel) {
         throw new UnsupportedOperationException();      // TODO
     }
 }

Modified: 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridGeometryWrapper.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridGeometryWrapper.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridGeometryWrapper.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridGeometryWrapper.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -31,7 +31,7 @@ import org.apache.sis.util.ArraysExt;
 
 
 /**
- * Information about NetCDF coordinate system, which include information about 
grid geometries.
+ * Information about netCDF coordinate system, which include information about 
grid geometries.
  * In OGC/ISO specifications, the coordinate system and the grid geometries 
are distinct entities.
  * However the UCAR model takes a different point of view where the coordinate 
system holds some
  * of the grid geometry information.
@@ -43,14 +43,14 @@ import org.apache.sis.util.ArraysExt;
  */
 final class GridGeometryWrapper extends GridGeometry {
     /**
-     * The NetCDF coordinate system to wrap.
+     * The netCDF coordinate system to wrap.
      */
     private final CoordinateSystem netcdfCS;
 
     /**
-     * Creates a new grid geometry for the given NetCDF coordinate system.
+     * Creates a new grid geometry for the given netCDF coordinate system.
      *
-     * @param  cs  the NetCDF coordinate system, or {@code null} if none.
+     * @param  cs  the netCDF coordinate system, or {@code null} if none.
      */
     GridGeometryWrapper(final CoordinateSystem cs) {
         netcdfCS = cs;
@@ -77,10 +77,10 @@ final class GridGeometryWrapper extends
     }
 
     /**
-     * Returns all axes of the NetCDF coordinate system, together with the 
grid dimension to which the axis
+     * Returns all axes of the netCDF coordinate system, together with the 
grid dimension to which the axis
      * is associated.
      *
-     * <p>In this method, the words "domain" and "range" are used in the 
NetCDF sense: they are the input
+     * <p>In this method, the words "domain" and "range" are used in the 
netCDF sense: they are the input
      * (domain) and output (range) of the function that convert grid indices 
to geodetic coordinates.</p>
      *
      * <p>The domain of all axes (or the {@linkplain 
CoordinateSystem#getDomain() coordinate system domain})
@@ -88,7 +88,7 @@ final class GridGeometryWrapper extends
      * In particular, the relationship is not straightforward when the 
coordinate system contains instances
      * of {@link CoordinateAxis2D}.</p>
      *
-     * @return the CRS axes, in NetCDF order (reverse of "natural" order).
+     * @return the CRS axes, in netCDF order (reverse of "natural" order).
      * @throws IOException if an I/O operation was necessary but failed.
      * @throws DataStoreException if a logical error occurred.
      */
@@ -121,7 +121,7 @@ final class GridGeometryWrapper extends
             /*
              * Get the grid dimensions (part of the "domain" in UCAR 
terminology) used for computing
              * the ordinate values along the current axis. There is exactly 1 
such grid dimension in
-             * straightforward NetCDF files. However some more complex files 
may have 2 dimensions.
+             * straightforward netCDF files. However some more complex files 
may have 2 dimensions.
              */
             int i = 0;
             final List<Dimension> axisDomain = axis.getDimensions();
@@ -135,7 +135,7 @@ final class GridGeometryWrapper extends
                 }
                 /*
                  * If the axis dimension has not been found in the coordinate 
system (sourceDim < 0),
-                 * then there is maybe a problem with the NetCDF file. However 
for the purpose of this
+                 * then there is maybe a problem with the netCDF file. However 
for the purpose of this
                  * package, we can proceed as if the dimension does not exist 
('i' not incremented).
                  */
             }

Modified: 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/LogAdapter.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/LogAdapter.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/LogAdapter.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/LogAdapter.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -22,7 +22,7 @@ import org.apache.sis.util.logging.Warni
 
 
 /**
- * Forwards NetCDF logging to the Apache SIS warning listeners.
+ * Forwards netCDF logging to the Apache SIS warning listeners.
  * NetCDF sends message to a user-specified {@link java.util.Formatter} with 
one message per line.
  * This class intercepts the characters and send them to the {@link 
WarningListeners} every time
  * that a complete line has been received.
@@ -34,7 +34,7 @@ import org.apache.sis.util.logging.Warni
  */
 final class LogAdapter implements Appendable {
     /**
-     * Temporary buffer where to append the NetCDF logging messages.
+     * Temporary buffer where to append the netCDF logging messages.
      */
     private final StringBuilder buffer = new StringBuilder();
 

Modified: 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -34,7 +34,7 @@ import org.apache.sis.storage.DataStoreC
 
 
 /**
- * A {@link Variable} backed by the UCAR NetCDF library.
+ * A {@link Variable} backed by the UCAR netCDF library.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
@@ -44,12 +44,12 @@ import org.apache.sis.storage.DataStoreC
  */
 final class VariableWrapper extends Variable {
     /**
-     * The NetCDF variable.
+     * The netCDF variable.
      */
     private final VariableIF variable;
 
     /**
-     * Creates a new variable wrapping the given NetCDF interface.
+     * Creates a new variable wrapping the given netCDF interface.
      */
     VariableWrapper(final VariableIF variable) {
         this.variable = variable;

Modified: 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/package-info.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/package-info.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/package-info.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/package-info.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -17,7 +17,7 @@
 
 /**
  * Implementation of the {@link org.apache.sis.internal.netcdf} API
- * as wrappers around the UCAR NetCDF library.
+ * as wrappers around the UCAR netCDF library.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @version 0.8

Modified: 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/AttributeNames.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/AttributeNames.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/AttributeNames.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/AttributeNames.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -52,10 +52,10 @@ import org.opengis.metadata.extent.Geogr
 
 
 /**
- * Name of attributes used in the mapping from/to NetCDF metadata to ISO 19115 
metadata.
+ * Name of attributes used in the mapping from/to netCDF metadata to ISO 19115 
metadata.
  * The attributes recognized by SIS are listed below:
  *
- * <blockquote><table class="compact" summary="List of all NetCDF attributes.">
+ * <blockquote><table class="compact" summary="List of all netCDF attributes.">
  * <tr valign="top"><td style="width: 25%">
  * {@value     #ACCESS_CONSTRAINT}<br>
  * {@value     #ACKNOWLEDGEMENT}<br>
@@ -376,7 +376,7 @@ public class AttributeNames {
      * class and the other cells give the values assigned in this class fields 
for those constants.
      *
      * <table class="sis">
-     * <caption>Names of NetCDF attributes describing a responsible 
party</caption>
+     * <caption>Names of netCDF attributes describing a responsible 
party</caption>
      * <tr>
      *   <th            >Field in this class</th>
      *   <th class="sep">{@link AttributeNames#CREATOR     CREATOR}</th>
@@ -419,7 +419,7 @@ public class AttributeNames {
      * For example {@code AttributeNames.CREATOR.EMAIL} maps exactly to the 
{@code "creator_email"} string
      * and nothing else. A lower-case {@code email} member name could be 
misleading since it would suggest
      * that the field contains the actual name value rather than the key by 
which the value is identified
-     * in a NetCDF file.</div>
+     * in a netCDF file.</div>
      *
      * @author  Martin Desruisseaux (Geomatys)
      * @version 0.3
@@ -669,7 +669,7 @@ public class AttributeNames {
      * class and the other cells give the values assigned in this class fields 
for those constants.
      *
      * <table class="sis">
-     * <caption>Names of NetCDF attributes describing an extent</caption>
+     * <caption>Names of netCDF attributes describing an extent</caption>
      * <tr>
      *   <th            >Field in this class</th>
      *   <th class="sep">{@link AttributeNames#LATITUDE  LATITUDE}</th>
@@ -725,7 +725,7 @@ public class AttributeNames {
      * For example {@code AttributeNames.LATITUDE.MINIMUM} maps exactly to the 
{@code "geospatial_lat_min"}
      * string and nothing else. A lower-case {@code minimum} member name could 
be misleading since it would
      * suggest that the field contains the actual name value rather than the 
key by which the value is
-     * identified in a NetCDF file.</div>
+     * identified in a netCDF file.</div>
      *
      * @author  Martin Desruisseaux (Geomatys)
      * @version 0.3
@@ -785,12 +785,12 @@ public class AttributeNames {
         /**
          * The default ISO-19115 dimension name type, or {@code null} if none.
          * By default, {@link DimensionNameType#COLUMN} is associated to 
longitudes and {@link DimensionNameType#ROW}
-         * to latitudes since geographic maps in NetCDF files are typically 
shown horizontally.
+         * to latitudes since geographic maps in netCDF files are typically 
shown horizontally.
          *
          * <p>The default associations may not be always correct since the 
columns and rows can be anything.
          * Strictly speaking, the dimension name types shall be associated to 
the <em>grid axes</em> rather
          * than the <em>coordinate system axes</em>. However the default 
association is correct in the common case
-         * (for NetCDF files) where there is no axis swapping in the 
<cite>grid to CRS</cite> conversion.</p>
+         * (for netCDF files) where there is no axis swapping in the 
<cite>grid to CRS</cite> conversion.</p>
          */
         public final DimensionNameType DEFAULT_NAME_TYPE;
 

Modified: 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -60,6 +60,7 @@ import org.apache.sis.internal.netcdf.Ax
 import org.apache.sis.internal.netcdf.Decoder;
 import org.apache.sis.internal.netcdf.Variable;
 import org.apache.sis.internal.netcdf.GridGeometry;
+import org.apache.sis.internal.storage.io.IOUtilities;
 import org.apache.sis.internal.storage.MetadataBuilder;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.util.CollectionsExt;
@@ -74,11 +75,10 @@ import ucar.nc2.constants.CF;
 
 import static java.util.Collections.singleton;
 import static org.apache.sis.storage.netcdf.AttributeNames.*;
-import static org.apache.sis.internal.util.CollectionsExt.first;
 
 
 /**
- * Mapping from NetCDF metadata to ISO 19115-2 metadata. The {@link String} 
constants declared in
+ * Mapping from netCDF metadata to ISO 19115-2 metadata. The {@link String} 
constants declared in
  * the {@linkplain AttributeNames parent class} are the name of attributes 
examined by this class.
  * The current implementation searches the attribute values in the following 
places, in that order:
  *
@@ -144,7 +144,7 @@ final class MetadataReader extends Metad
     private static final VerticalCRS VERTICAL_CRS = null;
 
     /**
-     * The source of NetCDF attributes from which to infer ISO metadata.
+     * The source of netCDF attributes from which to infer ISO metadata.
      * This source is set at construction time.
      *
      * <p>This {@code MetadataReader} class does <strong>not</strong> close 
this source.
@@ -171,7 +171,7 @@ final class MetadataReader extends Metad
      * more than once.
      *
      * <p>The point of contact is stored in the two following places. The 
semantic of those two
-     * contacts is not strictly identical, but the distinction is not used in 
NetCDF file:</p>
+     * contacts is not strictly identical, but the distinction is not used in 
netCDF file:</p>
      *
      * <ul>
      *   <li>{@link DefaultMetadata#getContacts()}</li>
@@ -184,9 +184,9 @@ final class MetadataReader extends Metad
     private transient ResponsibleParty pointOfContact;
 
     /**
-     * Creates a new <cite>NetCDF to ISO</cite> mapper for the given source.
+     * Creates a new <cite>netCDF to ISO</cite> mapper for the given source.
      *
-     * @param  decoder  the source of NetCDF attributes.
+     * @param  decoder  the source of netCDF attributes.
      */
     MetadataReader(final Decoder decoder) {
         this.decoder = decoder;
@@ -327,22 +327,22 @@ split:  while ((start = CharSequences.sk
     }
 
     /**
-     * Returns {@code true} if the given NetCDF attribute is either null or 
equals to the
+     * Returns {@code true} if the given netCDF attribute is either null or 
equals to the
      * string value of the given metadata value.
      *
      * @param metadata  The value stored in the metadata object.
-     * @param attribute The value parsed from the NetCDF file.
+     * @param attribute The value parsed from the netCDF file.
      */
     private static boolean canShare(final CharSequence metadata, final String 
attribute) {
         return (attribute == null) || (metadata != null && 
metadata.toString().equals(attribute));
     }
 
     /**
-     * Returns {@code true} if the given NetCDF attribute is either null or 
equals to one
+     * Returns {@code true} if the given netCDF attribute is either null or 
equals to one
      * of the values in the given collection.
      *
      * @param  metadata   the value stored in the metadata object.
-     * @param  attribute  the value parsed from the NetCDF file.
+     * @param  attribute  the value parsed from the netCDF file.
      */
     private static boolean canShare(final Collection<String> metadata, final 
String attribute) {
         return (attribute == null) || metadata.contains(attribute);
@@ -352,7 +352,7 @@ split:  while ((start = CharSequences.sk
      * Returns {@code true} if the given URL is null, or if the given resource 
contains that URL.
      *
      * @param  resource  the value stored in the metadata object.
-     * @param  url       the value parsed from the NetCDF file.
+     * @param  url       the value parsed from the netCDF file.
      */
     private static boolean canShare(final OnlineResource resource, final 
String url) {
         return (url == null) || (resource != null && 
canShare(resource.getLinkage().toString(), url));
@@ -362,7 +362,7 @@ split:  while ((start = CharSequences.sk
      * Returns {@code true} if the given email is null, or if the given 
address contains that email.
      *
      * @param  address  the value stored in the metadata object.
-     * @param  email    the value parsed from the NetCDF file.
+     * @param  email    the value parsed from the netCDF file.
      */
     private static boolean canShare(final Address address, final String email) 
{
         return (email == null) || (address != null && 
canShare(address.getElectronicMailAddresses(), email));
@@ -542,7 +542,7 @@ split:  while ((start = CharSequences.sk
             }
         }
         /*
-         * There is no distinction in NetCDF files between "point of contact" 
and "creator".
+         * There is no distinction in netCDF files between "point of contact" 
and "creator".
          * We take the first one as the data originator.
          */
         addCitedResponsibleParty(pointOfContact, Role.ORIGINATOR);
@@ -595,7 +595,7 @@ split:  while ((start = CharSequences.sk
             
addSpatialRepresentation(forCodeName(SpatialRepresentationType.class, 
stringValue(DATA_TYPE)));
             if (!hasExtent) {
                 /*
-                 * Takes only ONE extent, because a NetCDF file may declare 
many time the same
+                 * Takes only ONE extent, because a netCDF file may declare 
many time the same
                  * extent with different precision. The groups are ordered in 
such a way that
                  * the first extent should be the most accurate one.
                  */
@@ -614,15 +614,15 @@ split:  while ((start = CharSequences.sk
         addUseLimitation          (stringValue(LICENSE));
         addKeywords(standard,  KeywordType.THEME,       
stringValue(STANDARD_NAME_VOCABULARY));
         addKeywords(keywords,  KeywordType.THEME,       
stringValue(VOCABULARY));
-        addKeywords(project,   KeywordType.valueOf("project"), null);
-        addKeywords(publisher, KeywordType.valueOf("dataCentre"), null);
+        addKeywords(project,   KeywordType.valueOf("PROJECT"), null);
+        addKeywords(publisher, KeywordType.valueOf("DATA_CENTRE"), null);
     }
 
     /**
      * Adds information about axes and cell geometry.
      * This is the {@code <gmd:spatialRepresentationInfo>} element in XML.
      *
-     * @param  cs  the grid geometry (related to the NetCDF coordinate system).
+     * @param  cs  the grid geometry (related to the netCDF coordinate system).
      */
     private void addSpatialRepresentationInfo(final GridGeometry cs) throws 
IOException, DataStoreException {
         final Axis[] axes = cs.getAxes();
@@ -630,7 +630,7 @@ split:  while ((start = CharSequences.sk
             final int dim = axes.length - i;
             final Axis axis = axes[--i];
             /*
-             * Axes usually have exactly one dimension. However some NetCDF 
axes are backed by a two-dimensional
+             * Axes usually have exactly one dimension. However some netCDF 
axes are backed by a two-dimensional
              * conversion grid. In such case, our Axis constructor should have 
ensured that the first element in
              * the 'sourceDimensions' and 'sourceSizes' arrays are for the 
grid dimension which is most closely
              * oriented toward the axis direction.
@@ -750,7 +750,7 @@ split:  while ((start = CharSequences.sk
     }
 
     /**
-     * Adds information about all NetCDF variables. This is the {@code 
<gmd:contentInfo>} element in XML.
+     * Adds information about all netCDF variables. This is the {@code 
<gmd:contentInfo>} element in XML.
      * This method groups variables by their domains, i.e. variables having 
the same set of axes are grouped together.
      */
     private void addContentInfo() {
@@ -764,7 +764,7 @@ split:  while ((start = CharSequences.sk
         final String processingLevel = stringValue(PROCESSING_LEVEL);
         for (final List<Variable> group : contents.values()) {
             /*
-             * Instantiate a CoverageDescription for each distinct set of 
NetCDF dimensions
+             * Instantiate a CoverageDescription for each distinct set of 
netCDF dimensions
              * (e.g. longitude,latitude,time). This separation is based on the 
fact that a
              * coverage has only one domain for every range of values.
              */
@@ -792,7 +792,7 @@ split:  while ((start = CharSequences.sk
      * Adds metadata about a sample dimension (or band) from the given 
variable.
      * This is the {@code <gmd:dimension>} element in XML.
      *
-     * @param  variable  the NetCDF variable.
+     * @param  variable  the netCDF variable.
      */
     private void addSampleDimension(final Variable variable) {
         newSampleDimension();
@@ -835,7 +835,7 @@ split:  while ((start = CharSequences.sk
      * <p><b>Note:</b> ISO 19115 range elements are approximatively equivalent 
to
      * {@code org.apache.sis.coverage.Category} in the {@code sis-coverage} 
module.</p>
      *
-     * @param  variable  the NetCDF variable.
+     * @param  variable  the netCDF variable.
      * @param  name      one of the elements in the {@link 
AttributeNames#FLAG_NAMES} attribute, or {@code null}.
      * @param  meaning   one of the elements in the {@link 
AttributeNames#FLAG_MEANINGS} attribute or {@code null}.
      * @param  mask      one of the elements in the {@link 
AttributeNames#FLAG_MASKS} attribute or {@code null}.
@@ -850,34 +850,47 @@ split:  while ((start = CharSequences.sk
     }
 
     /**
-     * Adds a globally unique identifier for the current NetCDF {@linkplain 
#decoder}.
+     * Adds a globally unique identifier for the current netCDF {@linkplain 
#decoder}.
      * The current implementation builds the identifier from the following 
attributes:
      *
      * <ul>
      *   <li>{@value AttributeNames#NAMING_AUTHORITY} used as the {@linkplain 
Identifier#getAuthority() authority}.</li>
-     *   <li>{@value AttributeNames#IDENTIFIER}, or {@link 
ucar.nc2.NetcdfFile#getId()} if no identifier attribute was found.</li>
+     *   <li>{@value AttributeNames#IDENTIFIER}, or {@link 
ucar.nc2.NetcdfFile#getId()} if no identifier attribute was found,
+     *       or the filename without extension if {@code getId()} returned 
nothing.</li>
      * </ul>
+     *
+     * This method should be invoked last, after we made our best effort to 
set the title.
      */
     private void addFileIdentifier() {
         String identifier = stringValue(IDENTIFIER);
-        if (identifier == null) {
+        String authority;
+        if (identifier != null) {
+            authority = stringValue(NAMING_AUTHORITY);
+        } else {
             identifier = decoder.getId();
             if (identifier == null) {
-                return;
+                identifier = 
IOUtilities.filenameWithoutExtension(decoder.getFilename());
+                if (identifier == null) {
+                    return;
+                }
             }
+            authority = null;
+        }
+        if (authority == null) {
+            addTitleOrIdentifier(identifier, Scope.ALL);
+        } else {
+            addIdentifier(authority, identifier, Scope.ALL);
         }
-        addIdentifier(stringValue(NAMING_AUTHORITY), identifier, Scope.ALL);
     }
 
     /**
-     * Creates an ISO {@code Metadata} object from the information found in 
the NetCDF file.
+     * Creates an ISO {@code Metadata} object from the information found in 
the netCDF file.
      *
      * @return the ISO metadata object.
      * @throws IOException if an I/O operation was necessary but failed.
      * @throws DataStoreException if a logical error occurred.
      */
     public Metadata read() throws IOException, DataStoreException {
-        addFileIdentifier();
         addResourceScope(ScopeCode.DATASET, null);
         Set<InternationalString> publisher = addCitation();
         addIdentificationInfo(publisher);
@@ -890,7 +903,7 @@ split:  while ((start = CharSequences.sk
         addContentInfo();
         /*
          * Add the dimension information, if any. This metadata node
-         * is built from the NetCDF CoordinateSystem objects.
+         * is built from the netCDF CoordinateSystem objects.
          */
         for (final GridGeometry cs : decoder.getGridGeometries()) {
             if (cs.getSourceDimensions() >= Variable.MIN_DIMENSION &&
@@ -899,6 +912,7 @@ split:  while ((start = CharSequences.sk
                 addSpatialRepresentationInfo(cs);
             }
         }
+        addFileIdentifier();
         /*
          * Add history in Metadata.dataQualityInfo.lineage.statement as 
specified by UnidataDD2MI.xsl.
          * However Metadata.resourceLineage.statement could be a more 
appropriate place.

Modified: 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -18,6 +18,8 @@ package org.apache.sis.storage.netcdf;
 
 import java.io.IOException;
 import java.net.URI;
+import java.util.List;
+import java.util.Collection;
 import org.opengis.metadata.Metadata;
 import org.opengis.parameter.ParameterValueGroup;
 import org.apache.sis.util.Debug;
@@ -25,17 +27,23 @@ import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.UnsupportedStorageException;
 import org.apache.sis.storage.StorageConnector;
+import org.apache.sis.storage.Aggregate;
 import org.apache.sis.internal.netcdf.Decoder;
 import org.apache.sis.internal.storage.URIDataStore;
+import org.apache.sis.internal.util.UnmodifiableArrayList;
 import org.apache.sis.metadata.ModifiableMetadata;
 import org.apache.sis.setup.OptionKey;
+import org.apache.sis.storage.Resource;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.Version;
 import ucar.nc2.constants.CDM;
 
+// Branch-dependent imports
+import org.apache.sis.storage.ReadOnlyStorageException;
+
 
 /**
- * A data store backed by NetCDF files.
+ * A data store backed by netCDF files.
  * Instances of this data store are created by {@link 
NetcdfStoreProvider#open(StorageConnector)}.
  *
  * @author  Martin Desruisseaux (Geomatys)
@@ -46,9 +54,9 @@ import ucar.nc2.constants.CDM;
  * @since 0.3
  * @module
  */
-public class NetcdfStore extends DataStore {
+public class NetcdfStore extends DataStore implements Aggregate {
     /**
-     * The object to use for decoding the NetCDF file content. There is two 
different implementations,
+     * The object to use for decoding the netCDF file content. There is two 
different implementations,
      * depending on whether we are using the embedded SIS decoder or a wrapper 
around the UCAR library.
      */
     private final Decoder decoder;
@@ -64,12 +72,19 @@ public class NetcdfStore extends DataSto
     private Metadata metadata;
 
     /**
-     * Creates a new NetCDF store from the given file, URL, stream or {@link 
ucar.nc2.NetcdfFile} object.
+     * The data (raster or features) found in the netCDF file. This list is 
created when first needed.
+     *
+     * @see #components()
+     */
+    private List<Resource> components;
+
+    /**
+     * Creates a new netCDF store from the given file, URL, stream or {@link 
ucar.nc2.NetcdfFile} object.
      * This constructor invokes {@link 
StorageConnector#closeAllExcept(Object)}, keeping open only the
      * needed resource.
      *
      * @param  connector information about the storage (URL, stream, {@link 
ucar.nc2.NetcdfFile} instance, <i>etc</i>).
-     * @throws DataStoreException if an error occurred while opening the 
NetCDF file.
+     * @throws DataStoreException if an error occurred while opening the 
netCDF file.
      *
      * @deprecated Replaced by {@link #NetcdfStore(NetcdfStoreProvider, 
StorageConnector)}.
      */
@@ -79,13 +94,13 @@ public class NetcdfStore extends DataSto
     }
 
     /**
-     * Creates a new NetCDF store from the given file, URL, stream or {@link 
ucar.nc2.NetcdfFile} object.
+     * Creates a new netCDF store from the given file, URL, stream or {@link 
ucar.nc2.NetcdfFile} object.
      * This constructor invokes {@link 
StorageConnector#closeAllExcept(Object)}, keeping open only the
      * needed resource.
      *
      * @param  provider   the factory that created this {@code DataStore} 
instance, or {@code null} if unspecified.
      * @param  connector  information about the storage (URL, stream, {@link 
ucar.nc2.NetcdfFile} instance, <i>etc</i>).
-     * @throws DataStoreException if an error occurred while opening the 
NetCDF file.
+     * @throws DataStoreException if an error occurred while opening the 
netCDF file.
      *
      * @since 0.8
      */
@@ -142,7 +157,7 @@ public class NetcdfStore extends DataSto
     }
 
     /**
-     * Returns the version number of the Climate and Forecast (CF) conventions 
used in the NetCDF file.
+     * Returns the version number of the Climate and Forecast (CF) conventions 
used in the netCDF file.
      * The use of CF convention is mandated by the OGC 11-165r2 standard
      * (<cite>CF-netCDF3 Data Model Extension standard</cite>).
      *
@@ -161,9 +176,44 @@ public class NetcdfStore extends DataSto
     }
 
     /**
-     * Closes this NetCDF store and releases any underlying resources.
+     * Returns the resources (features or coverages) in this netCDF file.
+     *
+     * @return children resources that are components of this netCDF.
+     * @throws DataStoreException if an error occurred while fetching the 
components.
+     *
+     * @since 0.8
+     */
+    @Override
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
+    public synchronized Collection<Resource> components() throws 
DataStoreException {
+        if (components == null) try {
+            components = 
UnmodifiableArrayList.<Resource>wrap(decoder.getDiscreteSampling());
+        } catch (IOException e) {
+            throw new DataStoreException(e);
+        }
+        return components;
+    }
+
+    /**
+     * Unsupported operation in current version.
+     */
+    @Override
+    public Resource add(Resource resource) throws ReadOnlyStorageException {
+        throw new ReadOnlyStorageException();
+    }
+
+    /**
+     * Unsupported operation in current version.
+     */
+    @Override
+    public void remove(Resource resource) throws ReadOnlyStorageException {
+        throw new ReadOnlyStorageException();
+    }
+
+    /**
+     * Closes this netCDF store and releases any underlying resources.
      *
-     * @throws DataStoreException if an error occurred while closing the 
NetCDF file.
+     * @throws DataStoreException if an error occurred while closing the 
netCDF file.
      */
     @Override
     public synchronized void close() throws DataStoreException {
@@ -176,10 +226,10 @@ public class NetcdfStore extends DataSto
     }
 
     /**
-     * Returns a string representation of this NetCDF store for debugging 
purpose.
+     * Returns a string representation of this netCDF store for debugging 
purpose.
      * The content of the string returned by this method may change in any 
future SIS version.
      *
-     * @return a string representation of this datastore for debugging purpose.
+     * @return a string representation of this data store for debugging 
purpose.
      */
     @Debug
     @Override

Modified: 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -37,6 +37,8 @@ import org.apache.sis.internal.storage.C
 import org.apache.sis.internal.storage.URIDataStore;
 import org.apache.sis.internal.system.SystemListener;
 import org.apache.sis.internal.system.Modules;
+import org.apache.sis.setup.GeometryLibrary;
+import org.apache.sis.setup.OptionKey;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreProvider;
 import org.apache.sis.storage.StorageConnector;
@@ -49,7 +51,7 @@ import org.apache.sis.util.Version;
 
 /**
  * The provider of {@link NetcdfStore} instances. Given a {@link 
StorageConnector} input,
- * this class tries to instantiate a {@code NetcdfStore} using the embedded 
NetCDF decoder.
+ * this class tries to instantiate a {@code NetcdfStore} using the embedded 
netCDF decoder.
  * If the embedded decoder can not decode the given input and the UCAR library 
is reachable
  * on the classpath, then this class tries to instantiate a {@code 
NetcdfStore} backed by
  * the UCAR library.
@@ -74,7 +76,7 @@ public class NetcdfStoreProvider extends
     static final String NAME = "NetCDF";
 
     /**
-     * The MIME type for NetCDF files.
+     * The MIME type for netCDF files.
      */
     static final String MIME_TYPE = "application/x-netcdf";
 
@@ -103,7 +105,7 @@ public class NetcdfStoreProvider extends
 
     /**
      * If the {@link #netcdfFileClass} has been found, then the {@link 
DecoderWrapper} constructor receiving
-     * in argument the name of the NetCDF file as a {@link String} object. 
Otherwise {@code null}.
+     * in argument the name of the netCDF file as a {@link String} object. 
Otherwise {@code null}.
      */
     private static volatile Constructor<? extends Decoder> createFromPath;
 
@@ -256,51 +258,54 @@ public class NetcdfStoreProvider extends
      * {@link StorageConnector#closeAllExcept(Object)} after the decoder has 
been created.
      *
      * @param  listeners  where to send the warnings.
-     * @param  storage    information about the input (file, input stream, 
<i>etc.</i>)
+     * @param  connector  information about the input (file, input stream, 
<i>etc.</i>)
      * @return the decoder for the given input, or {@code null} if the input 
type is not recognized.
-     * @throws IOException if an error occurred while opening the NetCDF file.
+     * @throws IOException if an error occurred while opening the netCDF file.
      * @throws DataStoreException if a logical error (other than I/O) occurred.
      */
-    static Decoder decoder(final WarningListeners<DataStore> listeners, final 
StorageConnector storage)
+    static Decoder decoder(final WarningListeners<DataStore> listeners, final 
StorageConnector connector)
             throws IOException, DataStoreException
     {
+        final GeometryLibrary geomlib = 
connector.getOption(OptionKey.GEOMETRY_LIBRARY);
         Decoder decoder;
         Object keepOpen;
-        final ChannelDataInput input = 
storage.getStorageAs(ChannelDataInput.class);
+        final ChannelDataInput input = 
connector.getStorageAs(ChannelDataInput.class);
         if (input != null) try {
-            decoder = new ChannelDecoder(listeners, input);
+            decoder = new ChannelDecoder(input, 
connector.getOption(OptionKey.ENCODING), geomlib, listeners);
             keepOpen = input;
         } catch (DataStoreException e) {
-            final String path = storage.getStorageAs(String.class);
+            final String path = connector.getStorageAs(String.class);
             if (path != null) try {
-                decoder = createByReflection(listeners, path, false);
+                decoder = createByReflection(path, false, geomlib, listeners);
                 keepOpen = path;
             } catch (IOException | DataStoreException s) {
                 e.addSuppressed(s);
             }
             throw e;
         } else {
-            keepOpen = storage.getStorage();
-            decoder = createByReflection(listeners, keepOpen, true);
+            keepOpen = connector.getStorage();
+            decoder = createByReflection(keepOpen, true, geomlib, listeners);
         }
-        storage.closeAllExcept(keepOpen);
+        connector.closeAllExcept(keepOpen);
         return decoder;
     }
 
     /**
-     * Creates a new NetCDF decoder as a wrapper around the UCAR library. This 
decoder is used only when we can
-     * not create our embedded NetCDF decoder. This method uses reflection for 
creating the wrapper, in order
+     * Creates a new netCDF decoder as a wrapper around the UCAR library. This 
decoder is used only when we can
+     * not create our embedded netCDF decoder. This method uses reflection for 
creating the wrapper, in order
      * to keep the UCAR dependency optional.
      *
-     * @param  listeners  where to send the warnings.
-     * @param  input      the NetCDF file object of filename string from which 
to read data.
+     * @param  input      the netCDF file object of filename string from which 
to read data.
      * @param  isUCAR     {@code true} if {@code input} is an instance of the 
UCAR {@link ucar.nc2.NetcdfFile} object,
      *                    or {@code false} if it is the filename as a {@code 
String}.
+     * @param  geomlib    the library for geometric objects, or {@code null} 
for the default.
+     * @param  listeners  where to send the warnings.
      * @return the {@link DecoderWrapper} instance for the given input, or 
{@code null} if the input type is not recognized.
-     * @throws IOException if an error occurred while opening the NetCDF file.
+     * @throws IOException if an error occurred while opening the netCDF file.
      * @throws DataStoreException if a logical error (other than I/O) occurred.
      */
-    private static Decoder createByReflection(final 
WarningListeners<DataStore> listeners, final Object input, final boolean isUCAR)
+    private static Decoder createByReflection(final Object input, final 
boolean isUCAR,
+            final GeometryLibrary geomlib, final WarningListeners<DataStore> 
listeners)
             throws IOException, DataStoreException
     {
         ensureInitialized(true);
@@ -321,7 +326,7 @@ public class NetcdfStoreProvider extends
             return null;
         }
         try {
-            return constructor.newInstance(listeners, input);
+            return constructor.newInstance(input, geomlib, listeners);
         } catch (InvocationTargetException e) {
             final Throwable cause = e.getCause();
             if (cause instanceof IOException)        throw (IOException)       
 cause;
@@ -360,9 +365,9 @@ public class NetcdfStoreProvider extends
                          */
                         final Class<? extends Decoder> wrapper =
                                 
Class.forName("org.apache.sis.internal.netcdf.ucar.DecoderWrapper").asSubclass(Decoder.class);
-                        final Class<?>[] parameterTypes = new Class<?>[] 
{WarningListeners.class, netcdfFileClass};
+                        final Class<?>[] parameterTypes = new Class<?>[] 
{netcdfFileClass, GeometryLibrary.class, WarningListeners.class};
                         createFromUCAR = 
wrapper.getConstructor(parameterTypes);
-                        parameterTypes[1] = String.class;
+                        parameterTypes[0] = String.class;
                         createFromPath = 
wrapper.getConstructor(parameterTypes);
                         return;                                                
                         // Success
                     }
@@ -380,7 +385,7 @@ public class NetcdfStoreProvider extends
                      *
                      * ReflectiveOperationException should never happen 
because API compatibility shall be verified
                      * by the JUnit tests. If it happen anyway  (for example 
because the user puts on his classpath
-                     * a different version of the NetCDF library than the one 
we tested), report a warning.
+                     * a different version of the netCDF library than the one 
we tested), report a warning.
                      */
                     severity = Level.WARNING;
                     cause = e;

Modified: 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/package-info.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -17,7 +17,7 @@
 
 /**
  * Maps ISO metadata elements from/to the <a 
href="http://www.cfconventions.org";>Climate and Forecast (CF)</a>
- * attributes in a NetCDF file. The mapping is defined in the following web 
pages:
+ * attributes in a netCDF file. The mapping is defined in the following web 
pages:
  *
  * <ul>
  *   <li><a 
href="http://wiki.esipfed.org/index.php/Category:Attribute_Conventions_Dataset_Discovery";>NetCDF
@@ -25,7 +25,7 @@
  *   <li><a 
href="https://github.com/Unidata/threddsIso/blob/master/src/main/resources/xsl/nciso/UnidataDD2MI.xsl";>UnidataDD2MI.xsl</a>
 file.</li>
  * </ul>
  *
- * The NetCDF attributes recognized by this package are listed in the
+ * The netCDF attributes recognized by this package are listed in the
  * {@link org.apache.sis.storage.netcdf.AttributeNames} class.
  *
  * <div class="section">Note on the definition of terms</div>
@@ -42,7 +42,7 @@
  *       but is rather related to <cite>grid envelope</cite>.</li>
  *   <li>ISO 19123 coverage <cite>domain</cite> is related to UCAR coordinate 
system <cite>"range"</cite>.</li>
  *   <li>ISO 19123 coverage <cite>range</cite> is not equivalent to UCAR 
<cite>"range"</cite>,
- *       but is rather related to the NetCDF variable's minimum and maximum 
values.</li>
+ *       but is rather related to the netCDF variable's minimum and maximum 
values.</li>
  * </ul>
  *
  * Care must be taken for avoiding confusion when using SIS and UCAR libraries 
together.

Modified: 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DataTypeTest.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DataTypeTest.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DataTypeTest.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DataTypeTest.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -32,7 +32,7 @@ import static org.junit.Assert.*;
  */
 public final strictfp class DataTypeTest extends TestCase {
     /**
-     * Verifies the relationship between the enumeration ordinal value and the 
NetCDF numerical code.
+     * Verifies the relationship between the enumeration ordinal value and the 
netCDF numerical code.
      */
     @Test
     public void testOrdinalValues() {

Modified: 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -27,6 +27,7 @@ import org.apache.sis.storage.DataStoreE
 import org.apache.sis.util.logging.EmptyWarningListeners;
 import org.apache.sis.internal.netcdf.ucar.DecoderWrapper;
 import org.apache.sis.internal.system.Modules;
+import org.apache.sis.setup.GeometryLibrary;
 import ucar.nc2.dataset.NetcdfDataset;
 import org.junit.AfterClass;
 
@@ -34,7 +35,7 @@ import static org.junit.Assert.*;
 
 
 /**
- * Base class of NetCDF tests. Subclasses shall override the {@link 
#createDecoder(String)}.
+ * Base class of netCDF tests. Subclasses shall override the {@link 
#createDecoder(String)}.
  *
  * <p>This class is <strong>not</strong> thread safe - do not run subclasses 
in parallel.</p>
  *
@@ -75,7 +76,7 @@ public abstract strictfp class TestCase
     /**
      * Returns {@code true} if the given supplemental formats (THREDDS, HDF5) 
is supported.
      * The default implementation returns {@code true} since the UCAR library 
supports all
-     * supplemental formats tested in this suite. Subclasses working only with 
the NetCDF
+     * supplemental formats tested in this suite. Subclasses working only with 
the netCDF
      * classic or 64-bits format can unconditionally returns {@code false}.
      *
      * @param  format  either {@code "THREDDS"} or {@code "HDF5"}.
@@ -90,8 +91,8 @@ public abstract strictfp class TestCase
      * The {@code name} parameter can be one of the following values:
      *
      * <ul>
-     *   <li>{@link #NCEP}    for a NetCDF binary file.</li>
-     *   <li>{@link #CIP}     for a NetCDF binary file.</li>
+     *   <li>{@link #NCEP}    for a netCDF binary file.</li>
+     *   <li>{@link #CIP}     for a netCDF binary file.</li>
      * </ul>
      *
      * The default implementation first delegates to {@link #open(String)}, 
then wraps the result
@@ -105,7 +106,7 @@ public abstract strictfp class TestCase
      * @throws DataStoreException if a logical error occurred.
      */
     protected Decoder createDecoder(final String name) throws IOException, 
DataStoreException {
-        return new DecoderWrapper(LISTENERS, new NetcdfDataset(open(name)));
+        return new DecoderWrapper(new NetcdfDataset(open(name)), 
GeometryLibrary.JAVA2D, LISTENERS);
     }
 
     /**
@@ -136,7 +137,7 @@ public abstract strictfp class TestCase
 
     /**
      * Invoked after all tests in a class have been executed.
-     * This method closes all NetCDF files.
+     * This method closes all netCDF files.
      *
      * @throws IOException if an error occurred while closing a file.
      */
@@ -184,7 +185,7 @@ public abstract strictfp class TestCase
      *
      * @param  expected       the expected attribute value.
      * @param  attributeName  the name of the attribute to test.
-     * @throws IOException if an error occurred while reading the NetCDF file.
+     * @throws IOException if an error occurred while reading the netCDF file.
      */
     protected final void assertAttributeEquals(final String expected, final 
String attributeName) throws IOException {
         assertEquals(attributeName, expected, 
decoder.stringValue(attributeName));
@@ -196,7 +197,7 @@ public abstract strictfp class TestCase
      *
      * @param  expected       the expected attribute value.
      * @param  attributeName  the name of the attribute to test.
-     * @throws IOException if an error occurred while reading the NetCDF file.
+     * @throws IOException if an error occurred while reading the netCDF file.
      */
     protected final void assertAttributeEquals(final Number expected, final 
String attributeName) throws IOException {
         assertEquals(attributeName, expected, 
decoder.numericValue(attributeName));
@@ -208,7 +209,7 @@ public abstract strictfp class TestCase
      *
      * @param  expected       the expected attribute value.
      * @param  attributeName  the name of the attribute to test.
-     * @throws IOException if an error occurred while reading the NetCDF file.
+     * @throws IOException if an error occurred while reading the netCDF file.
      */
     protected final void assertAttributeEquals(final Date expected, final 
String attributeName) throws IOException {
         assertEquals(attributeName, expected, 
decoder.dateValue(attributeName));

Modified: 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -164,7 +164,7 @@ public strictfp class VariableTest exten
     /**
      * Tests {@link Variable#read()} on a one-dimensional variable.
      *
-     * @throws IOException if an error occurred while reading the NetCDF file.
+     * @throws IOException if an error occurred while reading the netCDF file.
      * @throws DataStoreException if a logical error occurred.
      */
     @Test

Modified: 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/ChannelDecoderTest.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/ChannelDecoderTest.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/ChannelDecoderTest.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/ChannelDecoderTest.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -25,6 +25,7 @@ import org.apache.sis.internal.netcdf.De
 import org.apache.sis.internal.netcdf.DecoderTest;
 import org.apache.sis.internal.storage.io.ChannelDataInput;
 import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.setup.GeometryLibrary;
 import org.apache.sis.test.DependsOn;
 
 import static org.junit.Assume.*;
@@ -59,8 +60,8 @@ public final strictfp class ChannelDecod
      * The {@code name} parameter can be one of the following values:
      *
      * <ul>
-     *   <li>{@link #NCEP}    for a NetCDF binary file.</li>
-     *   <li>{@link #CIP}     for a NetCDF binary file.</li>
+     *   <li>{@link #NCEP}    for a netCDF binary file.</li>
+     *   <li>{@link #CIP}     for a netCDF binary file.</li>
      * </ul>
      *
      * @param  name  the file name as one of the above-cited constants.
@@ -73,12 +74,12 @@ public final strictfp class ChannelDecod
         assumeNotNull(name, in);
         final ChannelDataInput input = new ChannelDataInput(name,
                 Channels.newChannel(in), ByteBuffer.allocate(4096), false);
-        return new ChannelDecoder(LISTENERS, input);
+        return new ChannelDecoder(input, null, GeometryLibrary.JAVA2D, 
LISTENERS);
     }
 
     /**
      * Unconditionally returns {@code false} since {@link ChannelDecoder}
-     * supports only the classic and 64 bits NetCDF formats.
+     * supports only the classic and 64 bits netCDF formats.
      *
      * @return {@code false}.
      */

Modified: 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfoTest.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfoTest.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfoTest.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfoTest.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -51,7 +51,7 @@ public final strictfp class GridGeometry
 
     /**
      * Unconditionally returns {@code false} since {@link ChannelDecoder}
-     * supports only the classic and 64 bits NetCDF formats.
+     * supports only the classic and 64 bits netCDF formats.
      *
      * @return {@code false}.
      */

Modified: 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/VariableInfoTest.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/VariableInfoTest.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/VariableInfoTest.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/VariableInfoTest.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -52,7 +52,7 @@ public final strictfp class VariableInfo
 
     /**
      * Unconditionally returns {@code false} since {@link ChannelDecoder}
-     * supports only the classic and 64 bits NetCDF formats.
+     * supports only the classic and 64 bits netCDF formats.
      *
      * @return {@code false}.
      */

Modified: 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -26,6 +26,7 @@ import org.apache.sis.internal.netcdf.uc
 import org.apache.sis.internal.netcdf.impl.ChannelDecoderTest;
 import org.apache.sis.metadata.iso.DefaultMetadata;
 import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.setup.GeometryLibrary;
 import org.apache.sis.test.DependsOn;
 import org.junit.Test;
 
@@ -35,7 +36,7 @@ import static org.apache.sis.test.TestUt
 
 /**
  * Tests {@link MetadataReader}. This tests uses the SIS embedded 
implementation and the UCAR library
- * for reading NetCDF attributes.
+ * for reading netCDF attributes.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 0.8
@@ -57,7 +58,7 @@ public final strictfp class MetadataRead
     }
 
     /**
-     * Reads the metadata using the NetCDF decoder embedded with SIS,
+     * Reads the metadata using the netCDF decoder embedded with SIS,
      * and compares its string representation with the expected one.
      *
      * @throws IOException if an I/O error occurred while opening the file.
@@ -82,7 +83,7 @@ public final strictfp class MetadataRead
     @Test
     public void testUCAR() throws IOException, DataStoreException {
         final Metadata metadata;
-        try (Decoder input = new DecoderWrapper(TestCase.LISTENERS, new 
NetcdfDataset(open(NCEP)))) {
+        try (Decoder input = new DecoderWrapper(new NetcdfDataset(open(NCEP)), 
GeometryLibrary.JAVA2D, TestCase.LISTENERS)) {
             metadata = new MetadataReader(input).read();
         }
         compareToExpected(metadata);

Modified: 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreProviderTest.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreProviderTest.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreProviderTest.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreProviderTest.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -48,7 +48,7 @@ import static org.opengis.test.Assert.*;
 public final strictfp class NetcdfStoreProviderTest extends IOTestCase {
     /**
      * Tests {@link NetcdfStoreProvider#probeContent(StorageConnector)} for an 
input stream which shall
-     * be recognized as a classic NetCDF file.
+     * be recognized as a classic netCDF file.
      *
      * @throws DataStoreException if a logical error occurred.
      */
@@ -66,7 +66,7 @@ public final strictfp class NetcdfStoreP
     /**
      * Tests {@link NetcdfStoreProvider#probeContent(StorageConnector)} for a 
UCAR {@link NetcdfFile} object.
      *
-     * @throws IOException if an error occurred while opening the NetCDF file.
+     * @throws IOException if an error occurred while opening the netCDF file.
      * @throws DataStoreException if a logical error occurred.
      */
     @Test
@@ -83,9 +83,9 @@ public final strictfp class NetcdfStoreP
 
     /**
      * Tests {@link NetcdfStoreProvider#decoder(WarningListeners, 
StorageConnector)} for an input stream which
-     * shall be recognized as a classic NetCDF file. The provider shall 
instantiate a {@link ChannelDecoder}.
+     * shall be recognized as a classic netCDF file. The provider shall 
instantiate a {@link ChannelDecoder}.
      *
-     * @throws IOException if an error occurred while opening the NetCDF file.
+     * @throws IOException if an error occurred while opening the netCDF file.
      * @throws DataStoreException if a logical error occurred.
      */
     @Test
@@ -100,7 +100,7 @@ public final strictfp class NetcdfStoreP
      * Tests {@link NetcdfStoreProvider#decoder(WarningListeners, 
StorageConnector)} for a UCAR
      * {@link NetcdfFile} object. The provider shall instantiate a {@link 
DecoderWrapper}.
      *
-     * @throws IOException if an error occurred while opening the NetCDF file.
+     * @throws IOException if an error occurred while opening the netCDF file.
      * @throws DataStoreException if a logical error occurred.
      */
     @Test

Modified: 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreTest.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreTest.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreTest.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreTest.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -40,10 +40,10 @@ import static org.opengis.test.Assert.*;
 })
 public final strictfp class NetcdfStoreTest extends IOTestCase {
     /**
-     * Returns a new NetCDF store to test.
+     * Returns a new netCDF store to test.
      *
      * @param  dataset the name of the datastore to load.
-     * @throws DataStoreException if an error occurred while reading the 
NetCDF file.
+     * @throws DataStoreException if an error occurred while reading the 
netCDF file.
      */
     private static NetcdfStore create(final String dataset) throws 
DataStoreException {
         return new NetcdfStore(null, new 
StorageConnector(IOTestCase.getResource(dataset)));
@@ -52,7 +52,7 @@ public final strictfp class NetcdfStoreT
     /**
      * Tests {@link NetcdfStore#getMetadata()}.
      *
-     * @throws DataStoreException if an error occurred while reading the 
NetCDF file.
+     * @throws DataStoreException if an error occurred while reading the 
netCDF file.
      */
     @Test
     public void testGetMetadata() throws DataStoreException {

Modified: 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractFeatureSet.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractFeatureSet.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractFeatureSet.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractFeatureSet.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -29,14 +29,13 @@ import org.apache.sis.util.logging.Warni
  * @since   0.8
  * @module
  */
-public abstract class AbstractFeatureSet extends AbstractDataSet implements 
FeatureSet {
+public abstract class AbstractFeatureSet extends AbstractResource implements 
FeatureSet {
     /**
      * Creates a new resource.
      *
-     * @param store      the data store which contains this resource.
      * @param listeners  the set of registered warning listeners for the data 
store.
      */
-    protected AbstractFeatureSet(final DataStore store, final 
WarningListeners<DataStore> listeners) {
-        super(store, listeners);
+    protected AbstractFeatureSet(final WarningListeners<DataStore> listeners) {
+        super(listeners);
     }
 }

Modified: 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractResource.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractResource.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractResource.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractResource.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -16,9 +16,22 @@
  */
 package org.apache.sis.internal.storage;
 
+import java.util.Locale;
+import org.opengis.geometry.Envelope;
+import org.opengis.metadata.Metadata;
+import org.opengis.metadata.extent.Extent;
+import org.opengis.metadata.extent.GeographicBoundingBox;
+import org.opengis.metadata.extent.GeographicExtent;
+import org.opengis.metadata.identification.Identification;
+import org.apache.sis.geometry.GeneralEnvelope;
+import org.apache.sis.util.Localized;
+import org.apache.sis.util.logging.WarningListeners;
 import org.apache.sis.storage.Resource;
 import org.apache.sis.storage.DataStore;
-import org.apache.sis.util.logging.WarningListeners;
+import org.apache.sis.storage.DataStoreException;
+
+// Branch-dependent imports
+import org.opengis.metadata.identification.DataIdentification;
 
 
 /**
@@ -29,37 +42,86 @@ import org.apache.sis.util.logging.Warni
  * @since   0.8
  * @module
  */
-public abstract class AbstractResource implements Resource {
-    /**
-     * The data store which contains this resource.
-     */
-    protected final DataStore store;
-
+public abstract class AbstractResource implements Resource, Localized {
     /**
      * The set of registered warning listeners for the data store.
-     *
-     * @todo Remove this field if we move {@code AbstractResource} to the 
{@code org.apache.sis.storage} package,
-     *       since we would be able to access {@code DataStore.listeners} 
directly.
      */
-    private final WarningListeners<DataStore> listeners;
+    protected final WarningListeners<DataStore> listeners;
 
     /**
      * Creates a new resource.
      *
-     * @param store      the data store which contains this resource.
      * @param listeners  the set of registered warning listeners for the data 
store.
      */
-    protected AbstractResource(final DataStore store, final 
WarningListeners<DataStore> listeners) {
-        this.store     = store;
+    protected AbstractResource(final WarningListeners<DataStore> listeners) {
         this.listeners = listeners;
     }
 
     /**
-     * The set of registered warning listeners for the data store.
+     * Returns the locale for error messages or warnings.
+     * Returns {@code null} if no locale is explicitly defined.
+     *
+     * @return the locale, or {@code null} if not explicitly defined.
+     */
+    @Override
+    public final Locale getLocale() {
+        return (listeners != null) ? listeners.getLocale() : null;
+    }
+
+    /**
+     * Returns the display name of the data store, or {@code null} if none.
+     * This is a convenience method for formatting error messages in 
subclasses.
+     *
+     * @return the data store display name, or {@code null}.
+     *
+     * @see DataStore#getDisplayName()
+     */
+    protected final String getStoreName() {
+        return (listeners != null) ? listeners.getSource().getDisplayName() : 
null;
+    }
+
+    /**
+     * Returns the spatio-temporal envelope of this resource.
+     * The default implementation computes the union of all {@link 
GeographicBoundingBox} in the resource metadata,
+     * assuming the {@linkplain 
org.apache.sis.referencing.CommonCRS#defaultGeographic() default geographic CRS}
+     * (usually WGS 84).
+     *
+     * @return the spatio-temporal resource extent, or {@code null} if none.
+     * @throws DataStoreException if an error occurred while reading or 
computing the envelope.
+     */
+    public Envelope getEnvelope() throws DataStoreException {
+        return envelope(getMetadata());
+    }
+
+    /**
+     * Implementation of {@link #getEnvelope()}, provided as a separated 
method for
+     * {@link org.apache.sis.storage.DataSet} implementations that do not 
extend {@code AbstractResource}.
      *
-     * @return the registered warning listeners for the data store.
+     * @param  metadata  the metadata from which to compute the envelope, or 
{@code null}.
+     * @return the spatio-temporal resource extent, or {@code null} if none.
      */
-    protected final WarningListeners<DataStore> listeners() {
-        return listeners;
+    public static Envelope envelope(final Metadata metadata) {
+        GeneralEnvelope bounds = null;
+        if (metadata != null) {
+            for (final Identification identification : 
metadata.getIdentificationInfo()) {
+                if (identification instanceof DataIdentification) {
+                    for (final Extent extent : ((DataIdentification) 
identification).getExtents()) {
+                        if (extent != null) {                                  
             // Paranoiac check.
+                            for (final GeographicExtent ge : 
extent.getGeographicElements()) {
+                                if (ge instanceof GeographicBoundingBox) {
+                                    final GeneralEnvelope env = new 
GeneralEnvelope((GeographicBoundingBox) ge);
+                                    if (bounds == null) {
+                                        bounds = env;
+                                    } else {
+                                        bounds.add(env);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return bounds;
     }
 }

Modified: 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java?rev=1809404&r1=1809403&r2=1809404&view=diff
==============================================================================
--- 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java
 [UTF-8] (original)
+++ 
sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java
 [UTF-8] Sat Sep 23 11:47:20 2017
@@ -883,6 +883,7 @@ public class MetadataBuilder {
      * @param  scope      whether the date applies to data, to metadata or to 
both.
      *
      * @see #addTitle(CharSequence)
+     * @see #addTitleOrIdentifier(String, Scope)
      */
     public final void addIdentifier(final CharSequence authority, String code, 
final Scope scope) {
         ArgumentChecks.ensureNonNull("scope", scope);
@@ -1086,7 +1087,7 @@ public class MetadataBuilder {
      * Storage location is:
      *
      * <ul>
-     *   <li>{@code metadata/identificationInfo/citation/title} if 
available</li>
+     *   <li>{@code metadata/identificationInfo/citation/title} if not yet 
used</li>
      *   <li>{@code metadata/identificationInfo/citation/alternateTitle} 
otherwise</li>
      * </ul>
      *
@@ -1108,6 +1109,31 @@ public class MetadataBuilder {
     }
 
     /**
+     * Adds the given code as a title if the current citation has no title, or 
as an identifier otherwise.
+     * This method is invoked when adding an identifier to a metadata that may 
have no title. Because the
+     * title is mandatory, adding only an identifier would make an invalid 
metadata.
+     *
+     * @param  code   the identifier code, or {@code null} for no-operation.
+     * @param  scope  whether the date applies to data, to metadata or to both.
+     *
+     * @see #addTitle(CharSequence)
+     * @see #addIdentifier(CharSequence, String, Scope)
+     */
+    public final void addTitleOrIdentifier(final String code, Scope scope) {
+        ArgumentChecks.ensureNonNull("scope", scope);
+        if (scope != Scope.METADATA) {
+            if (citation == null || citation.getTitle() == null) {
+                addTitle(code);
+                if (scope == Scope.RESOURCE) {
+                    return;
+                }
+                scope = Scope.METADATA;
+            }
+        }
+        addIdentifier(null, code, scope);
+    }
+
+    /**
      * Adds a brief narrative summary of the resource(s).
      * If a summary already existed, the new one will be appended after a new 
line.
      * Storage location is:

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=1809404&r1=1809403&r2=1809404&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 Sep 23 11:47:20 2017
@@ -67,6 +67,11 @@ public final class Resources extends Ind
         public static final short AmbiguousName_4 = 15;
 
         /**
+         * Can not read “{0}” directory.
+         */
+        public static final short CanNotReadDirectory_1 = 34;
+
+        /**
          * Can not read “{1}” as a file in the {0} format.
          */
         public static final short CanNotReadFile_2 = 1;
@@ -102,6 +107,31 @@ public final class Resources extends Ind
         public static final short ConcurrentWrite_1 = 20;
 
         /**
+         * Character encoding used by the data store.
+         */
+        public static final short DataStoreEncoding = 29;
+
+        /**
+         * Formating conventions of dates and numbers.
+         */
+        public static final short DataStoreLocale = 30;
+
+        /**
+         * Data store location as a file or URL.
+         */
+        public static final short DataStoreLocation = 31;
+
+        /**
+         * Timezone of dates in the data store.
+         */
+        public static final short DataStoreTimeZone = 32;
+
+        /**
+         * Content of “{0}” directory.
+         */
+        public static final short DirectoryContent_1 = 35;
+
+        /**
          * Character string in the “{0}” file is too long. The string has {2} 
characters while the
          * limit is {1}.
          */
@@ -164,6 +194,11 @@ public final class Resources extends Ind
         public static final short ShallBeDeclaredBefore_2 = 22;
 
         /**
+         * The “{0}” directory is used more than once because of symbolic 
links.
+         */
+        public static final short SharedDirectory_1 = 36;
+
+        /**
          * Write operations are not supported.
          */
         public static final short StoreIsReadOnly = 28;
@@ -202,6 +237,11 @@ public final class Resources extends Ind
          * Format of “{0}” is not recognized.
          */
         public static final short UnknownFormatFor_1 = 14;
+
+        /**
+         * Used only if this information is not encoded with the data.
+         */
+        public static final short UsedOnlyIfNotEncoded = 33;
     }
 
     /**

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=1809404&r1=1809403&r2=1809404&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 Sep 23 11:47:20 2017
@@ -20,6 +20,7 @@
 # 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.
+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.
@@ -27,6 +28,11 @@ ClosedReader_1                    = This
 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.
+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.
 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.
 ExcessiveStringSize_3             = Character string in the \u201c{0}\u201d 
file is too long. The string has {2} characters while the limit is {1}.
@@ -39,6 +45,7 @@ ProcessingExecutedOn_1            = Proc
 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.
+SharedDirectory_1                 = The \u201c{0}\u201d directory is used more 
than once because of symbolic links.
 StoreIsReadOnly                   = Write operations are not supported.
 StreamIsForwardOnly_1             = Can not move backward in the 
\u201c{0}\u201d stream.
 StreamIsNotReadable_1             = Stream \u201c{0}\u201d is not readable.
@@ -47,3 +54,4 @@ StreamIsReadOnce_1                = The
 StreamIsWriteOnce_1               = Can not modify previously written data in 
\u201c{0}\u201d.
 UndefinedParameter_2              = Can not open {0} data store without 
\u201c{1}\u201d parameter.
 UnknownFormatFor_1                = Format of \u201c{0}\u201d is not 
recognized.
+UsedOnlyIfNotEncoded              = Used only if this information is not 
encoded with the data.


Reply via email to