From f76fb0b39f14dab71d8d5753bf3032239f520ab7 Mon Sep 17 00:00:00 2001 From: Jeremy Grelle Date: Thu, 21 Feb 2008 19:46:04 +0000 Subject: [PATCH] SWF-389 - Encapsulate the recommended default Web Flow configuration for a JSF environment. --- .../src/main/java/META-INF/spring.handlers | 1 + .../src/main/java/META-INF/spring.schemas | 1 + .../config/FacesConfigNamespaceHandler.java | 11 +++ ...owBuilderServicesBeanDefinitionParser.java | 82 +++++++++++++++++++ .../faces/config/spring-faces-config-2.0.xsd | 81 ++++++++++++++++++ .../LegacyJSFELExpressionParser.java | 4 + ...lderServicesBeanDefinitionParserTests.java | 43 ++++++++++ .../faces/config/flow-builder-services.xml | 15 ++++ 8 files changed, 238 insertions(+) create mode 100644 spring-faces/src/main/java/META-INF/spring.handlers create mode 100644 spring-faces/src/main/java/META-INF/spring.schemas create mode 100644 spring-faces/src/main/java/org/springframework/faces/config/FacesConfigNamespaceHandler.java create mode 100644 spring-faces/src/main/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParser.java create mode 100644 spring-faces/src/main/java/org/springframework/faces/config/spring-faces-config-2.0.xsd create mode 100644 spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java create mode 100644 spring-faces/src/test/java/org/springframework/faces/config/flow-builder-services.xml diff --git a/spring-faces/src/main/java/META-INF/spring.handlers b/spring-faces/src/main/java/META-INF/spring.handlers new file mode 100644 index 00000000..d533e40a --- /dev/null +++ b/spring-faces/src/main/java/META-INF/spring.handlers @@ -0,0 +1 @@ +http\://www.springframework.org/schema/faces-config=org.springframework.faces.config.FacesConfigNamespaceHandler \ No newline at end of file diff --git a/spring-faces/src/main/java/META-INF/spring.schemas b/spring-faces/src/main/java/META-INF/spring.schemas new file mode 100644 index 00000000..7188d258 --- /dev/null +++ b/spring-faces/src/main/java/META-INF/spring.schemas @@ -0,0 +1 @@ +http\://www.springframework.org/schema/faces-config/spring-faces-config-2.0.xsd=org/springframework/faces/config/spring-faces-config-2.0.xsd \ No newline at end of file diff --git a/spring-faces/src/main/java/org/springframework/faces/config/FacesConfigNamespaceHandler.java b/spring-faces/src/main/java/org/springframework/faces/config/FacesConfigNamespaceHandler.java new file mode 100644 index 00000000..5390f3a5 --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/config/FacesConfigNamespaceHandler.java @@ -0,0 +1,11 @@ +package org.springframework.faces.config; + +import org.springframework.beans.factory.xml.NamespaceHandlerSupport; + +public class FacesConfigNamespaceHandler extends NamespaceHandlerSupport { + + public void init() { + registerBeanDefinitionParser("flow-builder-services", new FacesFlowBuilderServicesBeanDefinitionParser()); + } + +} diff --git a/spring-faces/src/main/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParser.java b/spring-faces/src/main/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParser.java new file mode 100644 index 00000000..c357f663 --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParser.java @@ -0,0 +1,82 @@ +package org.springframework.faces.config; + +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.faces.expression.LegacyJSFELExpressionParser; +import org.springframework.faces.model.converter.FacesConversionService; +import org.springframework.faces.webflow.JsfViewFactoryCreator; +import org.springframework.util.StringUtils; +import org.springframework.webflow.core.expression.el.WebFlowELExpressionParser; +import org.springframework.webflow.engine.builder.support.FlowBuilderServices; +import org.w3c.dom.Element; + +public class FacesFlowBuilderServicesBeanDefinitionParser extends AbstractSingleBeanDefinitionParser implements + BeanDefinitionParser { + + private static final String ENABLE_MANAGED_BEANS_ATTRIBUTE = "enable-managed-beans"; + + private static final String EXPRESSION_PARSER_ATTRIBUTE = "expression-parser"; + + private static final String EXPRESSION_PARSER_PROPERTY = "expressionParser"; + + private static final String VIEW_FACTORY_CREATOR_ATTRIBUTE = "view-factory-creator"; + + private static final String VIEW_FACTORY_CREATOR_PROPERTY = "viewFactoryCreator"; + + private static final String CONVERSION_SERVICE_ATTRIBUTE = "conversion-service"; + + private static final String CONVERSION_SERVICE_PROPERTY = "conversionService"; + + protected Class getBeanClass(Element element) { + return FlowBuilderServices.class; + } + + protected void doParse(Element element, BeanDefinitionBuilder definitionBuilder) { + boolean enableManagedBeans = parseEnableManagedBeans(element, definitionBuilder); + if (!enableManagedBeans) { + parseExpressionParser(element, definitionBuilder); + } + parseViewFactoryCreator(element, definitionBuilder); + parseConversionService(element, definitionBuilder); + } + + private boolean parseEnableManagedBeans(Element element, BeanDefinitionBuilder definitionBuilder) { + String enableManagedBeans = element.getAttribute(ENABLE_MANAGED_BEANS_ATTRIBUTE); + if (StringUtils.hasText(enableManagedBeans)) { + boolean enabled = Boolean.parseBoolean(enableManagedBeans); + if (enabled) { + definitionBuilder.addPropertyValue(EXPRESSION_PARSER_PROPERTY, new LegacyJSFELExpressionParser()); + } + return enabled; + } + return false; + } + + private void parseConversionService(Element element, BeanDefinitionBuilder definitionBuilder) { + String conversionService = element.getAttribute(CONVERSION_SERVICE_ATTRIBUTE); + if (StringUtils.hasText(conversionService)) { + definitionBuilder.addPropertyReference(CONVERSION_SERVICE_PROPERTY, conversionService); + } else { + definitionBuilder.addPropertyValue(CONVERSION_SERVICE_PROPERTY, new FacesConversionService()); + } + } + + private void parseViewFactoryCreator(Element element, BeanDefinitionBuilder definitionBuilder) { + String viewFactoryCreator = element.getAttribute(VIEW_FACTORY_CREATOR_ATTRIBUTE); + if (StringUtils.hasText(viewFactoryCreator)) { + definitionBuilder.addPropertyReference(VIEW_FACTORY_CREATOR_PROPERTY, viewFactoryCreator); + } else { + definitionBuilder.addPropertyValue(VIEW_FACTORY_CREATOR_PROPERTY, new JsfViewFactoryCreator()); + } + } + + private void parseExpressionParser(Element element, BeanDefinitionBuilder definitionBuilder) { + String expressionParser = element.getAttribute(EXPRESSION_PARSER_ATTRIBUTE); + if (StringUtils.hasText(expressionParser)) { + definitionBuilder.addPropertyReference(EXPRESSION_PARSER_PROPERTY, expressionParser); + } else { + definitionBuilder.addPropertyValue(EXPRESSION_PARSER_PROPERTY, new WebFlowELExpressionParser()); + } + } +} diff --git a/spring-faces/src/main/java/org/springframework/faces/config/spring-faces-config-2.0.xsd b/spring-faces/src/main/java/org/springframework/faces/config/spring-faces-config-2.0.xsd new file mode 100644 index 00000000..67f2996f --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/config/spring-faces-config-2.0.xsd @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-faces/src/main/java/org/springframework/faces/expression/LegacyJSFELExpressionParser.java b/spring-faces/src/main/java/org/springframework/faces/expression/LegacyJSFELExpressionParser.java index ed89d0e6..2d97ed5b 100644 --- a/spring-faces/src/main/java/org/springframework/faces/expression/LegacyJSFELExpressionParser.java +++ b/spring-faces/src/main/java/org/springframework/faces/expression/LegacyJSFELExpressionParser.java @@ -31,6 +31,10 @@ public class LegacyJSFELExpressionParser extends ELExpressionParser { putContextFactory(MutableAttributeMap.class, new AttributeMapELContextFactory()); } + public LegacyJSFELExpressionParser() { + this(ExpressionFactory.newInstance()); + } + private static class RequestContextELContextFactory implements ELContextFactory { public ELContext getELContext(Object target) { List customResolvers = new ArrayList(); diff --git a/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java b/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java new file mode 100644 index 00000000..1dad5b5f --- /dev/null +++ b/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java @@ -0,0 +1,43 @@ +package org.springframework.faces.config; + +import junit.framework.TestCase; + +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.faces.expression.LegacyJSFELExpressionParser; +import org.springframework.faces.model.converter.FacesConversionService; +import org.springframework.faces.webflow.JSFMockHelper; +import org.springframework.faces.webflow.JsfViewFactoryCreator; +import org.springframework.webflow.core.expression.el.WebFlowELExpressionParser; +import org.springframework.webflow.engine.builder.support.FlowBuilderServices; + +public class FacesFlowBuilderServicesBeanDefinitionParserTests extends TestCase { + + private ClassPathXmlApplicationContext context; + private FlowBuilderServices builderServices; + private JSFMockHelper jsf = new JSFMockHelper(); + + public void setUp() throws Exception { + jsf.setUp(); + context = new ClassPathXmlApplicationContext("org/springframework/faces/config/flow-builder-services.xml"); + } + + protected void tearDown() throws Exception { + jsf.tearDown(); + } + + public void testConfigureDefaults() { + builderServices = (FlowBuilderServices) context.getBean("flowBuilderServicesDefault"); + assertNotNull(builderServices); + assertTrue(builderServices.getExpressionParser() instanceof WebFlowELExpressionParser); + assertTrue(builderServices.getViewFactoryCreator() instanceof JsfViewFactoryCreator); + assertTrue(builderServices.getConversionService() instanceof FacesConversionService); + } + + public void testEnableManagedBeans() { + builderServices = (FlowBuilderServices) context.getBean("flowBuilderServicesLegacy"); + assertNotNull(builderServices); + assertTrue(builderServices.getExpressionParser() instanceof LegacyJSFELExpressionParser); + assertTrue(builderServices.getViewFactoryCreator() instanceof JsfViewFactoryCreator); + assertTrue(builderServices.getConversionService() instanceof FacesConversionService); + } +} diff --git a/spring-faces/src/test/java/org/springframework/faces/config/flow-builder-services.xml b/spring-faces/src/test/java/org/springframework/faces/config/flow-builder-services.xml new file mode 100644 index 00000000..1876bb3d --- /dev/null +++ b/spring-faces/src/test/java/org/springframework/faces/config/flow-builder-services.xml @@ -0,0 +1,15 @@ + + + + + + + + \ No newline at end of file