You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2016/12/31 07:33:02 UTC

svn commit: r1776697 [5/5] - in /sis/branches/JDK7: ./ application/sis-console/src/main/java/org/apache/sis/console/ core/sis-build-helper/src/main/java/org/apache/sis/util/resources/ core/sis-feature/src/main/java/org/apache/sis/feature/ core/sis-feat...

Modified: sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -63,111 +63,111 @@ public final class Resources extends Ind
         /**
          * TIFF file \u201c{0}\u201d has circular references in its chain of images.
          */
-        public static final short CircularImageReference_1 = 18;
+        public static final short CircularImageReference_1 = 1;
 
         /**
          * No value specified for the \u201c{0}\u201d TIFF tag. Computed the {1} value from other tags.
          */
-        public static final short ComputedValueForAttribute_2 = 0;
+        public static final short ComputedValueForAttribute_2 = 2;
 
         /**
          * Apache SIS implementation requires that all \u201c{0}\u201d elements have the same value, but the
          * element found in \u201c{1}\u201d are {2}.
          */
-        public static final short ConstantValueRequired_3 = 1;
+        public static final short ConstantValueRequired_3 = 3;
 
         /**
          * No value specified for the \u201c{0}\u201d TIFF tag. The {1} default value will be used.
          */
-        public static final short DefaultValueForAttribute_2 = 2;
+        public static final short DefaultValueForAttribute_2 = 4;
 
         /**
          * An ordered dither or halftone technique has been applied to the image data. The dithering or
          * halftoning matrix size is {0}�{1}.
          */
-        public static final short DitheringOrHalftoningApplied_2 = 3;
+        public static final short DitheringOrHalftoningApplied_2 = 5;
 
         /**
          * The following GeoTIFF keys have been ignored: {0}
          */
-        public static final short IgnoredGeoKeys_1 = 19;
+        public static final short IgnoredGeoKeys_1 = 6;
 
         /**
          * The \u201c{0}\u201d TIFF tag has been ignored.
          */
-        public static final short IgnoredTag_1 = 4;
+        public static final short IgnoredTag_1 = 7;
 
         /**
          * TIFF image \u201c{0}\u201d shall be either tiled or organized into strips.
          */
-        public static final short InconsistentTileStrip_1 = 5;
+        public static final short InconsistentTileStrip_1 = 8;
 
         /**
          * \u201c{1}\u201d is not a valid value for the \u201c{0}\u201d GeoTIFF key.
          */
-        public static final short InvalidGeoValue_2 = 12;
+        public static final short InvalidGeoValue_2 = 9;
 
         /**
          * TIFF tag \u201c{0}\u201d shall contain at least {1} values but found only {2}.
          */
-        public static final short ListTooShort_3 = 14;
+        public static final short ListTooShort_3 = 10;
 
         /**
          * TIFF tags \u201c{0}\u201d and \u201c{1}\u201d have values of different lengths. Found \u201c{2}\u201d and \u201c{3}\u201d elements
          * respectively.
          */
-        public static final short MismatchedLength_4 = 6;
+        public static final short MismatchedLength_4 = 11;
 
         /**
          * No value has been found for the \u201c{0}\u201d GeoTIFF key.
          */
-        public static final short MissingGeoValue_1 = 9;
+        public static final short MissingGeoValue_1 = 12;
 
         /**
          * Can not read TIFF image from \u201c{0}\u201d because the \u201c{1}\u201d tag is missing.
          */
-        public static final short MissingValue_2 = 7;
+        public static final short MissingValue_2 = 13;
 
         /**
          * The file defines \u201c{2}\u201d with value {3}{4}, but that value should be {1}{4} according parent
          * definition ({0}).
          */
-        public static final short NotTheEpsgValue_5 = 17;
+        public static final short NotTheEpsgValue_5 = 14;
 
         /**
          * A randomized process such as error diffusion has been applied to the image data.
          */
-        public static final short RandomizedProcessApplied = 8;
+        public static final short RandomizedProcessApplied = 15;
 
         /**
          * A single value was expected for the \u201c{0}\u201d key but {1} values have been found.
          */
-        public static final short UnexpectedListOfValues_2 = 15;
+        public static final short UnexpectedListOfValues_2 = 16;
 
         /**
          * The \u201c{1}\u201d parameter was not expected for the \u201c{0}\u201d projection method.
          */
-        public static final short UnexpectedParameter_2 = 20;
+        public static final short UnexpectedParameter_2 = 17;
 
         /**
          * Found {2} tiles or strips in the \u201c{0}\u201d file while {1} were expected.
          */
-        public static final short UnexpectedTileCount_3 = 10;
+        public static final short UnexpectedTileCount_3 = 18;
 
         /**
          * Coordinate system kind {0} is unsupported.
          */
-        public static final short UnsupportedCoordinateSystemKind_1 = 11;
+        public static final short UnsupportedCoordinateSystemKind_1 = 19;
 
         /**
          * Version {0}�of GeoTIFF key directory is not supported.
          */
-        public static final short UnsupportedGeoKeyDirectory_1 = 13;
+        public static final short UnsupportedGeoKeyDirectory_1 = 20;
 
         /**
          * Unsupported storage location for the \u201c{0}\u201d GeoTIFF value.
          */
