org.springframework.webflow.engine.builder.xml.XmlFlowRegistryFactoryBean Maven / Gradle / Ivy
/*
* Copyright 2002-2006 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.engine.builder.xml;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.springframework.core.io.Resource;
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
import org.springframework.webflow.definition.registry.FlowDefinitionResource;
import org.springframework.webflow.engine.builder.AbstractFlowBuildingFlowRegistryFactoryBean;
import org.springframework.webflow.engine.builder.DefaultFlowServiceLocator;
import org.springframework.webflow.engine.builder.FlowServiceLocator;
/**
* A factory bean that produces a populated flow registry using a
* {@link XmlFlowRegistrar}. This is the simplest implementation to use when
* using a Spring BeanFactory to deploy an explicit registry of XML-based Flow
* definitions for execution.
*
* By default, a configured flow definition will be assigned a registry
* identifier equal to the filename of the underlying definition resource, minus
* the filename extension. For example, a XML-based flow definition defined in
* the file flow1.xml
will be identified as flow1
* in the registry created by this factory bean.
*
* This class is also BeanFactoryAware
and when used with Spring
* will automatically create a configured {@link DefaultFlowServiceLocator} for
* loading Flow artifacts like Actions from the Spring bean factory during the
* Flow registration process.
*
* This class is also ResourceLoaderAware
; when an instance is
* created by a Spring BeanFactory the factory will automatically configure the
* XmlFlowRegistrar with a context-relative resource loader for accessing other
* resources during Flow assembly.
*
* Usage example:
*
*
* <bean id="flowRegistry" class="org.springframework.webflow.engine.builder.registry.XmlFlowRegistryFactoryBean">
* <property name="flowLocations"> value="/WEB-INF/flows/*-flow.xml"/>
* </bean>
*
*
* @author Keith Donald
*/
public class XmlFlowRegistryFactoryBean extends AbstractFlowBuildingFlowRegistryFactoryBean {
/**
* The flow registrar that will perform the definition registrations.
*/
private XmlFlowRegistrar flowRegistrar = new XmlFlowRegistrar();
/**
* Temporary holder for flow definitions configured using a property map.
*/
private Properties flowDefinitions;
/**
* Returns the configured externalized XML flow registrar.
*/
protected XmlFlowRegistrar getXmlFlowRegistrar() {
return flowRegistrar;
}
/**
* Sets the locations (resource file paths) pointing to XML-based flow
* definitions.
*
* When configuring as a Spring bean definition, ANT-style resource
* patterns/wildcards are also supported, taking advantage of Spring's built
* in ResourceArrayPropertyEditor machinery.
*
* For example:
*
*
* <bean id="flowRegistry" class="org.springframework.webflow.engine.builder.xml.XmlFlowRegistryFactoryBean">
* <property name="flowLocations"> value="/WEB-INF/flows/*-flow.xml"/>
* </bean>
*
*
* Another example:
*
*
* <bean id="flowRegistry" class="org.springframework.webflow.engine.builder.xml.XmlFlowRegistryFactoryBean">
* <property name="flowLocations"> value="classpath*:/example/flows/*-flow.xml"/>
* </bean>
*
*
* Flows registered from this set will be automatically assigned an id based
* on the filename of the matched XML resource.
* @param locations the resource locations
*/
public void setFlowLocations(Resource[] locations) {
getXmlFlowRegistrar().setLocations(locations);
}
/**
* Convenience method for setting externalized flow definitions
* from a java.util.Properties
map. Allows for more control
* over the definition, including which flowId
is assigned.
*
* Each property key is the flowId
and each property value is
* the string encoded location of the externalized flow definition resource.
*
* Here is the exact format:
*
*
* flow id=resource
*
*
* For example:
*
*
* <bean id="flowRegistry" class="org.springframework.webflow.engine.builder.xml.XmlFlowRegistryFactoryBean">
* <property name="flowDefinitions">
* <value>
* searchFlow=/WEB-INF/flows/search-flow.xml
* detailFlow=/WEB-INF/flows/detail-flow.xml
* </value>
* </property>
* </bean>
*
* @param flowDefinitions the flow definitions, defined within a properties
* map
*/
public void setFlowDefinitions(Properties flowDefinitions) {
this.flowDefinitions = flowDefinitions;
}
/**
* Sets the loader to load XML-based flow definition documents during flow
* definition assembly. Allows for customization over how flow definition
* documents are loaded. Optional.
* @param documentLoader the document loader
*/
public void setDocumentLoader(DocumentLoader documentLoader) {
getXmlFlowRegistrar().setDocumentLoader(documentLoader);
}
protected void init(FlowServiceLocator flowServiceLocator) {
// simply wire in the locator to the registrar
flowRegistrar.setFlowServiceLocator(flowServiceLocator);
}
protected void doPopulate(FlowDefinitionRegistry registry) {
addFlowDefinitionsFromProperties();
getXmlFlowRegistrar().registerFlowDefinitions(registry);
}
/**
* Add flow definitions configured using a property map to
* the flow definition registrar.
*/
private void addFlowDefinitionsFromProperties() {
if (flowDefinitions != null && flowDefinitions.size() > 0) {
List flows = new ArrayList(flowDefinitions.size());
Iterator it = flowDefinitions.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String flowId = (String)entry.getKey();
String location = (String)entry.getValue();
Resource resource = getFlowServiceLocator().getResourceLoader().getResource(location);
flows.add(new FlowDefinitionResource(flowId, resource));
}
getXmlFlowRegistrar().addResources(
(FlowDefinitionResource[])flows.toArray(new FlowDefinitionResource[flows.size()]));
// cleanup
flowDefinitions = null;
}
}
}