flow location pattern element for wildcard paths

This commit is contained in:
Keith Donald
2008-04-13 04:38:14 +00:00
parent 8ebf7c1c09
commit 76aa1aeab0
8 changed files with 102 additions and 11 deletions

View File

@@ -43,6 +43,8 @@ class FlowRegistryBeanDefinitionParser extends AbstractSingleBeanDefinitionParse
private static final String FLOW_LOCATION_ELEMENT = "flow-location";
private static final String FLOW_LOCATION_PATTERN_ELEMENT = "flow-location-pattern";
private static final String FLOW_BUILDER_ELEMENT = "flow-builder";
private static final String ID_ATTRIBUTE = "id";
@@ -63,6 +65,8 @@ class FlowRegistryBeanDefinitionParser extends AbstractSingleBeanDefinitionParse
private static final String FLOW_LOCATIONS_PROPERTY = "flowLocations";
private static final String FLOW_LOCATION_PATTERNS_PROPERTY = "flowLocationPatterns";
private static final String FLOW_BUILDERS_PROPERTY = "flowBuilders";
private static final String FLOW_BUILDER_SERVICES_PROPERTY = "flowBuilderServices";
@@ -87,6 +91,7 @@ class FlowRegistryBeanDefinitionParser extends AbstractSingleBeanDefinitionParse
definitionBuilder.addPropertyReference(PARENT_PROPERTY, parent);
}
definitionBuilder.addPropertyValue(FLOW_LOCATIONS_PROPERTY, parseLocations(element));
definitionBuilder.addPropertyValue(FLOW_LOCATION_PATTERNS_PROPERTY, parseLocationPatterns(element));
definitionBuilder.addPropertyValue(FLOW_BUILDERS_PROPERTY, parseFlowBuilders(element));
}
@@ -105,6 +110,20 @@ class FlowRegistryBeanDefinitionParser extends AbstractSingleBeanDefinitionParse
return locations;
}
private List parseLocationPatterns(Element element) {
List locationPatternElements = DomUtils.getChildElementsByTagName(element, FLOW_LOCATION_PATTERN_ELEMENT);
if (locationPatternElements.isEmpty()) {
return Collections.EMPTY_LIST;
}
List locationPatterns = new ArrayList(locationPatternElements.size());
for (Iterator it = locationPatternElements.iterator(); it.hasNext();) {
Element locationPatternElement = (Element) it.next();
String value = locationPatternElement.getAttribute(VALUE_ATTRIBUTE);
locationPatterns.add(value);
}
return locationPatterns;
}
private Set parseAttributes(Element element) {
Element definitionAttributesElement = DomUtils.getChildElementByTagName(element, DEFINITION_ATTRIBUTES_ELEMENT);
if (definitionAttributesElement != null) {

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.webflow.config;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
@@ -56,6 +57,8 @@ class FlowRegistryFactoryBean implements FactoryBean, InitializingBean {
private FlowLocation[] flowLocations;
private String[] flowLocationPatterns;
private FlowBuilderInfo[] flowBuilders;
private FlowBuilderServices flowBuilderServices;
@@ -85,6 +88,13 @@ class FlowRegistryFactoryBean implements FactoryBean, InitializingBean {
this.flowLocations = flowLocations;
}
/**
* Resolvable path patterns to flows to register in the registry produced by this factory bean.
*/
public void setFlowLocationPatterns(String[] flowLocationPatterns) {
this.flowLocationPatterns = flowLocationPatterns;
}
/**
* Java {@link FlowBuilder flow builder} classes that should be registered in the registry produced by this factory
* bean.
@@ -113,6 +123,7 @@ class FlowRegistryFactoryBean implements FactoryBean, InitializingBean {
flowRegistry.setParent(parent);
flowModelRegistry = new FlowModelRegistryImpl();
registerFlowLocations();
registerFlowLocationPatterns();
registerFlowBuilders();
}
@@ -132,7 +143,27 @@ class FlowRegistryFactoryBean implements FactoryBean, InitializingBean {
if (flowLocations != null) {
for (int i = 0; i < flowLocations.length; i++) {
FlowLocation location = flowLocations[i];
flowRegistry.registerFlowDefinition(createFlowDefinitionHolder(location));
flowRegistry.registerFlowDefinition(createFlowDefinitionHolder(createResource(location)));
}
}
}
private void registerFlowLocationPatterns() {
if (flowLocationPatterns != null) {
for (int i = 0; i < flowLocationPatterns.length; i++) {
String pattern = flowLocationPatterns[i];
FlowDefinitionResource[] resources;
try {
resources = flowResourceFactory.createResources(pattern);
} catch (IOException e) {
IllegalStateException ise = new IllegalStateException(
"An I/O Exception occurred resolving the flow location pattern '" + pattern + "'");
ise.initCause(e);
throw ise;
}
for (int j = 0; j < resources.length; j++) {
flowRegistry.registerFlowDefinition(createFlowDefinitionHolder(resources[j]));
}
}
}
}
@@ -146,8 +177,7 @@ class FlowRegistryFactoryBean implements FactoryBean, InitializingBean {
}
}
private FlowDefinitionHolder createFlowDefinitionHolder(FlowLocation location) {
FlowDefinitionResource flowResource = createResource(location);
private FlowDefinitionHolder createFlowDefinitionHolder(FlowDefinitionResource flowResource) {
FlowBuilder builder = createFlowBuilder(flowResource);
FlowBuilderContext builderContext = new FlowBuilderContextImpl(flowResource.getId(), flowResource
.getAttributes(), flowRegistry, flowBuilderServices);

View File

@@ -36,26 +36,46 @@ would index those definitions by "orderitem-flow" and "shipping-flow" by default
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:sequence>
<xsd:element name="flow-location" type="flowLocationType" minOccurs="0" maxOccurs="unbounded">
<xsd:choice maxOccurs="unbounded">
<xsd:element name="flow-location" type="flowLocationType">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
Registers a flow defined in an external resource such as a .xml file in this registry.
Registers a flow defined at an external resource such as a .xml file.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="flow-builder" type="flowBuilderType" minOccurs="0" maxOccurs="unbounded">
<xsd:element name="flow-location-pattern">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
Registers a custom FlowBuilder implementation in this registry.
Registers a set of flows resolved from a resource location pattern (e.g. /WEB-INF/flows/**/*-flow.xml).
]]>
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="value" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
The location pattern to resolve (e.g. /WEB-INF/flows/**/*-flow.xml)
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="flow-builder" type="flowBuilderType">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
Registers a custom FlowBuilder implementation.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:choice>
<xsd:attribute name="flow-builder-services" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
@@ -379,7 +399,7 @@ Example: 'flow1,flow2,flow3'.
<xsd:complexType name="flowExecutionAttributesType">
<xsd:sequence>
<xsd:element name="always-redirect-on-pause" type="alwaysRedirectOnPauseType" minOccurs="0">
<xsd:element name="always-redirect-on-pause" type="alwaysRedirectOnPauseType" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
<![CDATA[

View File

@@ -24,6 +24,13 @@ public class FlowRegistryBeanDefinitionParserTests extends TestCase {
assertEquals(new Integer(2), flow.getAttributes().get("bar"));
}
public void testRegistryFlowLocationPatternsPopulated() {
FlowDefinition flow1 = registry.getFlowDefinition("flow1");
assertEquals("flow1", flow1.getId());
FlowDefinition flow2 = registry.getFlowDefinition("flow2");
assertEquals("flow2", flow2.getId());
}
public void testRegistryFlowBuildersPopulated() {
FlowDefinition foo = registry.getFlowDefinition("foo");
assertEquals("foo", foo.getId());

View File

@@ -13,7 +13,7 @@
<webflow:flow-execution-attributes>
<webflow:always-redirect-on-pause value="false"/>
<webflow:attribute name="foo" value="bar"/>
<webflow:attribute name="bar" value="2" type="integer"/>
<webflow:attribute name="bar" value="2" type="integer"/>
</webflow:flow-execution-attributes>
<webflow:flow-execution-listeners>
<webflow:listener ref="listener" criteria="*"/>

View File

@@ -16,6 +16,7 @@
</webflow:flow-definition-attributes>
</webflow:flow-location>
<webflow:flow-location path="/some/path/that/is/bogus.xml" />
<webflow:flow-location-pattern value="org/springframework/webflow/config/flows/*.xml"/>
<webflow:flow-builder class="org.springframework.webflow.config.FooFlowBuilder" />
<webflow:flow-builder id="foo2" class="org.springframework.webflow.config.FooFlowBuilder" />
<webflow:flow-builder id="foo3" class="org.springframework.webflow.config.FooFlowBuilder">

View File

@@ -0,0 +1,7 @@
<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">
<end-state id="end"/>
</flow>

View File

@@ -0,0 +1,7 @@
<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">
<end-state id="end"/>
</flow>