5454import org .scijava .util .FileUtils ;
5555
5656/**
57- * Plugin for reading/writing {@link GenericTable }s.
58- *
57+ * Plugin for reading/writing {@link Table }s.
58+ *
5959 * @author Leon Yang
6060 */
6161@ SuppressWarnings ("rawtypes" )
6262@ Plugin (type = TableIOPlugin .class , priority = Priority .LOW )
63- public class DefaultTableIOPlugin extends AbstractIOPlugin <Table > implements TableIOPlugin {
63+ public class DefaultTableIOPlugin extends AbstractIOPlugin <Table > implements
64+ TableIOPlugin
65+ {
6466
6567 @ Parameter
6668 private DataHandleService dataHandleService ;
6769
6870 // FIXME: The "txt" extension is extremely general and will conflict with
6971 // other plugins. Consider another way to check supportsOpen/Close.
70- private static final Set <String > SUPPORTED_EXTENSIONS = Collections
71- .unmodifiableSet (new HashSet <>(Arrays . asList ( "csv" , "txt" , "prn" , "dif" ,
72- "rtf" )));
72+ private static final Set <String > SUPPORTED_EXTENSIONS = //
73+ Collections .unmodifiableSet (new HashSet <>(//
74+ Arrays . asList ( "csv" , "txt" , "prn" , "dif" , "rtf" )));
7375
7476 @ Override
7577 public boolean supportsOpen (final Location source ) {
@@ -84,8 +86,9 @@ public boolean supportsOpen(final String source) {
8486 }
8587
8688 @ Override
87- public boolean supportsSave (Object data , String destination ) {
88- return supports (destination ) && Table .class .isAssignableFrom (data .getClass ());
89+ public boolean supportsSave (final Object data , final String destination ) {
90+ return supports (destination ) && //
91+ Table .class .isAssignableFrom (data .getClass ());
8992 }
9093
9194 @ Override
@@ -101,7 +104,9 @@ public boolean supportsSave(final String source) {
101104 /**
102105 * Process a given line into a list of tokens.
103106 */
104- private ArrayList <String > processRow (final String line , char separator , char quote ) throws IOException {
107+ private ArrayList <String > processRow (final String line , final char separator ,
108+ final char quote ) throws IOException
109+ {
105110 final ArrayList <String > row = new ArrayList <>();
106111 final StringBuilder sb = new StringBuilder ();
107112 int idx = 0 ;
@@ -154,11 +159,15 @@ else if (line.charAt(idx) == separator) {
154159 }
155160
156161 @ Override
157- public GenericTable open (final Location source , TableIOOptions options ) throws IOException {
162+ public GenericTable open (final Location source , final TableIOOptions options )
163+ throws IOException
164+ {
158165 return open (source , options .values );
159166 }
160167
161- private GenericTable open (final Location source , TableIOOptions .Values options ) throws IOException {
168+ private GenericTable open (final Location source ,
169+ final TableIOOptions .Values options ) throws IOException
170+ {
162171
163172 final GenericTable table = new DefaultGenericTable ();
164173
@@ -168,7 +177,7 @@ private GenericTable open(final Location source, TableIOOptions.Values options)
168177 if (!handle .exists ()) {
169178 throw new IOException ("Cannot open source" );
170179 }
171- long length = handle .length ();
180+ final long length = handle .length ();
172181
173182 final byte [] buffer = new byte [(int ) length ];
174183 handle .read (buffer );
@@ -177,14 +186,14 @@ private GenericTable open(final Location source, TableIOOptions.Values options)
177186
178187 final char separator = options .columnDelimiter ();
179188 final char quote = options .quote ();
180- boolean readRowHeaders = options .readRowHeaders ();
181- boolean readColHeaders = options .readColumnHeaders ();
189+ final boolean readRowHeaders = options .readRowHeaders ();
190+ final boolean readColHeaders = options .readColumnHeaders ();
182191
183192 // split by any line delimiter
184193 final String [] lines = text .split ("\\ R" );
185194 if (lines .length == 0 ) return table ;
186195 // process first line to get number of cols
187- Map <Integer , Function <String , ?>> columnParsers = new HashMap <>();
196+ final Map <Integer , Function <String , ?>> columnParsers = new HashMap <>();
188197 {
189198 final ArrayList <String > tokens = processRow (lines [0 ], separator , quote );
190199 if (readColHeaders ) {
@@ -207,7 +216,8 @@ private GenericTable open(final Location source, TableIOOptions.Values options)
207216 table .appendRow ();
208217 }
209218 for (int i = 0 ; i < cols .size (); i ++) {
210- Function <String , ?> parser = getParser (cols .get (i ), i , options );
219+ final Function <String , ?> parser = getParser (cols .get (i ), i ,
220+ options );
211221 columnParsers .put (i , parser );
212222 table .set (i , 0 , parser .apply (cols .get (i )));
213223 }
@@ -230,7 +240,7 @@ private GenericTable open(final Location source, TableIOOptions.Values options)
230240 " is not the same length as the first line." );
231241 }
232242 for (int i = 0 ; i < cols .size (); i ++) {
233- if (lineNum == 1 && readColHeaders ) {
243+ if (lineNum == 1 && readColHeaders ) {
234244 columnParsers .put (i , getParser (cols .get (i ), i , options ));
235245 }
236246 table .set (i , lineNum - 1 , columnParsers .get (i ).apply (cols .get (i )));
@@ -240,36 +250,39 @@ private GenericTable open(final Location source, TableIOOptions.Values options)
240250 return table ;
241251 }
242252
243- private static Function <String , ?> getParser (String content , int column , TableIOOptions .Values options ) {
244- ColumnTableIOOptions .Values colOptions = options .column (column );
245- if (colOptions != null ) return colOptions .parser ();
246- if (options .guessParser ()) return guessParser (content );
253+ private static Function <String , ?> getParser (final String content ,
254+ final int column , final TableIOOptions .Values options )
255+ {
256+ final ColumnTableIOOptions .Values colOptions = options .column (column );
257+ if (colOptions != null ) return colOptions .parser ();
258+ if (options .guessParser ()) return guessParser (content );
247259 return options .parser ();
248260 }
249261
250- static Function <String , ?> guessParser (String content ) {
262+ static Function <String , ?> guessParser (final String content ) {
251263 try {
252- Function <String , ?> function = s -> Double .valueOf (s
253- .replace ("infinity" , "Infinity" )
254- .replace ("Nan" , "NaN" )
255- );
264+ final Function <String , ?> function = s -> Double .valueOf (s .replace (
265+ "infinity" , "Infinity" ).replace ("Nan" , "NaN" ));
256266 function .apply (content );
257267 return function ;
258- } catch (NumberFormatException ignored ) {}
259- if (content .equalsIgnoreCase ("true" )||content .equalsIgnoreCase ("false" )) {
268+ }
269+ catch (final NumberFormatException ignored ) {}
270+ if (content .equalsIgnoreCase ("true" ) || content .equalsIgnoreCase ("false" )) {
260271 return Boolean ::valueOf ;
261272 }
262273 return String ::valueOf ;
263274 }
264275
265276 @ Override
266- public void save (final Table table , final Location destination , final TableIOOptions options )
267- throws IOException {
277+ public void save (final Table table , final Location destination ,
278+ final TableIOOptions options ) throws IOException
279+ {
268280 save (table , destination , options .values );
269281 }
270282
271- private void save (final Table table , final Location destination , final TableIOOptions .Values options )
272- throws IOException {
283+ private void save (final Table table , final Location destination ,
284+ final TableIOOptions .Values options ) throws IOException
285+ {
273286
274287 try (final DataHandle <Location > handle = //
275288 dataHandleService .create (destination ))
@@ -280,58 +293,63 @@ private void save(final Table table, final Location destination, final TableIOOp
280293 final String eol = options .rowDelimiter ();
281294 final char quote = options .quote ();
282295
283- final StringBuilder sb = new StringBuilder ();
284- // write column headers
285- if (writeCH ) {
286- if (writeRH ) {
287- sb .append (tryQuote (options .cornerText (), separator , quote ));
288- if (table .getColumnCount () > 0 ) {
289- sb .append (separator );
290- sb .append (tryQuote (table .getColumnHeader (0 ), separator , quote ));
291- }
292- }
293- // avoid adding extra separator when there is 0 column
294- else if (table .getColumnCount () > 0 ) {
295- sb .append (tryQuote (table .getColumnHeader (0 ), separator , quote ));
296- }
297- for (int col = 1 ; col < table .getColumnCount (); col ++) {
296+ final StringBuilder sb = new StringBuilder ();
297+ // write column headers
298+ if (writeCH ) {
299+ if (writeRH ) {
300+ sb .append (tryQuote (options .cornerText (), separator , quote ));
301+ if (table .getColumnCount () > 0 ) {
298302 sb .append (separator );
299- sb .append (tryQuote (table .getColumnHeader (col ), separator , quote ));
303+ sb .append (tryQuote (table .getColumnHeader (0 ), separator , quote ));
300304 }
301- sb .append (eol );
302- handle .writeBytes (sb .toString ());
303- sb .setLength (0 );
304305 }
305- // write each row
306- for (int row = 0 ; row < table .getRowCount (); row ++) {
307- Function <Object , String > formatter = getFormatter (options , 0 );
308- if (writeRH ) {
309- sb .append (tryQuote (table .getRowHeader (row ), separator , quote ));
310- if (table .getColumnCount () > 0 ) {
311- sb .append (separator );
312- sb .append (tryQuote (formatter .apply (table .get (0 , row )), separator , quote ));
313- }
314- }
315- // avoid adding extra separator when there is 0 column
316- else if (table .getColumnCount () > 0 ) {
317- sb .append (tryQuote (formatter .apply (table .get (0 , row )), separator , quote ));
318- }
319- for (int col = 1 ; col < table .getColumnCount (); col ++) {
320- formatter = getFormatter (options , col );
306+ // avoid adding extra separator when there is 0 column
307+ else if (table .getColumnCount () > 0 ) {
308+ sb .append (tryQuote (table .getColumnHeader (0 ), separator , quote ));
309+ }
310+ for (int col = 1 ; col < table .getColumnCount (); col ++) {
311+ sb .append (separator );
312+ sb .append (tryQuote (table .getColumnHeader (col ), separator , quote ));
313+ }
314+ sb .append (eol );
315+ handle .writeBytes (sb .toString ());
316+ sb .setLength (0 );
317+ }
318+ // write each row
319+ for (int row = 0 ; row < table .getRowCount (); row ++) {
320+ Function <Object , String > formatter = getFormatter (options , 0 );
321+ if (writeRH ) {
322+ sb .append (tryQuote (table .getRowHeader (row ), separator , quote ));
323+ if (table .getColumnCount () > 0 ) {
321324 sb .append (separator );
322- sb .append (tryQuote (formatter .apply (table .get (col , row )), separator , quote ));
325+ sb .append (tryQuote (formatter .apply (table .get (0 , row )), separator ,
326+ quote ));
323327 }
324- sb .append (eol );
325- handle .writeBytes (sb .toString ());
326- sb .setLength (0 );
327328 }
329+ // avoid adding extra separator when there is 0 column
330+ else if (table .getColumnCount () > 0 ) {
331+ sb .append (tryQuote (formatter .apply (table .get (0 , row )), separator ,
332+ quote ));
333+ }
334+ for (int col = 1 ; col < table .getColumnCount (); col ++) {
335+ formatter = getFormatter (options , col );
336+ sb .append (separator );
337+ sb .append (tryQuote (formatter .apply (table .get (col , row )), separator ,
338+ quote ));
339+ }
340+ sb .append (eol );
341+ handle .writeBytes (sb .toString ());
342+ sb .setLength (0 );
343+ }
328344 }
329345
330346 }
331347
332- private Function <Object , String > getFormatter (TableIOOptions .Values options , int i ) {
333- ColumnTableIOOptions .Values columnOptions = options .column (i );
334- if (columnOptions != null ) return columnOptions .formatter ();
348+ private Function <Object , String > getFormatter (
349+ final TableIOOptions .Values options , final int i )
350+ {
351+ final ColumnTableIOOptions .Values columnOptions = options .column (i );
352+ if (columnOptions != null ) return columnOptions .formatter ();
335353 return options .formatter ();
336354 }
337355
@@ -340,11 +358,13 @@ private Function<Object, String> getFormatter(TableIOOptions.Values options, int
340358 * <li>it is null or empty</li>
341359 * <li>it has quotes inside</li>
342360 * <li>it has separators or EOL inside</li>
343- *
361+ *
344362 * @param str string to quote
345363 * @return string, possibly quoted
346364 */
347- private String tryQuote (final String str , char separator , char quote ) {
365+ private String tryQuote (final String str , final char separator ,
366+ final char quote )
367+ {
348368 if (str == null || str .length () == 0 ) return "" + quote + quote ;
349369 if (str .indexOf (quote ) != -1 ) return quote + str .replace ("" + quote , "" +
350370 quote + quote ) + quote ;
0 commit comments