-        public static final short UnsupportedGeoKeyStorage_1 = 16;
+        public static final short UnsupportedGeoKeyStorage_1 = 21;
     }
 
     /**

Modified: sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -21,6 +21,7 @@ import java.io.IOException;
 import java.nio.charset.Charset;
 import java.util.logging.LogRecord;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.StandardOpenOption;
 import org.opengis.util.FactoryException;
 import org.opengis.metadata.Metadata;
 import org.opengis.metadata.maintenance.ScopeCode;
@@ -33,8 +34,8 @@ import org.apache.sis.storage.Unsupporte
 import org.apache.sis.internal.storage.ChannelDataInput;
 import org.apache.sis.internal.storage.MetadataBuilder;
 import org.apache.sis.metadata.sql.MetadataStoreException;
+import org.apache.sis.storage.DataStoreClosedException;
 import org.apache.sis.util.resources.Errors;
-import org.apache.sis.util.Classes;
 
 
 /**
@@ -54,7 +55,7 @@ public class GeoTiffStore extends DataSt
     final Charset encoding;
 
     /**
-     * The GeoTIFF reader implementation, or {@code null} if none.
+     * The GeoTIFF reader implementation, or {@code null} if the store has been closed.
      */
     private Reader reader;
 
@@ -80,8 +81,8 @@ public class GeoTiffStore extends DataSt
         this.encoding = (encoding != null) ? encoding : StandardCharsets.US_ASCII;
         final ChannelDataInput input = connector.getStorageAs(ChannelDataInput.class);
         if (input == null) {
-            throw new UnsupportedStorageException(errors().getString(Errors.Keys.IllegalInputTypeForReader_2,
-                    "TIFF", Classes.getClass(connector.getStorage())));
+            throw new UnsupportedStorageException(super.getLocale(), "TIFF",
+                    connector.getStorage(), connector.getOption(OptionKey.OPEN_OPTIONS));
         }
         connector.closeAllExcept(input);
         try {
@@ -102,6 +103,7 @@ public class GeoTiffStore extends DataSt
     @Override
     public synchronized Metadata getMetadata() throws DataStoreException {
         if (metadata == null) {
+            final Reader reader = reader();
             final MetadataBuilder builder = reader.metadata;
             try {
                 builder.setFormat("GeoTIFF");
@@ -121,13 +123,24 @@ public class GeoTiffStore extends DataSt
             } catch (IOException e) {
                 throw new DataStoreException(errors().getString(Errors.Keys.CanNotRead_1, reader.input.filename), e);
             } catch (FactoryException | ArithmeticException e) {
-                throw new DataStoreContentException(reader.canNotDecode(), e);
+                throw new DataStoreContentException(getLocale(), "TIFF", reader.input.filename, null).initCause(e);
             }
         }
         return metadata;
     }
 
     /**
+     * Returns the reader if it is not closed, or thrown an exception otherwise.
+     */
+    private Reader reader() throws DataStoreException {
+        final Reader r = reader;
+        if (r == null) {
+            throw new DataStoreClosedException(getLocale(), "GeoTIFF", StandardOpenOption.READ);
+        }
+        return r;
+    }
+
+    /**
      * Closes this GeoTIFF store and releases any underlying resources.
      *
      * @throws DataStoreException if an error occurred while closing the GeoTIFF file.
@@ -147,8 +160,7 @@ public class GeoTiffStore extends DataSt
      * Returns the error resources in the current locale.
      */
     final Errors errors() {
-        // Must use "super" because GeoTiffStore construction may not be finished.
-        return Errors.getResources(super.getLocale());
+        return Errors.getResources(getLocale());
     }
 
     /**

Modified: sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Reader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Reader.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Reader.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Reader.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -198,13 +198,6 @@ final class Reader extends GeoTIFF {
     }
 
     /**
-     * Returns a default message for parsing error.
-     */
-    final String canNotDecode() {
-        return errors().getString(Errors.Keys.CanNotParseFile_2, "TIFF", input.filename);
-    }
-
-    /**
      * Reads the {@code int} or {@code long} value (depending if the file is
      * a standard of big TIFF) at the current {@linkplain #input} position.
      *
@@ -218,7 +211,7 @@ final class Reader extends GeoTIFF {
         if (pointer >= 0) {
             return pointer;
         }
-        throw new DataStoreContentException(canNotDecode());
+        throw new DataStoreContentException(owner.getLocale(), "TIFF", input.filename, null);
     }
 
     /**
@@ -235,7 +228,7 @@ final class Reader extends GeoTIFF {
         if (entry >= 0) {
             return entry;
         }
-        throw new DataStoreContentException(canNotDecode());
+        throw new DataStoreContentException(owner.getLocale(), "TIFF", input.filename, null);
     }
 
     /**

Modified: sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -61,17 +61,17 @@ public final class Resources extends Ind
         /**
          * Dimension \u201c{2}\u201d declared by attribute \u201c{1}\u201d is not found in the \u201c{0}\u201d file.
          */
-        public static final short DimensionNotFound_3 = 0;
+        public static final short DimensionNotFound_3 = 1;
 
         /**
          * Variable \u201c{1}\u201d in file \u201c{0}\u201d has a dimension \u201c{3}\u201d while we expected \u201c{2}\u201d.
          */
-        public static final short UnexpectedDimensionForVariable_4 = 1;
+        public static final short UnexpectedDimensionForVariable_4 = 2;
 
         /**
          * Variable \u201c{1}\u201d is not found in the \u201c{0}\u201d file.
          */
-        public static final short VariableNotFound_2 = 2;
+        public static final short VariableNotFound_2 = 3;
     }
 
     /**

Modified: sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -254,7 +254,7 @@ public final class ChannelDecoder extend
         VariableInfo[]     variables  = null;
         Map<String,Object> attributes = null;
         for (int i=0; i<3; i++) {
-            final long tn = input.readLong(); // Combination of tag and nelems
+            final long tn = input.readLong();                   // Combination of tag and nelems
             if (tn != 0) {
                 final int tag = (int) (tn >>> Integer.SIZE);
                 final int nelems = (int) tn;
@@ -267,7 +267,7 @@ public final class ChannelDecoder extend
                         default:        throw malformedHeader();
                     }
                 } catch (InvalidParameterCardinalityException e) {
-                    throw new DataStoreContentException(e.getLocalizedMessage());
+                    throw new DataStoreContentException(e.getLocalizedMessage(), e);
                 }
             }
         }
@@ -317,7 +317,7 @@ public final class ChannelDecoder extend
      * that the file should be a NetCDF one, but we found some inconsistency or unknown tags.
      */
     private DataStoreException malformedHeader() {
-        return new DataStoreContentException(errors().getString(Errors.Keys.CanNotParseFile_2, "NetCDF", getFilename()));
+        return new DataStoreContentException(listeners.getLocale(), "NetCDF", getFilename(), null);
     }
 
     /**
@@ -542,9 +542,7 @@ public final class ChannelDecoder extend
                     varDims[i] = allDimensions[input.readInt()];
                 }
             } catch (IndexOutOfBoundsException cause) {
-                final DataStoreException e = malformedHeader();
-                e.initCause(cause);
-                throw e;
+                throw malformedHeader().initCause(cause);
             }
             /*
              * Following block is almost a copy-and-paste of similar block in the contructor,

Modified: sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStore.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -19,14 +19,13 @@ package org.apache.sis.storage.netcdf;
 import java.io.IOException;
 import org.opengis.metadata.Metadata;
 import org.apache.sis.util.Debug;
-import org.apache.sis.util.Classes;
-import org.apache.sis.util.resources.Errors;
 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.internal.netcdf.Decoder;
 import org.apache.sis.metadata.ModifiableMetadata;
+import org.apache.sis.setup.OptionKey;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.Version;
 import ucar.nc2.constants.CDM;
@@ -89,8 +88,8 @@ public class NetcdfStore extends DataSto
             throw new DataStoreException(e);
         }
         if (decoder == null) {
-            throw new UnsupportedStorageException(errors().getString(Errors.Keys.IllegalInputTypeForReader_2,
-                    "NetCDF", Classes.getClass(connector.getStorage())));
+            throw new UnsupportedStorageException(super.getLocale(), "NetCDF",
+                    connector.getStorage(), connector.getOption(OptionKey.OPEN_OPTIONS));
         }
     }
 
@@ -151,14 +150,6 @@ public class NetcdfStore extends DataSto
     }
 
     /**
-     * Returns the error resources in the current locale.
-     */
-    private Errors errors() {
-        // Must use "super" because NetcdfStore construction may not be finished.
-        return Errors.getResources(super.getLocale());
-    }
-
-    /**
      * 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.
      *

Modified: sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/IOUtilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/IOUtilities.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/IOUtilities.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/IOUtilities.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -27,7 +27,6 @@ import java.io.FileInputStream;
 import java.io.InputStream;
 import java.io.IOException;
 import java.io.LineNumberReader;
-import java.io.Reader;
 import java.net.URI;
 import java.net.URL;
 import java.net.URLDecoder;
@@ -43,6 +42,8 @@ import java.nio.file.StandardOpenOption;
 import java.nio.channels.Channels;
 import java.nio.channels.ReadableByteChannel;
 import java.nio.charset.StandardCharsets;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamReader;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.Exceptions;
@@ -259,10 +260,8 @@ public final class IOUtilities extends S
              * Occurs only if the URL is not compliant with RFC 2396. Otherwise every URL
              * should succeed, so a failure can actually be considered as a malformed URL.
              */
