sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1778167 - in /sis/branches/JDK8: core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/ core/sis-metadata/src/main/resources/org/apache/sis/metadata/sql/ core/sis-utility/src/test/java/org/apache/sis/test/mock/ storage/sis-storage/sr...
Date Tue, 10 Jan 2017 17:43:20 GMT
Author: desruisseaux
Date: Tue Jan 10 17:43:20 2017
New Revision: 1778167

URL: http://svn.apache.org/viewvc?rev=1778167&view=rev
Log:
Complete (for now) GPX format support by leverage the MIME type detection mechanism that was done for JAXB-based data store, registering the GPX provider and adding an entry for GPX in the metadata.
In this commit was also simplified a little bit the loops on XMLStreamReader.next() or getEventType() by defining a 'next()' convenience method taking in account the post-unmarshal case.

Added:
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java
      - copied, changed from r1777936, sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/
    sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/
    sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/
    sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/org.apache.sis.storage.DataStoreProvider   (with props)
Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
    sis/branches/JDK8/core/sis-metadata/src/main/resources/org/apache/sis/metadata/sql/Create.sql
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/mock/MetadataMock.java
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/package-info.java
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/MimeTypeDetector.java
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/Store.java
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/package-info.java
    sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/xml/MimeTypeDetectorTest.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Metadata.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Reader.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Store.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/StoreProvider.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxDataStoreProvider.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStreamReader.java
    sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/gpx/ReaderTest.java

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/MetadataSource.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -740,7 +740,7 @@ public class MetadataSource implements A
      *
      * @param  <T>         the parameterized type of the {@code type} argument.
      * @param  type        the interface to implement (e.g. {@link org.opengis.metadata.citation.Citation}),
-     *                     or the {@link CodeList} value.
+     *                     or the {@link CodeList} type.
      * @param  identifier  the identifier of the record for the metadata entity to be created.
      *                     This is usually the primary key of the record to search for.
      * @return an implementation of the required interface, or the code list element.

