Skip to content

Commit b7285c5

Browse files
ctruedenfrauzufall
andcommitted
Use Location, not String, in the I/O API
This is much more elegant. It is also a very breaking change. Co-authored-by: Deborah Schmidt <mail@frauzufall.de>
1 parent a5993b3 commit b7285c5

File tree

14 files changed

+256
-57
lines changed

14 files changed

+256
-57
lines changed

src/main/java/org/scijava/io/AbstractIOPlugin.java

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,50 @@
2929

3030
package org.scijava.io;
3131

32+
import org.scijava.io.location.Location;
33+
import org.scijava.io.location.LocationService;
3234
import org.scijava.plugin.AbstractHandlerPlugin;
35+
import org.scijava.plugin.Parameter;
36+
37+
import java.io.IOException;
38+
import java.net.URISyntaxException;
3339

3440
/**
3541
* Abstract base class for {@link IOPlugin}s.
3642
*
3743
* @author Curtis Rueden
3844
*/
39-
public abstract class AbstractIOPlugin<D> extends AbstractHandlerPlugin<String>
40-
implements IOPlugin<D>
45+
public abstract class AbstractIOPlugin<D> extends
46+
AbstractHandlerPlugin<Location> implements IOPlugin<D>
4147
{
42-
// NB: No implementation needed.
48+
49+
@Parameter
50+
private LocationService locationService;
51+
52+
@Override
53+
public boolean supportsOpen(final String source) {
54+
try {
55+
return supportsOpen(locationService.resolve(source));
56+
} catch (URISyntaxException e) {
57+
return false;
58+
}
59+
}
60+
61+
@Override
62+
public boolean supportsSave(final String destination) {
63+
try {
64+
return supportsSave(locationService.resolve(destination));
65+
} catch (URISyntaxException e) {
66+
return false;
67+
}
68+
}
69+
70+
@Override
71+
public void save(final D data, final String destination) throws IOException {
72+
try {
73+
save(data, locationService.resolve(destination));
74+
} catch (URISyntaxException e) {
75+
throw new IOException(e);
76+
}
77+
}
4378
}

src/main/java/org/scijava/io/DefaultIOService.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,13 @@
3030
package org.scijava.io;
3131

3232
import java.io.IOException;
33+
import java.net.URISyntaxException;
3334

