sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1509317 - in /sis/trunk: ./ application/sis-console/src/main/java/org/apache/sis/console/ core/sis-metadata/src/main/java/org/apache/sis/metadata/ core/sis-referencing/src/main/java/org/apache/sis/geometry/ core/sis-utility/src/main/java/o...
Date Thu, 01 Aug 2013 16:28:18 GMT
Author: desruisseaux
Date: Thu Aug  1 16:28:17 2013
New Revision: 1509317

URL: http://svn.apache.org/r1509317
Log:
Merge from the JDK6 branch.

Added:
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/Files.java
      - copied unchanged from r1509316, sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/Files.java
    sis/trunk/storage/sis-netcdf/src/main/resources/
      - copied from r1509316, sis/branches/JDK6/storage/sis-netcdf/src/main/resources/
    sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java
      - copied unchanged from r1509316, sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java
    sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java
      - copied unchanged from r1509316, sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java
    sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/ProbeResult.java
      - copied unchanged from r1509316, sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/storage/ProbeResult.java
    sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/UnsupportedStorageException.java
      - copied unchanged from r1509316, sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/storage/UnsupportedStorageException.java
Modified:
    sis/trunk/   (props changed)
    sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNodeChildren.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/AdapterReplacement.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/TypeRegistration.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/Objects.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/StandardCharsets.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/setup/OptionKey.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/package-info.java
    sis/trunk/ide-project/NetBeans/build.xml
    sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
    sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/NetcdfStoreProviderTest.java
    sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/IOUtilities.java
    sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
    sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
    sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java
    sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/package-info.java

Propchange: sis/trunk/
------------------------------------------------------------------------------
  Merged /sis/branches/JDK7:r1508458-1509300
  Merged /sis/branches/JDK6:r1508464-1509316

Modified: sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java
URL: http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java [UTF-8] (original)
+++ sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -23,9 +23,9 @@ import javax.xml.bind.JAXBException;
 import org.opengis.metadata.Metadata;
 import org.apache.sis.metadata.MetadataStandard;
 import org.apache.sis.metadata.ValueExistencePolicy;
+import org.apache.sis.storage.DataStore;
+import org.apache.sis.storage.DataStores;
 import org.apache.sis.storage.DataStoreException;
-import org.apache.sis.storage.StorageConnector;
-import org.apache.sis.storage.netcdf.NetcdfStore;
 import org.apache.sis.util.collection.TableColumn;
 import org.apache.sis.util.collection.TreeTable;
 import org.apache.sis.util.collection.TreeTableFormat;
@@ -80,7 +80,7 @@ final class MetadataSC extends SubComman
             return Command.INVALID_ARGUMENT_EXIT_CODE;
         }
         final Metadata metadata;
