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");