@@ -199,12 +199,44 @@ protected URI loadBasePathURI( final Element root, final URI xmlURI ) throws Spi
199
199
return XmlHelpers .loadPathURI ( root , BASEPATH_TAG , "." , parent );
200
200
}
201
201
202
+ /**
203
+ * Gets a URI's parent, e.g. the containing directory of a file.
204
+ * <p>
205
+ * This function behaves differently than the invocation
206
+ * {@code uri.resolve("..")} when the URI ends in a trailing slash:
207
+ * </p>
208
+ * <pre>{@code
209
+ * jshell> new URI("file:/foo/bar/").resolve("..")
210
+ * $1 ==> file:/foo/
211
+ *
212
+ * jshell> new URI("file:/foo/bar").resolve("..")
213
+ * $2 ==> file:/
214
+ * }</pre>
215
+ * <p>
216
+ * Whereas this function returns "file:/foo/" in both cases.
217
+ */
202
218
private static URI getParent ( final URI uri ) throws SpimDataIOException
203
219
{
204
220
try
205
221
{
206
- final String parent = Paths .get ( uri .getPath () ).getParent ().toString () + "/" ;
207
- return new URI ( uri .getScheme (), uri .getAuthority (), parent , uri .getQuery (), uri .getFragment () );
222
+ final String uriPath = uri .getPath ();
223
+ final int parentSlash = uriPath .lastIndexOf ( "/" , uriPath .length () - 2 );
224
+ if ( parentSlash < 0 )
225
+ {
226
+ throw new SpimDataIOException ( "URI is already at the root" );
227
+ }
228
+ // NB: The "+ 1" below is *very important*, so that the resultant URI
229
+ // ends in a trailing slash. The behaviour of URI differs depending on
230
+ // whether this trailing slash is present; specifically:
231
+ //
232
+ // * new URI("file:/foo/bar/").resolve(".") -> "file:/foo/bar/"
233
+ // * new URI("file:/foo/bar").resolve(".") -> "file:/foo/"
234
+ //
235
+ // That is: /foo/bar/ is considered to be in the directory /foo/bar,
236
+ // whereas /foo/bar is considered to be in the directory /foo.
237
+ final String parentPath = uriPath .substring ( 0 , parentSlash + 1 );
238
+ return new URI ( uri .getScheme (), uri .getUserInfo (), uri .getHost (),
239
+ uri .getPort (), parentPath , uri .getQuery (), uri .getFragment () );
208
240
}
209
241
catch ( URISyntaxException e )
210
242
{
0 commit comments