-            final MalformedURLException e = new MalformedURLException(Exceptions.formatChainedMessages(
-                    null, Errors.format(Errors.Keys.IllegalArgumentValue_2, "URL", path), cause));
-            e.initCause(cause);
-            throw e;
+            throw (MalformedURLException) new MalformedURLException(Exceptions.formatChainedMessages(null,
+                    Errors.format(Errors.Keys.IllegalArgumentValue_2, "URL", path), cause)).initCause(cause);
         }
     }
 
@@ -557,21 +556,77 @@ public final class IOUtilities extends S
     }
 
     /**
-     * Returns an error message a file that can not be parsed because of an error at the given location.
+     * Returns {@code true} if the given options would open a file mostly for writing.
+     * This method returns {@code true} if the following conditions are true:
+     *
+     * <ul>
+     *   <li>The array contains {@link StandardOpenOption#WRITE}.</li>
+     *   <li>The array does not contain {@link StandardOpenOption#READ}, unless the array contains also
+     *       {@link StandardOpenOption#CREATE_NEW} or {@link StandardOpenOption#TRUNCATE_EXISTING} in which
+     *       case the {@code READ} option is ignored (because the caller would have no data to read).</li>
+     * </ul>
+     *
+     * @param  options  the open options to check, or {@code null} if none.
+     * @return {@code true} if a file opened with the given options would be mostly for write operations.
+     *
+     * @since 0.8
+     */
+    public static boolean isWrite(final OpenOption[] options) {
+        boolean isRead   = false;
+        boolean isWrite  = false;
+        boolean truncate = false;
+        if (options != null) {
+            for (final OpenOption op : options) {
+                if (op instanceof StandardOpenOption) {
+                    switch ((StandardOpenOption) op) {
+                        case READ:              isRead   = true; break;
+                        case WRITE:             isWrite  = true; break;
+                        case CREATE_NEW:
+                        case TRUNCATE_EXISTING: truncate = true; break;
+                    }
+                }
+            }
+        }
+        return isWrite & (!isRead | truncate);
+    }
+
+    /**
+     * Returns the {@link Resources.Keys} value together with the parameters given by {@code errorMessageParameters(\u2026)}.
+     *
+     * @param   parameters  the result of {@code errorMessageParameters(\u2026)} method call.
+     * @return  the {@link Resources.Keys} value to use for formatting the error message.
+     *
+     * @since 0.8
+     */
+    public static short errorMessageKey(final Object[] parameters) {
+        return (parameters.length == 2) ? Resources.Keys.CanNotReadFile_2 :
+               (parameters.length == 3) ? Resources.Keys.CanNotReadFile_3 :
+                                          Resources.Keys.CanNotReadFile_4;
+    }
+
+    /**
+     * Returns the parameters for an error message saying that an error occurred while processing a file.
+     * This method uses the information provided by methods like {@link LineNumberReader#getLineNumber()}
+     * or {@link XMLStreamReader#getLocation()} if the given {@code store} is one of the supported types.
      *
-     * @param  errors    the resource bundle to use for creating the message.
      * @param  format    abbreviation of the file format (e.g. "CSV", "GML", "WKT", <i>etc</i>).
-     * @param  filename  name of the file being parsed.
-     * @param  line      1-based line number where the error occurred, or 0 if unknown.
-     * @param  column    1-based column number where the error occurred, or 0 if unknown.
-     * @return a localized error message for a file that can not be parsed.
+     * @param  filename  name of the file or the data store.
+     * @param  store     the input or output object, or {@code null}.
+     * @return the parameters for a localized error message for a file that can not be processed.
      *
      * @since 0.8
      */
     @SuppressWarnings("fallthrough")