-        final NetcdfStore store = new NetcdfStore(new StorageConnector(files.get(0)));
+        final DataStore store = DataStores.open(files.get(0));
         try {
             metadata = store.getMetadata();
         } finally {

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -1085,47 +1085,6 @@ final class PropertyAccessor {
     }
 
     /**
-     * Appends all non-empty metadata from source to target. The source can be any implementation
-     * of the metadata interface, but the target must be the implementation expected by this class.
-     *
-     * <p>If the source contains any null or empty properties, then those properties will
-     * not overwrite the corresponding properties in the destination metadata.</p>
-     *
-     * @param  source The metadata to copy.
-     * @param  target The target metadata where to append.
-     * @return {@code true} in case of success, or {@code false} if at least
-     *         one setter method was not found.
-     * @throws UnmodifiableMetadataException if the target metadata is unmodifiable.
-     * @throws BackingStoreException If the implementation threw a checked exception.
-     */
-    public boolean append(final Object source, final Object target)
-            throws UnmodifiableMetadataException, BackingStoreException
-    {
-        // Because this PropertyAccesssor is designed for the target, we must
-        // check if the extra methods are suitable for the source object.
-        assert type.isInstance(source) : Classes.getClass(source);
-        boolean success = true;
-        final Object[] arguments = new Object[1];
-        for (int i=0; i<standardCount; i++) {
-            final Method getter = getters[i];
-            arguments[0] = get(getter, source);
-            if (!isNullOrEmpty(arguments[0])) {
-                if (setters == null) {
-                    return false;
-                }
-                final Method setter = setters[i];
-                if (setter != null) {
-                    convert(getter, target, null, arguments, elementTypes[i], true);
-                    set(setter, target, arguments);
-                } else {
-                    success = false;
-                }
-            }
-        }
-        return success;
-    }
-
-    /**
      * Replaces every properties in the specified metadata by their
      * {@linkplain ModifiableMetadata#unmodifiable() unmodifiable variant}.
      *

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNodeChildren.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNodeChildren.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNodeChildren.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNodeChildren.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -476,7 +476,8 @@ final class TreeNodeChildren extends Abs
      * are ignored.
      *
      * <p>If the identified property is a collection, then this method adds the value to that collection.
-     * Otherwise the new value will be set only if the previous value is null or empty.</p>
+     * Otherwise the new value will be set only if the previous value is null,
+     * {@linkplain org.apache.sis.xml.NilObject nil} or empty.</p>
      *
      * <p>This method does not iterate explicitly through the children list, because adding a metadata
      * object implicitly adds all its children.</p>

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -543,6 +543,10 @@ public class Envelope2D extends Rectangl
      *       represents this envelope as four separated rectangles.
      * </ul>
      *
+     * {@note The return type is the <code>Rectangle2D.Double</code> implementation class rather than the
+     *        <code>Rectangle2D</code> abstract class because the <code>Envelope2D</code> class hierarchy
+     *        already exposes this implementation choice.}
+     *
      * @return A representation of this envelope as an array of non-empty Java2D rectangles.
      *         The array never contains {@code this}.
      *

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/AdapterReplacement.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/AdapterReplacement.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/AdapterReplacement.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/AdapterReplacement.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.internal.jaxb;
 
-import java.util.ServiceLoader;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
 import javax.xml.bind.JAXBException;
@@ -47,22 +46,6 @@ import javax.xml.bind.annotation.adapter
  */
 public interface AdapterReplacement {
     /**
-     * The system-wide provider of {@code AdapterReplacement} instances.
-     * <strong>Every usage of this service loader must be synchronized.</strong>
-     * This loader is public for {@link org.apache.sis.xml.MarshallerPool} usage.
-     *
-     * <p>This loader needs to be cleared as below when modules are loaded or unloaded.
-     * This is done opportunistically by {@link TypeRegistration}.</p>
-     *
-     * {@preformat java
-     *     synchronized (AdapterReplacement.PROVIDER) {
-     *         AdapterReplacement.PROVIDER.reload();
-     *     }
-     * }
-     */
-    ServiceLoader<AdapterReplacement> PROVIDER = ServiceLoader.load(AdapterReplacement.class);
-
-    /**
      * Invoked when a new adapter is created by {@link org.apache.sis.xml.MarshallerPool}.
      * Typical implementations will be as below:
      *

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/TypeRegistration.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/TypeRegistration.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/TypeRegistration.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/TypeRegistration.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -49,22 +49,11 @@ public abstract class TypeRegistration {
     /**
      * The JAXB context, or {@code null} if not yet created or if the classpath changed.
      */
-    private static Reference<JAXBContext> context;
+    private static volatile Reference<JAXBContext> context;
     static {
         SystemListener.add(new SystemListener(Modules.UTILITIES) {
             @Override protected void classpathChanged() {
-                synchronized (TypeRegistration.class) {
-                    context = null;
-                }
-                /*
-                 * Opportunistically clears the AdapterReplacement.PROVIDER. We can not do this work in the
-                 * AdapterReplacement interface because we can not declare static initializer in interfaces.
-                 * This TypeRegistration class is an acceptable fallback because MarshallerPool uses this
-                 * class before to use AdapterReplacement.
-                 */
-                synchronized (AdapterReplacement.PROVIDER) {
-                    AdapterReplacement.PROVIDER.reload();
-                }
+                context = null;
             }
         });
     }
@@ -116,8 +105,9 @@ public abstract class TypeRegistration {
      * @throws JAXBException If an error occurred while creating the JAXB context.
      */
     public static synchronized JAXBContext getSharedContext() throws JAXBException {
-        if (context != null) {
-            final JAXBContext instance = context.get();
+        final Reference<JAXBContext> c = context;
+        if (c != null) {
+            final JAXBContext instance = c.get();
             if (instance != null) {
                 return instance;
             }

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/Objects.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/Objects.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/Objects.java (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/Objects.java Thu Aug  1 16:28:17 2013
@@ -21,7 +21,7 @@ import java.util.Arrays;
 
 /**
  * Place holder for {@link java.util.Objects}.
- * This class will be deleted when we will be allowed to compile for JDK7.
+ * This class exists only on the JDK6 branch of SIS.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from GeoAPI)

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/StandardCharsets.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/StandardCharsets.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/StandardCharsets.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk7/StandardCharsets.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -21,7 +21,7 @@ import java.nio.charset.Charset;
 
 /**
  * Place holder for {@link java.nio.charset.StandardCharsets}.
- * This class will be deleted when we will be allowed to compile for JDK7.
+ * This class exists only on the JDK6 branch of SIS.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from GeoAPI)

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -41,6 +41,11 @@ public final class Modules {
     /**
      * The {@value} module name.
      */
+    public static final String STORAGE = "org.apache.sis.storage";
+
+    /**
+     * The {@value} module name.
+     */
     public static final String NETCDF = "org.apache.sis.storage.netcdf";
 
     /**

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/setup/OptionKey.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/setup/OptionKey.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/setup/OptionKey.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/setup/OptionKey.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -33,7 +33,7 @@ import org.apache.sis.util.logging.Loggi
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.4
  * @module
  */
 public class OptionKey<T> implements Serializable {
@@ -45,10 +45,10 @@ public class OptionKey<T> implements Ser
     /**
      * The encoding of a URL (<strong>not</strong> the encoding of the document content).
      * This option may be used when converting a {@link String} or a {@link java.net.URL}
-     * to a {@link java.net.URI} or a {@link java.io.File}:
+     * to a {@link java.net.URI} or a {@link java.io.File}. The following rules apply:
      *
      * <ul>
-     *   <li>URI are always encoded in UTF-8.</li>
+     *   <li>URI are always encoded in UTF-8. Consequently this option is ignored for URI.</li>
      *   <li>URL are often encoded in UTF-8, but not necessarily. Other encodings are possible
      *       (while not recommended), or some URL may not be encoded at all.</li>
      * </ul>
@@ -75,6 +75,25 @@ public class OptionKey<T> implements Ser
     public static final OptionKey<String> URL_ENCODING = new OptionKey<String>("URL_ENCODING", String.class);
 
     /**
+     * Whether a storage object (e.g. a {@link org.apache.sis.storage.DataStore}) shall be opened in read,
+     * write, append or other modes. The main options that can be provided are:
+     *
+     * <table class="sis">
+     *   <tr><th>Value</th>                             <th>Meaning</th></tr>
+     *   <tr><td>{@code "READ"}</td>   <td>Open for reading data from the storage object.</td></tr>
+     *   <tr><td>{@code "WRITE"}</td>  <td>Open for modifying existing data in the storage object.</td></tr>
+     *   <tr><td>{@code "APPEND"}</td> <td>Open for appending new data in the storage object.</td></tr>
+     *   <tr><td>{@link "CREATE"}</td> <td>Creates a new storage object (file or database) if it does not exist.</td></tr>
+     * </table>
+     *
+     * {@section Differences between the JDK6 and JDK7 branches of SIS}
+     * In the JDK7 branch of SIS, the array type for this key is {@code java.nio.file.OpenOption[]} instead than
+     * {@code Object[]} and the constants listed in the above table are {@code java.nio.file.StandardOpenOption}
+     * enumeration values.
+     */
+    public static final OptionKey<Object[]> OPEN_OPTIONS = new OptionKey<Object[]>("OPEN_OPTIONS", Object[].class);
+
+    /**
      * The byte buffer to use for input/output operations. Some {@link org.apache.sis.storage.DataStore}
      * implementations allow a byte buffer to be specified, thus allowing users to choose the buffer
      * {@linkplain ByteBuffer#capacity() capacity}, whether the buffer {@linkplain ByteBuffer#isDirect()

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -511,6 +511,11 @@ public final class Errors extends Indexe
         public static final int UnknownCommand_1 = 102;
 
         /**
+         * Format of “{0}” is not recognized.
+         */
+        public static final int UnknownFormatFor_1 = 107;
+
+        /**
          * Option “{0}” is not recognized.
          */
         public static final int UnknownOption_1 = 98;

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] Thu Aug  1 16:28:17 2013
@@ -114,6 +114,7 @@ UnexpectedEndOfFile_1           = Unexpe
 UnexpectedEndOfString_1         = More characters were expected at the end of \u201c{0}\u201d.
 UnexpectedFileFormat_2          = File \u201c{1}\u201d seems to be encoded in an other format than {0}.
 UnknownCommand_1                = Command \u201c{0}\u201d is not recognized.
+UnknownFormatFor_1              = Format of \u201c{0}\u201d is not recognized.
 UnknownOption_1                 = Option \u201c{0}\u201d is not recognized.
 UnknownType_1                   = Type \u2018{0}\u2019 is unknown in this context.
 UnknownTypeForProperty_1        = Type of the \u201c{0}\u201d property is unknown.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] Thu Aug  1 16:28:17 2013
@@ -103,6 +103,7 @@ UnexpectedEndOfFile_1           = Fin de
 UnexpectedEndOfString_1         = D\u2019autres caract\u00e8res \u00e9taient attendus \u00e0 la fin du texte \u201c{0}\u201d.
 UnexpectedFileFormat_2          = Le fichier \u201c{1}\u201d semble \u00eatre encod\u00e9 dans un autre format que {0}.
 UnknownCommand_1                = La commande \u201c{0}\u201d n\u2019est pas reconnue.
+UnknownFormatFor_1              = Le format de \u201c{0}\u201d n\u2019est pas reconnu.
 UnknownOption_1                 = L\u2019option \u201c{0}\u201d n\u2019est pas reconnue.
 UnknownType_1                   = Le type \u2018{0}\u2019 n\u2019est pas reconnu dans ce contexte.
 UnknownTypeForProperty_1        = Le type de la propri\u00e9t\u00e9 \u201c{0}\u201d est inconnu.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/MarshallerPool.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -18,6 +18,7 @@ package org.apache.sis.xml;
 
 import java.util.Map;
 import java.util.Deque;
+import java.util.ServiceLoader;
 import java.util.concurrent.LinkedBlockingDeque;
 import java.util.concurrent.atomic.AtomicBoolean;
 import javax.xml.bind.JAXBContext;
@@ -94,6 +95,17 @@ public class MarshallerPool {
     private final Object mapper;
 
     /**
+     * The provider of {@code AdapterReplacement} instances.
+     * <strong>Every usage of this service loader must be synchronized.</strong>
+     *
+     * {@note Each <code>MarshallerPool</code> has its own service loader instance rather than using a
+     *        system-wide instance because the <code>ClassLoader</code> used by the service loader is
+     *        the <cite>context class loader</cite>, which depends on the thread that created the pool.
+     *        So two pools in two different applications could have two different set of replacements.}
+     */
+    private final ServiceLoader<AdapterReplacement> replacements;
+
+    /**
      * The {@link PooledTemplate} to use for initializing recycled (un)marshaller.
      */
     private final PooledTemplate template;
@@ -167,6 +179,7 @@ public class MarshallerPool {
     public MarshallerPool(final JAXBContext context, final Map<String,?> properties) throws JAXBException {
         ArgumentChecks.ensureNonNull("context", context);
         this.context = context;
+        replacements = ServiceLoader.load(AdapterReplacement.class);
         /*
          * Detects if we are using the endorsed JAXB implementation (i.e. the one provided in
          * separated JAR files) or the one bundled in JDK 6. We use the JAXB context package
@@ -424,8 +437,8 @@ public class MarshallerPool {
             }
             // Do nothing for the OTHER case.
         }
-        synchronized (AdapterReplacement.PROVIDER) {
-            for (final AdapterReplacement adapter : AdapterReplacement.PROVIDER) {
+        synchronized (replacements) {
+            for (final AdapterReplacement adapter : replacements) {
                 adapter.register(marshaller);
             }
         }
@@ -442,8 +455,8 @@ public class MarshallerPool {
      */
     protected Unmarshaller createUnmarshaller() throws JAXBException {
         final Unmarshaller unmarshaller = context.createUnmarshaller();
-        synchronized (AdapterReplacement.PROVIDER) {
-            for (final AdapterReplacement adapter : AdapterReplacement.PROVIDER) {
+        synchronized (replacements) {
+            for (final AdapterReplacement adapter : replacements) {
                 adapter.register(unmarshaller);
             }
         }

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -431,6 +431,12 @@ public final class NilReason implements 
      * <p><b>REMINDER:<b> If more special cases are added, do not forget to update the {@link #mayBeNil(Object)}
      * method and to update the {@link #createNilObject(Class)} and {@link #forObject(Object)} javadoc.</p>
      *
+     * {@note There is no special case for <code>Character</code> because Java <code>char</code>s are not really
+     *        full Unicode characters. They are parts of UTF-16 encoding instead. If there is a need to represent
+     *        a single Unicode character, we should probably still use a <code>String</code> where the string may
+     *        contain up to 2 Java characters. This may also facilitate the encoding in the XML files, since many
+     *        files use an other encoding than UTF-16 anyway.}
+     *
      * @throws IllegalArgumentException If the given type is not a supported type.
      */
     private static Object createNilPrimitive(final Class<?> type) {

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/package-info.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/package-info.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/package-info.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/package-info.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -59,7 +59,7 @@
  * @author  Guilhem Legal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.00)
- * @version 0.3
+ * @version 0.4
  * @module
  */
 package org.apache.sis.xml;

Modified: sis/trunk/ide-project/NetBeans/build.xml
URL: http://svn.apache.org/viewvc/sis/trunk/ide-project/NetBeans/build.xml?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/ide-project/NetBeans/build.xml (original)
+++ sis/trunk/ide-project/NetBeans/build.xml Thu Aug  1 16:28:17 2013
@@ -46,16 +46,33 @@
     <!-- Following are classical properties resources files. -->
     <copy todir="${build.classes.dir}">
       <fileset dir="${project.root}/core/sis-utility/src/main/resources">
-        <include name="META-INF/services/*"/>
         <include name="**/*.properties"/>
       </fileset>
-      <fileset dir="${project.root}/core/sis-metadata/src/main/resources">
-        <include name="META-INF/services/*"/>
-      </fileset>
       <fileset dir="${project.root}/application/sis-console/src/main/resources">
         <include name="**/*.properties"/>
       </fileset>
     </copy>
+
+    <!-- ObjectConverter implementations to be loaded by ServiceLoader. -->
+    <concat destfile="${build.classes.dir}/META-INF/services/org.apache.sis.util.ObjectConverter" encoding="UTF-8" fixlastline="yes">
+      <fileset dir="${project.root}">
+        <include name="*/*/src/main/resources/META-INF/services/org.apache.sis.util.ObjectConverter"/>
+      </fileset>
+    </concat>
+
+    <!-- TypeRegistration implementations to be loaded by ServiceLoader. -->
+    <concat destfile="${build.classes.dir}/META-INF/services/org.apache.sis.internal.jaxb.TypeRegistration" encoding="UTF-8" fixlastline="yes">
+      <fileset dir="${project.root}">
+        <include name="*/*/src/main/resources/META-INF/services/org.apache.sis.internal.jaxb.TypeRegistration"/>
+      </fileset>
+    </concat>
+
+    <!-- DataStoreProvider implementations to be loaded by ServiceLoader. -->
+    <concat destfile="${build.classes.dir}/META-INF/services/org.apache.sis.storage.DataStoreProvider" encoding="UTF-8" fixlastline="yes">
+      <fileset dir="${project.root}">
+        <include name="*/*/src/main/resources/META-INF/services/org.apache.sis.storage.DataStoreProvider"/>
+      </fileset>
+    </concat>
   </target>
 
   <!--

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=1509317&r1=1509316&r2=1509317&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] Thu Aug  1 16:28:17 2013
@@ -32,7 +32,9 @@ import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreProvider;
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.ProbeResult;
 import org.apache.sis.util.logging.WarningListeners;
+import org.apache.sis.util.ThreadSafe;
 
 
 /**
@@ -44,11 +46,12 @@ import org.apache.sis.util.logging.Warni
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.4
  * @module
  *
  * @see NetcdfStore
  */
+@ThreadSafe
 public class NetcdfStoreProvider extends DataStoreProvider {
     /**
      * The name of the {@link ucar.nc2.NetcdfFile} class, which is {@value}.
@@ -99,27 +102,25 @@ public class NetcdfStoreProvider extends
     }
 
     /**
-     * Returns {@code TRUE} if the given storage appears to be supported by {@link NetcdfStore}.
-     * Returning {@code TRUE} from this method does not guarantee that reading or writing will succeed,
+     * Returns {@link ProbeResult#SUPPORTED} if the given storage appears to be supported by {@link NetcdfStore}.
+     * Returning {@code SUPPORTED} from this method does not guarantee that reading or writing will succeed,
      * only that there appears to be a reasonable chance of success based on a brief inspection of the
      * {@linkplain StorageConnector#getStorage() storage object} or contents.
      *
      * @param  storage Information about the storage (URL, stream, {@link ucar.nc2.NetcdfFile} instance, <i>etc</i>).
-     * @return {@link Boolean#TRUE} if the given storage seems to be usable by the {@code NetcdfStore} instances,
-     *         {@link Boolean#FALSE} if {@code NetcdfStore} will not be able to use the given storage,
-     *         or {@code null} if this method does not have enough information.
+     * @return {@code SUPPORTED} if the given storage seems to be usable by the {@code NetcdfStore} instances.
      * @throws DataStoreException if an I/O error occurred.
      */
     @Override
-    public Boolean canOpen(StorageConnector storage) throws DataStoreException {
+    public ProbeResult canOpen(StorageConnector storage) throws DataStoreException {
         final ByteBuffer buffer = storage.getStorageAs(ByteBuffer.class);
         if (buffer != null) {
             if (buffer.remaining() < Integer.SIZE / Byte.SIZE) {
-                return null;
+                return ProbeResult.UNDETERMINED;
             }
             final int header = buffer.getInt(buffer.position());
             if ((header & 0xFFFFFF00) == ChannelDecoder.MAGIC_NUMBER) {
-                return Boolean.TRUE;
+                return ProbeResult.SUPPORTED;
             }
         }
         /*
@@ -130,7 +131,7 @@ public class NetcdfStoreProvider extends
             ensureInitialized();
             final Method method = canOpenFromPath;
             if (method != null) try {
-                return (Boolean) method.invoke(null, path);
+                return ((Boolean) method.invoke(null, path)) ? ProbeResult.SUPPORTED : ProbeResult.UNKNOWN_FORMAT;
             } catch (IllegalAccessException e) {
                 throw new AssertionError(e); // Should never happen, since the method is public.
             } catch (InvocationTargetException e) {
@@ -148,16 +149,14 @@ public class NetcdfStoreProvider extends
          */
         for (Class<?> type = storage.getStorage().getClass(); type != null; type = type.getSuperclass()) {
             if (UCAR_CLASSNAME.equals(type.getName())) {
-                return Boolean.TRUE;
+                return ProbeResult.SUPPORTED;
             }
         }
-        return Boolean.FALSE;
+        return ProbeResult.UNKNOWN_FORMAT;
     }
 
     /**
-     * Returns a {@link NetcdfStore} implementation associated with this provider. This method invokes
-     * {@link StorageConnector#closeAllExcept(Object)} after data store creation, keeping open only
-     * the needed resource.
+     * Returns a {@link NetcdfStore} implementation associated with this provider.
      *
      * @param storage Information about the storage (URL, stream, {@link ucar.nc2.NetcdfFile} instance, <i>etc</i>).
      */

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=1509317&r1=1509316&r2=1509317&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] Thu Aug  1 16:28:17 2013
@@ -24,6 +24,7 @@ import org.apache.sis.internal.netcdf.De
 import org.apache.sis.internal.netcdf.ucar.DecoderWrapper;
 import org.apache.sis.internal.netcdf.impl.ChannelDecoder;
 import org.apache.sis.internal.netcdf.impl.ChannelDecoderTest;
+import org.apache.sis.storage.ProbeResult;
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.test.DependsOn;
@@ -54,7 +55,7 @@ public final strictfp class NetcdfStoreP
     public void testCanOpenFromStream() throws DataStoreException {
         final StorageConnector c = new StorageConnector(IOTestCase.getResourceAsStream(NCEP));
         final NetcdfStoreProvider provider = new NetcdfStoreProvider();
-        assertTrue(provider.canOpen(c));
+        assertEquals(ProbeResult.SUPPORTED, provider.canOpen(c));
         c.closeAllExcept(null);
     }
 
@@ -69,7 +70,7 @@ public final strictfp class NetcdfStoreP
         final NetcdfFile file = open(NCEP);
         final StorageConnector c = new StorageConnector(file);
         final NetcdfStoreProvider provider = new NetcdfStoreProvider();
-        assertTrue(provider.canOpen(c));
+        assertEquals(ProbeResult.SUPPORTED, provider.canOpen(c));
         file.close();
     }
 

Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/IOUtilities.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/IOUtilities.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/IOUtilities.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/IOUtilities.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -28,12 +28,14 @@ import java.net.URISyntaxException;
 import java.net.MalformedURLException;
 import java.nio.channels.Channels;
 import java.nio.channels.ReadableByteChannel;
+import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.Exceptions;
 import org.apache.sis.util.Static;
 import org.apache.sis.util.resources.Errors;
 
 // Related to JDK7
+import org.apache.sis.internal.jdk7.Files;
 import org.apache.sis.internal.jdk7.StandardCharsets;
 
 
@@ -49,7 +51,7 @@ import org.apache.sis.internal.jdk7.Stan
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
  * @since   0.3 (derived from geotk-3.00)
- * @version 0.3
+ * @version 0.4
  * @module
  */
 public final class IOUtilities extends Static {
@@ -297,10 +299,6 @@ public final class IOUtilities extends S
      * A URL can represent a file, but {@link URL#openStream()} appears to return a {@code BufferedInputStream}
      * wrapping the {@link FileInputStream}, which is not a desirable feature when we want to obtain a channel.
      *
-     * <p>There is no {@code toPathOrURL} methods because {@link Path} can be associated to various file systems.
-     * It would be possible (not necessarily desirable, but at least doable) do create {@code Path} for HTTP or
-     * FTP protocols.</p>
-     *
      * @param  path The path to convert, or {@code null}.
      * @param  encoding If the URL is encoded in a {@code application/x-www-form-urlencoded}
      *         MIME format, the character encoding (normally {@code "UTF-8"}). If the URL is
@@ -326,8 +324,11 @@ public final class IOUtilities extends S
             }
         }
         final URL url = new URL(path);
-        if (url.getProtocol().equalsIgnoreCase("file")) {
-            return toFile(url, encoding);
+        final String scheme = url.getProtocol();
+        if (scheme != null) {
+            if (scheme.equalsIgnoreCase("file")) {
+                return toFile(url, encoding);
+            }
         }
         return url;
     }
@@ -344,15 +345,20 @@ public final class IOUtilities extends S
      *       or {@link CharSequence}, then a new channel is opened.</li>
      * </ul>
      *
+     * The given options are used for opening the channel on a <em>best effort basis</em>.
+     * In particular, even if the caller provided the {@code WRITE} option, he still needs
+     * to verify if the returned channel implements {@link java.nio.channels.WritableByteChannel}.
+     *
      * @param  input The file to open, or {@code null}.
      * @param  encoding If the URL is encoded in a {@code application/x-www-form-urlencoded}
      *         MIME format, the character encoding (normally {@code "UTF-8"}). If the URL is
      *         not encoded, then {@code null}. This argument is ignored if the given path does
      *         not need to be converted from URL to {@code File}.
+     * @param  options The options to use for creating a new byte channel, or an empty set for read-only.
      * @return The input stream for the given file, or {@code null} if the given type is unknown.
      * @throws IOException If an error occurred while opening the given file.
      */
-    public static ReadableByteChannel open(Object input, final String encoding) throws IOException {
+    public static ReadableByteChannel open(Object input, final String encoding, Object... options) throws IOException {
         if (input instanceof ReadableByteChannel) {
             return (ReadableByteChannel) input;
         }
@@ -367,14 +373,38 @@ public final class IOUtilities extends S
             }
             return Channels.newChannel((InputStream) input);
         }
+        // NOTE: Many comments below this point actually apply to the JDK7 branch.
+        //       We keep them here for making easier the synchonization between the branches.
+        /*
+         * In the following cases, we will try hard to convert to Path objects before to fallback
+         * on File, URL or URI, because only Path instances allow us to use the given OpenOptions.
+         */
         if (input instanceof CharSequence) { // Needs to be before the check for File or URL.
             input = toFileOrURL(input.toString(), encoding);
         }
+        /*
+         * If the input is a File or a CharSequence that we have been able to convert to a File,
+         * try to convert to a Path in order to be able to use the OpenOptions. Only if we fail
+         * to convert to a Path (which is unlikely), we will use directly the File.
+         */
         if (input instanceof File) {
-            return new FileInputStream((File) input).getChannel();
+            return Files.newByteChannel((File) input, options);
         }
+        /*
+         * If the user gave us a URI, try again to convert to a Path for the same reasons than the above File case.
+         * A failure here is much more likely than in the File case, because JDK7 does not provide file systems for
+         * HTTP or FTP protocols by default.
+         */
         if (input instanceof URI) { // Needs to be before the check for URL.
-            input = ((URI) input).toURL();
+            final URI uri = (URI) input;
+            try {
+                return Files.newByteChannel(new File(uri), options);
+            } catch (IllegalArgumentException e) {
+                input = uri.toURL();
+                // We have been able to create a channel, maybe not with the given OpenOptions.
+                // Log the exception at a fine level and without stack trace, because it was probably normal.
+                Logging.recoverableException(Logging.getLogger("org.apache.sis.storage"), IOUtilities.class, "open", e);
+            }
         }
         if (input instanceof URL) {
             return Channels.newChannel(((URL) input).openStream());

Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStore.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -29,7 +29,12 @@ import org.apache.sis.internal.jdk7.Auto
 
 
 /**
- * A storage object which manage a series of features, coverages or sensor data.
+ * Manages a series of features, coverages or sensor data.
+ *
+ * {@section Thread safety policy}
+ * This {@code DataStore} base class is thread-safe. However subclasses are usually not.
+ * Unless otherwise specified by subclasses, users should assume that {@code DataStore}
+ * instances are not thread-safe.
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)

Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreProvider.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -16,16 +16,43 @@
  */
 package org.apache.sis.storage;
 
+import java.util.Set;
+import org.apache.sis.util.ThreadSafe;
+
 
 /**
- * Creates {@link DataStore} instances for a specific format from a given {@link StorageConnector} input.
- * There is typically a different {@code DataStoreProvider} instance for each format provided by a library.
+ * Provides information about a specific {@link DataStore} implementation.
+ * There is typically one {@code DataStoreProvider} instance for each format supported by a library.
+ * Each {@code DataStoreProvider} instances provides the following services:
+ *
+ * <ul>
+ *   <li>Provide generic information about the storage (name, <i>etc.</i>).</li>
+ *   <li>Create instances of the {@link DataStore} implementation described by this provider.</li>
+ *   <li>Test if a {@code DataStore} instance created by this provider would have reasonable chances
+ *       to open a given {@link StorageConnector}.</li>
+ * </ul>
+ *
+ * {@section Packaging data stores}
+ * JAR files that provide implementations of this class shall contain an entry with exactly the following path:
+ *
+ * {@preformat text
+ *     META-INF/services/org.apache.sis.storage.DataStoreProvider
+ * }
+ *
+ * The above entry shall contain one line for each {@code DataStoreProvider} implementation provided in the JAR file,
+ * where each line is the fully qualified name of the implementation class.
+ * See {@link java.util.ServiceLoader} for more general discussion about this lookup mechanism.
+ *
+ * {@section Thread safety policy}
+ * All {@code DataStoreProvider} implementations shall be thread-safe.
+ * However the {@code DataStore} instances created by the providers do not need to be thread-safe.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.4
  * @module
  */
+@ThreadSafe
 public abstract class DataStoreProvider {
     /**
      * Creates a new provider.
@@ -34,64 +61,73 @@ public abstract class DataStoreProvider 
     }
 
     /**
-     * Returns {@code TRUE} if the given storage appears to be supported by the {@code DataStore}.
-     * Returning {@code TRUE} from this method does not guarantee that reading or writing will succeed,
-     * only that there appears to be a reasonable chance of success based on a brief inspection of the
-     * {@linkplain StorageConnector#getStorage() storage object} or contents.
+     * Indicates if the given storage appears to be supported by the {@code DataStore}s created by this provider.
+     * The most typical return values are:
      *
-     * <p>Implementations will typically check the first bytes of the stream for a "magic number"
-     * associated with the format, as in the following example:</p>
+     * <ul>
+     *   <li>{@link ProbeResult#SUPPORTED} if the {@code DataStore}s created by this provider
+     *       can open the given storage.</li>
+     *   <li>{@link ProbeResult#UNKNOWN_STORAGE} if the given storage does not appear to be in a format
+     *       supported by this {@code DataStoreProvider}.</li>
+     * </ul>
      *
-     * {@preformat java
-     *     final ByteBuffer buffer = storage.getStorageAs(ByteBuffer.class);
-     *     if (buffer == null) {
-     *         // If StorageConnector can not provide a ByteBuffer, then the storage is probably
-     *         // not a File, URL, URI, InputStream neither a ReadableChannel. In this example,
-     *         // our provider can not handle such unknown source.
-     *         return Boolean.FALSE;
-     *     }
-     *     if (buffer.remaining() < Integer.SIZE / Byte.SIZE) {
-     *         // If the buffer does not contain enough bytes for the 'int' type, this is not necessarily
-     *         // because the file is truncated. It may be because the data were not yet available at the
-     *         // time this method has been invoked. Returning 'null' means "don't know".
-     *         return null;
-     *     }
-     *     // Use ByteBuffer.getInt(int) instead than ByteBuffer.getInt() in order to keep buffer position
-     *     // unchanged after this method call.
-     *     return buffer.getInt(buffer.position()) == MAGIC_NUMBER;
-     * }
+     * Note that the {@code SUPPORTED_FORMAT} value does not guarantee that reading or writing will succeed,
+     * only that there appears to be a reasonable chance of success based on a brief inspection of the
+     * {@linkplain StorageConnector#getStorage() storage object} or contents.
      *
      * Implementors are responsible for restoring the input to its original stream position on return of this method.
      * Implementors can use a mark/reset pair for this purpose. Marks are available as
      * {@link java.nio.ByteBuffer#mark()}, {@link java.io.InputStream#mark(int)} and
      * {@link javax.imageio.stream.ImageInputStream#mark()}.
      *
-     * <table width="80%" align="center" cellpadding="18" border="4" bgcolor="#FFE0B0">
-     *   <tr><td>
-     *     <b>Warning:</b> this method is likely to change. SIS 0.4 will probably return a set of enumeration
-     *     values describing how the file can be open (read, write, append) similar to JDK7 open mode.
-     *   </td></tr>
-     * </table>
+     * {@section Implementation example}
+     * Implementations will typically check the first bytes of the stream for a "magic number" associated
+     * with the format, as in the following example:
+     *
+     * {@preformat java
+     *     public ProbeResult canOpen(StorageConnector storage) throws DataStoreException {
+     *         final ByteBuffer buffer = storage.getStorageAs(ByteBuffer.class);
+     *         if (buffer == null) {
+     *             // If StorageConnector can not provide a ByteBuffer, then the storage is
+     *             // probably not a File, URL, URI, InputStream neither a ReadableChannel.
+     *             return ProbeResult.UNKNOWN_STORAGE;
+     *         }
+     *         if (buffer.remaining() < Integer.SIZE / Byte.SIZE) {
+     *             // If the buffer does not contain enough bytes for the integer type, this is not
+     *             // necessarily because the file is truncated. It may be because the data were not
+     *             // yet available at the time this method has been invoked.
+     *             return ProbeResult.UNDETERMINED;
+     *         }
+     *         if (buffer.getInt(buffer.position()) != MAGIC_NUMBER) {
+     *             // We used ByteBuffer.getInt(int) instead than ByteBuffer.getInt() above
+     *             // in order to keep the buffer position unchanged after this method call.
+     *             return ProbeResult.UNKNOWN_FORMAT;
+     *         }
+     *         return ProbeResult.SUPPORTED;
+     *     }
+     * }
      *
      * @param  storage Information about the storage (URL, stream, JDBC connection, <i>etc</i>).
-     * @return {@link Boolean#TRUE} if the given storage seems to be usable by the {@code DataStore} instances
-     *         create by this provider, {@link Boolean#FALSE} if the {@code DataStore} will not be able to use
-     *         the given storage, or {@code null} if this method does not have enough information.
+     * @return {@link ProbeResult#SUPPORTED} if the given storage seems to be readable by the {@code DataStore}
+     *         instances created by this provider.
      * @throws DataStoreException if an I/O or SQL error occurred. The error shall be unrelated to the logical
      *         structure of the storage.
      */
-    public abstract Boolean canOpen(StorageConnector storage) throws DataStoreException;
+    public abstract ProbeResult canOpen(StorageConnector storage) throws DataStoreException;
 
     /**
      * Returns a data store implementation associated with this provider.
      *
-     * <p><b>Implementation note:</b>
+     * {@section Implementation note}
      * Implementors shall invoke {@link StorageConnector#closeAllExcept(Object)} after {@code DataStore}
-     * creation, keeping open only the needed resource.</p>
+     * creation, keeping open only the needed resource.
      *
      * @param  storage Information about the storage (URL, stream, JDBC connection, <i>etc</i>).
      * @return A data store implementation associated with this provider for the given storage.
-     * @throws DataStoreException if an error occurred while creating the data store instance.
+     * @throws IllegalArgumentException If the set contains an invalid combination of options.
+     * @throws DataStoreException If an error occurred while creating the data store instance.
+     *
+     * @see DataStores#open(Object, Set)
      */
     public abstract DataStore open(StorageConnector storage) throws DataStoreException;
 }

Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -48,7 +48,7 @@ import org.apache.sis.internal.jdk7.JDK7
  * {@code StorageConnector} wraps an input {@link Object}, which can be any of the following types:
  *
  * <ul>
- *   <li>A {@link java.nio.file.Path} or a {@link java.io.File} or file or a directory in a file system.</li>
+ *   <li>A {@link java.nio.file.Path} or a {@link java.io.File} for a file or a directory.</li>
  *   <li>A {@link java.net.URI} or a {@link java.net.URL} to a distant resource.</li>
  *   <li>A {@link CharSequence} interpreted as a filename or a URL.</li>
  *   <li>A {@link java.nio.channels.Channel} or a {@link DataInput}.</li>
@@ -167,6 +167,7 @@ public class StorageConnector implements
      *
      * <ul>
      *   <li>{@link OptionKey#URL_ENCODING} for converting URL to URI or filename, if needed.</li>
+     *   <li>{@link OptionKey#OPEN_OPTIONS} for specifying whether the data store shall be read only or read/write.</li>
      *   <li>{@link OptionKey#BYTE_BUFFER} for allowing users to control the byte buffer to be created.</li>
      * </ul>
      *
@@ -298,8 +299,8 @@ public class StorageConnector implements
      * </ul>
      *
      * Multiple invocations of this method on the same {@code StorageConnector} instance will try
-     * to return the same instance on a <cite>best effort</cite> basis. Consequently, implementations
-     * of {@link DataStoreProvider#canOpen(StorageConnector)} methods shall not close the stream or
+     * to return the same instance on a <cite>best effort</cite> basis. Consequently, implementations of
+     * {@link DataStoreProvider#canOpen(StorageConnector)} methods shall not close the stream or
      * database connection returned by this method. In addition, those {@code canOpen(StorageConnector)}
      * methods are responsible for restoring the stream or byte buffer to its original position on return.
      *
@@ -371,7 +372,8 @@ public class StorageConnector implements
      * @throws IOException If an error occurred while opening a channel for the input.
      */
     private void createChannelDataInput(final boolean asImageInputStream) throws IOException {
-        final ReadableByteChannel channel = IOUtilities.open(storage, getOption(OptionKey.URL_ENCODING));
+        final ReadableByteChannel channel = IOUtilities.open(storage,
+                getOption(OptionKey.URL_ENCODING), getOption(OptionKey.OPEN_OPTIONS));
         ChannelDataInput asDataInput = null;
         if (channel != null) {
             ByteBuffer buffer = getOption(OptionKey.BYTE_BUFFER);

Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/package-info.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/package-info.java?rev=1509317&r1=1509316&r2=1509317&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/package-info.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/package-info.java [UTF-8] Thu Aug  1 16:28:17 2013
@@ -19,24 +19,15 @@
  * {@linkplain org.apache.sis.storage.DataStore Data store} base types for retrieving and saving geospatial data
  * in various storage formats.
  *
- * <p>Different {@code DataStore} implementations will want different kind of input/output objects. Some examples are
- * {@link java.lang.String}, {@link java.nio.file.Path}, {@link java.io.File}, {@link java.net.URI}, {@link java.net.URL},
- * {@link java.io.InputStream}, {@link javax.imageio.stream.ImageInputStream}, {@link java.nio.channels.ReadableChannel},
- * JDBC {@link java.sql.Connection} or {@link javax.sql.DataSource}, or even
- * datastore-specific objects like {@link ucar.nc2.NetcdfFile}.
- * Because of this variety, SIS does not know which kind of object to accept before the appropriate {@code DataStore}
- * instance has been found. For this reason, storages are represented by arbitrary {@link java.lang.Object} encapsulated
- * in {@link org.apache.sis.storage.StorageConnector}. The later can open the object in various ways, for example
- * as {@link java.io.DataInput} or as {@link java.nio.ByteBuffer}, depending on {@code DataStore needs}.
- * Future versions may contain additional information like login/password.</p>
- *
- * <p>{@code StorageConnector} is used only for the "discovery" phase, and discarded once the actual
- * {@code DataStore} instance has been created.</p>
+ * <p>{@code DataStore} provides the methods for reading or writing geospatial data in a given storage.
+ * A storage may be a file, a directory, a connection to a database or any other implementation specific mechanism.
+ * Suitable {@code DataStore} implementation for a given storage can be discovered and opened by the static methods
+ * provided in {@link org.apache.sis.storage.DataStores}.</p>
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.10)
- * @version 0.3
+ * @version 0.4
  * @module
  */
 package org.apache.sis.storage;



Mime
View raw message