diff --git a/spring-webflow/ivy.xml b/spring-webflow/ivy.xml
index 64ad8c16..c6a1f3ec 100644
--- a/spring-webflow/ivy.xml
+++ b/spring-webflow/ivy.xml
@@ -33,6 +33,8 @@
<enable-flow-scopes> tag.
+ * @author Ben Hale
+ */
+class EnableFlowScopesBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
+ protected Class getBeanClass(Element element) {
+ return ScopeRegistrar.class;
+ }
+
+ protected boolean shouldGenerateId() {
+ return true;
+ }
+}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/WebFlowConfigNamespaceHandler.java b/spring-webflow/src/main/java/org/springframework/webflow/config/WebFlowConfigNamespaceHandler.java
index b29f34ed..232118c8 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/config/WebFlowConfigNamespaceHandler.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/config/WebFlowConfigNamespaceHandler.java
@@ -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());
}
}
\ No newline at end of file
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/scope/AbstractWebFlowScope.java b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/AbstractWebFlowScope.java
new file mode 100644
index 00000000..8024e056
--- /dev/null
+++ b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/AbstractWebFlowScope.java
@@ -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 null 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 null
+ */
+ 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;
+ }
+}
\ No newline at end of file
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
new file mode 100644
index 00000000..37b5887e
--- /dev/null
+++ b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/ConversationScope.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;
+
+/**
+ * Conversation {@link Scope scope} implementation.
+ * @author Ben Hale
+ */
+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
new file mode 100644
index 00000000..96d4a052
--- /dev/null
+++ b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/FlashScope.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;
+
+/**
+ * Flash {@link Scope scope} implementation.
+ * @author Ben Hale
+ */
+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
new file mode 100644
index 00000000..6f67cba7
--- /dev/null
+++ b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/FlowScope.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;
+
+/**
+ * Flow {@link Scope scope} implementation.
+ * @author Ben Hale
+ */
+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
new file mode 100644
index 00000000..e8c15625
--- /dev/null
+++ b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/RequestScope.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;
+
+/**
+ * Request {@link Scope scope} implementation.
+ * @author Ben Hale
+ */
+class RequestScope extends AbstractWebFlowScope {
+ protected MutableAttributeMap getScope() {
+ return getRequiredRequestContext().getRequestScope();
+ }
+}
\ No newline at end of file
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/scope/ScopeRegistrar.java b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/ScopeRegistrar.java
new file mode 100644
index 00000000..7411eafb
--- /dev/null
+++ b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/ScopeRegistrar.java
@@ -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;
+ }
+
+}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/scope/package.html b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/package.html
new file mode 100644
index 00000000..dd51d58d
--- /dev/null
+++ b/spring-webflow/src/main/java/org/springframework/webflow/config/scope/package.html
@@ -0,0 +1,5 @@
+
+