@@ -199,12 +199,50 @@ 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> var u = new URI("file:/foo/bar/")
210
+ * u ==> file:/foo/bar/
211
+ *
212
+ * jshell> u.resolve("..")
213
+ * $2 ==> file:/foo/
214
+ *
215
+ * jshell> u = new URI("file:/foo/bar")
216
+ * u ==> file:/foo/bar
217
+ *
218
+ * jshell> u.resolve("..")
219
+ * $4 ==> file:/
220
+ * }</pre>
221
+ * <p>
222
+ * Whereas this function returns "file:/C:/foo/" in both cases.
223
+ */
202
224
private static URI getParent ( final URI uri ) throws SpimDataIOException
203
225
{
204
226
try
205
227
{
206
- final String parent = Paths .get ( uri .getPath () ).getParent ().toString () + "/" ;
207
- return new URI ( uri .getScheme (), uri .getAuthority (), parent , uri .getQuery (), uri .getFragment () );
228
+ final String uriPath = uri .getPath ();
229
+ final int parentSlash = uriPath .lastIndexOf ( "/" , uriPath .length () - 2 );
230
+ if ( parentSlash < 0 )
231
+ {
232
+ throw new SpimDataIOException ( "URI is already at the root" );
233
+ }
234
+ // NB: The "+ 1" below is *very important*, so that the resultant URI
235
+ // ends in a trailing slash. The behaviour of URI differs depending on
236
+ // whether this trailing slash is present; specifically:
237
+ //
238
+ // * new URI("file:/foo/bar/").resolve(".") -> "file:/foo/bar/"
239
+ // * new URI("file:/foo/bar").resolve(".") -> "file:/foo/"
240
+ //
241
+ // That is: /foo/bar/ is considered to be in the directory /foo/bar,
242
+ // whereas /foo/bar is considered to be in the directory /foo.
243
+ final String parentPath = uriPath .substring ( 0 , parentSlash + 1 );
244
+ return new URI ( uri .getScheme (), uri .getUserInfo (), uri .getHost (),
245
+ uri .getPort (), parentPath , uri .getQuery (), uri .getFragment () );
208
246
}
209
247
catch ( URISyntaxException e )
210
248
{
0 commit comments