2016-08-10 4 views
1

Я пытаюсь создать сопоставление полей для сопоставления полей от удобных имен к переменным-членам в различных объектах домена. Чем больше контекста, что я построение запроса ElasticSearch на основе пользовательских построенных правил, хранящихся в базе данных, но ради MCVE:Использование groovy Eval для обработки сгенерированного выражения

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') 

Eval терпит неудачу. Вот результат:

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) 

Что необходимо оценить сгенерированное имя переменной и возвращает значение 123? Похоже, что реальная проблема заключается в том, что она не признает, что определено valueSource, а не фактическое выражение, содержащееся в valueSource, но это тоже может быть отжато.

+0

Я думал, что 'оценка()' может работать, но это просто для скриптов и не работает в контексте приложения grails. –

+0

Посмотрите на [docs] (http://docs.groovy-lang.org/latest/html/api/groovy/util/Eval.html) для Eval. Эти методы не знают о том, с какой целью вы их вызываете. Чтобы сделать доступным 'valueSource', вам нужно будет вызвать' Eval.me' с 'symbol' и' object' или вызвать один из методов 'x' /' xy'/'xyz'. – hsan

+0

Я смотрел документы. Благодарю. –

ответ

2

Вы почти там, но вам нужно использовать несколько иной механизм: GroovyShell. Вы можете создать экземпляр GroovyShell и использовать его для оценки String в качестве скрипта, возвращающего результат. Вот ваш пример, измененный для правильной работы:

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 
Смежные вопросы