Does Spring support an IN statement?

Does Spring support an expression statement for an IN statement? Like the SQL IN clause.

public class Security {
 private secTyp1;
 public Security (String aSecTyp1) {
  secTyp1 = aSecTyp1;
 }
}

Security security = new Security("BOND");
StandardEvaluationContext context = new StandardEvaluationContext(security);
ExpressionParser parser = new SpelExpressionParser();
// This should return true
boolean result = parser.parseExpression("secTyp1 **IN** {'BOND','SWPI'}").getValue(context, Boolean.class); 
// This should return false
result = parser.parseExpression("secTyp1 **IN** {'FUT','SWPI'}").getValue(context, Boolean.class); 

I get the following exception

org.springframework.expression.spel.SpelParseException: EL1041E:(pos 8): After parsing a valid expression, there is still more data in the expression: 'IN'
    at org.springframework.expression.spel.standard.InternalSpelExpressionParser.doParseExpression(InternalSpelExpressionParser.java:118)
    at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:56)
    at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:1)
    at org.springframework.expression.common.TemplateAwareExpressionParser.parseExpression(TemplateAwareExpressionParser.java:66)
    at org.springframework.expression.common.TemplateAwareExpressionParser.parseExpression(TemplateAwareExpressionParser.java:56)
    at com.rules.AssignableSecurityRule.evaluateInCondition(AssignableSecurityRule.java:48)
    at com.rules.AssignableSecurityRuleTest.testINCondition(AssignableSecurityRuleTest.java:43)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
+5
source share
2 answers

It does not support the IN statement because you do not need it. Instead, you can use the Invokation function of the method.

So, calling .contains (..) on the list will do what you want.

You can try these two solutions.

    @Test
    public void solutionOneTest() {
      final Security security = new Security("BOND");
      final EvaluationContext context = new StandardEvaluationContext(security);

      Boolean contains = PARSER.parseExpression("{'BOND','SWPI'}.contains(#root.secTyp1)").getValue(context, Boolean.class);
      Assert.assertTrue(contains);

      contains = PARSER.parseExpression("{'FUT','SWPI'}.contains(#root.secTyp1)").getValue(context, Boolean.class);
      Assert.assertFalse(contains);
    }

    @Test
    public void solutionTwoTest() {
      final Security security = new Security("BOND");
      final EvaluationContext context = new StandardEvaluationContext();
      context.setVariable("sec", security);

      Boolean contains = PARSER.parseExpression("{'BOND','SWPI'}.contains(#sec.secTyp1)").getValue(context, Boolean.class);
      Assert.assertTrue(contains);

      contains = PARSER.parseExpression("{'FUT','SWPI'}.contains(#sec.secTyp1)").getValue(context, Boolean.class);
      Assert.assertFalse(contains);
    }
+5
source

, micfra, SpEL . Collection Selection , :

!{'BOND','SWPI'}.?[#this == 'BOND'].empty

, :

!securities.?[secTyp1 == 'BOND'].empty
0

All Articles