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

commit b14531968a3ea50a3c9f70312a13a98ae240dcc5
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Fri Feb 2 16:33:17 2024 +0100

    `URISource.create(…)` should also separate the path from the fragment,
    which may result in a `URISyntaxException` to be thrown.
---
 .../main/org/apache/sis/xml/XML.java               |  3 ++-
 .../apache/sis/xml/util/ExternalLinkHandler.java   |  2 +-
 .../main/org/apache/sis/xml/util/URISource.java    | 24 ++++++-------------
 .../org/apache/sis/storage/base/PRJDataStore.java  |  2 +-
 .../org/apache/sis/storage/base/URIDataStore.java  |  8 +++++--
 .../org/apache/sis/storage/esri/RasterStore.java   | 11 +++++----
 .../apache/sis/storage/esri/RawRasterStore.java    |  8 ++++---
 .../apache/sis/storage/image/WorldFileStore.java   | 27 +++++++++++++++-------
 .../apache/sis/storage/image/WritableResource.java |  3 ++-
 .../apache/sis/storage/image/WritableStore.java    |  9 +++++---
 .../main/org/apache/sis/storage/xml/Store.java     |  6 ++++-
 .../org/apache/sis/storage/xml/StoreProvider.java  |  7 +++++-
 .../test/org/apache/sis/storage/xml/StoreTest.java | 11 +++++----
 13 files changed, 73 insertions(+), 48 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/XML.java 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/XML.java
index eb707e2da7..0e210a696f 100644
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/XML.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/XML.java
@@ -21,6 +21,7 @@ import java.util.Locale;
 import java.util.TimeZone;
 import java.util.logging.Filter;
 import java.util.logging.LogRecord;             // For javadoc
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.io.File;
 import java.io.IOException;