-    public static String canNotParseFile(final Errors errors, final String format,
-            final String filename, final int line, final int column)
-    {
+    public static Object[] errorMessageParameters(final String format, final String filename, final Object store) {
+        int line   = 0;
+        int column = 0;
+        if (store instanceof XMLStreamReader) {
+            final Location location = ((XMLStreamReader) store).getLocation();
+            line   = location.getLineNumber()   + 1;
+            column = location.getColumnNumber() + 1;
+        } else if (store instanceof LineNumberReader) {
+            line = ((LineNumberReader) store).getLineNumber();
+        }
         final Object[] params = new Object[(line == 0) ? 2 : (column == 0) ? 3 : 4];
         switch (params.length) {
             default: // Fallthrough everywhere
@@ -581,27 +636,6 @@ public final class IOUtilities extends S
             case 1:  params[0] = format;
             case 0:  break;
         }
-        return errors.getString((line   == 0) ? Errors.Keys.CanNotParseFile_2 :
-                                (column == 0) ? Errors.Keys.CanNotParseFile_3 :
-                                                Errors.Keys.CanNotParseFile_4, params);
-    }
-
-    /**
-     * Returns an error message a file that can not be parsed because of an error at the current line.
-     * This method uses the {@link LineNumberReader#getLineNumber()} value if the given {@code input}
-     * is an instance of {@link LineNumberReader}.
-     *
-     * @param  errors    the resource bundle to use for creating the message.
-     * @param  format    abbreviation of the file format (e.g. "CSV", "GML", "WKT", <i>etc</i>).
-     * @param  filename  name of the file being parsed.
-     * @param  input     the reader, preferably as an instance of {@link LineNumberReader}.
-     * @return a localized error message for a file that can not be parsed.
-     *
-     * @since 0.8
-     */
-    @SuppressWarnings("fallthrough")
-    public static String canNotParseFile(final Errors errors, final String format, final String filename, final Reader input) {
-        return canNotParseFile(errors, format, filename,
-                (input instanceof LineNumberReader) ? ((LineNumberReader) input).getLineNumber() : 0, 0);
+        return params;
     }
 }

Modified: sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -61,35 +61,75 @@ public final class Resources extends Ind
         }
 
         /**
+         * Can not read \u201c{1}\u201d as a file in the {0} format.
+         */
+        public static final short CanNotReadFile_2 = 1;
+
+        /**
+         * Can not read line {2} of \u201c{1}\u201d as part of a file in the {0} format.
+         */
+        public static final short CanNotReadFile_3 = 2;
+
+        /**
+         * Can not read line {2} (after column {3}) of \u201c{1}\u201d as part of a file in the {0} format.
+         */
+        public static final short CanNotReadFile_4 = 3;
+
+        /**
+         * This {0} reader is closed.
+         */
+        public static final short ClosedReader_1 = 4;
+
+        /**
+         * This {0} writer is closed.
+         */
+        public static final short ClosedWriter_1 = 5;
+
+        /**
          * Character string in the \u201c{0}\u201d file is too long. The string has {2} characters while the
          * limit is {1}.
          */
-        public static final short ExcessiveStringSize_3 = 0;
+        public static final short ExcessiveStringSize_3 = 6;
+
+        /**
+         * The {0} data store does not accept features of type \u201c{1}\u201d.
+         */
+        public static final short IllegalFeatureType_2 = 7;
+
+        /**
+         * The {0} reader does not accept inputs of type \u2018{1}\u2019.
+         */
+        public static final short IllegalInputTypeForReader_2 = 8;
+
+        /**
+         * The {0} writer does not accept outputs of type \u2018{1}\u2019.
+         */
+        public static final short IllegalOutputTypeForWriter_2 = 9;
 
         /**
          * Components of the \u201c{0}\u201d name are inconsistent with those of the name that was added.
          */
-        public static final short InconsistentNameComponents_1 = 4;
+        public static final short InconsistentNameComponents_1 = 10;
 
         /**
          * Missing scheme in \u201c{0}\u201d URI.
          */
