Skip to content

Commit 3207851

Browse files
committed
Merge pull request #198 from mminella/BATCH-2004
* BATCH-2004: BATCH-2004: Updated per review comments BATCH-2004: Added basic wrappers for the the majority of batch artifacts.
2 parents 7e85b50 + 9524084 commit 3207851

File tree

85 files changed

+3877
-337
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+3877
-337
lines changed

spring-batch-core-tests/pom.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,6 @@
152152
<artifactId>cglib-nodep</artifactId>
153153
<optional>true</optional>
154154
</dependency>
155-
<dependency>
156-
<groupId>com.ibm.jbatch</groupId>
157-
<artifactId>com.ibm.jbatch-tck-spi</artifactId>
158-
<version>1.0-b28</version>
159-
</dependency>
160155
</dependencies>
161156
<build>
162157
<pluginManagement>

spring-batch-core/pom.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@
2121
<dependency>
2222
<groupId>javax.batch</groupId>
2323
<artifactId>javax.batch-api</artifactId>
24-
<version>1.0-b29</version>
24+
<version>1.0</version>
25+
</dependency>
26+
<dependency>
27+
<groupId>com.ibm.jbatch</groupId>
28+
<artifactId>com.ibm.jbatch-tck-spi</artifactId>
29+
<version>1.0</version>
2530
</dependency>
2631
<dependency>
2732
<groupId>org.hsqldb</groupId>
@@ -204,7 +209,7 @@
204209
<fileset dir="${basedir}/src/main/sql" includes="schema*.sql.vpp" />
205210
<mapper type="glob" from="*.sql.vpp" to="*-sqlf.sql" />
206211
</vppcopy>
207-
212+
208213
<vppcopy todir="${basedir}/target/generated-resources" overwrite="true">
209214
<config>
210215
<context>

spring-batch-core/src/main/java/org/springframework/batch/core/BatchStatus.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
*
2222
* @author Lucas Ward
2323
* @author Dave Syer
24+
* @author Michael Minella
2425
*/
2526
public enum BatchStatus {
2627

@@ -76,8 +77,9 @@ public BatchStatus upgradeTo(BatchStatus other) {
7677
return max(this, other);
7778
}
7879
// Both less than or equal to STARTED
79-
if (this == COMPLETED || other == COMPLETED)
80+
if (this == COMPLETED || other == COMPLETED) {
8081
return COMPLETED;
82+
}
8183
return max(this, other);
8284
}
8385

@@ -105,6 +107,29 @@ public boolean isLessThanOrEqualTo(BatchStatus other) {
105107
return this.compareTo(other) <= 0;
106108
}
107109

