Search code examples
javaspring-el

Elvis operator in Spring Expression Language (SpEL)


6.5.14 The Elvis Operator

I'm seeing some trange behaviour using the elvis operator in SpEL. If I don't surround the elvis expression in brackets "()" then the result of the elvis operator is returned and the rest of the expression is ignored. Sample Code showing the behaviour below:

    HashMap<String, String> facts = new HashMap<String, String>();
    facts.put("flag", "flagvalue");
    String expressionString;
    Expression expression;
    Object expressionResult;

    expressionString = "[flag]?:'' matches '(?i)flagvalue'";
    expression = new SpelExpressionParser().parseExpression(expressionString);
    expressionResult = expression.getValue(facts);
    System.out.println("Unexpected Result:" + expressionResult);

    expressionString = "([flag]?:'') matches '(?i)flagvalue'";
    expression = new SpelExpressionParser().parseExpression(expressionString);
    expressionResult = expression.getValue(facts);
    System.out.println("Expected Result:" + expressionResult);

Output:

    Unexpected Result:flagvalue
    Expected Result:true

The strange part is when the value is not in the hashmap (i.e comment the facts.put line) the elvis operator appears to work fine and both expressions return false as expected.

(using spring-framework-3.0.5)


Solution

  • I think you need to expand your example to the Java expression to understand the difference, which would look like this:

    System.out.println(facts.containsKey("flag") ? facts.get("flag") : "".matches("(?i)flagvalue"))
    System.out.println((facts.containsKey("flag") ? facts.get("flag") : "").matches("(?i)flagvalue"))
    

    which prints

    flagvalue
    true
    

    I haven't had a look inside the implementation, but I guess the '' matches '(?i)flagvalue' will be evaluated at first, because matches is a nested operator in the view of an expression tree.

    Hope this helps.