Список свободных переменных в выражении EL

57
9

У меня есть приложение, которое содержит некоторую оценку EL, используемую для программной конфигурации. Учитывая выражение EL, я хочу получить, какие свободные переменные он содержит, фактически не оценивая его. Цель состоит в том, чтобы предоставить пользовательский интерфейс, где конечные пользователи могут привязывать значения к свободным переменным, прежде чем нажимать кнопку "оценить".

К сожалению, javax.el.ValueExpression не предоставляет эту функцию, поэтому мне может понадобиться API-интерфейс, специфичный для конкретного поставщика. Это довольно рано в разработке, поэтому я еще не определился с выбором реализации. Я думал о MVEL, JUEL и SpEL, но, конечно, все, что я выбрал, должно иметь функциональность, описанную выше.

спросил(а) 2012-08-06T15:58:00+04:00 8 лет назад
1
Решение
56

MVEL ParserContext может рассказать вам все о переменных, организованных местными жителями и входами.

ParserContext ctx = ParserContext.create();
MVEL.analysisCompile("a = 0; b = 0;", ctx);

HashMap<String, Class> vars = ctx.getVariables();

assert vars.containsKey("a") && Number.class.isAssignableFrom(vars.get("a"));
assert vars.containsKey("b") && Number.class.isAssignableFrom(vars.get("b"));

ответил(а) 2012-08-13T01:03:00+04:00 7 лет, 12 месяцев назад
78

Как насчет этого...


    SpelExpression parseExpression = (SpelExpression) new SpelExpressionParser().parseExpression(expressionString);
SpelNode node = parseExpression.getAST();
List<String> vars = getVars(node);

...

private List<String> getVars(SpelNode node) {
List<String> vars = new ArrayList<String>();
for (int i = 0; i < node.getChildCount(); i++) {
SpelNode child = node.getChild(i);
if (child.getChildCount() > 0) {
vars.addAll(getVars(child));
}
else {
if (child instanceof VariableReference) {
vars.add(child.toStringAST());
}
}
}
return vars;
}

ответил(а) 2012-08-06T17:04:00+04:00 8 лет назад
55

Ответ Гэри хороший, но это не сработало для меня, когда выражение содержало одну переменную, например "#var" (один узел без детей). Небольшое изменение:

private Set<String> getVars(SpelNode node) {
Set<String> vars = new HashSet<String>();
if (node == null) {
return vars;
}

if (node instanceof VariableReference) {
// Remove the "#" to get the actual variable name
vars.add(StringUtils.remove(node.toStringAST(), "#"));
}

for (int i = 0; i < node.getChildCount(); i++) {
SpelNode child = node.getChild(i);
vars.addAll(getVars(child));
}

return vars;
}

ответил(а) 2012-11-07T20:19:00+04:00 7 лет, 9 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема