diff --git a/spring-webflow/changelog.txt b/spring-webflow/changelog.txt index 790a796c..f53ffb80 100644 --- a/spring-webflow/changelog.txt +++ b/spring-webflow/changelog.txt @@ -25,6 +25,10 @@ Package org.springframework.webflow.conversation * Each SessionBindingConversationManager now uses a unique key to store it's conversation container in the session (SWF-304). +Package org.springframework.webflow.core +* Fixed DefaultExpressionParserFactory to not require OGNL on the classpath if another expression parser + is configured (SWF-335). + Package org.springframework.webflow.engine * Added invoke(String, Action) method to AbstractFlowBuilder. * Added initBuilder() hook method to AbstractFlowBuilder. diff --git a/spring-webflow/src/main/java/org/springframework/webflow/core/DefaultExpressionParserFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/core/DefaultExpressionParserFactory.java index 2630b237..45ed9779 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/core/DefaultExpressionParserFactory.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/core/DefaultExpressionParserFactory.java @@ -15,7 +15,10 @@ */ package org.springframework.webflow.core; +import org.springframework.binding.expression.Expression; import org.springframework.binding.expression.ExpressionParser; +import org.springframework.binding.expression.ParserException; +import org.springframework.binding.expression.SettableExpression; /** * Static helper factory that creates instances of the default expression parser @@ -26,11 +29,12 @@ import org.springframework.binding.expression.ExpressionParser; * the classpath when this class is loaded. * * @author Keith Donald + * @author Erwin Vervaet */ public final class DefaultExpressionParserFactory { /** - * The singleton instance. + * The singleton instance of the default expression parser. */ private static ExpressionParser INSTANCE; @@ -44,6 +48,28 @@ public final class DefaultExpressionParserFactory { * @return the expression parser */ public static synchronized ExpressionParser getExpressionParser() { + // return a wrapper that will lazily load the default expression parser + return new ExpressionParser() { + public boolean isDelimitedExpression(String expressionString) { + return getDefaultExpressionParser().isDelimitedExpression(expressionString); + } + + public Expression parseExpression(String expressionString) throws ParserException { + return getDefaultExpressionParser().parseExpression(expressionString); + } + + public SettableExpression parseSettableExpression(String expressionString) + throws ParserException, UnsupportedOperationException { + return getDefaultExpressionParser().parseSettableExpression(expressionString); + } + }; + } + + /** + * Returns the default expression parser, creating it if necessary. + * @return the default expression parser + */ + private static synchronized ExpressionParser getDefaultExpressionParser() { if (INSTANCE == null) { INSTANCE = createDefaultExpressionParser(); } @@ -58,12 +84,14 @@ public final class DefaultExpressionParserFactory { try { Class.forName("ognl.Ognl"); return new WebFlowOgnlExpressionParser(); - } catch (ClassNotFoundException e) { + } + catch (ClassNotFoundException e) { throw new IllegalStateException( "Unable to load the default expression parser: OGNL could not be found in the classpath. " + "Please add OGNL 2.x to your classpath or set the default ExpressionParser instance to something that is in the classpath. " + "Details: " + e.getMessage()); - } catch (NoClassDefFoundError e) { + } + catch (NoClassDefFoundError e) { throw new IllegalStateException( "Unable to construct the default expression parser: ognl.Ognl could not be instantiated. " + "Please add OGNL 2.x to your classpath or set the default ExpressionParser instance to something that is in the classpath. " diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/BaseFlowServiceLocator.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/BaseFlowServiceLocator.java index f7873982..bac49042 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/BaseFlowServiceLocator.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/BaseFlowServiceLocator.java @@ -66,11 +66,16 @@ public class BaseFlowServiceLocator implements FlowServiceLocator { * objects. */ private ExpressionParser expressionParser = DefaultExpressionParserFactory.getExpressionParser(); + + /** + * The conversion service configured by the user (none by default). + */ + private ConversionService userConversionService = null; /** * A conversion service that can convert between types. */ - private ConversionService conversionService = createConversionService(null); + private ConversionService conversionService = createConversionService(userConversionService); /** * A resource loader that can load resources. @@ -102,15 +107,18 @@ public class BaseFlowServiceLocator implements FlowServiceLocator { public void setExpressionParser(ExpressionParser expressionParser) { Assert.notNull(expressionParser, "The expression parser is required"); this.expressionParser = expressionParser; + //this has impact on the TextToExpression converter in the conversion service! + this.conversionService = createConversionService(userConversionService); } /** * Set the conversion service to use to convert between types; typically * from string to a rich object type. */ - public void setConversionService(ConversionService conversionService) { - Assert.notNull(conversionService, "The conversion service is required"); - this.conversionService = createConversionService(conversionService); + public void setConversionService(ConversionService userConversionService) { + Assert.notNull(userConversionService, "The conversion service is required"); + this.userConversionService = userConversionService; + this.conversionService = createConversionService(userConversionService); } /** diff --git a/spring-webflow/src/test/java/org/springframework/webflow/core/DefaultExpressionParserFactoryTests.java b/spring-webflow/src/test/java/org/springframework/webflow/core/DefaultExpressionParserFactoryTests.java index 71562385..6c10e58b 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/core/DefaultExpressionParserFactoryTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/core/DefaultExpressionParserFactoryTests.java @@ -27,6 +27,5 @@ public class DefaultExpressionParserFactoryTests extends TestCase { public void testGetDefaultExpressionParser() { ExpressionParser parser = DefaultExpressionParserFactory.getExpressionParser(); assertNotNull(parser); - assertTrue(parser instanceof WebFlowOgnlExpressionParser); } }