diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/SpringBeanWebFlowVariableResolver.java b/spring-faces/src/main/java/org/springframework/faces/webflow/SpringBeanWebFlowVariableResolver.java index 4880c760..e3c9a2f6 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/SpringBeanWebFlowVariableResolver.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/SpringBeanWebFlowVariableResolver.java @@ -23,12 +23,11 @@ public class SpringBeanWebFlowVariableResolver extends SpringBeanVariableResolve protected BeanFactory getBeanFactory(FacesContext facesContext) { RequestContext requestContext = RequestContextHolder.getRequestContext(); - if (requestContext != null && requestContext.getActiveFlow().getBeanFactory() != null) { - BeanFactory factory = requestContext.getActiveFlow().getBeanFactory(); - return factory; - } else { + if (requestContext == null) { return EMPTY_BEAN_FACTORY; } + BeanFactory beanFactory = requestContext.getActiveFlow().getApplicationContext(); + return beanFactory != null ? beanFactory : EMPTY_BEAN_FACTORY; } } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/FlowRegistryFactoryBean.java b/spring-webflow/src/main/java/org/springframework/webflow/config/FlowRegistryFactoryBean.java index 18f3c827..707f0713 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/config/FlowRegistryFactoryBean.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/config/FlowRegistryFactoryBean.java @@ -16,10 +16,10 @@ import org.springframework.webflow.definition.registry.FlowDefinitionConstructio import org.springframework.webflow.definition.registry.FlowDefinitionHolder; import org.springframework.webflow.definition.registry.FlowDefinitionRegistry; import org.springframework.webflow.definition.registry.FlowDefinitionRegistryImpl; +import org.springframework.webflow.engine.builder.DefaultFlowHolder; import org.springframework.webflow.engine.builder.FlowAssembler; import org.springframework.webflow.engine.builder.FlowBuilder; import org.springframework.webflow.engine.builder.FlowBuilderContext; -import org.springframework.webflow.engine.builder.DefaultFlowHolder; import org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder; import org.springframework.webflow.engine.builder.support.FlowBuilderContextImpl; import org.springframework.webflow.engine.builder.support.FlowBuilderServices; @@ -84,7 +84,7 @@ class FlowRegistryFactoryBean implements FactoryBean, InitializingBean { } public void afterPropertiesSet() throws Exception { - flowResourceFactory = new FlowDefinitionResourceFactory(flowBuilderServices.getResourceLoader()); + flowResourceFactory = new FlowDefinitionResourceFactory(flowBuilderServices.getApplicationContext()); flowRegistry = new FlowDefinitionRegistryImpl(); flowModelRegistry = new FlowModelRegistryImpl(); registerFlowLocations(); diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/scope/ConversationScope.java b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/ConversationScope.java index 37b5887e..4f5610ec 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/config/scope/ConversationScope.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/ConversationScope.java @@ -22,7 +22,7 @@ import org.springframework.webflow.core.collection.MutableAttributeMap; * Conversation {@link Scope scope} implementation. * @author Ben Hale */ -class ConversationScope extends AbstractWebFlowScope { +public class ConversationScope extends AbstractWebFlowScope { protected MutableAttributeMap getScope() { return getRequiredRequestContext().getConversationScope(); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/scope/FlashScope.java b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/FlashScope.java index 96d4a052..7b8c4d45 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/config/scope/FlashScope.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/FlashScope.java @@ -22,7 +22,7 @@ import org.springframework.webflow.core.collection.MutableAttributeMap; * Flash {@link Scope scope} implementation. * @author Ben Hale */ -class FlashScope extends AbstractWebFlowScope { +public class FlashScope extends AbstractWebFlowScope { protected MutableAttributeMap getScope() { return getRequiredRequestContext().getFlashScope(); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/scope/FlowScope.java b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/FlowScope.java index 6f67cba7..49c8cd93 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/config/scope/FlowScope.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/FlowScope.java @@ -22,7 +22,7 @@ import org.springframework.webflow.core.collection.MutableAttributeMap; * Flow {@link Scope scope} implementation. * @author Ben Hale */ -class FlowScope extends AbstractWebFlowScope { +public class FlowScope extends AbstractWebFlowScope { protected MutableAttributeMap getScope() { return getRequiredRequestContext().getFlowScope(); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/scope/RequestScope.java b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/RequestScope.java index e8c15625..ed192537 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/config/scope/RequestScope.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/RequestScope.java @@ -22,7 +22,7 @@ import org.springframework.webflow.core.collection.MutableAttributeMap; * Request {@link Scope scope} implementation. * @author Ben Hale */ -class RequestScope extends AbstractWebFlowScope { +public class RequestScope extends AbstractWebFlowScope { protected MutableAttributeMap getScope() { return getRequiredRequestContext().getRequestScope(); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/scope/ViewScope.java b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/ViewScope.java new file mode 100644 index 00000000..3a47a4c8 --- /dev/null +++ b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/ViewScope.java @@ -0,0 +1,29 @@ +/* + * Copyright 2004-2007 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.webflow.config.scope; + +import org.springframework.beans.factory.config.Scope; +import org.springframework.webflow.core.collection.MutableAttributeMap; + +/** + * View {@link Scope scope} implementation. + * @author Keith Donald + */ +public class ViewScope extends AbstractWebFlowScope { + protected MutableAttributeMap getScope() { + return getRequiredRequestContext().getViewScope(); + } +} diff --git a/spring-webflow/src/main/java/org/springframework/webflow/definition/FlowDefinition.java b/spring-webflow/src/main/java/org/springframework/webflow/definition/FlowDefinition.java index 558f2e25..542eca5f 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/definition/FlowDefinition.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/definition/FlowDefinition.java @@ -15,8 +15,7 @@ */ package org.springframework.webflow.definition; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.core.io.ResourceLoader; +import org.springframework.context.ApplicationContext; /** * The definition of a flow, a program that when executed carries out the orchestration of a task on behalf of a single @@ -65,13 +64,9 @@ public interface FlowDefinition extends Annotated { public StateDefinition getState(String id) throws IllegalArgumentException; /** - * Returns a reference to a bean factory hosting application objects needed by this flow definition. + * Returns a reference to application context hosting application objects and services needed by this flow + * definition. */ - public BeanFactory getBeanFactory(); - - /** - * Returns a reference to a resource loader capable of loading resources relative to this flow. - */ - public ResourceLoader getResourceLoader(); + public ApplicationContext getApplicationContext(); } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/Flow.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/Flow.java index 0d011184..d765f30f 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/Flow.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/Flow.java @@ -23,12 +23,9 @@ import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.support.StaticListableBeanFactory; import org.springframework.binding.mapping.Mapper; import org.springframework.binding.mapping.MappingResults; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.ResourceLoader; +import org.springframework.context.ApplicationContext; import org.springframework.core.style.StylerUtils; import org.springframework.core.style.ToStringCreator; import org.springframework.util.Assert; @@ -168,14 +165,9 @@ public class Flow extends AnnotatedObject implements FlowDefinition { private FlowExecutionExceptionHandlerSet exceptionHandlerSet = new FlowExecutionExceptionHandlerSet(); /** - * An optional bean factory hosting services needed by this flow. + * An optional application context hosting services needed by this flow. */ - private BeanFactory beanFactory = new StaticListableBeanFactory(); - - /** - * An optional resource loader capable of loading resources relative to this flow. - */ - private ResourceLoader resourceLoader = new DefaultResourceLoader(); + private ApplicationContext applicationContext; /** * Construct a new flow definition with the given id. The id should be unique among all flows. @@ -218,12 +210,8 @@ public class Flow extends AnnotatedObject implements FlowDefinition { return getStateInstance(stateId); } - public BeanFactory getBeanFactory() { - return beanFactory; - } - - public ResourceLoader getResourceLoader() { - return resourceLoader; + public ApplicationContext getApplicationContext() { + return applicationContext; } /** @@ -455,19 +443,11 @@ public class Flow extends AnnotatedObject implements FlowDefinition { } /** - * Sets a reference to a bean factory hosting application objects needed by this flow. - * @param beanFactory the bean factory + * Sets a reference to the application context hosting application objects needed by this flow. + * @param applicationContext the application context */ - public void setBeanFactory(BeanFactory beanFactory) { - this.beanFactory = beanFactory; - } - - /** - * Sets a reference to a resource loader capable of loading resources relative to this flow. - * @param resourceLoader the resource loader - */ - public void setResourceLoader(ResourceLoader resourceLoader) { - this.resourceLoader = resourceLoader; + public void setApplicationContext(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; } // id based equality diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/FlowBuilderContext.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/FlowBuilderContext.java index d8f4039a..f56fda0e 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/FlowBuilderContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/FlowBuilderContext.java @@ -15,11 +15,10 @@ */ package org.springframework.webflow.engine.builder; -import org.springframework.beans.factory.BeanFactory; import org.springframework.binding.convert.ConversionService; import org.springframework.binding.expression.ExpressionParser; import org.springframework.binding.format.FormatterRegistry; -import org.springframework.core.io.ResourceLoader; +import org.springframework.context.ApplicationContext; import org.springframework.webflow.core.collection.AttributeMap; import org.springframework.webflow.definition.registry.FlowDefinitionLocator; @@ -79,15 +78,8 @@ public interface FlowBuilderContext { public FormatterRegistry getFormatterRegistry(); /** - * Returns a generic resource loader for accessing file-based resources. - * @return the generic resource loader + * Returns the application context hosting the flow system. + * @return the application context */ - public ResourceLoader getResourceLoader(); - - /** - * Returns a generic bean factory for accessing arbitrary services by their id. - * @return the bean factory - */ - public BeanFactory getBeanFactory(); - + public ApplicationContext getApplicationContext(); } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java index 4bb632f0..4b193526 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java @@ -6,8 +6,6 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.binding.convert.ConversionException; @@ -29,6 +27,7 @@ import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.util.StringUtils; import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.request.RequestScope; import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.webflow.action.ActionResultExposer; import org.springframework.webflow.action.EvaluateAction; @@ -37,6 +36,10 @@ import org.springframework.webflow.action.FlowDefinitionRedirectAction; import org.springframework.webflow.action.RenderAction; import org.springframework.webflow.action.SetAction; import org.springframework.webflow.action.ViewFactoryActionAdapter; +import org.springframework.webflow.config.scope.ConversationScope; +import org.springframework.webflow.config.scope.FlashScope; +import org.springframework.webflow.config.scope.FlowScope; +import org.springframework.webflow.config.scope.ViewScope; import org.springframework.webflow.core.collection.AttributeMap; import org.springframework.webflow.core.collection.LocalAttributeMap; import org.springframework.webflow.core.collection.MutableAttributeMap; @@ -226,8 +229,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder { protected Flow createFlow() { Flow flow = parseFlow(flowModel); - flow.setBeanFactory(getLocalContext().getBeanFactory()); - flow.setResourceLoader(getLocalContext().getResourceLoader()); + flow.setApplicationContext(getLocalContext().getApplicationContext()); return flow; } @@ -285,9 +287,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder { } private GenericApplicationContext createFlowApplicationContext(Resource[] resources) { - // see if this factory has a parent - BeanFactory parent = getContext().getBeanFactory(); - // determine the context implementation based on the current environment + ApplicationContext parent = getContext().getApplicationContext(); GenericApplicationContext flowContext; if (parent instanceof WebApplicationContext) { GenericWebApplicationContext webContext = new GenericWebApplicationContext(); @@ -296,14 +296,12 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder { } else { flowContext = new GenericApplicationContext(); } - // set the parent if necessary - if (parent instanceof ApplicationContext) { - flowContext.setParent((ApplicationContext) parent); - } else { - if (parent != null) { - flowContext.getBeanFactory().setParentBeanFactory(parent); - } - } + flowContext.setParent(parent); + flowContext.getBeanFactory().registerScope("request", new RequestScope()); + flowContext.getBeanFactory().registerScope("flash", new FlashScope()); + flowContext.getBeanFactory().registerScope("view", new ViewScope()); + flowContext.getBeanFactory().registerScope("flow", new FlowScope()); + flowContext.getBeanFactory().registerScope("conversation", new ConversationScope()); Resource flowResource = flowModelHolder.getFlowModelResource(); if (flowResource != null) { flowContext.setResourceLoader(new FlowRelativeResourceLoader(flowResource)); @@ -312,7 +310,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder { AnnotationConfigUtils.registerAnnotationConfigProcessors(flowContext); } new XmlBeanDefinitionReader(flowContext).loadBeanDefinitions(resources); - registerFlowBeans(flowContext.getDefaultListableBeanFactory()); + registerFlowBeans(flowContext.getBeanFactory()); flowContext.refresh(); return flowContext; } @@ -329,8 +327,8 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder { private FlowVariable parseFlowVariable(VarModel var) { Class clazz = (Class) fromStringTo(Class.class).execute(var.getClassName()); - VariableValueFactory valueFactory = new BeanFactoryVariableValueFactory(clazz, - (AutowireCapableBeanFactory) getFlow().getBeanFactory()); + VariableValueFactory valueFactory = new BeanFactoryVariableValueFactory(clazz, getFlow() + .getApplicationContext().getAutowireCapableBeanFactory()); ScopeType scope = parseScopeType(var.getScope(), ScopeType.FLOW); return new FlowVariable(var.getName(), valueFactory, scope == ScopeType.FLOW ? true : false); } @@ -563,7 +561,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder { private ViewFactory createViewFactory(Expression viewId) { return getLocalContext().getViewFactoryCreator().createViewFactory(viewId, getLocalContext().getExpressionParser(), getLocalContext().getFormatterRegistry(), - getLocalContext().getResourceLoader()); + getLocalContext().getApplicationContext()); } private ViewVariable[] parseViewVariables(List vars) { @@ -580,8 +578,8 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder { private ViewVariable parseViewVariable(VarModel var) { Class clazz = (Class) fromStringTo(Class.class).execute(var.getClassName()); - VariableValueFactory valueFactory = new BeanFactoryVariableValueFactory(clazz, - (AutowireCapableBeanFactory) getFlow().getBeanFactory()); + VariableValueFactory valueFactory = new BeanFactoryVariableValueFactory(clazz, getFlow() + .getApplicationContext().getAutowireCapableBeanFactory()); return new ViewVariable(var.getName(), valueFactory); } @@ -632,7 +630,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder { private SubflowAttributeMapper parseSubflowAttributeMapper(SubflowStateModel state) { if (StringUtils.hasText(state.getSubflowAttributeMapper())) { String beanId = state.getSubflowAttributeMapper(); - return (SubflowAttributeMapper) getLocalContext().getBeanFactory().getBean(beanId, + return (SubflowAttributeMapper) getLocalContext().getApplicationContext().getBean(beanId, SubflowAttributeMapper.class); } else { Mapper inputMapper = parseSubflowInputMapper(state.getInputs()); @@ -695,7 +693,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder { } private FlowExecutionExceptionHandler parseCustomExceptionHandler(ExceptionHandlerModel exceptionHandler) { - return (FlowExecutionExceptionHandler) getLocalContext().getBeanFactory().getBean( + return (FlowExecutionExceptionHandler) getLocalContext().getApplicationContext().getBean( exceptionHandler.getBeanName(), FlowExecutionExceptionHandler.class); } @@ -776,7 +774,8 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder { private Action parseRenderAction(RenderModel render) { String[] fragmentExpressionStrings = StringUtils.commaDelimitedListToStringArray(render.getFragments()); fragmentExpressionStrings = StringUtils.trimArrayElements(fragmentExpressionStrings); - ParserContext context = new FluentParserContext().template().evaluate(RequestContext.class).expectResult(String.class); + ParserContext context = new FluentParserContext().template().evaluate(RequestContext.class).expectResult( + String.class); Expression[] fragments = new Expression[fragmentExpressionStrings.length]; for (int i = 0; i < fragmentExpressionStrings.length; i++) { String fragment = fragmentExpressionStrings[i]; diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/LocalFlowBuilderContext.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/LocalFlowBuilderContext.java index 7bf061a2..09437e71 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/LocalFlowBuilderContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/LocalFlowBuilderContext.java @@ -15,12 +15,11 @@ */ package org.springframework.webflow.engine.builder.model; -import org.springframework.beans.factory.BeanFactory; import org.springframework.binding.convert.ConversionService; import org.springframework.binding.expression.ExpressionParser; import org.springframework.binding.format.FormatterRegistry; +import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericApplicationContext; -import org.springframework.core.io.ResourceLoader; import org.springframework.webflow.core.collection.AttributeMap; import org.springframework.webflow.definition.registry.FlowDefinitionLocator; import org.springframework.webflow.engine.builder.FlowArtifactFactory; @@ -36,13 +35,17 @@ class LocalFlowBuilderContext implements FlowBuilderContext { private FlowBuilderContext parent; - private GenericApplicationContext localFlowContext; + private ApplicationContext localFlowContext; public LocalFlowBuilderContext(FlowBuilderContext parent, GenericApplicationContext localFlowContext) { this.parent = parent; this.localFlowContext = localFlowContext; } + public ApplicationContext getApplicationContext() { + return localFlowContext; + } + public String getFlowId() { return parent.getFlowId(); } @@ -99,11 +102,4 @@ class LocalFlowBuilderContext implements FlowBuilderContext { } } - public ResourceLoader getResourceLoader() { - return localFlowContext; - } - - public BeanFactory getBeanFactory() { - return localFlowContext.getBeanFactory(); - } } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderContextImpl.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderContextImpl.java index b23e39a0..fc096b69 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderContextImpl.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderContextImpl.java @@ -1,13 +1,12 @@ package org.springframework.webflow.engine.builder.support; -import org.springframework.beans.factory.BeanFactory; import org.springframework.binding.convert.ConversionException; import org.springframework.binding.convert.ConversionExecutor; import org.springframework.binding.convert.ConversionService; import org.springframework.binding.convert.service.GenericConversionService; import org.springframework.binding.expression.ExpressionParser; import org.springframework.binding.format.FormatterRegistry; -import org.springframework.core.io.ResourceLoader; +import org.springframework.context.ApplicationContext; import org.springframework.util.Assert; import org.springframework.webflow.core.collection.AttributeMap; import org.springframework.webflow.definition.registry.FlowDefinitionLocator; @@ -68,6 +67,10 @@ public class FlowBuilderContextImpl implements FlowBuilderContext { return flowBuilderServices.getFlowArtifactFactory(); } + public FlowDefinitionLocator getFlowDefinitionLocator() { + return flowDefinitionLocator; + } + public ConversionService getConversionService() { return conversionService; } @@ -84,16 +87,8 @@ public class FlowBuilderContextImpl implements FlowBuilderContext { return flowBuilderServices.getExpressionParser(); } - public ResourceLoader getResourceLoader() { - return flowBuilderServices.getResourceLoader(); - } - - public BeanFactory getBeanFactory() { - return flowBuilderServices.getBeanFactory(); - } - - public FlowDefinitionLocator getFlowDefinitionLocator() { - return flowDefinitionLocator; + public ApplicationContext getApplicationContext() { + return flowBuilderServices.getApplicationContext(); } /** diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderServices.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderServices.java index 0437f668..2454a59f 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderServices.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderServices.java @@ -1,14 +1,12 @@ package org.springframework.webflow.engine.builder.support; import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.InitializingBean; import org.springframework.binding.convert.ConversionService; import org.springframework.binding.expression.ExpressionParser; import org.springframework.binding.format.FormatterRegistry; -import org.springframework.context.ResourceLoaderAware; -import org.springframework.core.io.ResourceLoader; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; import org.springframework.util.Assert; import org.springframework.webflow.action.BeanInvokingActionFactory; import org.springframework.webflow.engine.Flow; @@ -29,7 +27,7 @@ import org.springframework.webflow.engine.builder.ViewFactoryCreator; * * @author Keith Donald */ -public class FlowBuilderServices implements ResourceLoaderAware, BeanFactoryAware, InitializingBean { +public class FlowBuilderServices implements ApplicationContextAware, InitializingBean { /** * The factory encapsulating the creation of central Flow artifacts such as {@link Flow flows} and @@ -60,14 +58,9 @@ public class FlowBuilderServices implements ResourceLoaderAware, BeanFactoryAwar private ExpressionParser expressionParser; /** - * A resource loader that can load resources. + * The Spring application context that provides access to the services of the application. */ - private ResourceLoader resourceLoader; - - /** - * The Spring bean factory that provides access to the services of the user application. - */ - private BeanFactory beanFactory; + private ApplicationContext applicationContext; public FlowArtifactFactory getFlowArtifactFactory() { return flowArtifactFactory; @@ -109,32 +102,24 @@ public class FlowBuilderServices implements ResourceLoaderAware, BeanFactoryAwar this.expressionParser = expressionParser; } - public ResourceLoader getResourceLoader() { - return resourceLoader; + public ApplicationContext getApplicationContext() { + return applicationContext; } - public void setResourceLoader(ResourceLoader resourceLoader) { - this.resourceLoader = resourceLoader; - } + // implementing ApplicationContextAware - public BeanFactory getBeanFactory() { - return beanFactory; - } - - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - this.beanFactory = beanFactory; + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; } // implementing InitializingBean public void afterPropertiesSet() throws Exception { - Assert.notNull(flowArtifactFactory, "The flow artifact factory is required"); - Assert.notNull(viewFactoryCreator, "The view factory creator is required"); - Assert.notNull(conversionService, "The type conversion service is required"); - Assert.notNull(formatterRegistry, "The formatter registry is required"); - Assert.notNull(expressionParser, "The expression parser is required"); - Assert.notNull(resourceLoader, "The resource loader is required"); - Assert.notNull(beanFactory, "The bean factory is required"); + Assert.notNull(flowArtifactFactory, "The FlowArtifactFactory is required"); + Assert.notNull(viewFactoryCreator, "The ViewFactoryCreator is required"); + Assert.notNull(conversionService, "The type ConversionService is required"); + Assert.notNull(formatterRegistry, "The FormatterRegistry is required"); + Assert.notNull(expressionParser, "The expressionParser is required"); + Assert.notNull(applicationContext, "The ApplicationContext is required"); } - } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParser.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParser.java index 16e6c8b7..b33c0336 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParser.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParser.java @@ -174,12 +174,8 @@ public class WebFlowOgnlExpressionParser extends OgnlExpressionParser { } private BeanFactory getBeanFactory(RequestContext requestContext) { - if (requestContext.getActiveFlow().getBeanFactory() != null) { - BeanFactory factory = requestContext.getActiveFlow().getBeanFactory(); - return factory; - } else { - return EMPTY_BEAN_FACTORY; - } + BeanFactory beanFactory = requestContext.getActiveFlow().getApplicationContext(); + return beanFactory != null ? beanFactory : EMPTY_BEAN_FACTORY; } } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/SpringBeanWebFlowELResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/SpringBeanWebFlowELResolver.java index 7406dd0a..a8323b14 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/SpringBeanWebFlowELResolver.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/SpringBeanWebFlowELResolver.java @@ -42,12 +42,11 @@ public class SpringBeanWebFlowELResolver extends SpringBeanELResolver { protected BeanFactory getBeanFactory(ELContext elContext) { RequestContext requestContext = getRequestContext(); - if (requestContext != null && requestContext.getActiveFlow().getBeanFactory() != null) { - BeanFactory factory = requestContext.getActiveFlow().getBeanFactory(); - return factory; - } else { + if (requestContext == null) { return EMPTY_BEAN_FACTORY; } + BeanFactory beanFactory = requestContext.getActiveFlow().getApplicationContext(); + return beanFactory != null ? beanFactory : EMPTY_BEAN_FACTORY; } protected RequestContext getRequestContext() { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcView.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcView.java index 81252778..a0b50b04 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcView.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/portlet/PortletMvcView.java @@ -21,8 +21,8 @@ import javax.portlet.PortletContext; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; -import org.springframework.context.ApplicationContext; import org.springframework.web.portlet.DispatcherPortlet; +import org.springframework.web.servlet.View; import org.springframework.web.servlet.ViewRendererServlet; import org.springframework.webflow.context.ExternalContext; import org.springframework.webflow.execution.RequestContext; @@ -35,40 +35,35 @@ import org.springframework.webflow.mvc.view.MvcView; */ public class PortletMvcView extends MvcView { - private ApplicationContext applicationContext; - /** * Creates a new portlet view. * @param view the view to render * @param context the current flow request context * @param applicationContext the application context */ - public PortletMvcView(org.springframework.web.servlet.View view, RequestContext context, - ApplicationContext applicationContext) { + public PortletMvcView(org.springframework.web.servlet.View view, RequestContext context) { super(view, context); - this.applicationContext = applicationContext; } - public void doRender(org.springframework.web.servlet.View view, Map model, ExternalContext context) throws Exception { - PortletContext portletContext = (PortletContext) context.getNativeContext(); - RenderRequest request = (RenderRequest) context.getNativeRequest(); - RenderResponse response = (RenderResponse) context.getNativeResponse(); - // Set the content type on the response if needed and if possible. - // The Portlet spec requires the content type to be set on the RenderResponse; - // it's not sufficient to let the View set it on the ServletResponse. + public void doRender(Map model) throws Exception { + RequestContext context = getRequestContext(); + ExternalContext externalContext = context.getExternalContext(); + View view = getView(); + PortletContext portletContext = (PortletContext) externalContext.getNativeContext(); + RenderRequest request = (RenderRequest) externalContext.getNativeRequest(); + RenderResponse response = (RenderResponse) externalContext.getNativeResponse(); if (response.getContentType() == null) { // No Portlet content type specified yet -> use the view-determined type. + // (The Portlet spec requires the content type to be set on the RenderResponse) String contentType = view.getContentType(); if (contentType != null) { response.setContentType(contentType); } } - // Expose Portlet ApplicationContext to view objects. - request.setAttribute(ViewRendererServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, applicationContext); - // These attributes are required by the ViewRendererServlet. request.setAttribute(ViewRendererServlet.VIEW_ATTRIBUTE, view); request.setAttribute(ViewRendererServlet.MODEL_ATTRIBUTE, model); - // Include the content of the view in the render response. + // request.setAttribute(org.springframework.web.servlet.support.RequestContext.WEB_APPLICATION_CONTEXT_ATTRIBUTE, + // context.getActiveFlow().getBeanFactory()); portletContext.getRequestDispatcher(DispatcherPortlet.DEFAULT_VIEW_RENDERER_URL).include(request, response); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcView.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcView.java index c66daa8b..cb002a45 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcView.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/ServletMvcView.java @@ -39,9 +39,13 @@ public class ServletMvcView extends MvcView { super(view, context); } - public void doRender(org.springframework.web.servlet.View view, Map model, ExternalContext context) throws Exception { - view.render(model, (HttpServletRequest) context.getNativeRequest(), (HttpServletResponse) context - .getNativeResponse()); + public void doRender(Map model) throws Exception { + RequestContext context = getRequestContext(); + ExternalContext externalContext = context.getExternalContext(); + HttpServletRequest request = (HttpServletRequest) externalContext.getNativeRequest(); + HttpServletResponse response = (HttpServletResponse) externalContext.getNativeResponse(); + // request.setAttribute(org.springframework.web.servlet.support.RequestContext.WEB_APPLICATION_CONTEXT_ATTRIBUTE, + // context.getActiveFlow().getBeanFactory()); + getView().render(model, request, response); } - } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/BindingModel.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/BindingModel.java index 4afb9015..9b720ec2 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/BindingModel.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/BindingModel.java @@ -19,6 +19,16 @@ import org.springframework.binding.message.Severity; import org.springframework.validation.FieldError; import org.springframework.validation.ObjectError; +/** + * Makes the properties of the "model" object available to Spring views during rendering. Also makes data binding (aka + * mapping) results available after a form postback attempt. Also makes error messages available to the view. + * + * This class is a Spring Errors adapter, basically, for use with spring form and bind tags. + * + * @see MvcView + * + * @author Keith Donald + */ public class BindingModel extends ViewRenderingErrors { private Object boundObject; @@ -31,6 +41,13 @@ public class BindingModel extends ViewRenderingErrors { private MessageContext messageContext; + /** + * Creates a new Spring Binding model. + * @param boundObject the bound model object + * @param expressionParser the expression parser used to access model object properties + * @param formatterRegistry the formatter registry used to access formatters for formatting properties + * @param messageContext the message context containing flow messages to display + */ public BindingModel(Object boundObject, ExpressionParser expressionParser, FormatterRegistry formatterRegistry, MessageContext messageContext) { this.boundObject = boundObject; @@ -39,10 +56,17 @@ public class BindingModel extends ViewRenderingErrors { this.messageContext = messageContext; } + /** + * Sets the results of a data mapping attempt onto the bound model object from the view. + * @see MvcView#processUserEvent() + * @param results + */ public void setMappingResults(MappingResults results) { this.mappingResults = results; } + // implementing Errors + public List getAllErrors() { return toErrors(messageContext.getMessagesByCriteria(ERRORS_ANY_SOURCE)); } @@ -70,6 +94,8 @@ public class BindingModel extends ViewRenderingErrors { return getFormattedValue(parseFieldExpression(field)); } + // internal helpers + private Expression parseFieldExpression(String field) { return expressionParser.parseExpression(field, new FluentParserContext().evaluate(boundObject.getClass())); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/InternalFlowResourceMvcViewFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/InternalFlowResourceMvcViewFactory.java index 350cb93f..8a22abd6 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/InternalFlowResourceMvcViewFactory.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/InternalFlowResourceMvcViewFactory.java @@ -5,6 +5,7 @@ import org.springframework.binding.expression.ExpressionParser; import org.springframework.binding.format.FormatterRegistry; import org.springframework.context.ApplicationContext; import org.springframework.core.io.ContextResource; +import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.util.ClassUtils; import org.springframework.web.servlet.view.InternalResourceView; @@ -22,6 +23,7 @@ import org.springframework.webflow.mvc.servlet.ServletMvcView; * @author Keith Donald */ class InternalFlowResourceMvcViewFactory implements ViewFactory { + private static final boolean JSTL_PRESENT = ClassUtils.isPresent("javax.servlet.jsp.jstl.fmt.LocalizationContext"); private Expression viewIdExpression; @@ -48,8 +50,12 @@ class InternalFlowResourceMvcViewFactory implements ViewFactory { if (viewId.startsWith("/")) { return getViewInternal(viewId, context); } else { - ContextResource viewResource = (ContextResource) resourceLoader.getResource(viewId); - return getViewInternal(viewResource.getPathWithinContext(), context); + Resource viewResource = resourceLoader.getResource(viewId); + if (!(viewResource instanceof ContextResource)) { + throw new IllegalStateException( + "A ContextResource is required to get relative view paths within this context"); + } + return getViewInternal(((ContextResource) viewResource).getPathWithinContext(), context); } } @@ -57,11 +63,10 @@ class InternalFlowResourceMvcViewFactory implements ViewFactory { if (viewPath.endsWith(".jsp")) { if (JSTL_PRESENT) { JstlView view = new JstlView(viewPath); - view.setApplicationContext(applicationContext); + view.setApplicationContext(context.getActiveFlow().getApplicationContext()); return createMvcView(view, context); } else { InternalResourceView view = new InternalResourceView(viewPath); - view.setApplicationContext(applicationContext); return createMvcView(view, context); } } else { @@ -72,7 +77,7 @@ class InternalFlowResourceMvcViewFactory implements ViewFactory { private MvcView createMvcView(org.springframework.web.servlet.View view, RequestContext context) { MvcView mvcView; if (context.getExternalContext() instanceof PortletExternalContext) { - mvcView = new PortletMvcView(view, context, applicationContext); + mvcView = new PortletMvcView(view, context); } else { mvcView = new ServletMvcView(view, context); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MessageContextErrors.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MessageContextErrors.java index 0d588c5f..5eb95436 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MessageContextErrors.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MessageContextErrors.java @@ -8,10 +8,20 @@ import org.springframework.validation.Errors; import org.springframework.validation.FieldError; import org.springframework.validation.ObjectError; +/** + * Adapts a MessageContext object to the Spring Errors interface. Allows Spring Validators to record errors that are + * managed by a backing MessageContext. + * + * @author Keith Donald + */ public class MessageContextErrors implements Errors { private MessageContext messageContext; + /** + * Creates a new message context errors adapter. + * @param messageContext the backing message context + */ public MessageContextErrors(MessageContext messageContext) { this.messageContext = messageContext; } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java index c7f8965b..622c3a21 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java @@ -46,7 +46,6 @@ import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; import org.springframework.validation.BindingResult; import org.springframework.validation.Errors; -import org.springframework.webflow.context.ExternalContext; import org.springframework.webflow.core.collection.ParameterMap; import org.springframework.webflow.definition.TransitionDefinition; import org.springframework.webflow.definition.TransitionableStateDefinition; @@ -68,7 +67,7 @@ public abstract class MvcView implements View { private org.springframework.web.servlet.View view; - private RequestContext context; + private RequestContext requestContext; private ExpressionParser expressionParser = DefaultExpressionParserFactory.getExpressionParser(); @@ -83,11 +82,11 @@ public abstract class MvcView implements View { /** * Creates a new MVC view. * @param view the Spring MVC view to render - * @param context the current flow request context + * @param requestContext the current flow request context */ - public MvcView(org.springframework.web.servlet.View view, RequestContext context) { + public MvcView(org.springframework.web.servlet.View view, RequestContext requestContext) { this.view = view; - this.context = context; + this.requestContext = requestContext; } /** @@ -110,13 +109,12 @@ public abstract class MvcView implements View { Map model = new HashMap(); model.putAll(flowScopes()); exposeBindingModel(model); - model.put("flowRequestContext", context); - model.put("flowExecutionKey", context.getFlowExecutionContext().getKey().toString()); - model.put("flowExecutionUrl", context.getFlowExecutionUrl()); - model.put("currentUser", context.getExternalContext().getCurrentUser()); - // TODO expose flow context to mvc view + model.put("flowRequestContext", requestContext); + model.put("flowExecutionKey", requestContext.getFlowExecutionContext().getKey().toString()); + model.put("flowExecutionUrl", requestContext.getFlowExecutionUrl()); + model.put("currentUser", requestContext.getExternalContext().getCurrentUser()); try { - doRender(view, model, context.getExternalContext()); + doRender(model); } catch (IOException e) { throw e; } catch (Exception e) { @@ -124,18 +122,8 @@ public abstract class MvcView implements View { } } - /** - * Template method subclasses should override to execute the view rendering logic. - * @param view the MVC view to render - * @param model the view model data - * @param context the flow external context, providing access to the request and response - * @throws Exception an exception occurred rendering the view - */ - protected abstract void doRender(org.springframework.web.servlet.View view, Map model, ExternalContext context) - throws Exception; - public void processUserEvent() { - determineEventId(context); + determineEventId(requestContext); if (eventId == null) { return; } @@ -150,7 +138,7 @@ public abstract class MvcView implements View { addErrorMessages(mappingResults); } else { validate(model); - if (context.getMessageContext().hasErrorMessages()) { + if (requestContext.getMessageContext().hasErrorMessages()) { viewErrors = true; } } @@ -165,19 +153,46 @@ public abstract class MvcView implements View { if (!hasFlowEvent()) { return null; } - return new Event(this, eventId, context.getRequestParameters().asAttributeMap()); + return new Event(this, eventId, requestContext.getRequestParameters().asAttributeMap()); } + // subclassing hooks + + /** + * Returns the current flow request context. + * @return the flow request context + */ + protected RequestContext getRequestContext() { + return requestContext; + } + + /** + * Returns the Spring MVC view to render + * @return the view + */ + protected org.springframework.web.servlet.View getView() { + return view; + } + + /** + * Template method subclasses should override to execute the view rendering logic. + * @param model the view model data + * @throws Exception an exception occurred rendering the view + */ + protected abstract void doRender(Map model) throws Exception; + + // internal helpers + private Map flowScopes() { - return context.getConversationScope().union(context.getFlowScope()).union(context.getFlashScope()).union( - context.getRequestScope()).asMap(); + return requestContext.getConversationScope().union(requestContext.getFlowScope()).union( + requestContext.getFlashScope()).union(requestContext.getRequestScope()).asMap(); } private void exposeBindingModel(Map model) { Object modelObject = getModelObject(); if (modelObject != null) { - BindingModel bindingModel = new BindingModel(modelObject, expressionParser, formatterRegistry, context - .getMessageContext()); + BindingModel bindingModel = new BindingModel(modelObject, expressionParser, formatterRegistry, + requestContext.getMessageContext()); bindingModel.setMappingResults(mappingResults); model.put(BindingResult.MODEL_KEY_PREFIX + getModelExpression().getExpressionString(), bindingModel); } @@ -186,18 +201,18 @@ public abstract class MvcView implements View { private Object getModelObject() { Expression model = getModelExpression(); if (model != null) { - return model.getValue(context); + return model.getValue(requestContext); } else { return null; } } private Expression getModelExpression() { - return (Expression) context.getCurrentState().getAttributes().get("model"); + return (Expression) requestContext.getCurrentState().getAttributes().get("model"); } private boolean shouldBind(Object model) { - TransitionableStateDefinition currentState = (TransitionableStateDefinition) context.getCurrentState(); + TransitionableStateDefinition currentState = (TransitionableStateDefinition) requestContext.getCurrentState(); TransitionDefinition transition = currentState.getTransition(eventId); if (transition != null) { if (transition.getAttributes().contains("bind")) { @@ -209,8 +224,8 @@ public abstract class MvcView implements View { private MappingResults bind(Object model) { DefaultMapper mapper = new DefaultMapper(); - addDefaultMappings(mapper, context.getRequestParameters(), model); - return mapper.map(context.getRequestParameters(), model); + addDefaultMappings(mapper, requestContext.getRequestParameters(), model); + return mapper.map(requestContext.getRequestParameters(), model); } private void addDefaultMappings(DefaultMapper mapper, ParameterMap requestParameters, Object model) { @@ -238,7 +253,7 @@ public abstract class MvcView implements View { List errors = results.getResults(MAPPING_ERROR); for (Iterator it = errors.iterator(); it.hasNext();) { MappingResult error = (MappingResult) it.next(); - context.getMessageContext().addMessage(createMessageResolver(error)); + requestContext.getMessageContext().addMessage(createMessageResolver(error)); } } @@ -252,27 +267,29 @@ public abstract class MvcView implements View { } private void validate(Object model) { - String validateMethodName = "validate" + StringUtils.capitalize(context.getCurrentState().getId()); + String validateMethodName = "validate" + StringUtils.capitalize(requestContext.getCurrentState().getId()); Method validateMethod = ReflectionUtils.findMethod(model.getClass(), validateMethodName, new Class[] { MessageContext.class }); if (validateMethod != null) { - ReflectionUtils.invokeMethod(validateMethod, model, new Object[] { context.getMessageContext() }); + ReflectionUtils.invokeMethod(validateMethod, model, new Object[] { requestContext.getMessageContext() }); } - BeanFactory beanFactory = context.getActiveFlow().getBeanFactory(); - String validatorName = getModelExpression().getExpressionString() + "Validator"; - if (beanFactory.containsBean(validatorName)) { - Object validator = beanFactory.getBean(validatorName); - validateMethod = ReflectionUtils.findMethod(validator.getClass(), validateMethodName, new Class[] { - model.getClass(), MessageContext.class }); - if (validateMethod != null) { - ReflectionUtils.invokeMethod(validateMethod, validator, new Object[] { model, - context.getMessageContext() }); - } else { + BeanFactory beanFactory = requestContext.getActiveFlow().getApplicationContext(); + if (beanFactory != null) { + String validatorName = getModelExpression().getExpressionString() + "Validator"; + if (beanFactory.containsBean(validatorName)) { + Object validator = beanFactory.getBean(validatorName); validateMethod = ReflectionUtils.findMethod(validator.getClass(), validateMethodName, new Class[] { - model.getClass(), Errors.class }); + model.getClass(), MessageContext.class }); if (validateMethod != null) { ReflectionUtils.invokeMethod(validateMethod, validator, new Object[] { model, - new MessageContextErrors(context.getMessageContext()) }); + requestContext.getMessageContext() }); + } else { + validateMethod = ReflectionUtils.findMethod(validator.getClass(), validateMethodName, new Class[] { + model.getClass(), Errors.class }); + if (validateMethod != null) { + ReflectionUtils.invokeMethod(validateMethod, validator, new Object[] { model, + new MessageContextErrors(requestContext.getMessageContext()) }); + } } } } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/ViewResolvingMvcViewFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/ViewResolvingMvcViewFactory.java index 97706101..4dcfba06 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/ViewResolvingMvcViewFactory.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/ViewResolvingMvcViewFactory.java @@ -45,7 +45,7 @@ class ViewResolvingMvcViewFactory implements ViewFactory { String viewName = (String) viewIdExpression.getValue(context); MvcView view; if (context.getExternalContext() instanceof PortletExternalContext) { - view = new PortletMvcView(resolveView(viewName), context, applicationContext); + view = new PortletMvcView(resolveView(viewName), context); } else { view = new ServletMvcView(resolveView(viewName), context); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/test/MockFlowBuilderContext.java b/spring-webflow/src/main/java/org/springframework/webflow/test/MockFlowBuilderContext.java index 84fcfe4c..9bffd226 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/test/MockFlowBuilderContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/test/MockFlowBuilderContext.java @@ -16,7 +16,7 @@ package org.springframework.webflow.test; import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.beans.factory.support.StaticListableBeanFactory; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.webflow.core.collection.AttributeMap; import org.springframework.webflow.core.collection.CollectionUtils; import org.springframework.webflow.definition.registry.FlowDefinitionRegistryImpl; @@ -69,7 +69,7 @@ public class MockFlowBuilderContext extends FlowBuilderContextImpl { * @param bean the singleton instance */ public void registerBean(String beanName, Object bean) { - ((StaticListableBeanFactory) getBeanFactory()).addBean(beanName, bean); + ((ConfigurableApplicationContext) getApplicationContext()).getBeanFactory().registerSingleton(beanName, bean); } } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/test/TestFlowBuilderServicesFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/test/TestFlowBuilderServicesFactory.java index 1487e2fe..4000c1d1 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/test/TestFlowBuilderServicesFactory.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/test/TestFlowBuilderServicesFactory.java @@ -1,8 +1,7 @@ package org.springframework.webflow.test; -import org.springframework.beans.factory.support.StaticListableBeanFactory; import org.springframework.binding.convert.service.DefaultConversionService; -import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.context.support.StaticApplicationContext; import org.springframework.webflow.engine.builder.support.FlowBuilderServices; import org.springframework.webflow.expression.DefaultExpressionParserFactory; @@ -19,8 +18,13 @@ public class TestFlowBuilderServicesFactory { services.setViewFactoryCreator(new MockViewFactoryCreator()); services.setConversionService(DefaultConversionService.getSharedInstance()); services.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser()); - services.setResourceLoader(new DefaultResourceLoader()); - services.setBeanFactory(new StaticListableBeanFactory()); + services.setApplicationContext(createTestApplicationContext()); return services; } + + private static StaticApplicationContext createTestApplicationContext() { + StaticApplicationContext context = new StaticApplicationContext(); + context.refresh(); + return context; + } } \ No newline at end of file diff --git a/spring-webflow/src/test/java/org/springframework/webflow/definition/registry/FlowDefinitionRegistryImplTests.java b/spring-webflow/src/test/java/org/springframework/webflow/definition/registry/FlowDefinitionRegistryImplTests.java index d36b6743..658e98e4 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/definition/registry/FlowDefinitionRegistryImplTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/definition/registry/FlowDefinitionRegistryImplTests.java @@ -17,8 +17,7 @@ package org.springframework.webflow.definition.registry; import junit.framework.TestCase; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.core.io.ResourceLoader; +import org.springframework.context.ApplicationContext; import org.springframework.webflow.core.collection.MutableAttributeMap; import org.springframework.webflow.definition.FlowDefinition; import org.springframework.webflow.definition.StateDefinition; @@ -104,15 +103,10 @@ public class FlowDefinitionRegistryImplTests extends TestCase { return null; } - public BeanFactory getBeanFactory() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Auto-generated method stub"); + public ApplicationContext getApplicationContext() { + return null; } - public ResourceLoader getResourceLoader() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Auto-generated method stub"); - } } private static class BarFlow implements FlowDefinition { @@ -142,14 +136,8 @@ public class FlowDefinitionRegistryImplTests extends TestCase { return null; } - public BeanFactory getBeanFactory() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Auto-generated method stub"); - } - - public ResourceLoader getResourceLoader() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Auto-generated method stub"); + public ApplicationContext getApplicationContext() { + return null; } } } \ No newline at end of file diff --git a/spring-webflow/src/test/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParserTests.java b/spring-webflow/src/test/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParserTests.java index e4949484..7f55bf3d 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParserTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParserTests.java @@ -4,9 +4,9 @@ import java.security.Principal; import junit.framework.TestCase; -import org.springframework.beans.factory.support.StaticListableBeanFactory; import org.springframework.binding.expression.Expression; import org.springframework.binding.expression.support.FluentParserContext; +import org.springframework.context.support.StaticApplicationContext; import org.springframework.webflow.TestBean; import org.springframework.webflow.action.FormAction; import org.springframework.webflow.core.collection.AttributeMap; @@ -33,7 +33,8 @@ public class WebFlowOgnlExpressionParserTests extends TestCase { LocalAttributeMap map = new LocalAttributeMap(); map.put("foo", "bar"); Expression exp = parser.parseExpression("foo", new FluentParserContext().evaluate(MutableAttributeMap.class)); - Expression exp2 = parser.parseExpression("bogus", new FluentParserContext().evaluate(MutableAttributeMap.class)); + Expression exp2 = parser + .parseExpression("bogus", new FluentParserContext().evaluate(MutableAttributeMap.class)); exp.setValue(map, "baz"); exp2.setValue(map, "new"); assertEquals("baz", exp.getValue(map)); @@ -50,7 +51,8 @@ public class WebFlowOgnlExpressionParserTests extends TestCase { public void testResolveCurrentUser() { MockRequestContext context = new MockRequestContext(); context.getMockExternalContext().setCurrentUser("Keith"); - Expression exp = parser.parseExpression("currentUser", new FluentParserContext().evaluate(RequestContext.class)); + Expression exp = parser + .parseExpression("currentUser", new FluentParserContext().evaluate(RequestContext.class)); assertEquals("Keith", ((Principal) exp.getValue(context)).getName()); } @@ -116,11 +118,11 @@ public class WebFlowOgnlExpressionParserTests extends TestCase { public void testResolveSpringBean() { MockRequestContext context = new MockRequestContext(); - StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); - beanFactory.addBean("testBean", new TestBean()); - beanFactory.addBean("action", new TestAction()); - beanFactory.addBean("multiAction", new FormAction(TestBean.class)); - context.getRootFlow().setBeanFactory(beanFactory); + StaticApplicationContext ac = new StaticApplicationContext(); + ac.getBeanFactory().registerSingleton("testBean", new TestBean()); + ac.getBeanFactory().registerSingleton("action", new TestAction()); + ac.getBeanFactory().registerSingleton("multiAction", new FormAction(TestBean.class)); + context.getRootFlow().setApplicationContext(ac); context.getConversationScope().put("foo", "bar"); Expression exp = parser.parseExpression("foo", new FluentParserContext().evaluate(RequestContext.class)); assertEquals("bar", exp.getValue(context)); @@ -128,22 +130,23 @@ public class WebFlowOgnlExpressionParserTests extends TestCase { public void testResolveAction() { MockRequestContext context = new MockRequestContext(); - StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); - beanFactory.addBean("action", new TestAction()); - context.getRootFlow().setBeanFactory(beanFactory); + StaticApplicationContext ac = new StaticApplicationContext(); + ac.getBeanFactory().registerSingleton("testBean", new TestBean()); + ac.getBeanFactory().registerSingleton("action", new TestAction()); + context.getRootFlow().setApplicationContext(ac); Expression exp = parser.parseExpression("action", new FluentParserContext().evaluate(RequestContext.class)); - assertSame(beanFactory.getBean("action"), exp.getValue(context)); + assertSame(ac.getBean("action"), exp.getValue(context)); } public void testResolveMultiAction() { MockRequestContext context = new MockRequestContext(); - StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); - beanFactory.addBean("multiAction", new FormAction()); - context.getRootFlow().setBeanFactory(beanFactory); + StaticApplicationContext ac = new StaticApplicationContext(); + ac.getBeanFactory().registerSingleton("multiAction", new FormAction()); + context.getRootFlow().setApplicationContext(ac); Expression exp = parser.parseExpression("multiAction.setupForm", new FluentParserContext() .evaluate(RequestContext.class)); AnnotatedAction action = (AnnotatedAction) exp.getValue(context); - assertSame(beanFactory.getBean("multiAction"), action.getTargetAction()); + assertSame(ac.getBean("multiAction"), action.getTargetAction()); assertEquals("setupForm", action.getMethod()); } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/expression/el/WebFlowELExpressionParserTests.java b/spring-webflow/src/test/java/org/springframework/webflow/expression/el/WebFlowELExpressionParserTests.java index 714b6646..5f6a66d7 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/expression/el/WebFlowELExpressionParserTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/expression/el/WebFlowELExpressionParserTests.java @@ -4,10 +4,10 @@ import java.security.Principal; import junit.framework.TestCase; -import org.springframework.beans.factory.support.StaticListableBeanFactory; import org.springframework.binding.expression.Expression; import org.springframework.binding.expression.el.DefaultExpressionFactoryUtils; import org.springframework.binding.expression.support.FluentParserContext; +import org.springframework.context.support.StaticApplicationContext; import org.springframework.webflow.TestBean; import org.springframework.webflow.action.FormAction; import org.springframework.webflow.core.collection.AttributeMap; @@ -35,7 +35,8 @@ public class WebFlowELExpressionParserTests extends TestCase { LocalAttributeMap map = new LocalAttributeMap(); map.put("foo", "bar"); Expression exp = parser.parseExpression("foo", new FluentParserContext().evaluate(MutableAttributeMap.class)); - Expression exp2 = parser.parseExpression("bogus", new FluentParserContext().evaluate(MutableAttributeMap.class)); + Expression exp2 = parser + .parseExpression("bogus", new FluentParserContext().evaluate(MutableAttributeMap.class)); exp.setValue(map, "baz"); exp2.setValue(map, "new"); assertEquals("baz", exp.getValue(map)); @@ -52,7 +53,8 @@ public class WebFlowELExpressionParserTests extends TestCase { public void testResolveCurrentUser() { MockRequestContext context = new MockRequestContext(); context.getMockExternalContext().setCurrentUser("Keith"); - Expression exp = parser.parseExpression("currentUser", new FluentParserContext().evaluate(RequestContext.class)); + Expression exp = parser + .parseExpression("currentUser", new FluentParserContext().evaluate(RequestContext.class)); assertEquals("Keith", ((Principal) exp.getValue(context)).getName()); } @@ -118,31 +120,31 @@ public class WebFlowELExpressionParserTests extends TestCase { public void testResolveSpringBean() { MockRequestContext context = new MockRequestContext(); - StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); - beanFactory.addBean("testBean", new TestBean()); - context.getRootFlow().setBeanFactory(beanFactory); + StaticApplicationContext ac = new StaticApplicationContext(); + ac.getBeanFactory().registerSingleton("testBean", new TestBean()); + context.getRootFlow().setApplicationContext(ac); Expression exp = parser.parseExpression("testBean", new FluentParserContext().evaluate(RequestContext.class)); - assertSame(beanFactory.getBean("testBean"), exp.getValue(context)); + assertSame(ac.getBean("testBean"), exp.getValue(context)); } public void testResolveAction() { MockRequestContext context = new MockRequestContext(); - StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); - beanFactory.addBean("action", new TestAction()); - context.getRootFlow().setBeanFactory(beanFactory); + StaticApplicationContext ac = new StaticApplicationContext(); + ac.getBeanFactory().registerSingleton("action", new TestAction()); + context.getRootFlow().setApplicationContext(ac); Expression exp = parser.parseExpression("action", new FluentParserContext().evaluate(RequestContext.class)); - assertSame(beanFactory.getBean("action"), exp.getValue(context)); + assertSame(ac.getBean("action"), exp.getValue(context)); } public void testResolveMultiAction() { MockRequestContext context = new MockRequestContext(); - StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); - beanFactory.addBean("multiAction", new FormAction()); - context.getRootFlow().setBeanFactory(beanFactory); + StaticApplicationContext ac = new StaticApplicationContext(); + ac.getBeanFactory().registerSingleton("multiAction", new FormAction()); + context.getRootFlow().setApplicationContext(ac); Expression exp = parser.parseExpression("multiAction.setupForm", new FluentParserContext() .evaluate(RequestContext.class)); AnnotatedAction action = (AnnotatedAction) exp.getValue(context); - assertSame(beanFactory.getBean("multiAction"), action.getTargetAction()); + assertSame(ac.getBean("multiAction"), action.getTargetAction()); assertEquals("setupForm", action.getMethod()); } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/PortletMvcViewTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/PortletMvcViewTests.java index fcca2ed0..a608d87d 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/PortletMvcViewTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/PortletMvcViewTests.java @@ -2,7 +2,6 @@ package org.springframework.webflow.mvc.portlet; import java.util.Date; import java.util.Locale; -import java.util.Map; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; @@ -12,31 +11,22 @@ import junit.framework.TestCase; import org.easymock.EasyMock; import org.springframework.binding.format.formatters.DateFormatter; import org.springframework.binding.format.registry.DefaultFormatterRegistry; -import org.springframework.context.ApplicationContext; import org.springframework.mock.web.portlet.MockPortletContext; import org.springframework.mock.web.portlet.MockRenderRequest; import org.springframework.mock.web.portlet.MockRenderResponse; import org.springframework.web.servlet.ViewRendererServlet; -import org.springframework.webflow.mvc.portlet.PortletMvcView; import org.springframework.webflow.mvc.view.MvcView; import org.springframework.webflow.test.MockFlowExecutionKey; import org.springframework.webflow.test.MockRequestContext; public class PortletMvcViewTests extends TestCase { - private boolean renderCalled; - - private Map model; - private DefaultFormatterRegistry formatterRegistry = new DefaultFormatterRegistry(); - private ApplicationContext applicationContext; - protected void setUp() { DateFormatter dateFormatter = new DateFormatter(); dateFormatter.setLocale(Locale.ENGLISH); formatterRegistry.registerFormatter(Date.class, dateFormatter); - applicationContext = (ApplicationContext) EasyMock.createMock(ApplicationContext.class); } public void testRender() throws Exception { @@ -49,10 +39,9 @@ public class PortletMvcViewTests extends TestCase { context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1")); org.springframework.web.servlet.View mvcView = (org.springframework.web.servlet.View) EasyMock .createMock(org.springframework.web.servlet.View.class); - MvcView view = new PortletMvcView(mvcView, context, applicationContext); + MvcView view = new PortletMvcView(mvcView, context); view.setFormatterRegistry(formatterRegistry); view.render(); - assertNotNull(request.getAttribute(ViewRendererServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE)); assertNotNull(request.getAttribute(ViewRendererServlet.VIEW_ATTRIBUTE)); assertNotNull(request.getAttribute(ViewRendererServlet.MODEL_ATTRIBUTE)); } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java index 58be78c0..ecf534aa 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java @@ -19,7 +19,6 @@ import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockServletContext; import org.springframework.validation.BindingResult; import org.springframework.web.servlet.View; -import org.springframework.webflow.context.ExternalContext; import org.springframework.webflow.execution.RequestContext; import org.springframework.webflow.test.MockFlowExecutionKey; import org.springframework.webflow.test.MockRequestContext; @@ -152,10 +151,9 @@ public class MvcViewTests extends TestCase { super(view, context); } - protected void doRender(org.springframework.web.servlet.View view, Map model, ExternalContext context) - throws Exception { - view.render(model, (HttpServletRequest) context.getNativeRequest(), (HttpServletResponse) context - .getNativeResponse()); + protected void doRender(Map model) throws Exception { + getView().render(model, (HttpServletRequest) getRequestContext().getExternalContext().getNativeRequest(), + (HttpServletResponse) getRequestContext().getExternalContext().getNativeResponse()); } }