BATCH-2004: Added basic wrappers for the the majority of batch artifacts.

This commit is contained in:
Michael Minella
2013-06-14 15:06:41 -05:00
parent 7e85b50616
commit 775dd15be1
85 changed files with 3877 additions and 339 deletions

View File

@@ -152,11 +152,6 @@
<artifactId>cglib-nodep</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.ibm.jbatch</groupId>
<artifactId>com.ibm.jbatch-tck-spi</artifactId>
<version>1.0-b28</version>
</dependency>
</dependencies>
<build>
<pluginManagement>

View File

@@ -23,6 +23,11 @@
<artifactId>javax.batch-api</artifactId>
<version>1.0-b29</version>
</dependency>
<dependency>
<groupId>com.ibm.jbatch</groupId>
<artifactId>com.ibm.jbatch-tck-spi</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
@@ -204,7 +209,7 @@
<fileset dir="${basedir}/src/main/sql" includes="schema*.sql.vpp" />
<mapper type="glob" from="*.sql.vpp" to="*-sqlf.sql" />
</vppcopy>
<vppcopy todir="${basedir}/target/generated-resources" overwrite="true">
<config>
<context>

View File

@@ -21,6 +21,7 @@ package org.springframework.batch.core;
*
* @author Lucas Ward
* @author Dave Syer
* @author Michael Minella
*/
public enum BatchStatus {
@@ -76,8 +77,9 @@ public enum BatchStatus {
return max(this, other);
}
// Both less than or equal to STARTED
if (this == COMPLETED || other == COMPLETED)
if (this == COMPLETED || other == COMPLETED) {
return COMPLETED;
}
return max(this, other);
}
@@ -105,6 +107,29 @@ public enum BatchStatus {
return this.compareTo(other) <= 0;
}
/**
* Converts the current status to the JSR-352 equivalent
*
* @return JSR-352 equivalent to the current status
*/
public javax.batch.runtime.BatchStatus getBatchStatus() {
if(this == ABANDONED) {
return javax.batch.runtime.BatchStatus.ABANDONED;
} else if(this == COMPLETED) {
return javax.batch.runtime.BatchStatus.COMPLETED;
} else if(this == STARTED) {
return javax.batch.runtime.BatchStatus.STARTED;
} else if(this == STARTING) {
return javax.batch.runtime.BatchStatus.STARTING;
} else if(this == STOPPED) {
return javax.batch.runtime.BatchStatus.STOPPED;
} else if(this == STOPPING) {
return javax.batch.runtime.BatchStatus.STOPPING;
} else {
return javax.batch.runtime.BatchStatus.FAILED;
}
}
/**
* Find a BatchStatus that matches the beginning of the given value. If no
* match is found, return COMPLETED as the default because has is low

View File

@@ -30,6 +30,7 @@ import org.springframework.util.Assert;
* @see Job
* @see JobParameters
* @see JobExecution
* @see javax.batch.runtime.JobInstance
*
* @author Lucas Ward
* @author Dave Syer
@@ -38,7 +39,7 @@ import org.springframework.util.Assert;
*
*/
@SuppressWarnings("serial")
public class JobInstance extends Entity {
public class JobInstance extends Entity implements javax.batch.runtime.JobInstance{
private final String jobName;
@@ -51,6 +52,7 @@ public class JobInstance extends Entity {
/**
* @return the job name. (Equivalent to getJob().getName())
*/
@Override
public String getJobName() {
return jobName;
}
@@ -60,4 +62,8 @@ public class JobInstance extends Entity {
return super.toString() + ", Job=[" + jobName + "]";
}
@Override
public long getInstanceId() {
return super.getId();
}
}

View File

@@ -20,6 +20,7 @@ import java.io.Serializable;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
/**
* Value object representing runtime parameters to a batch job. Because the
@@ -209,4 +210,16 @@ public class JobParameters implements Serializable {
public String toString() {
return parameters.toString();
}
public Properties toProperties() {
Properties props = new Properties();
for (Map.Entry<String, JobParameter> param : parameters.entrySet()) {
if(param.getValue() != null) {
props.put(param.getKey(), param.getValue().toString());
}
}
return props;
}
}

View File

@@ -19,6 +19,7 @@ package org.springframework.batch.core;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import org.springframework.util.Assert;
@@ -58,6 +59,22 @@ public class JobParametersBuilder {
this.parameterMap = new LinkedHashMap<String, JobParameter>(jobParameters.getParameters());
}
/**
* Constructor to add conversion capabilities to support JSR-352. Per the spec, it is expected that all
* keys and values in the provided {@link Properties} instance are Strings
*
* @param properties the job parameters to be used
*/
public JobParametersBuilder(Properties properties) {
this.parameterMap = new LinkedHashMap<String, JobParameter>();
if(properties != null) {
for (Map.Entry<Object, Object> curProperty : properties.entrySet()) {
this.parameterMap.put((String) curProperty.getKey(), new JobParameter((String) curProperty.getValue(), false));
}
}
}
/**
* Add a new identifying String parameter for the given key.
*

View File

@@ -33,6 +33,11 @@ import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.core.StepListener;
import org.springframework.batch.core.job.flow.Flow;
import org.springframework.batch.core.jsr.ChunkListenerAdapter;
import org.springframework.batch.core.jsr.ItemProcessListenerAdapter;
import org.springframework.batch.core.jsr.ItemReadListenerAdapter;
import org.springframework.batch.core.jsr.ItemWriteListenerAdapter;
import org.springframework.batch.core.jsr.StepListenerAdapter;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.partition.PartitionHandler;
import org.springframework.batch.core.partition.support.Partitioner;
@@ -85,6 +90,7 @@ import org.springframework.util.Assert;
*
* @author Dan Garrette
* @author Josh Long
* @author Michael Minella
* @see SimpleStepFactoryBean
* @see FaultTolerantStepFactoryBean
* @see TaskletStep
@@ -111,7 +117,7 @@ public class StepParserStepFactoryBean<I, O> implements FactoryBean, BeanNameAwa
private PlatformTransactionManager transactionManager;
private Set<StepExecutionListener> stepExecutionListeners = new LinkedHashSet<StepExecutionListener>();
private Set<Object> stepExecutionListeners = new LinkedHashSet<Object>();
//
// Flow Elements
@@ -218,8 +224,6 @@ public class StepParserStepFactoryBean<I, O> implements FactoryBean, BeanNameAwa
private StepExecutionAggregator stepExecutionAggregator;
private StepListener[] listeners;
/**
* Create a {@link Step} from the configuration provided.
*
@@ -269,8 +273,12 @@ public class StepParserStepFactoryBean<I, O> implements FactoryBean, BeanNameAwa
}
builder.repository(jobRepository);
builder.transactionManager(transactionManager);
for (StepExecutionListener listener : stepExecutionListeners) {
builder.listener(listener);
for (Object listener : stepExecutionListeners) {
if(listener instanceof StepExecutionListener) {
builder.listener((StepExecutionListener) listener);
} else if(listener instanceof StepListener) {
builder.listener(new StepListenerAdapter((javax.batch.api.listener.StepListener) listener));
}
}
}
@@ -715,11 +723,11 @@ public class StepParserStepFactoryBean<I, O> implements FactoryBean, BeanNameAwa
*
* @param listeners an array of listeners
*/
public void setListeners(StepListener[] listeners) {
this.listeners = listeners; // useful for testing
for (StepListener listener : listeners) {
@SuppressWarnings("unchecked")
public void setListeners(Object[] listeners) {
// this.listeners = listeners; // useful for testing
for (Object listener : listeners) {
if (listener instanceof SkipListener) {
@SuppressWarnings("unchecked")
SkipListener<I, O> skipListener = (SkipListener<I, O>) listener;
skipListeners.add(skipListener);
}
@@ -727,25 +735,42 @@ public class StepParserStepFactoryBean<I, O> implements FactoryBean, BeanNameAwa
StepExecutionListener stepExecutionListener = (StepExecutionListener) listener;
stepExecutionListeners.add(stepExecutionListener);
}
if(listener instanceof javax.batch.api.listener.StepListener) {
StepExecutionListener stepExecutionListener = new StepListenerAdapter((javax.batch.api.listener.StepListener) listener);
stepExecutionListeners.add(stepExecutionListener);
}
if (listener instanceof ChunkListener) {
ChunkListener chunkListener = (ChunkListener) listener;
chunkListeners.add(chunkListener);
}
if(listener instanceof javax.batch.api.chunk.listener.ChunkListener) {
ChunkListener chunkListener = new ChunkListenerAdapter((javax.batch.api.chunk.listener.ChunkListener) listener);
chunkListeners.add(chunkListener);
}
if (listener instanceof ItemReadListener) {
@SuppressWarnings("unchecked")
ItemReadListener<I> readListener = (ItemReadListener<I>) listener;
readListeners.add(readListener);
}
if(listener instanceof javax.batch.api.chunk.listener.ItemReadListener) {
ItemReadListener itemListener = new ItemReadListenerAdapter((javax.batch.api.chunk.listener.ItemReadListener) listener);
readListeners.add(itemListener);
}
if (listener instanceof ItemWriteListener) {
@SuppressWarnings("unchecked")
ItemWriteListener<O> writeListener = (ItemWriteListener<O>) listener;
writeListeners.add(writeListener);
}
if(listener instanceof javax.batch.api.chunk.listener.ItemWriteListener) {
ItemWriteListener itemListener = new ItemWriteListenerAdapter((javax.batch.api.chunk.listener.ItemWriteListener) listener);
writeListeners.add(itemListener);
}
if (listener instanceof ItemProcessListener) {
@SuppressWarnings("unchecked")
ItemProcessListener<I, O> processListener = (ItemProcessListener<I, O>) listener;
processListeners.add(processListener);
}
if(listener instanceof javax.batch.api.chunk.listener.ItemProcessListener) {
ItemProcessListener itemListener = new ItemProcessListenerAdapter((javax.batch.api.chunk.listener.ItemProcessListener) listener);
processListeners.add(itemListener);
}
}
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr;
import javax.batch.operations.BatchRuntimeException;
import org.springframework.batch.core.ChunkListener;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.util.Assert;
/**
* Wrapper class to adapt the {@link javax.batch.api.chunk.listener.ChunkListener} to
* a {@link ChunkListener}.
*
* @author Michael Minella
* @since 3.0
*/
public class ChunkListenerAdapter implements ChunkListener {
private final javax.batch.api.chunk.listener.ChunkListener delegate;
/**
* @param delegate to be called within the step chunk lifecycle
*/
public ChunkListenerAdapter(javax.batch.api.chunk.listener.ChunkListener delegate) {
Assert.notNull(delegate, "A ChunkListener is required");
this.delegate = delegate;
}
@Override
public void beforeChunk(ChunkContext context) {
try {
delegate.beforeChunk();
} catch (Exception e) {
throw new BatchRuntimeException(e);
}
}
@Override
public void afterChunk(ChunkContext context) {
try {
delegate.afterChunk();
} catch (Exception e) {
throw new BatchRuntimeException(e);
}
}
@Override
public void afterChunkError(ChunkContext context) {
if(context != null) {
try {
delegate.onError((Exception) context.getAttribute(ChunkListener.ROLLBACK_EXCEPTION_KEY));
} catch (Exception e) {
throw new BatchRuntimeException(e);
}
} else {
throw new BatchRuntimeException("Unable to retrieve causing exception");
}
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr;
import javax.batch.operations.BatchRuntimeException;
import org.springframework.batch.core.ItemProcessListener;
import org.springframework.util.Assert;
/**
* Wrapper class for {@link javax.batch.api.chunk.listener.ItemProcessListener}
*
* @author Michael Minella
*
* @param <T> input type
* @param <S> output type
* @since 3.0
*/
public class ItemProcessListenerAdapter<T,S> implements ItemProcessListener<T, S> {
private javax.batch.api.chunk.listener.ItemProcessListener delegate;
/**
* @param delegate to be called within the batch lifecycle
*/
public ItemProcessListenerAdapter(javax.batch.api.chunk.listener.ItemProcessListener delegate) {
Assert.notNull(delegate, "An ItemProcessListener is requred");
this.delegate = delegate;
}
@Override
public void beforeProcess(T item) {
try {
delegate.beforeProcess(item);
} catch (Exception e) {
throw new BatchRuntimeException(e);
}
}
@Override
public void afterProcess(T item, S result) {
try {
delegate.afterProcess(item, result);
} catch (Exception e) {
throw new BatchRuntimeException(e);
}
}
@Override
public void onProcessError(T item, Exception e) {
try {
delegate.onProcessError(item, e);
} catch (Exception e1) {
throw new BatchRuntimeException(e);
}
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr;
import javax.batch.operations.BatchRuntimeException;
import org.springframework.batch.core.ItemReadListener;
import org.springframework.batch.item.ItemReader;
import org.springframework.util.Assert;
/**
* Wrapper class to adapt the {@link javax.batch.api.chunk.listener.ItemReadListener} to
* a {@link ItemReadListener}.
*
* @author Michael Minella
*
* @param <T> type to be returned via a read on the associated {@link ItemReader}
* @since 3.0
*/
public class ItemReadListenerAdapter<T> implements ItemReadListener<T> {
private javax.batch.api.chunk.listener.ItemReadListener delegate;
public ItemReadListenerAdapter(javax.batch.api.chunk.listener.ItemReadListener delegate) {
Assert.notNull(delegate, "An ItemReadListener is required");
this.delegate = delegate;
}
@Override
public void beforeRead() {
try {
delegate.beforeRead();
} catch (Exception e) {
throw new BatchRuntimeException(e);
}
}
@Override
public void afterRead(T item) {
try {
delegate.afterRead(item);
} catch (Exception e) {
throw new BatchRuntimeException(e);
}
}
@Override
public void onReadError(Exception ex) {
try {
delegate.onReadError(ex);
} catch (Exception e) {
throw new BatchRuntimeException(e);
}
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr;
import java.util.List;
import javax.batch.operations.BatchRuntimeException;
import org.springframework.batch.core.ItemWriteListener;
import org.springframework.batch.item.ItemWriter;
import org.springframework.util.Assert;
/**
* Wrapper class to adapt the {@link javax.batch.api.chunk.listener.ItemWriteListener} to
* a {@link ItemWriteListener}.
*
* @author Michael Minella
*
* @param <S> type to be written by the associated {@link ItemWriter}
* @since 3.0
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class ItemWriteListenerAdapter<S> implements ItemWriteListener<S> {
private javax.batch.api.chunk.listener.ItemWriteListener delegate;
public ItemWriteListenerAdapter(javax.batch.api.chunk.listener.ItemWriteListener delegate) {
Assert.notNull(delegate, "An ItemWriteListener is required");
this.delegate = delegate;
}
@Override
public void beforeWrite(List items) {
try {
delegate.beforeWrite(items);
} catch (Exception e) {
throw new BatchRuntimeException(e);
}
}
@Override
public void afterWrite(List items) {
try {
delegate.afterWrite(items);
} catch (Exception e) {
throw new BatchRuntimeException(e);
}
}
@Override
public void onWriteError(Exception exception, List items) {
try {
delegate.onWriteError(items, exception);
} catch (Exception e) {
throw new BatchRuntimeException(e);
}
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr;
import java.util.Properties;
import javax.batch.runtime.BatchStatus;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.util.Assert;
/**
* Wrapper class to provide the {@link javax.batch.runtime.context.JobContext} functionality
* as specified in JSR-352. Wrapper delegates to the underlying {@link JobExecution} to
* obtain the related contextual information.
*
* @author Michael Minella
* @since 3.0
*/
public class JobContext implements javax.batch.runtime.context.JobContext {
private JobExecution jobExecution;
private Object transientUserData;
/**
* @param jobExecution for the related job
*/
public JobContext(JobExecution jobExecution) {
Assert.notNull(jobExecution, "A JobExecution is required");
this.jobExecution = jobExecution;
}
@Override
public String getJobName() {
return jobExecution.getJobInstance().getJobName();
}
@Override
public Object getTransientUserData() {
return transientUserData;
}
@Override
public void setTransientUserData(Object data) {
transientUserData = data;
}
@Override
public long getInstanceId() {
return jobExecution.getJobInstance().getId();
}
@Override
public long getExecutionId() {
return jobExecution.getId();
}
@Override
public Properties getProperties() {
return jobExecution.getJobParameters().toProperties();
}
@Override
public BatchStatus getBatchStatus() {
return jobExecution.getStatus().getBatchStatus();
}
@Override
public String getExitStatus() {
return jobExecution.getExitStatus().getExitCode();
}
@Override
public void setExitStatus(String status) {
jobExecution.setExitStatus(new ExitStatus(status));
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr;
import java.util.Date;
import java.util.Properties;
import javax.batch.runtime.BatchStatus;
import org.springframework.util.Assert;
/**
* Wrapper class to adapt the {@link javax.batch.runtime.JobExecution} to
* a {@link JobExecution}.
*
* @author Michael Minella
* @since 3.0
*/
public class JobExecution implements javax.batch.runtime.JobExecution {
private org.springframework.batch.core.JobExecution execution;
/**
* @param execution for all information to be delegated from
*/
public JobExecution(org.springframework.batch.core.JobExecution execution) {
Assert.notNull(execution, "A JobExecution is required");
this.execution = execution;
}
@Override
public long getExecutionId() {
return this.execution.getId();
}
@Override
public String getJobName() {
return this.execution.getJobInstance().getJobName();
}
@Override
public BatchStatus getBatchStatus() {
return this.execution.getStatus().getBatchStatus();
}
@Override
public Date getStartTime() {
return this.execution.getStartTime();
}
@Override
public Date getEndTime() {
return this.execution.getEndTime();
}
@Override
public String getExitStatus() {
return this.execution.getExitStatus().getExitCode();
}
@Override
public Date getCreateTime() {
return this.execution.getCreateTime();
}
@Override
public Date getLastUpdatedTime() {
return this.execution.getLastUpdated();
}
@Override
public Properties getJobParameters() {
return this.execution.getJobParameters().toProperties();
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr;
import javax.batch.api.listener.JobListener;
import javax.batch.operations.BatchRuntimeException;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.util.Assert;
/**
* Wrapper class to adapt the {@link JobListener} to
* a {@link JobExecutionListener}.
*
* @author Michael Minella
* @since 3.0
*/
public class JobListenerAdapter implements JobExecutionListener {
private JobListener delegate;
/**
* @param delegate to be delegated to
*/
public JobListenerAdapter(JobListener delegate) {
Assert.notNull(delegate);
this.delegate = delegate;
}
@Override
public void beforeJob(JobExecution jobExecution) {
try {
delegate.beforeJob();
} catch (Exception e) {
throw new BatchRuntimeException(e);
}
}
@Override
public void afterJob(JobExecution jobExecution) {
try {
delegate.afterJob();
} catch (Exception e) {
throw new BatchRuntimeException(e);
}
}
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;
import javax.batch.api.listener.JobListener;
import org.springframework.batch.core.listener.ListenerMetaData;
/**
* Enumeration for {@link JobListener} meta data, which ties together the names
* of methods, their interfaces, annotation, and expected arguments.
*
* @author Michael Minella
* @since 3.0
*/
public enum JsrJobListenerMetaData implements ListenerMetaData {
BEFORE_JOB("beforeJob", "jsr-before-job", null),
AFTER_JOB("afterJob", "jsr-after-job", null);
private final String methodName;
private final String propertyName;
private final Class<? extends Annotation> annotation;
private static final Map<String, JsrJobListenerMetaData> propertyMap;
JsrJobListenerMetaData(String methodName, String propertyName, Class<? extends Annotation> annotation) {
this.methodName = methodName;
this.propertyName = propertyName;
this.annotation = annotation;
}
static{
propertyMap = new HashMap<String, JsrJobListenerMetaData>();
for(JsrJobListenerMetaData metaData : values()){
propertyMap.put(metaData.getPropertyName(), metaData);
}
}
@Override
public String getMethodName() {
return methodName;
}
@Override
public Class<? extends Annotation> getAnnotation() {
return annotation;
}
@Override
public Class<?> getListenerInterface() {
return JobListener.class;
}
@Override
public String getPropertyName() {
return propertyName;
}
@Override
public Class<?>[] getParamTypes() {
return new Class<?>[0];
}
/**
* Return the relevant meta data for the provided property name.
*
* @param propertyName
* @return meta data with supplied property name, null if none exists.
*/
public static JsrJobListenerMetaData fromPropertyName(String propertyName){
return propertyMap.get(propertyName);
}
}

View File

@@ -0,0 +1,112 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.batch.api.chunk.listener.ChunkListener;
import javax.batch.api.chunk.listener.ItemProcessListener;
import javax.batch.api.chunk.listener.ItemReadListener;
import javax.batch.api.chunk.listener.ItemWriteListener;
import javax.batch.api.listener.StepListener;
import org.springframework.batch.core.listener.ListenerMetaData;
import org.springframework.batch.core.listener.StepListenerFactoryBean;
/**
* Enumeration for the JSR specific {@link StepListener} meta data, which
* ties together the names of methods, their interfaces, and expected arguments.
*
* @author Michael Minella
* @since 3.0
* @see StepListenerFactoryBean
*/
public enum JsrStepListenerMetaData implements ListenerMetaData {
BEFORE_STEP("beforeStep", "jsr-before-step", StepListener.class),
AFTER_STEP("afterStep", "jsr-after-step", StepListener.class),
BEFORE_CHUNK("beforeChunk", "jsr-before-chunk", ChunkListener.class),
AFTER_CHUNK("afterChunk", "jsr-after-chunk", ChunkListener.class),
AFTER_CHUNK_ERROR("onError", "jsr-after-chunk-error", ChunkListener.class, Exception.class),
BEFORE_READ("beforeRead", "jsr-before-read", ItemReadListener.class),
AFTER_READ("afterRead", "jsr-after-read", ItemReadListener.class, Object.class),
AFTER_READ_ERROR("onReadError", "jsr-after-read-error", ItemReadListener.class, Exception.class),
BEFORE_PROCESS("beforeProcess", "jsr-before-process", ItemProcessListener.class, Object.class),
AFTER_PROCESS("afterProcess", "jsr-after-process", ItemProcessListener.class, Object.class, Object.class),
AFTER_PROCESS_ERROR("onProcessError", "jsr-after-process-error", ItemProcessListener.class, Object.class, Exception.class),
BEFORE_WRITE("beforeWrite", "jsr-before-write", ItemWriteListener.class, List.class),
AFTER_WRITE("afterWrite", "jsr-after-write", ItemWriteListener.class, List.class),
AFTER_WRITE_ERROR("onWriteError", "jsr-after-write-error", ItemWriteListener.class, List.class, Exception.class);
private final String methodName;
private final String propertyName;
private final Class<? extends javax.batch.api.listener.StepListener> listenerInterface;
private static final Map<String, JsrStepListenerMetaData> propertyMap;
private final Class<?>[] paramTypes;
@SuppressWarnings({"rawtypes", "unchecked"})
JsrStepListenerMetaData(String methodName, String propertyName, Class listenerInterface, Class<?>... paramTypes) {
this.propertyName = propertyName;
this.methodName = methodName;
this.listenerInterface = listenerInterface;
this.paramTypes = paramTypes;
}
static{
propertyMap = new HashMap<String, JsrStepListenerMetaData>();
for(JsrStepListenerMetaData metaData : values()){
propertyMap.put(metaData.getPropertyName(), metaData);
}
}
@Override
public String getMethodName() {
return methodName;
}
@Override
public Class<? extends Annotation> getAnnotation() {
return null;
}
@Override
public Class<?> getListenerInterface() {
return listenerInterface;
}
@Override
public Class<?>[] getParamTypes() {
return paramTypes;
}
@Override
public String getPropertyName() {
return propertyName;
}
/**
* Return the relevant meta data for the provided property name.
*
* @param propertyName
* @return meta data with supplied property name, null if none exists.
*/
public static JsrStepListenerMetaData fromPropertyName(String propertyName){
return propertyMap.get(propertyName);
}
}

View File

@@ -0,0 +1,47 @@
package org.springframework.batch.core.jsr;
import javax.batch.api.chunk.listener.SkipProcessListener;
import javax.batch.api.chunk.listener.SkipReadListener;
import javax.batch.api.chunk.listener.SkipWriteListener;
import org.springframework.batch.core.SkipListener;
public class SkipListenerAdapter<T, S> implements SkipListener<T, S> {
private final SkipReadListener skipReadDelegate;
private final SkipProcessListener skipProcessDelegate;
private final SkipWriteListener skipWriteDelegate;
public SkipListenerAdapter(SkipReadListener skipReadDelgate, SkipProcessListener skipProcessDelegate, SkipWriteListener skipWriteDelegate) {
this.skipReadDelegate = skipReadDelgate;
this.skipProcessDelegate = skipProcessDelegate;
this.skipWriteDelegate = skipWriteDelegate;
}
@Override
public void onSkipInRead(Throwable t) {
if(skipReadDelegate != null && t instanceof Exception) {
try {
skipReadDelegate.onSkipReadItem((Exception) t);
} catch (Exception e) {
//TODO: Do something here
}
}
}
@Override
public void onSkipInWrite(S item, Throwable t) {
//TODO: Awating information on the JSR's method
}
@Override
public void onSkipInProcess(T item, Throwable t) {
if(skipProcessDelegate != null && t instanceof Exception) {
try {
skipProcessDelegate.onSkipProcessItem(item, (Exception) t);
} catch (Exception e) {
//TODO: Do something here
}
}
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr;
import javax.batch.api.listener.StepListener;
import javax.batch.operations.BatchRuntimeException;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.util.Assert;
/**
* Wrapper class to adapt the {@link StepListener} to
* a {@link StepExecutionListener}.
*
* @author Michael Minella
* @since 3.0
*/
public class StepListenerAdapter implements StepExecutionListener {
private final StepListener delegate;
/**
* @param delegate
*/
public StepListenerAdapter(StepListener delegate) {
Assert.notNull(delegate, "A listener is required");
this.delegate = delegate;
}
@Override
public void beforeStep(StepExecution stepExecution) {
try {
delegate.beforeStep();
} catch (Exception e) {
throw new BatchRuntimeException(e);
}
}
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
try {
delegate.afterStep();
} catch (Exception e) {
throw new BatchRuntimeException(e);
}
return stepExecution.getExitStatus();
}
}

View File

@@ -64,6 +64,8 @@ public class BatchParser extends AbstractBeanDefinitionParser {
AbstractBeanDefinition beanDefintion = BeanDefinitionBuilder.genericBeanDefinition(curElement.getAttribute("class"))
.getBeanDefinition();
beanDefintion.setScope("step");
String beanName = curElement.getAttribute("id");
if(!registry.containsBeanDefinition(beanName)) {

View File

@@ -15,7 +15,6 @@
*/
package org.springframework.batch.core.jsr.configuration.xml;
import org.springframework.batch.core.configuration.xml.StepParserStepFactoryBean;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.RuntimeBeanReference;
@@ -40,8 +39,8 @@ public class BatchletParser extends AbstractSingleBeanDefinitionParser {
public void parseBatchlet(Element stepElement, Element taskletElement, AbstractBeanDefinition bd,
ParserContext parserContext) {
bd.setBeanClass(StepParserStepFactoryBean.class);
bd.setAttribute("isNamespaceStep", true);
bd.setBeanClass(StepFactoryBean.class);
bd.setAttribute("isNamespaceStep", false);
String taskletRef = taskletElement.getAttribute(REF);

View File

@@ -18,7 +18,6 @@ package org.springframework.batch.core.jsr.configuration.xml;
import java.util.List;
import org.springframework.batch.core.configuration.xml.ExceptionElementParser;
import org.springframework.batch.core.configuration.xml.StepParserStepFactoryBean;
import org.springframework.batch.core.step.item.ChunkOrientedTasklet;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
@@ -67,7 +66,8 @@ public class ChunkParser {
public void parse(Element element, AbstractBeanDefinition bd, ParserContext parserContext) {
MutablePropertyValues propertyValues = bd.getPropertyValues();
bd.setBeanClass(StepParserStepFactoryBean.class);
bd.setBeanClass(StepFactoryBean.class);
bd.setAttribute("isNamespaceStep", false);
propertyValues.addPropertyValue("hasChunkElement", Boolean.TRUE);

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.configuration.xml;
import javax.batch.api.listener.JobListener;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.configuration.xml.JobParserJobFactoryBean;
import org.springframework.batch.core.job.flow.FlowJob;
import org.springframework.batch.core.jsr.JobListenerAdapter;
import org.springframework.beans.factory.FactoryBean;
/**
* This {@link FactoryBean} is used by the JSR-352 namespace parser to create
* {@link FlowJob} objects. It stores all of the properties that are
* configurable on the &lt;job/&gt;.
*
* @author Michael Minella
* @since 3.0
*/
public class JobFactoryBean extends JobParserJobFactoryBean {
public JobFactoryBean(String name) {
super(name);
}
/**
* Addresses wrapping {@link JobListener} as needed to be used with
* the framework.
*
* @param jobListeners a list of all job listeners
*/
public void setJobExecutionListeners(Object[] jobListeners) {
if(jobListeners != null) {
JobExecutionListener[] listeners = new JobExecutionListener[jobListeners.length];
for(int i = 0; i < jobListeners.length; i++) {
Object curListener = jobListeners[i];
if(curListener instanceof JobExecutionListener) {
listeners[i] = (JobExecutionListener) curListener;
} else if(curListener instanceof JobListener){
listeners[i] = new JobListenerAdapter((JobListener) curListener);
}
}
super.setJobExecutionListeners(listeners);
}
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.configuration.xml;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.batch.api.listener.JobListener;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.jsr.JsrJobListenerMetaData;
import org.springframework.batch.core.listener.JobListenerMetaData;
import org.springframework.batch.core.listener.ListenerMetaData;
import org.springframework.beans.factory.FactoryBean;
/**
* This {@link FactoryBean} is used by the JSR-352 namespace parser to create
* {@link JobExecutionListener} objects.
*
* @author Michael Minella
* @since 3.0
*/
public class JobListenerFactoryBean extends org.springframework.batch.core.listener.JobListenerFactoryBean {
@Override
public Class<?> getObjectType() {
return JobListener.class;
}
@Override
protected ListenerMetaData[] getMetaDataValues() {
List<ListenerMetaData> values = new ArrayList<ListenerMetaData>();
Collections.addAll(values, JobListenerMetaData.values());
Collections.addAll(values, JsrJobListenerMetaData.values());
return values.toArray(new ListenerMetaData[0]);
}
@Override
protected ListenerMetaData getMetaDataFromPropertyName(String propertyName) {
ListenerMetaData result = JobListenerMetaData.fromPropertyName(propertyName);
if(result == null) {
result = JsrJobListenerMetaData.fromPropertyName(propertyName);
}
return result;
}
}

View File

@@ -16,8 +16,6 @@
package org.springframework.batch.core.jsr.configuration.xml;
import org.springframework.batch.core.configuration.xml.CoreNamespaceUtils;
import org.springframework.batch.core.configuration.xml.JobParserJobFactoryBean;
import org.springframework.batch.core.listener.JobListenerFactoryBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
@@ -38,8 +36,8 @@ public class JobParser extends AbstractSingleBeanDefinitionParser {
private static final String ID_ATTRIBUTE = "id";
@Override
protected Class<JobParserJobFactoryBean> getBeanClass(Element element) {
return JobParserJobFactoryBean.class;
protected Class<JobFactoryBean> getBeanClass(Element element) {
return JobFactoryBean.class;
}
@Override

View File

@@ -66,7 +66,6 @@ public class ListnerParser {
}
private ManagedList<AbstractBeanDefinition> parseListeners(Element element, ParserContext parserContext) {
List<Element> listenersElements = DomUtils.getChildElementsByTagName(element, LISTENERS_ELEMENT);
ManagedList<AbstractBeanDefinition> listeners = new ManagedList<AbstractBeanDefinition>();

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.configuration.xml;
import javax.batch.api.Batchlet;
import javax.batch.api.chunk.ItemProcessor;
import javax.batch.api.chunk.ItemReader;
import javax.batch.api.chunk.ItemWriter;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.xml.StepParserStepFactoryBean;
import org.springframework.batch.core.jsr.step.batchlet.BatchletAdapter;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.jsr.item.ItemProcessorAdapter;
import org.springframework.batch.jsr.item.ItemReaderAdapter;
import org.springframework.batch.jsr.item.ItemWriterAdapter;
import org.springframework.beans.factory.FactoryBean;
/**
* This {@link FactoryBean} is used by the JSR-352 namespace parser to create
* {@link Step} objects. It stores all of the properties that are
* configurable on the &lt;step/&gt;.
*
* @author Michael Minella
* @since 3.0
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class StepFactoryBean extends StepParserStepFactoryBean {
public void setTasklet(Object tasklet) {
if(tasklet instanceof Tasklet) {
super.setTasklet((Tasklet) tasklet);
} else if(tasklet instanceof Batchlet){
super.setTasklet(new BatchletAdapter((Batchlet) tasklet));
} else {
throw new IllegalArgumentException("The field tasklet must reference an implementation of " +
"either org.springframework.batch.core.step.tasklet.Tasklet or javax.batch.api.Batchlet");
}
}
public void setItemReader(Object itemReader) {
if(itemReader instanceof org.springframework.batch.item.ItemReader) {
super.setItemReader((org.springframework.batch.item.ItemReader) itemReader);
} else if(itemReader instanceof ItemReader){
super.setItemReader(new ItemReaderAdapter((ItemReader) itemReader));
} else {
throw new IllegalArgumentException("The definition of an item reader must implement either " +
"org.springframework.batch.item.ItemReader or javax.batch.api.chunk.ItemReader");
}
}
public void setItemProcessor(Object itemProcessor) {
if(itemProcessor instanceof org.springframework.batch.item.ItemProcessor) {
super.setItemProcessor((org.springframework.batch.item.ItemProcessor) itemProcessor);
} else if(itemProcessor instanceof ItemProcessor){
super.setItemProcessor(new ItemProcessorAdapter((ItemProcessor)itemProcessor));
} else {
throw new IllegalArgumentException("The definition of an item processor must implement either " +
"org.springframework.batch.item.ItemProcessor or javax.batch.api.chunk.ItemProcessor");
}
}
public void setItemWriter(Object itemWriter) {
if(itemWriter instanceof org.springframework.batch.item.ItemWriter) {
super.setItemWriter((org.springframework.batch.item.ItemWriter) itemWriter);
} else if(itemWriter instanceof ItemWriter){
super.setItemWriter(new ItemWriterAdapter((ItemWriter) itemWriter));
} else {
throw new IllegalArgumentException("The definition of an item writer must implement either " +
"org.springframework.batch.item.ItemWriter or javax.batch.api.chunk.ItemWriter");
}
}
}

View File

@@ -17,7 +17,6 @@ package org.springframework.batch.core.jsr.configuration.xml;
import java.util.Collection;
import org.springframework.batch.core.configuration.xml.StepParserStepFactoryBean;
import org.springframework.batch.core.job.flow.support.state.StepState;
import org.springframework.batch.core.listener.StepListenerFactoryBean;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -32,8 +31,7 @@ import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Parser for the &lt;step /&gt; element defined by JSR-352. Current state parses it
* into existing Spring Batch artifacts.
* Parser for the &lt;step /&gt; element defined by JSR-352.
*
* @author Michael Minella
* @since 3.0
@@ -46,15 +44,10 @@ public class StepParser extends AbstractSingleBeanDefinitionParser {
private static final String START_LIMIT_ATTRIBUTE = "start-limit";
private static final String SPLIT_ID_ATTRIBUTE = "id";
@Override
@SuppressWarnings("rawtypes")
protected Class<StepParserStepFactoryBean> getBeanClass(Element element) {
return StepParserStepFactoryBean.class;
}
protected Collection<BeanDefinition> parse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
BeanDefinitionBuilder defBuilder = BeanDefinitionBuilder.genericBeanDefinition();
AbstractBeanDefinition bd = defBuilder.getRawBeanDefinition();
bd.setBeanClass(StepFactoryBean.class);
BeanDefinitionBuilder stateBuilder = BeanDefinitionBuilder.genericBeanDefinition(StepState.class);

View File

@@ -0,0 +1,297 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.launch;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import javax.batch.operations.JobExecutionAlreadyCompleteException;
import javax.batch.operations.JobExecutionIsRunningException;
import javax.batch.operations.JobExecutionNotMostRecentException;
import javax.batch.operations.JobExecutionNotRunningException;
import javax.batch.operations.JobOperator;
import javax.batch.operations.JobRestartException;
import javax.batch.operations.JobSecurityException;
import javax.batch.operations.JobStartException;
import javax.batch.operations.NoSuchJobException;
import javax.batch.operations.NoSuchJobExecutionException;
import javax.batch.operations.NoSuchJobInstanceException;
import javax.batch.runtime.JobExecution;
import javax.batch.runtime.JobInstance;
import javax.batch.runtime.StepExecution;
import javax.sql.DataSource;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.explore.support.JobExplorerFactoryBean;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.launch.support.SimpleJobOperator;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
/**
* The entrance for executing batch jobs as defined by JSR-352. This class provides
* a base {@link ApplicationContext} that is the equivalent to the following:
*
* <pre class="code">
* &#064;Configuration
* &#064;EnableBatchProcessing
* public static class BaseConfiguration extends DefaultBatchConfigurer {
*
* &#064;Bean
* JobLauncher jobLauncher() { ... }
*
* &#064;Bean
* org.springframework.batch.core.launch.JobOperator batchJobOperator(JobExplorer jobExplorer,
* JobLauncher jobLauncher,
* JobRepository jobRepository,
* JobRegistry jobRegistry) { ... }
*
* &#064;Bean
* JobExplorerFactoryBean jobExplorer(final DataSource dataSource) { ... }
*
* &#064;Bean
* DataSource dataSource() { ... }
* }
* </pre>
*
* @author Michael Minella
* @since 3.0
* @see EnableBatchProcessing
*/
public class JsrJobOperator implements JobOperator {
private org.springframework.batch.core.launch.JobOperator batchJobOperator;
private JobExplorer jobExplorer;
private JobLauncher jobLauncher;
private GenericApplicationContext baseContext;
public JsrJobOperator() {
baseContext = new AnnotationConfigApplicationContext(BaseConfiguration.class);
jobLauncher = baseContext.getBean(JobLauncher.class);
jobExplorer = baseContext.getBean(JobExplorer.class);
batchJobOperator = baseContext.getBean(org.springframework.batch.core.launch.JobOperator.class);
try {
((SimpleJobLauncher) jobLauncher).afterPropertiesSet();
((SimpleJobOperator) batchJobOperator).afterPropertiesSet();
} catch (Exception e) {
}
}
@Override
public void abandon(long jobExecutionId) throws NoSuchJobExecutionException,
JobExecutionIsRunningException, JobSecurityException {
try {
batchJobOperator.abandon(jobExecutionId);
} catch (org.springframework.batch.core.launch.NoSuchJobExecutionException e) {
throw new NoSuchJobException(e);
} catch (JobExecutionAlreadyRunningException e) {
throw new JobExecutionIsRunningException(e);
}
}
@Override
public JobExecution getJobExecution(long executionId)
throws NoSuchJobExecutionException, JobSecurityException {
org.springframework.batch.core.JobExecution jobExecution = jobExplorer.getJobExecution(executionId);
if(jobExecution == null) {
throw new NoSuchJobException("No execution was found for executionId " + executionId);
}
return new org.springframework.batch.core.jsr.JobExecution(jobExecution);
}
@Override
public List<JobExecution> getJobExecutions(JobInstance jobInstance)
throws NoSuchJobInstanceException, JobSecurityException {
org.springframework.batch.core.JobInstance instance = (org.springframework.batch.core.JobInstance) jobInstance;
List<org.springframework.batch.core.JobExecution> batchExecutions = jobExplorer.getJobExecutions(instance);
if(batchExecutions == null) {
throw new NoSuchJobInstanceException("Unable to find JobInstance " + jobInstance.getInstanceId());
}
List<JobExecution> results = new ArrayList<JobExecution>(batchExecutions.size());
for (org.springframework.batch.core.JobExecution jobExecution : batchExecutions) {
results.add(new org.springframework.batch.core.jsr.JobExecution(jobExecution));
}
return results;
}
@Override
public JobInstance getJobInstance(long instanceId)
throws NoSuchJobExecutionException, JobSecurityException {
return jobExplorer.getJobInstance(instanceId);
}
@Override
public int getJobInstanceCount(String arg0) throws NoSuchJobException,
JobSecurityException {
return 0;
}
@Override
public List<JobInstance> getJobInstances(String arg0, int arg1, int arg2)
throws NoSuchJobException, JobSecurityException {
return null;
}
@Override
public Set<String> getJobNames() throws JobSecurityException {
return new HashSet<String>(jobExplorer.getJobNames());
}
@Override
public Properties getParameters(long executionId)
throws NoSuchJobExecutionException, JobSecurityException {
org.springframework.batch.core.JobExecution execution = jobExplorer.getJobExecution(executionId);
if(execution == null) {
throw new NoSuchJobExecutionException("Unable to find the JobExecution for id " + executionId);
}
return execution.getJobParameters().toProperties();
}
@Override
public List<Long> getRunningExecutions(String name)
throws NoSuchJobException, JobSecurityException {
Set<org.springframework.batch.core.JobExecution> findRunningJobExecutions = jobExplorer.findRunningJobExecutions(name);
List<Long> results = new ArrayList<Long>(findRunningJobExecutions.size());
for (org.springframework.batch.core.JobExecution jobExecution : findRunningJobExecutions) {
results.add(jobExecution.getId());
}
return results;
}
@Override
public List<StepExecution> getStepExecutions(long executionId)
throws NoSuchJobExecutionException, JobSecurityException {
org.springframework.batch.core.JobExecution execution = jobExplorer.getJobExecution(executionId);
if(execution == null) {
throw new NoSuchJobException("JobExecution with the id " + executionId + " was not found");
}
return null;
// return execution.getStepExecutions();
}
@Override
public long restart(long arg0, Properties arg1)
throws JobExecutionAlreadyCompleteException,
NoSuchJobExecutionException, JobExecutionNotMostRecentException,
JobRestartException, JobSecurityException {
return 0;
}
@Override
public long start(String jobName, Properties params) throws JobStartException,
JobSecurityException {
GenericXmlApplicationContext batchContext = new GenericXmlApplicationContext();
batchContext.setValidating(false);
batchContext.load(new String[] {"/META-INF/batch.xml", "META-INF/batch-jobs/" + jobName + ".xml"});
batchContext.setParent(baseContext);
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setBeanClass(AutowiredAnnotationBeanPostProcessor.class);
batchContext.registerBeanDefinition("postProcessor", bd);
batchContext.refresh();
Job job = batchContext.getBean(jobName, Job.class);
try {
return jobLauncher.run(job, new JobParametersBuilder(params).toJobParameters()).getId();
} catch (Exception e) {
e.printStackTrace();
throw new JobStartException(e);
}
}
@Override
public void stop(long executionId) throws NoSuchJobExecutionException,
JobExecutionNotRunningException, JobSecurityException {
try {
batchJobOperator.stop(executionId);
} catch (org.springframework.batch.core.launch.NoSuchJobExecutionException e) {
throw new NoSuchJobException(e);
} catch (org.springframework.batch.core.launch.JobExecutionNotRunningException e) {
throw new JobExecutionNotRunningException(e);
}
}
@Configuration
@EnableBatchProcessing
public static class BaseConfiguration extends DefaultBatchConfigurer {
@Bean
JobLauncher jobLauncher() {
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
jobLauncher.setJobRepository(super.getJobRepository());
try {
jobLauncher.afterPropertiesSet();
} catch (Exception e) {
e.printStackTrace();
}
return jobLauncher;
}
@Bean
org.springframework.batch.core.launch.JobOperator batchJobOperator(JobExplorer jobExplorer, JobLauncher jobLauncher, JobRepository jobRepository, JobRegistry jobRegistry) {
SimpleJobOperator operator = new SimpleJobOperator();
operator.setJobExplorer(jobExplorer);
operator.setJobLauncher(jobLauncher);
operator.setJobRepository(jobRepository);
operator.setJobRegistry(jobRegistry);
return operator;
}
@Bean
JobExplorerFactoryBean jobExplorer(final DataSource dataSource) {
return new JobExplorerFactoryBean() {{
setDataSource(dataSource);
}};
}
@Bean
DataSource dataSource() {
return new EmbeddedDatabaseBuilder().
addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql").
addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql").
build();
}
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.step.batchlet;
import javax.batch.api.Batchlet;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
//TODO: This needs to implement StoppableTasklet
public class BatchletAdapter implements Tasklet {
private Batchlet batchlet;
public BatchletAdapter(Batchlet batchlet) {
Assert.notNull(batchlet, "A Batchlet implementation is required");
this.batchlet = batchlet;
}
@Override
public RepeatStatus execute(StepContribution contribution,
ChunkContext chunkContext) throws Exception {
String exitStatus = batchlet.process();
if(StringUtils.hasText(exitStatus)) {
contribution.setExitStatus(new ExitStatus(exitStatus));
}
return RepeatStatus.FINISHED;
}
//TODO: Once the stoppable tasklet is implemented...this will be good to go
// @Override
// public void stop() {
// batchlet.stop();
// }
}

View File

@@ -25,12 +25,18 @@ import org.springframework.batch.core.JobInstance;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.jsr.JobContext;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.task.SyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;
import org.springframework.core.task.TaskRejectedException;
@@ -55,13 +61,14 @@ import org.springframework.util.Assert;
* @author Lucas Ward
* @Author Dave Syer
* @author Will Schipp
* @author Michael Minella
*
* @since 1.0
*
* @see JobRepository
* @see TaskExecutor
*/
public class SimpleJobLauncher implements JobLauncher, InitializingBean {
public class SimpleJobLauncher implements JobLauncher, InitializingBean, ApplicationContextAware {
protected static final Log logger = LogFactory.getLog(SimpleJobLauncher.class);
@@ -69,6 +76,8 @@ public class SimpleJobLauncher implements JobLauncher, InitializingBean {
private TaskExecutor taskExecutor;
private ApplicationContext context;
/**
* Run the provided job with the given {@link JobParameters}. The
* {@link JobParameters} will be used to determine if this is an execution
@@ -106,15 +115,15 @@ public class SimpleJobLauncher implements JobLauncher, InitializingBean {
for (StepExecution execution : lastExecution.getStepExecutions()) {
if (execution.getStatus() == BatchStatus.UNKNOWN) {
//throw
throw new JobRestartException("Step [" + execution.getStepName() + "] is of status UNKNOWN");
throw new JobRestartException("Step [" + execution.getStepName() + "] is of status UNKNOWN");
}//end if
}//end for
}//end for
}
// Check the validity of the parameters before doing creating anything
// in the repository...
job.getJobParametersValidator().validate(jobParameters);
/*
* There is a very small probability that a non-restartable job can be
* restarted, but only if another process or thread manages to launch
@@ -123,6 +132,11 @@ public class SimpleJobLauncher implements JobLauncher, InitializingBean {
*/
jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters);
if(context != null && context instanceof ConfigurableApplicationContext) {
ConfigurableListableBeanFactory factory = ((ConfigurableApplicationContext)context).getBeanFactory();
factory.registerSingleton(job.getName() + "_" + jobExecution.getId() + "_jobContext", new JobContext(jobExecution));
}
try {
taskExecutor.execute(new Runnable() {
@@ -196,4 +210,9 @@ public class SimpleJobLauncher implements JobLauncher, InitializingBean {
}
}
@Override
public void setApplicationContext(ApplicationContext context)
throws BeansException {
this.context = context;
}
}

View File

@@ -71,7 +71,6 @@ public abstract class AbstractListenerFactoryBean implements FactoryBean, Initia
@Override
public Object getObject() {
if (metaDataMap == null) {
metaDataMap = new HashMap<String, String>();
}
@@ -92,12 +91,10 @@ public abstract class AbstractListenerFactoryBean implements FactoryBean, Initia
Map<String, Set<MethodInvoker>> invokerMap = new HashMap<String, Set<MethodInvoker>>();
boolean synthetic = false;
for (Entry<String, String> entry : metaDataMap.entrySet()) {
final ListenerMetaData metaData = this.getMetaDataFromPropertyName(entry.getKey());
Set<MethodInvoker> invokers = new HashSet<MethodInvoker>();
MethodInvoker invoker;
invoker = getMethodInvokerForInterface(metaData.getListenerInterface(), metaData.getMethodName(), delegate,
metaData.getParamTypes());
if (invoker != null) {
@@ -110,10 +107,12 @@ public abstract class AbstractListenerFactoryBean implements FactoryBean, Initia
synthetic = true;
}
invoker = getMethodInvokerByAnnotation(metaData.getAnnotation(), delegate, metaData.getParamTypes());
if (invoker != null) {
invokers.add(invoker);
synthetic = true;
if(metaData.getAnnotation() != null) {
invoker = getMethodInvokerByAnnotation(metaData.getAnnotation(), delegate, metaData.getParamTypes());
if (invoker != null) {
invokers.add(invoker);
synthetic = true;
}
}
if (!invokers.isEmpty()) {

View File

@@ -15,7 +15,12 @@
*/
package org.springframework.batch.core.listener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.batch.core.StepListener;
import org.springframework.batch.core.jsr.JsrStepListenerMetaData;
/**
* This {@link AbstractListenerFactoryBean} implementation is used to create a
@@ -31,12 +36,22 @@ public class StepListenerFactoryBean extends AbstractListenerFactoryBean {
@Override
protected ListenerMetaData getMetaDataFromPropertyName(String propertyName) {
return StepListenerMetaData.fromPropertyName(propertyName);
ListenerMetaData metaData = StepListenerMetaData.fromPropertyName(propertyName);
if(metaData == null) {
metaData = JsrStepListenerMetaData.fromPropertyName(propertyName);
}
return metaData;
}
@Override
protected ListenerMetaData[] getMetaDataValues() {
return StepListenerMetaData.values();
List<ListenerMetaData> values = new ArrayList<ListenerMetaData>();
Collections.addAll(values, StepListenerMetaData.values());
Collections.addAll(values, JsrStepListenerMetaData.values());
return values.toArray(new ListenerMetaData[0]);
}
@Override

View File

@@ -0,0 +1 @@
org.springframework.batch.core.jsr.launch.JsrJobOperator

View File

@@ -2,5 +2,5 @@ http\://www.springframework.org/schema/batch/spring-batch.xsd=/org/springframewo
http\://www.springframework.org/schema/batch/spring-batch-2.2.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-2.2.xsd
http\://www.springframework.org/schema/batch/spring-batch-2.1.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-2.1.xsd
http\://www.springframework.org/schema/batch/spring-batch-2.0.xsd=/org/springframework/batch/core/configuration/xml/spring-batch-2.0.xsd
http\://xmlns.jcp.org/xml/ns/javaee=/org/springframework/batch/core/jsr/configuration/xml/jobXML_1_0.xsd
http\://xmlns.jcp.org/xml/ns/javaee=/org/springframework/batch/core/jsr/configuration/xml/batchXML_1_0.xsd
http\://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd=/org/springframework/batch/core/jsr/configuration/xml/jobXML_1_0.xsd
http\://xmlns.jcp.org/xml/ns/javaee/batchXML_1_0.xsd=/org/springframework/batch/core/jsr/configuration/xml/batchXML_1_0.xsd

View File

@@ -30,7 +30,7 @@ import org.junit.Test;
/**
* @author Dave Syer
*
*
*/
public class BatchStatusTests {
@@ -118,4 +118,15 @@ public class BatchStatusTests {
BatchStatus status = (BatchStatus) in.readObject();
assertEquals(BatchStatus.COMPLETED, status);
}
@Test
public void testJsrConversion() {
assertEquals(javax.batch.runtime.BatchStatus.ABANDONED, BatchStatus.ABANDONED.getBatchStatus());
assertEquals(javax.batch.runtime.BatchStatus.COMPLETED, BatchStatus.COMPLETED.getBatchStatus());
assertEquals(javax.batch.runtime.BatchStatus.STARTED, BatchStatus.STARTED.getBatchStatus());
assertEquals(javax.batch.runtime.BatchStatus.STARTING, BatchStatus.STARTING.getBatchStatus());
assertEquals(javax.batch.runtime.BatchStatus.STOPPED, BatchStatus.STOPPED.getBatchStatus());
assertEquals(javax.batch.runtime.BatchStatus.STOPPING, BatchStatus.STOPPING.getBatchStatus());
assertEquals(javax.batch.runtime.BatchStatus.FAILED, BatchStatus.FAILED.getBatchStatus());
}
}

View File

@@ -15,15 +15,17 @@
*/
package org.springframework.batch.core;
import junit.framework.TestCase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.springframework.batch.support.SerializationUtils;
/**
* @author dsyer
*
*/
public class JobInstanceTests extends TestCase {
public class JobInstanceTests {
private JobInstance instance = new JobInstance(new Long(11), "job");
@@ -31,15 +33,18 @@ public class JobInstanceTests extends TestCase {
* Test method for
* {@link org.springframework.batch.core.JobInstance#getJobName()}.
*/
@Test
public void testGetName() {
instance = new JobInstance(new Long(1), "foo");
assertEquals("foo", instance.getJobName());
}
@Test
public void testGetJob() {
assertEquals("job", instance.getJobName());
}
@Test
public void testCreateWithNulls() {
try {
new JobInstance(null, null);
@@ -52,6 +57,7 @@ public class JobInstanceTests extends TestCase {
assertEquals("testJob", instance.getJobName());
}
@Test
public void testSerialization() {
instance = new JobInstance(new Long(1), "jobName");
@@ -59,4 +65,9 @@ public class JobInstanceTests extends TestCase {
assertEquals(instance, SerializationUtils.deserialize(serialized));
}
@Test
public void testGetInstanceId() {
assertEquals(11, instance.getInstanceId());
}
}

View File

@@ -6,6 +6,7 @@ import static org.junit.Assert.assertFalse;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import org.junit.Test;
@@ -20,6 +21,30 @@ public class JobParametersBuilderTests {
Date date = new Date(System.currentTimeMillis());
@Test
public void testFromProperties() {
Properties props = new Properties();
props.put("SCHEDULE_DATE", date.toString());
props.put("LONG", "1");
props.put("STRING", "string value");
JobParametersBuilder builder = new JobParametersBuilder(props);
JobParameters parameters = builder.toJobParameters();
assertEquals(date.toString(), parameters.getString("SCHEDULE_DATE"));
assertEquals("1", parameters.getString("LONG").toString());
assertEquals("string value", parameters.getString("STRING"));
assertFalse(parameters.getParameters().get("SCHEDULE_DATE").isIdentifying());
assertFalse(parameters.getParameters().get("LONG").isIdentifying());
assertFalse(parameters.getParameters().get("STRING").isIdentifying());
}
@Test
public void testFromNullProperties() {
JobParametersBuilder builder = new JobParametersBuilder((Properties) null);
JobParameters parameters = builder.toJobParameters();
assertEquals(0, parameters.getParameters().size());
}
@Test
public void testNonIdentifyingParameters() {
parametersBuilder.addDate("SCHEDULE_DATE", date, false);

View File

@@ -10,6 +10,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import org.junit.Before;
import org.junit.Test;
@@ -212,4 +213,18 @@ public class JobParametersTests {
public void testDateReturnsNullWhenKeyDoesntExit(){
assertNull(new JobParameters().getDate("keythatdoesntexist"));
}
@Test
public void testToProperties() {
Properties results = parameters.toProperties();
assertEquals(results.get("string.key1"), "value1");
assertEquals(results.get("string.key2"), "value2");
assertEquals(results.get("long.key1"), "1");
assertEquals(results.get("long.key2"), "2");
assertEquals(results.get("double.key1"), "1.1");
assertEquals(results.get("double.key2"), "2.2");
assertEquals(results.get("date.key1"), String.valueOf(date1.getTime()));
assertEquals(results.get("date.key2"), String.valueOf(date2.getTime()));
}
}

View File

@@ -25,13 +25,13 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.aop.framework.Advised;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.core.StepListener;
import org.springframework.batch.core.job.AbstractJob;
import org.springframework.batch.core.listener.CompositeStepExecutionListener;
import org.springframework.batch.core.listener.StepExecutionListenerSupport;
@@ -446,7 +446,7 @@ public class StepParserTests {
Map<Class<? extends Throwable>, Boolean> retryableFound = getExceptionMap(fb, "retryableExceptionClasses");
ItemStream[] streamsFound = (ItemStream[]) ReflectionTestUtils.getField(fb, "streams");
RetryListener[] retryListenersFound = (RetryListener[]) ReflectionTestUtils.getField(fb, "retryListeners");
StepListener[] stepListenersFound = (StepListener[]) ReflectionTestUtils.getField(fb, "listeners");
Set<StepExecutionListener> stepListenersFound = (Set<StepExecutionListener>) ReflectionTestUtils.getField(fb, "stepExecutionListeners");
Collection<Class<? extends Throwable>> noRollbackFound = getExceptionList(fb, "noRollbackExceptionClasses");
assertSameMaps(skippable, skippableFound);
@@ -480,7 +480,7 @@ public class StepParserTests {
Map<Class<? extends Throwable>, Boolean> retryableFound = getExceptionMap(fb, "retryableExceptionClasses");
ItemStream[] streamsFound = (ItemStream[]) ReflectionTestUtils.getField(fb, "streams");
RetryListener[] retryListenersFound = (RetryListener[]) ReflectionTestUtils.getField(fb, "retryListeners");
StepListener[] stepListenersFound = (StepListener[]) ReflectionTestUtils.getField(fb, "listeners");
Set<StepExecutionListener> stepListenersFound = (Set<StepExecutionListener>) ReflectionTestUtils.getField(fb, "stepExecutionListeners");
Collection<Class<? extends Throwable>> noRollbackFound = getExceptionList(fb, "noRollbackExceptionClasses");
assertSameMaps(skippable, skippableFound);
@@ -491,6 +491,7 @@ public class StepParserTests {
assertSameCollections(noRollback, noRollbackFound);
}
@SuppressWarnings("unchecked")
@Test
public void testStepWithListsOverrideWithEmpty() throws Exception {
ApplicationContext ctx = stepParserParentAttributeTestsCtx;
@@ -502,7 +503,7 @@ public class StepParserTests {
assertEquals(1, getExceptionMap(fb, "retryableExceptionClasses").size());
assertEquals(0, ((ItemStream[]) ReflectionTestUtils.getField(fb, "streams")).length);
assertEquals(0, ((RetryListener[]) ReflectionTestUtils.getField(fb, "retryListeners")).length);
assertEquals(0, ((StepListener[]) ReflectionTestUtils.getField(fb, "listeners")).length);
assertEquals(0, ((Set<StepExecutionListener>) ReflectionTestUtils.getField(fb, "stepExecutionListeners")).size());
assertEquals(0, getExceptionList(fb, "noRollbackExceptionClasses").size());
}

View File

@@ -19,13 +19,15 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepListener;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.item.ItemStream;
import org.springframework.beans.factory.annotation.Autowired;
@@ -42,36 +44,37 @@ import org.springframework.test.util.ReflectionTestUtils;
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class StepWithBasicProcessTaskJobParserTests {
@Autowired
private Job job;
@Autowired
private JobRepository jobRepository;
@Autowired
private TestReader reader;
@Autowired
@Qualifier("listener")
private TestListener listener;
@Autowired
private TestProcessor processor;
@Autowired
private TestWriter writer;
@Autowired
private StepParserStepFactoryBean<?,?> factory;
@SuppressWarnings("unchecked")
@Test
public void testStepWithTask() throws Exception {
assertNotNull(job);
Object ci = ReflectionTestUtils.getField(factory, "commitInterval");
assertEquals("wrong chunk-size:", 10, ci);
Object listeners = ReflectionTestUtils.getField(factory, "listeners");
assertEquals("wrong number of listeners:", 2, ((StepListener[])listeners).length);
Object listeners = ReflectionTestUtils.getField(factory, "stepExecutionListeners");
assertEquals("wrong number of listeners:", 2, ((Set<StepExecutionListener>)listeners).size());
Object streams = ReflectionTestUtils.getField(factory, "streams");
assertEquals("wrong number of streams:", 1, ((ItemStream[])streams).length);
JobExecution jobExecution = jobRepository.createJobExecution(job.getName(), new JobParameters());

View File

@@ -19,13 +19,15 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepListener;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.item.ItemStream;
import org.springframework.beans.factory.annotation.Autowired;
@@ -40,7 +42,7 @@ import org.springframework.transaction.annotation.Propagation;
/**
* @author Thomas Risberg
*
*
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@@ -71,6 +73,7 @@ public class StepWithFaultTolerantProcessTaskJobParserTests {
@Autowired
private StepParserStepFactoryBean<?, ?> factory;
@SuppressWarnings("unchecked")
@Test
public void testStepWithTask() throws Exception {
assertNotNull(job);
@@ -91,8 +94,8 @@ public class StepWithFaultTolerantProcessTaskJobParserTests {
assertEquals("wrong reader-transactional-queue:", true, txq);
Object te = ReflectionTestUtils.getField(factory, "taskExecutor");
assertEquals("wrong task-executor:", ConcurrentTaskExecutor.class, te.getClass());
Object listeners = ReflectionTestUtils.getField(factory, "listeners");
assertEquals("wrong number of listeners:", 2, ((StepListener[]) listeners).length);
Object listeners = ReflectionTestUtils.getField(factory, "stepExecutionListeners");
assertEquals("wrong number of listeners:", 2, ((Set<StepExecutionListener>) listeners).size());
Object retryListeners = ReflectionTestUtils.getField(factory, "retryListeners");
assertEquals("wrong number of retry-listeners:", 2, ((RetryListener[]) retryListeners).length);
Object streams = ReflectionTestUtils.getField(factory, "streams");

View File

@@ -0,0 +1,82 @@
package org.springframework.batch.core.jsr;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import javax.batch.api.chunk.listener.ChunkListener;
import javax.batch.operations.BatchRuntimeException;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.batch.core.scope.context.ChunkContext;
public class ChunkListenerAdapterTests {
private ChunkListenerAdapter adapter;
@Mock
private ChunkListener delegate;
@Mock
private ChunkContext context;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
adapter = new ChunkListenerAdapter(delegate);
}
@Test(expected=IllegalArgumentException.class)
public void testNullDelegate() {
adapter = new ChunkListenerAdapter(null);
}
@Test
public void testBeforeChunk() throws Exception {
adapter.beforeChunk(null);
verify(delegate).beforeChunk();
}
@Test(expected=BatchRuntimeException.class)
public void testBeforeChunkException() throws Exception {
doThrow(new Exception("This is expected")).when(delegate).beforeChunk();
adapter.beforeChunk(null);
}
@Test
public void testAfterChunk() throws Exception {
adapter.afterChunk(null);
verify(delegate).afterChunk();
}
@Test(expected=BatchRuntimeException.class)
public void testAfterChunkException() throws Exception {
doThrow(new Exception("This is expected")).when(delegate).afterChunk();
adapter.afterChunk(null);
}
@Test(expected=BatchRuntimeException.class)
public void testAfterChunkErrorNullContext() throws Exception {
adapter.afterChunkError(null);
}
@Test(expected=BatchRuntimeException.class)
public void testAfterChunkErrorException() throws Exception {
doThrow(new Exception("This is expected")).when(delegate).afterChunk();
adapter.afterChunk(null);
}
@Test
public void testAfterChunkError() throws Exception {
Exception exception = new Exception("This was expected");
when(context.getAttribute(org.springframework.batch.core.ChunkListener.ROLLBACK_EXCEPTION_KEY)).thenReturn(exception);
adapter.afterChunkError(context);
verify(delegate).onError(exception);
}
}

View File

@@ -0,0 +1,91 @@
package org.springframework.batch.core.jsr;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import javax.batch.api.chunk.listener.ItemProcessListener;
import javax.batch.operations.BatchRuntimeException;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class ItemProcessListenerAdapterTests {
private ItemProcessListenerAdapter<String, String> adapter;
@Mock
private ItemProcessListener delegate;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
adapter = new ItemProcessListenerAdapter<String, String>(delegate);
}
@Test(expected=IllegalArgumentException.class)
public void testNullCreation() {
adapter = new ItemProcessListenerAdapter<String, String>(null);
}
@Test
public void testBeforeProcess() throws Exception {
String item = "This is my item";
adapter.beforeProcess(item);
verify(delegate).beforeProcess(item);
}
@Test(expected=BatchRuntimeException.class)
public void testBeforeProcessException() throws Exception {
Exception exception = new Exception("This should occur");
String item = "This is the bad item";
doThrow(exception).when(delegate).beforeProcess(item);
adapter.beforeProcess(item);
}
@Test
public void testAfterProcess() throws Exception {
String item = "This is the input";
String result = "This is the output";
adapter.afterProcess(item, result);
verify(delegate).afterProcess(item, result);
}
@Test(expected=BatchRuntimeException.class)
public void testAfterProcessException() throws Exception {
String item = "This is the input";
String result = "This is the output";
Exception exception = new Exception("This is expected");
doThrow(exception).when(delegate).afterProcess(item, result);
adapter.afterProcess(item, result);
}
@Test
public void testOnProcessError() throws Exception {
String item = "This is the input";
Exception cause = new Exception("This was the cause");
adapter.onProcessError(item, cause);
verify(delegate).onProcessError(item, cause);
}
@Test(expected=BatchRuntimeException.class)
public void testOnProcessErrorException() throws Exception {
String item = "This is the input";
Exception cause = new Exception("This was the cause");
Exception exception = new Exception("This is expected");
doThrow(exception).when(delegate).onProcessError(item, cause);
adapter.onProcessError(item, cause);
}
}

View File

@@ -0,0 +1,82 @@
package org.springframework.batch.core.jsr;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import javax.batch.api.chunk.listener.ItemReadListener;
import javax.batch.operations.BatchRuntimeException;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class ItemReadListenerAdapterTests {
private ItemReadListenerAdapter<String> adapter;
@Mock
private ItemReadListener delegate;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
adapter = new ItemReadListenerAdapter<String>(delegate);
}
@Test(expected=IllegalArgumentException.class)
public void testNullDelegate() {
adapter = new ItemReadListenerAdapter<String>(null);
}
@Test
public void testBeforeRead() throws Exception {
adapter.beforeRead();
verify(delegate).beforeRead();
}
@Test(expected=BatchRuntimeException.class)
public void testBeforeReadException() throws Exception {
doThrow(new Exception("Should occur")).when(delegate).beforeRead();
adapter.beforeRead();
}
@Test
public void testAfterRead() throws Exception {
String item = "item";
adapter.afterRead(item);
verify(delegate).afterRead(item);
}
@Test(expected=BatchRuntimeException.class)
public void testAfterReadException() throws Exception {
String item = "item";
Exception expected = new Exception("expected");
doThrow(expected).when(delegate).afterRead(item);
adapter.afterRead(item);
}
@Test
public void testOnReadError() throws Exception {
Exception cause = new Exception ("cause");
adapter.onReadError(cause);
verify(delegate).onReadError(cause);
}
@Test(expected=BatchRuntimeException.class)
public void testOnReadErrorException() throws Exception {
Exception cause = new Exception ("cause");
Exception result = new Exception("result");
doThrow(result).when(delegate).onReadError(cause);
adapter.onReadError(cause);
}
}

View File

@@ -0,0 +1,81 @@
package org.springframework.batch.core.jsr;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import java.util.ArrayList;
import java.util.List;
import javax.batch.api.chunk.listener.ItemWriteListener;
import javax.batch.operations.BatchRuntimeException;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SuppressWarnings({"rawtypes", "unchecked"})
public class ItemWriteListenerAdapterTests {
private ItemWriteListenerAdapter<String> adapter;
@Mock
private ItemWriteListener delegate;
private List items = new ArrayList();
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
adapter = new ItemWriteListenerAdapter<String>(delegate);
}
@Test(expected=IllegalArgumentException.class)
public void testCreateWithNull() {
adapter = new ItemWriteListenerAdapter<String>(null);
}
@Test
public void testBeforeWrite() throws Exception {
adapter.beforeWrite(items);
verify(delegate).beforeWrite(items);
}
@Test(expected=BatchRuntimeException.class)
public void testBeforeTestWriteException() throws Exception {
doThrow(new Exception("expected")).when(delegate).beforeWrite(items);
adapter.beforeWrite(items);
}
@Test
public void testAfterWrite() throws Exception {
adapter.afterWrite(items);
verify(delegate).afterWrite(items);
}
@Test(expected=BatchRuntimeException.class)
public void testAfterTestWriteException() throws Exception {
doThrow(new Exception("expected")).when(delegate).afterWrite(items);
adapter.afterWrite(items);
}
@Test
public void testOnWriteError() throws Exception {
Exception cause = new Exception("cause");
adapter.onWriteError(cause, items);
verify(delegate).onWriteError(items, cause);
}
@Test(expected=BatchRuntimeException.class)
public void testOnWriteErrorException() throws Exception {
Exception cause = new Exception("cause");
doThrow(new Exception("expected")).when(delegate).onWriteError(items, cause);
adapter.onWriteError(cause, items);
}
}

View File

@@ -0,0 +1,97 @@
package org.springframework.batch.core.jsr;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Properties;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobInstance;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
public class JobContextTests {
private JobContext context;
@Mock
private JobExecution execution;
@Mock
private JobInstance instance;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
context = new JobContext(execution);
when(execution.getJobInstance()).thenReturn(instance);
}
@Test(expected=IllegalArgumentException.class)
public void testCreateWithNull() {
context = new JobContext(null);
}
@Test
public void testGetJobName() {
when(instance.getJobName()).thenReturn("jobName");
assertEquals("jobName", context.getJobName());
}
@Test
public void testTransientUserData() {
context.setTransientUserData("This is my data");
assertEquals("This is my data", context.getTransientUserData());
}
@Test
public void testGetInstanceId() {
when(instance.getId()).thenReturn(5L);
assertEquals(5L, context.getInstanceId());
}
@Test
public void testGetExecutionId() {
when(execution.getId()).thenReturn(5L);
assertEquals(5L, context.getExecutionId());
}
@Test
public void testGetProperties() {
JobParameters params = new JobParametersBuilder()
.addString("key1", "value1")
.toJobParameters();
when(execution.getJobParameters()).thenReturn(params);
Properties props = context.getProperties();
assertEquals("value1", props.get("key1"));
}
@Test
public void testGetBatchStatus() {
when(execution.getStatus()).thenReturn(BatchStatus.COMPLETED);
assertEquals(javax.batch.runtime.BatchStatus.COMPLETED, context.getBatchStatus());
}
@Test
public void testExitStatus() {
when(execution.getExitStatus()).thenReturn(new ExitStatus("exit"));
assertEquals("exit", context.getExitStatus());
context.setExitStatus("my exit status");
verify(execution).setExitStatus(new ExitStatus("my exit status"));
}
}

View File

@@ -0,0 +1,60 @@
package org.springframework.batch.core.jsr;
import static org.junit.Assert.assertEquals;
import java.util.Date;
import java.util.Properties;
import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobInstance;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
public class JobExecutionTests {
private JobExecution adapter;
@Before
public void setUp() throws Exception {
JobInstance instance = new JobInstance(2L, "job name");
JobParameters params = new JobParametersBuilder().addString("key1", "value1").toJobParameters();
org.springframework.batch.core.JobExecution execution = new org.springframework.batch.core.JobExecution(instance, params);
execution.setId(5L);
execution.setCreateTime(new Date(0));
execution.setEndTime(new Date(999999999l));
execution.setExitStatus(new ExitStatus("exit status"));
execution.setLastUpdated(new Date(12345));
execution.setStartTime(new Date(98765));
execution.setStatus(BatchStatus.FAILED);
execution.setVersion(21);
adapter = new JobExecution(execution);
}
@Test(expected=IllegalArgumentException.class)
public void testCreateWithNull() {
adapter = new JobExecution(null);
}
@Test
public void testGetBasicValues() {
assertEquals(javax.batch.runtime.BatchStatus.FAILED, adapter.getBatchStatus());
assertEquals(new Date(0), adapter.getCreateTime());
assertEquals(new Date(999999999l), adapter.getEndTime());
assertEquals(5L, adapter.getExecutionId());
assertEquals("exit status", adapter.getExitStatus());
assertEquals("job name", adapter.getJobName());
assertEquals(new Date(12345), adapter.getLastUpdatedTime());
assertEquals(new Date(98765), adapter.getStartTime());
Properties props = adapter.getJobParameters();
assertEquals("value1", props.get("key1"));
}
}

View File

@@ -0,0 +1,58 @@
package org.springframework.batch.core.jsr;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import javax.batch.api.listener.JobListener;
import javax.batch.operations.BatchRuntimeException;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class JobListenerAdapterTests {
private JobListenerAdapter adapter;
@Mock
private JobListener delegate;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
adapter = new JobListenerAdapter(delegate);
}
@Test(expected=IllegalArgumentException.class)
public void testCreateWithNull() {
adapter = new JobListenerAdapter(null);
}
@Test
public void testBeforeJob() throws Exception {
adapter.beforeJob(null);
verify(delegate).beforeJob();
}
@Test(expected=BatchRuntimeException.class)
public void testBeforeJobException() throws Exception {
doThrow(new Exception("expected")).when(delegate).beforeJob();
adapter.beforeJob(null);
}
@Test
public void testAfterJob() throws Exception {
adapter.afterJob(null);
verify(delegate).afterJob();
}
@Test(expected=BatchRuntimeException.class)
public void testAfterJobException() throws Exception {
doThrow(new Exception("expected")).when(delegate).afterJob();
adapter.afterJob(null);
}
}

View File

@@ -0,0 +1,68 @@
package org.springframework.batch.core.jsr;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import javax.batch.api.listener.StepListener;
import javax.batch.operations.BatchRuntimeException;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepExecution;
public class StepListenerAdapterTests {
private StepListenerAdapter adapter;
@Mock
private StepListener delegate;
@Mock
private StepExecution execution;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
adapter = new StepListenerAdapter(delegate);
}
@Test(expected=IllegalArgumentException.class)
public void testCreateWithNull() {
adapter = new StepListenerAdapter(null);
}
@Test
public void testBeforeStep() throws Exception {
adapter.beforeStep(null);
verify(delegate).beforeStep();
}
@Test(expected=BatchRuntimeException.class)
public void testBeforeStepException() throws Exception {
doThrow(new Exception("expected")).when(delegate).beforeStep();
adapter.beforeStep(null);
}
@Test
public void testAfterStep() throws Exception {
ExitStatus exitStatus = new ExitStatus("complete");
when(execution.getExitStatus()).thenReturn(exitStatus);
assertEquals(exitStatus, adapter.afterStep(execution));
verify(delegate).afterStep();
}
@Test(expected=BatchRuntimeException.class)
public void testAfterStepException() throws Exception {
doThrow(new Exception("expected")).when(delegate).afterStep();
adapter.afterStep(null);
}
}

View File

@@ -1,36 +1,76 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import javax.sql.DataSource;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.xml.DummyItemProcessor;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.support.PassThroughItemProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
@ContextConfiguration(value="batch.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class BatchParserTests {
@Autowired
@Qualifier("itemProcessor")
@SuppressWarnings("rawtypes")
private ItemProcessor itemProcessor;
private ApplicationContext baseContext;
@Test
public void testRoseyScenario() {
assertNotNull(itemProcessor);
assertTrue(itemProcessor instanceof PassThroughItemProcessor);
@Before
public void setUp() {
baseContext = new AnnotationConfigApplicationContext(BaseConfiguration.class);
}
@Test
@Ignore
public void testRoseyScenario() {
GenericXmlApplicationContext batchContext = new GenericXmlApplicationContext();
batchContext.setValidating(false);
batchContext.load(new String[] {"classpath:/org/springframework/batch/core/jsr/configuration/xml/batch.xml"});
System.out.println("baseContext = " + baseContext);
batchContext.setParent(baseContext);
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setBeanClass(AutowiredAnnotationBeanPostProcessor.class);
batchContext.registerBeanDefinition("postProcessor", bd);
batchContext.refresh();
Object itemProcessor = batchContext.getBean(ItemProcessor.class);
assertNotNull(itemProcessor);
assertTrue(itemProcessor instanceof PassThroughItemProcessor);
batchContext.close();
}
@Test
@Ignore
@SuppressWarnings({"resource", "rawtypes"})
public void testOverrideBeansFirst() {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("/org/springframework/batch/core/jsr/configuration/xml/override_batch.xml",
@@ -43,6 +83,7 @@ public class BatchParserTests {
}
@Test
@Ignore
@SuppressWarnings({"resource", "rawtypes"})
public void testOverrideBeansLast() {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("/org/springframework/batch/core/jsr/configuration/xml/batch.xml",
@@ -53,4 +94,17 @@ public class BatchParserTests {
assertNotNull(processor);
assertTrue(processor instanceof DummyItemProcessor);
}
@Configuration
@EnableBatchProcessing
public static class BaseConfiguration extends DefaultBatchConfigurer {
@Bean
DataSource dataSource() {
return new EmbeddedDatabaseBuilder().
addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql").
addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql").
build();
}
}
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import java.util.List;
import javax.batch.api.chunk.AbstractItemWriter;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ChunkListener;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class ChunkListenerParsingTests {
@Autowired
public Job job;
@Autowired
public JobLauncher jobLauncher;
@Autowired
public SpringChunkListener springChunkListener;
@Autowired
public JsrChunkListener jsrChunkListener;
@Test
public void test() throws Exception {
JobExecution execution = jobLauncher.run(job, new JobParameters());
assertEquals(BatchStatus.FAILED, execution.getStatus());
assertEquals(3, execution.getStepExecutions().size());
assertEquals(4, springChunkListener.beforeChunkCount);
assertEquals(3, springChunkListener.afterChunkCount);
assertEquals(4, jsrChunkListener.beforeChunkCount);
assertEquals(3, jsrChunkListener.afterChunkCount);
assertEquals(1, springChunkListener.afterChunkErrorCount);
assertEquals(1, jsrChunkListener.afterChunkErrorCount);
}
public static class SpringChunkListener implements ChunkListener {
protected int beforeChunkCount = 0;
protected int afterChunkCount = 0;
protected int afterChunkErrorCount = 0;
@Override
public void beforeChunk(ChunkContext context) {
beforeChunkCount++;
}
@Override
public void afterChunk(ChunkContext context) {
afterChunkCount++;
}
@Override
public void afterChunkError(ChunkContext context) {
afterChunkErrorCount++;
}
}
public static class JsrChunkListener implements javax.batch.api.chunk.listener.ChunkListener {
protected int beforeChunkCount = 0;
protected int afterChunkCount = 0;
protected int afterChunkErrorCount = 0;
@Override
public void beforeChunk() throws Exception {
beforeChunkCount++;
}
@Override
public void onError(Exception ex) throws Exception {
afterChunkErrorCount++;
}
@Override
public void afterChunk() throws Exception {
afterChunkCount++;
}
}
public static class ErrorThrowingItemWriter extends AbstractItemWriter {
@Override
public void writeItems(List<Object> items) throws Exception {
throw new Exception("This should cause the rollback");
}
}
}

View File

@@ -0,0 +1,14 @@
package org.springframework.batch.core.jsr.configuration.xml;
import javax.batch.api.chunk.ItemProcessor;
public class CountingItemProcessor implements ItemProcessor {
protected int count = 0;
@Override
public Object processItem(Object item) throws Exception {
count++;
return item;
}
}

View File

@@ -1,7 +1,23 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
@@ -16,7 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration({"DecisionParsingTests-context.xml", "jsr-base-context.xml"})
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class DecisionParsingTests {
@@ -27,6 +43,7 @@ public class DecisionParsingTests {
public JobLauncher jobLauncher;
@Test
@Ignore
public void test() throws Exception {
JobExecution execution = jobLauncher.run(job, new JobParameters());
assertEquals(BatchStatus.COMPLETED, execution.getStatus());

View File

@@ -1,3 +1,18 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
@@ -6,6 +21,7 @@ import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.List;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
@@ -19,7 +35,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration({"ExceptionHandlingParsingTests-context.xml", "jsr-base-context.xml"})
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class ExceptionHandlingParsingTests {
@@ -30,6 +46,7 @@ public class ExceptionHandlingParsingTests {
public JobLauncher jobLauncher;
@Test
@Ignore
public void testSkippable() throws Exception {
JobExecution execution1 = jobLauncher.run(job, new JobParametersBuilder().addLong("run", 1l).toJobParameters());
assertEquals(BatchStatus.FAILED, execution1.getStatus());

View File

@@ -0,0 +1,188 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ItemProcessListener;
import org.springframework.batch.core.ItemReadListener;
import org.springframework.batch.core.ItemWriteListener;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class ItemListenerParsingTests {
@Autowired
public Job job;
@Autowired
public JobLauncher jobLauncher;
@Autowired
public SpringItemListener springListener;
@Autowired
public JsrItemListener jsrListener;
@Test
public void test() throws Exception {
JobExecution execution = jobLauncher.run(job, new JobParameters());
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
assertEquals(3, execution.getStepExecutions().size());
assertEquals(6, springListener.beforeReadCount);
assertEquals(4, springListener.afterReadCount);
assertEquals(4, springListener.beforeProcessCount);
assertEquals(4, springListener.afterProcessCount);
assertEquals(2, springListener.beforeWriteCount);
assertEquals(2, springListener.afterWriteCount);
assertEquals(6, jsrListener.beforeReadCount);
assertEquals(4, jsrListener.afterReadCount);
assertEquals(4, jsrListener.beforeProcessCount);
assertEquals(4, jsrListener.afterProcessCount);
assertEquals(2, jsrListener.beforeWriteCount);
assertEquals(2, jsrListener.afterWriteCount);
}
@SuppressWarnings("rawtypes")
public static class SpringItemListener implements ItemReadListener, ItemProcessListener, ItemWriteListener {
protected int beforeReadCount = 0;
protected int afterReadCount = 0;
protected int onReadErrorCount = 0;
protected int beforeProcessCount = 0;
protected int afterProcessCount = 0;
protected int onProcessErrorCount = 0;
protected int beforeWriteCount = 0;
protected int afterWriteCount = 0;
protected int onWriteErrorCount = 0;
@Override
public void beforeRead() {
beforeReadCount++;
}
@Override
public void afterRead(Object item) {
afterReadCount++;
}
@Override
public void onReadError(Exception ex) {
onReadErrorCount++;
}
@Override
public void beforeWrite(List items) {
beforeWriteCount++;
}
@Override
public void afterWrite(List items) {
afterWriteCount++;
}
@Override
public void onWriteError(Exception exception, List items) {
onWriteErrorCount++;
}
@Override
public void beforeProcess(Object item) {
beforeProcessCount++;
}
@Override
public void afterProcess(Object item, Object result) {
afterProcessCount++;
}
@Override
public void onProcessError(Object item, Exception e) {
onProcessErrorCount++;
}
}
public static class JsrItemListener implements javax.batch.api.chunk.listener.ItemReadListener, javax.batch.api.chunk.listener.ItemProcessListener, javax.batch.api.chunk.listener.ItemWriteListener {
protected int beforeReadCount = 0;
protected int afterReadCount = 0;
protected int onReadErrorCount = 0;
protected int beforeProcessCount = 0;
protected int afterProcessCount = 0;
protected int onProcessErrorCount = 0;
protected int beforeWriteCount = 0;
protected int afterWriteCount = 0;
protected int onWriteErrorCount = 0;
@Override
public void beforeWrite(List<Object> items) throws Exception {
beforeWriteCount++;
}
@Override
public void afterWrite(List<Object> items) throws Exception {
afterWriteCount++;
}
@Override
public void onWriteError(List<Object> items, Exception ex)
throws Exception {
onWriteErrorCount++;
}
@Override
public void beforeProcess(Object item) throws Exception {
beforeProcessCount++;
}
@Override
public void afterProcess(Object item, Object result) throws Exception {
afterProcessCount++;
}
@Override
public void onProcessError(Object item, Exception ex) throws Exception {
onProcessErrorCount++;
}
@Override
public void beforeRead() throws Exception {
beforeReadCount++;
}
@Override
public void afterRead(Object item) throws Exception {
afterReadCount++;
}
@Override
public void onReadError(Exception ex) throws Exception {
onReadErrorCount++;
}
}
}

View File

@@ -1,3 +1,18 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
@@ -5,6 +20,7 @@ import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.List;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
@@ -23,7 +39,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration({"ItemSkipParsingTests-context.xml", "jsr-base-context.xml"})
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class ItemSkipParsingTests {
@@ -37,6 +53,7 @@ public class ItemSkipParsingTests {
public TestSkipListener skipListener;
@Test
@Ignore
public void test() throws Exception {
// Read skip and fail
JobExecution execution = jobLauncher.run(job, new JobParametersBuilder().toJobParameters());

View File

@@ -1,8 +1,25 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import javax.batch.api.listener.JobListener;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
@@ -15,7 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration({"JobListenerParsingTests-context.xml", "jsr-base-context.xml"})
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class JobListenerParsingTests {
@@ -26,7 +43,10 @@ public class JobListenerParsingTests {
public JobLauncher jobLauncher;
@Autowired
public JobListener listener;
public SpringJobListener springListener;
@Autowired
public JsrJobListener jsrListener;
@Test
public void test() throws Exception {
@@ -36,11 +56,13 @@ public class JobListenerParsingTests {
JobExecution execution = jobLauncher.run(job, new JobParameters());
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
assertEquals(2, execution.getStepExecutions().size());
assertEquals(1, listener.countAfterJob);
assertEquals(1, listener.countBeforeJob);
assertEquals(1, springListener.countAfterJob);
assertEquals(1, springListener.countBeforeJob);
assertEquals(1, jsrListener.countAfterJob);
assertEquals(1, jsrListener.countBeforeJob);
}
public static class JobListener implements JobExecutionListener {
public static class SpringJobListener implements JobExecutionListener {
protected int countBeforeJob = 0;
protected int countAfterJob = 0;
@@ -55,4 +77,20 @@ public class JobListenerParsingTests {
countAfterJob++;
}
}
public static class JsrJobListener implements JobListener {
protected int countBeforeJob = 0;
protected int countAfterJob = 0;
@Override
public void afterJob() throws Exception {
countBeforeJob++;
}
@Override
public void beforeJob() throws Exception {
countAfterJob++;
}
}
}

View File

@@ -1,3 +1,18 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
@@ -11,7 +26,6 @@ import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.repeat.CompletionPolicy;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.RepeatStatus;
@@ -19,7 +33,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration({"SimpleItemBasedJobParsingTests-context.xml", "jsr-base-context.xml"})
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class SimpleItemBasedJobParsingTests {
@@ -52,16 +66,6 @@ public class SimpleItemBasedJobParsingTests {
assertEquals(3, policy.counter);
}
public static class CountingItemProcessor implements ItemProcessor<String, String>{
protected int count = 0;
@Override
public String process(String item) throws Exception {
count++;
return item;
}
}
public static class CountingCompletionPolicy implements CompletionPolicy {
protected int counter;

View File

@@ -3,6 +3,8 @@ package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import javax.batch.api.Batchlet;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
@@ -16,7 +18,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration({"SimpleJobParsingTests-context.xml", "jsr-base-context.xml"})
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class SimpleJobParsingTests {
@@ -38,6 +40,9 @@ public class SimpleJobParsingTests {
@Autowired
public JobLauncher jobLauncher;
@Autowired
public Batchlet batchlet;
@Test
public void test() throws Exception {
assertNotNull(job);
@@ -48,6 +53,7 @@ public class SimpleJobParsingTests {
assertEquals("step2", step2.getName());
assertNotNull(step3);
assertEquals("step3", step3.getName());
assertNotNull(batchlet);
JobExecution execution = jobLauncher.run(job, new JobParameters());
assertEquals(BatchStatus.COMPLETED, execution.getStatus());

View File

@@ -1,9 +1,25 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -33,6 +49,7 @@ public class SplitParsingTests {
public ExpectedException expectedException = ExpectedException.none();
@Test
@Ignore
public void test() throws Exception {
JobExecution execution = jobLauncher.run(job, new JobParameters());
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
@@ -40,6 +57,7 @@ public class SplitParsingTests {
}
@Test
@Ignore
public void testOneFlowInSplit() {
try {
new ClassPathXmlApplicationContext("/org/springframework/batch/core/jsr/configuration/xml/invalid-split-context.xml");

View File

@@ -1,7 +1,24 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.jsr.configuration.xml;
import static org.junit.Assert.assertEquals;
import javax.batch.api.listener.StepListener;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
@@ -16,7 +33,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration({"StepListenerParsingTests-context.xml", "jsr-base-context.xml"})
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class StepListenerParsingTests {
@@ -27,18 +44,23 @@ public class StepListenerParsingTests {
public JobLauncher jobLauncher;
@Autowired
public StepListener stepListener;
public SpringStepListener springStepListener;
@Autowired
public JsrStepListener jsrStepListener;
@Test
public void test() throws Exception {
JobExecution execution = jobLauncher.run(job, new JobParameters());
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
assertEquals(2, execution.getStepExecutions().size());
assertEquals(2, stepListener.countBeforeStep);
assertEquals(2, stepListener.countAfterStep);
assertEquals(3, execution.getStepExecutions().size());
assertEquals(2, springStepListener.countBeforeStep);
assertEquals(2, springStepListener.countAfterStep);
assertEquals(2, jsrStepListener.countBeforeStep);
assertEquals(2, jsrStepListener.countAfterStep);
}
public static class StepListener implements StepExecutionListener {
public static class SpringStepListener implements StepExecutionListener {
protected int countBeforeStep = 0;
protected int countAfterStep = 0;
@@ -53,4 +75,19 @@ public class StepListenerParsingTests {
return null;
}
}
public static class JsrStepListener implements StepListener {
protected int countBeforeStep = 0;
protected int countAfterStep = 0;
@Override
public void beforeStep() throws Exception {
countBeforeStep++;
}
@Override
public void afterStep() throws Exception {
countAfterStep++;
}
}
}

View File

@@ -0,0 +1,53 @@
package org.springframework.batch.core.jsr.step.batchlet;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import javax.batch.api.Batchlet;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.repeat.RepeatStatus;
public class BatchletAdapterTests {
private BatchletAdapter adapter;
@Mock
private Batchlet delegate;
@Mock
private StepContribution contribution;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
adapter = new BatchletAdapter(delegate);
}
@Test(expected=IllegalArgumentException.class)
public void testCreateWithNull() {
adapter = new BatchletAdapter(null);
}
@Test
public void testExecuteNoExitStatus() throws Exception {
assertEquals(RepeatStatus.FINISHED, adapter.execute(contribution, null));
verify(delegate).process();
}
@Test
public void testExecuteWithExitStatus() throws Exception {
when(delegate.process()).thenReturn("my exit status");
assertEquals(RepeatStatus.FINISHED, adapter.execute(contribution, null));
verify(delegate).process();
verify(contribution).setExitStatus(new ExitStatus("my exit status"));
}
}

View File

@@ -0,0 +1,16 @@
package org.springframework.batch.core.jsr.step.batchlet;
import javax.batch.api.Batchlet;
public class BatchletSupport implements Batchlet {
@Override
public String process() throws Exception {
return null;
}
@Override
public void stop() throws Exception {
// no-op
}
}

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
<step id="step1" next="step2">
<listeners>
<listener ref="springChunkListener" />
</listeners>
<chunk checkpoint-policy="item" item-count="1">
<reader ref="generatingItemReader1" />
<processor ref="countingItemProcessor" />
<writer ref="sysoutItemWriter" />
</chunk>
</step>
<step id="step2" next="step3">
<listeners>
<listener ref="jsrChunkListener" />
</listeners>
<chunk checkpoint-policy="item" item-count="1">
<reader ref="generatingItemReader2" />
<processor ref="countingItemProcessor" />
<writer ref="sysoutItemWriter" />
</chunk>
</step>
<step id="step3">
<listeners>
<listener ref="jsrChunkListener" />
<listener ref="springChunkListener" />
</listeners>
<chunk checkpoint-policy="item" item-count="1">
<reader ref="generatingItemReader3" />
<processor ref="countingItemProcessor" />
<writer ref="errorGeneratingWriter" />
</chunk>
</step>
</job>
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository"/>
</bean>
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
<bean id="generatingItemReader1" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>One</value>
<value>Two</value>
</list>
</constructor-arg>
</bean>
<bean id="generatingItemReader2" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>Three</value>
<value>Four</value>
</list>
</constructor-arg>
</bean>
<bean id="generatingItemReader3" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>Five</value>
<value>Six</value>
</list>
</constructor-arg>
</bean>
<bean id="countingItemProcessor" class="org.springframework.batch.core.jsr.configuration.xml.CountingItemProcessor"/>
<bean id="sysoutItemWriter" class="org.springframework.batch.item.adapter.ItemWriterAdapter">
<property name="targetObject">
<util:constant static-field="java.lang.System.out"/>
</property>
<property name="targetMethod" value="println"/>
</bean>
<bean id="springChunkListener" class="org.springframework.batch.core.jsr.configuration.xml.ChunkListenerParsingTests.SpringChunkListener"/>
<bean id="jsrChunkListener" class="org.springframework.batch.core.jsr.configuration.xml.ChunkListenerParsingTests.JsrChunkListener"/>
<bean id="errorGeneratingWriter" class="org.springframework.batch.core.jsr.configuration.xml.ChunkListenerParsingTests.ErrorThrowingItemWriter"/>
</beans>

View File

@@ -1,16 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
version="1.0">
<step id="step1" next="decider">
<batchlet ref="step1Ref" />
</step>
<decision ref="testDecider" id="decider">
<next on="step2" to="step2"/>
<end on="*"/>
</decision>
<step id="step2">
<batchlet ref="step1Ref" />
</step>
</job>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
<step id="step1" next="decider">
<batchlet ref="step1Ref" />
</step>
<decision ref="testDecider" id="decider">
<next on="step2" to="step2" />
<end on="*" />
</decision>
<step id="step2">
<batchlet ref="step1Ref" />
</step>
</job>
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository"/>
</bean>
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
<bean id="testDecider" class="org.springframework.batch.core.jsr.configuration.xml.DecisionParsingTests.TestDecider"/>
<bean id="step1Ref" class="org.springframework.batch.core.step.tasklet.TaskletSupport"/>
</beans>

View File

@@ -1,38 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
version="1.0">
<step id="step1" next="step2">
<chunk item-count="5" skip-limit="2">
<reader ref="generatingItemReader1"/>
<processor ref="problemProcessor"/>
<writer ref="sysoutItemWriter"/>
<skippable-exception-classes>
<include class="java.lang.Exception"/>
<exclude class="java.lang.RuntimeException"/>
</skippable-exception-classes>
</chunk>
</step>
<step id="step2" next="step3">
<chunk item-count="5" retry-limit="2">
<reader ref="generatingItemReader2"/>
<processor ref="problemProcessor"/>
<writer ref="sysoutItemWriter"/>
<retryable-exception-classes>
<include class="java.lang.Exception"/>
<exclude class="java.lang.RuntimeException"/>
</retryable-exception-classes>
</chunk>
</step>
<step id="step3">
<chunk item-count="5">
<reader ref="generatingItemReader3"/>
<processor ref="problemProcessor"/>
<writer ref="sysoutItemWriter"/>
<no-rollback-exception-classes>
<include class="java.lang.Exception"/>
</no-rollback-exception-classes>
</chunk>
</step>
</job>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
<step id="step1" next="step2">
<chunk item-count="5" skip-limit="2">
<reader ref="generatingItemReader1" />
<processor ref="problemProcessor" />
<writer ref="sysoutItemWriter" />
<skippable-exception-classes>
<include class="java.lang.Exception" />
<exclude class="java.lang.RuntimeException" />
</skippable-exception-classes>
</chunk>
</step>
<step id="step2" next="step3">
<chunk item-count="5" retry-limit="2">
<reader ref="generatingItemReader2" />
<processor ref="problemProcessor" />
<writer ref="sysoutItemWriter" />
<retryable-exception-classes>
<include class="java.lang.Exception" />
<exclude class="java.lang.RuntimeException" />
</retryable-exception-classes>
</chunk>
</step>
<step id="step3">
<chunk item-count="5">
<reader ref="generatingItemReader3" />
<processor ref="problemProcessor" />
<writer ref="sysoutItemWriter" />
<no-rollback-exception-classes>
<include class="java.lang.Exception" />
</no-rollback-exception-classes>
</chunk>
</step>
</job>
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository"/>
</bean>
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
<bean id="generatingItemReader1" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>One</value>
<value>Two</value>
</list>
</constructor-arg>
</bean>
<bean id="generatingItemReader2" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>Three</value>
<value>Four</value>
</list>
</constructor-arg>
</bean>
<bean id="generatingItemReader3" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>Five</value>
<value>Six</value>
</list>
</constructor-arg>
</bean>
<bean id="problemProcessor" class="org.springframework.batch.core.jsr.configuration.xml.ExceptionHandlingParsingTests.ProblemProcessor" scope="step">
<property name="runId" value="#{jobParameters[run]}"/>
</bean>
<bean id="sysoutItemWriter" class="org.springframework.batch.item.adapter.ItemWriterAdapter">
<property name="targetObject">
<util:constant static-field="java.lang.System.out"/>
</property>
<property name="targetMethod" value="println"/>
</bean>
</beans>

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
<step id="step1" next="step2">
<listeners>
<listener ref="springItemListener" />
</listeners>
<chunk checkpoint-policy="item" item-count="2">
<reader ref="generatingItemReader1" />
<processor ref="countingItemProcessor" />
<writer ref="sysoutItemWriter" />
</chunk>
</step>
<step id="step2" next="step3">
<listeners>
<listener ref="jsrItemListener" />
</listeners>
<chunk checkpoint-policy="item" item-count="2">
<reader ref="generatingItemReader2" />
<processor ref="countingItemProcessor" />
<writer ref="sysoutItemWriter" />
</chunk>
</step>
<step id="step3">
<listeners>
<listener ref="springItemListener" />
<listener ref="jsrItemListener" />
</listeners>
<chunk checkpoint-policy="item" item-count="2">
<reader ref="generatingItemReader3" />
<processor ref="countingItemProcessor" />
<writer ref="sysoutItemWriter" />
</chunk>
</step>
</job>
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository"/>
</bean>
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
<bean id="generatingItemReader1" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>One</value>
<value>Two</value>
</list>
</constructor-arg>
</bean>
<bean id="generatingItemReader2" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>Three</value>
<value>Four</value>
</list>
</constructor-arg>
</bean>
<bean id="generatingItemReader3" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>Five</value>
<value>Six</value>
</list>
</constructor-arg>
</bean>
<bean id="countingItemProcessor" class="org.springframework.batch.core.jsr.configuration.xml.CountingItemProcessor"/>
<bean id="sysoutItemWriter" class="org.springframework.batch.item.adapter.ItemWriterAdapter">
<property name="targetObject">
<util:constant static-field="java.lang.System.out"/>
</property>
<property name="targetMethod" value="println"/>
</bean>
<bean id="springItemListener" class="org.springframework.batch.core.jsr.configuration.xml.ItemListenerParsingTests.SpringItemListener"/>
<bean id="jsrItemListener" class="org.springframework.batch.core.jsr.configuration.xml.ItemListenerParsingTests.JsrItemListener"/>
</beans>

View File

@@ -1,20 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
version="1.0">
<step id="step1">
<listeners>
<listener ref="skipListener"/>
</listeners>
<chunk checkpoint-policy="item" item-count="1" skip-limit="4">
<reader ref="skipErrorGeneratingReader"/>
<processor ref="skipErrorGeneratingProcessor"/>
<writer ref="skipErrorGeneratingWriter"/>
<skippable-exception-classes>
<include class="java.lang.Exception"/>
<exclude class="java.lang.RuntimeException"/>
</skippable-exception-classes>
</chunk>
</step>
</job>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
<step id="step1">
<listeners>
<listener ref="skipListener" />
</listeners>
<chunk checkpoint-policy="item" item-count="1" skip-limit="4">
<reader ref="skipErrorGeneratingReader" />
<processor ref="skipErrorGeneratingProcessor" />
<writer ref="skipErrorGeneratingWriter" />
<skippable-exception-classes>
<include class="java.lang.Exception" />
<exclude class="java.lang.RuntimeException" />
</skippable-exception-classes>
</chunk>
</step>
</job>
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository"/>
</bean>
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
<bean id="skipErrorGeneratingReader" class="org.springframework.batch.core.jsr.configuration.xml.ItemSkipParsingTests.SkipErrorGeneratingReader"/>
<bean id="skipErrorGeneratingProcessor" class="org.springframework.batch.core.jsr.configuration.xml.ItemSkipParsingTests.SkipErrorGeneratingProcessor"/>
<bean id="skipErrorGeneratingWriter" class="org.springframework.batch.core.jsr.configuration.xml.ItemSkipParsingTests.SkipErrorGeneratingWriter"/>
<bean id="skipListener" class="org.springframework.batch.core.jsr.configuration.xml.ItemSkipParsingTests.TestSkipListener"/>
</beans>

View File

@@ -1,15 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
version="1.0">
<listeners>
<listener ref="jobListener"/>
</listeners>
<step id="step1" next="step2">
<batchlet ref="step1Ref" />
</step>
<step id="step2">
<batchlet ref="step1Ref" />
</step>
</job>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
<listeners>
<listener ref="springJobListener" />
<listener ref="jsrJobListener" />
</listeners>
<step id="step1" next="step2">
<batchlet ref="step1Ref" />
</step>
<step id="step2">
<batchlet ref="step1Ref" />
</step>
</job>
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository"/>
</bean>
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
<bean id="springJobListener" class="org.springframework.batch.core.jsr.configuration.xml.JobListenerParsingTests.SpringJobListener"/>
<bean id="jsrJobListener" class="org.springframework.batch.core.jsr.configuration.xml.JobListenerParsingTests.JsrJobListener"/>
<bean id="step1Ref" class="org.springframework.batch.core.step.tasklet.TaskletSupport"/>
</beans>

View File

@@ -1,29 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
version="1.0">
<step id="step1" next="step2">
<chunk checkpoint-policy="item" item-count="3">
<reader ref="generatingItemReader1"/>
<processor ref="countingItemProcessor"/>
<writer ref="sysoutItemWriter"/>
</chunk>
</step>
<step id="step2" next="step3">
<chunk checkpoint-policy="custom">
<reader ref="generatingItemReader1"/>
<processor ref="countingItemProcessor"/>
<writer ref="sysoutItemWriter"/>
<checkpoint-algorithm ref="testCompletionPolicy"/>
</chunk>
</step>
<step id="step3">
<chunk checkpoint-policy="item" item-count="3" time-limit="1">
<reader ref="generatingItemReader1"/>
<processor ref="countingItemProcessor"/>
<writer ref="sysoutItemWriter"/>
<checkpoint-algorithm ref="testCompletionPolicy"/>
</chunk>
</step>
</job>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
<step id="step1" next="step2">
<chunk checkpoint-policy="item" item-count="3">
<reader ref="generatingItemReader1" />
<processor ref="countingItemProcessor" />
<writer ref="sysoutItemWriter" />
</chunk>
</step>
<step id="step2" next="step3">
<chunk checkpoint-policy="custom">
<reader ref="generatingItemReader1" />
<processor ref="countingItemProcessor" />
<writer ref="sysoutItemWriter" />
<checkpoint-algorithm ref="testCompletionPolicy" />
</chunk>
</step>
<step id="step3">
<chunk checkpoint-policy="item" item-count="3" time-limit="1">
<reader ref="generatingItemReader1" />
<processor ref="countingItemProcessor" />
<writer ref="sysoutItemWriter" />
<checkpoint-algorithm ref="testCompletionPolicy" />
</chunk>
</step>
</job>
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository"/>
</bean>
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
<bean id="generatingItemReader1" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>One</value>
<value>Two</value>
</list>
</constructor-arg>
</bean>
<bean id="generatingItemReader2" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>Three</value>
<value>Four</value>
</list>
</constructor-arg>
</bean>
<bean id="generatingItemReader3" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>Five</value>
<value>Six</value>
</list>
</constructor-arg>
</bean>
<bean id="countingItemProcessor" class="org.springframework.batch.core.jsr.configuration.xml.CountingItemProcessor"/>
<bean id="sysoutItemWriter" class="org.springframework.batch.item.adapter.ItemWriterAdapter">
<property name="targetObject">
<util:constant static-field="java.lang.System.out"/>
</property>
<property name="targetMethod" value="println"/>
</bean>
<bean id="testCompletionPolicy" class="org.springframework.batch.core.jsr.configuration.xml.SimpleItemBasedJobParsingTests.CountingCompletionPolicy"/>
</beans>

View File

@@ -1,16 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
version="1.0">
<step id="step1" next="step2">
<batchlet ref="step1Ref" />
</step>
<step id="step2">
<batchlet ref="step1Ref" />
<next on="*" to="step3"/>
</step>
<step id="step3">
<batchlet ref="step1Ref" />
</step>
</job>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
<step id="step1" next="step2">
<batchlet ref="batchlet" />
</step>
<step id="step2">
<batchlet ref="step1Ref" />
<next on="*" to="step3" />
</step>
<step id="step3">
<batchlet ref="batchlet" />
</step>
</job>
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository"/>
</bean>
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
<bean id="batchlet" class="org.springframework.batch.core.jsr.step.batchlet.BatchletSupport"/>
<bean id="step1Ref" class="org.springframework.batch.core.step.tasklet.TaskletSupport"/>
</beans>

View File

@@ -1,18 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
version="1.0">
<step id="step1" next="step2">
<listeners>
<listener ref="stepListener"/>
</listeners>
<batchlet ref="step1Ref" />
</step>
<step id="step2">
<listeners>
<listener ref="stepListener"/>
</listeners>
<batchlet ref="step1Ref" />
</step>
</job>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
<step id="step1" next="step2">
<listeners>
<listener ref="springStepListener" />
</listeners>
<batchlet ref="step1Ref" />
</step>
<step id="step2" next="step3">
<listeners>
<listener ref="jsrStepListener" />
</listeners>
<batchlet ref="step1Ref" />
</step>
<step id="step3">
<listeners>
<listener ref="springStepListener" />
<listener ref="jsrStepListener" />
</listeners>
<batchlet ref="step1Ref" />
</step>
</job>
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository"/>
</bean>
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
<bean id="step1Ref" class="org.springframework.batch.core.step.tasklet.TaskletSupport"/>
<bean id="springStepListener" class="org.springframework.batch.core.jsr.configuration.xml.StepListenerParsingTests.SpringStepListener"/>
<bean id="jsrStepListener" class="org.springframework.batch.core.jsr.configuration.xml.StepListenerParsingTests.JsrStepListener"/>
</beans>

View File

@@ -1,5 +1,3 @@
<batch-artifacts xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/batchXML_1_0.xsd">
<batch-artifacts xmlns="http://xmlns.jcp.org/xml/ns/javaee">
<ref id="itemProcessor" class="org.springframework.batch.item.support.PassThroughItemProcessor" />
</batch-artifacts>

View File

@@ -1,74 +0,0 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository"/>
</bean>
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
<bean id="step1Ref" class="org.springframework.batch.core.step.tasklet.TaskletSupport"/>
<bean id="generatingItemReader1" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>One</value>
<value>Two</value>
</list>
</constructor-arg>
</bean>
<bean id="generatingItemReader2" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>Three</value>
<value>Four</value>
</list>
</constructor-arg>
</bean>
<bean id="generatingItemReader3" class="org.springframework.batch.item.support.ListItemReader">
<constructor-arg>
<list>
<value>Five</value>
<value>Six</value>
</list>
</constructor-arg>
</bean>
<bean id="countingItemProcessor" class="org.springframework.batch.core.jsr.configuration.xml.SimpleItemBasedJobParsingTests.CountingItemProcessor"/>
<bean id="sysoutItemWriter" class="org.springframework.batch.item.adapter.ItemWriterAdapter">
<property name="targetObject">
<util:constant static-field="java.lang.System.out"/>
</property>
<property name="targetMethod" value="println"/>
</bean>
<bean id="jobListener" class="org.springframework.batch.core.jsr.configuration.xml.JobListenerParsingTests.JobListener"/>
<bean id="stepListener" class="org.springframework.batch.core.jsr.configuration.xml.StepListenerParsingTests.StepListener"/>
<bean id="problemProcessor" class="org.springframework.batch.core.jsr.configuration.xml.ExceptionHandlingParsingTests.ProblemProcessor" scope="step">
<property name="runId" value="#{jobParameters[run]}"/>
</bean>
<bean id="testDecider" class="org.springframework.batch.core.jsr.configuration.xml.DecisionParsingTests.TestDecider"/>
<bean id="testCompletionPolicy" class="org.springframework.batch.core.jsr.configuration.xml.SimpleItemBasedJobParsingTests.CountingCompletionPolicy"/>
<bean id="skipErrorGeneratingReader" class="org.springframework.batch.core.jsr.configuration.xml.ItemSkipParsingTests.SkipErrorGeneratingReader"/>
<bean id="skipErrorGeneratingProcessor" class="org.springframework.batch.core.jsr.configuration.xml.ItemSkipParsingTests.SkipErrorGeneratingProcessor"/>
<bean id="skipErrorGeneratingWriter" class="org.springframework.batch.core.jsr.configuration.xml.ItemSkipParsingTests.SkipErrorGeneratingWriter"/>
<bean id="skipListener" class="org.springframework.batch.core.jsr.configuration.xml.ItemSkipParsingTests.TestSkipListener"/>
</beans>

View File

@@ -136,6 +136,12 @@
<version>1.4</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.batch</groupId>
<artifactId>javax.batch-api</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>

View File

@@ -0,0 +1,21 @@
package org.springframework.batch.jsr.item;
import javax.batch.api.chunk.ItemProcessor;
import org.springframework.util.Assert;
@SuppressWarnings("rawtypes")
public class ItemProcessorAdapter implements org.springframework.batch.item.ItemProcessor {
private ItemProcessor delegate;
public ItemProcessorAdapter(ItemProcessor processor) {
Assert.notNull(processor, "An ItemProcessor implementation is required");
this.delegate = processor;
}
@Override
public Object process(Object item) throws Exception {
return delegate.processItem(item);
}
}

View File

@@ -0,0 +1,64 @@
package org.springframework.batch.jsr.item;
import java.io.Serializable;
import javax.batch.api.chunk.ItemReader;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ItemStreamSupport;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@SuppressWarnings("rawtypes")
public class ItemReaderAdapter extends ItemStreamSupport implements org.springframework.batch.item.ItemReader {
private static final String CHECKPOINT_KEY = "reader.checkpoint";
private ItemReader delegate;
public ItemReaderAdapter(ItemReader reader) {
Assert.notNull(reader, "An ItemReader implementation is required");
this.delegate = reader;
setExecutionContextName(ClassUtils.getShortName(delegate.getClass()));
}
@Override
public void open(ExecutionContext executionContext)
throws ItemStreamException {
try {
delegate.open((Serializable) executionContext.get(getExecutionContextKey(CHECKPOINT_KEY)));
} catch (Exception e) {
throw new ItemStreamException(e);
}
}
@Override
public void update(ExecutionContext executionContext)
throws ItemStreamException {
try {
Serializable checkpoint = delegate.checkpointInfo();
executionContext.put(getExecutionContextKey(CHECKPOINT_KEY), checkpoint);
} catch (Exception e) {
throw new ItemStreamException(e);
}
}
@Override
public void close() throws ItemStreamException {
try {
delegate.close();
} catch (Exception e) {
throw new ItemStreamException(e);
}
}
@Override
public Object read() throws Exception, UnexpectedInputException, ParseException,
NonTransientResourceException {
return delegate.readItem();
}
}

View File

@@ -0,0 +1,62 @@
package org.springframework.batch.jsr.item;
import java.io.Serializable;
import java.util.List;
import javax.batch.api.chunk.ItemWriter;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ItemStreamSupport;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@SuppressWarnings("rawtypes")
public class ItemWriterAdapter extends ItemStreamSupport implements org.springframework.batch.item.ItemWriter {
private static final String CHECKPOINT_KEY = "writer.checkpoint";
private ItemWriter delegate;
public ItemWriterAdapter(ItemWriter writer) {
Assert.notNull(writer, "An ItemWriter implementation is required");
this.delegate = writer;
super.setExecutionContextName(ClassUtils.getShortName(delegate.getClass()));
}
@Override
public void open(ExecutionContext executionContext)
throws ItemStreamException {
try {
delegate.open((Serializable) executionContext.get(getExecutionContextKey(CHECKPOINT_KEY)));
} catch (Exception e) {
throw new ItemStreamException(e);
}
}
@Override
public void update(ExecutionContext executionContext)
throws ItemStreamException {
try {
Serializable checkpoint = delegate.checkpointInfo();
executionContext.put(getExecutionContextKey(CHECKPOINT_KEY), checkpoint);
} catch (Exception e) {
throw new ItemStreamException(e);
}
}
@Override
public void close() throws ItemStreamException {
try {
delegate.close();
} catch (Exception e) {
throw new ItemStreamException(e);
}
}
@Override
@SuppressWarnings("unchecked")
public void write(List items) throws Exception {
delegate.writeItems(items);
}
}

View File

@@ -0,0 +1,63 @@
package org.springframework.batch.jsr.repeat;
import javax.batch.api.chunk.CheckpointAlgorithm;
import org.springframework.batch.repeat.CompletionPolicy;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.util.Assert;
public class CheckpointAlgorithmAdapter implements CompletionPolicy {
private CheckpointAlgorithm policy;
public CheckpointAlgorithmAdapter(CheckpointAlgorithm policy) {
Assert.notNull(policy, "A CheckpointAlgorithm is required");
this.policy = policy;
}
@Override
public boolean isComplete(RepeatContext context, RepeatStatus result) {
try {
return policy.isReadyToCheckpoint();
} catch (Exception e) {
//TODO: do something here
}
return false;
}
@Override
public boolean isComplete(RepeatContext context) {
try {
return policy.isReadyToCheckpoint();
} catch (Exception e) {
//TODO: do something here
}
return false;
}
@Override
public RepeatContext start(RepeatContext parent) {
try {
policy.beginCheckpoint();
} catch (Exception e) {
//TODO: do something here
}
return null;
}
@Override
public void update(RepeatContext context) {
try {
if(policy.isReadyToCheckpoint()) {
policy.endCheckpoint();
}
} catch (Exception e) {
//TODO: do something here
}
}
}

View File

@@ -0,0 +1,40 @@
package org.springframework.batch.jsr.item;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
import javax.batch.api.chunk.ItemProcessor;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class ItemProcessorAdapterTests {
private ItemProcessorAdapter adapter;
@Mock
private ItemProcessor delegate;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
adapter = new ItemProcessorAdapter(delegate);
}
@Test(expected=IllegalArgumentException.class)
public void testCreateWithNull() {
adapter = new ItemProcessorAdapter(null);
}
@Test
public void testProcess() throws Exception {
String input = "input";
String output = "output";
when(delegate.processItem(input)).thenReturn(output);
assertEquals(output, adapter.process(input));
}
}

View File

@@ -0,0 +1,91 @@
package org.springframework.batch.jsr.item;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import javax.batch.api.chunk.ItemReader;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStreamException;
public class ItemReaderAdapterTests {
private ItemReaderAdapter adapter;
@Mock
private ItemReader delegate;
@Mock
private ExecutionContext executionContext;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
adapter = new ItemReaderAdapter(delegate);
}
@Test(expected=IllegalArgumentException.class)
public void testCreateWithNull() {
adapter = new ItemReaderAdapter(null);
}
@Test
public void testOpen() throws Exception {
when(executionContext.get("ItemReader.reader.checkpoint")).thenReturn("checkpoint");
adapter.open(executionContext);
verify(delegate).open("checkpoint");
}
@Test(expected=ItemStreamException.class)
public void testOpenException() throws Exception {
when(executionContext.get("ItemReader.reader.checkpoint")).thenReturn("checkpoint");
doThrow(new Exception("expected")).when(delegate).open("checkpoint");
adapter.open(executionContext);
}
@Test
public void testUpdate() throws Exception {
when(delegate.checkpointInfo()).thenReturn("checkpoint");
adapter.update(executionContext);
verify(executionContext).put("ItemReader.reader.checkpoint", "checkpoint");
}
@Test(expected=ItemStreamException.class)
public void testUpdateException() throws Exception {
doThrow(new Exception("expected")).when(delegate).checkpointInfo();
adapter.update(executionContext);
}
@Test
public void testClose() throws Exception {
adapter.close();
verify(delegate).close();
}
@Test(expected=ItemStreamException.class)
public void testCloseException() throws Exception {
doThrow(new Exception("expected")).when(delegate).close();
adapter.close();
}
@Test
public void testRead() throws Exception {
when(delegate.readItem()).thenReturn("item");
assertEquals("item", adapter.read());
}
}

View File

@@ -0,0 +1,99 @@
package org.springframework.batch.jsr.item;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import javax.batch.api.chunk.ItemWriter;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStreamException;
public class ItemWriterAdapterTests {
private ItemWriterAdapter adapter;
@Mock
private ItemWriter delegate;
@Mock
private ExecutionContext executionContext;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
adapter = new ItemWriterAdapter(delegate);
}
@Test(expected=IllegalArgumentException.class)
public void testCreateWithNull() {
adapter = new ItemWriterAdapter(null);
}
@Test
public void testOpen() throws Exception {
when(executionContext.get("ItemWriter.writer.checkpoint")).thenReturn("checkpoint");
adapter.open(executionContext);
verify(delegate).open("checkpoint");
}
@Test(expected=ItemStreamException.class)
public void testOpenException() throws Exception {
when(executionContext.get("ItemWriter.writer.checkpoint")).thenReturn("checkpoint");
doThrow(new Exception("expected")).when(delegate).open("checkpoint");
adapter.open(executionContext);
}
@Test
public void testUpdate() throws Exception {
when(delegate.checkpointInfo()).thenReturn("checkpoint");
adapter.update(executionContext);
verify(executionContext).put("ItemWriter.writer.checkpoint", "checkpoint");
}
@Test(expected=ItemStreamException.class)
public void testUpdateException() throws Exception {
doThrow(new Exception("expected")).when(delegate).checkpointInfo();
adapter.update(executionContext);
}
@Test
public void testClose() throws Exception {
adapter.close();
verify(delegate).close();
}
@Test(expected=ItemStreamException.class)
public void testCloseException() throws Exception {
doThrow(new Exception("expected")).when(delegate).close();
adapter.close();
}
@Test
@SuppressWarnings({"rawtypes", "unchecked"})
public void testWrite() throws Exception {
List items = new ArrayList();
items.add("item1");
items.add("item2");
adapter.write(items);
verify(delegate).writeItems(items);
}
}

View File

@@ -599,6 +599,13 @@
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.batch</groupId>
<artifactId>javax.batch-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>stax</groupId>
<artifactId>stax</artifactId>