- *
+ *
* @param source The source (e.g., file path) from which to data should be
* loaded.
* @return An object representing the loaded data, or null if the source is
@@ -86,6 +104,22 @@ default IOPlugin getSaver(final D data, final String destination) {
*/
Object open(String source) throws IOException;
+ /**
+ * Loads data from the given location.
+ *
+ * The opener to use is automatically determined based on available
+ * {@link IOPlugin}s; see {@link #getOpener(Location)}.
+ *
+ *
+ * @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.
+ */
+ default Object open(Location source) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
/**
* Saves data to the given destination. The nature of the destination is left
* intentionally general, but the most common example is a file path.
@@ -93,7 +127,7 @@ default IOPlugin getSaver(final D data, final String destination) {
* The saver to use is automatically determined based on available
* {@link IOPlugin}s; see {@link #getSaver(Object, String)}.
*
- *
+ *
* @param data The data to be saved to the destination.
* @param destination The destination (e.g., file path) to which data should
* be saved.
@@ -101,6 +135,21 @@ default IOPlugin getSaver(final D data, final String destination) {
*/
void save(Object data, String destination) throws IOException;
+ /**
+ * Saves data to the given location.
+ *
+ * The saver to use is automatically determined based on available
+ * {@link IOPlugin}s; see {@link #getSaver(Object, Location)}.
+ *
+ *
+ * @param data The data to be saved to the destination.
+ * @param destination The destination location to which data should be saved.
+ * @throws IOException if something goes wrong saving the data.
+ */
+ default void save(Object data, Location destination) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
// -- HandlerService methods --
@Override
@@ -110,7 +159,7 @@ default Class> getPluginType() {
}
@Override
- default Class getType() {
- return String.class;
+ default Class getType() {
+ return Location.class;
}
}
diff --git a/src/main/java/org/scijava/io/event/DataOpenedEvent.java b/src/main/java/org/scijava/io/event/DataOpenedEvent.java
index 7af006c5a..2d9c50929 100644
--- a/src/main/java/org/scijava/io/event/DataOpenedEvent.java
+++ b/src/main/java/org/scijava/io/event/DataOpenedEvent.java
@@ -29,22 +29,40 @@
package org.scijava.io.event;
+
+import org.scijava.io.location.FileLocation;
+import org.scijava.io.location.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);
+ public DataOpenedEvent(final Location location, final Object data) {
+ super(location, data);
}
- // -- DataOpenedEvent methods --
+ /**
+ * @deprecated use {@link #DataOpenedEvent(Location, Object)} instead
+ */
+ @Deprecated
+ public DataOpenedEvent(final String source, final Object data) {
+ this(new FileLocation(source), data);
+ }
- /** Gets the source from which data was opened. */
+ /**
+ * @deprecated use {@link #getLocation} instead
+ */
+ @Deprecated
public String getSource() {
- return getDescriptor();
+ try {
+ FileLocation fileLocation = (FileLocation) getLocation();
+ return fileLocation.getFile().getAbsolutePath();
+ } catch(ClassCastException e) {
+ return getLocation().getURI().toString();
+ }
}
}
diff --git a/src/main/java/org/scijava/io/event/DataSavedEvent.java b/src/main/java/org/scijava/io/event/DataSavedEvent.java
index cd6d22439..600eccafc 100644
--- a/src/main/java/org/scijava/io/event/DataSavedEvent.java
+++ b/src/main/java/org/scijava/io/event/DataSavedEvent.java
@@ -29,6 +29,10 @@
package org.scijava.io.event;
+
+import org.scijava.io.location.FileLocation;
+import org.scijava.io.location.Location;
+
/**
* An event indicating that data has been saved to a destination.
*
@@ -36,15 +40,28 @@
*/
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 --
+ /**
+ * @deprecated use {@link #DataSavedEvent(Location, Object)} instead
+ */
+ @Deprecated
+ public DataSavedEvent(final String destination, final Object data) {
+ this(new FileLocation(destination), data);
+ }
- /** Gets the destination to which data was saved. */
+ /**
+ * @deprecated use {@link #getLocation} instead
+ */
+ @Deprecated
public String getDestination() {
- return getDescriptor();
+ try {
+ FileLocation fileLocation = (FileLocation) getLocation();
+ return fileLocation.getFile().getAbsolutePath();
+ } catch(ClassCastException e) {
+ return getLocation().getURI().toString();
+ }
}
-
}
diff --git a/src/main/java/org/scijava/io/event/IOEvent.java b/src/main/java/org/scijava/io/event/IOEvent.java
index 1a62e6fca..89bfe0f27 100644
--- a/src/main/java/org/scijava/io/event/IOEvent.java
+++ b/src/main/java/org/scijava/io/event/IOEvent.java
@@ -30,6 +30,8 @@
package org.scijava.io.event;
import org.scijava.event.SciJavaEvent;
+import org.scijava.io.location.FileLocation;
+import org.scijava.io.location.Location;
/**
* An event indicating that I/O (e.g., opening or saving) has occurred.
@@ -38,20 +40,28 @@
*/
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;
+ /**
+ * @deprecated use {@link #IOEvent(Location, Object)} instead
+ */
+ @Deprecated
public IOEvent(final String descriptor, final Object data) {
- this.descriptor = descriptor;
+ this(new FileLocation(descriptor), data);
+ }
+
+ 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. */
@@ -63,7 +73,21 @@ 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;
+ }
+
+ /**
+ * @deprecated use {@link #getLocation()} instead
+ */
+ @Deprecated
+ public String getDescriptor() {
+ try {
+ FileLocation fileLocation = (FileLocation) getLocation();
+ return fileLocation.getFile().getAbsolutePath();
+ } catch(ClassCastException e) {
+ return getLocation().getURI().toString();
+ }
}
}
diff --git a/src/main/java/org/scijava/script/io/ScriptIOPlugin.java b/src/main/java/org/scijava/script/io/ScriptIOPlugin.java
index 56d201770..f881dc429 100644
--- a/src/main/java/org/scijava/script/io/ScriptIOPlugin.java
+++ b/src/main/java/org/scijava/script/io/ScriptIOPlugin.java
@@ -33,6 +33,8 @@
import org.scijava.io.AbstractIOPlugin;
import org.scijava.io.IOPlugin;
+import org.scijava.io.location.FileLocation;
+import org.scijava.io.location.Location;
import org.scijava.plugin.Parameter;
import org.scijava.script.ScriptService;
@@ -55,13 +57,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 3d2c64172..523ff2c34 100644
--- a/src/main/java/org/scijava/text/io/TextIOPlugin.java
+++ b/src/main/java/org/scijava/text/io/TextIOPlugin.java
@@ -29,12 +29,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.IOPlugin;
+import org.scijava.io.location.FileLocation;
+import org.scijava.io.location.Location;
import org.scijava.plugin.Parameter;
import org.scijava.plugin.Plugin;
import org.scijava.text.TextService;
@@ -59,15 +60,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 2076c6a20..02289b6e4 100644
--- a/src/main/java/org/scijava/ui/dnd/FileDragAndDropHandler.java
+++ b/src/main/java/org/scijava/ui/dnd/FileDragAndDropHandler.java
@@ -36,6 +36,7 @@
import org.scijava.display.Display;
import org.scijava.display.DisplayService;
import org.scijava.io.IOService;
+import org.scijava.io.location.FileLocation;
import org.scijava.log.LogService;
import org.scijava.plugin.Parameter;
import org.scijava.plugin.Plugin;
@@ -68,7 +69,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
@@ -78,13 +80,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;
}
diff --git a/src/test/java/org/scijava/io/IOServiceTest.java b/src/test/java/org/scijava/io/IOServiceTest.java
new file mode 100644
index 000000000..bd3f7a3af
--- /dev/null
+++ b/src/test/java/org/scijava/io/IOServiceTest.java
@@ -0,0 +1,53 @@
+package org.scijava.io;
+
+import org.junit.Test;
+import org.scijava.Context;
+import org.scijava.io.location.FileLocation;
+import org.scijava.plugin.PluginInfo;
+import org.scijava.text.AbstractTextFormat;
+import org.scijava.text.TextFormat;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class IOServiceTest {
+
+ @Test
+ public void testTextFile() throws IOException {
+ // create context, add dummy text format
+ final Context ctx = new Context();
+ ctx.getPluginIndex().add(new PluginInfo<>(DummyTextFormat.class, TextFormat.class));
+ final IOService io = ctx.getService(IOService.class);
+
+ // open text file from resources as String
+ String localFile = getClass().getResource("test.txt").getPath();
+ Object obj = io.open(localFile);
+ assertNotNull(obj);
+ String content = obj.toString();
+ assertTrue(content.contains("content"));
+
+ // open text file from resources as FileLocation
+ obj = io.open(new FileLocation(localFile));
+ assertNotNull(obj);
+ assertEquals(content, obj.toString());
+ }
+
+
+ public static class DummyTextFormat extends AbstractTextFormat {
+
+ @Override
+ public List getExtensions() {
+ return Collections.singletonList("txt");
+ }
+
+ @Override
+ public String asHTML(String text) {
+ return text;
+ }
+ }
+}
diff --git a/src/test/java/org/scijava/io/event/DataEventTest.java b/src/test/java/org/scijava/io/event/DataEventTest.java
new file mode 100644
index 000000000..8e2ce0aa0
--- /dev/null
+++ b/src/test/java/org/scijava/io/event/DataEventTest.java
@@ -0,0 +1,25 @@
+package org.scijava.io.event;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class DataEventTest {
+
+ @Test
+ public void testDeprecatedMethods() {
+ String localPath = "/local/absolute/path.txt";
+ Object obj = null;
+ DataOpenedEvent openedEvent = new DataOpenedEvent(localPath, obj);
+ DataSavedEvent savedEvent = new DataSavedEvent(localPath, obj);
+ assertEquals(localPath, openedEvent.getSource());
+ assertEquals(localPath, savedEvent.getDestination());
+
+// String remotepath = "https://remote.org/path.txt";
+// openedEvent = new DataOpenedEvent(remotepath, obj);
+// savedEvent = new DataSavedEvent(remotepath, obj);
+// assertEquals(remotepath, openedEvent.getSource());
+// assertEquals(remotepath, savedEvent.getDestination());
+ }
+
+}
diff --git a/src/test/resources/org/scijava/io/test.txt b/src/test/resources/org/scijava/io/test.txt
new file mode 100644
index 000000000..d95f3ad14
--- /dev/null
+++ b/src/test/resources/org/scijava/io/test.txt
@@ -0,0 +1 @@
+content