Mark Estrada
Mark Estrada

Reputation: 9201

Escaping the dot in groovy expression binding from java

How do you escape . (dot) in evaluating the bindings in a GroovyShell? It seems the evaluator is not able to handle the .

import groovy.lang.GroovyShell;
import groovy.lang.Binding; 
public class BindingSample {
    public static void main(String[] args) {
        String expression = "sample.name == ben ||  sample.name == mark || sample.name == trae";

        Binding binding = new Binding();
        binding.setVariable("sample.name", "ben");
        GroovyShell shell = new GroovyShell(binding);
        Object result = shell.evaluate(expression);
        System.out.println(result);
    }
}

Exception in thread "main" groovy.lang.MissingPropertyException: No such property: sample for class: Script1
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:50)
    at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:49)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:231)
    at Script1.run(Script1.groovy:1)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:518)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:556)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:527)
    at templates.postprocess.BindingSample.main(BindingSample.java:23)

Upvotes: 1

Views: 704

Answers (1)

ernest_k
ernest_k

Reputation: 45329

You cannot, and probably shouldn't try to, "escape" the dot in variable identifiers. That's because when the script references sample.name, Groovy will try to read the name property of an object in a variable named sample.

If you really (really really) need to use that identifier, then perhaps you should use getProperty directly, although this shouldn't be done in normal script code... The following worked:

String expression = "getProperty('sample.name') == 'ben' ||  getProperty('sample.name') == 'mark' || getProperty('sample.name') == 'trae'";

Also note that your comparison doesn't quote string literals, and that's another reason for failures in that expression.

You have yet another alternative, that of using a map:

Map<String, String> m = new HashMap<>();
m.put("name", "ben");
binding.setVariable("sample", m);

And this should allow you to run your expression as it was (with literals in quotes, of course)

Upvotes: 1

Related Questions