2012-08-06 6 views
1

프로그래밍 방식 구성에 사용되는 일부 EL 평가가 포함 된 응용 프로그램이 있습니다. EL 표현식이 주어지면 실제로 평가하지 않고 포함 된 자유 변수를 얻고 싶습니다. 최종 사용자가 "평가"버튼을 누르기 전에 변수를 자유 변수에 바인딩 할 수있는 UI를 제공하기위한 것입니다.EL 표현식에 자유 변수 나열

불행히도 javax.el.ValueExpression은이 기능을 제공하지 않으므로 공급 업체 특정 API를 사용해야 할 수도 있습니다. 개발 초기 단계이기 때문에 아직 구현 방법을 선택하지 않았습니다. 나는 MVEL, JUEL, SpEL에 대해 생각해 왔지만, 내가 선택한 것은 위에서 설명한 기능을 가지고 있어야한다. 이것에 대해 ...

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

답변

1

MVEL의 ParserContext에이 지역 주민과 입력에 의해 조직 된 변수에 대해 모든 것을 알 수있는 방법

3

.

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")); 
+0

재미있어 보입니다. – Saintali

1

게리의 대답은 좋지만 표현식에 단일 변수가 포함 된 경우 나에게 적합하지 않습니다. "#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; 
}