Reputation: 9191
I have an app that I wanted to customize using some sort of expression evaluator. I wanted to change certain parts of the app without recompiling my code. I am thinking of using groovy expression.
Say for example, I have a feature that can be enabled/disabled by supplying expression:
In this case, this feature will be enabled
Example 1:
EXPRESSION : status = part-time || status = hourly
INPUT: status = part-time
In this case, this feature will be disabled
Example 2:
EXPRESSION : status = part-time || status = hourly
INPUT: status = permanent
Users are required to enter an expression and an Input. Expression should evaluate to a boolean expression
They can also change the expression and the program will pick up this by some evaluation. These expressions by the way are documented and is exposed by me to the user of my application
Example 3:
EXPRESSION : salary > 10000
INPUT: salary = 7000
I have seen a program before that does this and they say that they uses groovy under the hood. But I cannot get my head wrap around the concept.
Can somebody please give me an idea?
Upvotes: 5
Views: 2897
Reputation: 21073
Alternative approach using evaluate
. Your variables are defined in binding, evaluate
contains the expression:
// setup binding
def emp = [status:'permanent', name:'Hugo']
def binding = new Binding()
binding.status = 'permanent'
binding.status2 = 'part-time'
binding.salary = 7000
binding.employee = emp
println binding.variables
// evaluate the script
def ret = new GroovyShell(binding).evaluate("status == 'part-time' || status == 'hourly'")
println ret
ret = new GroovyShell(binding).evaluate("status2 == 'part-time' || status2 == 'hourly'")
println ret
ret = new GroovyShell(binding).evaluate("salary > 10000")
println ret
ret = new GroovyShell(binding).evaluate("employee.status == 'permanent' || employee.status == 'hourly'")
println ret
returns
[status:permanent, status2:part-time, salary:7000, employee:[status:permanent, name:Hugo]]
false
true
false
true
Upvotes: 3
Reputation: 28564
the usual call of groovy script:
import groovy.lang.Binding;
import groovy.lang.Script;
import groovy.lang.GroovyShell;
Binding binding = new Binding();
binding.setProperty("status", "part-time");
GroovyShell shell = new GroovyShell(binding);
Script script = shell.parse(" status == 'part-time' || status == 'hourly' ");
Object result = script.run();
after run the binding will be populated with new values of the variables.
you can cache the parsed script (or class of the parsed script) because parsing/compiling is expensive process.
as alternative - the easiest script evaluation:
Object result = groovy.util.Eval.me("status", "part-time",
" status == 'part-time' || status == 'hourly' ");
Upvotes: 2