scijava-common icon indicating copy to clipboard operation
scijava-common copied to clipboard

Improve ConvertService to properly convert lists and arrays to String values

Open imagejan opened this issue 8 years ago • 2 comments

Currently, DefaultConvertService supports conversion from File[] to String and vice versa, but the result is wrong (i.e. a String representation of the File[] array, such as [Ljava.io.File;@31c3cff5).

The following Groovy script illustrates the issue:

#@ ConvertService cs

import java.io.File

file1 = new File("test1.csv")
file2 = new File("test2.csv")

File[] fileList = [file1, file2].toArray()

println fileList.getClass() // class [Ljava.io.File;

println cs.supports(fileList, String.class) // true
println cs.convert(fileList, String.class) // [Ljava.io.File;@31c3cff5

(The expected re-convertible output in this case should be something like test1.csv\ntest2.csv, ideally with the absolute paths of the files)

See also some related discussion in https://github.com/scijava/scijava-ui-swing/pull/27.

imagejan avatar Jul 19 '17 09:07 imagejan

I guess a first step would be to fix the result of supports for those cases where lossless conversion currently is not possible/implemented.

#@ ConvertService cs
#@OUTPUT boolean stringToFile
#@OUTPUT boolean stringListToFile
#@OUTPUT boolean stringToFileList
#@OUTPUT boolean stringListToFileList
#@OUTPUT boolean fileToString
#@OUTPUT boolean fileListToString
#@OUTPUT boolean fileToStringList
#@OUTPUT boolean fileListToStringList

fileList = [new File("test1.txt"), new File("test2.txt")]
stringList = ["a", "b"]

stringToFile = cs.supports("aFile", File.class)
stringListToFile = cs.supports(stringList, File.class)
stringToFileList = cs.supports("aFile", File[].class)
stringListToFileList = cs.supports(stringList, File[].class)
fileToString = cs.supports(new File("aFile"), String.class)
fileListToString = cs.supports(fileList, String.class)
fileToStringList = cs.supports(new File("aFile"), String[].class)
fileListToStringList = cs.supports(fileList, String[].class)

image

Then we'll have to provide a converter supporting String to File[] and File[] to String doing the right thing. The question is how the string representation should look like:

  • C:\temp\file1.csv;C:\temp\file2.csv is a problem because semicolons (;) are actually valid file name characters
  • C:\temp\file1.csv\nC:\temp\file2.csv would work but is a bit awkward in case you'd like to provide default inputs for scripts, such as: #@ File[] (value="C:\\temp\\file1.csv\nC:\\temp\\file2.csv") input
  • 'C:\temp\file1.csv','C:\temp\file2.csv' quoting would be possible, using a csv parsing library or some such (how about dependencies in scijava-common??)

Comments welcome, I'll try to work on it over the coming weeks.

imagejan avatar Jul 20 '17 09:07 imagejan

The question is how the string representation should look like

I'd vote to use a path separator similar to how this is done from the CLI. This is ; on Windows and : on POSIXish systems. We could use some kind of escaping, probably backslash, for when the separator character actually appears in a folder name. (As an aside, I went to check how PATH handles this on POSIXish systems, and it turns out: it doesn't! You cannot include directories with a colon on the PATH! Crazy eh?)

ctrueden avatar Jul 31 '17 21:07 ctrueden