3030
3131package org .scijava .table ;
3232
33- import java .net .URISyntaxException ;
3433import java .io .IOException ;
3534import java .util .ArrayList ;
3635import java .util .Arrays ;
4342import java .util .function .Function ;
4443
4544import org .scijava .Priority ;
46- import org .scijava .io .IOPlugin ;
45+ import org .scijava .io .AbstractIOPlugin ;
4746import org .scijava .io .handle .DataHandle ;
4847import org .scijava .io .handle .DataHandleService ;
4948import org .scijava .io .location .Location ;
50- import org .scijava .io .location .LocationService ;
5149import org .scijava .plugin .Parameter ;
5250import org .scijava .plugin .Plugin ;
5351import org .scijava .table .io .ColumnTableIOOptions ;
6159 * @author Leon Yang
6260 */
6361@ SuppressWarnings ("rawtypes" )
64- @ Plugin (type = IOPlugin .class , priority = Priority .LOW )
65- public class DefaultTableIOPlugin extends TableIOPlugin {
66-
67- @ Parameter
68- private LocationService locationService ;
62+ @ Plugin (type = TableIOPlugin .class , priority = Priority .LOW )
63+ public class DefaultTableIOPlugin extends AbstractIOPlugin <Table > implements TableIOPlugin {
6964
7065 @ Parameter
7166 private DataHandleService dataHandleService ;
@@ -76,12 +71,28 @@ public class DefaultTableIOPlugin extends TableIOPlugin {
7671 .unmodifiableSet (new HashSet <>(Arrays .asList ("csv" , "txt" , "prn" , "dif" ,
7772 "rtf" )));
7873
74+ @ Override
75+ public boolean supportsOpen (final Location source ) {
76+ final String ext = FileUtils .getExtension (source .getName ()).toLowerCase ();
77+ return SUPPORTED_EXTENSIONS .contains (ext );
78+ }
79+
7980 @ Override
8081 public boolean supportsOpen (final String source ) {
8182 final String ext = FileUtils .getExtension (source ).toLowerCase ();
8283 return SUPPORTED_EXTENSIONS .contains (ext );
8384 }
8485
86+ @ Override
87+ public boolean supportsSave (Object data , String destination ) {
88+ return supports (destination ) && Table .class .isAssignableFrom (data .getClass ());
89+ }
90+
91+ @ Override
92+ public boolean supportsSave (final Location source ) {
93+ return supportsOpen (source );
94+ }
95+
8596 @ Override
8697 public boolean supportsSave (final String source ) {
8798 return supportsOpen (source );
@@ -143,23 +154,16 @@ else if (line.charAt(idx) == separator) {
143154 }
144155
145156 @ Override
146- public GenericTable open (final String source , TableIOOptions options ) throws IOException {
157+ public GenericTable open (final Location source , TableIOOptions options ) throws IOException {
147158 return open (source , options .values );
148159 }
149160
150- private GenericTable open (final String source , TableIOOptions .Values options ) throws IOException {
161+ private GenericTable open (final Location source , TableIOOptions .Values options ) throws IOException {
151162
152- final Location sourceLocation ;
153- try {
154- sourceLocation = locationService .resolve (source );
155- }
156- catch (final URISyntaxException exc ) {
157- throw new IOException ("Unresolvable source: " + source , exc );
158- }
159163 final GenericTable table = new DefaultGenericTable ();
160164
161165 try (final DataHandle <? extends Location > handle = //
162- dataHandleService .create (sourceLocation ))
166+ dataHandleService .create (source ))
163167 {
164168 if (!handle .exists ()) {
165169 throw new IOException ("Cannot open source" );
@@ -180,7 +184,7 @@ private GenericTable open(final String source, TableIOOptions.Values options) th
180184 final String [] lines = text .split ("\\ R" );
181185 if (lines .length == 0 ) return table ;
182186 // process first line to get number of cols
183- Map <Integer , Function <String , Object >> columnParsers = new HashMap <>();
187+ Map <Integer , Function <String , ? >> columnParsers = new HashMap <>();
184188 {
185189 final ArrayList <String > tokens = processRow (lines [0 ], separator , quote );
186190 if (readColHeaders ) {
@@ -203,7 +207,7 @@ private GenericTable open(final String source, TableIOOptions.Values options) th
203207 table .appendRow ();
204208 }
205209 for (int i = 0 ; i < cols .size (); i ++) {
206- Function <String , Object > parser = getParser (cols .get (i ), i , options );
210+ Function <String , ? > parser = getParser (cols .get (i ), i , options );
207211 columnParsers .put (i , parser );
208212 table .set (i , 0 , parser .apply (cols .get (i )));
209213 }
@@ -236,25 +240,21 @@ private GenericTable open(final String source, TableIOOptions.Values options) th
236240 return table ;
237241 }
238242
239- private static Function <String , Object > getParser (String content , int column , TableIOOptions .Values options ) {
243+ private static Function <String , ? > getParser (String content , int column , TableIOOptions .Values options ) {
240244 ColumnTableIOOptions .Values colOptions = options .column (column );
241245 if (colOptions != null ) return colOptions .parser ();
242246 if (options .guessParser ()) return guessParser (content );
243247 return options .parser ();
244248 }
245249
246- static Function <String , Object > guessParser (String content ) {
247- try {
248- Integer .valueOf (content );
249- return Integer ::valueOf ;
250- } catch (NumberFormatException ignored ) {}
250+ static Function <String , ?> guessParser (String content ) {
251251 try {
252- Long .valueOf (content );
253- return Long :: valueOf ;
254- } catch ( NumberFormatException ignored ) {}
255- try {
256- Double . valueOf (content );
257- return Double :: valueOf ;
252+ Function < String , ?> function = s -> Double .valueOf (s
253+ . replace ( "infinity" , "Infinity" )
254+ . replace ( "Nan" , "NaN" )
255+ );
256+ function . apply (content );
257+ return function ;
258258 } catch (NumberFormatException ignored ) {}
259259 if (content .equalsIgnoreCase ("true" )||content .equalsIgnoreCase ("false" )) {
260260 return Boolean ::valueOf ;
@@ -263,29 +263,16 @@ static Function<String, Object> guessParser(String content) {
263263 }
264264
265265 @ Override
266- public void save (final Table table , final String destination )
267- throws IOException {
268- save (table , destination , new TableIOOptions ().values );
269- }
270-
271- @ Override
272- public void save (final Table table , final String destination , final TableIOOptions options )
266+ public void save (final Table table , final Location destination , final TableIOOptions options )
273267 throws IOException {
274268 save (table , destination , options .values );
275269 }
276270
277- private void save (final Table table , final String destination , final TableIOOptions .Values options )
271+ private void save (final Table table , final Location destination , final TableIOOptions .Values options )
278272 throws IOException {
279- final Location dstLocation ;
280- try {
281- dstLocation = locationService .resolve (destination );
282- }
283- catch (final URISyntaxException exc ) {
284- throw new IOException ("Unresolvable destination: " + destination , exc );
285- }
286273
287274 try (final DataHandle <Location > handle = //
288- dataHandleService .create (dstLocation ))
275+ dataHandleService .create (destination ))
289276 {
290277 final boolean writeRH = options .writeRowHeaders ();
291278 final boolean writeCH = options .writeColumnHeaders ();
0 commit comments