From 2cc51f6c194d160c6ad4dd371808a4a89070174a Mon Sep 17 00:00:00 2001 From: frauzufall Date: Wed, 12 Aug 2020 23:53:12 +0200 Subject: [PATCH 1/2] Adapt to API changes in scijava-table 0.7.0 * Use Location instead of String * Parser is now Function instead of Function --- pom.xml | 7 +- .../scijava/table/DefaultTableIOPlugin.java | 65 ++++++++----------- .../table/DefaultTableIOPluginTest.java | 8 +-- 3 files changed, 34 insertions(+), 46 deletions(-) diff --git a/pom.xml b/pom.xml index 347b3ec..2c39abb 100644 --- a/pom.xml +++ b/pom.xml @@ -5,12 +5,12 @@ org.scijava pom-scijava - 29.2.0 + 29.2.1 scijava-plugins-io-table - 0.3.1-SNAPSHOT + 0.4.0-SNAPSHOT SciJava IO Plugin: Tables I/O plugins for SciJava table objects. @@ -100,7 +100,8 @@ Wisconsin-Madison and University of Konstanz. deploy-to-scijava - 0.6.1 + 0.7.0 + 2.84.0 diff --git a/src/main/java/org/scijava/table/DefaultTableIOPlugin.java b/src/main/java/org/scijava/table/DefaultTableIOPlugin.java index 43930f9..aceaab3 100644 --- a/src/main/java/org/scijava/table/DefaultTableIOPlugin.java +++ b/src/main/java/org/scijava/table/DefaultTableIOPlugin.java @@ -30,7 +30,6 @@ package org.scijava.table; -import java.net.URISyntaxException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -43,11 +42,10 @@ import java.util.function.Function; import org.scijava.Priority; -import org.scijava.io.IOPlugin; +import org.scijava.io.AbstractIOPlugin; import org.scijava.io.handle.DataHandle; import org.scijava.io.handle.DataHandleService; import org.scijava.io.location.Location; -import org.scijava.io.location.LocationService; import org.scijava.plugin.Parameter; import org.scijava.plugin.Plugin; import org.scijava.table.io.ColumnTableIOOptions; @@ -61,11 +59,8 @@ * @author Leon Yang */ @SuppressWarnings("rawtypes") -@Plugin(type = IOPlugin.class, priority = Priority.LOW) -public class DefaultTableIOPlugin extends TableIOPlugin { - - @Parameter - private LocationService locationService; +@Plugin(type = TableIOPlugin.class, priority = Priority.LOW) +public class DefaultTableIOPlugin extends AbstractIOPlugin implements TableIOPlugin { @Parameter private DataHandleService dataHandleService; @@ -76,12 +71,28 @@ public class DefaultTableIOPlugin extends TableIOPlugin { .unmodifiableSet(new HashSet<>(Arrays.asList("csv", "txt", "prn", "dif", "rtf"))); + @Override + public boolean supportsOpen(final Location source) { + final String ext = FileUtils.getExtension(source.getName()).toLowerCase(); + return SUPPORTED_EXTENSIONS.contains(ext); + } + @Override public boolean supportsOpen(final String source) { final String ext = FileUtils.getExtension(source).toLowerCase(); return SUPPORTED_EXTENSIONS.contains(ext); } + @Override + public boolean supportsSave(Object data, String destination) { + return supports(destination) && Table.class.isAssignableFrom(data.getClass()); + } + + @Override + public boolean supportsSave(final Location source) { + return supportsOpen(source); + } + @Override public boolean supportsSave(final String source) { return supportsOpen(source); @@ -143,23 +154,16 @@ else if (line.charAt(idx) == separator) { } @Override - public GenericTable open(final String source, TableIOOptions options) throws IOException { + public GenericTable open(final Location source, TableIOOptions options) throws IOException { return open(source, options.values); } - private GenericTable open(final String source, TableIOOptions.Values options) throws IOException { + private GenericTable open(final Location source, TableIOOptions.Values options) throws IOException { - final Location sourceLocation; - try { - sourceLocation = locationService.resolve(source); - } - catch (final URISyntaxException exc) { - throw new IOException("Unresolvable source: " + source, exc); - } final GenericTable table = new DefaultGenericTable(); try (final DataHandle handle = // - dataHandleService.create(sourceLocation)) + dataHandleService.create(source)) { if (!handle.exists()) { throw new IOException("Cannot open source"); @@ -180,7 +184,7 @@ private GenericTable open(final String source, TableIOOptions.Values options) th final String[] lines = text.split("\\R"); if (lines.length == 0) return table; // process first line to get number of cols - Map> columnParsers = new HashMap<>(); + Map> columnParsers = new HashMap<>(); { final ArrayList tokens = processRow(lines[0], separator, quote); if (readColHeaders) { @@ -203,7 +207,7 @@ private GenericTable open(final String source, TableIOOptions.Values options) th table.appendRow(); } for (int i = 0; i < cols.size(); i++) { - Function parser = getParser(cols.get(i), i, options); + Function parser = getParser(cols.get(i), i, options); columnParsers.put(i, parser); table.set(i, 0, parser.apply(cols.get(i))); } @@ -236,7 +240,7 @@ private GenericTable open(final String source, TableIOOptions.Values options) th return table; } - private static Function getParser(String content, int column, TableIOOptions.Values options) { + private static Function getParser(String content, int column, TableIOOptions.Values options) { ColumnTableIOOptions.Values colOptions = options.column(column); if(colOptions != null) return colOptions.parser(); if(options.guessParser()) return guessParser(content); @@ -263,29 +267,16 @@ static Function guessParser(String content) { } @Override - public void save(final Table table, final String destination) - throws IOException { - save(table, destination, new TableIOOptions().values); - } - - @Override - public void save(final Table table, final String destination, final TableIOOptions options) + public void save(final Table table, final Location destination, final TableIOOptions options) throws IOException { save(table, destination, options.values); } - private void save(final Table table, final String destination, final TableIOOptions.Values options) + private void save(final Table table, final Location destination, final TableIOOptions.Values options) throws IOException { - final Location dstLocation; - try { - dstLocation = locationService.resolve(destination); - } - catch (final URISyntaxException exc) { - throw new IOException("Unresolvable destination: " + destination, exc); - } try (final DataHandle handle = // - dataHandleService.create(dstLocation)) + dataHandleService.create(destination)) { final boolean writeRH = options.writeRowHeaders(); final boolean writeCH = options.writeColumnHeaders(); diff --git a/src/test/java/org/scijava/table/DefaultTableIOPluginTest.java b/src/test/java/org/scijava/table/DefaultTableIOPluginTest.java index 06c15ed..cdbc084 100644 --- a/src/test/java/org/scijava/table/DefaultTableIOPluginTest.java +++ b/src/test/java/org/scijava/table/DefaultTableIOPluginTest.java @@ -36,10 +36,8 @@ import java.io.File; import java.io.IOException; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; import org.junit.After; @@ -52,10 +50,8 @@ import org.scijava.io.handle.DataHandleService; import org.scijava.io.location.FileLocation; import org.scijava.io.location.Location; -import org.scijava.plugin.Parameter; import org.scijava.table.io.TableIOOptions; import org.scijava.table.io.TableIOPlugin; -import org.scijava.util.ClassUtils; /** * Tests for {@link DefaultTableIOPlugin}. @@ -293,7 +289,7 @@ private Table openTable(final String tableSource, tempFiles.add(tempFile); try (DataHandle destHandle = dataHandleService.create(new FileLocation(tempFile))) { destHandle.write(tableSource.getBytes()); - result = tableIO.open(tempFile.getAbsolutePath(), options); + result = tableIO.open(destHandle.get(), options); } return result; } @@ -307,7 +303,7 @@ private String saveTable(final Table table, File tempFile = File.createTempFile("saveTest", ".txt"); tempFiles.add(tempFile); try (DataHandle sourceHandle = dataHandleService.create(new FileLocation(tempFile))) { - tableIO.save(table, tempFile.getAbsolutePath(), options); + tableIO.save(table, sourceHandle.get(), options); result = sourceHandle.readString(Integer.MAX_VALUE); } return result; From ac885083b5068e3c36b63db6d66efa16df9ab112 Mon Sep 17 00:00:00 2001 From: frauzufall Date: Thu, 13 Aug 2020 10:36:30 +0200 Subject: [PATCH 2/2] Making guessParser less error-prone When auto detecting the column type of such a column, the previous guessParser implementation produced exceptions: -1 0 -1.0 1.0 0.0 infinity -infinity +Nan NaN -NaN 1.23e7 13.8f 57269d Therefore, now the only number format which will be guessed by guessParser is Double. Also, when testing this with imagej-server, the Strings "infinity" and "Nan" where used which are not compatible with Double::valueOf, therefore they are replaced with the compatible capitalization. Maybe there is a better way to do this.. Co-authored-by: Jan Eglinger --- .../scijava/table/DefaultTableIOPlugin.java | 18 +++++++----------- .../table/DefaultTableIOPluginTest.java | 10 ++++++---- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/scijava/table/DefaultTableIOPlugin.java b/src/main/java/org/scijava/table/DefaultTableIOPlugin.java index aceaab3..85bb5ef 100644 --- a/src/main/java/org/scijava/table/DefaultTableIOPlugin.java +++ b/src/main/java/org/scijava/table/DefaultTableIOPlugin.java @@ -247,18 +247,14 @@ private GenericTable open(final Location source, TableIOOptions.Values options) return options.parser(); } - static Function guessParser(String content) { + static Function guessParser(String content) { try { - Integer.valueOf(content); - return Integer::valueOf; - } catch(NumberFormatException ignored) {} - try { - Long.valueOf(content); - return Long::valueOf; - } catch(NumberFormatException ignored) {} - try { - Double.valueOf(content); - return Double::valueOf; + Function function = s -> Double.valueOf(s + .replace("infinity", "Infinity") + .replace("Nan", "NaN") + ); + function.apply(content); + return function; } catch(NumberFormatException ignored) {} if(content.equalsIgnoreCase("true")||content.equalsIgnoreCase("false")) { return Boolean::valueOf; diff --git a/src/test/java/org/scijava/table/DefaultTableIOPluginTest.java b/src/test/java/org/scijava/table/DefaultTableIOPluginTest.java index cdbc084..6a72835 100644 --- a/src/test/java/org/scijava/table/DefaultTableIOPluginTest.java +++ b/src/test/java/org/scijava/table/DefaultTableIOPluginTest.java @@ -111,7 +111,7 @@ public void testDefaultOptions() throws IOException { } /** - * Tests if quoting works in different senarios. + * Tests if quoting works in different scenarios. */ @Test public void testQuote() { @@ -160,7 +160,7 @@ public void testQuote() { } /** - * Tests if samll tables could be opened/saved correctly. + * Tests if small tables can be opened/saved correctly. */ @Test public void testSmallTables() { @@ -250,11 +250,13 @@ public void testGuessParser() { assertEquals(false, DefaultTableIOPlugin.guessParser("false").apply("false")); assertEquals(123.0, DefaultTableIOPlugin.guessParser("123.0").apply("123.0")); assertEquals(-123.0, DefaultTableIOPlugin.guessParser("-123.0").apply("-123.0")); - assertEquals(3, DefaultTableIOPlugin.guessParser("3").apply("3")); - assertEquals(36564573745634564L, DefaultTableIOPlugin.guessParser("36564573745634564").apply("36564573745634564")); + assertEquals(3.0, DefaultTableIOPlugin.guessParser("3").apply("3")); + assertEquals(36564573745634564d, DefaultTableIOPlugin.guessParser("36564573745634564").apply("36564573745634564")); assertEquals(1234567890.0987654321, DefaultTableIOPlugin.guessParser("1.2345678900987654E9").apply("1.2345678900987654E9")); assertEquals(Double.NaN, DefaultTableIOPlugin.guessParser("NaN").apply("NaN")); + assertEquals(Double.NaN, DefaultTableIOPlugin.guessParser("Nan").apply("Nan")); assertEquals(Double.NEGATIVE_INFINITY, DefaultTableIOPlugin.guessParser("-Infinity").apply("-Infinity")); + assertEquals(Double.POSITIVE_INFINITY, DefaultTableIOPlugin.guessParser("infinity").apply("infinity")); assertEquals(0.0, DefaultTableIOPlugin.guessParser("0.0").apply("0.0")); }