@@ -619,7 +620,7 @@ public final class XML extends Static {
         final Object object;
         try (InputStream in = new 
BufferedInputStream(Files.newInputStream(input, StandardOpenOption.READ))) {
             object = unmarshal(URISource.create(in, input.toUri()), null);
-        } catch (IOException e) {
+        } catch (URISyntaxException | IOException e) {
             throw new JAXBException(Errors.format(Errors.Keys.CanNotRead_1, 
input), e);
         }
         return object;
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/util/ExternalLinkHandler.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/util/ExternalLinkHandler.java
index 5940fcc9e2..dd4c91e0dd 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/util/ExternalLinkHandler.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/util/ExternalLinkHandler.java
@@ -274,7 +274,7 @@ public class ExternalLinkHandler {
         }
         final XMLResolver resolver = (XMLResolver) property;
         return new ExternalLinkHandler(base) {
-            @Override public Source openReader(final URI path) throws 
XMLStreamException {
+            @Override public Source openReader(final URI path) throws 
Exception {
                 /*
                  * According StAX specification, the return type can be either 
InputStream,
                  * XMLStreamReader or XMLEventReader. We additionally accept 
Source as well.
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/util/URISource.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/util/URISource.java
index e8b59821fc..a9cec509b1 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/util/URISource.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/util/URISource.java
@@ -48,8 +48,8 @@ public final class URISource extends StreamSource {
      * Creates a source from an URI. This constructor separates the fragment 
from the path.
      * The URI stored by this constructor in {@link #document} excludes the 
fragment part.
      *
-     * @param source  URI to the XML document.
-     * @throws URISyntaxException if the URI is not valid.
+     * @param  source  URI to the XML document.
+     * @throws URISyntaxException if an error occurred while normalizing the 
URI.
      */
     URISource(URI source) throws URISyntaxException {
         source = source.normalize();
@@ -59,19 +59,6 @@ public final class URISource extends StreamSource {
         fragment = Strings.trimOrNull(source.getFragment());
     }
 
-    /**
-     * Creates a new source from an input stream.
-     *
-     * @param input   stream of the XML document.
-     * @param source  URL of the XML document.
-     */
-    private URISource(final InputStream input, final URI source) {
-        super(input);
-        // SystemId will be computed only if requested.
-        document = source.normalize();
-        fragment = null;
-    }
-
     /**
      * Creates a new source from the given input stream.
      * The input should not be null, unless it will be specified later
@@ -80,10 +67,13 @@ public final class URISource extends StreamSource {
      * @param  input   stream of the XML document, or {@code null} if none.
      * @param  source  URL of the XML document, or {@code null} if none.
      * @return the given input stream as a source.
+     * @throws URISyntaxException if an error occurred while normalizing the 
URI.
      */
-    public static StreamSource create(final InputStream input, final URI 
source) {
+    public static StreamSource create(final InputStream input, final URI 
source) throws URISyntaxException {
         if (source != null) {
-            return new URISource(input, source);
+            var s = new URISource(source);
+            s.setInputStream(input);
+            return s;
         } else {
             return new StreamSource(input);
         }
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/PRJDataStore.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/PRJDataStore.java
index eff3b39cd7..60712fad88 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/PRJDataStore.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/PRJDataStore.java
@@ -175,7 +175,7 @@ public abstract class PRJDataStore extends URIDataStore {
         } catch (NoSuchFileException | FileNotFoundException e) {
             cannotReadAuxiliaryFile(caller, method, extension, e, true);
             return Optional.empty();
-        } catch (IOException | ParseException | ClassCastException e) {
+        } catch (URISyntaxException | IOException | ParseException | 
ClassCastException e) {
             cause = e;
         }
         final var e = new 
DataStoreReferencingException(cannotReadAuxiliaryFile(extension), cause);
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStore.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStore.java
index 25d3f42255..64ab956876 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStore.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStore.java
@@ -374,10 +374,13 @@ public abstract class URIDataStore extends DataStore 
implements StoreResource, R
      * @param  input   the input stream of the XML document. Will be closed by 
this method.
      * @param  source  the source of the XML document to read.
      * @return the unmarshalled object.
+     * @throws URISyntaxException if an error occurred while normalizing the 
URI.
      * @throws JAXBException if an error occurred while parsing the XML 
document.
      * @throws IOException if an error occurred while closing the input stream.
      */
-    protected final Object readXML(final InputStream input, final URI source) 
throws IOException, JAXBException {
+    protected final Object readXML(final InputStream input, final URI source)
+            throws URISyntaxException, IOException, JAXBException
+    {
         try (input) {
             return readXML(URISource.create(input, source));
         }
@@ -423,11 +426,12 @@ public abstract class URIDataStore extends DataStore 
implements StoreResource, R
      * @return the file content together with the source, or {@code null} if 
none. Should be short-lived.
      * @throws NoSuchFileException if the auxiliary file has not been found 
(when opened from path).
      * @throws FileNotFoundException if the auxiliary file has not been found 
(when opened from URL).
+     * @throws URISyntaxException if an error occurred while normalizing the 
URI.
      * @throws IOException if another error occurred while opening the stream.
      * @throws DataStoreException if the auxiliary file content seems too 
large.
      */
     protected final AuxiliaryContent readAuxiliaryFile(final String extension, 
final boolean acceptXML)
-            throws IOException, DataStoreException
+            throws URISyntaxException, IOException, DataStoreException
     {
         /*
          * Try to open the stream using the storage type (Path or URL) closest 
to the type
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RasterStore.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RasterStore.java
index 431e86d9f8..96d4771b46 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RasterStore.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RasterStore.java
@@ -24,6 +24,7 @@ import java.io.IOException;
 import java.io.FileNotFoundException;
 import java.nio.file.NoSuchFileException;
 import java.nio.file.Path;
+import java.net.URISyntaxException;
 import java.awt.image.ColorModel;
 import java.awt.image.DataBuffer;
 import java.awt.image.SampleModel;
@@ -194,11 +195,12 @@ abstract class RasterStore extends PRJDataStore 
implements GridCoverageResource
      * @return the color model, or {@code null} if the file does not contain 
enough entries.
      * @throws NoSuchFileException if the auxiliary file has not been found 
(when opened from path).
      * @throws FileNotFoundException if the auxiliary file has not been found 
(when opened from URL).
+     * @throws URISyntaxException if an error occurred while normalizing the 
URI.
      * @throws IOException if another error occurred while opening the stream.
      * @throws NumberFormatException if a number cannot be parsed.
      */
     private ColorModel readColorMap(final int dataType, final int mapSize, 
final int numBands)
-            throws DataStoreException, IOException
+            throws DataStoreException, URISyntaxException, IOException
     {
         final int maxSize;
         switch (dataType) {
@@ -272,11 +274,12 @@ abstract class RasterStore extends PRJDataStore 
implements GridCoverageResource
      * @return statistics for each band. Some elements may be null if not 
specified in the file.
      * @throws NoSuchFileException if the auxiliary file has not been found 
(when opened from path).
      * @throws FileNotFoundException if the auxiliary file has not been found 
(when opened from URL).
+     * @throws URISyntaxException if an error occurred while normalizing the 
URI.
      * @throws IOException if another error occurred while opening the stream.
      * @throws NumberFormatException if a number cannot be parsed.
      */
     private Statistics[] readStatistics(final String name, final SampleModel 
sm)
-            throws DataStoreException, IOException
+            throws DataStoreException, URISyntaxException, IOException
     {
         final Statistics[] stats = new Statistics[sm.getNumBands()];
         for (final CharSequence line : 
CharSequences.splitOnEOL(readAuxiliaryFile(STX, false))) {
@@ -332,7 +335,7 @@ abstract class RasterStore extends PRJDataStore implements 
GridCoverageResource
          */
         try {
             stats = readStatistics(name, sm);
-        } catch (IOException | NumberFormatException e) {
+        } catch (URISyntaxException | IOException | NumberFormatException e) {
             cannotReadAuxiliaryFile(STX, e);
         }
         /*
@@ -401,7 +404,7 @@ abstract class RasterStore extends PRJDataStore implements 
GridCoverageResource
                 } else {
                     try {
                         colorModel = readColorMap(dataType, (int) (maximum + 
1), bands.length);
-                    } catch (IOException | NumberFormatException e) {
+                    } catch (URISyntaxException | IOException | 
NumberFormatException e) {
                         cannotReadAuxiliaryFile(CLR, e);
                     }
                     if (colorModel == null) {
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RawRasterStore.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RawRasterStore.java
index 64932fd5fc..b3624000a9 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RawRasterStore.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RawRasterStore.java
@@ -21,6 +21,7 @@ import java.util.Locale;
 import java.io.IOException;
 import java.nio.ByteOrder;
 import java.nio.file.Path;
+import java.net.URISyntaxException;
 import java.awt.image.DataBuffer;
 import java.awt.image.SampleModel;
 import java.awt.image.BandedSampleModel;
@@ -226,7 +227,7 @@ final class RawRasterStore extends RasterStore {
     public synchronized GridGeometry getGridGeometry() throws 
DataStoreException {
         if (reader == null) try {
             readHeader();
-        } catch (IOException e) {
+        } catch (URISyntaxException | IOException e) {
             throw new DataStoreException(canNotRead(), e);
         } catch (RuntimeException e) {
             throw new DataStoreContentException(canNotRead(), e);
@@ -251,7 +252,7 @@ final class RawRasterStore extends RasterStore {
             }
             loadBandDescriptions(input.filename, reader.layout);
             sampleDimensions = super.getSampleDimensions();
-        } catch (IOException e) {
+        } catch (URISyntaxException | IOException e) {
             throw new DataStoreException(canNotRead(), e);
         } catch (RuntimeException e) {
             throw new DataStoreContentException(canNotRead(), e);
@@ -329,13 +330,14 @@ final class RawRasterStore extends RasterStore {
      * <p>Note: we don't do this initialization in the constructor
      * for giving a chance for users to register listeners first.</p>
      *
+     * @throws URISyntaxException if an error occurred while normalizing the 
URI.
      * @throws IOException if the auxiliary file cannot be found or read.
      * @throws DataStoreException if the auxiliary file cannot be parsed.
      * @throws RasterFormatException if the number of bits or the 
signed/unsigned property is invalid.
      * @throws ArithmeticException if image size of pixel/line/band stride is 
too large.
      * @throws IllegalArgumentException if {@link SampleModel} constructor 
rejects some argument values.
      */
-    private void readHeader() throws IOException, DataStoreException {
+    private void readHeader() throws URISyntaxException, IOException, 
DataStoreException {
         assert Thread.holdsLock(this);
         @SuppressWarnings("LocalVariableHidesMemberVariable")
         final ChannelDataInput input = this.input;
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WorldFileStore.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WorldFileStore.java
index 32964b2ec1..b89c3f819d 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WorldFileStore.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WorldFileStore.java
@@ -29,6 +29,7 @@ import java.io.UncheckedIOException;
 import java.nio.file.Path;
 import java.nio.file.NoSuchFileException;
 import java.nio.file.StandardOpenOption;
+import java.net.URISyntaxException;
 import javax.imageio.ImageIO;
 import javax.imageio.ImageReader;
 import javax.imageio.spi.ImageReaderSpi;
@@ -330,10 +331,11 @@ public class WorldFileStore extends PRJDataStore {
      * </ol>
      *
      * @return the "World file" content as an affine transform, or {@code 
null} if none was found.
+     * @throws URISyntaxException if an error occurred while normalizing the 
URI.
      * @throws IOException if an I/O error occurred.
      * @throws DataStoreException if the auxiliary file content cannot be 
parsed.
      */
-    private AffineTransform2D readWorldFile() throws IOException, 
DataStoreException {
+    private AffineTransform2D readWorldFile() throws URISyntaxException, 
IOException, DataStoreException {
         IOException warning = null;
         final String preferred = getWorldFileSuffix();
 loop:   for (int convention=0;; convention++) {
@@ -369,10 +371,13 @@ loop:   for (int convention=0;; convention++) {
      *
      * @param  wld  suffix of the auxiliary file.
      * @return the "World file" content as an affine transform, or {@code 
null} if none was found.
+     * @throws URISyntaxException if an error occurred while normalizing the 
URI.
      * @throws IOException if an I/O error occurred.
      * @throws DataStoreException if the file content cannot be parsed.
      */
-    private AffineTransform2D readWorldFile(final String wld) throws 
IOException, DataStoreException {
+    private AffineTransform2D readWorldFile(final String wld)
+            throws URISyntaxException, IOException, DataStoreException
+    {
         final AuxiliaryContent content = readAuxiliaryFile(wld, false);
         if (content == null) {
             cannotReadAuxiliaryFile(WorldFileStore.class, "getGridGeometry", 
wld, null, true);
@@ -448,7 +453,7 @@ loop:   for (int convention=0;; convention++) {
     public synchronized Path[] getComponentFiles() throws DataStoreException {
         if (suffixWLD == null) try {
             getGridGeometry(MAIN_IMAGE);                // Will compute 
`suffixWLD` as a side effect.
-        } catch (IOException e) {
+        } catch (URISyntaxException | IOException e) {
             throw new DataStoreException(e);
         }
         return listComponentFiles(suffixWLD, PRJ);      // `suffixWLD` still 
null if file was not found.
@@ -461,10 +466,11 @@ loop:   for (int convention=0;; convention++) {
      * @param  index  index of the image for which to read the grid geometry.
      * @return grid geometry of the image at the given index.
      * @throws IndexOutOfBoundsException if the image index is out of bounds.
+     * @throws URISyntaxException if an error occurred while normalizing the 
URI.
      * @throws IOException if an I/O error occurred.
      * @throws DataStoreException if the {@code *.prj} or {@code *.tfw} 
auxiliary file content cannot be parsed.
      */
-    final GridGeometry getGridGeometry(final int index) throws IOException, 
DataStoreException {
+    final GridGeometry getGridGeometry(final int index) throws 
URISyntaxException, IOException, DataStoreException {
         assert Thread.holdsLock(this);
         @SuppressWarnings("LocalVariableHidesMemberVariable")
         final ImageReader reader = reader();
@@ -495,7 +501,9 @@ loop:   for (int convention=0;; convention++) {
      * @param  gg     the new grid geometry.
      * @return suffix of the "world file", or {@code null} if the image cannot 
be written.
      */
-    String setGridGeometry(final int index, final GridGeometry gg) throws 
IOException, DataStoreException {
+    String setGridGeometry(final int index, final GridGeometry gg)
+            throws URISyntaxException, IOException, DataStoreException
+    {
         if (index != MAIN_IMAGE) {
             return null;
         }
@@ -540,7 +548,7 @@ loop:   for (int convention=0;; convention++) {
             builder.addTitleOrIdentifier(getFilename(), 
MetadataBuilder.Scope.ALL);
             builder.setISOStandards(false);
             metadata = builder.buildAndFreeze();
-        } catch (IOException e) {
+        } catch (URISyntaxException | IOException e) {
             throw new DataStoreException(e);
         }
         return metadata;
@@ -672,7 +680,7 @@ loop:   for (int convention=0;; convention++) {
                     images[index] = image;
                 } catch (IOException e) {
                     throw new UncheckedIOException(e);
-                } catch (DataStoreException e) {
+                } catch (URISyntaxException | DataStoreException e) {
                     throw new BackingStoreException(e);
                 }
                 return image;
@@ -741,8 +749,11 @@ loop:   for (int convention=0;; convention++) {
      * @param  index  index of the image for which to create a resource.
      * @return resource for the image identified by the given index.
      * @throws IndexOutOfBoundsException if the image index is out of bounds.
+     * @throws URISyntaxException if an error occurred while normalizing the 
URI.
      */
-    WorldFileResource createImageResource(final int index) throws 
DataStoreException, IOException {
+    WorldFileResource createImageResource(final int index)
+            throws DataStoreException, URISyntaxException, IOException
+    {
         return new WorldFileResource(this, listeners, index, 
getGridGeometry(index));
     }
 
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WritableResource.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WritableResource.java
index 18999f115b..8d974a749a 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WritableResource.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WritableResource.java
@@ -17,6 +17,7 @@
 package org.apache.sis.storage.image;
 
 import java.io.IOException;
+import java.net.URISyntaxException;
 import java.awt.image.RenderedImage;
 import javax.imageio.ImageWriter;
 import org.apache.sis.coverage.grid.GridCoverage;
@@ -67,7 +68,7 @@ final class WritableResource extends WorldFileResource 
implements WritableGridCo
                 final ImageWriter writer = store.writer();                     
 // Should be after `setGridGeometry(…)`.
                 writer.write(data);
             }
-        } catch (IOException | RuntimeException e) {
+        } catch (URISyntaxException | IOException | RuntimeException e) {
             throw new 
DataStoreException(store.resources().getString(Resources.Keys.CanNotWriteResource_1,
 store.getDisplayName()), e);
         }
     }
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WritableStore.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WritableStore.java
index ec40e5651b..f2954a2f4e 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WritableStore.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WritableStore.java
@@ -20,6 +20,7 @@ import java.util.function.BiConsumer;
 import java.io.IOException;
 import java.io.BufferedWriter;
 import java.nio.file.StandardOpenOption;
+import java.net.URISyntaxException;
 import java.awt.geom.AffineTransform;
 import javax.imageio.ImageIO;
 import javax.imageio.ImageReader;
@@ -202,7 +203,9 @@ class WritableStore extends WorldFileStore {
      * @see #getGridGeometry(int)
      */
     @Override
-    String setGridGeometry(final int index, GridGeometry gg) throws 
IOException, DataStoreException {
+    String setGridGeometry(final int index, GridGeometry gg)
+            throws URISyntaxException, IOException, DataStoreException
+    {
         assert Thread.holdsLock(this);
         /*
          * Make sure that the grid geometry starts at (0,0).
@@ -274,7 +277,7 @@ writeCoeffs:    for (int i=0;; i++) {
      * @throws IndexOutOfBoundsException if the image index is out of bounds.
      */
     @Override
-    WorldFileResource createImageResource(final int index) throws 
DataStoreException, IOException {
+    WorldFileResource createImageResource(final int index) throws 
DataStoreException, URISyntaxException, IOException {
         return new WritableResource(this, listeners, index, 
getGridGeometry(index));
     }
 
@@ -313,7 +316,7 @@ writeCoeffs:    for (int i=0;; i++) {
             components.added(image);        // Must be invoked only after 
above succeeded.
             numImages++;
             return image;
-        } catch (IOException | RuntimeException e) {
+        } catch (URISyntaxException | IOException | RuntimeException e) {
             cause = e;
         }
         throw new 
DataStoreException(resources().getString(Resources.Keys.CanNotWriteResource_1, 
label(resource)), cause);
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/Store.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/Store.java
index 8d9a26478d..4f4cdadb8c 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/Store.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/Store.java
@@ -23,6 +23,7 @@ import java.io.Closeable;
 import java.io.Reader;
 import java.io.InputStream;
 import java.io.IOException;
+import java.net.URISyntaxException;
 import javax.xml.transform.stream.StreamSource;
 import jakarta.xml.bind.JAXBException;
 import org.opengis.metadata.Metadata;
@@ -80,9 +81,12 @@ final class Store extends URIDataStore implements Filter {
      *
      * @param  provider   the factory that created this {@code DataStore} 
instance, or {@code null} if unspecified.
      * @param  connector  information about the storage (URL, stream, 
<i>etc</i>).
+     * @throws URISyntaxException if an error occurred while normalizing the 
URI.
      * @throws DataStoreException if an error occurred while opening the 
stream.
      */
-    public Store(final StoreProvider provider, final StorageConnector 
connector) throws DataStoreException {
+    public Store(final StoreProvider provider, final StorageConnector 
connector)
+            throws URISyntaxException, DataStoreException
+    {
         super(provider, connector);
         final InputStream in = connector.getStorageAs(InputStream.class);
         if (in != null) {
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/StoreProvider.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/StoreProvider.java
index 7e205420b1..f21460ee34 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/StoreProvider.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/StoreProvider.java
@@ -18,6 +18,7 @@ package org.apache.sis.storage.xml;
 
 import java.util.Map;
 import java.util.logging.Logger;
+import java.net.URISyntaxException;
 import org.apache.sis.xml.Namespaces;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
@@ -82,7 +83,11 @@ public final class StoreProvider extends AbstractProvider {
      */
     @Override
     public DataStore open(final StorageConnector connector) throws 
DataStoreException {
-        return new Store(this, connector);
+        try {
+            return new Store(this, connector);
+        } catch (URISyntaxException e) {
+            throw new DataStoreException(e);
+        }
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/xml/StoreTest.java
 
b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/xml/StoreTest.java
index a3d693b9a5..5bdaf5f248 100644
--- 
a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/xml/StoreTest.java
+++ 
b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/xml/StoreTest.java
@@ -18,6 +18,7 @@ package org.apache.sis.storage.xml;
 
 import java.util.Locale;
 import java.io.StringReader;
+import java.net.URISyntaxException;
 import org.opengis.metadata.Metadata;
 import org.opengis.metadata.citation.*;
 import org.apache.sis.xml.Namespaces;
@@ -27,8 +28,7 @@ import org.apache.sis.xml.util.LegacyNamespaces;
 
 // Test dependencies
 import org.junit.Test;
-import static org.junit.Assert.*;
-import static org.opengis.test.Assert.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.*;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import static org.apache.sis.test.TestUtilities.getSingleton;
@@ -94,21 +94,22 @@ public final class StoreTest extends TestCase {
     /**
      * Tests {@link Store#getMetadata()}.
      *
+     * @throws URISyntaxException if an error occurred while normalizing the 
URI.
      * @throws DataStoreException if en error occurred while reading the XML.
      */
     @Test
-    public void testMetadata() throws DataStoreException {
+    public void testMetadata() throws URISyntaxException, DataStoreException {
         final Metadata metadata;
         try (Store store = new Store(null, new StorageConnector(new 
StringReader(XML)))) {
             metadata = store.getMetadata();
-            assertSame("Expected cached value.", metadata, 
store.getMetadata());
+            assertSame(metadata, store.getMetadata(), "Expected cached 
value.");
         }
         final Responsibility resp     = getSingleton(metadata.getContacts());
         final Party          party    = getSingleton(resp.getParties());
         final Contact        contact  = getSingleton(party.getContactInfo());
         final OnlineResource resource = 
getSingleton(contact.getOnlineResources());
 
-        assertInstanceOf("party", Organisation.class, party);
+        assertInstanceOf(Organisation.class, party, "party");
         assertEquals(Locale.ENGLISH,              
getSingleton(metadata.getLocalesAndCharsets().keySet()));
         assertEquals(StandardCharsets.UTF_8,      
getSingleton(metadata.getLocalesAndCharsets().values()));
         assertEquals(Role.PRINCIPAL_INVESTIGATOR, resp.getRole());

Reply via email to