You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2024/02/02 17:13:39 UTC

(sis) 01/03: Allow `IOUtilities.toFileOrURL(String)` to convert "file:something" to a relative file. Previously recognized only "file:/something" or "file:///something", which are absolute.

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 <ma...@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");