Skip to content

Commit 315f08a

Browse files
author
nebhale
committed
[BATCH-63] Added <job/> tag parsing
1 parent 7841e0b commit 315f08a

File tree

2 files changed

+52
-38
lines changed

2 files changed

+52
-38
lines changed

spring-batch-execution/src/main/java/org/springframework/batch/execution/configuration/ConfigBeanDefinitionParser.java

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@
1616

1717
package org.springframework.batch.execution.configuration;
1818

19+
import java.util.ArrayList;
20+
import java.util.List;
21+
22+
import org.springframework.batch.execution.job.SimpleJob;
1923
import org.springframework.batch.execution.repository.SimpleJobRepository;
2024
import org.springframework.batch.execution.repository.dao.JdbcJobExecutionDao;
2125
import org.springframework.batch.execution.repository.dao.JdbcJobInstanceDao;
2226
import org.springframework.batch.execution.repository.dao.JdbcStepExecutionDao;
2327
import org.springframework.batch.execution.step.ItemOrientedStep;
2428
import org.springframework.batch.execution.step.TaskletStep;
29+
import org.springframework.batch.execution.step.support.LimitCheckingItemSkipPolicy;
2530
import org.springframework.beans.MutablePropertyValues;
2631
import org.springframework.beans.factory.config.BeanDefinition;
2732
import org.springframework.beans.factory.config.ConstructorArgumentValues;
@@ -50,7 +55,7 @@
5055
public class ConfigBeanDefinitionParser implements BeanDefinitionParser {
5156

5257
private static final String JOB_REPOSITORY_ELEMENT = "job-repository";
53-
58+
5459
private static final String JOB_REPOSITORY_BEAN_NAME = "_jobRepository";
5560

5661
private static final String DATA_SOURCE_ATT = "data-source";
@@ -70,33 +75,31 @@ public class ConfigBeanDefinitionParser implements BeanDefinitionParser {
7075
private static final String DB_TYPE_POSTGRES = "postgres";
7176

7277
private static final String JOB_ELEMENT = "job";
73-
78+
7479
private static final String ID_ATT = "id";
75-
80+
7681
private static final String RERUN_ATT = "rerun";
77-
82+
7883
private static final String RERUN_ALWAYS = "always";
79-
84+
8085
private static final String RERUN_NEVER = "never";
81-
86+
8287
private static final String RERUN_INCOMPLETE = "incomplete";
8388

8489
private static final String STEP_ELEMENT = "step";
85-
90+
8691
private static final String SIZE_ATT = "size";
87-
92+
8893
private static final String TRANSACTION_MANAGER_ATT = "transaction-manager";
89-
94+
9095
private static final String ITEM_READER_ATT = "item-reader";
91-
96+
9297
private static final String ITEM_WRITER_ATT = "item-writer";
93-
94-
private static final String INPUT_SKIP_LIMIT_ATT = "input-skip-limit";
95-
96-
private static final String OUTPUT_SKIP_LIMIT_ATT = "output-skip-limit";
98+
99+
private static final String SKIP_LIMIT_ATT = "skip-limit";
97100

98101
private static final String TASKLET_STEP_ELEMENT = "tasklet-step";
99-
102+
100103
private static final String TASKLET_ATT = "tasklet";
101104

102105
public BeanDefinition parse(Element element, ParserContext parserContext) {
@@ -218,28 +221,43 @@ private void addTableIncrementer(String dataSourceId, String incrementerName,
218221
}
219222

220223
private void parseJob(Element jobEle, ParserContext parserContext) {
224+
AbstractBeanDefinition jobDef = createJobBeanDefinition(jobEle, parserContext);
225+
List steps = new ArrayList();
226+
221227
NodeList childNodes = jobEle.getChildNodes();
222228
for (int i = 0; i < childNodes.getLength(); i++) {
223229
Node child = childNodes.item(i);
224230
if (child.getNodeType() == Node.ELEMENT_NODE) {
225231
String localName = child.getLocalName();
226232
if (STEP_ELEMENT.equals(localName)) {
227-
parseStep((Element) child, parserContext);
233+
String id = parseStep((Element) child, parserContext);
234+
steps.add(new RuntimeBeanReference(id));
228235
} else if (TASKLET_STEP_ELEMENT.equals(localName)) {
229-
parseTaskletStep((Element) child, parserContext);
236+
String id = parseTaskletStep((Element) child, parserContext);
237+
steps.add(new RuntimeBeanReference(id));
230238
}
231239
}
232240
}
241+
242+
jobDef.getPropertyValues().addPropertyValue("steps", steps);
233243
}
234-
235-
private void parseStep(Element stepEle, ParserContext parserContext) {
244+
245+
private AbstractBeanDefinition createJobBeanDefinition(Element jobEle, ParserContext parserContext) {
246+
RootBeanDefinition jobDef = new RootBeanDefinition(SimpleJob.class);
247+
jobDef.setSource(parserContext.extractSource(jobEle));
248+
jobDef.getPropertyValues().addPropertyValue("jobRepository", JOB_REPOSITORY_BEAN_NAME);
249+
return jobDef;
250+
}
251+
252+
private String parseStep(Element stepEle, ParserContext parserContext) {
236253
AbstractBeanDefinition stepDef = createStepBeanDefinition(stepEle, parserContext);
237254
String id = stepEle.getAttribute(ID_ATT);
238255

239256
if (StringUtils.hasText(id)) {
240257
parserContext.getRegistry().registerBeanDefinition(id, stepDef);
258+
return id;
241259
} else {
242-
parserContext.getReaderContext().registerWithGeneratedName(stepDef);
260+
return parserContext.getReaderContext().registerWithGeneratedName(stepDef);
243261
}
244262
}
245263

@@ -256,7 +274,7 @@ private AbstractBeanDefinition createStepBeanDefinition(Element stepElement, Par
256274
} else {
257275
propertyValues.addPropertyValue("transactionManager", new RuntimeBeanReference(transactionManager));
258276
}
259-
277+
260278
String itemReader = stepElement.getAttribute(ITEM_READER_ATT);
261279
if (!StringUtils.hasText(itemReader)) {
262280
parserContext.getReaderContext().error("'item-reader' attribute contains empty value", stepElement);
@@ -270,32 +288,33 @@ private AbstractBeanDefinition createStepBeanDefinition(Element stepElement, Par
270288
propertyValues.addPropertyValue("itemWriter", new RuntimeBeanReference(itemWriter));
271289
}
272290

273-
if (stepElement.hasAttribute(INPUT_SKIP_LIMIT_ATT)) {
274-
String inputSkipLimit = stepElement.getAttribute(INPUT_SKIP_LIMIT_ATT);
275-
propertyValues.addPropertyValue("skipLimit", Integer.valueOf(inputSkipLimit));
291+
if (stepElement.hasAttribute(SKIP_LIMIT_ATT)) {
292+
String skipLimit = stepElement.getAttribute(SKIP_LIMIT_ATT);
293+
propertyValues.addPropertyValue("skipLimit", createSkipLimitBeanDefinition(Integer.valueOf(skipLimit)));
276294
}
277295

278-
// TODO: Create difference between input skip limit and output skip limit
279-
// if (stepElement.hasAttribute(ATT_OUTPUT_SKIP_LIMIT)) {
280-
// String outputSkipLimit = stepElement.getAttribute(ATT_OUTPUT_SKIP_LIMIT);
281-
// propertyValues.addPropertyValue(PROP_OUTPUT_SKIP_LIMIT, Integer.valueOf(outputSkipLimit));
282-
// }
283-
284296
String rerun = stepElement.getAttribute(RERUN_ATT);
285297
setPropertiesForRerun(rerun, propertyValues);
286298
propertyValues.addPropertyValue("jobRepository", new RuntimeBeanReference(JOB_REPOSITORY_BEAN_NAME));
287299
return stepDef;
288300
}
289301

290-
private void parseTaskletStep(Element taskletStepEle, ParserContext parserContext) {
302+
private AbstractBeanDefinition createSkipLimitBeanDefinition(Integer skipLimit) {
303+
RootBeanDefinition skipLimitDef = new RootBeanDefinition(LimitCheckingItemSkipPolicy.class);
304+
skipLimitDef.getConstructorArgumentValues().addGenericArgumentValue(skipLimit);
305+
return skipLimitDef;
306+
}
307+
308+
private String parseTaskletStep(Element taskletStepEle, ParserContext parserContext) {
291309
AbstractBeanDefinition stepDef = createTaskletStepBeanDefinition(taskletStepEle, parserContext);
292310

293311
String id = taskletStepEle.getAttribute(ID_ATT);
294312

295313
if (StringUtils.hasText(id)) {
296314
parserContext.getRegistry().registerBeanDefinition(id, stepDef);
315+
return id;
297316
} else {
298-
parserContext.getReaderContext().registerWithGeneratedName(stepDef);
317+
return parserContext.getReaderContext().registerWithGeneratedName(stepDef);
299318
}
300319
}
301320

spring-batch-execution/src/main/resources/org/springframework/batch/execution/configuration/spring-batch-1.0.xsd

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,16 +96,11 @@
9696
</xs:annotation>
9797
</xs:attribute>
9898
<xs:attributeGroup ref="rerun.enum"/>
99-
<xs:attribute name="input-skip-limit" type="xs:nonNegativeInteger" use="optional">
99+
<xs:attribute name="skip-limit" type="xs:nonNegativeInteger" use="optional">
100100
<xs:annotation>
101101
<xs:documentation><![CDATA[The maximum number of items the ItemReader can skip before this step is marked as a failure. The default is no limit.]]></xs:documentation>
102102
</xs:annotation>
103103
</xs:attribute>
104-
<xs:attribute name="output-skip-limit" type="xs:nonNegativeInteger" use="optional">
105-
<xs:annotation>
106-
<xs:documentation><![CDATA[The maximum number of items the ItemWriter can skip before this step is marked as a failure. The default is no limit.]]></xs:documentation>
107-
</xs:annotation>
108-
</xs:attribute>
109104
</xs:complexType>
110105

111106
<xs:complexType name="taskletStepType">

0 commit comments

Comments
 (0)