1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.springframework.batch.core.configuration.xml;
17
18 import java.util.Collection;
19 import java.util.List;
20
21 import org.springframework.beans.MutablePropertyValues;
22 import org.springframework.beans.factory.config.BeanDefinition;
23 import org.springframework.beans.factory.config.RuntimeBeanReference;
24 import org.springframework.beans.factory.support.AbstractBeanDefinition;
25 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
26 import org.springframework.beans.factory.support.GenericBeanDefinition;
27 import org.springframework.beans.factory.support.ManagedList;
28 import org.springframework.beans.factory.xml.ParserContext;
29 import org.springframework.core.task.TaskExecutor;
30 import org.springframework.util.StringUtils;
31 import org.springframework.util.xml.DomUtils;
32 import org.w3c.dom.Element;
33
34
35
36
37
38
39
40
41
42
43
44
45 public class SplitParser {
46
47
48
49
50 private static final String PARENT_ATTR = "parent";
51
52 private final String jobFactoryRef;
53
54
55
56
57
58
59
60
61 public SplitParser(String jobFactoryRef) {
62 this.jobFactoryRef = jobFactoryRef;
63 }
64
65
66
67
68
69
70
71
72
73
74 public Collection<BeanDefinition> parse(Element element, ParserContext parserContext) {
75
76 String idAttribute = element.getAttribute("id");
77
78 BeanDefinitionBuilder stateBuilder = BeanDefinitionBuilder
79 .genericBeanDefinition("org.springframework.batch.core.job.flow.support.state.SplitState");
80
81 String taskExecutorBeanId = element.getAttribute("task-executor");
82 if (StringUtils.hasText(taskExecutorBeanId)) {
83 RuntimeBeanReference taskExecutorRef = new RuntimeBeanReference(taskExecutorBeanId);
84 stateBuilder.addPropertyValue("taskExecutor", taskExecutorRef);
85 }
86
87 @SuppressWarnings("unchecked")
88 List<Element> flowElements = DomUtils.getChildElementsByTagName(element, "flow");
89
90 if (flowElements.size() < 2) {
91 parserContext.getReaderContext().error("A <split/> must contain at least two 'flow' elements.", element);
92 }
93
94 @SuppressWarnings("unchecked")
95 Collection<Object> flows = new ManagedList();
96 int i = 0;
97 String prefix = idAttribute;
98 for (Element nextElement : flowElements) {
99 String ref = nextElement.getAttribute(PARENT_ATTR);
100 if (StringUtils.hasText(ref)) {
101 if (nextElement.getElementsByTagName("*").getLength() > 0) {
102 parserContext.getReaderContext().error(
103 "A <flow/> in a <split/> must have ref= or nested <flow/>, but not both.", nextElement);
104 }
105 AbstractBeanDefinition flowDefinition = new GenericBeanDefinition();
106 flowDefinition.setParentName(ref);
107 MutablePropertyValues propertyValues = flowDefinition.getPropertyValues();
108 propertyValues.addPropertyValue("name", prefix + "." + i);
109 flows.add(flowDefinition);
110 }
111 else {
112 InlineFlowParser flowParser = new InlineFlowParser(prefix + "." + i, jobFactoryRef);
113 flows.add(flowParser.parse(nextElement, parserContext));
114 }
115 i++;
116 }
117
118 stateBuilder.addConstructorArgValue(flows);
119 stateBuilder.addConstructorArgValue(prefix);
120
121 return InlineFlowParser.getNextElements(parserContext, stateBuilder.getBeanDefinition(), element);
122
123 }
124
125 }