-        public static final short MissingSchemeInURI_1 = 1;
+        public static final short MissingSchemeInURI_1 = 11;
 
         /**
          * Processing executed on {0}.
          */
-        public static final short ProcessingExecutedOn_1 = 5;
+        public static final short ProcessingExecutedOn_1 = 12;
 
         /**
          * Can not move backward in the \u201c{0}\u201d stream.
          */
-        public static final short StreamIsForwardOnly_1 = 2;
+        public static final short StreamIsForwardOnly_1 = 13;
 
         /**
          * Format of \u201c{0}\u201d is not recognized.
          */
-        public static final short UnknownFormatFor_1 = 3;
+        public static final short UnknownFormatFor_1 = 14;
     }
 
     /**

Modified: sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties [ISO-8859-1] Sat Dec 31 07:33:01 2016
@@ -19,7 +19,15 @@
 # Resources in this file are for "sis-netcdf" 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.
 #
+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.
+ClosedReader_1                    = This {0} reader is closed.
+ClosedWriter_1                    = This {0} writer is closed.
 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_1      = Components of the \u201c{0}\u201d name are inconsistent with those of the name that was added.
 MissingSchemeInURI_1              = Missing scheme in \u201c{0}\u201d URI.
 ProcessingExecutedOn_1            = Processing executed on {0}.

Modified: sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties [ISO-8859-1] Sat Dec 31 07:33:01 2016
@@ -24,7 +24,15 @@
 #   U+202F NARROW NO-BREAK SPACE  before  ; ! and ?
 #   U+00A0 NO-BREAK SPACE         before  :
 #
+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}.
+ClosedReader_1                    = Ce lecteur {0} est ferm\u00e9.
+ClosedWriter_1                    = Cet encodeur {0} est ferm\u00e9.
 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}.
+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.
 InconsistentNameComponents_1      = Les \u00e9l\u00e9ments qui composent le nom \u00ab\u202f{0}\u202f\u00bb ne sont pas coh\u00e9rents avec ceux du nom qui avait \u00e9t\u00e9 ajout\u00e9.
 MissingSchemeInURI_1              = Il manque le sch\u00e9ma dans l\u2019URI \u00ab\u202f{0}\u202f\u00bb.
 ProcessingExecutedOn_1            = Traitement ex\u00e9cut\u00e9 sur {0}.

Modified: sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -240,11 +240,11 @@ public final class Store extends Feature
             }
             source.reset();
         } catch (IOException e) {
-            throw new DataStoreException(canNotParseFile(), e);
+            throw new DataStoreException(getLocale(), "CSV", filename, source).initCause(e);
         } catch (FactoryException e) {
-            throw new DataStoreReferencingException(canNotParseFile(), e);
+            throw new DataStoreReferencingException(getLocale(), "CSV", filename, source).initCause(e);
         } catch (IllegalArgumentException | DateTimeException e) {
-            throw new DataStoreContentException(canNotParseFile(), e);
+            throw new DataStoreContentException(getLocale(), "CSV", filename, source).initCause(e);
         }
         this.encoding    = connector.getOption(OptionKey.ENCODING);
         this.envelope    = envelope;
@@ -284,7 +284,7 @@ public final class Store extends Feature
                     case 2: if (element.length() == 2 && Character.toUpperCase(element.charAt(1)) == 'D') {
                                 spatialDimensionCount = element.charAt(0) - '0';
                                 if (spatialDimensionCount < 2 || spatialDimensionCount > 3) {
-                                    throw new DataStoreContentException(errors().getString(
+                                    throw new DataStoreReferencingException(errors().getString(
                                         Errors.Keys.IllegalCoordinateSystem_1, element));
                                 }
                                 continue;
@@ -306,7 +306,7 @@ public final class Store extends Feature
                                 case "hour":     timeUnit = Units.HOUR;   continue;
                                 case "day":      timeUnit = Units.DAY;    continue;
                                 case "absolute": isTimeAbsolute = true;   continue;
-                                default: throw new DataStoreContentException(errors().getString(Errors.Keys.UnknownUnit_1, element));
+                                default: throw new DataStoreReferencingException(errors().getString(Errors.Keys.UnknownUnit_1, element));
                             }
                 }
                 // If we reach this point, there is some remaining unknown elements. Ignore them.
@@ -369,7 +369,7 @@ public final class Store extends Feature
         if ((dim = lowerCorner.length) != spatialDimensionCount ||
             (dim = upperCorner.length) != spatialDimensionCount)
         {
-            throw new DataStoreContentException(errors().getString(
+            throw new DataStoreReferencingException(errors().getString(
                     Errors.Keys.MismatchedDimension_2, dim, spatialDimensionCount));
         }
         for (int i=0; i<spatialDimensionCount; i++) {
@@ -502,7 +502,7 @@ public final class Store extends Feature
             try {
                 builder.addExtent(envelope);
             } catch (TransformException e) {
-                throw new DataStoreReferencingException(canNotParseFile(), e);
+                throw new DataStoreReferencingException(getLocale(), "CSV", filename, source).initCause(e);
             } catch (UnsupportedOperationException e) {
                 // Failed to set the temporal components if the sis-temporal module was
                 // not on the classpath, but the other dimensions still have been set.
@@ -768,7 +768,8 @@ public final class Store extends Feature
      * The error message will contain the line number if available.
      */
     final String canNotParseFile() {
-        return IOUtilities.canNotParseFile(errors(), "CSV", filename, source);
+        final Object[] parameters = IOUtilities.errorMessageParameters("CSV", filename, source);
+        return errors().getString(IOUtilities.errorMessageKey(parameters), parameters);
     }
 
     /**

Modified: sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -34,7 +34,6 @@ import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreContentException;
-import org.apache.sis.internal.storage.IOUtilities;
 import org.apache.sis.metadata.iso.DefaultMetadata;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.CharSequences;
@@ -139,21 +138,13 @@ final class Store extends DataStore {
                 }
             } while (pos.getIndex() < wkt.length());
         } catch (ParseException e) {
-            throw new DataStoreContentException(canNotParseFile(in), e);
+            throw new DataStoreContentException(getLocale(), "WKT", name, in).initCause(e);
         } catch (IOException e) {
-            throw new DataStoreException(canNotParseFile(in), e);
+            throw new DataStoreException(getLocale(), "WKT", name, in).initCause(e);
         }
     }
 
     /**
-     * Returns the error message for a file that can not be parsed.
-     * The error message will contain the line number if available.
-     */
-    private String canNotParseFile(final Reader in) {
-        return IOUtilities.canNotParseFile(Errors.getResources(getLocale()), "WKT", name, in);
-    }
-
-    /**
      * 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 cases.

Modified: sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -99,7 +99,7 @@ public abstract class DataStore implemen
 
     /**
      * The locale to use for formatting warnings and other messages. This locale if for user interfaces
-     * only - it has no effect on the data to be read or written from/to the data store.
+     * only \u2013 it has no effect on the data to be read or written from/to the data store.
      *
      * <p>The default value is the {@linkplain Locale#getDefault() system default locale}.</p>
      */
