1

プログラム構成に使用されるEL評価を含むアプリケーションがあります。EL式が与えられた場合、実際に評価せずに、それに含まれる自由変数を取得したいと思います。目的は、エンドユーザーが「評価」ボタンを押す前に値を自由変数にバインドできるUIを提供することです。

残念ながらjavax.el.ValueExpression、この機能は提供されていないため、ベンダー固有のAPIを使用する必要がある場合があります。開発のかなり早い段階なので、実装の選択はまだ修正していません。私はMVEL、JUEL、SpELについて考えましたが、もちろん、私が選択したものはすべて、上記で説明した機能を備えている必要があります。

4

3 に答える 3

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;
}
于 2012-08-06T14:04:50.887 に答える
1

ゲイリーの答えは良いですが、式に「#var」(子のない1つのノード)などの単一の変数が含まれている場合は機能しませんでした。小さな変更:

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-07T17:19:06.387 に答える
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"));
于 2012-08-12T22:03:52.360 に答える