Skip to content

Commit d387414

Browse files
authored
Merge pull request #396 from scijava/typedioservice
TypedIOService interface
2 parents 6ada478 + bba50af commit d387414

File tree

6 files changed

+441
-0
lines changed

6 files changed

+441
-0
lines changed
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2020 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+
30+
package org.scijava.io;
31+
32+
import org.scijava.io.location.Location;
33+
import org.scijava.io.location.LocationService;
34+
import org.scijava.plugin.AbstractHandlerService;
35+
import org.scijava.plugin.Parameter;
36+
37+
import java.io.IOException;
38+
import java.net.URISyntaxException;
39+
40+
/**
41+
* Abstract base class for typed {@link IOPlugin}s.
42+
*
43+
* @author Curtis Rueden
44+
* @author Deborah Schmidt
45+
*/
46+
public abstract class AbstractTypedIOService<D> extends AbstractHandlerService<Location, IOPlugin<D>> implements TypedIOService<D>
47+
{
48+
49+
@Parameter
50+
private LocationService locationService;
51+
52+
@Parameter
53+
private IOService ioService;
54+
55+
@Override
56+
public D open(String source) throws IOException {
57+
try {
58+
return open(locationService.resolve(source));
59+
} catch (URISyntaxException e) {
60+
throw new IOException(e);
61+
}
62+
}
63+
64+
@Override
65+
public D open(Location source) throws IOException {
66+
IOPlugin<?> opener = ioService().getOpener(source);
67+
try {
68+
Class<D> ignored = (Class<D>) opener.getDataType();
69+
return (D) opener.open(source);
70+
}
71+
catch(ClassCastException e) {
72+
throw new UnsupportedOperationException("No compatible opener found.");
73+
}
74+
}
75+
76+
@Override
77+
public void save(D data, String destination) throws IOException {
78+
try {
79+
save(data, locationService.resolve(destination));
80+
} catch (URISyntaxException e) {
81+
throw new IOException(e);
82+
}
83+
}
84+
85+
@Override
86+
public void save(D data, Location destination) throws IOException {
87+
IOPlugin<D> saver = ioService().getSaver(data, destination);
88+
if (saver != null) {
89+
saver.save(data, destination);
90+
}
91+
else {
92+
throw new UnsupportedOperationException("No compatible saver found.");
93+
}
94+
}
95+
96+
@Override
97+
public boolean canOpen(String source) {
98+
try {
99+
return canOpen(locationService.resolve(source));
100+
} catch (URISyntaxException e) {
101+
return false;
102+
}
103+
}
104+
105+
@Override
106+
public boolean canOpen(Location source) {
107+
IOPlugin<?> opener = ioService().getOpener(source);
108+
if (opener == null) return false;
109+
try {
110+
Class<D> ignored = (Class<D>) (opener.getDataType());
111+
return true;
112+
} catch(ClassCastException e) {
113+
return false;
114+
}
115+
}
116+
117+
@Override
118+
public boolean canSave(D data, String source) {
119+
try {
120+
return canSave(data, locationService.resolve(source));
121+
} catch (URISyntaxException e) {
122+
return false;
123+
}
124+
}
125+
126+
@Override
127+
public boolean canSave(D data, Location destination) {
128+
IOPlugin<D> saver = ioService.getSaver(data, destination);
129+
if (saver == null) return false;
130+
return saver.supportsSave(destination);
131+
}
132+
133+
protected LocationService locationService() {
134+
return locationService;
135+
}
136+
137+
protected IOService ioService() {
138+
return ioService;
139+
}
140+
}
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2020 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+
30+
package org.scijava.io;
31+
32+
import java.io.IOException;
33+
34+
import org.scijava.io.location.FileLocation;
35+
import org.scijava.io.location.Location;
36+
import org.scijava.plugin.HandlerService;
37+
import org.scijava.service.SciJavaService;
38+
39+
/**
40+
* Interface for high-level data I/O: opening and saving data of a specific type.
41+
*
42+
* @author Curtis Rueden
43+
* @author Deborah Schmidt
44+
*/
45+
public interface TypedIOService<D> extends HandlerService<Location, IOPlugin<D>>,
46+
SciJavaService
47+
{
48+
49+
/**
50+
* Gets the most appropriate {@link IOPlugin} for opening data from the given
51+
* location.
52+
*/
53+
default IOPlugin<D> getOpener(final String source) {
54+
return getOpener(new FileLocation(source));
55+
}
56+
57+
/**
58+
* Gets the most appropriate {@link IOPlugin} for opening data from the given
59+
* location.
60+
*/
61+
default IOPlugin<D> getOpener(Location source) {
62+
for (final IOPlugin<D> handler : getInstances()) {
63+
if (handler.supportsOpen(source)) return handler;
64+
}
65+
return null;
66+
}
67+
68+
/**
69+
* Gets the most appropriate {@link IOPlugin} for saving data to the given
70+
* location.
71+
*/
72+
default IOPlugin<D> getSaver(final D data, final String destination) {
73+
return getSaver(data, new FileLocation(destination));
74+
}
75+
76+
/**
77+
* Gets the most appropriate {@link IOPlugin} for saving data to the given
78+
* location.
79+
*/
80+
default IOPlugin<D> getSaver(D data, Location destination) {
81+
for (final IOPlugin<?> handler : getInstances()) {
82+
if (handler.supportsSave(data, destination)) {
83+
return (IOPlugin<D>) handler;
84+
}
85+
}
86+
return null;
87+
}
88+
89+
/**
90+
* Loads data from the given source. For extensibility, the nature of the
91+
* source is left intentionally general, but two common examples include file
92+
* paths and URLs.
93+
* <p>
94+
* The opener to use is automatically determined based on available
95+
* {@link IOPlugin}s; see {@link #getOpener(String)}.
96+
* </p>
97+
*
98+
* @param source The source (e.g., file path) from which to data should be
99+
* loaded.
100+
* @return An object representing the loaded data, or null if the source is
101+
* not supported.
102+
* @throws IOException if something goes wrong loading the data.
103+
*/
104+
D open(String source) throws IOException;
105+
106+
/**
107+
* Loads data from the given location.
108+
* <p>
109+
* The opener to use is automatically determined based on available
110+
* {@link IOPlugin}s; see {@link #getOpener(Location)}.
111+
* </p>
112+
*
113+
* @param source The location from which to data should be loaded.
114+
* @return An object representing the loaded data, or null if the source is
115+
* not supported.
116+
* @throws IOException if something goes wrong loading the data.
117+
*/
118+
D open(Location source) throws IOException;
119+
120+
/**
121+
* Saves data to the given destination. The nature of the destination is left
122+
* intentionally general, but the most common example is a file path.
123+
* <p>
124+
* The saver to use is automatically determined based on available
125+
* {@link IOPlugin}s; see {@link #getSaver(Object, String)}.
126+
* </p>
127+
*
128+
* @param data The data to be saved to the destination.
129+
* @param destination The destination (e.g., file path) to which data should
130+
* be saved.
131+
* @throws IOException if something goes wrong saving the data.
132+
*/
133+
void save(D data, String destination) throws IOException;
134+
135+
/**
136+
* Saves data to the given location.
137+
* <p>
138+
* The saver to use is automatically determined based on available
139+
* {@link IOPlugin}s; see {@link #getSaver(Object, Location)}.
140+
* </p>
141+
*
142+
* @param data The data to be saved to the destination.
143+
* @param destination The destination location to which data should be saved.
144+
* @throws IOException if something goes wrong saving the data.
145+
*/
146+
void save(D data, Location destination) throws IOException;
147+
148+
boolean canOpen(String source);
149+
150+
boolean canOpen(Location source);
151+
152+
boolean canSave(D data, String destination);
153+
154+
boolean canSave(D data, Location destination);
155+
156+
// -- HandlerService methods --
157+
158+
@Override
159+
@SuppressWarnings({ "rawtypes", "unchecked" })
160+
default Class<IOPlugin<D>> getPluginType() {
161+
return (Class) IOPlugin.class;
162+
}
163+
164+
@Override
165+
default Class<Location> getType() {
166+
return Location.class;
167+
}
168+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2020 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+
30+
package org.scijava.text.io;
31+
32+
import org.scijava.io.AbstractTypedIOService;
33+
import org.scijava.plugin.Plugin;
34+
import org.scijava.service.Service;
35+
36+
/**
37+
* Default {@link TextIOService} implementation for opening and saving text data
38+
*
39+
* @author Deborah Schmidt
40+
*/
41+
@Plugin(type = Service.class)
42+
public class DefaultTextIOService extends AbstractTypedIOService<String> implements TextIOService {
43+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2020 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+
30+
package org.scijava.text.io;
31+
32+
import org.scijava.io.TypedIOService;
33+
34+
/**
35+
* {@link TypedIOService} for opening and saving text data
36+
*
37+
* @author Deborah Schmidt
38+
*/
39+
public interface TextIOService extends TypedIOService<String> {
40+
}

0 commit comments

Comments
 (0)