@@ -110,8 +110,16 @@ public abstract class DataStore implemen
 
     /**
      * Sets the locale to use for formatting warnings and other messages.
+     * In a client-server architecture, it should be the locale on the <em>client</em> side.
+     *
+     * <p>This locale is used on a <cite>best-effort</cite> basis; whether messages will honor this locale or not
+     * depends on the code that logged warnings or threw exceptions. In Apache SIS implementation, this locale has
+     * better chances to be honored by the {@link DataStoreException#getLocalizedMessage()} method rather than
+     * {@code getMessage()}. See {@code getLocalizedMessage()} javadoc for more information.</p>
      *
      * @param locale  the new locale to use.
+     *
+     * @see DataStoreException#getLocalizedMessage()
      */
     public synchronized void setLocale(final Locale locale) {
         ArgumentChecks.ensureNonNull("locale", locale);

Modified: sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreClosedException.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreClosedException.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreClosedException.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreClosedException.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -16,13 +16,18 @@
  */
 package org.apache.sis.storage;
 
+import java.util.Locale;
+import java.nio.file.OpenOption;
+import org.apache.sis.internal.storage.IOUtilities;
+import org.apache.sis.internal.storage.Resources;
+
 
 /**
  * Thrown when a data store is closed and can no more return data.
  *
  * @author  Marc Le Bihan
  * @version 0.6
- * @since   0.6
+ * @since   0.8
  * @module
  */
 public class DataStoreClosedException extends DataStoreException {
@@ -49,4 +54,20 @@ public class DataStoreClosedException ex
     public DataStoreClosedException(String message, Throwable cause) {
         super(message, cause);
     }
+
+    /**
+     * Creates a localized exception for a reader or writer which has been closed.
+     * Arguments given to this constructor are hints for building an error message.
+     *
+     * @param locale   the locale of the message to be returned by {@link #getLocalizedMessage()}, or {@code null}.
+     * @param format   short name or abbreviation of the data format (e.g. "CSV", "GML", "WKT", <i>etc</i>).
+     * @param options  the option used for opening the file, or {@code null} or empty if unknown.
+     *                 This method looks in particular for {@link java.nio.file.StandardOpenOption#READ} and
+     *                 {@code WRITE} options for inferring if the data store was used as a reader or as a writer.
+     *
+     * @since 0.8
+     */
+    public DataStoreClosedException(final Locale locale, final String format, final OpenOption... options) {
+        super(locale, IOUtilities.isWrite(options) ? Resources.Keys.ClosedWriter_1 : Resources.Keys.ClosedReader_1, format);
+    }
 }

Modified: sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreContentException.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreContentException.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreContentException.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreContentException.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -16,6 +16,8 @@
  */
 package org.apache.sis.storage;
 
+import java.util.Locale;
+
 
 /**
  * Thrown when a store can not be read because the stream contains invalid data.
@@ -66,4 +68,20 @@ public class DataStoreContentException e
     public DataStoreContentException(String message, Throwable cause) {
         super(message, cause);
     }
+
+    /**
+     * Creates a localized exception with a message saying that the given store can not be read.
+     * Location in the file where the error occurred while be fetched from the given {@code store}
+     * argument if possible. If the given store is not recognized, then it will be ignored.
+     *
+     * @param locale    the locale of the message to be returned by {@link #getLocalizedMessage()}, or {@code null}.
+     * @param format    short name or abbreviation of the data format (e.g. "CSV", "GML", "WKT", <i>etc</i>).
+     * @param filename  name of the file or data store where the error occurred.
+     * @param store     the input or output object from which to get the current position, or {@code null} if none.
+     *                  This can be a {@link java.io.LineNumberReader} or {@link javax.xml.stream.XMLStreamReader}
+     *                  for example.
+     */
+    public DataStoreContentException(Locale locale, String format, String filename, Object store) {
+        super(locale, format, filename, store);
+    }
 }

Modified: sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreException.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreException.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreException.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreException.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -16,22 +16,53 @@
  */
 package org.apache.sis.storage;
 
