revised expression parser API design
This commit is contained in:
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.common;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.standard.StandardEvaluationContext;
|
||||
|
||||
/**
|
||||
* Test LiteralExpression
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class CompositeStringExpressionTests extends TestCase {
|
||||
|
||||
public void testGetValue() throws Exception {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression ex = parser.parseExpression("hello ${'world'}", DefaultTemplateParserContext.INSTANCE);
|
||||
checkString("hello world", ex.getValue());
|
||||
checkString("hello world", ex.getValue(String.class));
|
||||
EvaluationContext ctx = new StandardEvaluationContext();
|
||||
checkString("hello world", ex.getValue(ctx));
|
||||
checkString("hello world", ex.getValue(ctx, String.class));
|
||||
assertEquals("hello ${'world'}", ex.getExpressionString());
|
||||
assertFalse(ex.isWritable(new StandardEvaluationContext()));
|
||||
}
|
||||
|
||||
// public void testSetValue() {
|
||||
// try {
|
||||
// LiteralExpression lEx = new LiteralExpression("somevalue");
|
||||
// lEx.setValue(new StandardEvaluationContext(), "flibble");
|
||||
// fail("Should have got an exception that the value cannot be set");
|
||||
// } catch (EvaluationException ee) {
|
||||
// // success, not allowed - whilst here, check the expression value in the exception
|
||||
// assertEquals(ee.getExpressionString(), "somevalue");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void testGetValueType() throws Exception {
|
||||
// LiteralExpression lEx = new LiteralExpression("somevalue");
|
||||
// assertEquals(String.class, lEx.getValueType());
|
||||
// assertEquals(String.class, lEx.getValueType(new StandardEvaluationContext()));
|
||||
// }
|
||||
|
||||
private void checkString(String expectedString, Object value) {
|
||||
if (!(value instanceof String)) {
|
||||
fail("Result was not a string, it was of type " + value.getClass() + " (value=" + value + ")");
|
||||
}
|
||||
if (!((String) value).equals(expectedString)) {
|
||||
fail("Did not get expected result. Should have been '" + expectedString + "' but was '" + value + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.springframework.expression.common.CompositeStringExpressionTests;
|
||||
import org.springframework.expression.common.LiteralExpressionTests;
|
||||
|
||||
/**
|
||||
* Pulls together all the tests for Spring EL into a single suite.
|
||||
*
|
||||
* @author Andy Clement
|
||||
*
|
||||
*/
|
||||
public class AllTests {
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite("Spring Expression Language tests");
|
||||
// $JUnit-BEGIN$
|
||||
suite.addTestSuite(BooleanExpressionTests.class);
|
||||
suite.addTestSuite(LiteralTests.class);
|
||||
suite.addTestSuite(ParsingTests.class);
|
||||
suite.addTestSuite(VariableAndFunctionTests.class);
|
||||
suite.addTestSuite(ParserErrorMessagesTests.class);
|
||||
suite.addTestSuite(EvaluationTests.class);
|
||||
suite.addTestSuite(OperatorTests.class);
|
||||
suite.addTestSuite(ConstructorInvocationTests.class);
|
||||
suite.addTestSuite(MethodInvocationTests.class);
|
||||
suite.addTestSuite(PropertyAccessTests.class);
|
||||
suite.addTestSuite(TypeReferencing.class);
|
||||
suite.addTestSuite(PerformanceTests.class);
|
||||
suite.addTestSuite(DefaultComparatorUnitTests.class);
|
||||
suite.addTestSuite(TemplateExpressionParsingTests.class);
|
||||
suite.addTestSuite(ExpressionLanguageScenarioTests.class);
|
||||
suite.addTestSuite(ScenariosForSpringSecurity.class);
|
||||
suite.addTestSuite(MapAccessTests.class);
|
||||
suite.addTestSuite(SpelUtilitiesTests.class);
|
||||
suite.addTestSuite(LiteralExpressionTests.class);
|
||||
suite.addTestSuite(CompositeStringExpressionTests.class);
|
||||
// $JUnit-END$
|
||||
return suite;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,9 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import org.springframework.expression.spel.standard.StandardEvaluationContext;
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
/**
|
||||
* Tests invocation of constructors.
|
||||
@@ -93,20 +92,4 @@ public class ConstructorInvocationTests extends ExpressionTestCase {
|
||||
evaluate("new String(3.0d)", "3.0", String.class);
|
||||
}
|
||||
|
||||
public void testVarargsInvocation01() throws Exception {
|
||||
// Calling 'public TestCode(String... strings)'
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
ctx.setClasspath("target/test-classes/testcode.jar");
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
Object v = parser.parseExpression("new TestType('a','b','c')").getValue(ctx);
|
||||
v = parser.parseExpression("new TestType('a')").getValue(ctx);
|
||||
v = parser.parseExpression("new TestType()").getValue(ctx);
|
||||
v = parser.parseExpression("new TestType(1,2,3)").getValue(ctx);
|
||||
v = parser.parseExpression("new TestType(1)").getValue(ctx);
|
||||
v = parser.parseExpression("new TestType(1,'a',3.0d)").getValue(ctx);
|
||||
// v = parser.parseExpression("new TestType(new String[]{'a','b','c'})").getValue(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.TypeComparator;
|
||||
import org.springframework.expression.spel.standard.StandardComparator;
|
||||
import org.springframework.expression.spel.support.StandardTypeComparator;
|
||||
|
||||
/**
|
||||
* Unit tests for type comparison
|
||||
@@ -29,7 +29,7 @@ import org.springframework.expression.spel.standard.StandardComparator;
|
||||
public class DefaultComparatorUnitTests extends TestCase {
|
||||
|
||||
public void testPrimitives() throws EvaluationException {
|
||||
TypeComparator comparator = new StandardComparator();
|
||||
TypeComparator comparator = new StandardTypeComparator();
|
||||
// primitive int
|
||||
assertTrue(comparator.compare(1, 2) < 0);
|
||||
assertTrue(comparator.compare(1, 1) == 0);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
/**
|
||||
@@ -325,12 +326,6 @@ public class EvaluationTests extends ExpressionTestCase {
|
||||
evaluateAndCheckError("'hello'?1:2", SpelMessages.TYPE_CONVERSION_ERROR); // cannot convert String to boolean
|
||||
}
|
||||
|
||||
public void testTernaryOperator04() {
|
||||
// an int becomes TRUE if not 0, otherwise FALSE
|
||||
evaluate("12?1:2", 1, Integer.class); // int to boolean
|
||||
evaluate("1L?1:2", 1, Integer.class); // long to boolean
|
||||
}
|
||||
|
||||
// Indexer
|
||||
// public void testCutProcessor01() {
|
||||
// evaluate("{1,2,3,4,5}.cut(1,3)", "[2, 3, 4]", ArrayList.class);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,9 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@@ -23,16 +24,13 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.CacheablePropertyAccessor;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ParseException;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.PropertyReaderExecutor;
|
||||
import org.springframework.expression.PropertyWriterExecutor;
|
||||
import org.springframework.expression.spel.standard.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.standard.StandardIndividualTypeConverter;
|
||||
import org.springframework.expression.spel.antlr.SpelAntlrExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
/**
|
||||
* Testcases showing the common scenarios/use-cases for picking up the expression language support.
|
||||
@@ -63,7 +61,7 @@ public class ExpressionLanguageScenarioTests extends ExpressionTestCase {
|
||||
public void testScenario_UsingStandardInfrastructure() {
|
||||
try {
|
||||
// Create a parser
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
// Parse an expression
|
||||
Expression expr = parser.parseExpression("new String('hello world')");
|
||||
// Evaluate it using a 'standard' context
|
||||
@@ -82,43 +80,12 @@ public class ExpressionLanguageScenarioTests extends ExpressionTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scenario: using the standard context but adding a jar to the classpath and registering an import.
|
||||
*/
|
||||
public void testScenario_LoadingDifferentClassesAndUsingImports() {
|
||||
try {
|
||||
// Create a parser
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
// Use the standard evaluation context
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
// Set the classpath (creates a new classloader with this classpath and uses it)
|
||||
ctx.setClasspath("target/test-classes/testcode.jar");
|
||||
// Register an import (so types in a.b.c can be referred to by their short name)
|
||||
ctx.registerImport("a.b.c");
|
||||
|
||||
// Parse an expression (here, PackagedType is in package a.b.c)
|
||||
Expression expr = parser.parseExpression("new PackagedType().sayHi('Andy')");
|
||||
|
||||
// Evaluate the expression in our context
|
||||
Object value = expr.getValue(ctx);
|
||||
|
||||
assertEquals("Hi! Andy", value);
|
||||
assertEquals(String.class, value.getClass());
|
||||
} catch (EvaluationException ee) {
|
||||
ee.printStackTrace();
|
||||
fail("Unexpected Exception: " + ee.getMessage());
|
||||
} catch (ParseException pe) {
|
||||
pe.printStackTrace();
|
||||
fail("Unexpected Exception: " + pe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scenario: using the standard context but adding your own variables
|
||||
*/
|
||||
public void testScenario_DefiningVariablesThatWillBeAccessibleInExpressions() throws Exception {
|
||||
// Create a parser
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
// Use the standard evaluation context
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
ctx.setVariable("favouriteColour","blue");
|
||||
@@ -153,22 +120,21 @@ public class ExpressionLanguageScenarioTests extends ExpressionTestCase {
|
||||
*/
|
||||
public void testScenario_UsingADifferentRootContextObject() throws Exception {
|
||||
// Create a parser
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
// Use the standard evaluation context
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
|
||||
TestClass tc = new TestClass();
|
||||
tc.setProperty(42);
|
||||
tc.str = "wibble";
|
||||
|
||||
ctx.setRootObject(tc);
|
||||
|
||||
// read it, set it, read it again
|
||||
Expression expr = parser.parseExpression("str");
|
||||
Object value = expr.getValue(ctx);
|
||||
assertEquals("wibble", value);
|
||||
expr = parser.parseExpression("str");
|
||||
expr.setValue(ctx,"wobble");
|
||||
expr = parser.parseExpression("str");
|
||||
expr.setValue(ctx, "wobble");
|
||||
expr = parser.parseExpression("str");
|
||||
value = expr.getValue(ctx);
|
||||
assertEquals("wobble", value);
|
||||
@@ -200,7 +166,7 @@ public class ExpressionLanguageScenarioTests extends ExpressionTestCase {
|
||||
public void testScenario_RegisteringJavaMethodsAsFunctionsAndCallingThem() throws SecurityException, NoSuchMethodException {
|
||||
try {
|
||||
// Create a parser
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
// Use the standard evaluation context
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
ctx.registerFunction("repeat",ExpressionLanguageScenarioTests.class.getDeclaredMethod("repeat",String.class));
|
||||
@@ -221,40 +187,52 @@ public class ExpressionLanguageScenarioTests extends ExpressionTestCase {
|
||||
/**
|
||||
* Scenario: add a property resolver that will get called in the resolver chain, this one only supports reading.
|
||||
*/
|
||||
public void testScenario_AddingYourOwnPropertyResolvers_1() throws SecurityException, NoSuchMethodException {
|
||||
try {
|
||||
// Create a parser
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
// Use the standard evaluation context
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
|
||||
ctx.addPropertyAccessor(new FruitColourAccessor());
|
||||
Expression expr = parser.parseExpression("orange");
|
||||
Object value = expr.getValue(ctx);
|
||||
assertEquals(Color.orange,value);
|
||||
|
||||
try {
|
||||
expr.setValue(ctx,Color.blue);
|
||||
fail("Should not be allowed to set oranges to be blue !");
|
||||
} catch (EvaluationException ee) {
|
||||
SpelException ele = (SpelException)ee;
|
||||
assertEquals(ele.getMessageUnformatted(),SpelMessages.PROPERTY_OR_FIELD_SETTER_NOT_FOUND);
|
||||
}
|
||||
public void testScenario_AddingYourOwnPropertyResolvers_1() throws Exception {
|
||||
// Create a parser
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
// Use the standard evaluation context
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
|
||||
} catch (EvaluationException ee) {
|
||||
ee.printStackTrace();
|
||||
fail("Unexpected Exception: " + ee.getMessage());
|
||||
} catch (ParseException pe) {
|
||||
pe.printStackTrace();
|
||||
fail("Unexpected Exception: " + pe.getMessage());
|
||||
ctx.addPropertyAccessor(new FruitColourAccessor());
|
||||
Expression expr = parser.parseExpression("orange");
|
||||
Object value = expr.getValue(ctx);
|
||||
assertEquals(Color.orange, value);
|
||||
|
||||
try {
|
||||
expr.setValue(ctx, Color.blue);
|
||||
fail("Should not be allowed to set oranges to be blue !");
|
||||
}
|
||||
catch (SpelException ee) {
|
||||
assertEquals(ee.getMessageUnformatted(), SpelMessages.PROPERTY_OR_FIELD_SETTER_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
public void testScenario_AddingYourOwnPropertyResolvers_2() throws Exception {
|
||||
// Create a parser
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
// Use the standard evaluation context
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
|
||||
ctx.addPropertyAccessor(new VegetableColourAccessor());
|
||||
Expression expr = parser.parseExpression("pea");
|
||||
Object value = expr.getValue(ctx);
|
||||
assertEquals(Color.green, value);
|
||||
|
||||
try {
|
||||
expr.setValue(ctx, Color.blue);
|
||||
fail("Should not be allowed to set peas to be blue !");
|
||||
}
|
||||
catch (SpelException ee) {
|
||||
assertEquals(ee.getMessageUnformatted(), SpelMessages.PROPERTY_OR_FIELD_SETTER_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Regardless of the current context object, or root context object, this resolver can tell you what colour a fruit is !
|
||||
* It only supports property reading, not writing. To support writing it would need to override canWrite() and write()
|
||||
*/
|
||||
static class FruitColourAccessor implements PropertyAccessor {
|
||||
private static class FruitColourAccessor implements PropertyAccessor {
|
||||
|
||||
private static Map<String,Color> propertyMap = new HashMap<String,Color>();
|
||||
|
||||
@@ -270,69 +248,30 @@ public class ExpressionLanguageScenarioTests extends ExpressionTestCase {
|
||||
public Class<?>[] getSpecificTargetClasses() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, Object name) throws AccessException {
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return propertyMap.containsKey(name);
|
||||
}
|
||||
|
||||
|
||||
public Object read(EvaluationContext context, Object target, Object name) throws AccessException {
|
||||
public Object read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return propertyMap.get(name);
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, Object name) throws AccessException {
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void write(EvaluationContext context, Object target, Object name, Object newValue)
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue)
|
||||
throws AccessException {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Scenario: add an optimized property resolver. Property resolution can be thought of it two parts: resolving (finding the property you mean) and accessing (reading or writing that property).
|
||||
* In some cases the act of discovering which property is meant is expensive - and there is no benefit to rediscovering it every time the expression is evaluated as it will
|
||||
* always be the same property. For example, with reflection it can be expensive to find out which field on an object maps to the property, but it will always be the same field
|
||||
* for each evaluation. In these cases we use a Resolver/Executor based property accessor. In this setup the property resolver does not immediately return the value of the property,
|
||||
* instead it returns an executor object that can be used to read the property. The executor can be cached and reused by SPEL so it does not go back to the resolver every time the
|
||||
* expression is evaluated. In this testcase we use this different accessor mechanism to return the colours of vegetables.
|
||||
*/
|
||||
public void testScenario_AddingYourOwnPropertyResolvers_2() throws SecurityException, NoSuchMethodException {
|
||||
try {
|
||||
// Create a parser
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
// Use the standard evaluation context
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
|
||||
ctx.addPropertyAccessor(new VegetableColourAccessor());
|
||||
Expression expr = parser.parseExpression("pea");
|
||||
Object value = expr.getValue(ctx);
|
||||
assertEquals(Color.green,value);
|
||||
|
||||
try {
|
||||
expr.setValue(ctx,Color.blue);
|
||||
fail("Should not be allowed to set peas to be blue !");
|
||||
} catch (EvaluationException ee) {
|
||||
SpelException ele = (SpelException)ee;
|
||||
assertEquals(ele.getMessageUnformatted(),SpelMessages.PROPERTY_OR_FIELD_SETTER_NOT_FOUND);
|
||||
}
|
||||
|
||||
} catch (EvaluationException ee) {
|
||||
ee.printStackTrace();
|
||||
fail("Unexpected Exception: " + ee.getMessage());
|
||||
} catch (ParseException pe) {
|
||||
pe.printStackTrace();
|
||||
fail("Unexpected Exception: " + pe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Regardless of the current context object, or root context object, this resolver can tell you what colour a vegetable is !
|
||||
* It only supports property reading, not writing.
|
||||
*/
|
||||
static class VegetableColourAccessor extends CacheablePropertyAccessor {
|
||||
private static class VegetableColourAccessor implements PropertyAccessor {
|
||||
|
||||
private static Map<String,Color> propertyMap = new HashMap<String,Color>();
|
||||
|
||||
@@ -348,84 +287,20 @@ public class ExpressionLanguageScenarioTests extends ExpressionTestCase {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Work out if we can resolve the named property and if so return an executor that can be cached and reused to
|
||||
* discover the value.
|
||||
*/
|
||||
public PropertyReaderExecutor getReaderAccessor(EvaluationContext relatedContext, Object target, Object name) {
|
||||
if (propertyMap.containsKey(name)) {
|
||||
return new VegetableColourExecutor(propertyMap.get(name));
|
||||
}
|
||||
return null;
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return propertyMap.containsKey(name);
|
||||
}
|
||||
|
||||
public PropertyWriterExecutor getWriterAccessor(EvaluationContext context, Object target, Object name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class VegetableColourExecutor implements PropertyReaderExecutor {
|
||||
private Color colour;
|
||||
|
||||
public VegetableColourExecutor(Color colour) {
|
||||
this.colour = colour;
|
||||
public Object read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return propertyMap.get(name);
|
||||
}
|
||||
|
||||
public Object execute(EvaluationContext context, Object target) throws AccessException {
|
||||
return colour;
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Scenario: adding your own type converter
|
||||
*/
|
||||
public void testScenario_AddingYourOwnTypeConverter() throws SecurityException, NoSuchMethodException {
|
||||
try {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
ctx.registerFunction("functionTakesColour",ExpressionLanguageScenarioTests.class.getDeclaredMethod("functionTakesColour",Color.class));
|
||||
|
||||
Expression expr = parser.parseExpression("#functionTakesColour('orange')");
|
||||
try {
|
||||
@SuppressWarnings("unused")
|
||||
Object value = expr.getValue(ctx);
|
||||
fail("Should have failed, no type converter registered");
|
||||
} catch (EvaluationException ee) {}
|
||||
|
||||
ctx.addTypeConverter(new StringToColorConverter());
|
||||
Object value = expr.getValue(ctx);
|
||||
|
||||
assertEquals(Color.orange,value);
|
||||
} catch (EvaluationException ee) {
|
||||
ee.printStackTrace();
|
||||
fail("Unexpected Exception: " + ee.getMessage());
|
||||
} catch (ParseException pe) {
|
||||
pe.printStackTrace();
|
||||
fail("Unexpected Exception: " + pe.getMessage());
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
|
||||
}
|
||||
}
|
||||
|
||||
public static Color functionTakesColour(Color c) {return c;}
|
||||
|
||||
static class StringToColorConverter implements StandardIndividualTypeConverter {
|
||||
|
||||
public Object convert(Object value) throws EvaluationException {
|
||||
String colourName = (String)value;
|
||||
if (colourName.equals("orange")) return Color.orange;
|
||||
else if (colourName.equals("red")) return Color.red;
|
||||
else return Color.blue; // hmm, quite a simplification here
|
||||
}
|
||||
|
||||
public Class<?>[] getFrom() {
|
||||
return new Class[]{String.class};
|
||||
}
|
||||
|
||||
public Class<?> getTo() {
|
||||
return Color.class;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -23,7 +24,8 @@ import junit.framework.TestCase;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ParseException;
|
||||
import org.springframework.expression.spel.standard.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.antlr.SpelAntlrExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
/**
|
||||
* Common superclass for expression tests.
|
||||
@@ -37,7 +39,7 @@ public abstract class ExpressionTestCase extends TestCase {
|
||||
protected final static boolean SHOULD_BE_WRITABLE = true;
|
||||
protected final static boolean SHOULD_NOT_BE_WRITABLE = false;
|
||||
|
||||
protected final static SpelExpressionParser parser = new SpelExpressionParser();
|
||||
protected final static SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
protected final static StandardEvaluationContext eContext = TestScenarioCreator.getTestEvaluationContext();
|
||||
|
||||
/**
|
||||
@@ -49,7 +51,7 @@ public abstract class ExpressionTestCase extends TestCase {
|
||||
*/
|
||||
public void evaluate(String expression, Object expectedValue, Class<?> expectedResultType) {
|
||||
try {
|
||||
SpelExpression expr = parser.parseExpression(expression);
|
||||
Expression expr = parser.parseExpression(expression);
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
@@ -97,7 +99,7 @@ public abstract class ExpressionTestCase extends TestCase {
|
||||
|
||||
public void evaluateAndAskForReturnType(String expression, Object expectedValue, Class<?> expectedResultType) {
|
||||
try {
|
||||
SpelExpression expr = parser.parseExpression(expression);
|
||||
Expression expr = parser.parseExpression(expression);
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
@@ -146,7 +148,7 @@ public abstract class ExpressionTestCase extends TestCase {
|
||||
public void evaluate(String expression, Object expectedValue, Class<?> expectedClassOfResult,
|
||||
boolean shouldBeWritable) {
|
||||
try {
|
||||
SpelExpression e = parser.parseExpression(expression);
|
||||
Expression e = parser.parseExpression(expression);
|
||||
if (e == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
@@ -288,7 +290,7 @@ public abstract class ExpressionTestCase extends TestCase {
|
||||
*/
|
||||
protected void parseAndCheckError(String expression, SpelMessages expectedMessage, Object... otherProperties) {
|
||||
try {
|
||||
SpelExpression expr = parser.parseExpression(expression);
|
||||
Expression expr = parser.parseExpression(expression);
|
||||
SpelUtilities.printAbstractSyntaxTree(System.out, expr);
|
||||
fail("Parsing should have failed!");
|
||||
} catch (ParseException pe) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,17 +13,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.common;
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.spel.standard.StandardEvaluationContext;
|
||||
import org.springframework.expression.common.LiteralExpression;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
/**
|
||||
* Test LiteralExpression
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class LiteralExpressionTests extends TestCase {
|
||||
@@ -44,7 +44,8 @@ public class LiteralExpressionTests extends TestCase {
|
||||
LiteralExpression lEx = new LiteralExpression("somevalue");
|
||||
lEx.setValue(new StandardEvaluationContext(), "flibble");
|
||||
fail("Should have got an exception that the value cannot be set");
|
||||
} catch (EvaluationException ee) {
|
||||
}
|
||||
catch (EvaluationException ee) {
|
||||
// success, not allowed - whilst here, check the expression value in the exception
|
||||
assertEquals(ee.getExpressionString(), "somevalue");
|
||||
}
|
||||
@@ -64,4 +65,5 @@ public class LiteralExpressionTests extends TestCase {
|
||||
fail("Did not get expected result. Should have been '" + expectedString + "' but was '" + value + "'");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
/**
|
||||
@@ -78,8 +79,7 @@ public class LiteralTests extends ExpressionTestCase {
|
||||
// ask for the result to be made into an Integer
|
||||
evaluateAndAskForReturnType("0x20 * 2L", 64, Integer.class);
|
||||
// ask for the result to be made into an Integer knowing that it will not fit
|
||||
evaluateAndCheckError("0x1220 * 0xffffffffL", Integer.class, SpelMessages.PROBLEM_DURING_TYPE_CONVERSION, -1,
|
||||
"long value '19928648248800' cannot be represented as an int");
|
||||
evaluateAndCheckError("0x1220 * 0xffffffffL", Integer.class, SpelMessages.PROBLEM_DURING_TYPE_CONVERSION, -1);
|
||||
}
|
||||
|
||||
public void testSignedIntLiterals() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -21,7 +22,8 @@ import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.spel.standard.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.antlr.SpelAntlrExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
/**
|
||||
* Testing variations on map access.
|
||||
@@ -30,31 +32,6 @@ import org.springframework.expression.spel.standard.StandardEvaluationContext;
|
||||
*/
|
||||
public class MapAccessTests extends ExpressionTestCase {
|
||||
|
||||
static class MapAccessor implements PropertyAccessor {
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, Object name) throws AccessException {
|
||||
return (((Map) target).containsKey(name));
|
||||
}
|
||||
|
||||
public Object read(EvaluationContext context, Object target, Object name) throws AccessException {
|
||||
return ((Map) target).get(name);
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, Object name) throws AccessException {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void write(EvaluationContext context, Object target, Object name, Object newValue)
|
||||
throws AccessException {
|
||||
((Map) target).put(name, newValue);
|
||||
}
|
||||
|
||||
public Class<?>[] getSpecificTargetClasses() {
|
||||
return new Class[] { Map.class };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testSimpleMapAccess01() {
|
||||
evaluate("testMap.get('monday')", "montag", String.class);
|
||||
}
|
||||
@@ -64,7 +41,7 @@ public class MapAccessTests extends ExpressionTestCase {
|
||||
}
|
||||
|
||||
public void testCustomMapAccessor() throws Exception {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
StandardEvaluationContext ctx = TestScenarioCreator.getTestEvaluationContext();
|
||||
ctx.addPropertyAccessor(new MapAccessor());
|
||||
|
||||
@@ -74,7 +51,7 @@ public class MapAccessTests extends ExpressionTestCase {
|
||||
}
|
||||
|
||||
public void testVariableMapAccess() throws Exception {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
StandardEvaluationContext ctx = TestScenarioCreator.getTestEvaluationContext();
|
||||
ctx.setVariable("day", "saturday");
|
||||
|
||||
@@ -83,7 +60,29 @@ public class MapAccessTests extends ExpressionTestCase {
|
||||
assertEquals("samstag", value);
|
||||
}
|
||||
|
||||
// public void testMapAccess04() {
|
||||
// evaluate("testMap[monday]", "montag", String.class);
|
||||
// }
|
||||
|
||||
private static class MapAccessor implements PropertyAccessor {
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return (((Map) target).containsKey(name));
|
||||
}
|
||||
|
||||
public Object read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return ((Map) target).get(name);
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue)
|
||||
throws AccessException {
|
||||
((Map) target).put(name, newValue);
|
||||
}
|
||||
|
||||
public Class<?>[] getSpecificTargetClasses() {
|
||||
return new Class[] { Map.class };
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,10 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.spel.standard.StandardEvaluationContext;
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
/**
|
||||
* Tests invocation of methods.
|
||||
@@ -88,25 +86,4 @@ public class MethodInvocationTests extends ExpressionTestCase {
|
||||
// evaluate("aVarargsMethod2(8,new String[]{'a','b','c'})", 11, Integer.class);
|
||||
}
|
||||
|
||||
// Due to conversion there are two possible methods to call ...
|
||||
public void testVarargsInvocation03() throws Exception {
|
||||
// Calling 'm(String... strings)' and 'm(int i,String... strings)'
|
||||
try {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
ctx.setClasspath("target/test-classes/testcode.jar");
|
||||
|
||||
Object v = null;
|
||||
v = parser.parseExpression("new TestType().m(1,2,3)").getValue(ctx);
|
||||
// v = parser.parseExpression("new TestType().m('a','b','c')").getValue(ctx);
|
||||
// v = parser.parseExpression("new TestType().m(5,'a','b','c')").getValue(ctx);
|
||||
// v = parser.parseExpression("new TestType().m()").getValue(ctx);
|
||||
// v = parser.parseExpression("new TestType().m(1)").getValue(ctx);
|
||||
// v = parser.parseExpression("new TestType().m(1,'a',3.0d)").getValue(ctx);
|
||||
// v = parser.parseExpression("new TestType().m(new String[]{'a','b','c'})").getValue(ctx);
|
||||
fail("Should have detected ambiguity, there are two possible matches");
|
||||
} catch (EvaluationException ee) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,11 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.expression.ParseException;
|
||||
import org.springframework.expression.spel.antlr.SpelAntlrExpressionParser;
|
||||
|
||||
/**
|
||||
* Parse some expressions and check we get the AST we expect. Rather than inspecting each node in the AST, we ask it to
|
||||
@@ -27,12 +29,7 @@ import org.springframework.expression.ParseException;
|
||||
*/
|
||||
public class ParsingTests extends TestCase {
|
||||
|
||||
private SpelExpressionParser parser;
|
||||
|
||||
@Override
|
||||
public void setUp() {
|
||||
parser = new SpelExpressionParser();
|
||||
}
|
||||
private SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
|
||||
// literals
|
||||
public void testLiteralBoolean01() {
|
||||
@@ -393,7 +390,7 @@ public class ParsingTests extends TestCase {
|
||||
*/
|
||||
public void parseCheck(String expression, String expectedStringFormOfAST) {
|
||||
try {
|
||||
SpelExpression e = parser.parseExpression(expression);
|
||||
SpelExpression e = (SpelExpression) parser.parseExpression(expression);
|
||||
if (e != null && !e.toStringAST().equals(expectedStringFormOfAST)) {
|
||||
SpelUtilities.printAbstractSyntaxTree(System.err, e);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,7 @@ import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.antlr.SpelAntlrExpressionParser;
|
||||
import org.springframework.expression.spel.ast.ConstructorReference;
|
||||
import org.springframework.expression.spel.ast.PropertyOrFieldReference;
|
||||
|
||||
@@ -30,35 +31,39 @@ import org.springframework.expression.spel.ast.PropertyOrFieldReference;
|
||||
*/
|
||||
public class PerformanceTests extends TestCase {
|
||||
|
||||
public static final int ITERATIONS = 1000;
|
||||
public static final int ITERATIONS = 100000;
|
||||
public static final boolean report = true;
|
||||
|
||||
private static SpelExpressionParser parser = new SpelExpressionParser();
|
||||
private static SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
private static EvaluationContext eContext = TestScenarioCreator.getTestEvaluationContext();
|
||||
|
||||
public void testPerformanceOfSimpleAccess() throws Exception {
|
||||
public void testPerformanceOfPropertyAccess() throws Exception {
|
||||
long starttime = 0;
|
||||
long endtime = 0;
|
||||
|
||||
starttime = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
Expression expr = parser.parseExpression("getPlaceOfBirth().getCity()");
|
||||
if (expr == null)
|
||||
Expression expr = parser.parseExpression("placeOfBirth.city");
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
Object value = expr.getValue(eContext);
|
||||
}
|
||||
endtime = System.currentTimeMillis();
|
||||
long freshParseTime = endtime - starttime;
|
||||
System.out.println(freshParseTime);
|
||||
|
||||
Expression expr = parser.parseExpression("getPlaceOfBirth().getCity()");
|
||||
if (expr == null)
|
||||
Expression expr = parser.parseExpression("placeOfBirth.city");
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
starttime = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
Object value = expr.getValue(eContext);
|
||||
}
|
||||
endtime = System.currentTimeMillis();
|
||||
long reuseTime = endtime - starttime;
|
||||
System.out.println(reuseTime);
|
||||
if (reuseTime > freshParseTime) {
|
||||
System.out.println("Fresh parse every time, ITERATIONS iterations = " + freshParseTime + "ms");
|
||||
System.out.println("Reuse SpelExpression, ITERATIONS iterations = " + reuseTime + "ms");
|
||||
@@ -66,33 +71,13 @@ public class PerformanceTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing that using a resolver/executor split for constructor invocation (ie. just doing the reflection once to
|
||||
* find the constructor then executing it over and over) is faster than redoing the reflection and execution every
|
||||
* time.
|
||||
*
|
||||
* MacBook speeds: 4-Aug-08 <br>
|
||||
* Fresh parse every time, ITERATIONS iterations = 373ms <br>
|
||||
* Reuse SpelExpression, ITERATIONS iterations = 1ms <br>
|
||||
* Reuse SpelExpression (caching off), ITERATIONS iterations = 188ms <br>
|
||||
*/
|
||||
public void testConstructorResolverExecutorBenefit01() throws Exception {
|
||||
public void testPerformanceOfMethodAccess() throws Exception {
|
||||
long starttime = 0;
|
||||
long endtime = 0;
|
||||
|
||||
// warmup
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
Expression expr = parser.parseExpression("new Integer(5)");
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
Object value = expr.getValue(eContext);
|
||||
}
|
||||
|
||||
// ITERATIONS calls, parsing fresh each time
|
||||
starttime = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
Expression expr = parser.parseExpression("new Integer(5)");
|
||||
Expression expr = parser.parseExpression("getPlaceOfBirth().getCity()");
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
@@ -100,26 +85,9 @@ public class PerformanceTests extends TestCase {
|
||||
}
|
||||
endtime = System.currentTimeMillis();
|
||||
long freshParseTime = endtime - starttime;
|
||||
System.out.println(freshParseTime);
|
||||
|
||||
// ITERATIONS calls, parsing once and using cached executor
|
||||
Expression expr = parser.parseExpression("new Integer(5)");
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
try {
|
||||
ConstructorReference.useCaching = false;
|
||||
starttime = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
Object value = expr.getValue(eContext);
|
||||
}
|
||||
} finally {
|
||||
ConstructorReference.useCaching = true;
|
||||
}
|
||||
endtime = System.currentTimeMillis();
|
||||
long cachingOffReuseTime = endtime - starttime;
|
||||
|
||||
// ITERATIONS calls, parsing once and using cached executor
|
||||
expr = parser.parseExpression("new Integer(5)");
|
||||
Expression expr = parser.parseExpression("getPlaceOfBirth().getCity()");
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
@@ -129,167 +97,11 @@ public class PerformanceTests extends TestCase {
|
||||
}
|
||||
endtime = System.currentTimeMillis();
|
||||
long reuseTime = endtime - starttime;
|
||||
|
||||
if (report) {
|
||||
System.out.println("Timings for constructor execution 'new Integer(5)'");
|
||||
System.out.println("Fresh parse every time, " + ITERATIONS + " iterations = " + freshParseTime + "ms");
|
||||
System.out.println("Reuse SpelExpression (caching off), " + ITERATIONS + " iterations = "
|
||||
+ cachingOffReuseTime + "ms");
|
||||
System.out.println("Reuse SpelExpression, " + ITERATIONS + " iterations = " + reuseTime + "ms");
|
||||
}
|
||||
System.out.println(reuseTime);
|
||||
if (reuseTime > freshParseTime) {
|
||||
fail("Should have been quicker to reuse a parsed expression!");
|
||||
}
|
||||
if (reuseTime > cachingOffReuseTime) {
|
||||
fail("Should have been quicker to reuse cached!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing that using a resolver/executor split for property access is faster than redoing the reflection and
|
||||
* execution every time.
|
||||
*
|
||||
* MacBook speeds: <br>
|
||||
*/
|
||||
public void testPropertyResolverExecutorBenefit_Reading() throws Exception {
|
||||
long starttime = 0;
|
||||
long endtime = 0;
|
||||
|
||||
// warmup
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
Expression expr = parser.parseExpression("getPlaceOfBirth().city");
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
Object value = expr.getValue(eContext);
|
||||
}
|
||||
|
||||
// ITERATIONS calls, parsing fresh each time
|
||||
starttime = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
Expression expr = parser.parseExpression("getPlaceOfBirth().city");
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
Object value = expr.getValue(eContext);
|
||||
}
|
||||
endtime = System.currentTimeMillis();
|
||||
long freshParseTime = endtime - starttime;
|
||||
|
||||
// ITERATIONS calls, parsing once and using cached executor
|
||||
Expression expr = parser.parseExpression("getPlaceOfBirth().city");
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
try {
|
||||
PropertyOrFieldReference.useCaching = false;
|
||||
starttime = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
Object value = expr.getValue(eContext);
|
||||
}
|
||||
} finally {
|
||||
PropertyOrFieldReference.useCaching = true;
|
||||
}
|
||||
endtime = System.currentTimeMillis();
|
||||
long cachingOffReuseTime = endtime - starttime;
|
||||
|
||||
// ITERATIONS calls, parsing once and using cached executor
|
||||
expr = parser.parseExpression("getPlaceOfBirth().city");
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
starttime = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
Object value = expr.getValue(eContext);
|
||||
}
|
||||
endtime = System.currentTimeMillis();
|
||||
long reuseTime = endtime - starttime;
|
||||
if (report) {
|
||||
System.out.println("Timings for property reader execution 'getPlaceOfBirth().city'");
|
||||
System.out.println("Fresh parse every time, " + ITERATIONS + " iterations = " + freshParseTime + "ms");
|
||||
System.out.println("Reuse SpelExpression (caching off), " + ITERATIONS + " iterations = "
|
||||
+ cachingOffReuseTime + "ms");
|
||||
System.out.println("Reuse SpelExpression, " + ITERATIONS + " iterations = " + reuseTime + "ms");
|
||||
}
|
||||
if (reuseTime > freshParseTime) {
|
||||
//TODO fail("Should have been quicker to reuse a parsed expression!");
|
||||
}
|
||||
if (reuseTime > cachingOffReuseTime) {
|
||||
//TODO fail("Should have been quicker to reuse cached!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing that using a resolver/executor split for property writing is faster than redoing the reflection and
|
||||
* execution every time.
|
||||
*
|
||||
* MacBook speeds: <br>
|
||||
*/
|
||||
public void testPropertyResolverExecutorBenefit_Writing() throws Exception {
|
||||
long starttime = 0;
|
||||
long endtime = 0;
|
||||
|
||||
// warmup
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
Expression expr = parser.parseExpression("randomField='Andy'");
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
Object value = expr.getValue(eContext);
|
||||
}
|
||||
|
||||
// ITERATIONS calls, parsing fresh each time
|
||||
starttime = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
Expression expr = parser.parseExpression("randomField='Andy'");
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
Object value = expr.getValue(eContext);
|
||||
}
|
||||
endtime = System.currentTimeMillis();
|
||||
long freshParseTime = endtime - starttime;
|
||||
|
||||
// ITERATIONS calls, parsing once and using cached executor
|
||||
Expression expr = parser.parseExpression("randomField='Andy'");
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
try {
|
||||
PropertyOrFieldReference.useCaching = false;
|
||||
starttime = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
Object value = expr.getValue(eContext);
|
||||
}
|
||||
} finally {
|
||||
PropertyOrFieldReference.useCaching = true;
|
||||
}
|
||||
endtime = System.currentTimeMillis();
|
||||
long cachingOffReuseTime = endtime - starttime;
|
||||
|
||||
// ITERATIONS calls, parsing once and using cached executor
|
||||
expr = parser.parseExpression("randomField='Andy'");
|
||||
if (expr == null) {
|
||||
fail("Parser returned null for expression");
|
||||
}
|
||||
starttime = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
Object value = expr.getValue(eContext);
|
||||
}
|
||||
endtime = System.currentTimeMillis();
|
||||
long reuseTime = endtime - starttime;
|
||||
if (report) {
|
||||
System.out.println("Timings for property writing execution 'randomField='Andy''");
|
||||
System.out.println("Fresh parse every time, " + ITERATIONS + " iterations = " + freshParseTime + "ms");
|
||||
System.out.println("Reuse SpelExpression (caching off), " + ITERATIONS + " iterations = "
|
||||
+ cachingOffReuseTime + "ms");
|
||||
System.out.println("Reuse SpelExpression, " + ITERATIONS + " iterations = " + reuseTime + "ms");
|
||||
}
|
||||
if (reuseTime > freshParseTime) {
|
||||
//TODO fail("Should have been quicker to reuse a parsed expression!");
|
||||
}
|
||||
if (reuseTime > cachingOffReuseTime) {
|
||||
//TODO fail("Should have been quicker to reuse cached!");
|
||||
System.out.println("Fresh parse every time, ITERATIONS iterations = " + freshParseTime + "ms");
|
||||
System.out.println("Reuse SpelExpression, ITERATIONS iterations = " + reuseTime + "ms");
|
||||
fail("Should have been quicker to reuse!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import org.springframework.expression.AccessException;
|
||||
@@ -20,7 +21,8 @@ import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.spel.standard.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.antlr.SpelAntlrExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
/**
|
||||
* Tests accessing of properties.
|
||||
@@ -45,49 +47,9 @@ public class PropertyAccessTests extends ExpressionTestCase {
|
||||
evaluateAndCheckError("name.foobar", SpelMessages.PROPERTY_OR_FIELD_NOT_FOUND, 5);
|
||||
}
|
||||
|
||||
// This can resolve the property 'flibbles' on any String (very useful...)
|
||||
static class StringyPropertyAccessor implements PropertyAccessor {
|
||||
|
||||
int flibbles = 7;
|
||||
|
||||
public Class<?>[] getSpecificTargetClasses() {
|
||||
return new Class[] { String.class };
|
||||
}
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, Object name) throws AccessException {
|
||||
if (!(target instanceof String))
|
||||
throw new RuntimeException("Assertion Failed! target should be String");
|
||||
return (name.equals("flibbles"));
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, Object name) throws AccessException {
|
||||
if (!(target instanceof String))
|
||||
throw new RuntimeException("Assertion Failed! target should be String");
|
||||
return (name.equals("flibbles"));
|
||||
}
|
||||
|
||||
public Object read(EvaluationContext context, Object target, Object name) throws AccessException {
|
||||
if (!name.equals("flibbles"))
|
||||
throw new RuntimeException("Assertion Failed! name should be flibbles");
|
||||
return flibbles;
|
||||
}
|
||||
|
||||
public void write(EvaluationContext context, Object target, Object name, Object newValue)
|
||||
throws AccessException {
|
||||
if (!name.equals("flibbles"))
|
||||
throw new RuntimeException("Assertion Failed! name should be flibbles");
|
||||
try {
|
||||
flibbles = (Integer) context.getTypeUtils().getTypeConverter().convertValue(newValue, Integer.class);
|
||||
} catch (EvaluationException e) {
|
||||
throw new AccessException("Cannot set flibbles to an object of type '" + newValue.getClass() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Adding a new property accessor just for a particular type
|
||||
public void testAddingSpecificPropertyAccessor() throws Exception {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
|
||||
// Even though this property accessor is added after the reflection one, it specifically
|
||||
@@ -119,4 +81,44 @@ public class PropertyAccessTests extends ExpressionTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This can resolve the property 'flibbles' on any String (very useful...)
|
||||
private static class StringyPropertyAccessor implements PropertyAccessor {
|
||||
|
||||
int flibbles = 7;
|
||||
|
||||
public Class<?>[] getSpecificTargetClasses() {
|
||||
return new Class[] { String.class };
|
||||
}
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
if (!(target instanceof String))
|
||||
throw new RuntimeException("Assertion Failed! target should be String");
|
||||
return (name.equals("flibbles"));
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
if (!(target instanceof String))
|
||||
throw new RuntimeException("Assertion Failed! target should be String");
|
||||
return (name.equals("flibbles"));
|
||||
}
|
||||
|
||||
public Object read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
if (!name.equals("flibbles"))
|
||||
throw new RuntimeException("Assertion Failed! name should be flibbles");
|
||||
return flibbles;
|
||||
}
|
||||
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue)
|
||||
throws AccessException {
|
||||
if (!name.equals("flibbles"))
|
||||
throw new RuntimeException("Assertion Failed! name should be flibbles");
|
||||
try {
|
||||
flibbles = context.getTypeConverter().convertValue(newValue, Integer.class);
|
||||
} catch (EvaluationException e) {
|
||||
throw new AccessException("Cannot set flibbles to an object of type '" + newValue.getClass() + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
@@ -25,9 +26,9 @@ import org.springframework.expression.MethodExecutor;
|
||||
import org.springframework.expression.MethodResolver;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypeConverter;
|
||||
import org.springframework.expression.spel.reflection.ReflectionUtils;
|
||||
import org.springframework.expression.spel.standard.StandardEvaluationContext;
|
||||
|
||||
import org.springframework.expression.spel.antlr.SpelAntlrExpressionParser;
|
||||
import org.springframework.expression.spel.support.ReflectionHelper;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
/**
|
||||
* Spring Security scenarios from https://wiki.springsource.com/display/SECURITY/Spring+Security+Expression-based+Authorization
|
||||
@@ -36,74 +37,18 @@ import org.springframework.expression.spel.standard.StandardEvaluationContext;
|
||||
*/
|
||||
public class ScenariosForSpringSecurity extends ExpressionTestCase {
|
||||
|
||||
// Helper classes for the scenario:
|
||||
static class Person {
|
||||
|
||||
private String n;
|
||||
|
||||
Person(String n) { this.n = n; }
|
||||
|
||||
public String[] getRoles() { return new String[]{"NONE"}; }
|
||||
|
||||
public boolean hasAnyRole(String... roles) {
|
||||
if (roles==null) return true;
|
||||
String[] myRoles = getRoles();
|
||||
for (int i=0;i<myRoles.length;i++) {
|
||||
for (int j=0;j<roles.length;j++) {
|
||||
if (myRoles[i].equals(roles[j])) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasRole(String role) {
|
||||
return hasAnyRole(role);
|
||||
}
|
||||
|
||||
public boolean hasIpAddress(String ipaddr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getName() { return n; }
|
||||
}
|
||||
|
||||
static class Manager extends Person {
|
||||
Manager(String n) {
|
||||
super(n);
|
||||
}
|
||||
|
||||
public String[] getRoles() { return new String[]{"MANAGER"};}
|
||||
}
|
||||
|
||||
static class Teller extends Person {
|
||||
Teller(String n) {
|
||||
super(n);
|
||||
}
|
||||
|
||||
public String[] getRoles() { return new String[]{"TELLER"};}
|
||||
}
|
||||
|
||||
static class Supervisor extends Person {
|
||||
Supervisor(String n) {
|
||||
super(n);
|
||||
}
|
||||
|
||||
public String[] getRoles() { return new String[]{"SUPERVISOR"};}
|
||||
}
|
||||
// End of helper code
|
||||
|
||||
public void testScenario01_Roles() throws Exception {
|
||||
try {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
Expression expr = parser.parseExpression("hasAnyRole('MANAGER','TELLER')");
|
||||
|
||||
ctx.setRootObject(new Person("Ben"));
|
||||
Boolean value = (Boolean)expr.getValue(ctx,Boolean.class);
|
||||
Boolean value = expr.getValue(ctx,Boolean.class);
|
||||
assertFalse(value);
|
||||
|
||||
ctx.setRootObject(new Manager("Luke"));
|
||||
value = (Boolean)expr.getValue(ctx,Boolean.class);
|
||||
value = expr.getValue(ctx,Boolean.class);
|
||||
assertTrue(value);
|
||||
|
||||
} catch (EvaluationException ee) {
|
||||
@@ -111,69 +56,9 @@ public class ScenariosForSpringSecurity extends ExpressionTestCase {
|
||||
fail("Unexpected SpelException: " + ee.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
static class SecurityPrincipalAccessor implements PropertyAccessor {
|
||||
|
||||
static class Principal {
|
||||
public String name = "Andy";
|
||||
}
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, Object name) throws AccessException {
|
||||
return name.equals("principal");
|
||||
}
|
||||
|
||||
public Object read(EvaluationContext context, Object target, Object name) throws AccessException {
|
||||
return new Principal();
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, Object name) throws AccessException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void write(EvaluationContext context, Object target, Object name, Object newValue)
|
||||
throws AccessException {
|
||||
}
|
||||
|
||||
public Class<?>[] getSpecificTargetClasses() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class PersonAccessor implements PropertyAccessor {
|
||||
|
||||
Person activePerson;
|
||||
|
||||
void setPerson(Person p) { this.activePerson = p; }
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, Object name) throws AccessException {
|
||||
return name.equals("p");
|
||||
}
|
||||
|
||||
public Object read(EvaluationContext context, Object target, Object name) throws AccessException {
|
||||
return activePerson;
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, Object name) throws AccessException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void write(EvaluationContext context, Object target, Object name, Object newValue)
|
||||
throws AccessException {
|
||||
}
|
||||
|
||||
public Class<?>[] getSpecificTargetClasses() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void testScenario02_ComparingNames() throws Exception {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
|
||||
ctx.addPropertyAccessor(new SecurityPrincipalAccessor());
|
||||
@@ -183,11 +68,11 @@ public class ScenariosForSpringSecurity extends ExpressionTestCase {
|
||||
Expression expr = parser.parseExpression("name == principal.name");
|
||||
|
||||
ctx.setRootObject(new Person("Andy"));
|
||||
Boolean value = (Boolean)expr.getValue(ctx,Boolean.class);
|
||||
Boolean value = expr.getValue(ctx,Boolean.class);
|
||||
assertTrue(value);
|
||||
|
||||
ctx.setRootObject(new Person("Christian"));
|
||||
value = (Boolean)expr.getValue(ctx,Boolean.class);
|
||||
value = expr.getValue(ctx,Boolean.class);
|
||||
assertFalse(value);
|
||||
|
||||
// (2) Or register an accessor that can understand 'p' and return the right person
|
||||
@@ -207,7 +92,7 @@ public class ScenariosForSpringSecurity extends ExpressionTestCase {
|
||||
}
|
||||
|
||||
public void testScenario03_Arithmetic() throws Exception {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
|
||||
// Might be better with a as a variable although it would work as a property too...
|
||||
@@ -218,59 +103,23 @@ public class ScenariosForSpringSecurity extends ExpressionTestCase {
|
||||
|
||||
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 = (Boolean)expr.getValue(ctx,Boolean.class);
|
||||
value = expr.getValue(ctx,Boolean.class);
|
||||
assertTrue(value);
|
||||
|
||||
ctx.setRootObject(new Manager("Luke"));
|
||||
ctx.setVariable("a",1.043d);
|
||||
value = (Boolean)expr.getValue(ctx,Boolean.class);
|
||||
value = expr.getValue(ctx,Boolean.class);
|
||||
assertFalse(value);
|
||||
}
|
||||
|
||||
static class MyMethodResolver implements MethodResolver {
|
||||
|
||||
static class HasRoleExecutor implements MethodExecutor {
|
||||
|
||||
TypeConverter tc;
|
||||
|
||||
public HasRoleExecutor(TypeConverter typeConverter) {
|
||||
this.tc = typeConverter;
|
||||
}
|
||||
|
||||
public Object execute(EvaluationContext context, Object target, Object... methodArguments)
|
||||
throws AccessException {
|
||||
try {
|
||||
Method m = HasRoleExecutor.class.getMethod("hasRole",new String[]{}.getClass());
|
||||
Object[] args = ReflectionUtils.prepareArguments(tc,m,methodArguments);
|
||||
return m.invoke(null,args);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new AccessException("Problem invoking hasRole");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasRole(String... strings) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name, Class<?>[] arguments)
|
||||
throws AccessException {
|
||||
if (name.equals("hasRole")) {
|
||||
return new HasRoleExecutor(context.getTypeUtils().getTypeConverter());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Here i'm going to change which hasRole() executes and make it one of my own Java methods
|
||||
public void testScenario04_ControllingWhichMethodsRun() throws Exception {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
|
||||
ctx.insertMethodResolver(0, new MyMethodResolver()); // NEEDS TO OVERRIDE THE REFLECTION ONE - SHOW REORDERING MECHANISM
|
||||
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')");
|
||||
@@ -279,8 +128,7 @@ public class ScenariosForSpringSecurity extends ExpressionTestCase {
|
||||
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 = (Boolean)expr.getValue(ctx,Boolean.class);
|
||||
value = expr.getValue(ctx,Boolean.class);
|
||||
assertTrue(value);
|
||||
|
||||
// ctx.setRootObject(new Manager("Luke"));
|
||||
@@ -289,4 +137,164 @@ public class ScenariosForSpringSecurity extends ExpressionTestCase {
|
||||
// assertFalse(value);
|
||||
}
|
||||
|
||||
|
||||
static class Person {
|
||||
|
||||
private String n;
|
||||
|
||||
Person(String n) { this.n = n; }
|
||||
|
||||
public String[] getRoles() { return new String[]{"NONE"}; }
|
||||
|
||||
public boolean hasAnyRole(String... roles) {
|
||||
if (roles==null) return true;
|
||||
String[] myRoles = getRoles();
|
||||
for (int i=0;i<myRoles.length;i++) {
|
||||
for (int j=0;j<roles.length;j++) {
|
||||
if (myRoles[i].equals(roles[j])) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasRole(String role) {
|
||||
return hasAnyRole(role);
|
||||
}
|
||||
|
||||
public boolean hasIpAddress(String ipaddr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getName() { return n; }
|
||||
}
|
||||
|
||||
|
||||
static class Manager extends Person {
|
||||
|
||||
Manager(String n) {
|
||||
super(n);
|
||||
}
|
||||
|
||||
public String[] getRoles() { return new String[]{"MANAGER"};}
|
||||
}
|
||||
|
||||
|
||||
static class Teller extends Person {
|
||||
|
||||
Teller(String n) {
|
||||
super(n);
|
||||
}
|
||||
|
||||
public String[] getRoles() { return new String[]{"TELLER"};}
|
||||
}
|
||||
|
||||
|
||||
static class Supervisor extends Person {
|
||||
|
||||
Supervisor(String n) {
|
||||
super(n);
|
||||
}
|
||||
|
||||
public String[] getRoles() { return new String[]{"SUPERVISOR"};}
|
||||
}
|
||||
|
||||
|
||||
static class SecurityPrincipalAccessor implements PropertyAccessor {
|
||||
|
||||
static class Principal {
|
||||
public String name = "Andy";
|
||||
}
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return name.equals("principal");
|
||||
}
|
||||
|
||||
public Object read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return new Principal();
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue)
|
||||
throws AccessException {
|
||||
}
|
||||
|
||||
public Class<?>[] getSpecificTargetClasses() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class PersonAccessor implements PropertyAccessor {
|
||||
|
||||
Person activePerson;
|
||||
|
||||
void setPerson(Person p) { this.activePerson = p; }
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return name.equals("p");
|
||||
}
|
||||
|
||||
public Object read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return activePerson;
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue)
|
||||
throws AccessException {
|
||||
}
|
||||
|
||||
public Class<?>[] getSpecificTargetClasses() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class MyMethodResolver implements MethodResolver {
|
||||
|
||||
static class HasRoleExecutor implements MethodExecutor {
|
||||
|
||||
TypeConverter tc;
|
||||
|
||||
public HasRoleExecutor(TypeConverter typeConverter) {
|
||||
this.tc = typeConverter;
|
||||
}
|
||||
|
||||
public Object execute(EvaluationContext context, Object target, Object... arguments)
|
||||
throws AccessException {
|
||||
try {
|
||||
Method m = HasRoleExecutor.class.getMethod("hasRole", String[].class);
|
||||
Object[] args = arguments;
|
||||
if (args != null) {
|
||||
ReflectionHelper.convertArguments(m.getParameterTypes(), m.isVarArgs(), tc, args);
|
||||
}
|
||||
if (m.isVarArgs()) {
|
||||
args = ReflectionHelper.setupArgumentsForVarargsInvocation(m.getParameterTypes(), args);
|
||||
}
|
||||
return m.invoke(null, args);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new AccessException("Problem invoking hasRole", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasRole(String... strings) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name, Class<?>[] arguments)
|
||||
throws AccessException {
|
||||
if (name.equals("hasRole")) {
|
||||
return new HasRoleExecutor(context.getTypeConverter());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
import org.springframework.expression.Expression;
|
||||
|
||||
/**
|
||||
* Utilities for working with Spring Expressions.
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class SpelUtilities {
|
||||
|
||||
/**
|
||||
* Output an indented representation of the expression syntax tree to the specified output stream.
|
||||
* @param printStream the output stream to print into
|
||||
* @param expression the expression to be displayed
|
||||
*/
|
||||
public static void printAbstractSyntaxTree(PrintStream printStream, Expression expression) {
|
||||
printStream.println("===> Expression '" + expression.getExpressionString() + "' - AST start");
|
||||
printAST(printStream, ((SpelExpression) expression).getAST(), "");
|
||||
printStream.println("===> Expression '" + expression.getExpressionString() + "' - AST end");
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper method for printing the AST with indentation
|
||||
*/
|
||||
private static void printAST(PrintStream out, SpelNode t, String indent) {
|
||||
if (t != null) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(indent).append(t.getClass().getSimpleName());
|
||||
sb.append(" value:").append(t.toStringAST());
|
||||
sb.append(t.getChildCount() < 2 ? "" : " #children:" + t.getChildCount());
|
||||
out.println(sb.toString());
|
||||
for (int i = 0; i < t.getChildCount(); i++) {
|
||||
printAST(out, t.getChild(i), indent + " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests the SpelUtilities
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class SpelUtilitiesTests extends TestCase {
|
||||
|
||||
public void testPrintAbstractSyntaxTree01() throws Exception {
|
||||
SpelExpression sEx = new SpelExpressionParser().parseExpression("1 + 2");
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SpelUtilities.printAbstractSyntaxTree(new PrintStream(baos), sEx);
|
||||
String theAst = baos.toString();
|
||||
System.out.println(theAst);
|
||||
String[] expectedLines = new String[] { "===> Expression '1 + 2' - AST start",
|
||||
"OperatorPlus value=+ children=#2", " CompoundExpression value=EXPRESSION",
|
||||
" IntLiteral value=1", " CompoundExpression value=EXPRESSION", " IntLiteral value=2",
|
||||
"===> Expression '1 + 2' - AST end" };
|
||||
//checkExpected(theAst, expectedLines);
|
||||
}
|
||||
|
||||
private static void checkExpected(String theData, String[] expectedLines) {
|
||||
String[] theDataSplit = theData.split("\n");
|
||||
if (theDataSplit.length != expectedLines.length) {
|
||||
System.out.println("TheData:");
|
||||
System.out.println(theData);
|
||||
System.out.println("ExpectedData:\n" + expectedLines);
|
||||
fail("Data incorrect, expected " + expectedLines.length + " but got " + theDataSplit.length + " lines");
|
||||
}
|
||||
for (int i = 0; i < expectedLines.length; i++) {
|
||||
assertEquals("Failure in comparison at line " + i, expectedLines[i], theDataSplit[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,43 +13,77 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.common.DefaultTemplateParserContext;
|
||||
import org.springframework.expression.ParserContext;
|
||||
import org.springframework.expression.spel.antlr.SpelAntlrExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
/**
|
||||
* Test parsing of template expressions
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class TemplateExpressionParsingTests extends ExpressionTestCase {
|
||||
|
||||
public static final ParserContext DEFAULT_TEMPLATE_PARSER_CONTEXT = new ParserContext() {
|
||||
public String getExpressionPrefix() {
|
||||
return "${";
|
||||
}
|
||||
public String getExpressionSuffix() {
|
||||
return "}";
|
||||
}
|
||||
public boolean isTemplate() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public void testParsingSimpleTemplateExpression01() throws Exception {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expr = parser.parseExpression("hello ${'world'}", DefaultTemplateParserContext.INSTANCE);
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
Expression expr = parser.parseExpression("hello ${'world'}", DEFAULT_TEMPLATE_PARSER_CONTEXT);
|
||||
Object o = expr.getValue();
|
||||
System.out.println(o);
|
||||
assertEquals("hello world", o.toString());
|
||||
}
|
||||
|
||||
public void testParsingSimpleTemplateExpression02() throws Exception {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expr = parser.parseExpression("hello ${'to'} you", DefaultTemplateParserContext.INSTANCE);
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
Expression expr = parser.parseExpression("hello ${'to'} you", DEFAULT_TEMPLATE_PARSER_CONTEXT);
|
||||
Object o = expr.getValue();
|
||||
System.out.println(o);
|
||||
assertEquals("hello to you", o.toString());
|
||||
}
|
||||
|
||||
public void testParsingSimpleTemplateExpression03() throws Exception {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
Expression expr = parser.parseExpression("The quick ${'brown'} fox jumped over the ${'lazy'} dog",
|
||||
DefaultTemplateParserContext.INSTANCE);
|
||||
DEFAULT_TEMPLATE_PARSER_CONTEXT);
|
||||
Object o = expr.getValue();
|
||||
System.out.println(o);
|
||||
assertEquals("The quick brown fox jumped over the lazy dog", o.toString());
|
||||
}
|
||||
|
||||
public void testCompositeStringExpression() throws Exception {
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
Expression ex = parser.parseExpression("hello ${'world'}", DEFAULT_TEMPLATE_PARSER_CONTEXT);
|
||||
checkString("hello world", ex.getValue());
|
||||
checkString("hello world", ex.getValue(String.class));
|
||||
EvaluationContext ctx = new StandardEvaluationContext();
|
||||
checkString("hello world", ex.getValue(ctx));
|
||||
checkString("hello world", ex.getValue(ctx, String.class));
|
||||
assertEquals("hello ${'world'}", ex.getExpressionString());
|
||||
assertFalse(ex.isWritable(new StandardEvaluationContext()));
|
||||
}
|
||||
|
||||
private void checkString(String expectedString, Object value) {
|
||||
if (!(value instanceof String)) {
|
||||
fail("Result was not a string, it was of type " + value.getClass() + " (value=" + value + ")");
|
||||
}
|
||||
if (!value.equals(expectedString)) {
|
||||
fail("Did not get expected result. Should have been '" + expectedString + "' but was '" + value + "'");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO need to support this case but what is the neatest way? Escape the clashing delimiters in the expression
|
||||
// string?
|
||||
// public void testParsingTemplateExpressionThatEmbedsTheDelimiters() throws Exception {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,19 +13,16 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.awt.*;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.expression.spel.standard.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.testresources.Fruit;
|
||||
import org.springframework.expression.spel.testresources.Inventor;
|
||||
import org.springframework.expression.spel.testresources.Person;
|
||||
@@ -43,7 +40,6 @@ public class TestScenarioCreator {
|
||||
StandardEvaluationContext testContext = new StandardEvaluationContext();
|
||||
setupRootContextObject(testContext);
|
||||
populateContextMap(testContext);
|
||||
createTestClassloader(testContext);
|
||||
populateVariables(testContext);
|
||||
populateFunctions(testContext);
|
||||
return testContext;
|
||||
@@ -81,20 +77,6 @@ public class TestScenarioCreator {
|
||||
testContext.setVariable("answer", 42);
|
||||
}
|
||||
|
||||
/**
|
||||
* Include a testcode jar on the default context classpath so that tests can lookup entries in it.
|
||||
* @param testContext the test evaluation context
|
||||
*/
|
||||
private static void createTestClassloader(StandardEvaluationContext testContext) {
|
||||
try {
|
||||
ClassLoader cl = new URLClassLoader(new URL[] { new File("target/test-classes/testcode.jar").toURI()
|
||||
.toURL() }, Thread.currentThread().getContextClassLoader());
|
||||
testContext.setClassLoader(cl);
|
||||
} catch (MalformedURLException mue) {
|
||||
mue.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the root context object, an Inventor instance. Non-qualified property and method references will be
|
||||
* resolved against this context object.
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import org.springframework.expression.spel.standard.StandardTypeLocator;
|
||||
|
||||
/**
|
||||
* Tests referring to system types, custom types, unqualified types.
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class TypeReferencing extends ExpressionTestCase {
|
||||
|
||||
public void testFromAJar() {
|
||||
evaluate("new SimpleType().sayHi('Andy')", "Hi! Andy", String.class);
|
||||
}
|
||||
|
||||
public void testFromAJar2() {
|
||||
evaluate("new a.b.c.PackagedType().sayHi('Andy')", "Hi! Andy", String.class);
|
||||
}
|
||||
|
||||
public void testFromAJar3() {
|
||||
evaluateAndCheckError("new PackagedType().sayHi('Andy')", SpelMessages.TYPE_NOT_FOUND);
|
||||
}
|
||||
|
||||
public void testFromAJar4() {
|
||||
((StandardTypeLocator) eContext.getTypeUtils().getTypeLocator()).registerImport("a.b.c");
|
||||
evaluate("new PackagedType().sayHi('Andy')", "Hi! Andy", String.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,9 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import org.springframework.expression.spel.standard.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.antlr.SpelAntlrExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
/**
|
||||
* Tests the evaluation of expressions that access variables and functions (lambda/java).
|
||||
@@ -53,13 +55,8 @@ public class VariableAndFunctionTests extends ExpressionTestCase {
|
||||
evaluate("#varargsFunctionReverseStringsAndMerge2(5,25)", "525", String.class);
|
||||
}
|
||||
|
||||
public void testCallingFunctionsIncorrectly() {
|
||||
evaluateAndCheckError("#varargsFunctionReverseStringsAndMerge(new StringBuilder())",
|
||||
SpelMessages.TYPE_CONVERSION_ERROR);
|
||||
}
|
||||
|
||||
public void testCallingIllegalFunctions() throws Exception {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||
ctx.setVariable("notStatic", this.getClass().getMethod("nonStatic"));
|
||||
try {
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
rem Used to test jar referencing, to rebuild
|
||||
|
||||
javac *.java -d .
|
||||
jar -cvMf testcode.jar *
|
||||
Binary file not shown.
Reference in New Issue
Block a user