diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java index 2bdd8d77811..9f56baa947c 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java @@ -97,11 +97,20 @@ public class StandardEvaluationContext implements EvaluationContext { ensureConstructorResolversInitialized(); this.constructorResolvers.add(this.constructorResolvers.size() - 1, resolver); } + + public boolean removeConstructorResolver(ConstructorResolver resolver) { + ensureConstructorResolversInitialized(); + return this.constructorResolvers.remove(resolver); + } public List getConstructorResolvers() { ensureConstructorResolversInitialized(); return this.constructorResolvers; } + + public void setConstructorResolvers(List constructorResolvers) { + this.constructorResolvers = constructorResolvers; + } private void ensureConstructorResolversInitialized() { if (this.constructorResolvers == null) { @@ -114,11 +123,20 @@ public class StandardEvaluationContext implements EvaluationContext { ensureMethodResolversInitialized(); this.methodResolvers.add(this.methodResolvers.size() - 1, resolver); } + + public boolean removeMethodResolver(MethodResolver methodResolver) { + ensureMethodResolversInitialized(); + return this.methodResolvers.remove(methodResolver); + } public List getMethodResolvers() { ensureMethodResolversInitialized(); return this.methodResolvers; } + + public void setMethodResolvers(List methodResolvers) { + this.methodResolvers = methodResolvers; + } private void ensureMethodResolversInitialized() { if (this.methodResolvers == null) { @@ -131,11 +149,19 @@ public class StandardEvaluationContext implements EvaluationContext { ensurePropertyAccessorsInitialized(); this.propertyAccessors.add(this.propertyAccessors.size() - 1, accessor); } + + public boolean removePropertyAccessor(PropertyAccessor accessor) { + return this.propertyAccessors.remove(accessor); + } public List getPropertyAccessors() { ensurePropertyAccessorsInitialized(); return this.propertyAccessors; } + + public void setPropertyAccessors(List propertyAccessors) { + this.propertyAccessors = propertyAccessors; + } private void ensurePropertyAccessorsInitialized() { if (this.propertyAccessors == null) { diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/ConstructorInvocationTests.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/ConstructorInvocationTests.java index 2e6adf3b374..e02f340992c 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/ConstructorInvocationTests.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/ConstructorInvocationTests.java @@ -16,9 +16,16 @@ package org.springframework.expression.spel; +import java.util.ArrayList; +import java.util.List; + import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; +import org.springframework.expression.AccessException; +import org.springframework.expression.ConstructorExecutor; +import org.springframework.expression.ConstructorResolver; +import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; @@ -140,6 +147,37 @@ public class ConstructorInvocationTests extends ExpressionTestCase { Assert.assertEquals(4,parser.parseExpression("counter").getValue(eContext)); } + @Test + public void testAddingConstructorResolvers() { + StandardEvaluationContext ctx = new StandardEvaluationContext(); + + // reflective constructor accessor is the only one by default + List constructorResolvers = ctx.getConstructorResolvers(); + Assert.assertEquals(1,constructorResolvers.size()); + + ConstructorResolver dummy = new DummyConstructorResolver(); + ctx.addConstructorResolver(dummy); + Assert.assertEquals(2,ctx.getConstructorResolvers().size()); + + List copy = new ArrayList(); + copy.addAll(ctx.getConstructorResolvers()); + Assert.assertTrue(ctx.removeConstructorResolver(dummy)); + Assert.assertFalse(ctx.removeConstructorResolver(dummy)); + Assert.assertEquals(1,ctx.getConstructorResolvers().size()); + + ctx.setConstructorResolvers(copy); + Assert.assertEquals(2,ctx.getConstructorResolvers().size()); + } + + static class DummyConstructorResolver implements ConstructorResolver { + + public ConstructorExecutor resolve(EvaluationContext context, String typeName, Class[] argumentTypes) + throws AccessException { + throw new UnsupportedOperationException("Auto-generated method stub"); + } + + } + @Test public void testVarargsInvocation01() { // Calling 'Fruit(String... strings)' diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java index d25bc127ba5..617b9883823 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java @@ -25,8 +25,12 @@ import java.util.List; import org.junit.Assert; import org.junit.Test; +import org.springframework.expression.AccessException; +import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; +import org.springframework.expression.MethodExecutor; import org.springframework.expression.MethodFilter; +import org.springframework.expression.MethodResolver; import org.springframework.expression.spel.standard.SpelExpression; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; @@ -243,6 +247,38 @@ public class MethodInvocationTests extends ExpressionTestCase { } } + + @Test + public void testAddingMethodResolvers() { + StandardEvaluationContext ctx = new StandardEvaluationContext(); + + // reflective method accessor is the only one by default + List methodResolvers = ctx.getMethodResolvers(); + Assert.assertEquals(1,methodResolvers.size()); + + MethodResolver dummy = new DummyMethodResolver(); + ctx.addMethodResolver(dummy); + Assert.assertEquals(2,ctx.getMethodResolvers().size()); + + List copy = new ArrayList(); + copy.addAll(ctx.getMethodResolvers()); + Assert.assertTrue(ctx.removeMethodResolver(dummy)); + Assert.assertFalse(ctx.removeMethodResolver(dummy)); + Assert.assertEquals(1,ctx.getMethodResolvers().size()); + + ctx.setMethodResolvers(copy); + Assert.assertEquals(2,ctx.getMethodResolvers().size()); + } + + static class DummyMethodResolver implements MethodResolver { + + public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name, + Class[] argumentTypes) throws AccessException { + throw new UnsupportedOperationException("Auto-generated method stub"); + } + + } + @Test public void testVarargsInvocation01() { diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/PropertyAccessTests.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/PropertyAccessTests.java index e33fdf26070..9cb89d55975 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/PropertyAccessTests.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/PropertyAccessTests.java @@ -16,6 +16,9 @@ package org.springframework.expression.spel; +import java.util.ArrayList; +import java.util.List; + import junit.framework.Assert; import org.junit.Test; @@ -129,6 +132,28 @@ public class PropertyAccessTests extends ExpressionTestCase { // System.out.println(e.getMessage()); } } + + @Test + public void testAddingRemovingAccessors() { + StandardEvaluationContext ctx = new StandardEvaluationContext(); + + // reflective property accessor is the only one by default + List propertyAccessors = ctx.getPropertyAccessors(); + Assert.assertEquals(1,propertyAccessors.size()); + + StringyPropertyAccessor spa = new StringyPropertyAccessor(); + ctx.addPropertyAccessor(spa); + Assert.assertEquals(2,ctx.getPropertyAccessors().size()); + + List copy = new ArrayList(); + copy.addAll(ctx.getPropertyAccessors()); + Assert.assertTrue(ctx.removePropertyAccessor(spa)); + Assert.assertFalse(ctx.removePropertyAccessor(spa)); + Assert.assertEquals(1,ctx.getPropertyAccessors().size()); + + ctx.setPropertyAccessors(copy); + Assert.assertEquals(2,ctx.getPropertyAccessors().size()); + } // This can resolve the property 'flibbles' on any String (very useful...)