3435
import org.scijava.event.EventService;
3536
import org.scijava.io.event.DataOpenedEvent;
3637
import org.scijava.io.event.DataSavedEvent;
38+
import org.scijava.io.location.Location;
39+
import org.scijava.io.location.LocationService;
3740
import org.scijava.log.LogService;
3841
import org.scijava.plugin.AbstractHandlerService;
3942
import org.scijava.plugin.Parameter;
@@ -47,7 +50,7 @@
4750
*/
4851
@Plugin(type = Service.class)
4952
public final class DefaultIOService
50-
extends AbstractHandlerService<String, IOPlugin<?>> implements IOService
53+
extends AbstractHandlerService<Location, IOPlugin<?>> implements IOService
5154
{
5255

5356
@Parameter
@@ -56,10 +59,31 @@ public final class DefaultIOService
5659
@Parameter
5760
private EventService eventService;
5861

59-
// -- IOService methods --
62+
@Parameter
63+
private LocationService locationService;
6064

6165
@Override
6266
public Object open(final String source) throws IOException {
67+
try {
68+
return open(locationService.resolve(source));
69+
} catch (URISyntaxException e) {
70+
throw new IOException(e);
71+
}
72+
}
73+
74+
@Override
75+
public void save(final Object data, final String destination)
76+
throws IOException
77+
{
78+
try {
79+
save(data, locationService.resolve(destination));
80+
} catch (URISyntaxException e) {
81+
throw new IOException(e);
82+
}
83+
}
84+
85+
@Override
86+
public Object open(final Location source) throws IOException {
6387
final IOPlugin<?> opener = getOpener(source);
6488
if (opener == null) {
6589
log.error("No opener IOPlugin found for " + source + ".");
@@ -77,7 +101,7 @@ public Object open(final String source) throws IOException {
77101
}
78102

79103
@Override
80-
public void save(final Object data, final String destination)
104+
public void save(final Object data, final Location destination)
81105
throws IOException
82106
{
83107
final IOPlugin<Object> saver = getSaver(data, destination);

src/main/java/org/scijava/io/DefaultRecentFileService.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import org.scijava.event.EventHandler;
4242
import org.scijava.event.EventService;
4343
import org.scijava.io.event.IOEvent;
44+
import org.scijava.io.location.FileLocation;
45+
import org.scijava.io.location.Location;
4446
import org.scijava.menu.MenuConstants;
4547
import org.scijava.module.ModuleInfo;
4648
import org.scijava.module.ModuleService;
@@ -181,7 +183,10 @@ public void dispose() {
181183

182184
@EventHandler
183185
protected void onEvent(final IOEvent event) {
184-
add(event.getDescriptor());
186+
final Location loc = event.getLocation();
187+
if (!(loc instanceof FileLocation)) return;
188+
final FileLocation fileLoc = (FileLocation) loc;
189+
add(fileLoc.getFile().getPath());
185190
}
186191

187192
// -- Helper methods --

src/main/java/org/scijava/io/IOPlugin.java

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
import java.io.IOException;
3333

34+
import org.scijava.io.location.FileLocation;
35+
import org.scijava.io.location.Location;
3436
import org.scijava.plugin.HandlerPlugin;
3537
import org.scijava.plugin.Plugin;
3638

@@ -48,52 +50,74 @@
4850
* @see Plugin
4951
* @see IOService
5052
*/
51-
public interface IOPlugin<D> extends HandlerPlugin<String> {
53+
public interface IOPlugin<D> extends HandlerPlugin<Location> {
5254

5355
/** The type of data opened and/or saved by the plugin. */
5456
Class<D> getDataType();
5557

5658
/** Checks whether the I/O plugin can open data from the given source. */
5759
@SuppressWarnings("unused")
5860
default boolean supportsOpen(final String source) {
61+
return supportsOpen(new FileLocation(source));
62+
}
63+
64+
/** Checks whether the I/O plugin can open data from the given location. */
65+
default boolean supportsOpen(Location source) {
5966
return false;
6067
}
6168

6269
/** Checks whether the I/O plugin can save data to the given destination. */
6370
@SuppressWarnings("unused")
6471
default boolean supportsSave(final String destination) {
72+
return supportsSave(new FileLocation(destination));
73+
}
74+
75+
/** Checks whether the I/O plugin can save data to the given location. */
76+
default boolean supportsSave(Location destination) {
6577
return false;
6678
}
6779

6880
/**
6981
* Checks whether the I/O plugin can save the given data to the specified
70-
* destination.
82+
* location.
7183
*/
7284
default boolean supportsSave(final Object data, final String destination) {
7385
return supportsSave(destination) && getDataType().isInstance(data);
7486
}
7587

88+
default boolean supportsSave(Object data, Location destination) {
89+
return supportsSave(destination) && getDataType().isInstance(data);
90+
}
91+
7692
/** Opens data from the given source. */
7793
@SuppressWarnings("unused")
7894
default D open(final String source) throws IOException {
7995
throw new UnsupportedOperationException();
8096
}
8197

98+
/** Opens data from the given location. */
99+
default D open(Location source) throws IOException {
100+
throw new UnsupportedOperationException();
101+
}
82102
/** Saves the given data to the specified destination. */
83103
@SuppressWarnings("unused")
84104
default void save(final D data, final String destination) throws IOException {
105+
save(data, new FileLocation(destination));
106+
}
107+
108+
/** Saves the given data to the specified location. */
109+
default void save(D data, Location destination) throws IOException {
85110
throw new UnsupportedOperationException();
86111
}
87112

88113
// -- Typed methods --
89114

90-
@Override
91115
default boolean supports(final String descriptor) {
92116
return supportsOpen(descriptor) || supportsSave(descriptor);
93117
}
94118

95119
@Override
96-
default Class<String> getType() {
97-
return String.class;
120+
default Class<Location> getType() {
121+
return Location.class;
98122
}
99123
}

src/main/java/org/scijava/io/IOService.java

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
import java.io.IOException;
3333

34+
import org.scijava.io.location.FileLocation;
35+
import org.scijava.io.location.Location;
3436
import org.scijava.plugin.HandlerService;
3537
import org.scijava.service.SciJavaService;
3638

@@ -39,15 +41,23 @@
3941
*
4042
* @author Curtis Rueden
4143
*/
42-
public interface IOService extends HandlerService<String, IOPlugin<?>>,
44+
public interface IOService extends HandlerService<Location, IOPlugin<?>>,
4345
SciJavaService
4446
{
4547

4648
/**
4749
* Gets the most appropriate {@link IOPlugin} for opening data from the given
48-
* source.
50+
* location.
4951
*/
5052
default IOPlugin<?> getOpener(final String source) {
53+
return getOpener(new FileLocation(source));
54+
}
55+
56+
/**
57+
* Gets the most appropriate {@link IOPlugin} for opening data from the given
58+
* location.
59+
*/
60+
default IOPlugin<?> getOpener(Location source) {
5161
for (final IOPlugin<?> handler : getInstances()) {
5262
if (handler.supportsOpen(source)) return handler;
5363
}
@@ -56,9 +66,17 @@ default IOPlugin<?> getOpener(final String source) {
5666

5767
/**
5868
* Gets the most appropriate {@link IOPlugin} for saving data to the given
59-
* destination.
69+
* location.
6070
*/
6171
default <D> IOPlugin<D> getSaver(final D data, final String destination) {
72+
return getSaver(data, new FileLocation(destination));
73+
}
74+
75+
/**
76+
* Gets the most appropriate {@link IOPlugin} for saving data to the given
77+
* location.
78+
*/
79+
default <D> IOPlugin<D> getSaver(D data, Location destination) {
6280
for (final IOPlugin<?> handler : getInstances()) {
6381
if (handler.supportsSave(data, destination)) {
6482
@SuppressWarnings("unchecked")
@@ -77,7 +95,7 @@ default <D> IOPlugin<D> getSaver(final D data, final String destination) {
7795
* The opener to use is automatically determined based on available
7896
* {@link IOPlugin}s; see {@link #getOpener(String)}.
7997
* </p>
80-
*
98+
*
8199
* @param source The source (e.g., file path) from which to data should be
82100
* loaded.
83101
* @return An object representing the loaded data, or null if the source is
@@ -86,21 +104,48 @@ default <D> IOPlugin<D> getSaver(final D data, final String destination) {
86104
*/
87105
Object open(String source) throws IOException;
88106

107+
/**
108+
* Loads data from the given location.
109+
* <p>
110+
* The opener to use is automatically determined based on available
111+
* {@link IOPlugin}s; see {@link #getOpener(Location)}.
112+
* </p>
113+
*
114+
* @param source The location from which to data should be loaded.
115+
* @return An object representing the loaded data, or null if the source is
116+
* not supported.
117+
* @throws IOException if something goes wrong loading the data.
118+
*/
119+
Object open(Location source) throws IOException;
120+
89121
/**
90122
* Saves data to the given destination. The nature of the destination is left
91123
* intentionally general, but the most common example is a file path.
92124
* <p>
93125
* The saver to use is automatically determined based on available
94126
* {@link IOPlugin}s; see {@link #getSaver(Object, String)}.
95127
* </p>
96-
*
128+
*
97129
* @param data The data to be saved to the destination.
98130
* @param destination The destination (e.g., file path) to which data should
99131
* be saved.
100132
* @throws IOException if something goes wrong saving the data.
101133
*/
102134
void save(Object data, String destination) throws IOException;
103135

136+
/**
137+
* Saves data to the given location.
138+
* <p>
139+
* The saver to use is automatically determined based on available
140+
* {@link IOPlugin}s; see {@link #getSaver(Object, Location)}.
141+
* </p>
142+
*
143+
* @param data The data to be saved to the destination.
144+
* @param destination The destination location to which data should be saved.
145+
* @throws IOException if something goes wrong saving the data.
146+
*/
147+
void save(Object data, Location destination) throws IOException;
148+
104149
// -- HandlerService methods --
105150

106151
@Override
@@ -110,7 +155,7 @@ default Class<IOPlugin<?>> getPluginType() {
110155
}
111156

112157
@Override
113-
default Class<String> getType() {
114-
return String.class;
158+
default Class<Location> getType() {
159+
return Location.class;
115160
}
116161
}

src/main/java/org/scijava/io/event/DataOpenedEvent.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,18 @@
2929

3030
package org.scijava.io.event;
3131

32+
33+
import org.scijava.io.location.Location;
34+
3235
/**
33-
* An event indicating that data has been opened from a source.
36+
* An event indicating that data has been opened from a location.
3437
*
3538
* @author Curtis Rueden
3639
*/
3740
public class DataOpenedEvent extends IOEvent {
3841

39-
public DataOpenedEvent(final String source, final Object data) {
40-
super(source, data);
41-
}
42-
43-
// -- DataOpenedEvent methods --
44-
45-
/** Gets the source from which data was opened. */
46-
public String getSource() {
47-
return getDescriptor();
42+
public DataOpenedEvent(final Location location, final Object data) {
43+
super(location, data);
4844
}
4945

5046
}

0 commit comments

Comments
 (0)