diff --git a/pom.xml b/pom.xml
index 104302e..fc2207b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.scijava
pom-scijava
- 26.0.0
+ 27.0.1
@@ -100,6 +100,8 @@
Board of Regents of the University of
Wisconsin-Madison, and Friedrich Miescher Institute for Biomedical Research.
+ 2.81.0
+
deploy-to-scijava
diff --git a/src/main/java/org/scijava/table/io/DefaultTableIOService.java b/src/main/java/org/scijava/table/io/DefaultTableIOService.java
new file mode 100644
index 0000000..1d1bba9
--- /dev/null
+++ b/src/main/java/org/scijava/table/io/DefaultTableIOService.java
@@ -0,0 +1,84 @@
+/*-
+ * #%L
+ * Table structures for SciJava.
+ * %%
+ * Copyright (C) 2012 - 2019 Board of Regents of the University of
+ * Wisconsin-Madison, and Friedrich Miescher Institute for Biomedical Research.
+ * %%
+ * 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.table.io;
+
+import java.io.IOException;
+
+import org.scijava.io.IOPlugin;
+import org.scijava.io.IOService;
+import org.scijava.plugin.Parameter;
+import org.scijava.plugin.Plugin;
+import org.scijava.service.AbstractService;
+import org.scijava.service.Service;
+import org.scijava.table.Table;
+
+@Plugin(type = Service.class)
+public class DefaultTableIOService extends AbstractService implements
+ TableIOService
+{
+
+ @Parameter
+ private IOService ioService;
+
+ @Override
+ public boolean canOpen(String source) {
+ IOPlugin> opener = ioService.getOpener(source);
+ if (opener == null) return false;
+ return Table.class.isAssignableFrom(opener.getDataType());
+ }
+
+ @Override
+ public boolean canSave(Table, ?> table, String destination) {
+ IOPlugin
> saver = ioService.getSaver(table, destination);
+ if (saver == null) return false;
+ return saver.supportsSave(destination);
+ }
+
+ @Override
+ public Table, ?> open(String source) throws IOException {
+ IOPlugin> opener = ioService.getOpener(source);
+ if (opener != null && Table.class.isAssignableFrom(opener.getDataType())) {
+ return (Table, ?>) opener.open(source);
+ }
+ throw new UnsupportedOperationException("No compatible opener found.");
+ }
+
+ @Override
+ public void save(Table, ?> table, String destination) throws IOException {
+ IOPlugin> saver = ioService.getSaver(table, destination);
+ if (saver != null) {
+ saver.save(table, destination);
+ }
+ else {
+ throw new UnsupportedOperationException("No compatible saver found.");
+ }
+ }
+}
diff --git a/src/main/java/org/scijava/table/io/TableIOService.java b/src/main/java/org/scijava/table/io/TableIOService.java
new file mode 100644
index 0000000..50076d0
--- /dev/null
+++ b/src/main/java/org/scijava/table/io/TableIOService.java
@@ -0,0 +1,47 @@
+/*-
+ * #%L
+ * Table structures for SciJava.
+ * %%
+ * Copyright (C) 2012 - 2019 Board of Regents of the University of
+ * Wisconsin-Madison, and Friedrich Miescher Institute for Biomedical Research.
+ * %%
+ * 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.table.io;
+
+import java.io.IOException;
+
+import org.scijava.service.SciJavaService;
+import org.scijava.table.Table;
+
+public interface TableIOService extends SciJavaService {
+
+ boolean canOpen(String source);
+
+ boolean canSave(Table, ?> table, String destination);
+
+ Table, ?> open(String source) throws IOException;
+
+ void save(Table, ?> table, String destination) throws IOException;
+}
diff --git a/src/test/java/org/scijava/table/FakeTableIOPlugin.java b/src/test/java/org/scijava/table/FakeTableIOPlugin.java
new file mode 100644
index 0000000..67391c4
--- /dev/null
+++ b/src/test/java/org/scijava/table/FakeTableIOPlugin.java
@@ -0,0 +1,56 @@
+/*-
+ * #%L
+ * Table structures for SciJava.
+ * %%
+ * Copyright (C) 2012 - 2019 Board of Regents of the University of
+ * Wisconsin-Madison, and Friedrich Miescher Institute for Biomedical Research.
+ * %%
+ * 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.table;
+
+import org.scijava.io.AbstractIOPlugin;
+
+@SuppressWarnings("rawtypes")
+public class FakeTableIOPlugin extends AbstractIOPlugin {
+
+ @Override
+ public Class getDataType() {
+ return Table.class;
+ }
+
+ @Override
+ public boolean supportsOpen(String loc) {
+ return loc.endsWith("csv");
+ }
+
+ @Override
+ public boolean supportsSave(String loc) {
+ return loc.endsWith("csv");
+ }
+
+ @Override
+ public Table open(String loc) {
+ return new DefaultGenericTable();
+ }
+}
diff --git a/src/test/java/org/scijava/table/TableIOServiceTest.java b/src/test/java/org/scijava/table/TableIOServiceTest.java
new file mode 100644
index 0000000..2dacf27
--- /dev/null
+++ b/src/test/java/org/scijava/table/TableIOServiceTest.java
@@ -0,0 +1,83 @@
+/*-
+ * #%L
+ * Table structures for SciJava.
+ * %%
+ * Copyright (C) 2012 - 2019 Board of Regents of the University of
+ * Wisconsin-Madison, and Friedrich Miescher Institute for Biomedical Research.
+ * %%
+ * 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.table;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.scijava.Context;
+import org.scijava.io.IOPlugin;
+import org.scijava.plugin.PluginInfo;
+import org.scijava.plugin.PluginService;
+import org.scijava.table.io.DefaultTableIOService;
+import org.scijava.table.io.TableIOService;
+
+public class TableIOServiceTest {
+
+ private Context context;
+
+ @SuppressWarnings("rawtypes")
+ @Before
+ public void setUp() {
+ context = new Context();
+ PluginInfo info = PluginInfo.create(FakeTableIOPlugin.class,
+ IOPlugin.class);
+ context.service(PluginService.class).addPlugin(info);
+ }
+
+ @After
+ public void tearDown() {
+ context.dispose();
+ context = null;
+ }
+
+ @Test
+ public void testTableIOService() {
+ String tableFile = "fakeTableFile.csv";
+ GenericTable table = new DefaultGenericTable();
+ TableIOService tableIOService = context.getService(TableIOService.class);
+ assertTrue(tableIOService.getClass().equals(DefaultTableIOService.class));
+ assertTrue(tableIOService.canOpen(tableFile));
+ assertTrue(tableIOService.canSave(table, tableFile));
+ try {
+ Table, ?> data = tableIOService.open(tableFile);
+ assertTrue(Table.class.isAssignableFrom(data.getClass()));
+ }
+ catch (IOException exc) {
+ fail(exc.toString());
+ }
+ }
+}