Skip to content

Commit 37bfe92

Browse files
author
nebhale
committed
[BATCH-63] <step/> tag of namespace complete
1 parent 29ea3e1 commit 37bfe92

16 files changed

+508
-19
lines changed

spring-batch-execution/.springBeans

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<beansProjectDescription>
33
<version>1</version>
4-
<pluginVersion><![CDATA[2.0.4.v200802132100]]></pluginVersion>
4+
<pluginVersion><![CDATA[2.0.4.v200802202100]]></pluginVersion>
55
<configSuffixes>
66
<configSuffix><![CDATA[xml]]></configSuffix>
77
</configSuffixes>
@@ -29,6 +29,14 @@
2929
<config>src/test/resources/org/springframework/batch/execution/configuration/BatchNamespaceHandlerTaskletStepRerunAlways.xml</config>
3030
<config>src/test/resources/org/springframework/batch/execution/configuration/BatchNamespaceHandlerTaskletStepRerunIncomplete.xml</config>
3131
<config>src/test/resources/org/springframework/batch/execution/configuration/BatchNamespaceHandlerTaskletStepRerunNever.xml</config>
32+
<config>src/test/resources/org/springframework/batch/execution/configuration/BatchNamespaceHandlerStepOk.xml</config>
33+
<config>src/test/resources/org/springframework/batch/execution/configuration/BatchNamespaceHandlerStepMissingItemReader.xml</config>
34+
<config>src/test/resources/org/springframework/batch/execution/configuration/BatchNamespaceHandlerStepMissingItemWriter.xml</config>
35+
<config>src/test/resources/org/springframework/batch/execution/configuration/BatchNamespaceHandlerStepMissingTransactionManager.xml</config>
36+
<config>src/test/resources/org/springframework/batch/execution/configuration/BatchNamespaceHandlerStepRerunAlways.xml</config>
37+
<config>src/test/resources/org/springframework/batch/execution/configuration/BatchNamespaceHandlerStepRerunIncomplete.xml</config>
38+
<config>src/test/resources/org/springframework/batch/execution/configuration/BatchNamespaceHandlerStepRerunNever.xml</config>
39+
<config>src/test/resources/org/springframework/batch/execution/configuration/BatchNamespaceHandlerStepSpecificTransactionManager.xml</config>
3240
</configs>
3341
<configSets>
3442
<configSet>

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

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

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

