@Test public void testScenario02_ComparingNames() throws Exception { SpelExpressionParser parser = new SpelExpressionParser(); StandardEvaluationContext ctx = new StandardEvaluationContext(); ctx.addPropertyAccessor(new SecurityPrincipalAccessor()); // Multiple options for supporting this expression: "p.name == principal.name" // (1) If the right person is the root context object then "name==principal.name" is good enough Expression expr = parser.parseRaw("name == principal.name"); ctx.setRootObject(new Person("Andy")); Boolean value = expr.getValue(ctx, Boolean.class); Assert.assertTrue(value); ctx.setRootObject(new Person("Christian")); value = expr.getValue(ctx, Boolean.class); Assert.assertFalse(value); // (2) Or register an accessor that can understand 'p' and return the right person expr = parser.parseRaw("p.name == principal.name"); PersonAccessor pAccessor = new PersonAccessor(); ctx.addPropertyAccessor(pAccessor); ctx.setRootObject(null); pAccessor.setPerson(new Person("Andy")); value = expr.getValue(ctx, Boolean.class); Assert.assertTrue(value); pAccessor.setPerson(new Person("Christian")); value = expr.getValue(ctx, Boolean.class); Assert.assertFalse(value); }
// Here i'm going to change which hasRole() executes and make it one of my own Java methods @Test public void testScenario04_ControllingWhichMethodsRun() throws Exception { SpelExpressionParser parser = new SpelExpressionParser(); StandardEvaluationContext ctx = new StandardEvaluationContext(); ctx.setRootObject( new Supervisor( "Ben")); // so non-qualified references 'hasRole()' 'hasIpAddress()' are invoked against // it); ctx.addMethodResolver( new MyMethodResolver()); // NEEDS TO OVERRIDE THE REFLECTION ONE - SHOW REORDERING MECHANISM // Might be better with a as a variable although it would work as a property too... // Variable references using a '#' // SpelExpression expr = parser.parseExpression("(hasRole('SUPERVISOR') or (#a < 1.042)) and // hasIpAddress('10.10.0.0/16')"); Expression expr = parser.parseRaw("(hasRole(3) or (#a < 1.042)) and hasIpAddress('10.10.0.0/16')"); Boolean value = null; ctx.setVariable("a", 1.0d); // referenced as #a in the expression value = expr.getValue(ctx, Boolean.class); Assert.assertTrue(value); // ctx.setRootObject(new Manager("Luke")); // ctx.setVariable("a",1.043d); // value = (Boolean)expr.getValue(ctx,Boolean.class); // assertFalse(value); }
@Test public void testScenario03_Arithmetic() throws Exception { SpelExpressionParser parser = new SpelExpressionParser(); StandardEvaluationContext ctx = new StandardEvaluationContext(); // Might be better with a as a variable although it would work as a property too... // Variable references using a '#' Expression expr = parser.parseRaw( "(hasRole('SUPERVISOR') or (#a < 1.042)) and hasIpAddress('10.10.0.0/16')"); Boolean value = null; ctx.setVariable("a", 1.0d); // referenced as #a in the expression ctx.setRootObject( new Supervisor( "Ben")); // so non-qualified references 'hasRole()' 'hasIpAddress()' are invoked against // it value = expr.getValue(ctx, Boolean.class); Assert.assertTrue(value); ctx.setRootObject(new Manager("Luke")); ctx.setVariable("a", 1.043d); value = expr.getValue(ctx, Boolean.class); Assert.assertFalse(value); }
private MessageHandler neoFindEntityTags() { SpelExpressionParser expressionParser = new SpelExpressionParser(); HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler(getEntityTags()); handler.setExpectedResponseTypeExpression( expressionParser.parseExpression("T (org.flockdata.model.EntityTag[])")); Map<String, Expression> vars = new HashMap<>(); vars.put("entityId", expressionParser.parseExpression("payload[0]")); handler.setUriVariableExpressions(vars); handler.setHttpMethod(HttpMethod.GET); return handler; }
/** * Extracts principal name from authentication. * * @param authentication Authentication object * @return principal name */ static String extractName(Object authentication) { if (authentication != null) { Expression expression = PARSER.parseExpression(NAME_EXPRESSION); return expression.getValue(authentication, String.class); } return null; }
@Test public void canCallMethodsOnVariables() throws Exception { ctx.setVariable("var", "somestring"); Expression e = parser.parseExpression("#var.length() == 10"); assertThat(ExpressionUtils.evaluateAsBoolean(e, ctx)).isTrue(); }
/** * Parse values to {@link SpelExpression} * * @return */ protected SpelExpression getExpression() { if (this.expression == null) { this.expression = parser.parseRaw(buildExpressionForPath()); } return this.expression; }
private MessageHandler neoFindEntityTag() { SpelExpressionParser expressionParser = new SpelExpressionParser(); HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler(getEntityTag()); handler.setExpectedResponseType(AbstractEntityTag.class); Map<String, Expression> vars = new HashMap<>(); vars.put("entityId", expressionParser.parseExpression("payload[0]")); vars.put("tagType", expressionParser.parseExpression("payload[1]")); vars.put("tagCode", expressionParser.parseExpression("payload[2]")); vars.put("relationshipType", expressionParser.parseExpression("payload[3]")); handler.setUriVariableExpressions(vars); handler.setHttpMethod(HttpMethod.GET); return handler; }
@Bean public MessageHandler cassandraMessageHandler4() { CassandraMessageHandler<Book> cassandraMessageHandler = new CassandraMessageHandler<>(this.template); // TODO https://jira.spring.io/browse/DATACASS-213 // cassandraMessageHandler.setQuery("SELECT * FROM book WHERE author = :author limit :size"); cassandraMessageHandler.setQuery("SELECT * FROM book limit :size"); Map<String, Expression> params = new HashMap<>(); params.put("author", PARSER.parseExpression("payload")); params.put("size", PARSER.parseExpression("headers.limit")); cassandraMessageHandler.setParameterExpressions(params); cassandraMessageHandler.setOutputChannel(resultChannel()); cassandraMessageHandler.setProducesReply(true); return cassandraMessageHandler; }
public void setNullResultPropertyExpressions( Map<String, Expression> nullResultPropertyExpressions) { Map<Expression, Expression> localMap = new HashMap<Expression, Expression>(nullResultPropertyExpressions.size()); for (Map.Entry<String, Expression> entry : nullResultPropertyExpressions.entrySet()) { String key = entry.getKey(); Expression value = entry.getValue(); localMap.put(parser.parseExpression(key), value); } this.nullResultPropertyExpressions = localMap; }
@Test public void testScenario01_Roles() throws Exception { try { SpelExpressionParser parser = new SpelExpressionParser(); StandardEvaluationContext ctx = new StandardEvaluationContext(); Expression expr = parser.parseRaw("hasAnyRole('MANAGER','TELLER')"); ctx.setRootObject(new Person("Ben")); Boolean value = expr.getValue(ctx, Boolean.class); Assert.assertFalse(value); ctx.setRootObject(new Manager("Luke")); value = expr.getValue(ctx, Boolean.class); Assert.assertTrue(value); } catch (EvaluationException ee) { ee.printStackTrace(); Assert.fail("Unexpected SpelException: " + ee.getMessage()); } }
@Test public void hasPermissionOnDomainObjectWorksWithIntegerExpressions() throws Exception { final Object dummyDomainObject = new Object(); ctx.setVariable("domainObject", dummyDomainObject); final PermissionEvaluator pe = mock(PermissionEvaluator.class); root.setPermissionEvaluator(pe); when(pe.hasPermission(eq(user), eq(dummyDomainObject), any(Integer.class))) .thenReturn(true) .thenReturn(true) .thenReturn(false); Expression e = parser.parseExpression("hasPermission(#domainObject, 0xA)"); // evaluator returns true assertThat(ExpressionUtils.evaluateAsBoolean(e, ctx)).isTrue(); e = parser.parseExpression("hasPermission(#domainObject, 10)"); // evaluator returns true assertThat(ExpressionUtils.evaluateAsBoolean(e, ctx)).isTrue(); e = parser.parseExpression("hasPermission(#domainObject, 0xFF)"); // evaluator returns false, make sure return value matches assertThat(ExpressionUtils.evaluateAsBoolean(e, ctx)).isFalse(); }
@Test public void testMethodFiltering_SPR6764() { SpelExpressionParser parser = new SpelExpressionParser(); StandardEvaluationContext context = new StandardEvaluationContext(); context.setRootObject(new TestObject()); LocalFilter filter = new LocalFilter(); context.registerMethodFilter(TestObject.class, filter); // Filter will be called but not do anything, so first doit() will be invoked SpelExpression expr = (SpelExpression) parser.parseExpression("doit(1)"); String result = expr.getValue(context, String.class); Assert.assertEquals("1", result); Assert.assertTrue(filter.filterCalled); // Filter will now remove non @Anno annotated methods filter.removeIfNotAnnotated = true; filter.filterCalled = false; expr = (SpelExpression) parser.parseExpression("doit(1)"); result = expr.getValue(context, String.class); Assert.assertEquals("double 1.0", result); Assert.assertTrue(filter.filterCalled); // check not called for other types filter.filterCalled = false; context.setRootObject(new String("abc")); expr = (SpelExpression) parser.parseExpression("charAt(0)"); result = expr.getValue(context, String.class); Assert.assertEquals("a", result); Assert.assertFalse(filter.filterCalled); // check de-registration works filter.filterCalled = false; context.registerMethodFilter(TestObject.class, null); // clear filter context.setRootObject(new TestObject()); expr = (SpelExpression) parser.parseExpression("doit(1)"); result = expr.getValue(context, String.class); Assert.assertEquals("1", result); Assert.assertFalse(filter.filterCalled); }
@Test public void hasPermissionWorksWithThisObject() throws Exception { Object targetObject = new Object() { public String getX() { return "x"; } }; root.setThis(targetObject); Integer i = 2; PermissionEvaluator pe = mock(PermissionEvaluator.class); root.setPermissionEvaluator(pe); when(pe.hasPermission(user, targetObject, i)).thenReturn(true).thenReturn(false); when(pe.hasPermission(user, "x", i)).thenReturn(true); Expression e = parser.parseExpression("hasPermission(this, 2)"); assertThat(ExpressionUtils.evaluateAsBoolean(e, ctx)).isTrue(); e = parser.parseExpression("hasPermission(this, 2)"); assertThat(ExpressionUtils.evaluateAsBoolean(e, ctx)).isFalse(); e = parser.parseExpression("hasPermission(this.x, 2)"); assertThat(ExpressionUtils.evaluateAsBoolean(e, ctx)).isTrue(); }
/** * Check on first usage (when the cachedExecutor in MethodReference is null) that the exception is * not wrapped. */ @Test public void testMethodThrowingException_SPR6941() { // Test method on inventor: throwException() // On 1 it will throw an IllegalArgumentException // On 2 it will throw a RuntimeException // On 3 it will exit normally // In each case it increments the Inventor field 'counter' when invoked SpelExpressionParser parser = new SpelExpressionParser(); Expression expr = parser.parseExpression("throwException(#bar)"); eContext.setVariable("bar", 2); try { expr.getValue(eContext); Assert.fail(); } catch (Exception e) { if (e instanceof SpelEvaluationException) { e.printStackTrace(); Assert.fail("Should not be a SpelEvaluationException"); } // normal } }
/** * Provide the map of expressions to evaluate when enriching the target payload. The keys should * simply be property names, and the values should be Expressions that will evaluate against the * reply Message as the root object. * * @param propertyExpressions The property expressions. */ public void setPropertyExpressions(Map<String, Expression> propertyExpressions) { Assert.notEmpty(propertyExpressions, "propertyExpressions must not be empty"); Assert.noNullElements( propertyExpressions.keySet().toArray(), "propertyExpressions keys must not be empty"); Assert.noNullElements( propertyExpressions.values().toArray(), "propertyExpressions values must not be empty"); Map<Expression, Expression> localMap = new HashMap<Expression, Expression>(propertyExpressions.size()); for (Map.Entry<String, Expression> entry : propertyExpressions.entrySet()) { String key = entry.getKey(); Expression value = entry.getValue(); localMap.put(parser.parseExpression(key), value); } this.propertyExpressions = localMap; }
@Test public void testMethodThrowingException_SPR6941_2() { // Test method on inventor: throwException() // On 1 it will throw an IllegalArgumentException // On 2 it will throw a RuntimeException // On 3 it will exit normally // In each case it increments the Inventor field 'counter' when invoked SpelExpressionParser parser = new SpelExpressionParser(); Expression expr = parser.parseExpression("throwException(#bar)"); eContext.setVariable("bar", 4); try { expr.getValue(eContext); Assert.fail(); } catch (ExpressionInvocationTargetException e) { Throwable t = e.getCause(); Assert.assertEquals( "org.springframework.expression.spel.testresources.Inventor$TestException", t.getClass().getName()); return; } Assert.fail("Should not be a SpelEvaluationException"); }
public void setSubject(String subject) { this.subject = parser.parseExpression(subject, ParserContext.TEMPLATE_EXPRESSION); }
public void setText(String text) { this.text = parser.parseExpression(text, ParserContext.TEMPLATE_EXPRESSION); }
private Expression generateExpression(Method method) { StringBuilder sb = new StringBuilder("#target." + method.getName() + "("); Class<?>[] parameterTypes = method.getParameterTypes(); Annotation[][] parameterAnnotations = method.getParameterAnnotations(); boolean hasUnqualifiedMapParameter = false; for (int i = 0; i < parameterTypes.length; i++) { if (i != 0) { sb.append(", "); } MethodParameter methodParameter = new MethodParameter(method, i); TypeDescriptor parameterTypeDescriptor = new TypeDescriptor(methodParameter); Class<?> parameterType = parameterTypeDescriptor.getObjectType(); Annotation mappingAnnotation = findMappingAnnotation(parameterAnnotations[i]); if (mappingAnnotation != null) { Class<? extends Annotation> annotationType = mappingAnnotation.annotationType(); if (annotationType.equals(Payload.class)) { sb.append("payload"); String qualifierExpression = ((Payload) mappingAnnotation).value(); if (StringUtils.hasText(qualifierExpression)) { sb.append("." + qualifierExpression); } if (!StringUtils.hasText(qualifierExpression)) { this.setExclusiveTargetParameterType(parameterTypeDescriptor, methodParameter); } } if (annotationType.equals(Payloads.class)) { sb.append("messages.![payload"); String qualifierExpression = ((Payloads) mappingAnnotation).value(); if (StringUtils.hasText(qualifierExpression)) { sb.append("." + qualifierExpression); } sb.append("]"); if (!StringUtils.hasText(qualifierExpression)) { this.setExclusiveTargetParameterType(parameterTypeDescriptor, methodParameter); } } else if (annotationType.equals(Headers.class)) { Assert.isTrue( Map.class.isAssignableFrom(parameterType), "The @Headers annotation can only be applied to a Map-typed parameter."); sb.append("headers"); } else if (annotationType.equals(Header.class)) { Header headerAnnotation = (Header) mappingAnnotation; sb.append(this.determineHeaderExpression(headerAnnotation, methodParameter)); } } else if (parameterTypeDescriptor.isAssignableTo(messageTypeDescriptor)) { this.messageMethod = true; sb.append("message"); this.setExclusiveTargetParameterType(parameterTypeDescriptor, methodParameter); } else if ((parameterTypeDescriptor.isAssignableTo(messageListTypeDescriptor) || parameterTypeDescriptor.isAssignableTo(messageArrayTypeDescriptor))) { sb.append("messages"); this.setExclusiveTargetParameterType(parameterTypeDescriptor, methodParameter); } else if (Collection.class.isAssignableFrom(parameterType) || parameterType.isArray()) { if (canProcessMessageList) { sb.append("messages.![payload]"); } else { sb.append("payload"); } this.setExclusiveTargetParameterType(parameterTypeDescriptor, methodParameter); } else if (Iterator.class.isAssignableFrom(parameterType)) { if (canProcessMessageList) { Type type = method.getGenericParameterTypes()[i]; Type parameterizedType = null; if (type instanceof ParameterizedType) { parameterizedType = ((ParameterizedType) type).getActualTypeArguments()[0]; if (parameterizedType instanceof ParameterizedType) { parameterizedType = ((ParameterizedType) parameterizedType).getRawType(); } } if (parameterizedType != null && Message.class.isAssignableFrom((Class<?>) parameterizedType)) { sb.append("messages.iterator()"); } else { sb.append("messages.![payload].iterator()"); } } else { sb.append("payload.iterator()"); } this.setExclusiveTargetParameterType(parameterTypeDescriptor, methodParameter); } else if (Map.class.isAssignableFrom(parameterType)) { if (Properties.class.isAssignableFrom(parameterType)) { sb.append( "payload instanceof T(java.util.Map) or " + "(payload instanceof T(String) and payload.contains('=')) ? payload : headers"); } else { sb.append("(payload instanceof T(java.util.Map) ? payload : headers)"); } Assert.isTrue( !hasUnqualifiedMapParameter, "Found more than one Map typed parameter without any qualification. " + "Consider using @Payload or @Headers on at least one of the parameters."); hasUnqualifiedMapParameter = true; } else { sb.append("payload"); this.setExclusiveTargetParameterType(parameterTypeDescriptor, methodParameter); } } if (hasUnqualifiedMapParameter) { if (targetParameterType != null && Map.class.isAssignableFrom(this.targetParameterType)) { throw new IllegalArgumentException( "Unable to determine payload matching parameter due to ambiguous Map typed parameters. " + "Consider adding the @Payload and or @Headers annotations as appropriate."); } } sb.append(")"); if (this.targetParameterTypeDescriptor == null) { this.targetParameterTypeDescriptor = TypeDescriptor.valueOf(Void.class); } return EXPRESSION_PARSER.parseExpression(sb.toString()); }
public MailNotifier(MailSender sender) { this.sender = sender; this.subject = parser.parseExpression(DEFAULT_SUBJECT, ParserContext.TEMPLATE_EXPRESSION); this.text = parser.parseExpression(DEFAULT_TEXT, ParserContext.TEMPLATE_EXPRESSION); }
@Test public void testMethodThrowingException_SPR6760() { // Test method on inventor: throwException() // On 1 it will throw an IllegalArgumentException // On 2 it will throw a RuntimeException // On 3 it will exit normally // In each case it increments the Inventor field 'counter' when invoked SpelExpressionParser parser = new SpelExpressionParser(); Expression expr = parser.parseExpression("throwException(#bar)"); // Normal exit StandardEvaluationContext eContext = TestScenarioCreator.getTestEvaluationContext(); eContext.setVariable("bar", 3); Object o = expr.getValue(eContext); Assert.assertEquals(o, 3); Assert.assertEquals(1, parser.parseExpression("counter").getValue(eContext)); // Now the expression has cached that throwException(int) is the right thing to call // Let's change 'bar' to be a PlaceOfBirth which indicates the cached reference is // out of date. eContext.setVariable("bar", new PlaceOfBirth("London")); o = expr.getValue(eContext); Assert.assertEquals("London", o); // That confirms the logic to mark the cached reference stale and retry is working // Now let's cause the method to exit via exception and ensure it doesn't cause // a retry. // First, switch back to throwException(int) eContext.setVariable("bar", 3); o = expr.getValue(eContext); Assert.assertEquals(3, o); Assert.assertEquals(2, parser.parseExpression("counter").getValue(eContext)); // Now cause it to throw an exception: eContext.setVariable("bar", 1); try { o = expr.getValue(eContext); Assert.fail(); } catch (Exception e) { if (e instanceof SpelEvaluationException) { e.printStackTrace(); Assert.fail("Should not be a SpelEvaluationException"); } // normal } // If counter is 4 then the method got called twice! Assert.assertEquals(3, parser.parseExpression("counter").getValue(eContext)); eContext.setVariable("bar", 4); try { o = expr.getValue(eContext); Assert.fail(); } catch (Exception e) { // 4 means it will throw a checked exception - this will be wrapped if (!(e instanceof ExpressionInvocationTargetException)) { e.printStackTrace(); Assert.fail("Should have been wrapped"); } // normal } // If counter is 5 then the method got called twice! Assert.assertEquals(4, parser.parseExpression("counter").getValue(eContext)); }