+import java.util.Locale;
+import org.opengis.util.InternationalString;
+import org.apache.sis.util.LocalizedException;
+import org.apache.sis.internal.storage.Resources;
+import org.apache.sis.internal.storage.IOUtilities;
+import org.apache.sis.util.Workaround;
+
 
 /**
  * Thrown when a {@link DataStore} can not complete a read or write operation.
  *
+ * <div class="section">Localization</div>
+ * The {@link #getMessage()} and {@link #getLocalizedMessage()} methods return the same message,
+ * but sometime in different languages. The general policy is that {@link #getMessage()} returns
+ * the message in the JVM {@linkplain Locale#getDefault() default locale} while {@link #getLocalizedMessage()}
+ * returns the message in the locale specified by the last call to {@link DataStore#setLocale(Locale)}.
+ * In a client-server architecture, the former is typically the locale of the system administrator
+ * while the later is presumably the locale of the client connected to the server.
+ * However this policy is applied on a <em>best-effort</em> basis only.
+ *
  * @author  Johann Sorel (Geomatys)
+ * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.8
  * @module
  */
-public class DataStoreException extends Exception {
+public class DataStoreException extends Exception implements LocalizedException {
     /**
      * For cross-version compatibility.
      */
     private static final long serialVersionUID = -1778987176103191950L;
 
     /**
+     * The resources key as one of the {@link Resources.Keys} constant, or 0 if none.
+     *
+     * <p>This field is not serialized because key values sometime change between different SIS versions.
+     * The deserialized value will be 0, which will cause this {@code DataStoreException} to fallback on
+     * {@code super.getMessage()}.</p>
+     */
+    private transient short key;
+
+    /**
+     * The parameters for the localization message, or {@code null} if none.
+     */
+    private transient Object[] parameters;
+
+    /**
      * Creates an exception with no cause and no details message.
      */
     public DataStoreException() {
@@ -41,7 +72,7 @@ public class DataStoreException extends
     /**
      * Creates an exception with the specified details message.
      *
-     * @param message  the detail message.
+     * @param message  the detail message in the default locale.
      */
     public DataStoreException(final String message) {
         super(message);
@@ -59,10 +90,113 @@ public class DataStoreException extends
     /**
      * Creates an exception with the specified details message and cause.
      *
-     * @param message  the detail message.
+     * @param message  the detail message in the default locale.
      * @param cause    the cause for this exception.
      */
     public DataStoreException(final String message, final Throwable cause) {
         super(message, cause);
     }
+
+    /**
+     * Creates a localized exception with a message saying that the given store can not be processed.
+     * Location in the file where the error occurred while be fetched from the given {@code store}
+     * argument if possible, for example by invoking the {@link java.io.LineNumberReader#getLineNumber()}
+     * or {@link javax.xml.stream.XMLStreamReader#getLocation()} method.
+     * If the given {@code store} argument is not one of the recognized types, then it is ignored.
+     *
+     * @param locale    the locale of the message to be returned by {@link #getLocalizedMessage()}, or {@code null}.
+     * @param format    short name or abbreviation of the data format (e.g. "CSV", "GML", "WKT", <i>etc</i>).
+     * @param filename  name of the file or data store where the error occurred.
+     * @param store     the input or output object from which to get the current position, or {@code null} if none.
+     *                  This can be a {@link LineNumberReader} or {@link XMLStreamReader} for example.
+     *
+     * @since 0.8
+     */
+    public DataStoreException(final Locale locale, final String format, final String filename, final Object store) {
+        this(locale, IOUtilities.errorMessageParameters(format, filename, store));
+    }
+
+    /**
+     * Workaround for RFE #4093999
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    @Workaround(library="JDK", version="1.8")
+    private DataStoreException(final Locale locale, final Object[] params) {
+        this(locale, IOUtilities.errorMessageKey(params), params);
+    }
+
+    /**
+     * Creates a new exception which will format a localized message in the given locale.
+     *
+     * @param locale      the locale for the message to be returned by {@link #getLocalizedMessage()}.
+     * @param key         one of {@link Resources.Keys} constants.
+     * @param parameters  parameters to use for formatting the messages.
+     */
+    DataStoreException(final Locale locale, final short key, final Object... parameters) {
+        super(Resources.forLocale(locale).getString(key, parameters));
+        this.key        = key;
+        this.parameters = parameters;
+    }
+
+    /**
+     * Returns the exception message in the default locale, typically for system administrator.
+     *
+     * @return the message of this exception.
+     */
+    @Override
+    public String getMessage() {
+        return (key != 0) ? Resources.format(key, parameters) : super.getMessage();
+    }
+
+    /**
+     * Returns a localized version of the exception message, typically for final user.
+     * This is often the same message than the one returned by {@link #getMessage()},
+     * but may in some occasions be different if {@link DataStore#setLocale(Locale)}
+     * has been invoked with a different locale.
+     *
+     * <div class="section">{@code getMessage()} versus {@code getLocalizedMessage()}</div>
+     * When {@code getMessage()} and {@code getLocalizedMessage()} are not equivalent, the Apache SIS policy
+     * is that {@code getMessage()} returns the message in the {@linkplain Locale#getDefault() default locale}
+     * while {@code getLocalizedMessage()} returns the message in a locale that depends on the context in which
+     * the exception has been thrown.
+     *
+     * In a client-server architecture, the former is often the locale on the <em>server</em> side while the later
+     * is the locale on the <em>client</em> side if that information has been provided to the {@link DataStore}.
+     *
+     * @return the localized message of this exception.
+     *
+     * @see DataStore#setLocale(Locale)
+     *
+     * @since 0.8
+     */
+    @Override
+    public String getLocalizedMessage() {
+        return super.getMessage();
+    }
+
+    /**
+     * If this exception is capable to return the message in various locales, returns that message.
+     * Otherwise returns {@code null}.
+     *
+     * @return the exception message, or {@code null} if this exception can not produce international message.
+     *
+     * @since 0.8
+     */
+    @Override
+    public InternationalString getInternationalMessage() {
+        return (key != 0) ? Resources.formatInternational(key, parameters) : null;
+    }
+
+    /**
+     * Initializes the <i>cause</i> of this throwable to the specified value.
+     *
+     * @param  cause  the cause saved for later retrieval by the {@link #getCause()} method.
+     * @return a reference to this {@code DataStoreException} instance.
+     *
+     * @since 0.8
+     */
+    @Override
+    public DataStoreException initCause(final Throwable cause) {
+        return (DataStoreException) super.initCause(cause);
+    }
 }

Modified: sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreReferencingException.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreReferencingException.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreReferencingException.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreReferencingException.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -16,6 +16,8 @@
  */
 package org.apache.sis.storage;
 
+import java.util.Locale;
+
 
 /**
  * Thrown when a data store failed to construct the coordinate reference system (CRS)
@@ -35,13 +37,6 @@ public class DataStoreReferencingExcepti
     private static final long serialVersionUID = 2671737996817267335L;
 
     /**
-     * Creates an exception with no cause and no details message.
-     */
-    public DataStoreReferencingException() {
-        super();
-    }
-
-    /**
      * Creates an exception with the specified details message.
      *
      * @param message  the detail message.
@@ -68,4 +63,20 @@ public class DataStoreReferencingExcepti
     public DataStoreReferencingException(final String message, final Throwable cause) {
         super(message, cause);
     }
+
+    /**
+     * Creates a localized exception with a message saying that the given store can not be read.
+     * Location in the file where the error occurred while be fetched from the given {@code store}
+     * argument if possible. If the given store is not recognized, then it will be ignored.
+     *
+     * @param locale    the locale of the message to be returned by {@link #getLocalizedMessage()}, or {@code null}.
+     * @param format    short name or abbreviation of the data format (e.g. "CSV", "GML", "WKT", <i>etc</i>).
+     * @param filename  name of the file or data store where the error occurred.
+     * @param store     the input or output object from which to get the current position, or {@code null} if none.
+     *                  This can be a {@link java.io.LineNumberReader} or {@link javax.xml.stream.XMLStreamReader}
+     *                  for example.
+     */
+    public DataStoreReferencingException(Locale locale, String format, String filename, Object store) {
+        super(locale, format, filename, store);
+    }
 }

Modified: sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -212,7 +212,7 @@ search:         while (!deferred.isEmpty
             }
         }
         if (open && selected == null) {
-            throw new UnsupportedStorageException(Resources.format(Resources.Keys.UnknownFormatFor_1, connector.getStorageName()));
+            throw new UnsupportedStorageException(null, Resources.Keys.UnknownFormatFor_1, connector.getStorageName());
         }
         return selected;
     }

