Q:

Using groovy Eval to process generated expression

I'm trying to create a field mapping to map fields from user-friendly names to member variables in a variety of domain objects. The larger context is that I'm building up an ElasticSearch query based on user-constructed rules stored in a database, but for the sake of MCVE:
class MyClass {
  Integer amount = 123
}

target = new MyClass()
println "${target.amount}"

fieldMapping = [
  'TUITION' : 'target.amount'
]

fieldName = 'TUITION'
valueSource = '${' + "${fieldMapping[fieldName]}" + '}'
println valueSource

value = Eval.me('valueSource')

The Eval fails. Here's the output:
123
${target.amount}
Caught: groovy.lang.MissingPropertyException: No such property: valueSource for class: Script1
groovy.lang.MissingPropertyException: No such property: valueSource for class: Script1
    at Script1.run(Script1.groovy:1)
    at t.run(t.groovy:17)

What's necessary to evaluate the generated variable name and return the value 123? It seems like the real problem is that it's not recognizing that valueSource has been defined, not the actual expression held in valueSource, but that could be wring, too.

A:

You're almost there, but you need to use a slightly different mechanism: the GroovyShell. You can instantiate a GroovyShell and use it to evaluate a String as a script, returning the result. Here's your example, modified to work properly:
class MyClass {
    Integer amount = 123
}

target = new MyClass()

fieldMapping = [
        'TUITION' : 'target.amount'
]
fieldName = 'TUITION'

// These are the values made available to the script through the Binding
args = [target: target]

// Create the shell with the binding as a parameter
shell = new GroovyShell(args as Binding)

// Evaluate the "script", which in this case is just the string "target.amount".
// Inside the shell, "target" is available because you added it to the shell's binding.
result = shell.evaluate(fieldMapping[fieldName])

assert result == 123
assert result instanceof Integer

