This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new aa41c4d0ec GPX store should implement `WritableFeatureSet` only if the 
stream allows write operations.
aa41c4d0ec is described below

commit aa41c4d0eca216d23940ca7bf5f5f13c72f3d78e
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Sun Dec 4 16:23:35 2022 +0100

    GPX store should implement `WritableFeatureSet` only if the stream allows 
write operations.
---
 .../apache/sis/console/FormattedOutputCommand.java |   2 +-
 .../org/apache/sis/internal/storage/gpx/Store.java | 146 ++---------------
 .../sis/internal/storage/gpx/StoreProvider.java    |  10 +-
 .../apache/sis/internal/storage/gpx/Updater.java   |   4 +-
 .../sis/internal/storage/gpx/WritableStore.java    | 182 +++++++++++++++++++++
 .../apache/sis/internal/storage/gpx/Writer.java    |   4 +-
 .../sis/internal/storage/gpx/UpdaterTest.java      |  13 +-
 .../sis/internal/storage/gpx/WriterTest.java       |  14 +-
 8 files changed, 220 insertions(+), 155 deletions(-)

diff --git 
a/application/sis-console/src/main/java/org/apache/sis/console/FormattedOutputCommand.java
 
b/application/sis-console/src/main/java/org/apache/sis/console/FormattedOutputCommand.java
index 5a2c95a52c..9070cfdf30 100644
--- 
a/application/sis-console/src/main/java/org/apache/sis/console/FormattedOutputCommand.java
+++ 
b/application/sis-console/src/main/java/org/apache/sis/console/FormattedOutputCommand.java
@@ -269,7 +269,7 @@ abstract class FormattedOutputCommand extends CommandRunner 
{
                      * Note: after such generalization is done, revert the 
xml-store dependency
                      *       scope in pom.xml from "compile" to "runtime".
                      */
-                    final org.apache.sis.internal.storage.gpx.Store fs = 
(org.apache.sis.internal.storage.gpx.Store) store;
+                    final org.apache.sis.internal.storage.gpx.WritableStore fs 
= (org.apache.sis.internal.storage.gpx.WritableStore) store;
                     if (version != null) {
                         fs.setVersion(version);
                     }
diff --git 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Store.java
 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Store.java
index 5d14b374ef..5d20ef12b2 100644
--- 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Store.java
+++ 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Store.java
@@ -17,30 +17,22 @@
 package org.apache.sis.internal.storage.gpx;
 
 import java.util.Optional;
-import java.util.Iterator;
-import java.util.function.Predicate;
-import java.util.function.UnaryOperator;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
-import java.io.IOException;
-import java.io.UncheckedIOException;
 import java.net.URISyntaxException;
 import org.opengis.util.NameFactory;
 import org.opengis.util.FactoryException;
 import org.opengis.geometry.Envelope;
 import org.opengis.metadata.Metadata;
 import org.opengis.metadata.distribution.Format;
-import org.apache.sis.storage.WritableFeatureSet;
+import org.apache.sis.storage.FeatureSet;
 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.storage.IllegalFeatureTypeException;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.storage.StoreUtilities;
 import org.apache.sis.internal.storage.xml.stream.StaxDataStore;
-import org.apache.sis.util.collection.BackingStoreException;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Version;
 import org.apache.sis.setup.OptionKey;
@@ -66,7 +58,7 @@ import org.opengis.feature.FeatureType;
  * @since   0.8
  * @module
  */
-public final class Store extends StaxDataStore implements WritableFeatureSet {
+public class Store extends StaxDataStore implements FeatureSet {
     /**
      * Version of the GPX file, or {@code null} if unknown.
      */
@@ -216,21 +208,6 @@ public final class Store extends StaxDataStore implements 
WritableFeatureSet {
         return types.names.get(this, name);
     }
 
-    /**
-     * Verifies the type of feature instances in this feature set.
-     * This method does nothing if the specified type is equal to {@link 
#getType()},
-     * or throws {@link IllegalFeatureTypeException} otherwise.
-     *
-     * @param  newType  new feature type definition (not {@code null}).
-     * @throws DataStoreException if the given type is not compatible with the 
types supported by the store.
-     */
-    @Override
-    public void updateType(final FeatureType newType) throws 
DataStoreException {
-        if (!newType.equals(getType())) {
-            throw new IllegalFeatureTypeException(getLocale(), 
StoreProvider.NAME, newType.getName());
-        }
-    }
-
     /**
      * Returns the stream of features.
      * This store does not cache the features. Any new iteration over features 
will re-read from the file.
@@ -260,113 +237,14 @@ public final class Store extends StaxDataStore 
implements WritableFeatureSet {
     }
 
     /**
-     * Appends new feature instances in this {@code FeatureSet}.
-     * Any feature already present in this {@link FeatureSet} will remain 
unmodified.
-     *
-     * @param  features  feature instances to append in this {@code 
FeatureSet}.
-     * @throws DataStoreException if the feature stream cannot be obtained or 
updated.
+     * Closes only the reader, without closing this store.
+     * This method may be invoked before write operation.
      */
-    @Override
-    public synchronized void add(final Iterator<? extends Feature> features) 
throws DataStoreException {
-        try (Updater updater = updater()) {
-            updater.add(features);
-            updater.flush();
-        }
-    }
-
-    /**
-     * Removes all feature instances from this {@code FeatureSet} which 
matches the given predicate.
-     *
-     * @param  filter  a predicate which returns {@code true} for feature 
instances to be removed.
-     * @return {@code true} if any elements were removed.
-     * @throws DataStoreException if the feature stream cannot be obtained or 
updated.
-     */
-    @Override
-    public synchronized boolean removeIf(final Predicate<? super Feature> 
filter) throws DataStoreException {
-        try (Updater updater = updater()) {
-            return updater.removeIf(filter);
-        }
-    }
-
-    /**
-     * Updates all feature instances from this {@code FeatureSet} which match 
the given predicate.
-     * If the given operator returns {@code null}, then the filtered feature 
is removed.
-     *
-     * @param  filter       a predicate which returns {@code true} for feature 
instances to be updated.
-     * @param  replacement  operation called for each matching {@link Feature} 
instance. May return {@code null}.
-     * @throws DataStoreException if the feature stream cannot be obtained or 
updated.
-     */
-    @Override
-    public synchronized void replaceIf(final Predicate<? super Feature> 
filter, final UnaryOperator<Feature> replacement)
-            throws DataStoreException
-    {
-        try (Updater updater = updater()) {
-            updater.replaceIf(filter, replacement);
-            updater.flush();
-        }
-    }
-
-    /**
-     * Returns the helper object to use for updating the GPX file.
-     *
-     * @todo In current version, we flush the updater after each write 
operation.
-     *       In a future version, we should keep it in a private field and 
flush
-     *       only after some delay, on close, or before a read operation.
-     */
-    private Updater updater() throws DataStoreException {
-        try {
-            return new Updater(this, getSpecifiedPath());
-        } catch (IOException e) {
-            throw new DataStoreException(e);
-        }
-    }
-
-    /**
-     * Replaces the content of this GPX file by the given metadata and 
features.
-     *
-     * @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.
-     *
-     * @deprecated To be replaced by {@link #add(Iterator)}, after we resolved 
how to specify metadata.
-     *
-     * @see <a href="https://issues.apache.org/jira/browse/SIS-411";>SIS-411</a>
-     */
-    @Deprecated
-    public synchronized void write(final Metadata metadata, final Stream<? 
extends Feature> features) throws DataStoreException {
-        try {
-            /*
-             * If we created a reader for reading metadata, we need to close 
that reader now otherwise the call
-             * to `new Writer(…)` will fail.  Note that if that reader was in 
use by someone else, the `reader`
-             * field would be null and the `new Writer(…)` call should detect 
that a reader is in use somewhere.
-             */
-            final Reader r = reader;
-            if (r != null) {
-                reader = null;
-                r.close();
-            }
-            /*
-             * Get the writer if no read or other write operation is in 
progress, then write the data.
-             */
-            try (Writer writer = new Writer(this, 
org.apache.sis.internal.storage.gpx.Metadata.castOrCopy(metadata, locale), 
null)) {
-                writer.writeStartDocument();
-                if (features != null) {
-                    features.forEachOrdered(writer);
-                }
-                writer.writeEndDocument();
-            }
-        } catch (BackingStoreException e) {
-            final Throwable cause = e.getCause();
-            if (cause instanceof DataStoreException) {
-                throw (DataStoreException) cause;
-            }
-            throw new DataStoreException(e.getLocalizedMessage(), cause);
-        } catch (Exception e) {
-            if (e instanceof UncheckedIOException) {
-                e = ((UncheckedIOException) e).getCause();
-            }
-            throw new DataStoreException(e);
+    final void closeReader() throws Exception {
+        final Reader r = reader;
+        if (r != null) {
+            reader = null;
+            r.close();
         }
     }
 
@@ -378,10 +256,8 @@ public final class Store extends StaxDataStore implements 
WritableFeatureSet {
     @Override
     public synchronized void close() throws DataStoreException {
         listeners.close();                  // Should never fail.
-        final Reader r = reader;
-        reader = null;
-        if (r != null) try {
-            r.close();
+        try {
+            closeReader();
         } catch (Exception e) {
             final DataStoreException ds = new DataStoreException(e);
             try {
diff --git 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java
 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java
index 74e0a1faa3..6595a46bcb 100644
--- 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java
+++ 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java
@@ -35,7 +35,7 @@ import org.apache.sis.util.Version;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.3
  * @since   0.8
  * @module
  */
@@ -92,8 +92,12 @@ public final class StoreProvider extends 
StaxDataStoreProvider {
      * @throws DataStoreException if an error occurred while creating the data 
store instance.
      */
     @Override
-    public DataStore open(StorageConnector connector) throws 
DataStoreException {
-        return new Store(this, connector);
+    public DataStore open(final StorageConnector connector) throws 
DataStoreException {
+        if (isWritable(connector)) {
+            return new WritableStore(this, connector);
+        } else {
+            return new Store(this, connector);
+        }
     }
 
     /**
diff --git 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Updater.java
 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Updater.java
index 8a739175ff..d67c57bcaf 100644
--- 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Updater.java
+++ 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Updater.java
@@ -48,7 +48,7 @@ final class Updater extends RewriteOnUpdate {
      * @param  location  the main file, or {@code null} if unknown.
      * @throws IOException if an error occurred while determining whether the 
file is empty.
      */
-    Updater(final Store source, final Path location) throws IOException {
+    Updater(final WritableStore source, final Path location) throws 
IOException {
         super(source, location);
     }
 
@@ -84,6 +84,6 @@ final class Updater extends RewriteOnUpdate {
      */
     @Override
     protected StaxStreamWriter createWriter(OutputStream temporary) throws 
Exception {
-        return new Writer((Store) source, metadata, temporary);
+        return new Writer((WritableStore) source, metadata, temporary);
     }
 }
diff --git 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/WritableStore.java
 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/WritableStore.java
new file mode 100644
index 0000000000..a4ced88d7e
--- /dev/null
+++ 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/WritableStore.java
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.storage.gpx;
+
+import java.util.Iterator;
+import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import org.opengis.metadata.Metadata;
+import org.apache.sis.storage.WritableFeatureSet;
+import org.apache.sis.storage.StorageConnector;
+import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.ConcurrentReadException;
+import org.apache.sis.storage.IllegalFeatureTypeException;
+import org.apache.sis.util.collection.BackingStoreException;
+
+// Branch-dependent imports
+import org.opengis.feature.Feature;
+import org.opengis.feature.FeatureType;
+
+
+/**
+ * A GPX store capable to write GPX file.
+ *
+ * @author  Johann Sorel (Geomatys)
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 1.3
+ * @since   1.3
+ * @module
+ */
+public final class WritableStore extends Store implements WritableFeatureSet {
+    /**
+     * Creates a new GPX store from the given file, URL or stream object.
+     * This constructor invokes {@link 
StorageConnector#closeAllExcept(Object)},
+     * keeping open only the needed resource.
+     *
+     * @param  provider   the provider of this data store, or {@code null} if 
unspecified.
+     * @param  connector  information about the storage (URL, stream, 
<i>etc</i>).
+     * @throws DataStoreException if an error occurred while opening the GPX 
file.
+     */
+    public WritableStore(final StoreProvider provider, final StorageConnector 
connector) throws DataStoreException {
+        super(provider, connector);
+    }
+
+    /**
+     * Verifies the type of feature instances in this feature set.
+     * This method does nothing if the specified type is equal to {@link 
#getType()},
+     * or throws {@link IllegalFeatureTypeException} otherwise.
+     *
+     * @param  newType  new feature type definition (not {@code null}).
+     * @throws DataStoreException if the given type is not compatible with the 
types supported by the store.
+     */
+    @Override
+    public void updateType(final FeatureType newType) throws 
DataStoreException {
+        if (!newType.equals(getType())) {
+            throw new IllegalFeatureTypeException(getLocale(), 
StoreProvider.NAME, newType.getName());
+        }
+    }
+
+    /**
+     * Appends new feature instances in this {@code FeatureSet}.
+     * Any feature already present in this {@link FeatureSet} will remain 
unmodified.
+     *
+     * @param  features  feature instances to append in this {@code 
FeatureSet}.
+     * @throws DataStoreException if the feature stream cannot be obtained or 
updated.
+     */
+    @Override
+    public synchronized void add(final Iterator<? extends Feature> features) 
throws DataStoreException {
+        try (Updater updater = updater()) {
+            updater.add(features);
+            updater.flush();
+        }
+    }
+
+    /**
+     * Removes all feature instances from this {@code FeatureSet} which 
matches the given predicate.
+     *
+     * @param  filter  a predicate which returns {@code true} for feature 
instances to be removed.
+     * @return {@code true} if any elements were removed.
+     * @throws DataStoreException if the feature stream cannot be obtained or 
updated.
+     */
+    @Override
+    public synchronized boolean removeIf(final Predicate<? super Feature> 
filter) throws DataStoreException {
+        try (Updater updater = updater()) {
+            return updater.removeIf(filter);
+        }
+    }
+
+    /**
+     * Updates all feature instances from this {@code FeatureSet} which match 
the given predicate.
+     * If the given operator returns {@code null}, then the filtered feature 
is removed.
+     *
+     * @param  filter       a predicate which returns {@code true} for feature 
instances to be updated.
+     * @param  replacement  operation called for each matching {@link Feature} 
instance. May return {@code null}.
+     * @throws DataStoreException if the feature stream cannot be obtained or 
updated.
+     */
+    @Override
+    public synchronized void replaceIf(final Predicate<? super Feature> 
filter, final UnaryOperator<Feature> replacement)
+            throws DataStoreException
+    {
+        try (Updater updater = updater()) {
+            updater.replaceIf(filter, replacement);
+            updater.flush();
+        }
+    }
+
+    /**
+     * Returns the helper object to use for updating the GPX file.
+     *
+     * @todo In current version, we flush the updater after each write 
operation.
+     *       In a future version, we should keep it in a private field and 
flush
+     *       only after some delay, on close, or before a read operation.
+     */
+    private Updater updater() throws DataStoreException {
+        try {
+            return new Updater(this, getSpecifiedPath());
+        } catch (IOException e) {
+            throw new DataStoreException(e);
+        }
+    }
+
+    /**
+     * Replaces the content of this GPX file by the given metadata and 
features.
+     *
+     * @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.
+     *
+     * @deprecated To be replaced by {@link #add(Iterator)}, after we resolved 
how to specify metadata.
+     *
+     * @see <a href="https://issues.apache.org/jira/browse/SIS-411";>SIS-411</a>
+     */
+    @Deprecated
+    public synchronized void write(final Metadata metadata, final Stream<? 
extends Feature> features) throws DataStoreException {
+        try {
+            /*
+             * If we created a reader for reading metadata, we need to close 
that reader now otherwise the call
+             * to `new Writer(…)` will fail.  Note that if that reader was in 
use by someone else, the `reader`
+             * field would be null and the `new Writer(…)` call should detect 
that a reader is in use somewhere.
+             */
+            closeReader();
+            /*
+             * Get the writer if no read or other write operation is in 
progress, then write the data.
+             */
+            try (Writer writer = new Writer(this, 
org.apache.sis.internal.storage.gpx.Metadata.castOrCopy(metadata, locale), 
null)) {
+                writer.writeStartDocument();
+                if (features != null) {
+                    features.forEachOrdered(writer);
+                }
+                writer.writeEndDocument();
+            }
+        } catch (BackingStoreException e) {
+            final Throwable cause = e.getCause();
+            if (cause instanceof DataStoreException) {
+                throw (DataStoreException) cause;
+            }
+            throw new DataStoreException(e.getLocalizedMessage(), cause);
+        } catch (Exception e) {
+            if (e instanceof UncheckedIOException) {
+                e = ((UncheckedIOException) e).getCause();
+            }
+            throw new DataStoreException(e);
+        }
+    }
+}
diff --git 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Writer.java
 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Writer.java
index 97d33b705a..8c5ac95d73 100644
--- 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Writer.java
+++ 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Writer.java
@@ -65,7 +65,7 @@ final class Writer extends StaxStreamWriter {
      * @throws XMLStreamException if an error occurred while opening the XML 
file.
      * @throws IOException if an error occurred while preparing the output 
stream.
      */
-    Writer(final Store owner, final Metadata metadata, final OutputStream 
temporary)
+    Writer(final WritableStore owner, final Metadata metadata, final 
OutputStream temporary)
             throws DataStoreException, XMLStreamException, IOException
     {
         super(owner, temporary);
@@ -146,7 +146,7 @@ final class Writer extends StaxStreamWriter {
     @Override
     public void write(final Feature feature) throws DataStoreException, 
XMLStreamException, JAXBException {
         if (feature != null) {
-            final Types types = ((Store) owner).types;
+            final Types types = ((WritableStore) owner).types;
             final FeatureType type = feature.getType();
             if (types.wayPoint.isAssignableFrom(type)) {
                 writeWayPoint(feature, Tags.WAY_POINT);
diff --git 
a/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/UpdaterTest.java
 
b/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/UpdaterTest.java
index b951f5973e..8f2fc1b77e 100644
--- 
a/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/UpdaterTest.java
+++ 
b/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/UpdaterTest.java
@@ -107,12 +107,12 @@ public final strictfp class UpdaterTest extends TestCase {
     /**
      * Creates a new GPX data store which will read and write in a temporary 
file.
      */
-    private Store create() throws DataStoreException, IOException {
+    private WritableStore create() throws DataStoreException, IOException {
         final StorageConnector connector = new StorageConnector(file);
         connector.setOption(OptionKey.GEOMETRY_LIBRARY, GeometryLibrary.ESRI);
         connector.setOption(OptionKey.OPEN_OPTIONS, new StandardOpenOption[] {
                             StandardOpenOption.READ, 
StandardOpenOption.WRITE});
-        return new Store(provider, connector);
+        return new WritableStore(provider, connector);
     }
 
     /**
@@ -123,7 +123,7 @@ public final strictfp class UpdaterTest extends TestCase {
      */
     @Test
     public void testWriteEmpty() throws DataStoreException, IOException {
-        try (final Store store = create()) {
+        try (final WritableStore store = create()) {
             final Types types = store.types;
             final Feature point1 = types.wayPoint.newInstance();
             final Feature point2 = types.wayPoint.newInstance();
@@ -160,7 +160,7 @@ public final strictfp class UpdaterTest extends TestCase {
         }
         assertTrue(containsLat20());
         final boolean result;
-        try (final Store store = create()) {
+        try (final WritableStore store = create()) {
             result = store.removeIf((feature) -> {
                 Object point = feature.getPropertyValue("sis:geometry");
                 return ((Point) point).getY() == 20;
@@ -172,8 +172,11 @@ public final strictfp class UpdaterTest extends TestCase {
 
     /**
      * Returns whether the temporary file contains the {@code lat="20"} string.
+     * Also checks some invariants such as the presence of metadata.
      */
     private boolean containsLat20() throws IOException {
-        return 
org.apache.sis.internal.jdk9.JDK9.readString(file).contains("lat=\"20");     // 
May have trailing ".0".
+        final String xml = org.apache.sis.internal.jdk9.JDK9.readString(file);
+        assertTrue(xml.contains("<bounds "));       // Sentinel value for 
presence of metadata.
+        return xml.contains("lat=\"20");            // May have trailing ".0".
     }
 }
diff --git 
a/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/WriterTest.java
 
b/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/WriterTest.java
index ae66a25895..71d9260874 100644
--- 
a/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/WriterTest.java
+++ 
b/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/WriterTest.java
@@ -46,7 +46,7 @@ import org.opengis.feature.Feature;
 
 /**
  * Tests (indirectly) the {@link Writer} class.
- * This class creates a {@link Store} instance and uses it in write mode.
+ * This class creates a {@link WritableStore} instance and uses it in write 
mode.
  * The {@link Reader} is used for verifying the content.
  *
  * @author  Johann Sorel (Geomatys)
@@ -86,10 +86,10 @@ public final strictfp class WriterTest extends TestCase {
     /**
      * Creates a new GPX data store which will read and write in memory.
      */
-    private Store create() throws DataStoreException {
+    private WritableStore create() throws DataStoreException {
         final StorageConnector connector = new StorageConnector(output);
         connector.setOption(OptionKey.GEOMETRY_LIBRARY, GeometryLibrary.ESRI);
-        return new Store(provider, connector);
+        return new WritableStore(provider, connector);
     }
 
     /**
@@ -137,7 +137,7 @@ public final strictfp class WriterTest extends TestCase {
      */
     private void testMetadata(final Version version, final String expected) 
throws Exception {
         final Metadata metadata = MetadataTest.create();
-        try (Store store = create()) {
+        try (WritableStore store = create()) {
             store.setVersion(version);
             store.write(metadata, null);
         }
@@ -233,7 +233,7 @@ public final strictfp class WriterTest extends TestCase {
      * @param expected  name of a test file containing the expected XML result.
      */
     private void testFeatures(final Version version, final Type type, final 
String expected) throws Exception {
-        try (Store store = create()) {
+        try (WritableStore store = create()) {
             store.version = version;
             testFeatures(store, type);
         }
@@ -247,7 +247,7 @@ public final strictfp class WriterTest extends TestCase {
      * @param store  the store where to write.
      * @param type   the kind of feature to write: way point, route or track.
      */
-    private void testFeatures(final Store store, final Type type) throws 
Exception {
+    private void testFeatures(final WritableStore store, final Type type) 
throws Exception {
         final Types types = store.types;
         /*
          * Way Points as defined in "waypoint.xml" test file.
@@ -370,7 +370,7 @@ public final strictfp class WriterTest extends TestCase {
         final StorageConnector connector = new StorageConnector(
                 TestUtilities.createTemporaryFile(ReaderTest.class, 
"1.1/metadata.xml"));
         connector.setOption(OptionKey.GEOMETRY_LIBRARY, GeometryLibrary.ESRI);
-        try (Store store = new Store(provider, connector)) {
+        try (WritableStore store = new WritableStore(provider, connector)) {
             /*
              * Read part of the file. We verify its content as a matter of 
principle,
              * but the main purpose of following code is to advance in the 
stream.

Reply via email to