19+
import org.springframework.batch.execution.step.ItemOrientedStep;
1920
import org.springframework.batch.execution.step.TaskletStep;
2021
import org.springframework.beans.MutablePropertyValues;
2122
import org.springframework.beans.factory.config.BeanDefinition;
@@ -37,7 +38,7 @@ class JobBeanDefinitionParser implements BeanDefinitionParser {
3738

3839
private static final String TAG_JOB = "job";
3940

40-
private static final String TAG_CHUNKING_STEP = "chunking-step";
41+
private static final String TAG_STEP = "step";
4142

4243
private static final String TAG_TASKLET_STEP = "tasklet-step";
4344

@@ -63,14 +64,39 @@ class JobBeanDefinitionParser implements BeanDefinitionParser {
6364

6465
private static final String REPOSITORY_BEAN_NAME = "_jobRepository";
6566

67+
private static final String ATT_SIZE = "size";
68+
69+
private static final String PROP_COMMIT_INTERVAL = "commitInterval";
70+
71+
private static final String ATT_TRANSACTION_MANAGER = "transaction-manager";
72+
73+
private static final String PROP_TRANSACTION_MANAGER = "transactionManager";
74+
75+
private static final String ATT_ITEM_READER = "item-reader";
76+
77+
private static final String PROP_ITEM_READER = "itemReader";
78+
79+
private static final String ATT_ITEM_WRITER = "item-writer";
80+
81+
private static final String PROP_ITEM_WRITER = "itemWriter";
82+
83+
private static final String ATT_INPUT_SKIP_LIMIT = "input-skip-limit";
84+
85+
// TODO: Create difference between input skip limit and output skip limit
86+
private static final String PROP_INPUT_SKIP_LIMIT = "skipLimit";
87+
88+
private static final String ATT_OUTPUT_SKIP_LIMIT = "output-skip-limit";
89+
90+
private static final String PROP_OUTPUT_SKIP_LIMIT = "outputSkipLimit";
91+
6692
public BeanDefinition parse(Element element, ParserContext parserContext) {
6793
NodeList childNodes = element.getChildNodes();
6894
for (int i = 0; i < childNodes.getLength(); i++) {
6995
Node node = childNodes.item(i);
7096
if (node.getNodeType() == Node.ELEMENT_NODE) {
7197
String localName = node.getLocalName();
72-
if (TAG_CHUNKING_STEP.equals(localName)) {
73-
// parseChunkingStep((Element) node, parserContext);
98+
if (TAG_STEP.equals(localName)) {
99+
parseStep((Element) node, parserContext);
74100
} else if (TAG_TASKLET_STEP.equals(localName)) {
75101
parseTaskletStep((Element) node, parserContext);
76102
}
@@ -79,6 +105,61 @@ public BeanDefinition parse(Element element, ParserContext parserContext) {
79105
return null;
80106
}
81107

108+
private void parseStep(Element stepElement, ParserContext parserContext) {
109+
AbstractBeanDefinition stepDef = createStepBeanDefinition(stepElement, parserContext);
110+
String id = stepElement.getAttribute(ATT_ID);
111+
112+
if (StringUtils.hasText(id)) {
113+
parserContext.getRegistry().registerBeanDefinition(id, stepDef);
114+
} else {
115+
parserContext.getReaderContext().registerWithGeneratedName(stepDef);
116+
}
117+
}
118+
119+
private AbstractBeanDefinition createStepBeanDefinition(Element stepElement, ParserContext parserContext) {
120+
RootBeanDefinition stepDef = new RootBeanDefinition(ItemOrientedStep.class);
121+
stepDef.setSource(parserContext.extractSource(stepElement));
122+
MutablePropertyValues propertyValues = stepDef.getPropertyValues();
123+
124+
String size = stepElement.getAttribute(ATT_SIZE);
125+
propertyValues.addPropertyValue(PROP_COMMIT_INTERVAL, Integer.valueOf(size));
126+
String transactionManager = stepElement.getAttribute(ATT_TRANSACTION_MANAGER);
127+
if (!StringUtils.hasText(transactionManager)) {
128+
parserContext.getReaderContext().error("'transaction-manager' attribute contains empty value", stepElement);
129+
} else {
130+
propertyValues.addPropertyValue(PROP_TRANSACTION_MANAGER, new RuntimeBeanReference(transactionManager));
131+
}
132+
133+
String itemReader = stepElement.getAttribute(ATT_ITEM_READER);
134+
if (!StringUtils.hasText(itemReader)) {
135+
parserContext.getReaderContext().error("'item-reader' attribute contains empty value", stepElement);
136+
} else {
137+
propertyValues.addPropertyValue(PROP_ITEM_READER, new RuntimeBeanReference(itemReader));
138+
}
139+
String itemWriter = stepElement.getAttribute(ATT_ITEM_WRITER);
140+
if (!StringUtils.hasText(itemWriter)) {
141+
parserContext.getReaderContext().error("'item-writer' attribute contains empty value", stepElement);
142+
} else {
143+
propertyValues.addPropertyValue(PROP_ITEM_WRITER, new RuntimeBeanReference(itemWriter));
144+
}
145+
146+
if (stepElement.hasAttribute(ATT_INPUT_SKIP_LIMIT)) {
147+
String inputSkipLimit = stepElement.getAttribute(ATT_INPUT_SKIP_LIMIT);
148+
propertyValues.addPropertyValue(PROP_INPUT_SKIP_LIMIT, Integer.valueOf(inputSkipLimit));
149+
}
150+
151+
// TODO: Create difference between input skip limit and output skip limit
152+
// if (stepElement.hasAttribute(ATT_OUTPUT_SKIP_LIMIT)) {
153+
// String outputSkipLimit = stepElement.getAttribute(ATT_OUTPUT_SKIP_LIMIT);
154+
// propertyValues.addPropertyValue(PROP_OUTPUT_SKIP_LIMIT, Integer.valueOf(outputSkipLimit));
155+
// }
156+
157+
String rerun = stepElement.getAttribute(ATT_RERUN);
158+
setPropertiesForRerun(rerun, propertyValues);
159+
propertyValues.addPropertyValue(PROP_JOB_REPOSITORY, new RuntimeBeanReference(REPOSITORY_BEAN_NAME));
160+
return stepDef;
161+
}
162+
82163
private void parseTaskletStep(Element taskletElement, ParserContext parserContext) {
83164
AbstractBeanDefinition stepDef = createTaskletStepBeanDefinition(taskletElement, parserContext);
84165
String id = taskletElement.getAttribute(ATT_ID);
@@ -93,18 +174,18 @@ private void parseTaskletStep(Element taskletElement, ParserContext parserContex
93174
private AbstractBeanDefinition createTaskletStepBeanDefinition(Element taskletElement, ParserContext parserContext) {
94175
RootBeanDefinition stepDef = new RootBeanDefinition(TaskletStep.class);
95176
stepDef.setSource(parserContext.extractSource(taskletElement));
177+
MutablePropertyValues propertyValues = stepDef.getPropertyValues();
96178

97179
String tasklet = taskletElement.getAttribute(ATT_TASKLET);
98180
if (!StringUtils.hasText(tasklet)) {
99181
parserContext.getReaderContext().error("'tasklet' attribute contains empty value", taskletElement);
100182
} else {
101-
stepDef.getPropertyValues().addPropertyValue(PROP_TASKLET, new RuntimeBeanReference(tasklet));
183+
propertyValues.addPropertyValue(PROP_TASKLET, new RuntimeBeanReference(tasklet));
102184
}
103185

104186
String rerun = taskletElement.getAttribute(ATT_RERUN);
105-
setPropertiesForRerun(rerun, stepDef.getPropertyValues());
106-
stepDef.getPropertyValues().addPropertyValue(PROP_JOB_REPOSITORY,
107-
new RuntimeBeanReference(REPOSITORY_BEAN_NAME));
187+
setPropertiesForRerun(rerun, propertyValues);
188+
propertyValues.addPropertyValue(PROP_JOB_REPOSITORY, new RuntimeBeanReference(REPOSITORY_BEAN_NAME));
108189

109190
return stepDef;
110191
}

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
import org.w3c.dom.Element;
3939

4040
/**
41+
* Creates a {@link BeanDefinitionParser} for the <code>&lt;job-repository&gt;</code> tag.
42+
*
4143
* @author Ben Hale
4244
*/
4345
class JobRepositoryBeanDefinitionParser implements BeanDefinitionParser {
@@ -151,16 +153,17 @@ private BeanDefinition getIncrementer(String dbType, String dataSourceId, String
151153
return incrementerDef;
152154
}
153155

154-
private void addSequenceIncrementer(String dataSourceId, String incrementerName,
155-
ConstructorArgumentValues constructorArgumentValues) {
156-
constructorArgumentValues.addGenericArgumentValue(new RuntimeBeanReference(dataSourceId));
156+
private void addSequenceIncrementer(String dataSourceId, String incrementerName,
157+
ConstructorArgumentValues constructorArgumentValues) {
158+
constructorArgumentValues.addGenericArgumentValue(new RuntimeBeanReference(dataSourceId));
157159
constructorArgumentValues.addGenericArgumentValue(incrementerName);
158-
}
159-
160-
private void addTableIncrementer(String dataSourceId, String incrementerName, ConstructorArgumentValues constructorArgumentValues) {
161-
constructorArgumentValues.addGenericArgumentValue(new RuntimeBeanReference(dataSourceId));
160+
}
161+
162+
private void addTableIncrementer(String dataSourceId, String incrementerName,
163+
ConstructorArgumentValues constructorArgumentValues) {
164+
constructorArgumentValues.addGenericArgumentValue(new RuntimeBeanReference(dataSourceId));
162165
constructorArgumentValues.addGenericArgumentValue(incrementerName);
163166
constructorArgumentValues.addGenericArgumentValue("id");
164-
}
167+
}
165168

166169
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
</xs:annotation>
3939
<xs:complexType>
4040
<xs:choice minOccurs="1" maxOccurs="unbounded">
41-
<xs:element name="chunk-step" type="chunkStepType">
41+
<xs:element name="step" type="stepType">
4242
<xs:annotation>
4343
<xs:documentation><![CDATA[Defines a step that supports chunking]]></xs:documentation>
4444
</xs:annotation>
@@ -58,7 +58,7 @@
5858
</xs:element>
5959

6060
<!-- Types -->
61-
<xs:complexType name="chunkStepType">
61+
<xs:complexType name="stepType">
6262
<xs:attribute name="id" type="xs:token" use="required">
6363
<xs:annotation>
6464
<xs:documentation><![CDATA[The unique identifier to use in this step. The id must be unique within the context of this job.]]></xs:documentation>
@@ -80,7 +80,7 @@
8080
</xs:annotation>
8181
</xs:attribute>
8282
<xs:attribute name="transaction-manager" type="xs:token" use="optional"
83-
default="transaction-manager">
83+
default="transactionManager">
8484
<xs:annotation>
8585
<xs:documentation><![CDATA[The id of the transaction manager to use in this step. This should be an implementation of Spring's PlatformTransactionManager.]]></xs:documentation>
8686
</xs:annotation>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2002-2007 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+
17+
package org.springframework.batch.execution.configuration;
18+
19+
import junit.framework.TestCase;
20+
21+
import org.springframework.batch.execution.step.ItemOrientedStep;
22+
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
23+
import org.springframework.context.ApplicationContext;
24+
import org.springframework.context.support.ClassPathXmlApplicationContext;
25+
26+
public class BatchNamespaceHandlerStepTests extends TestCase {
27+
28+
private static final String PACKAGE = "org/springframework/batch/execution/configuration/";
29+
30+
public void testStepOk() {
31+
new ClassPathXmlApplicationContext(PACKAGE + "BatchNamespaceHandlerStepOk.xml");
32+
}
33+
34+
public void testStepMissingIteamReader() {
35+
try {
36+
new ClassPathXmlApplicationContext(PACKAGE + "BatchNamespaceHandlerStepMissingItemReader.xml");
37+
fail("Expected BeanDefinitionParsingException");
38+
} catch (BeanDefinitionParsingException e) { }
39+
}
40+
41+
public void testStepMissingItemWriter() {
42+
try {
43+
new ClassPathXmlApplicationContext(PACKAGE + "BatchNamespaceHandlerStepMissingItemWriter.xml");
44+
fail("Expected BeanDefinitionParsingException");
45+
} catch (BeanDefinitionParsingException e) { }
46+
}
47+
48+
public void testStepMissingTransactionManager() {
49+
try {
50+
new ClassPathXmlApplicationContext(PACKAGE + "BatchNamespaceHandlerStepMissingTransactionManager.xml");
51+
fail("Expected BeanDefinitionParsingException");
52+
} catch (BeanDefinitionParsingException e) { }
53+
}
54+
55+
public void testStepSpecificTransactionManager() {
56+
new ClassPathXmlApplicationContext(PACKAGE + "BatchNamespaceHandlerStepSpecificTransactionManager.xml");
57+
}
58+
59+
public void testStepRerunAlways() {
60+
ApplicationContext ctx = new ClassPathXmlApplicationContext(PACKAGE + "BatchNamespaceHandlerStepRerunAlways.xml");
61+
ItemOrientedStep step = (ItemOrientedStep) ctx.getBean("process");
62+
assertEquals(Integer.MAX_VALUE, step.getStartLimit());
63+
assertTrue(step.isAllowStartIfComplete());
64+
}
65+
66+
public void testStepRerunNever() {
67+
ApplicationContext ctx = new ClassPathXmlApplicationContext(PACKAGE + "BatchNamespaceHandlerStepRerunNever.xml");
68+
ItemOrientedStep step = (ItemOrientedStep) ctx.getBean("process");
69+
assertEquals(1, step.getStartLimit());
70+
assertFalse(step.isAllowStartIfComplete());
71+
}
72+
73+
public void testStepRerunIncomplete() {
74+
ApplicationContext ctx = new ClassPathXmlApplicationContext(PACKAGE + "BatchNamespaceHandlerStepRerunIncomplete.xml");
75+
ItemOrientedStep step = (ItemOrientedStep) ctx.getBean("process");
76+
assertEquals(Integer.MAX_VALUE, step.getStartLimit());
77+
assertFalse(step.isAllowStartIfComplete());
78+
}
79+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2002-2007 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+
17+
package org.springframework.batch.execution.configuration;
18+
19+
import org.springframework.batch.item.ItemReader;
20+
import org.springframework.batch.item.exception.MarkFailedException;
21+
import org.springframework.batch.item.exception.ResetFailedException;
22+
23+
public class StubItemReader implements ItemReader {
24+
25+
public void mark() throws MarkFailedException {
26+
// TODO Auto-generated method stub
27+
throw new UnsupportedOperationException();
28+
}
29+
30+
public Object read() throws Exception {
31+
// TODO Auto-generated method stub
32+
throw new UnsupportedOperationException();
33+
}
34+
35+
public void reset() throws ResetFailedException {
36+
// TODO Auto-generated method stub
37+
throw new UnsupportedOperationException();
38+
}
39+
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2002-2007 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+
17+
package org.springframework.batch.execution.configuration;
18+
19+
import org.springframework.batch.item.ItemWriter;
20+
21+
public class StubItemWriter implements ItemWriter {
22+
23+
public void clear() throws Exception {
24+
// TODO Auto-generated method stub
25+
throw new UnsupportedOperationException();
26+
}
27+
28+
public void flush() throws Exception {
29+
// TODO Auto-generated method stub
30+
throw new UnsupportedOperationException();
31+
}
32+
33+
public void write(Object item) throws Exception {
34+
// TODO Auto-generated method stub
35+
throw new UnsupportedOperationException();
36+
}
37+
38+
}

0 commit comments

Comments
 (0)