/*
* Copyright 2004-2012 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 java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
/**
* {@link BeanDefinitionParser} for the <code><flow-executor></code> tag.
*
* @author Keith Donald
*/
class FlowExecutorBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
private static final String FLOW_EXECUTOR_FACTORY_BEAN_CLASS_NAME = "org.springframework.webflow.config.FlowExecutorFactoryBean";
protected String getBeanClassName(Element element) {
return FLOW_EXECUTOR_FACTORY_BEAN_CLASS_NAME;
}
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder definitionBuilder) {
definitionBuilder.addPropertyReference("flowDefinitionLocator", getFlowRegistry(element, parserContext));
addFlowExecutionRepositoryProperties(element, definitionBuilder, parserContext);
definitionBuilder.addPropertyValue("flowExecutionAttributes", parseFlowExecutionAttributes(element));
addFlowExecutionListenerLoader(element, parserContext, definitionBuilder);
}
private String getFlowRegistry(Element element, ParserContext parserContext) {
String registry = element.getAttribute("flow-registry");
if (!StringUtils.hasText(registry)) {
return "flowRegistry";
} else {
return registry;
}
}
private void addFlowExecutionRepositoryProperties(Element element, BeanDefinitionBuilder definitionBuilder,
ParserContext parserContext) {
Element repositoryElement = DomUtils.getChildElementByTagName(element, "flow-execution-repository");
if (repositoryElement != null) {
addMaxExecutions(repositoryElement, definitionBuilder, parserContext);
addConversationManager(repositoryElement, definitionBuilder, parserContext);
addMaxSnapshots(repositoryElement, definitionBuilder, parserContext);
}
}
private void addMaxExecutions(Element element, BeanDefinitionBuilder definitionBuilder, ParserContext parserContext) {
String maxConversations = element.getAttribute("max-executions");
if (StringUtils.hasText(maxConversations)) {
definitionBuilder.addPropertyValue("maxFlowExecutions", maxConversations);
}
}
private void addConversationManager(Element element, BeanDefinitionBuilder definitionBuilder,
ParserContext parserContext) {
String conversationManager = element.getAttribute("conversation-manager");
if (StringUtils.hasText(conversationManager)) {
definitionBuilder.addPropertyReference("conversationManager", conversationManager);
}
}
private void addMaxSnapshots(Element element, BeanDefinitionBuilder definitionBuilder, ParserContext parserContext) {
String maxSnapshots = element.getAttribute("max-execution-snapshots");
if (StringUtils.hasText(maxSnapshots)) {
definitionBuilder.addPropertyValue("maxFlowExecutionSnapshots", maxSnapshots);
}
}
private Set<Object> parseFlowExecutionAttributes(Element element) {
Element executionAttributesElement = DomUtils.getChildElementByTagName(element, "flow-execution-attributes");
if (executionAttributesElement != null) {
HashSet<Object> attributes = new HashSet<Object>();
Element redirectElement = DomUtils.getChildElementByTagName(executionAttributesElement,
"always-redirect-on-pause");
if (redirectElement != null) {
String value = redirectElement.getAttribute("value");
attributes.add(new FlowElementAttribute("alwaysRedirectOnPause", value, "boolean"));
}
Element redirectInSameStateElement = DomUtils.getChildElementByTagName(executionAttributesElement,
"redirect-in-same-state");
if (redirectInSameStateElement != null) {
String value = redirectInSameStateElement.getAttribute("value");
attributes.add(new FlowElementAttribute("redirectInSameState", value, "boolean"));
}
List<Element> attributeElements = DomUtils.getChildElementsByTagName(executionAttributesElement,
"attribute");
for (Element attributeElement : attributeElements) {
String name = attributeElement.getAttribute("name");
String value = attributeElement.getAttribute("value");
String type = attributeElement.getAttribute("type");
attributes.add(new FlowElementAttribute(name, value, type));
}
return attributes;
} else {
return null;
}
}
private void addFlowExecutionListenerLoader(Element element, ParserContext parserContext,
BeanDefinitionBuilder definitionBuilder) {
Element listenersElement = DomUtils.getChildElementByTagName(element, "flow-execution-listeners");
if (listenersElement != null) {
definitionBuilder.addPropertyValue("flowExecutionListenerLoader", parserContext.getDelegate()
.parseCustomElement(listenersElement, definitionBuilder.getBeanDefinition()));
}
}
}