diff --git a/pom.xml b/pom.xml index 9868b80ee..35e36da1e 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ scijava-common - 2.41.1-SNAPSHOT + 3.0.0-SNAPSHOT SciJava Common SciJava Common is a shared library for SciJava software. It provides a plugin framework, with an extensible mechanism for service discovery, backed by its own annotation processor, so that plugins can be loaded dynamically. It is used by both ImageJ and SCIFIO. diff --git a/src/main/java/org/scijava/io/AbstractIOPlugin.java b/src/main/java/org/scijava/io/AbstractIOPlugin.java index 9091ae38f..dbbe7f2b1 100644 --- a/src/main/java/org/scijava/io/AbstractIOPlugin.java +++ b/src/main/java/org/scijava/io/AbstractIOPlugin.java @@ -40,47 +40,47 @@ * * @author Curtis Rueden */ -public abstract class AbstractIOPlugin extends AbstractHandlerPlugin - implements IOPlugin +public abstract class AbstractIOPlugin extends + AbstractHandlerPlugin implements IOPlugin { // -- IOPlugin methods -- @Override - public boolean supportsOpen(final String source) { + public boolean supportsOpen(final Location source) { return false; } @Override - public boolean supportsSave(final String destination) { + public boolean supportsSave(final Location destination) { return false; } @Override - public boolean supportsSave(final Object data, final String destination) { + public boolean supportsSave(final Object data, final Location destination) { return supportsSave(destination) && getDataType().isInstance(data); } @Override - public D open(final String source) throws IOException { + public D open(final Location source) throws IOException { throw new UnsupportedOperationException(); } @Override - public void save(final D data, final String destination) throws IOException { + public void save(final D data, final Location destination) throws IOException { throw new UnsupportedOperationException(); } // -- Typed methods -- @Override - public boolean supports(final String descriptor) { - return supportsOpen(descriptor) || supportsSave(descriptor); + public boolean supports(final Location location) { + return supportsOpen(location) || supportsSave(location); } @Override - public Class getType() { - return String.class; + public Class getType() { + return Location.class; } } diff --git a/src/main/java/org/scijava/io/DefaultIOService.java b/src/main/java/org/scijava/io/DefaultIOService.java index 2ad822f72..29cb415c9 100644 --- a/src/main/java/org/scijava/io/DefaultIOService.java +++ b/src/main/java/org/scijava/io/DefaultIOService.java @@ -49,7 +49,7 @@ */ @Plugin(type = Service.class) public final class DefaultIOService - extends AbstractHandlerService> implements IOService + extends AbstractHandlerService> implements IOService { @Parameter @@ -61,7 +61,7 @@ public final class DefaultIOService // -- IOService methods -- @Override - public IOPlugin getOpener(final String source) { + public IOPlugin getOpener(final Location source) { for (final IOPlugin handler : getInstances()) { if (handler.supportsOpen(source)) return handler; } @@ -69,7 +69,7 @@ public IOPlugin getOpener(final String source) { } @Override - public IOPlugin getSaver(final D data, final String destination) { + public IOPlugin getSaver(D data, Location destination) { for (final IOPlugin handler : getInstances()) { if (handler.supportsSave(data, destination)) { @SuppressWarnings("unchecked") @@ -81,7 +81,7 @@ public IOPlugin getSaver(final D data, final String destination) { } @Override - public Object open(final String source) throws IOException { + public Object open(final Location source) throws IOException { final IOPlugin opener = getOpener(source); if (opener == null) return null; // no appropriate IOPlugin @@ -93,7 +93,7 @@ public Object open(final String source) throws IOException { } @Override - public void save(final Object data, final String destination) + public void save(final Object data, final Location destination) throws IOException { final IOPlugin saver = getSaver(data, destination); @@ -112,8 +112,8 @@ public Class> getPluginType() { } @Override - public Class getType() { - return String.class; + public Class getType() { + return Location.class; } } diff --git a/src/main/java/org/scijava/io/DefaultRecentFileService.java b/src/main/java/org/scijava/io/DefaultRecentFileService.java index ce0ddd9e6..3fe7e3c41 100644 --- a/src/main/java/org/scijava/io/DefaultRecentFileService.java +++ b/src/main/java/org/scijava/io/DefaultRecentFileService.java @@ -178,7 +178,10 @@ public void initialize() { @EventHandler protected void onEvent(final IOEvent event) { - add(event.getDescriptor()); + final Location loc = event.getLocation(); + if (!(loc instanceof FileLocation)) return; + final FileLocation fileLoc = (FileLocation) loc; + add(fileLoc.getFile().getPath()); } // -- Helper methods -- diff --git a/src/main/java/org/scijava/io/IOPlugin.java b/src/main/java/org/scijava/io/IOPlugin.java index aacaade90..51c461f57 100644 --- a/src/main/java/org/scijava/io/IOPlugin.java +++ b/src/main/java/org/scijava/io/IOPlugin.java @@ -50,27 +50,27 @@ * @see Plugin * @see IOService */ -public interface IOPlugin extends HandlerPlugin { +public interface IOPlugin extends HandlerPlugin { /** The type of data opened and/or saved by the plugin. */ Class getDataType(); - /** Checks whether the I/O plugin can open data from the given source. */ - boolean supportsOpen(String source); + /** Checks whether the I/O plugin can open data from the given location. */ + boolean supportsOpen(Location source); - /** Checks whether the I/O plugin can save data to the given destination. */ - boolean supportsSave(String destination); + /** Checks whether the I/O plugin can save data to the given location. */ + boolean supportsSave(Location destination); + + /** Opens data from the given location. */ + D open(Location source) throws IOException; /** * Checks whether the I/O plugin can save the given data to the specified - * destination. + * location. */ - boolean supportsSave(Object data, String destination); - - /** Opens data from the given source. */ - D open(String source) throws IOException; + boolean supportsSave(Object data, Location destination); - /** Saves the given data to the specified destination. */ - void save(D data, String destination) throws IOException; + /** Saves the given data to the specified location. */ + void save(D data, Location destination) throws IOException; } diff --git a/src/main/java/org/scijava/io/IOService.java b/src/main/java/org/scijava/io/IOService.java index b82fd0f1e..af9c18456 100644 --- a/src/main/java/org/scijava/io/IOService.java +++ b/src/main/java/org/scijava/io/IOService.java @@ -43,52 +43,47 @@ * @see DataHandleService * @see Location */ -public interface IOService extends HandlerService>, +public interface IOService extends HandlerService>, SciJavaService { /** * Gets the most appropriate {@link IOPlugin} for opening data from the given - * source. + * location. */ - IOPlugin getOpener(String source); + IOPlugin getOpener(Location source); /** * Gets the most appropriate {@link IOPlugin} for saving data to the given - * destination. + * location. */ - IOPlugin getSaver(D data, String destination); + IOPlugin getSaver(D data, Location destination); /** - * Loads data from the given source. For extensibility, the nature of the - * source is left intentionally general, but two common examples include file - * paths and URLs. + * Loads data from the given location. *

* The opener to use is automatically determined based on available - * {@link IOPlugin}s; see {@link #getOpener(String)}. + * {@link IOPlugin}s; see {@link #getOpener(Location)}. *

* - * @param source The source (e.g., file path) from which to data should be - * loaded. + * @param source The location from which to data should be loaded. * @return An object representing the loaded data, or null if the source is * not supported. * @throws IOException if something goes wrong loading the data. */ - Object open(String source) throws IOException; + Object open(Location source) throws IOException; /** - * Saves data to the given destination. The nature of the destination is left - * intentionally general, but the most common example is a file path. + * Saves data to the given location. *

* The saver to use is automatically determined based on available - * {@link IOPlugin}s; see {@link #getSaver(Object, String)}. + * {@link IOPlugin}s; see {@link #getSaver(Object, Location)}. *

* * @param data The data to be saved to the destination. - * @param destination The destination (e.g., file path) to which data should - * be saved. + * @param destination The destination location to which data should be saved. * @throws IOException if something goes wrong saving the data. */ - void save(Object data, String destination) throws IOException; + void save(Object data, Location destination) throws IOException; } diff --git a/src/main/java/org/scijava/io/console/OpenArgument.java b/src/main/java/org/scijava/io/console/OpenArgument.java index 1f5457e6b..ea7385683 100644 --- a/src/main/java/org/scijava/io/console/OpenArgument.java +++ b/src/main/java/org/scijava/io/console/OpenArgument.java @@ -37,6 +37,7 @@ import org.scijava.console.AbstractConsoleArgument; import org.scijava.console.ConsoleArgument; import org.scijava.display.DisplayService; +import org.scijava.io.FileLocation; import org.scijava.io.IOService; import org.scijava.log.LogService; import org.scijava.plugin.Parameter; @@ -69,7 +70,7 @@ public void handle(final LinkedList args) { final String source = args.removeFirst(); try { - final Object o = ioService.open(source); + final Object o = ioService.open(new FileLocation(source)); displayService.createDisplay(o); } catch (IOException exc) { diff --git a/src/main/java/org/scijava/io/event/DataOpenedEvent.java b/src/main/java/org/scijava/io/event/DataOpenedEvent.java index 03028ecb2..03f0abb8d 100644 --- a/src/main/java/org/scijava/io/event/DataOpenedEvent.java +++ b/src/main/java/org/scijava/io/event/DataOpenedEvent.java @@ -31,22 +31,17 @@ package org.scijava.io.event; +import org.scijava.io.Location; + /** - * An event indicating that data has been opened from a source. + * An event indicating that data has been opened from a location. * * @author Curtis Rueden */ public class DataOpenedEvent extends IOEvent { - public DataOpenedEvent(final String source, final Object data) { - super(source, data); - } - - // -- DataOpenedEvent methods -- - - /** Gets the source from which data was opened. */ - public String getSource() { - return getDescriptor(); + public DataOpenedEvent(final Location location, final Object data) { + super(location, data); } } diff --git a/src/main/java/org/scijava/io/event/DataSavedEvent.java b/src/main/java/org/scijava/io/event/DataSavedEvent.java index 8f5f2955a..a9be0ba01 100644 --- a/src/main/java/org/scijava/io/event/DataSavedEvent.java +++ b/src/main/java/org/scijava/io/event/DataSavedEvent.java @@ -31,6 +31,8 @@ package org.scijava.io.event; +import org.scijava.io.Location; + /** * An event indicating that data has been saved to a destination. * @@ -38,15 +40,8 @@ */ public class DataSavedEvent extends IOEvent { - public DataSavedEvent(final String destination, final Object data) { + public DataSavedEvent(final Location destination, final Object data) { super(destination, data); } - // -- DataSavedEvent methods -- - - /** Gets the destination to which data was saved. */ - public String getDestination() { - return getDescriptor(); - } - } diff --git a/src/main/java/org/scijava/io/event/IOEvent.java b/src/main/java/org/scijava/io/event/IOEvent.java index d678ae19c..1ecbc062b 100644 --- a/src/main/java/org/scijava/io/event/IOEvent.java +++ b/src/main/java/org/scijava/io/event/IOEvent.java @@ -32,6 +32,7 @@ package org.scijava.io.event; import org.scijava.event.SciJavaEvent; +import org.scijava.io.Location; /** * An event indicating that I/O (e.g., opening or saving) has occurred. @@ -40,20 +41,20 @@ */ public abstract class IOEvent extends SciJavaEvent { - /** The data descriptor (source or destination). */ - private final String descriptor; + /** The data location (source or destination). */ + private final Location location; /** The data for which I/O took place. */ private final Object data; - public IOEvent(final String descriptor, final Object data) { - this.descriptor = descriptor; + public IOEvent(final Location location, final Object data) { + this.location = location; this.data = data; } - /** Gets the data descriptor (source or destination). */ - public String getDescriptor() { - return descriptor; + /** Gets the data location (source or destination). */ + public Location getLocation() { + return location; } /** Gets the data for which I/O took place. */ @@ -65,7 +66,8 @@ public Object getData() { @Override public String toString() { - return super.toString() + "\n\tdescriptor = " + data + "\n\tdata = " + data; + return super.toString() + "\n\tlocation = " + location + "\n\tdata = " + + data; } } diff --git a/src/main/java/org/scijava/script/io/ScriptIOPlugin.java b/src/main/java/org/scijava/script/io/ScriptIOPlugin.java index 4338b2f0d..2f689a262 100644 --- a/src/main/java/org/scijava/script/io/ScriptIOPlugin.java +++ b/src/main/java/org/scijava/script/io/ScriptIOPlugin.java @@ -34,7 +34,9 @@ import java.io.IOException; import org.scijava.io.AbstractIOPlugin; +import org.scijava.io.FileLocation; import org.scijava.io.IOPlugin; +import org.scijava.io.Location; import org.scijava.plugin.Parameter; import org.scijava.plugin.Plugin; import org.scijava.script.ScriptService; @@ -59,13 +61,16 @@ public Class getDataType() { } @Override - public boolean supportsOpen(final String source) { + public boolean supportsOpen(final Location source) { if (scriptService == null) return false; // no service for opening scripts - return scriptService.canHandleFile(source); + // TODO: Update ScriptService to use Location instead of File. + if (!(source instanceof FileLocation)) return false; + final FileLocation loc = (FileLocation) source; + return scriptService.canHandleFile(loc.getFile()); } @Override - public String open(final String source) throws IOException { + public String open(final Location source) throws IOException { if (scriptService == null) return null; // no service for opening scripts // TODO: Use the script service to open the file in the script editor. return null; diff --git a/src/main/java/org/scijava/text/io/TextIOPlugin.java b/src/main/java/org/scijava/text/io/TextIOPlugin.java index 2dfbee160..4085cf94d 100644 --- a/src/main/java/org/scijava/text/io/TextIOPlugin.java +++ b/src/main/java/org/scijava/text/io/TextIOPlugin.java @@ -31,12 +31,13 @@ package org.scijava.text.io; -import java.io.File; import java.io.IOException; import org.scijava.Priority; import org.scijava.io.AbstractIOPlugin; +import org.scijava.io.FileLocation; import org.scijava.io.IOPlugin; +import org.scijava.io.Location; import org.scijava.plugin.Parameter; import org.scijava.plugin.Plugin; import org.scijava.text.TextService; @@ -61,15 +62,19 @@ public Class getDataType() { } @Override - public boolean supportsOpen(final String source) { + public boolean supportsOpen(final Location source) { if (textService == null) return false; // no service for opening text files - return textService.supports(new File(source)); + if (!(source instanceof FileLocation)) return false; + final FileLocation loc = (FileLocation) source; + return textService.supports(loc.getFile()); } @Override - public String open(final String source) throws IOException { + public String open(final Location source) throws IOException { if (textService == null) return null; // no service for opening text files - return textService.asHTML(new File(source)); + if (!(source instanceof FileLocation)) throw new IllegalArgumentException(); + final FileLocation loc = (FileLocation) source; + return textService.asHTML(loc.getFile()); } } diff --git a/src/main/java/org/scijava/ui/dnd/FileDragAndDropHandler.java b/src/main/java/org/scijava/ui/dnd/FileDragAndDropHandler.java index e1e2d4603..274ea4694 100644 --- a/src/main/java/org/scijava/ui/dnd/FileDragAndDropHandler.java +++ b/src/main/java/org/scijava/ui/dnd/FileDragAndDropHandler.java @@ -37,6 +37,7 @@ import org.scijava.Priority; import org.scijava.display.Display; import org.scijava.display.DisplayService; +import org.scijava.io.FileLocation; import org.scijava.io.IOService; import org.scijava.log.LogService; import org.scijava.plugin.Parameter; @@ -70,7 +71,8 @@ public boolean supports(final File file) { if (!super.supports(file)) return false; // verify that the file can be opened somehow - return ioService.getOpener(file.getAbsolutePath()) != null; + final FileLocation loc = new FileLocation(file); + return ioService.getOpener(loc) != null; } @Override @@ -80,13 +82,12 @@ public boolean drop(final File file, final Display display) { if (file == null) return true; // trivial case // load the data - final String filename = file.getAbsolutePath(); final Object data; try { - data = ioService.open(filename); + data = ioService.open(new FileLocation(file)); } catch (final IOException exc) { - if (log != null) log.error("Error opening file: " + filename, exc); + if (log != null) log.error("Error opening file: " + file, exc); return false; }