2012-08-06 39 views
1

我有一個應用程序,其中包含用於編程配置的一些EL評估。給定一個EL表達式,我想得到它包含的自由變量而不實際評估它。目的是提供一個用戶界面,最終用戶可以在按下「評估」按鈕之前將值綁定到自由變量。列出EL表達式中的自由變量

不幸的是javax.el.ValueExpression不提供此功能,所以我可能需要使用供應商特定的API。這是在開發早期,所以我還沒有確定我的選擇實施。我曾經想過MVEL,JUEL和SpEL,但是當然我選擇的應該有我上面描述的功能。

回答

1

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")); 
3

這個怎麼樣...

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; 
} 
+0

它看起來很有趣。 – Saintali 2012-08-07 12:32:52

1

Gary的回答很好,但當表達式包含單個變量時,它不起作用。 「#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; 
}