|
38 | 38 | import java.io.Reader; |
39 | 39 | import java.io.StringReader; |
40 | 40 | import java.text.SimpleDateFormat; |
| 41 | +import java.util.Arrays; |
| 42 | +import java.util.Collections; |
41 | 43 | import java.util.Date; |
42 | 44 | import java.util.HashMap; |
| 45 | +import java.util.List; |
43 | 46 | import java.util.Map; |
44 | 47 |
|
45 | 48 | import javax.script.ScriptException; |
|
56 | 59 | import org.scijava.module.DefaultMutableModuleItem; |
57 | 60 | import org.scijava.module.ModuleException; |
58 | 61 | import org.scijava.plugin.Parameter; |
| 62 | +import org.scijava.sjep.Variable; |
| 63 | +import org.scijava.sjep.eval.DefaultEvaluator; |
59 | 64 | import org.scijava.util.DigestUtils; |
60 | 65 | import org.scijava.util.FileUtils; |
61 | 66 |
|
@@ -337,11 +342,11 @@ private void parseParam(final String param) throws ScriptException { |
337 | 342 | if (rParen < lParen) { |
338 | 343 | throw new ScriptException("Invalid parameter: " + param); |
339 | 344 | } |
340 | | - if (lParen < 0) parseParam(param, parseAttrs("")); |
| 345 | + if (lParen < 0) parseParam(param, parseAttrs("()")); |
341 | 346 | else { |
342 | 347 | final String cutParam = |
343 | 348 | param.substring(0, lParen) + param.substring(rParen + 1); |
344 | | - final String attrs = param.substring(lParen + 1, rParen); |
| 349 | + final String attrs = param.substring(lParen, rParen + 1); |
345 | 350 | parseParam(cutParam, parseAttrs(attrs)); |
346 | 351 | } |
347 | 352 | } |
@@ -374,20 +379,39 @@ private void parseParam(final String param, |
374 | 379 | private HashMap<String, Object> parseAttrs(final String attrs) |
375 | 380 | throws ScriptException |
376 | 381 | { |
377 | | - // TODO: We probably want to use a real CSV parser. |
378 | | - final HashMap<String, Object> attrsMap = new HashMap<String, Object>(); |
379 | | - for (final String token : attrs.split(",")) { |
380 | | - if (token.isEmpty()) continue; |
381 | | - final int equals = token.indexOf("="); |
382 | | - if (equals < 0) throw new ScriptException("Invalid attribute: " + token); |
383 | | - final String key = token.substring(0, equals).trim(); |
384 | | - String value = token.substring(equals + 1).trim(); |
385 | | - if (value.startsWith("\"") && value.endsWith("\"")) { |
386 | | - value = value.substring(1, value.length() - 1); |
| 382 | + // NB: Parse the attributes using the SciJava Expression Parser. |
| 383 | + final DefaultEvaluator e = new DefaultEvaluator(); |
| 384 | + try { |
| 385 | + final Object result = e.evaluate(attrs); |
| 386 | + if (result == null) throw new ScriptException("Unparseable attributes"); |
| 387 | + final List<?> list; |
| 388 | + if (result instanceof List) list = (List<?>) result; |
| 389 | + else if (result instanceof Variable) { |
| 390 | + list = Collections.singletonList(result); |
| 391 | + } |
| 392 | + else { |
| 393 | + throw new ScriptException("Unexpected attributes type: " + |
| 394 | + result.getClass().getName()); |
| 395 | + } |
| 396 | + |
| 397 | + final HashMap<String, Object> attrsMap = new HashMap<String, Object>(); |
| 398 | + for (final Object o : list) { |
| 399 | + if (o instanceof Variable) { |
| 400 | + final Variable v = (Variable) o; |
| 401 | + attrsMap.put(v.getToken(), e.value(v)); |
| 402 | + } |
| 403 | + else { |
| 404 | + throw new ScriptException("Invalid attribute: " + o); |
| 405 | + } |
387 | 406 | } |
388 | | - attrsMap.put(key, value); |
| 407 | + return attrsMap; |
| 408 | + } |
| 409 | + catch (final IllegalArgumentException exc) { |
| 410 | + final ScriptException se = new ScriptException( |
| 411 | + "Error parsing attributes"); |
| 412 | + se.initCause(exc); |
| 413 | + throw se; |
389 | 414 | } |
390 | | - return attrsMap; |
391 | 415 | } |
392 | 416 |
|
393 | 417 | private boolean isIOType(final String token) { |
|
0 commit comments