From 5979e596a834e2461aa24fd0891f7c523929fbeb Mon Sep 17 00:00:00 2001 From: Jan Eglinger Date: Thu, 14 Nov 2019 17:20:23 +0100 Subject: [PATCH 1/2] Add TableIOService and test This commit adds a Service that allows to open and save org.scijava.table.Table objects. TableIOService#open() explicitly returns Table objects, so it can be used instead of IOService whenever strict types are desired. Fixes #7. Dedicated to Robert Haase. --- pom.xml | 2 +- .../table/io/DefaultTableIOService.java | 84 +++++++++++++++++++ .../org/scijava/table/io/TableIOService.java | 47 +++++++++++ .../org/scijava/table/FakeTableIOPlugin.java | 59 +++++++++++++ .../org/scijava/table/TableIOServiceTest.java | 76 +++++++++++++++++ 5 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/scijava/table/io/DefaultTableIOService.java create mode 100644 src/main/java/org/scijava/table/io/TableIOService.java create mode 100644 src/test/java/org/scijava/table/FakeTableIOPlugin.java create mode 100644 src/test/java/org/scijava/table/TableIOServiceTest.java diff --git a/pom.xml b/pom.xml index 104302e..64f07cd 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.scijava pom-scijava - 26.0.0 + 27.0.1 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..651dc5f --- /dev/null +++ b/src/test/java/org/scijava/table/FakeTableIOPlugin.java @@ -0,0 +1,59 @@ +/*- + * #%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; +import org.scijava.io.IOPlugin; +import org.scijava.plugin.Plugin; + +@SuppressWarnings("rawtypes") +@Plugin(type = IOPlugin.class) +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..a98c7b8 --- /dev/null +++ b/src/test/java/org/scijava/table/TableIOServiceTest.java @@ -0,0 +1,76 @@ +/*- + * #%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.table.io.DefaultTableIOService; +import org.scijava.table.io.TableIOService; + +public class TableIOServiceTest { + + private Context context; + + @Before + public void setUp() { + context = new Context(); + } + + @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()); + } + } +} From 2ceaf972d24d729687f5124b3812c9bc436e1781 Mon Sep 17 00:00:00 2001 From: Jan Eglinger Date: Fri, 20 Dec 2019 13:56:43 +0100 Subject: [PATCH 2/2] Adapt TableIOServiceTest Using PluginInfo.create available in scijava-common 2.81.0, we can avoid having the FakeTableIOPlugin test class visible in all tests. --- pom.xml | 2 ++ src/test/java/org/scijava/table/FakeTableIOPlugin.java | 3 --- src/test/java/org/scijava/table/TableIOServiceTest.java | 7 +++++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 64f07cd..fc2207b 100644 --- a/pom.xml +++ b/pom.xml @@ -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/test/java/org/scijava/table/FakeTableIOPlugin.java b/src/test/java/org/scijava/table/FakeTableIOPlugin.java index 651dc5f..67391c4 100644 --- a/src/test/java/org/scijava/table/FakeTableIOPlugin.java +++ b/src/test/java/org/scijava/table/FakeTableIOPlugin.java @@ -30,11 +30,8 @@ package org.scijava.table; import org.scijava.io.AbstractIOPlugin; -import org.scijava.io.IOPlugin; -import org.scijava.plugin.Plugin; @SuppressWarnings("rawtypes") -@Plugin(type = IOPlugin.class) public class FakeTableIOPlugin extends AbstractIOPlugin
{ @Override diff --git a/src/test/java/org/scijava/table/TableIOServiceTest.java b/src/test/java/org/scijava/table/TableIOServiceTest.java index a98c7b8..2dacf27 100644 --- a/src/test/java/org/scijava/table/TableIOServiceTest.java +++ b/src/test/java/org/scijava/table/TableIOServiceTest.java @@ -39,6 +39,9 @@ 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; @@ -46,9 +49,13 @@ 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