diff --git a/src/main/java/org/scijava/io/location/AbstractLocationResolver.java b/src/main/java/org/scijava/io/location/AbstractLocationResolver.java new file mode 100644 index 000000000..3ab3c8e75 --- /dev/null +++ b/src/main/java/org/scijava/io/location/AbstractLocationResolver.java @@ -0,0 +1,72 @@ +/* + * #%L + * SciJava Common shared library for SciJava software. + * %% + * Copyright (C) 2009 - 2017 Board of Regents of the University of + * Wisconsin-Madison, Broad Institute of MIT and Harvard, Max Planck + * Institute of Molecular Cell Biology and Genetics, University of + * Konstanz, and KNIME GmbH. + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ + +package org.scijava.io.location; + +import java.net.URI; + +import org.scijava.plugin.AbstractHandlerPlugin; + +/** + * Abstract super class for {@link LocationResolver} plugins. + * + * @author Gabriel Einsdorf + */ +public abstract class AbstractLocationResolver extends + AbstractHandlerPlugin implements LocationResolver +{ + + private final String[] schemes; + + /** + * @param schemes the uri schmemes that the implementing sub-type supports + */ + public AbstractLocationResolver(String... schemes) { + assert schemes.length > 0; + this.schemes = schemes; + } + + @Override + public boolean supports(URI uri) { + boolean supports = false; + for (final String scheme : schemes) { + supports = supports || scheme.equals(uri.getScheme()); + } + return supports; + } + + @Override + public Class getType() { + return URI.class; + } + +} diff --git a/src/main/java/org/scijava/io/location/DefaultLocationService.java b/src/main/java/org/scijava/io/location/DefaultLocationService.java new file mode 100644 index 000000000..d8c3c037d --- /dev/null +++ b/src/main/java/org/scijava/io/location/DefaultLocationService.java @@ -0,0 +1,60 @@ +/* + * #%L + * SciJava Common shared library for SciJava software. + * %% + * Copyright (C) 2009 - 2017 Board of Regents of the University of + * Wisconsin-Madison, Broad Institute of MIT and Harvard, Max Planck + * Institute of Molecular Cell Biology and Genetics, University of + * Konstanz, and KNIME GmbH. + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ + +package org.scijava.io.location; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +import org.scijava.plugin.AbstractHandlerService; +import org.scijava.plugin.Plugin; +import org.scijava.service.Service; + +/** + * Default {@link LocationService} implementation. + * + * @author Gabriel Einsdorf + */ +@Plugin(type = Service.class) +public class DefaultLocationService extends + AbstractHandlerService implements + LocationService +{ + + private final Map resolvers = new HashMap<>(); + + @Override + public LocationResolver getResolver(final URI uri) { + return resolvers.computeIfAbsent(uri.getScheme(), u -> getHandler(uri)); + } +} diff --git a/src/main/java/org/scijava/io/location/FileLocationResolver.java b/src/main/java/org/scijava/io/location/FileLocationResolver.java new file mode 100644 index 000000000..b40f0f13e --- /dev/null +++ b/src/main/java/org/scijava/io/location/FileLocationResolver.java @@ -0,0 +1,55 @@ +/* + * #%L + * SciJava Common shared library for SciJava software. + * %% + * Copyright (C) 2009 - 2017 Board of Regents of the University of + * Wisconsin-Madison, Broad Institute of MIT and Harvard, Max Planck + * Institute of Molecular Cell Biology and Genetics, University of + * Konstanz, and KNIME GmbH. + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ + +package org.scijava.io.location; + +import java.net.URI; + +import org.scijava.plugin.Plugin; + +/** + * Implementation of {@link LocationResolver} for {@link FileLocation}. + * + * @author Gabriel Einsdorf + */ +@Plugin(type = LocationResolver.class) +public class FileLocationResolver extends AbstractLocationResolver { + + public FileLocationResolver() { + super("file"); + } + + @Override + public Location resolve(URI uri) { + return new FileLocation(uri); + } +} diff --git a/src/main/java/org/scijava/io/location/LocationResolver.java b/src/main/java/org/scijava/io/location/LocationResolver.java new file mode 100644 index 000000000..6e71f617c --- /dev/null +++ b/src/main/java/org/scijava/io/location/LocationResolver.java @@ -0,0 +1,56 @@ +/* + * #%L + * SciJava Common shared library for SciJava software. + * %% + * Copyright (C) 2009 - 2017 Board of Regents of the University of + * Wisconsin-Madison, Broad Institute of MIT and Harvard, Max Planck + * Institute of Molecular Cell Biology and Genetics, University of + * Konstanz, and KNIME GmbH. + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ + +package org.scijava.io.location; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.scijava.plugin.HandlerPlugin; + +/** + * {@link LocationResolver} plugins allow resolving an {@link URI} to a + * {@link Location}. Extending {@link AbstractLocationResolver} is recommended + * for easy implementation. + * + * @author Gabriel Einsdorf + */ +public interface LocationResolver extends HandlerPlugin { + + /** + * Resolves the given {@link URI} to a {@link Location} + * + * @return the resolved Location + * @throws URISyntaxException + */ + Location resolve(URI uri) throws URISyntaxException; +} diff --git a/src/main/java/org/scijava/io/location/LocationService.java b/src/main/java/org/scijava/io/location/LocationService.java new file mode 100644 index 000000000..193e03929 --- /dev/null +++ b/src/main/java/org/scijava/io/location/LocationService.java @@ -0,0 +1,100 @@ +/* + * #%L + * SciJava Common shared library for SciJava software. + * %% + * Copyright (C) 2009 - 2017 Board of Regents of the University of + * Wisconsin-Madison, Broad Institute of MIT and Harvard, Max Planck + * Institute of Molecular Cell Biology and Genetics, University of + * Konstanz, and KNIME GmbH. + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ + +package org.scijava.io.location; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.scijava.plugin.HandlerService; +import org.scijava.service.SciJavaService; + +/** + * A service that allows resolving of URIs to Locations, using + * {@link LocationResolver} plugins for translation. + * + * @author Gabriel Einsdorf + */ +public interface LocationService extends HandlerService, + SciJavaService +{ + + /** + * Turns the given string into an {@link URI}, then resolves it to a + * {@link Location} + * + * @param uri the uri to resolve + * @return the resolved {@link Location} + * @throws URISyntaxException if the URI is malformed + */ + default Location resolve(final String uri) throws URISyntaxException { + return resolve(new URI(uri)); + } + + /** + * Resolves the given {@link URI} to a location. + * + * @param uri the uri to resolve + * @return the resolved {@link Location} or null if no resolver + * could be found. + * @throws URISyntaxException if the URI is malformed + */ + default Location resolve(final URI uri) throws URISyntaxException { + final LocationResolver resolver = getResolver(uri); + return resolver != null ? resolver.resolve(uri) : null; + } + + /** + * Returns a {@link LocationResolver} capable of resolving URL like the one + * provided to this method. Allows faster repeated resolving of similar URIs + * without going through this service. + * + * @param uri the uri + * @return the {@link LocationResolver} for this uri type, or + * null if no resolver could be found. + */ + LocationResolver getResolver(URI uri); + + // -- PTService methods -- + + @Override + default Class getPluginType() { + return LocationResolver.class; + } + + // -- Typed methods -- + + @Override + default Class getType() { + return URI.class; + } +} diff --git a/src/test/java/org/scijava/ContextCreationTest.java b/src/test/java/org/scijava/ContextCreationTest.java index 79b80affc..bfcce46e5 100644 --- a/src/test/java/org/scijava/ContextCreationTest.java +++ b/src/test/java/org/scijava/ContextCreationTest.java @@ -100,6 +100,7 @@ public void testFull() { org.scijava.io.DefaultIOService.class, org.scijava.io.DefaultRecentFileService.class, org.scijava.io.handle.DefaultDataHandleService.class, + org.scijava.io.location.DefaultLocationService.class, org.scijava.io.nio.DefaultNIOService.class, org.scijava.main.DefaultMainService.class, org.scijava.menu.DefaultMenuService.class, diff --git a/src/test/java/org/scijava/io/location/FileLocationResolverTest.java b/src/test/java/org/scijava/io/location/FileLocationResolverTest.java new file mode 100644 index 000000000..9e94b0281 --- /dev/null +++ b/src/test/java/org/scijava/io/location/FileLocationResolverTest.java @@ -0,0 +1,72 @@ +/* + * #%L + * SciJava Common shared library for SciJava software. + * %% + * Copyright (C) 2009 - 2017 Board of Regents of the University of + * Wisconsin-Madison, Broad Institute of MIT and Harvard, Max Planck + * Institute of Molecular Cell Biology and Genetics, University of + * Konstanz, and KNIME GmbH. + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ + +package org.scijava.io.location; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; + +import org.junit.Test; +import org.scijava.Context; + +/** + * Test for {@link FileLocationResolver}. + * + * @author Gabriel Einsdorf + */ +public class FileLocationResolverTest { + + Context ctx = new Context(LocationService.class); + LocationService resolver = ctx.getService(LocationService.class); + + @Test + public void testStringResolve() throws URISyntaxException { + final String uri = new File(new File(".").getAbsolutePath()) // + .toURI().toString(); + final Location loc = resolver.resolve(uri); + assertTrue(loc instanceof FileLocation); + assertEquals(uri, loc.getURI().toString()); + } + + @Test + public void testURIResolve() throws URISyntaxException { + final URI uri = new File(new File(".").getAbsolutePath()).toURI(); + final Location loc = resolver.resolve(uri); + assertTrue(loc instanceof FileLocation); + assertEquals(uri, loc.getURI()); + } + +} diff --git a/src/test/java/org/scijava/io/location/LocationServiceTest.java b/src/test/java/org/scijava/io/location/LocationServiceTest.java new file mode 100644 index 000000000..5d6d5d9b7 --- /dev/null +++ b/src/test/java/org/scijava/io/location/LocationServiceTest.java @@ -0,0 +1,66 @@ +/* + * #%L + * SciJava Common shared library for SciJava software. + * %% + * Copyright (C) 2009 - 2017 Board of Regents of the University of + * Wisconsin-Madison, Broad Institute of MIT and Harvard, Max Planck + * Institute of Molecular Cell Biology and Genetics, University of + * Konstanz, and KNIME GmbH. + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ + +package org.scijava.io.location; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; + +import org.junit.Test; +import org.scijava.Context; + +/** + * Tests {@link LocationService}. + * + * @author Gabriel Einsdorf + */ +public class LocationServiceTest { + + @Test + public void testResolve() throws URISyntaxException { + final Context ctx = new Context(LocationService.class); + final LocationService loc = ctx.getService(LocationService.class); + + final URI uri = new File(new File(".").getAbsolutePath()).toURI(); + final LocationResolver res = loc.getResolver(uri); + + assertTrue(res instanceof FileLocationResolver); + assertEquals(uri, res.resolve(uri).getURI()); + assertEquals(uri, loc.resolve(uri).getURI()); + assertEquals(uri, loc.resolve(uri.toString()).getURI()); + } + +}