Description
The scripting service handles only a very limited set of parameter options. For example, this Beanshell parameter that cropped up in a coding session with @schmiedc fails:
// @String(label = 'Monty Hall', choices = { 'Door A', 'Door B', 'Door C' }) montyHall
The error javax.script.ScriptException: Invalid attribute: 'Door B'
is hidden in the standard error stream.
The reason is that parameters that are even mildly complex are not handled correctly can be found here: It is assumed that the attributes (i.e. the "label = 'Monty Hall', choices = { 'Door A', 'Door B', 'Door C' }
" of the example above) can be parsed simply by cutting it apart at every comma.
Please note that this parser would already fail to handle something as simple as @String(label = "Hello, world!") label
.
Please note also that the comment // TODO: We probably want to use a real CSV parser.
is quite misleading. The attributes of a parameter have nothing in common with CSV, but much more with, say, JSON.
Alas, there is already a full-fledged JSON parser in scijava-common
, as part of the IndexReader
we use to read the indexed annotations.
It would most likely require only a gentle amount of refactoring to turn this into a JSONReader
that could be put into org.scijava.util
. A cursory look makes this person believe that the only thing that would need to be factored out is the getLegacyReader()
method.
To support the script parameters use case, the JSONReader
would probably need to sprout a public char peek()
method that would skip white space, continue parsing upon encountering a comma, finalize the parameters upon seeing a closing parenthesis, and erroring out otherwise.
In the meantime, we will have to resort to using code like the following:
// @ModuleService moduleService
import java.util.Arrays;
import org.scijava.module.DefaultMutableModule;
gui = new DefaultMutableModule();
info = gui.addInput("Monty Hall", String.class);
info.setChoices(Arrays.asList(new String[] { "Door A", "Door B", "Door C" }));
moduleService.run(gui, true, new Object[0]).get();
print(info.getValue(gui));