1 | /* |
2 | * Copyright 2006-2008 the original author or authors. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | package org.springframework.batch.core.configuration.xml; |
17 | |
18 | import java.util.ArrayList; |
19 | import java.util.Collection; |
20 | import java.util.List; |
21 | |
22 | import org.springframework.beans.factory.config.BeanDefinition; |
23 | import org.springframework.beans.factory.config.RuntimeBeanReference; |
24 | import org.springframework.beans.factory.support.BeanDefinitionBuilder; |
25 | import org.springframework.beans.factory.support.ManagedList; |
26 | import org.springframework.beans.factory.xml.ParserContext; |
27 | import org.springframework.util.StringUtils; |
28 | import org.springframework.util.xml.DomUtils; |
29 | import org.w3c.dom.Element; |
30 | |
31 | /** |
32 | * Internal parser for the <split/> elements inside a job. A split element |
33 | * references a bean definition for a |
34 | * {@link org.springframework.batch.core.job.flow.JobExecutionDecider} and goes |
35 | * on to list a set of transitions to other states with <next on="pattern" |
36 | * to="stepName"/>. Used by the {@link JobParser}. |
37 | * |
38 | * @see JobParser |
39 | * |
40 | * @author Dave Syer |
41 | * |
42 | */ |
43 | public class SplitParser { |
44 | |
45 | private final String jobFactoryRef; |
46 | |
47 | /** |
48 | * Construct a {@link FlowParser} using the provided job repository ref. |
49 | * |
50 | * @param jobFactoryRef the reference to the {@link JobParserJobFactoryBean} |
51 | * from the enclosing tag |
52 | */ |
53 | public SplitParser(String jobFactoryRef) { |
54 | this.jobFactoryRef = jobFactoryRef; |
55 | } |
56 | |
57 | /** |
58 | * Parse the split and turn it into a list of transitions. |
59 | * |
60 | * @param element the <split/gt; element to parse |
61 | * @param parserContext the parser context for the bean factory |
62 | * @return a collection of bean definitions for |
63 | * {@link org.springframework.batch.core.job.flow.support.StateTransition} |
64 | * instances objects |
65 | */ |
66 | public Collection<BeanDefinition> parse(Element element, ParserContext parserContext) { |
67 | |
68 | String idAttribute = element.getAttribute("id"); |
69 | |
70 | BeanDefinitionBuilder stateBuilder = BeanDefinitionBuilder |
71 | .genericBeanDefinition("org.springframework.batch.core.job.flow.support.state.SplitState"); |
72 | |
73 | String taskExecutorBeanId = element.getAttribute("task-executor"); |
74 | if (StringUtils.hasText(taskExecutorBeanId)) { |
75 | RuntimeBeanReference taskExecutorRef = new RuntimeBeanReference(taskExecutorBeanId); |
76 | stateBuilder.addPropertyValue("taskExecutor", taskExecutorRef); |
77 | } |
78 | |
79 | @SuppressWarnings("unchecked") |
80 | List<Element> flowElements = (List<Element>) DomUtils.getChildElementsByTagName(element, "flow"); |
81 | |
82 | if (flowElements.size() < 2) { |
83 | parserContext.getReaderContext().error("A <split/> must contain at least two 'flow' elements.", element); |
84 | } |
85 | |
86 | Collection<BeanDefinition> flows = new ArrayList<BeanDefinition>(); |
87 | int i = 0; |
88 | for (Element nextElement : flowElements) { |
89 | FlowParser flowParser = new FlowParser(idAttribute + "#" + i, jobFactoryRef); |
90 | flows.add(flowParser.parse(nextElement, parserContext)); |
91 | i++; |
92 | } |
93 | ManagedList managedList = new ManagedList(); |
94 | @SuppressWarnings( { "unchecked", "unused" }) |
95 | boolean dummy = managedList.addAll(flows); |
96 | |
97 | stateBuilder.addConstructorArgValue(managedList); |
98 | stateBuilder.addConstructorArgValue(idAttribute); |
99 | |
100 | return FlowParser.getNextElements(parserContext, stateBuilder.getBeanDefinition(), element); |
101 | |
102 | } |
103 | |
104 | } |