Modified: sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/UnsupportedStorageException.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/UnsupportedStorageException.java?rev=1776697&r1=1776696&r2=1776697&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/UnsupportedStorageException.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/UnsupportedStorageException.java [UTF-8] Sat Dec 31 07:33:01 2016
@@ -16,6 +16,12 @@
  */
 package org.apache.sis.storage;
 
+import java.util.Locale;
+import java.nio.file.OpenOption;
+import org.apache.sis.util.Classes;
+import org.apache.sis.internal.storage.Resources;
+import org.apache.sis.internal.storage.IOUtilities;
+
 
 /**
  * Thrown when no {@link DataStoreProvider} is found for a given storage object.
@@ -24,7 +30,7 @@ package org.apache.sis.storage;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.8
  * @module
  */
 public class UnsupportedStorageException extends DataStoreException {
@@ -67,4 +73,35 @@ public class UnsupportedStorageException
     public UnsupportedStorageException(final String message, final Throwable cause) {
         super(message, cause);
     }
+
+    /**
+     * Creates a new exception which will format a localized message in the given locale.
+     *
+     * @param locale      the locale for the message to be returned by {@link #getLocalizedMessage()}.
+     * @param key         one of {@link Resources.Keys} constants.
+     * @param parameters  parameters to use for formatting the messages.
+     */
+    UnsupportedStorageException(final Locale locale, final short key, final Object... parameters) {
+        super(locale, key, parameters);
+    }
+
+    /**
+     * Creates a localized exception for an invalid input or output object given to a data store.
+     * Arguments given to this constructor are hints for building an error message.
+     *
+     * @param locale   the locale of the message to be returned by {@link #getLocalizedMessage()}, or {@code null}.
+     * @param format   short name or abbreviation of the data format (e.g. "CSV", "GML", "WKT", <i>etc</i>).
+     * @param storage  the invalid input or output object. This is typically {@link StorageConnector#getStorage()}.
+     * @param options  the option used for opening the file, or {@code null} or empty if unknown.
+     *                 This method looks in particular for {@link java.nio.file.StandardOpenOption#READ} and
+     *                 {@code WRITE} options for inferring if the data store was to be used as a reader or as a writer.
+     *                 Those options can be obtained by {@code StorageConnector.getOption(OptionKey.OPEN_OPTIONS)}.
+     *
+     * @since 0.8
+     */
+    public UnsupportedStorageException(final Locale locale, final String format, final Object storage, final OpenOption... options) {
+        super(locale, IOUtilities.isWrite(options) ? Resources.Keys.IllegalOutputTypeForWriter_2
+                                                   : Resources.Keys.IllegalInputTypeForReader_2,
+                      format, Classes.getClass(storage));
+    }
 }