Skip to content

Commit dc410ce

Browse files
committed
Add a subsystem for handling URI links
1 parent 7fd0973 commit dc410ce

File tree

6 files changed

+399
-0
lines changed

6 files changed

+399
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*-
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2023 SciJava developers.
6+
* %%
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
* #L%
28+
*/
29+
package org.scijava.links;
30+
31+
import org.scijava.plugin.AbstractHandlerPlugin;
32+
33+
import java.net.URI;
34+
35+
public abstract class AbstractLinkHandler extends AbstractHandlerPlugin<URI>
36+
implements LinkHandler
37+
{
38+
// NB: No implementation needed.
39+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*-
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2023 SciJava developers.
6+
* %%
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
* #L%
28+
*/
29+
package org.scijava.links;
30+
31+
import org.scijava.plugin.AbstractHandlerService;
32+
import org.scijava.plugin.Plugin;
33+
import org.scijava.service.Service;
34+
35+
import java.net.URI;
36+
37+
/**
38+
* Default implementation of {@link LinkService}.
39+
*
40+
* @author Curtis Rueden
41+
*/
42+
@Plugin(type = Service.class)
43+
public class DefaultLinkService extends AbstractHandlerService<URI, LinkHandler> implements LinkService {
44+
// NB: No implementation needed.
45+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*-
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2023 SciJava developers.
6+
* %%
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
* #L%
28+
*/
29+
package org.scijava.links;
30+
31+
import org.scijava.plugin.HandlerPlugin;
32+
33+
import java.net.URI;
34+
35+
/**
36+
* A plugin for handling URI links.
37+
*
38+
* @author Curtis Rueden
39+
*/
40+
public interface LinkHandler extends HandlerPlugin<URI> {
41+
42+
/**
43+
* Handles the given URI.
44+
*
45+
* @param uri The URI to handle.
46+
*/
47+
void handle(URI uri);
48+
49+
@Override
50+
default Class<URI> getType() {
51+
return URI.class;
52+
}
53+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*-
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2023 SciJava developers.
6+
* %%
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
* #L%
28+
*/
29+
package org.scijava.links;
30+
31+
import org.scijava.log.Logger;
32+
import org.scijava.plugin.HandlerService;
33+
import org.scijava.service.SciJavaService;
34+
35+
import java.awt.*;
36+
import java.net.URI;
37+
import java.util.Optional;
38+
39+
/**
40+
* Service interface for handling URIs.
41+
*
42+
* @author Curtis Rueden
43+
* @see LinkHandler
44+
*/
45+
public interface LinkService extends HandlerService<URI, LinkHandler>,
46+
SciJavaService
47+
{
48+
49+
default void handle(final URI uri) {
50+
// Find the highest-priority link handler plugin which matches, if any.
51+
final Optional<LinkHandler> match = getInstances().stream() //
52+
.filter(handler -> handler.supports(uri)) //
53+
.findFirst();
54+
if (!match.isPresent()) {
55+
// No appropriate link handler plugin was found.
56+
final Logger log = log();
57+
if (log != null) log.debug("No handler for URI: " + uri);
58+
return; // no handler for this URI
59+
}
60+
// Handle the URI using the matching link handler.
61+
match.get().handle(uri);
62+
}
63+
64+
// -- PTService methods --
65+
66+
@Override
67+
default Class<LinkHandler> getPluginType() {
68+
return LinkHandler.class;
69+
}
70+
71+
// -- Service methods --
72+
73+
@Override
74+
default void initialize() {
75+
HandlerService.super.initialize();
76+
// Register URI handler with the desktop system, if possible.
77+
if (!Desktop.isDesktopSupported()) return;
78+
final Desktop desktop = Desktop.getDesktop();
79+
if (!desktop.isSupported(Desktop.Action.APP_OPEN_URI)) return;
80+
desktop.setOpenURIHandler(event -> handle(event.getURI()));
81+
}
82+
83+
// -- Typed methods --
84+
85+
@Override
86+
default Class<URI> getType() {
87+
return URI.class;
88+
}
89+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*-
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2023 SciJava developers.
6+
* %%
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
* #L%
28+
*/
29+
package org.scijava.links;
30+
31+
import java.net.URI;
32+
import java.util.LinkedHashMap;
33+
import java.util.Map;
34+
35+
/**
36+
* Utility class for working with {@link URI} objects.
37+
*
38+
* @author Curtis Rueden
39+
*/
40+
public final class Links {
41+
private Links() {
42+
// NB: Prevent instantiation of utility class.
43+
}
44+
45+
public static String path(final URI uri) {
46+
final String path = uri.getPath();
47+
if (path == null) return null;
48+
return path.startsWith("/") ? path.substring(1) : path;
49+
}
50+
51+
public static String operation(final URI uri) {
52+
final String path = path(uri);
53+
if (path == null) return null;
54+
final int slash = path.indexOf("/");
55+
return slash < 0 ? path : path.substring(0, slash);
56+
}
57+
58+
public static String[] pathFragments(final URI uri) {
59+
final String path = path(uri);
60+
if (path == null) return null;
61+
return path.isEmpty() ? new String[0] : path.split("/");
62+
}
63+
64+
public static String subPath(final URI uri) {
65+
final String path = path(uri);
66+
if (path == null) return null;
67+
final int slash = path.indexOf("/");
68+
return slash < 0 ? "" : path.substring(slash + 1);
69+
}
70+
71+
public static Map<String, String> query(final URI uri) {
72+
final LinkedHashMap<String, String> map = new LinkedHashMap<>();
73+
final String query = uri.getQuery();
74+
final String[] tokens = query == null ? new String[0] : query.split("&");
75+
for (final String token : tokens) {
76+
final String[] kv = token.split("=", 2);
77+
final String k = kv[0];
78+
final String v = kv.length > 1 ? kv[1] : null;
79+
map.put(k, v);
80+
}
81+
return map;
82+
}
83+
}

0 commit comments

Comments
 (0)