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 495d154bc6fe4b3f54add7b8e673ed98e4a5573c
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Fri Feb 2 15:26:08 2024 +0100

    Allow `IOUtilities.toFileOrURL(String)` to convert "file:something" to a 
relative file.
    Previously recognized only "file:/something" or "file:///something", which 
are absolute.
---
 .../main/org/apache/sis/io/stream/IOUtilities.java  | 12 +++++++++---
 .../org/apache/sis/io/stream/IOUtilitiesTest.java   | 21 +++++++++++++++++----
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/IOUtilities.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/IOUtilities.java
index 1c85cc877d..f0bad997ce 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/IOUtilities.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/IOUtilities.java
@@ -361,6 +361,8 @@ public final class IOUtilities extends Static {
      * <h4>Rational</h4>
      * A URL can represent a file, but {@link URL#openStream()} appears to 
return a {@code BufferedInputStream}
      * wrapping the {@link FileInputStream}, which is not a desirable feature 
when we want to obtain a channel.
+     * Another reason is that {@link File} can be relative to the current 
working directory, while {@link URI}
+     * can be {@linkplain URI#resolve(URI) resolved} only against absolute URI.
      *
      * @param  path      the path to convert, or {@code null}.
      * @param  encoding  if the URL is encoded in a {@code 
application/x-www-form-urlencoded} MIME format,
@@ -399,9 +401,13 @@ public final class IOUtilities extends Static {
         IllegalArgumentException suppressed = null;
         try {
             final URI uri = new URI(path);
-            final String scheme = uri.getScheme();
-            if (scheme != null && scheme.equalsIgnoreCase("file")) try {
-                return new File(uri);
+            if ("file".equalsIgnoreCase(uri.getScheme())) try {
+                if (uri.isOpaque() && uri.getRawFragment() == null) {
+                    // Case where the path is only "file:something" without 
"/" or "///" characters.
+                    return new File(uri.getSchemeSpecificPart());
+                } else {
+                    return new File(uri);
+                }
             } catch (IllegalArgumentException e) {
                 suppressed = e;
             }
diff --git 
a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/io/stream/IOUtilitiesTest.java
 
b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/io/stream/IOUtilitiesTest.java
index 59146b4cc1..8817e6fe6e 100644
--- 
a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/io/stream/IOUtilitiesTest.java
+++ 
b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/io/stream/IOUtilitiesTest.java
@@ -163,14 +163,27 @@ public final class IOUtilitiesTest extends TestCase {
     @Test
     @DependsOnMethod("testToFileFromUTF8")
     public void testToFileOrURL() throws IOException {
-        assertEquals(new File("/Users/name/Map.png"),        
IOUtilities.toFileOrURL("/Users/name/Map.png", null));
-        assertEquals(new File("/Users/name/Map.png"),        
IOUtilities.toFileOrURL("file:/Users/name/Map.png", null));
-        assertEquals(URI.create("http://localhost";).toURL(), 
IOUtilities.toFileOrURL("http://localhost";, null));
+        // Absolute file paths
+        File expected = new File("/Users/name/Map.png");
+        assertEquals(expected, IOUtilities.toFileOrURL("/Users/name/Map.png", 
null));
+        assertEquals(expected, 
IOUtilities.toFileOrURL("file:/Users/name/Map.png", null));
+        assertEquals(expected, 
IOUtilities.toFileOrURL("file:///Users/name/Map.png", null));
+
+        // Relative file paths
+        expected = new File("name/Map.png");
+        assertEquals(expected, IOUtilities.toFileOrURL("name/Map.png", null));
+        assertEquals(expected, IOUtilities.toFileOrURL("file:name/Map.png", 
null));
+
+        // HTTP paths
+        assertEquals(URI.create("http://localhost";).toURL(),
+                IOUtilities.toFileOrURL("http://localhost";, null));
+
+        // Encoded paths
         assertEquals(new File("/Users/name/Map with spaces.png"),
                 
IOUtilities.toFileOrURL("file:/Users/name/Map%20with%20spaces.png", "UTF-8"));
 
         String path = "file:/Users/name/++t--++est.shp";
-        var expected = new File("/Users/name/++t--++est.shp");
+        expected = new File("/Users/name/++t--++est.shp");
         assertEquals(expected, IOUtilities.toFileOrURL(path, null));
 
         path = path.replace("+", "%2B");

Reply via email to