scope support
This commit is contained in:
@@ -33,6 +33,8 @@
|
||||
<dependency org="org.springframework" name="spring-web" rev="2.5-rc1" />
|
||||
|
||||
<!-- testing support only dependencies -->
|
||||
<dependency org="aopalliance" name="aopalliance" rev="1.0" conf="test->default"/>
|
||||
<dependency org="org.springframework" name="spring-aop" rev="2.5-rc1" conf="test->default" />
|
||||
<dependency org="junit" name="junit" rev="3.8.2" conf="buildtime, testing->default" />
|
||||
|
||||
<!-- spring mvc only dependencies -->
|
||||
@@ -45,7 +47,7 @@
|
||||
<dependency org="struts" name="struts" rev="1.2.9" conf="buildtime, struts->default" />
|
||||
<dependency org="org.springframework" name="spring-webmvc-struts" rev="2.5-rc1" conf="buildtime, struts->default" />
|
||||
|
||||
<!-- build time only dependencies -->
|
||||
<!-- build time only dependencies -->
|
||||
<dependency org="javax.servlet" name="servlet-api" rev="2.4" conf="buildtime->default" />
|
||||
<dependency org="javax.portlet" name="portlet-api" rev="1.0" conf="buildtime->default" />
|
||||
<dependency org="javax.el" name="el-api" rev="1.0" conf="buildtime->default" />
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.webflow.config.scope.ScopeRegistrar;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* {@link BeanDefinitionParser} for the <code><enable-flow-scopes></code> tag.
|
||||
* @author Ben Hale
|
||||
*/
|
||||
class EnableFlowScopesBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
|
||||
protected Class getBeanClass(Element element) {
|
||||
return ScopeRegistrar.class;
|
||||
}
|
||||
|
||||
protected boolean shouldGenerateId() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -28,5 +28,6 @@ public class WebFlowConfigNamespaceHandler extends NamespaceHandlerSupport {
|
||||
registerBeanDefinitionParser("flow-executor", new FlowExecutorBeanDefinitionParser());
|
||||
registerBeanDefinitionParser("flow-execution-listeners", new FlowExecutionListenerLoaderBeanDefinitionParser());
|
||||
registerBeanDefinitionParser("flow-registry", new FlowRegistryBeanDefinitionParser());
|
||||
registerBeanDefinitionParser("enable-flow-scopes", new EnableFlowScopesBeanDefinitionParser());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package org.springframework.webflow.config.scope;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.config.Scope;
|
||||
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
/**
|
||||
* Base class for {@link Scope} implementations that access a Web Flow scope from the current request.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public abstract class AbstractWebFlowScope implements Scope {
|
||||
|
||||
/**
|
||||
* Logger, usable by subclasses.
|
||||
*/
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
public Object get(String name, ObjectFactory objectFactory) {
|
||||
MutableAttributeMap scope = getScope();
|
||||
Object scopedObject = scope.get(name);
|
||||
if (scopedObject == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("No scoped instance '" + name + "' found; creating new instance");
|
||||
}
|
||||
scopedObject = objectFactory.getObject();
|
||||
scope.put(name, scopedObject);
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Returning scoped instance '" + name + "'");
|
||||
}
|
||||
}
|
||||
return scopedObject;
|
||||
}
|
||||
|
||||
public Object remove(String name) {
|
||||
return getScope().remove(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Template method that returns the target scope map.
|
||||
* @throws IllegalStateException if the scope could not be accessed
|
||||
*/
|
||||
protected abstract MutableAttributeMap getScope() throws IllegalStateException;
|
||||
|
||||
/**
|
||||
* Always returns <code>null</code> as most Spring Web Flow scopes do not have obvious conversation ids.
|
||||
* Subclasses should override this method where conversation ids can be intelligently returned.
|
||||
* @return always returns <code>null</code>
|
||||
*/
|
||||
public String getConversationId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will not register a destruction callback as Spring Web Flow does not support destruction of scoped beans.
|
||||
* Subclasses should override this method where where destruction can adequately be accomplished.
|
||||
* @param name the name of the bean to register the callback for
|
||||
* @param callback the callback to execute
|
||||
*/
|
||||
public void registerDestructionCallback(String name, Runnable callback) {
|
||||
logger.warn("Destruction callback for '" + name + "' was not registered. Spring Web Flow does not "
|
||||
+ "support destruction of scoped beans.");
|
||||
}
|
||||
|
||||
protected RequestContext getRequiredRequestContext() {
|
||||
RequestContext context = RequestContextHolder.getRequestContext();
|
||||
if (context == null) {
|
||||
throw new IllegalStateException(
|
||||
"No request context bound to this thread; to access flow-scoped beans you must be running in a flow execution request");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* Conversation {@link Scope scope} implementation.
|
||||
* @author Ben Hale
|
||||
*/
|
||||
class ConversationScope extends AbstractWebFlowScope {
|
||||
protected MutableAttributeMap getScope() {
|
||||
return getRequiredRequestContext().getConversationScope();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* Flash {@link Scope scope} implementation.
|
||||
* @author Ben Hale
|
||||
*/
|
||||
class FlashScope extends AbstractWebFlowScope {
|
||||
protected MutableAttributeMap getScope() {
|
||||
return getRequiredRequestContext().getFlashScope();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* Flow {@link Scope scope} implementation.
|
||||
* @author Ben Hale
|
||||
*/
|
||||
class FlowScope extends AbstractWebFlowScope {
|
||||
protected MutableAttributeMap getScope() {
|
||||
return getRequiredRequestContext().getFlowScope();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* Request {@link Scope scope} implementation.
|
||||
* @author Ben Hale
|
||||
*/
|
||||
class RequestScope extends AbstractWebFlowScope {
|
||||
protected MutableAttributeMap getScope() {
|
||||
return getRequiredRequestContext().getRequestScope();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.Scope;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.webflow.execution.ScopeType;
|
||||
|
||||
/**
|
||||
* Registers the Spring Web Flow bean scopes with a
|
||||
* @{link ConfigurableListableBeanFactory}.
|
||||
*
|
||||
* @author Ben Hale
|
||||
* @see Scope
|
||||
*/
|
||||
public class ScopeRegistrar implements BeanFactoryPostProcessor, Ordered {
|
||||
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
beanFactory.registerScope(ScopeType.REQUEST.getLabel().toLowerCase(), new RequestScope());
|
||||
beanFactory.registerScope(ScopeType.FLASH.getLabel().toLowerCase(), new FlashScope());
|
||||
beanFactory.registerScope(ScopeType.FLOW.getLabel().toLowerCase(), new FlowScope());
|
||||
beanFactory.registerScope(ScopeType.CONVERSATION.getLabel().toLowerCase(), new ConversationScope());
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Support code to allow access to the Spring Web Flow scopes (request, flash, flow conversation) from a Spring ApplicationContext.
|
||||
</body>
|
||||
</html>
|
||||
@@ -208,6 +208,16 @@ The idref to the registry this executor will use to locate flow definitions for
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="enable-flow-scopes">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Allows access to the Spring Web Flow scopes (request, flash, flow, conversation) from a Spring ApplicationContext.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="flowExecutionRepositoryType">
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.springframework.webflow.config;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.execution.FlowExecutionListenerAdapter;
|
||||
import org.springframework.webflow.execution.FlowSession;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.executor.FlowExecutor;
|
||||
import org.springframework.webflow.test.MockExternalContext;
|
||||
|
||||
public class EnableScopesBeanDefinitionParserTests extends TestCase {
|
||||
|
||||
private ClassPathXmlApplicationContext context;
|
||||
|
||||
private FlowExecutor executor;
|
||||
|
||||
public void setUp() {
|
||||
context = new ClassPathXmlApplicationContext("org/springframework/webflow/config/enable-flow-scopes.xml");
|
||||
executor = (FlowExecutor) context.getBean("flowExecutor");
|
||||
}
|
||||
|
||||
public void testExecute() {
|
||||
MockExternalContext context = new MockExternalContext();
|
||||
context.setFlowId("flow");
|
||||
executor.execute(context);
|
||||
}
|
||||
|
||||
public static class ConfigurationListener extends FlowExecutionListenerAdapter {
|
||||
public void sessionEnded(RequestContext context, FlowSession session, AttributeMap output) {
|
||||
assertNotNull(session.getScope().get("user"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.springframework.webflow.config;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class EnableScopesService {
|
||||
private EnableScopesUser user;
|
||||
|
||||
public void setUser(EnableScopesUser user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public void execute() {
|
||||
Assert.isTrue("foo".equals(user.getName()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.springframework.webflow.config;
|
||||
|
||||
public class EnableScopesUser {
|
||||
private String name = "foo";
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<flow xmlns="http://www.springframework.org/schema/webflow"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/webflow
|
||||
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
|
||||
|
||||
<start-state idref="end"/>
|
||||
|
||||
<end-state id="end">
|
||||
<entry-actions>
|
||||
<bean-action bean="service" method="execute"/>
|
||||
</entry-actions>
|
||||
</end-state>
|
||||
|
||||
</flow>
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:web="http://www.springframework.org/schema/webflow-config"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/aop
|
||||
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
|
||||
http://www.springframework.org/schema/webflow-config
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">
|
||||
|
||||
<web:enable-flow-scopes/>
|
||||
|
||||
<web:flow-executor id="flowExecutor" flow-registry="flowRegistry">
|
||||
<web:flow-execution-repository type="continuation" max-conversations="1" max-continuations="2"/>
|
||||
<web:flow-execution-attributes>
|
||||
<web:alwaysRedirectOnPause value="false"/>
|
||||
<web:attribute name="foo" value="bar"/>
|
||||
<web:attribute name="bar" value="2" type="integer"/>
|
||||
</web:flow-execution-attributes>
|
||||
<web:flow-execution-listeners>
|
||||
<web:listener ref="listener" criteria="*"/>
|
||||
</web:flow-execution-listeners>
|
||||
</web:flow-executor>
|
||||
|
||||
<bean id="listener" class="org.springframework.webflow.config.EnableScopesBeanDefinitionParserTests$ConfigurationListener" />
|
||||
|
||||
<web:flow-registry id="flowRegistry">
|
||||
<web:flow-location path="org/springframework/webflow/config/enable-flow-scopes-flowdef.xml" />
|
||||
</web:flow-registry>
|
||||
|
||||
<bean id="user" class="org.springframework.webflow.config.EnableScopesUser" scope="flow">
|
||||
<aop:scoped-proxy/>
|
||||
</bean>
|
||||
|
||||
<bean id="service" class="org.springframework.webflow.config.EnableScopesService">
|
||||
<property name="user" ref="user"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
Reference in New Issue
Block a user