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..85bb5ef 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,25 +240,21 @@ 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); return options.parser(); } - static Function guessParser(String content) { - try { - Integer.valueOf(content); - return Integer::valueOf; - } catch(NumberFormatException ignored) {} + static Function guessParser(String content) { 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; @@ -263,29 +263,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..6a72835 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}. @@ -115,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() { @@ -164,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() { @@ -254,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")); } @@ -293,7 +291,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 +305,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;