110+
/**
111+
* Converts the current status to the JSR-352 equivalent
112+
*
113+
* @return JSR-352 equivalent to the current status
114+
*/
115+
public javax.batch.runtime.BatchStatus getBatchStatus() {
116+
if(this == ABANDONED) {
117+
return javax.batch.runtime.BatchStatus.ABANDONED;
118+
} else if(this == COMPLETED) {
119+
return javax.batch.runtime.BatchStatus.COMPLETED;
120+
} else if(this == STARTED) {
121+
return javax.batch.runtime.BatchStatus.STARTED;
122+
} else if(this == STARTING) {
123+
return javax.batch.runtime.BatchStatus.STARTING;
124+
} else if(this == STOPPED) {
125+
return javax.batch.runtime.BatchStatus.STOPPED;
126+
} else if(this == STOPPING) {
127+
return javax.batch.runtime.BatchStatus.STOPPING;
128+
} else {
129+
return javax.batch.runtime.BatchStatus.FAILED;
130+
}
131+
}
132+
108133
/**
109134
* Find a BatchStatus that matches the beginning of the given value. If no
110135
* match is found, return COMPLETED as the default because has is low

spring-batch-core/src/main/java/org/springframework/batch/core/JobInstance.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
* @see Job
3131
* @see JobParameters
3232
* @see JobExecution
33+
* @see javax.batch.runtime.JobInstance
3334
*
3435
* @author Lucas Ward
3536
* @author Dave Syer
@@ -38,7 +39,7 @@
3839
*
3940
*/
4041
@SuppressWarnings("serial")
41-
public class JobInstance extends Entity {
42+
public class JobInstance extends Entity implements javax.batch.runtime.JobInstance{
4243

4344
private final String jobName;
4445

@@ -51,6 +52,7 @@ public JobInstance(Long id, String jobName) {
5152
/**
5253
* @return the job name. (Equivalent to getJob().getName())
5354
*/
55+
@Override
5456
public String getJobName() {
5557
return jobName;
5658
}
@@ -60,4 +62,8 @@ public String toString() {
6062
return super.toString() + ", Job=[" + jobName + "]";
6163
}
6264

65+
@Override
66+
public long getInstanceId() {
67+
return super.getId();
68+
}
6369
}

spring-batch-core/src/main/java/org/springframework/batch/core/JobParameters.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Date;
2121
import java.util.LinkedHashMap;
2222
import java.util.Map;
23+
import java.util.Properties;
2324

2425
/**
2526
* Value object representing runtime parameters to a batch job. Because the
@@ -209,4 +210,16 @@ public int hashCode() {
209210
public String toString() {
210211
return parameters.toString();
211212
}
213+
214+
public Properties toProperties() {
215+
Properties props = new Properties();
216+
217+
for (Map.Entry<String, JobParameter> param : parameters.entrySet()) {
218+
if(param.getValue() != null) {
219+
props.put(param.getKey(), param.getValue().toString());
220+
}
221+
}
222+
223+
return props;
224+
}
212225
}

spring-batch-core/src/main/java/org/springframework/batch/core/JobParametersBuilder.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.Date;
2020
import java.util.LinkedHashMap;
2121
import java.util.Map;
22+
import java.util.Properties;
2223

2324
import org.springframework.util.Assert;
2425

@@ -58,6 +59,22 @@ public JobParametersBuilder(JobParameters jobParameters) {
5859
this.parameterMap = new LinkedHashMap<String, JobParameter>(jobParameters.getParameters());
5960
}
6061

62+
/**
63+
* Constructor to add conversion capabilities to support JSR-352. Per the spec, it is expected that all
64+
* keys and values in the provided {@link Properties} instance are Strings
65+
*
66+
* @param properties the job parameters to be used
67+
*/
68+
public JobParametersBuilder(Properties properties) {
69+
this.parameterMap = new LinkedHashMap<String, JobParameter>();
70+
71+
if(properties != null) {
72+
for (Map.Entry<Object, Object> curProperty : properties.entrySet()) {
73+
this.parameterMap.put((String) curProperty.getKey(), new JobParameter((String) curProperty.getValue(), false));
74+
}
75+
}
76+
}
77+
6178
/**
6279
* Add a new identifying String parameter for the given key.
6380
*

spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBean.java

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333
import org.springframework.batch.core.StepExecutionListener;
3434
import org.springframework.batch.core.StepListener;
3535
import org.springframework.batch.core.job.flow.Flow;
36+
import org.springframework.batch.core.jsr.ChunkListenerAdapter;
37+
import org.springframework.batch.core.jsr.ItemProcessListenerAdapter;
38+
import org.springframework.batch.core.jsr.ItemReadListenerAdapter;
39+
import org.springframework.batch.core.jsr.ItemWriteListenerAdapter;
40+
import org.springframework.batch.core.jsr.StepListenerAdapter;
3641
import org.springframework.batch.core.launch.JobLauncher;
3742
import org.springframework.batch.core.partition.PartitionHandler;
3843
import org.springframework.batch.core.partition.support.Partitioner;
@@ -85,6 +90,7 @@
8590
*
8691
* @author Dan Garrette
8792
* @author Josh Long
93+
* @author Michael Minella
8894
* @see SimpleStepFactoryBean
8995
* @see FaultTolerantStepFactoryBean
9096
* @see TaskletStep
@@ -111,7 +117,7 @@ public class StepParserStepFactoryBean<I, O> implements FactoryBean, BeanNameAwa
111117

112118
private PlatformTransactionManager transactionManager;
113119

114-
private Set<StepExecutionListener> stepExecutionListeners = new LinkedHashSet<StepExecutionListener>();
120+
private Set<Object> stepExecutionListeners = new LinkedHashSet<Object>();
115121

116122
//
117123
// Flow Elements
@@ -218,8 +224,6 @@ public class StepParserStepFactoryBean<I, O> implements FactoryBean, BeanNameAwa
218224

219225
private StepExecutionAggregator stepExecutionAggregator;
220226

221-
private StepListener[] listeners;
222-
223227
/**
224228
* Create a {@link Step} from the configuration provided.
225229
*
@@ -269,8 +273,12 @@ private void enhanceCommonStep(StepBuilderHelper<?> builder) {
269273
}
270274
builder.repository(jobRepository);
271275
builder.transactionManager(transactionManager);
272-
for (StepExecutionListener listener : stepExecutionListeners) {
273-
builder.listener(listener);
276+
for (Object listener : stepExecutionListeners) {
277+
if(listener instanceof StepExecutionListener) {
278+
builder.listener((StepExecutionListener) listener);
279+
} else if(listener instanceof StepListener) {
280+
builder.listener(new StepListenerAdapter((javax.batch.api.listener.StepListener) listener));
281+
}
274282
}
275283
}
276284

@@ -394,7 +402,7 @@ private Step createSimpleStep() {
394402
CompositeCompletionPolicy completionPolicy = new CompositeCompletionPolicy();
395403
CompletionPolicy [] policies = new CompletionPolicy[2];
396404
policies[0] = new SimpleCompletionPolicy(commitInterval);
397-
policies[1] = new TimeoutTerminationPolicy(timeout);
405+
policies[1] = new TimeoutTerminationPolicy(timeout * 1000);
398406
completionPolicy.setPolicies(policies);
399407
builder.chunk(completionPolicy);
400408
} else if(timeout != null) {
@@ -715,37 +723,54 @@ public void setTransactionManager(PlatformTransactionManager transactionManager)
715723
*
716724
* @param listeners an array of listeners
717725
*/
718-
public void setListeners(StepListener[] listeners) {
719-
this.listeners = listeners; // useful for testing
720-
for (StepListener listener : listeners) {
726+
@SuppressWarnings("unchecked")
727+
public void setListeners(Object[] listeners) {
728+
// this.listeners = listeners; // useful for testing
729+
for (Object listener : listeners) {
721730
if (listener instanceof SkipListener) {
722-
@SuppressWarnings("unchecked")
723731
SkipListener<I, O> skipListener = (SkipListener<I, O>) listener;
724732
skipListeners.add(skipListener);
725733
}
726734
if (listener instanceof StepExecutionListener) {
727735
StepExecutionListener stepExecutionListener = (StepExecutionListener) listener;
728736
stepExecutionListeners.add(stepExecutionListener);
729737
}
738+
if(listener instanceof javax.batch.api.listener.StepListener) {
739+
StepExecutionListener stepExecutionListener = new StepListenerAdapter((javax.batch.api.listener.StepListener) listener);
740+
stepExecutionListeners.add(stepExecutionListener);
741+
}
730742
if (listener instanceof ChunkListener) {
731743
ChunkListener chunkListener = (ChunkListener) listener;
732744
chunkListeners.add(chunkListener);
733745
}
746+
if(listener instanceof javax.batch.api.chunk.listener.ChunkListener) {
747+
ChunkListener chunkListener = new ChunkListenerAdapter((javax.batch.api.chunk.listener.ChunkListener) listener);
748+
chunkListeners.add(chunkListener);
749+
}
734750
if (listener instanceof ItemReadListener) {
735-
@SuppressWarnings("unchecked")
736751
ItemReadListener<I> readListener = (ItemReadListener<I>) listener;
737752
readListeners.add(readListener);
738753
}
754+
if(listener instanceof javax.batch.api.chunk.listener.ItemReadListener) {
755+
ItemReadListener itemListener = new ItemReadListenerAdapter((javax.batch.api.chunk.listener.ItemReadListener) listener);
756+
readListeners.add(itemListener);
757+
}
739758
if (listener instanceof ItemWriteListener) {
740-
@SuppressWarnings("unchecked")
741759
ItemWriteListener<O> writeListener = (ItemWriteListener<O>) listener;
742760
writeListeners.add(writeListener);
743761
}
762+
if(listener instanceof javax.batch.api.chunk.listener.ItemWriteListener) {
763+
ItemWriteListener itemListener = new ItemWriteListenerAdapter((javax.batch.api.chunk.listener.ItemWriteListener) listener);
764+
writeListeners.add(itemListener);
765+
}
744766
if (listener instanceof ItemProcessListener) {
745-
@SuppressWarnings("unchecked")
746767
ItemProcessListener<I, O> processListener = (ItemProcessListener<I, O>) listener;
747768
processListeners.add(processListener);
748769
}
770+
if(listener instanceof javax.batch.api.chunk.listener.ItemProcessListener) {
771+
ItemProcessListener itemListener = new ItemProcessListenerAdapter((javax.batch.api.chunk.listener.ItemProcessListener) listener);
772+
processListeners.add(itemListener);
773+
}
749774
}
750775
}
751776

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2013 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.jsr;
17+
18+
import javax.batch.operations.BatchRuntimeException;
19+
20+
import org.springframework.batch.core.ChunkListener;
21+
import org.springframework.batch.core.scope.context.ChunkContext;
22+
import org.springframework.util.Assert;
23+
24+
/**
25+
* Wrapper class to adapt the {@link javax.batch.api.chunk.listener.ChunkListener} to
26+
* a {@link ChunkListener}.
27+
*
28+
* @author Michael Minella
29+
* @since 3.0
30+
*/
31+
public class ChunkListenerAdapter implements ChunkListener {
32+
33+
private final javax.batch.api.chunk.listener.ChunkListener delegate;
34+
35+
/**
36+
* @param delegate to be called within the step chunk lifecycle
37+
*/
38+
public ChunkListenerAdapter(javax.batch.api.chunk.listener.ChunkListener delegate) {
39+
Assert.notNull(delegate, "A ChunkListener is required");
40+
this.delegate = delegate;
41+
}
42+
43+
@Override
44+
public void beforeChunk(ChunkContext context) {
45+
try {
46+
delegate.beforeChunk();
47+
} catch (Exception e) {
48+
throw new BatchRuntimeException(e);
49+
}
50+
}
51+
52+
@Override
53+
public void afterChunk(ChunkContext context) {
54+
try {
55+
delegate.afterChunk();
56+
} catch (Exception e) {
57+
throw new BatchRuntimeException(e);
58+
}
59+
}
60+
61+
@Override
62+
public void afterChunkError(ChunkContext context) {
63+
if(context != null) {
64+
try {
65+
delegate.onError((Exception) context.getAttribute(ChunkListener.ROLLBACK_EXCEPTION_KEY));
66+
} catch (Exception e) {
67+
throw new BatchRuntimeException(e);
68+
}
69+
} else {
70+
throw new BatchRuntimeException("Unable to retrieve causing exception due to null ChunkContext");
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)