Modified: sis/branches/JDK8/core/sis-metadata/src/main/resources/org/apache/sis/metadata/sql/Create.sql
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/resources/org/apache/sis/metadata/sql/Create.sql?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/resources/org/apache/sis/metadata/sql/Create.sql [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/resources/org/apache/sis/metadata/sql/Create.sql [UTF-8] Tue Jan 10 17:43:20 2017
@@ -118,11 +118,13 @@ INSERT INTO metadata."CI_Citation" (ID,
   ('NetCDF',  'NetCDF',  'NetCDF Classic and 64-bit Offset Format'),
   ('PNG',     'PNG',     'PNG (Portable Network Graphics) Specification'),
   ('CSV',     'CSV',     'Common Format and MIME Type for Comma-Separated Values (CSV) Files'),
-  ('CSV-MF',  'CSV',     'OGC Moving Features Encoding Extension: Simple Comma-Separated Values (CSV)');
+  ('CSV-MF',  'CSV',     'OGC Moving Features Encoding Extension: Simple Comma-Separated Values (CSV)'),
+  ('GPX',     'GPX',     'GPS Exchange Format');
 
 INSERT INTO metadata."MD_Format" (ID, "formatSpecificationCitation") VALUES
   ('GeoTIFF', 'GeoTIFF'),
   ('NetCDF',  'NetCDF'),
   ('PNG',     'PNG'),
   ('CSV',     'CSV'),
-  ('CSV-MF',  'CSV-MF');
+  ('CSV-MF',  'CSV-MF'),
+  ('GPX',     'GPX');

Modified: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/mock/MetadataMock.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/mock/MetadataMock.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/mock/MetadataMock.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/mock/MetadataMock.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -56,7 +56,7 @@ public final strictfp class MetadataMock
      * Creates an initially empty metadata with the given language.
      * Callers are free to assign new value to the {@link #language} field directly.
      *
-     * @param language The initial {@link #language} value (can be {@code null}).
+     * @param  language  the initial {@link #language} value (can be {@code null}).
      */
     public MetadataMock(final Locale language) {
         this.language = language;

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/StoreProvider.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -37,7 +37,7 @@ import org.apache.sis.internal.storage.w
  * @version 0.8
  * @module
  */
-public class StoreProvider extends DataStoreProvider {
+public final class StoreProvider extends DataStoreProvider {
     /**
      * The object to use for verifying if the first keyword is the expected one.
      */

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/StoreProvider.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -36,7 +36,7 @@ import org.apache.sis.util.Version;
  * @version 0.8
  * @module
  */
-public class StoreProvider extends DataStoreProvider {
+public final class StoreProvider extends DataStoreProvider {
     /**
      * The {@value} MIME type.
      */

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/package-info.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/package-info.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -20,7 +20,7 @@
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7
- * @version 0.7
+ * @version 0.8
  * @module
  */
 package org.apache.sis.internal.storage.wkt;

Copied: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java (from r1777936, sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java?p2=sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java&p1=sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java&r1=1777936&r2=1778167&rev=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -16,6 +16,8 @@
  */
 package org.apache.sis.internal.storage.xml;
 
+import java.util.Map;
+import java.util.HashMap;
 import java.io.Reader;
 import java.io.IOException;
 import java.nio.ByteBuffer;
@@ -27,16 +29,18 @@ import org.apache.sis.storage.ProbeResul
 
 
 /**
- * The provider of {@link Store} instances.
+ * Base class for providers of {@link DataStore} implementations for XML files.
+ * This base class does not assume that the data store will use any particular framework
+ * (JAXB, StAX, <i>etc</i>).
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @since   0.4
- * @version 0.7
+ * @since   0.8
+ * @version 0.8
  * @module
  */
-public class StoreProvider extends DataStoreProvider {
+public abstract class AbstractProvider extends DataStoreProvider {
     /**
-     * The {@value} MIME type, used only of {@link #probeContent(StorageConnector)} can not determine
+     * The {@value} MIME type, used only if {@link #probeContent(StorageConnector)} can not determine
      * a more accurate type.
      */
     public static final String MIME_TYPE = "application/xml";
@@ -53,13 +57,30 @@ public class StoreProvider extends DataS
     private static final byte[] HEADER = {'<','?','x','m','l',' '};
 
     /**
-     * Creates a new provider.
+     * The mapping from XML namespace to MIME type. This map shall be populated by subclasses
+     * at construction time, then never modified anymore since we do not synchronize it.
+     *
+     * <div class="note"><b>Example</b>
+     * public MyDataStore() {
+     *     types.put("http://www.opengis.net/gml/3.2",        "application/gml+xml");
+     *     types.put("http://www.isotc211.org/2005/gmd",      "application/vnd.iso.19139+xml");
+     *     types.put("http://www.opengis.net/cat/csw/2.0.2",  "application/vnd.ogc.csw_xml");
+     * }</div>
+     */
+    protected final Map<String,String> types;
+
+    /**
+     * Creates a new provider. Subclasses shall populate the {@link #types} map with a mapping
+     * from their namespace to the MIME type to declare.
+     *
+     * @param  initialCapacity  initial capacity of the hash map to create.
      */
-    public StoreProvider() {
+    protected AbstractProvider(final int initialCapacity) {
+        types = new HashMap<>(initialCapacity);
     }
 
     /**
-     * Returns {@link ProbeResult#SUPPORTED} if the given storage appears to be supported by {@link Store}.
+     * Returns {@link ProbeResult#SUPPORTED} if the given storage appears to be supported by the data store.
      * 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 storage
      * header.
@@ -70,7 +91,7 @@ public class StoreProvider extends DataS
     @Override
     public ProbeResult probeContent(final StorageConnector connector) throws DataStoreException {
         /*
-         * Usual case. This include InputStream, DataInput, File, Path, URL, URI.
+         * Usual case. This includes InputStream, DataInput, File, Path, URL, URI.
          */
         final ByteBuffer buffer = connector.getStorageAs(ByteBuffer.class);
         if (buffer != null) {
@@ -85,7 +106,7 @@ public class StoreProvider extends DataS
             }
             // Now check for a more accurate MIME type.
             buffer.position(HEADER.length);
-            final ProbeResult result = new MimeTypeDetector() {
+            final ProbeResult result = new MimeTypeDetector(types) {
                 @Override int read() {
                     if (buffer.hasRemaining()) {
                         return buffer.get();
@@ -112,7 +133,7 @@ public class StoreProvider extends DataS
                 }
             }
             // Now check for a more accurate MIME type.
-            final ProbeResult result = new MimeTypeDetector() {
+            final ProbeResult result = new MimeTypeDetector(types) {
                 private int remaining = READ_AHEAD_LIMIT;
                 @Override int read() throws IOException {
                     return (--remaining >= 0) ? reader.read() : -1;
@@ -125,16 +146,4 @@ public class StoreProvider extends DataS
         }
         return ProbeResult.UNSUPPORTED_STORAGE;
     }
-
-    /**
-     * Returns a {@link Store} implementation associated with this provider.
-     *
-     * @param  connector  information about the storage (URL, stream, <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.
-     */
-    @Override
-    public DataStore open(final StorageConnector connector) throws DataStoreException {
-        return new Store(this, connector);
-    }
 }

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/MimeTypeDetector.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/MimeTypeDetector.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/MimeTypeDetector.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/MimeTypeDetector.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -17,12 +17,10 @@
 package org.apache.sis.internal.storage.xml;
 
 import java.util.Map;
-import java.util.HashMap;
 import java.util.Arrays;
 import java.io.IOException;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.ProbeResult;
-import org.apache.sis.xml.Namespaces;
 
 
 /**
@@ -38,7 +36,7 @@ import org.apache.sis.xml.Namespaces;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.8
  * @module
  */
 abstract class MimeTypeDetector {
@@ -46,13 +44,7 @@ abstract class MimeTypeDetector {
      * The mapping from XML namespace to MIME type.
      * This map shall be read-only, since we do not synchronize it.
      */
-    private static final Map<String,String> TYPES = new HashMap<>();
-    static {
-        TYPES.put(Namespaces.GML, "application/gml+xml");
-        TYPES.put(Namespaces.GMD, "application/vnd.iso.19139+xml");
-        TYPES.put(Namespaces.CSW, "application/vnd.ogc.csw_xml");
-        // More types to be added in future versions.
-    }
+    private final Map<String,String> types;
 
     /**
      * The {@code "xmlns"} string as a sequence of bytes.
@@ -86,8 +78,11 @@ abstract class MimeTypeDetector {
 
     /**
      * Creates a new instance.
+     *
+     * @param  types  the mapping from XML namespaces to MIME type.
      */
-    MimeTypeDetector() {
+    MimeTypeDetector(final Map<String,String> types) {
+        this.types = types;
     }
 
     /**
@@ -114,7 +109,7 @@ abstract class MimeTypeDetector {
      * Skips all bytes or characters up to {@code search}, then returns the character after it.
      * Characters inside quotes will be ignored.
      *
-     * @param  search the byte or character to skip.
+     * @param  search  the byte or character to skip.
      * @return the byte or character after {@code search}, or -1 on EOF.
      * @throws IOException if an error occurred while reading the bytes or characters.
      */
@@ -255,7 +250,7 @@ abstract class MimeTypeDetector {
         /*
          * Done reading the "xmlns" attribute value.
          */
-        return TYPES.get(new String(buffer, 0, length, "US-ASCII"));
+        return types.get(new String(buffer, 0, length, "US-ASCII"));
     }
 
     /**

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/Store.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/Store.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/Store.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/Store.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -63,7 +63,7 @@ final class Store extends DataStore {
 
     /**
      * The unmarshalled object, initialized only when first needed.
-     * May still {@code null} if the unmarshalling failed.
+     * May still be {@code null} if the unmarshalling failed.
      */
     private Object object;
 

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -16,14 +16,10 @@
  */
 package org.apache.sis.internal.storage.xml;
 
-import java.io.Reader;
-import java.io.IOException;
-import java.nio.ByteBuffer;
+import org.apache.sis.xml.Namespaces;
 import org.apache.sis.storage.DataStore;
-import org.apache.sis.storage.DataStoreProvider;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.StorageConnector;
-import org.apache.sis.storage.ProbeResult;
 
 
 /**
@@ -31,99 +27,19 @@ import org.apache.sis.storage.ProbeResul
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.7
+ * @version 0.8
  * @module
  */
-public class StoreProvider extends DataStoreProvider {
-    /**
-     * The {@value} MIME type, used only of {@link #probeContent(StorageConnector)} can not determine
-     * a more accurate type.
-     */
-    public static final String MIME_TYPE = "application/xml";
-
-    /**
-     * The read-ahead limit when reading the XML document from a {@link Reader}.
-     */
-    private static final int READ_AHEAD_LIMIT = 2048;
-
-    /**
-     * The expected XML header. According XML specification, this declaration is required to appear
-     * at the document beginning (no space allowed before the declaration).
-     */
-    private static final byte[] HEADER = {'<','?','x','m','l',' '};
-
+public final class StoreProvider extends AbstractProvider {
     /**
      * Creates a new provider.
      */
     public StoreProvider() {
-    }
-
-    /**
-     * Returns {@link ProbeResult#SUPPORTED} if the given storage appears to be supported by {@link Store}.
-     * 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 storage
-     * header.
-     *
-     * @return {@link ProbeResult#SUPPORTED} if the given storage seems to be readable as a XML file.
-     * @throws DataStoreException if an I/O or SQL error occurred.
-     */
-    @Override
-    public ProbeResult probeContent(final StorageConnector connector) throws DataStoreException {
-        /*
-         * Usual case. This include InputStream, DataInput, File, Path, URL, URI.
-         */
-        final ByteBuffer buffer = connector.getStorageAs(ByteBuffer.class);
-        if (buffer != null) {
-            if (buffer.remaining() < HEADER.length) {
-                return ProbeResult.INSUFFICIENT_BYTES;
-            }
-            // Quick check for "<?xml " header.
-            for (int i=0; i<HEADER.length; i++) {
-                if (buffer.get(i) != HEADER[i]) {
-                    return ProbeResult.UNSUPPORTED_STORAGE;
-                }
-            }
-            // Now check for a more accurate MIME type.
-            buffer.position(HEADER.length);
-            final ProbeResult result = new MimeTypeDetector() {
-                @Override int read() {
-                    if (buffer.hasRemaining()) {
-                        return buffer.get();
-                    }
-                    insufficientBytes = (buffer.limit() != buffer.capacity());
-                    return -1;
-                }
-            }.probeContent();
-            buffer.position(0);
-            return result;
-        }
-        /*
-         * We should enter in this block only if the user gave us explicitely a Reader.
-         * A common case is a StringReader wrapping a String object.
-         */
-        final Reader reader = connector.getStorageAs(Reader.class);
-        if (reader != null) try {
-            // Quick check for "<?xml " header.
-            reader.mark(HEADER.length + READ_AHEAD_LIMIT);
-            for (int i=0; i<HEADER.length; i++) {
-                if (reader.read() != HEADER[i]) {
-                    reader.reset();
-                    return ProbeResult.UNSUPPORTED_STORAGE;
-                }
-            }
-            // Now check for a more accurate MIME type.
-            final ProbeResult result = new MimeTypeDetector() {
-                private int remaining = READ_AHEAD_LIMIT;
-                @Override int read() throws IOException {
-                    return (--remaining >= 0) ? reader.read() : -1;
-                }
-            }.probeContent();
-            reader.reset();
-            return result;
-        } catch (IOException e) {
-            throw new DataStoreException(e);
-        }
-        return ProbeResult.UNSUPPORTED_STORAGE;
+        super(8);
+        types.put(Namespaces.GML, "application/gml+xml");
+        types.put(Namespaces.GMD, "application/vnd.iso.19139+xml");
+        types.put(Namespaces.CSW, "application/vnd.ogc.csw_xml");
+        // More types to be added in future versions.
     }
 
     /**

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/package-info.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/package-info.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -16,13 +16,13 @@
  */
 
 /**
- * {@link org.apache.sis.storage.DataStore} implementation for XML files.
- * The kind of objects recognized by this package is listed in the
+ * {@link org.apache.sis.storage.DataStore} implementation for XML files that can be unmarshalled by the
+ * {@link org.apache.sis.xml.XML} class. The kind of objects recognized by this package is listed in the
  * {@link org.apache.sis.internal.storage.xml.Store} class.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.7
+ * @version 0.8
  * @module
  */
 package org.apache.sis.internal.storage.xml;

Modified: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/xml/MimeTypeDetectorTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/xml/MimeTypeDetectorTest.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/xml/MimeTypeDetectorTest.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/xml/MimeTypeDetectorTest.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -24,6 +24,8 @@ import org.apache.sis.test.DependsOnMeth
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
+import static java.util.Collections.singletonMap;
+import static org.apache.sis.xml.Namespaces.GMD;
 import static org.junit.Assert.*;
 
 
@@ -40,14 +42,14 @@ public final strictfp class MimeTypeDete
      * Tests a XML file in the {@value org.apache.sis.xml.Namespaces#GMD} namespace
      * read from a hard-coded string.
      *
-     * @throws IOException should never happen.
+     * @throws IOException if an error occurred while reading the bytes or characters.
      */
     @Test
     public void testGMDFromString() throws IOException {
         final StringReader in = new StringReader(StoreTest.XML);
         assertEquals('<', in.read());
         assertEquals('?', in.read());
-        final MimeTypeDetector detector = new MimeTypeDetector() {
+        final MimeTypeDetector detector = new MimeTypeDetector(singletonMap(GMD, "application/vnd.iso.19139+xml")) {
             @Override int read() throws IOException {
                 return in.read();
             }
@@ -68,7 +70,7 @@ public final strictfp class MimeTypeDete
         final InputStream in = DefaultExtentTest.getResource("Extent.xml").openStream();
         assertEquals('<', in.read());
         assertEquals('?', in.read());
-        final MimeTypeDetector detector = new MimeTypeDetector() {
+        final MimeTypeDetector detector = new MimeTypeDetector(singletonMap(GMD, "application/vnd.iso.19139+xml")) {
             @Override int read() throws IOException {
                 return in.read();
             }

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Metadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Metadata.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Metadata.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Metadata.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -38,16 +38,17 @@ import org.opengis.metadata.extent.Exten
 import org.opengis.metadata.identification.Keywords;
 import org.opengis.metadata.identification.Identification;
 import org.opengis.metadata.content.ContentInformation;
+import org.opengis.metadata.distribution.Format;
 import org.opengis.util.InternationalString;
-import org.apache.sis.util.iso.Types;
 
 import org.apache.sis.io.TableAppender;
 import org.apache.sis.internal.simple.SimpleMetadata;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
-import org.apache.sis.util.iso.SimpleInternationalString;
 import org.apache.sis.metadata.iso.citation.DefaultCitationDate;
 import org.apache.sis.metadata.iso.identification.DefaultKeywords;
 import org.apache.sis.metadata.iso.extent.Extents;
+import org.apache.sis.util.iso.SimpleInternationalString;
+import org.apache.sis.util.iso.Types;
 
 
 /**
@@ -81,6 +82,15 @@ import org.apache.sis.metadata.iso.exten
  */
 public final class Metadata extends SimpleMetadata {
     /**
+     * The data store that created this metadata, or {@code null} if none. This information is used for fetching
+     * information that are constants for all GPX files, for example the feature types and the format description.
+     *
+     * <p>This field needs to be set after construction. It can not be set at construction time because JAXB needs
+     * to invoke a no-argument constructor.</p>
+     */
+    Store store;
+
+    /**
      * The creator of the GPX file. The creator is a property of the GPX node;
      * it is not part of the content marshalled in a GPX {@code <metadata>} element.
      */
@@ -157,15 +167,6 @@ public final class Metadata extends Simp
     public Bounds bounds;
 
     /**
-     * Names of features types available for the GPX format, or null if none.
-     * This field is not part of metadata described in GPX file; it is rather a hard-coded value shared by all
-     * GPX files. Users could however filter the list of features, for example with only routes and no tracks.
-     *
-     * @see #getContentInfo()
-     */
-    public Collection<ContentInformation> features;
-
-    /**
      * Creates an initially empty metadata object.
      */
     public Metadata() {
@@ -364,13 +365,32 @@ public final class Metadata extends Simp
     }
 
     /**
-     * Information about the feature and coverage characteristics.
+     * Names of features types available for the GPX format, or an empty list if none.
+     * This property is not part of metadata described in GPX file; it is rather a hard-coded value shared by all
+     * GPX files. Users could however filter the list of features, for example with only routes and no tracks.
      *
      * @return information about the feature characteristics.
      */
     @Override
     public Collection<ContentInformation> getContentInfo() {
-        return (features != null) ? features : Collections.emptyList();
+        return (store != null) ? store.types.metadata : super.getContentInfo();
+    }
+
+    /**
+     * Description of the format of the resource(s).
+     * This is part of the information returned by {@link #getIdentificationInfo()}.
+     *
+     * @return description of the format of the resource(s).
+     */
+    @Override
+    public synchronized Collection<Format> getResourceFormats() {
+        if (store != null) {
+            final Format f = store.getFormat();
+            if (f != null) {
+                return Collections.singletonList(f);
+            }
+        }
+        return super.getResourceFormats();
     }
 
     /**

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Reader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Reader.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Reader.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Reader.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -186,7 +186,7 @@ final class Reader extends StaxStreamRea
          *     more elaborated than what it was in the previous version. We will use JAXB for parsing them.
          */
 parse:  while (reader.hasNext()) {
-            switch (reader.next()) {
+            switch (next()) {
                 case START_ELEMENT: {
                     /*
                      * GPX 1.0 and 1.1 metadata should not be mixed. However the following code will work even
@@ -232,19 +232,20 @@ parse:  while (reader.hasNext()) {
                 }
                 case END_ELEMENT: {
                     /*
-                     * Reminder: END_ELEMENT events are skipped by getElementText(), getElementAsFoo()
-                     * and unmarshal(…) methods. There is only the enclosing <gpx> tag to check here.
-                     * If that end tag is found, we skip the metadata().features = … line since there
-                     * is no feature in that file.
+                     * Reminder: calling next() after getElementText(), getElementAsFoo() and unmarshal(…) methods
+                     * moves the reader after the END_ELEMENT event. Consequently there is only the enclosing <gpx>
+                     * tag to check here.
                      */
                     if (isEndGPX()) {
-                        return version;
+                        break parse;
                     }
                     break;
                 }
             }
         }
-        metadata().features = ((Store) owner).types.metadata;
+        if (readMetadata) {
+            metadata().store = (Store) owner;
+        }
         return version;
     }
 
@@ -411,13 +412,12 @@ parse:  while (reader.hasNext()) {
         feature.setPropertyValue("@identifier", index);
         feature.setPropertyValue("@geometry", new Point(parseDouble(lon), parseDouble(lat)));
         List<Link> links = null;
-        int event = reader.next();
         while (true) {
             /*
              * We do not need to check 'reader.hasNext()' in above loop
              * since this check is done by the END_DOCUMENT case below.
              */
-            switch (event) {
+            switch (next()) {
                 case START_ELEMENT: {
                     final Object value;
                     final String name = reader.getLocalName();
@@ -439,19 +439,16 @@ parse:  while (reader.hasNext()) {
                         case Tags.SATELITTES:       // Fallthrough to getElementAsInteger()
                         case Tags.DGPS_ID:          value = getElementAsInteger(); break;
                         case Tags.FIX:              value = Fix.fromGPX(getElementText()); break;
-                        case Tags.LINK:             links = Metadata.addIfNonNull(links, unmarshal(Link.class)); event = reader.getEventType(); continue;
-                        case Tags.URL:              links = Metadata.addIfNonNull(links, Link.valueOf(getElementAsURI())); event = reader.next(); continue;
+                        case Tags.LINK:             links = Metadata.addIfNonNull(links, unmarshal(Link.class)); continue;
+                        case Tags.URL:              links = Metadata.addIfNonNull(links, Link.valueOf(getElementAsURI())); continue;
                         default: {
                             if (name.equals(tagName)) {
                                 throw new DataStoreContentException(nestedElement(name));
                             }
-                            value = null;
-                            break;
+                            continue;
                         }
                     }
-                    if (value != null) {
-                        feature.setPropertyValue(name, value);
-                    }
+                    feature.setPropertyValue(name, value);
                     break;
                 }
                 case END_ELEMENT: {
@@ -465,7 +462,6 @@ parse:  while (reader.hasNext()) {
                     throw new EOFException(endOfFile());
                 }
             }
-            event = reader.next();
         }
     }
 
@@ -481,37 +477,33 @@ parse:  while (reader.hasNext()) {
         feature.setPropertyValue("@identifier", index);
         List<Feature> wayPoints = null;
         List<Link> links = null;
-        int event = reader.next();
         while (true) {
             /*
              * We do not need to check 'reader.hasNext()' in above loop
              * since this check is done by the END_DOCUMENT case below.
              */
-            switch (event) {
+            switch (next()) {
                 case START_ELEMENT: {
                     final Object value;
                     final String name = reader.getLocalName();
                     switch (isGPX() ? name : "") {
-                        default:               value = null; break;
+                        default: continue;
                         case Tags.NAME:        // Fallthrough to getElementText()
                         case Tags.COMMENT:     // ︙
                         case Tags.DESCRIPTION: // ︙
                         case Tags.SOURCE:      // ︙
                         case Tags.TYPE:        value = getElementText(); break;
                         case Tags.NUMBER:      value = getElementAsInteger(); break;
-                        case Tags.LINK:        links = Metadata.addIfNonNull(links, unmarshal(Link.class)); event = reader.getEventType(); continue;
-                        case Tags.URL:         links = Metadata.addIfNonNull(links, Link.valueOf(getElementAsURI())); event = reader.next(); continue;
+                        case Tags.LINK:        links = Metadata.addIfNonNull(links, unmarshal(Link.class)); continue;
+                        case Tags.URL:         links = Metadata.addIfNonNull(links, Link.valueOf(getElementAsURI())); continue;
                         case Tags.ROUTES:      throw new DataStoreContentException(nestedElement(name));
                         case Tags.ROUTE_POINTS: {
                             if (wayPoints == null) wayPoints = new ArrayList<>(8);
                             wayPoints.add(parseWayPoint(wayPoints.size() + 1));
-                            event = reader.next();
                             continue;
                         }
                     }
-                    if (value != null) {
-                        feature.setPropertyValue(name, value);
-                    }
+                    feature.setPropertyValue(name, value);
                     break;
                 }
                 case END_ELEMENT: {
@@ -526,7 +518,6 @@ parse:  while (reader.hasNext()) {
                     throw new EOFException(endOfFile());
                 }
             }
-            event = reader.next();
         }
     }
 
@@ -585,37 +576,33 @@ parse:  while (reader.hasNext()) {
         feature.setPropertyValue("@identifier", index);
         List<Feature> segments = null;
         List<Link> links = null;
-        int event = reader.next();
         while (true) {
             /*
              * We do not need to check 'reader.hasNext()' in above loop
              * since this check is done by the END_DOCUMENT case below.
              */
-            switch (event) {
+            switch (next()) {
                 case START_ELEMENT: {
                     final Object value;
                     final String name = reader.getLocalName();
                     switch (isGPX() ? name : "") {
-                        default:                value = null; break;
+                        default: continue;
                         case Tags.NAME:         // Fallthrough to getElementText()
                         case Tags.COMMENT:      // ︙
                         case Tags.DESCRIPTION:  // ︙
                         case Tags.SOURCE:       // ︙
                         case Tags.TYPE:         value = getElementText(); break;
                         case Tags.NUMBER:       value = getElementAsInteger(); break;
-                        case Tags.LINK:         links = Metadata.addIfNonNull(links, unmarshal(Link.class)); event = reader.getEventType(); continue;
-                        case Tags.URL:          links = Metadata.addIfNonNull(links, Link.valueOf(getElementAsURI())); event = reader.next(); continue;
+                        case Tags.LINK:         links = Metadata.addIfNonNull(links, unmarshal(Link.class)); continue;
+                        case Tags.URL:          links = Metadata.addIfNonNull(links, Link.valueOf(getElementAsURI())); continue;
                         case Tags.TRACKS:       throw new DataStoreContentException(nestedElement(name));
                         case Tags.TRACK_SEGMENTS: {
                             if (segments == null) segments = new ArrayList<>(8);
                             segments.add(parseTrackSegment(segments.size() + 1));
-                            event = reader.next();
                             continue;
                         }
                     }
-                    if (value != null) {
-                        feature.setPropertyValue(name, value);
-                    }
+                    feature.setPropertyValue(name, value);
                     break;
                 }
                 case END_ELEMENT: {
@@ -630,7 +617,6 @@ parse:  while (reader.hasNext()) {
                     throw new EOFException(endOfFile());
                 }
             }
-            event = reader.next();
         }
     }
 }

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Store.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Store.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Store.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Store.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -17,15 +17,19 @@
 package org.apache.sis.internal.gpx;
 
 import java.net.URISyntaxException;
+import org.opengis.metadata.Metadata;
+import org.opengis.metadata.distribution.Format;
 import org.apache.sis.internal.xml.StaxDataStore;
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreContentException;
+import org.apache.sis.storage.ConcurrentReadException;
 import org.apache.sis.storage.IllegalNameException;
 import org.apache.sis.util.collection.BackingStoreException;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Version;
-import org.opengis.metadata.Metadata;
+import org.apache.sis.metadata.sql.MetadataSource;
+import org.apache.sis.metadata.sql.MetadataStoreException;
 
 // Branch-dependent imports
 import java.util.stream.Stream;
@@ -61,12 +65,6 @@ public final class Store extends StaxDat
     Version version;
 
     /**
-     * {@code true} if the {@linkplain #metadata} field has been initialized.
-     * Note that metadata after initialization may still be {@code null}.
-     */
-    private boolean initialized;
-
-    /**
      * The metadata, or {@code null} if not yet parsed.
      */
     private Metadata metadata;
@@ -109,6 +107,18 @@ public final class Store extends StaxDat
     }
 
     /**
+     * Returns a more complete description of the GPX format, or {@code null} if not available.
+     */
+    final Format getFormat() {
+        try {
+            return MetadataSource.getProvided().lookup(Format.class, "GPX");
+        } catch (MetadataStoreException e) {
+            listeners.warning(null, e);
+        }
+        return null;
+    }
+
+    /**
      * Returns the GPX file version.
      *
      * @return the GPX file version, or {@code null} if none.
@@ -140,8 +150,7 @@ public final class Store extends StaxDat
      */
     @Override
     public synchronized Metadata getMetadata() throws DataStoreException {
-        if (!initialized) try {
-            initialized = true;
+        if (metadata == null) try {
             reader      = new Reader(this);
             version     = reader.initialize(true);
             metadata    = reader.getMetadata();
@@ -197,9 +206,8 @@ public final class Store extends StaxDat
      *
      * @param  metadata  the metadata to write, or {@code null} if none.
      * @param  features  the features to write, or {@code null} if none.
+     * @throws ConcurrentReadException if the {@code features} stream was provided by this data store.
      * @throws DataStoreException if an error occurred while writing the data.
-     *
-     * @todo verify that the given stream is not connected to this GPX file.
      */
     public synchronized void write(final Metadata metadata, final Stream<? extends Feature> features)
             throws DataStoreException

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/StoreProvider.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/StoreProvider.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/StoreProvider.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/StoreProvider.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -20,7 +20,6 @@ import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
-import org.apache.sis.storage.ProbeResult;
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.internal.xml.StaxDataStoreProvider;
 
@@ -40,14 +39,9 @@ public final class StoreProvider extends
      * Creates a new GPX store provider.
      */
     public StoreProvider() {
-    }
-
-    /**
-     * TODO
-     */
-    @Override
-    public ProbeResult probeContent(StorageConnector connector) throws DataStoreException {
-        throw new UnsupportedOperationException("Not supported yet.");
+        super(4);
+        types.put(Tags.NAMESPACE_V10, "application/gpx+xml");
+        types.put(Tags.NAMESPACE_V11, "application/gpx+xml");
     }
 
     /**

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxDataStoreProvider.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxDataStoreProvider.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxDataStoreProvider.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxDataStoreProvider.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -18,7 +18,7 @@ package org.apache.sis.internal.xml;
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
-import org.apache.sis.storage.DataStoreProvider;
+import org.apache.sis.internal.storage.xml.AbstractProvider;
 import org.apache.sis.xml.MarshallerPool;
 
 
@@ -31,7 +31,7 @@ import org.apache.sis.xml.MarshallerPool
  * @version 0.8
  * @module
  */
-public abstract class StaxDataStoreProvider extends DataStoreProvider {
+public abstract class StaxDataStoreProvider extends AbstractProvider {
     /**
      * Pool of JAXB marshallers shared by all data stores created by this provider.
      * This pool is created only when first needed; it will never be instantiated
@@ -40,9 +40,13 @@ public abstract class StaxDataStoreProvi
     private volatile MarshallerPool jaxb;
 
     /**
-     * Creates a new provider.
+     * Creates a new provider. Subclasses shall populate the {@link #types} map with a mapping
+     * from their namespace to the MIME type to declare.
+     *
+     * @param  initialCapacity  initial capacity of the hash map to create.
      */
-    protected StaxDataStoreProvider() {
+    protected StaxDataStoreProvider(final int initialCapacity) {
+        super(initialCapacity);
     }
 
     /**

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStreamReader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStreamReader.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStreamReader.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStreamReader.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -113,6 +113,13 @@ public abstract class StaxStreamReader e
     protected final XMLStreamReader reader;
 
     /**
+     * {@code true} if the {@link #reader} already moved to the next element. This happen if {@link #unmarshal(Class)}
+     * has been invoked. In such case, the next call to {@link XMLStreamReader#next()} needs to be replaced by a call
+     * to {@link XMLStreamReader#getEventType()}.
+     */
+    private boolean isNextDone;
+
+    /**
      * The unmarshaller reserved to this reader usage,
      * created only when first needed and kept until this reader is closed.
      *
@@ -257,13 +264,17 @@ public abstract class StaxStreamReader e
     /**
      * Skips all remaining elements until we reach the end of the given tag.
      * Nested tags of the same name, if any, are also skipped.
-     * After this method invocation, the current event is {@link #END_ELEMENT}.
+     *
+     * <p>The current event when this method is invoked must be {@link #START_ELEMENT}.
+     * After this method invocation, the current event will be {@link #END_ELEMENT}.</p>
      *
      * @param  tagName name of the tag to close.
      * @throws EOFException if end tag could not be found.
      * @throws XMLStreamException if an error occurred while reading the XML stream.
      */
     protected final void skipUntilEnd(final QName tagName) throws EOFException, XMLStreamException {
+        assert reader.getEventType() == START_ELEMENT;
+        isNextDone = false;
         int nested = 0;
         while (reader.hasNext()) {
             switch (reader.next()) {
@@ -285,9 +296,27 @@ public abstract class StaxStreamReader e
     }
 
     /**
+     * Gets next parsing event. This method should be used instead of {@link XMLStreamReader#next()}
+     * when the {@code while (next())} loop may contain call to the {@link #unmarshal(Class)} method.
+     *
+     * @return one of the {@link XMLStreamConstants}.
+     * @throws XMLStreamException if an error occurred while fetching the next event.
+     */
+    protected final int next() throws XMLStreamException {
+        if (!isNextDone) {
+            return reader.next();       // This is the usual case.
+        }
+        isNextDone = false;
+        return reader.getEventType();
+    }
+
+    /**
      * Returns the current value of {@link XMLStreamReader#getElementText()},
      * or {@code null} if that value is null or empty.
      *
+     * <p>The current event when this method is invoked must be {@link #START_ELEMENT}.
+     * After this method invocation, the current event will be {@link #END_ELEMENT}.</p>
+     *
      * @return the current text element, or {@code null} if empty.
      * @throws XMLStreamException if a text element can not be returned.
      */
@@ -471,6 +500,7 @@ parse:  switch (value.length()) {
         unmarshaller = null;
         final JAXBElement<T> element = m.unmarshal(reader, type);
         unmarshaller = m;                                           // Allow reuse or recycling only on success.
+        isNextDone = true;
         return element.getValue();
     }
 

Added: sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/org.apache.sis.storage.DataStoreProvider
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/org.apache.sis.storage.DataStoreProvider?rev=1778167&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/org.apache.sis.storage.DataStoreProvider (added)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/org.apache.sis.storage.DataStoreProvider [UTF-8] Tue Jan 10 17:43:20 2017
@@ -0,0 +1 @@
+org.apache.sis.internal.gpx.StoreProvider

Propchange: sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/org.apache.sis.storage.DataStoreProvider
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/org.apache.sis.storage.DataStoreProvider
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/gpx/ReaderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/gpx/ReaderTest.java?rev=1778167&r1=1778166&r2=1778167&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/gpx/ReaderTest.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/gpx/ReaderTest.java [UTF-8] Tue Jan 10 17:43:20 2017
@@ -184,11 +184,6 @@ public final strictfp class ReaderTest e
                      assertStringEquals("first",                     md.links.get(0).text);
             case 0:  break;
         }
-        /*
-         * In the particular case of "metadata.xml" test files, there is no route, track or way points
-         * after the metadata. Consequently the GPX reader should not declare any list of features.
-         */
-        assertTrue("contentInfo", md.getContentInfo().isEmpty());
     }
 
     /**



Mime
View raw message