Introduce KeyedItemReader to push the getKey() method into a separate place.
This commit is contained in:
@@ -18,7 +18,6 @@ package org.springframework.batch.core.domain;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
/**
|
||||
* Batch domain object representing a job. Job is an explicit abstraction
|
||||
@@ -39,6 +38,6 @@ public interface Job {
|
||||
|
||||
boolean isRestartable();
|
||||
|
||||
ExitStatus run(JobExecution execution) throws BatchCriticalException;
|
||||
void run(JobExecution execution) throws BatchCriticalException;
|
||||
|
||||
}
|
||||
@@ -20,7 +20,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
@@ -134,7 +133,7 @@ public class JobSupport implements BeanNameAware, Job {
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.domain.Job#run(org.springframework.batch.core.domain.JobExecution)
|
||||
*/
|
||||
public ExitStatus run(JobExecution execution) throws BatchCriticalException {
|
||||
public void run(JobExecution execution) throws BatchCriticalException {
|
||||
throw new UnsupportedOperationException("JobSupport does not provide an implementation of run(). Use a smarter subclass.");
|
||||
}
|
||||
|
||||
|
||||
@@ -16,14 +16,12 @@
|
||||
package org.springframework.batch.core.domain;
|
||||
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
|
||||
|
||||
/**
|
||||
* Batch domain interface representing the configuration of a step. As with the
|
||||
* (@link Job), step configuration is meant to explicitly represent
|
||||
* a the configuration of a step by a developer. This allows for the separation
|
||||
* of what a developer configures from the myriad of concerns required for
|
||||
* (@link Job), step configuration is meant to explicitly represent a the
|
||||
* configuration of a step by a developer. This allows for the separation of
|
||||
* what a developer configures from the myriad of concerns required for
|
||||
* executing a job.
|
||||
*
|
||||
* @author Dave Syer
|
||||
@@ -41,7 +39,7 @@ public interface Step {
|
||||
* again.
|
||||
*/
|
||||
boolean isAllowStartIfComplete();
|
||||
|
||||
|
||||
/**
|
||||
* Flag to indicate if restart data needs to be saved for this step.
|
||||
* @return true if restart data should be saved
|
||||
@@ -53,11 +51,15 @@ public interface Step {
|
||||
* identifier.
|
||||
*/
|
||||
int getStartLimit();
|
||||
|
||||
|
||||
/**
|
||||
* It is not safe to re-use an instance of {@link StepExecutor} to process
|
||||
* multiple concurrent executions. Use the factory method in {@link Step} to
|
||||
* create a new instance and execute that.
|
||||
* Process the step and assign progress and status meta information to the
|
||||
* {@link StepExecution} provided. The {@link Step} is responsible for
|
||||
* setting the meta information and also saving it if required by the
|
||||
* implementation.<br/>
|
||||
*
|
||||
* It is not safe to re-use an instance of {@link Step} to process multiple
|
||||
* concurrent executions.
|
||||
*
|
||||
* @param stepExecution an entity representing the step to be executed
|
||||
*
|
||||
@@ -65,6 +67,6 @@ public interface Step {
|
||||
* @throws BatchCriticalException if there is a problem that needs to be
|
||||
* signalled to the caller
|
||||
*/
|
||||
ExitStatus process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException;
|
||||
void process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException;
|
||||
|
||||
}
|
||||
@@ -136,7 +136,7 @@ public class StepSupport implements Step, BeanNameAware {
|
||||
*
|
||||
* @see org.springframework.batch.core.domain.Step#process(org.springframework.batch.core.domain.StepExecution)
|
||||
*/
|
||||
public org.springframework.batch.repeat.ExitStatus process(StepExecution stepExecution)
|
||||
public void process(StepExecution stepExecution)
|
||||
throws StepInterruptedException, BatchCriticalException {
|
||||
throw new UnsupportedOperationException(
|
||||
"Cannot process a StepExecution. Use a smarter subclass of StepSupport.");
|
||||
|
||||
@@ -55,7 +55,7 @@ public class SimpleJob extends JobSupport {
|
||||
*
|
||||
* @see org.springframework.batch.core.domain.Job#run(org.springframework.batch.core.domain.JobExecution)
|
||||
*/
|
||||
public ExitStatus run(JobExecution execution) throws BatchCriticalException {
|
||||
public void run(JobExecution execution) throws BatchCriticalException {
|
||||
|
||||
JobInstance jobInstance = execution.getJobInstance();
|
||||
updateStatus(execution, BatchStatus.STARTING);
|
||||
@@ -78,7 +78,8 @@ public class SimpleJob extends JobSupport {
|
||||
startedCount++;
|
||||
updateStatus(execution, BatchStatus.STARTED);
|
||||
StepExecution stepExecution = execution.createStepExecution(stepInstance);
|
||||
status = step.process(stepExecution);
|
||||
step.process(stepExecution);
|
||||
status = stepExecution.getExitStatus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +112,6 @@ public class SimpleJob extends JobSupport {
|
||||
jobRepository.saveOrUpdate(execution);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
private void updateStatus(JobExecution jobExecution, BatchStatus status) {
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.springframework.batch.core.domain.JobParameters;
|
||||
import org.springframework.batch.core.domain.JobSupport;
|
||||
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.task.SyncTaskExecutor;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
@@ -83,10 +82,7 @@ public class SimpleJobLauncher implements JobLauncher, InitializingBean {
|
||||
public void run() {
|
||||
try {
|
||||
logger.info("Job: [" + job + "] launched with the following parameters: [" + jobParameters + "]");
|
||||
ExitStatus exitStatus = job.run(jobExecution);
|
||||
// The exit status should be set by the Job. TODO: remove
|
||||
// this line...
|
||||
jobExecution.setExitStatus(exitStatus);
|
||||
job.run(jobExecution);
|
||||
logger.info("Job: [" + job + "] completed successfully with the following parameters: ["
|
||||
+ jobParameters + "]");
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.springframework.batch.core.domain.StepSupport;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.tasklet.Tasklet;
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.exception.handler.ExceptionHandler;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -112,9 +111,9 @@ public abstract class AbstractStep extends StepSupport {
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.domain.StepSupport#process(org.springframework.batch.core.domain.StepExecution)
|
||||
*/
|
||||
public ExitStatus process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException {
|
||||
public void process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException {
|
||||
SimpleStepExecutor executor = createStepExecutor();
|
||||
return executor.process(stepExecution);
|
||||
executor.process(stepExecution);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,6 @@ import org.springframework.batch.core.domain.Step;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
import org.springframework.batch.core.domain.StepInterruptedException;
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.RepeatOperations;
|
||||
|
||||
/**
|
||||
@@ -78,7 +77,7 @@ public class RepeatOperationsStep extends AbstractStep implements RepeatOperatio
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.execution.step.simple.AbstractStep#process(org.springframework.batch.core.domain.StepExecution)
|
||||
*/
|
||||
public ExitStatus process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException {
|
||||
public void process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException {
|
||||
assertMandatoryProperties();
|
||||
SimpleStepExecutor executor = (SimpleStepExecutor) super.createStepExecutor();
|
||||
if (stepOperations != null) {
|
||||
@@ -87,6 +86,6 @@ public class RepeatOperationsStep extends AbstractStep implements RepeatOperatio
|
||||
if (chunkOperations != null) {
|
||||
executor.setChunkOperations(chunkOperations);
|
||||
}
|
||||
return executor.process(stepExecution);
|
||||
executor.process(stepExecution);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ public class SimpleStepExecutor {
|
||||
* execution
|
||||
* @see StepExecutor#process(StepExecution)
|
||||
*/
|
||||
public ExitStatus process(final StepExecution stepExecution) throws BatchCriticalException,
|
||||
public void process(final StepExecution stepExecution) throws BatchCriticalException,
|
||||
StepInterruptedException {
|
||||
|
||||
final StepInstance stepInstance = stepExecution.getStep();
|
||||
@@ -276,7 +276,6 @@ public class SimpleStepExecutor {
|
||||
});
|
||||
|
||||
updateStatus(stepExecution, BatchStatus.COMPLETED);
|
||||
return status;
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.springframework.batch.io.Skippable;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemRecoverer;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.KeyedItemReader;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.retry.RetryPolicy;
|
||||
import org.springframework.batch.retry.callback.ItemReaderRetryCallback;
|
||||
@@ -111,7 +112,8 @@ public class ItemOrientedTasklet implements Tasklet, Skippable, InitializingBean
|
||||
template.setRetryPolicy(itemProviderRetryPolicy);
|
||||
|
||||
if (retryPolicy != null) {
|
||||
retryCallback = new ItemReaderRetryCallback(itemProvider, itemWriter);
|
||||
Assert.state(itemProvider instanceof KeyedItemReader, "ItemReader must be instance of KeyedItemReader to use the retry policy");
|
||||
retryCallback = new ItemReaderRetryCallback((KeyedItemReader) itemProvider, itemWriter);
|
||||
retryCallback.setRecoverer(itemRecoverer);
|
||||
}
|
||||
|
||||
|
||||
@@ -272,7 +272,7 @@ public class SimpleJobTests extends TestCase {
|
||||
this.runnable = runnable;
|
||||
}
|
||||
|
||||
public ExitStatus process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException {
|
||||
public void process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException {
|
||||
if (exception instanceof RuntimeException) {
|
||||
throw (RuntimeException)exception;
|
||||
}
|
||||
@@ -282,7 +282,7 @@ public class SimpleJobTests extends TestCase {
|
||||
if (runnable!=null) {
|
||||
runnable.run();
|
||||
}
|
||||
return ExitStatus.FINISHED;
|
||||
stepExecution.setExitStatus(ExitStatus.FINISHED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,8 +41,9 @@ public class SimpleJobLauncherTests extends TestCase {
|
||||
private MockControl repositoryControl = MockControl.createControl(JobRepository.class);
|
||||
|
||||
private Job job = new JobSupport("foo") {
|
||||
public ExitStatus run(JobExecution execution) {
|
||||
return ExitStatus.FINISHED;
|
||||
public void run(JobExecution execution) {
|
||||
execution.setExitStatus(ExitStatus.FINISHED);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -88,7 +89,7 @@ public class SimpleJobLauncherTests extends TestCase {
|
||||
|
||||
public void testRunWithException() throws Exception {
|
||||
job = new JobSupport() {
|
||||
public ExitStatus run(JobExecution execution) {
|
||||
public void run(JobExecution execution) {
|
||||
execution.setExitStatus(ExitStatus.FAILED);
|
||||
throw new RuntimeException("foo");
|
||||
}
|
||||
@@ -104,7 +105,7 @@ public class SimpleJobLauncherTests extends TestCase {
|
||||
|
||||
public void testRunWithError() throws Exception {
|
||||
job = new JobSupport() {
|
||||
public ExitStatus run(JobExecution execution) {
|
||||
public void run(JobExecution execution) {
|
||||
execution.setExitStatus(ExitStatus.FAILED);
|
||||
throw new Error("foo");
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.batch.io.Skippable;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemRecoverer;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.KeyedItemReader;
|
||||
import org.springframework.batch.item.reader.AbstractItemReader;
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.repeat.context.RepeatContextSupport;
|
||||
@@ -217,11 +218,7 @@ public class ItemOrientedTaskletTests extends TestCase {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
module.setItemReader(new AbstractItemReader() {
|
||||
public Object read() throws Exception {
|
||||
return "foo";
|
||||
}
|
||||
});
|
||||
module.setItemReader(new MockItemReader());
|
||||
module.setItemWriter(new AbstractItemWriter() {
|
||||
public void write(Object data) throws Exception {
|
||||
throw new RuntimeException("FOO");
|
||||
@@ -267,7 +264,16 @@ public class ItemOrientedTaskletTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
private class SkippableItemReader implements ItemReader,
|
||||
private class MockItemReader extends AbstractItemReader implements KeyedItemReader {
|
||||
public Object read() throws Exception {
|
||||
return "foo";
|
||||
}
|
||||
public Object getKey(Object item) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
private class SkippableItemReader implements KeyedItemReader,
|
||||
Skippable, StatisticsProvider {
|
||||
public Object read() throws Exception {
|
||||
return itemProvider.read();
|
||||
|
||||
@@ -55,10 +55,6 @@ public class RestartableItemOrientedTaskletTests extends TestCase {
|
||||
assertEquals(this.data.getProperties(), data.getProperties());
|
||||
}
|
||||
|
||||
public Object getKey(Object item) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean recover(Object data, Throwable cause) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.io.Skippable;
|
||||
import org.springframework.batch.io.support.AbstractTransactionalIoSource;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.KeyedItemReader;
|
||||
import org.springframework.batch.item.ResourceLifecycle;
|
||||
import org.springframework.batch.restart.GenericRestartData;
|
||||
import org.springframework.batch.restart.RestartData;
|
||||
@@ -117,7 +117,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Peter Zozom
|
||||
*/
|
||||
public class JdbcCursorItemReader extends AbstractTransactionalIoSource
|
||||
implements ItemReader, ResourceLifecycle, DisposableBean,
|
||||
implements KeyedItemReader, ResourceLifecycle, DisposableBean,
|
||||
InitializingBean, Restartable, StatisticsProvider, Skippable {
|
||||
|
||||
private static Log log = LogFactory.getLog(JdbcCursorItemReader.class);
|
||||
|
||||
@@ -19,7 +19,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.io.support.AbstractTransactionalIoSource;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.KeyedItemReader;
|
||||
import org.springframework.batch.item.ResourceLifecycle;
|
||||
import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationManager;
|
||||
import org.springframework.batch.restart.RestartData;
|
||||
@@ -51,7 +51,7 @@ import org.springframework.util.Assert;
|
||||
* @since 1.0
|
||||
*/
|
||||
public class DrivingQueryItemReader extends AbstractTransactionalIoSource
|
||||
implements ItemReader, ResourceLifecycle, InitializingBean,
|
||||
implements KeyedItemReader, ResourceLifecycle, InitializingBean,
|
||||
DisposableBean, Restartable {
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
|
||||
package org.springframework.batch.item;
|
||||
|
||||
import org.springframework.batch.item.reader.AbstractItemReader;
|
||||
|
||||
/**
|
||||
* Strategy interface for providing the data for a given batch stage execution.
|
||||
* <br/>
|
||||
* Strategy interface for providing the data. <br/>
|
||||
*
|
||||
* Implementations are expected to be stateful and will be called multiple times
|
||||
* for each batch, with each call to {@link #next} returning a different value
|
||||
@@ -26,8 +27,8 @@ package org.springframework.batch.item;
|
||||
*
|
||||
* Implementations need to be thread safe and clients of a {@link ItemReader}
|
||||
* need to be aware that this is the case. Clients can code to this interface
|
||||
* without worrying about thread safety by using the AbstractItemProvider base
|
||||
* class.<br/>
|
||||
* without worrying about thread safety by using the {@link AbstractItemReader}
|
||||
* base class.<br/>
|
||||
*
|
||||
* A richer interface (e.g. with a look ahead or peek) is not feasible because
|
||||
* we need to support transactions in an asynchronous batch.
|
||||
@@ -50,15 +51,6 @@ public interface ItemReader {
|
||||
*/
|
||||
Object read() throws Exception;
|
||||
|
||||
/**
|
||||
* Get a unique identifier for the item that can be used to cache it between
|
||||
* calls if necessary, and then identify it later.
|
||||
*
|
||||
* @param item the current item.
|
||||
* @return a unique identifier.
|
||||
*/
|
||||
Object getKey(Object item);
|
||||
|
||||
/**
|
||||
* Close the reader, freeing any resources that may have been allocated
|
||||
* since the first call to read().
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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.item;
|
||||
|
||||
/**
|
||||
* Extension of the {@link ItemReader} interface that allows items to be
|
||||
* identified and tagged by a unique key.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public interface KeyedItemReader extends ItemReader {
|
||||
|
||||
/**
|
||||
* Get a unique identifier for the item that can be used to cache it between
|
||||
* calls if necessary, and then identify it later.
|
||||
*
|
||||
* @param item the current item.
|
||||
* @return a unique identifier.
|
||||
*/
|
||||
Object getKey(Object item);
|
||||
|
||||
}
|
||||
@@ -24,18 +24,11 @@ import org.springframework.batch.item.ItemReader;
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractItemReader implements ItemReader {
|
||||
|
||||
/**
|
||||
* Simply returns the item itself. Will be adequate for many purposes, but
|
||||
* not (for example) if the item is a message - in which case the identifier
|
||||
* should be used.
|
||||
*
|
||||
* @see org.springframework.batch.item.ItemReader#getKey(java.lang.Object)
|
||||
*/
|
||||
public Object getKey(Object item) {
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemReader#close()
|
||||
*/
|
||||
public void close() throws Exception {
|
||||
}
|
||||
|
||||
|
||||
@@ -33,11 +33,11 @@ public class ItemReaderAdapter extends AbstractMethodInvokingDelegator implement
|
||||
return invokeDelegateMethod();
|
||||
}
|
||||
|
||||
//harmless implementation of method required by ItemReader interface
|
||||
public Object getKey(Object item) {
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
*
|
||||
* @see org.springframework.batch.item.ItemReader#close()
|
||||
*/
|
||||
public void close() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.item.FailedItemIdentifier;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.KeyedItemReader;
|
||||
import org.springframework.batch.item.exception.UnexpectedInputException;
|
||||
import org.springframework.jms.JmsException;
|
||||
import org.springframework.jms.core.JmsOperations;
|
||||
@@ -39,7 +40,7 @@ import org.springframework.util.Assert;
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class JmsItemReader extends AbstractItemReader implements FailedItemIdentifier {
|
||||
public class JmsItemReader extends AbstractItemReader implements KeyedItemReader, FailedItemIdentifier {
|
||||
|
||||
protected Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
@@ -151,7 +152,7 @@ public class JmsItemReader extends AbstractItemReader implements FailedItemIdent
|
||||
throw new UnexpectedInputException("Could not extract message ID", e);
|
||||
}
|
||||
}
|
||||
return super.getKey(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemRecoverer;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.KeyedItemReader;
|
||||
import org.springframework.batch.retry.RetryCallback;
|
||||
import org.springframework.batch.retry.RetryContext;
|
||||
import org.springframework.batch.retry.RetryPolicy;
|
||||
@@ -47,13 +48,13 @@ public class ItemReaderRetryCallback implements RetryCallback {
|
||||
public static final String ITEM = ItemReaderRetryCallback.class.getName()
|
||||
+ ".ITEM";
|
||||
|
||||
private ItemReader provider;
|
||||
private KeyedItemReader provider;
|
||||
|
||||
private ItemWriter writer;
|
||||
|
||||
private ItemRecoverer recoverer;
|
||||
|
||||
public ItemReaderRetryCallback(ItemReader provider,
|
||||
public ItemReaderRetryCallback(KeyedItemReader provider,
|
||||
ItemWriter writer) {
|
||||
super();
|
||||
this.provider = provider;
|
||||
@@ -127,7 +128,7 @@ public class ItemReaderRetryCallback implements RetryCallback {
|
||||
*
|
||||
* @return the {@link ItemReader} instance.
|
||||
*/
|
||||
public ItemReader getReader() {
|
||||
public KeyedItemReader getReader() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ package org.springframework.batch.retry.policy;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.item.FailedItemIdentifier;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemRecoverer;
|
||||
import org.springframework.batch.item.KeyedItemReader;
|
||||
import org.springframework.batch.repeat.synch.RepeatSynchronizationManager;
|
||||
import org.springframework.batch.retry.RetryCallback;
|
||||
import org.springframework.batch.retry.RetryContext;
|
||||
@@ -109,7 +109,7 @@ public class ItemReaderRetryPolicy extends AbstractStatefulRetryPolicy {
|
||||
public RetryContext open(RetryCallback callback) {
|
||||
Assert.state(callback instanceof ItemReaderRetryCallback,
|
||||
"Callback must be ItemProviderRetryCallback");
|
||||
ItemProviderRetryContext context = new ItemProviderRetryContext(
|
||||
ItemReaderRetryContext context = new ItemReaderRetryContext(
|
||||
(ItemReaderRetryCallback) callback);
|
||||
context.open(callback);
|
||||
return context;
|
||||
@@ -137,7 +137,7 @@ public class ItemReaderRetryPolicy extends AbstractStatefulRetryPolicy {
|
||||
return ((RetryPolicy) context).handleRetryExhausted(context);
|
||||
}
|
||||
|
||||
private class ItemProviderRetryContext extends RetryContextSupport
|
||||
private class ItemReaderRetryContext extends RetryContextSupport
|
||||
implements RetryPolicy {
|
||||
|
||||
private Object item;
|
||||
@@ -145,11 +145,11 @@ public class ItemReaderRetryPolicy extends AbstractStatefulRetryPolicy {
|
||||
// The delegate context...
|
||||
private RetryContext delegateContext;
|
||||
|
||||
private ItemReader reader;
|
||||
private KeyedItemReader reader;
|
||||
|
||||
private ItemRecoverer recoverer;
|
||||
|
||||
public ItemProviderRetryContext(ItemReaderRetryCallback callback) {
|
||||
public ItemReaderRetryContext(ItemReaderRetryCallback callback) {
|
||||
super(RetrySynchronizationManager.getContext());
|
||||
item = callback.next(this);
|
||||
this.reader = callback.getReader();
|
||||
@@ -239,7 +239,7 @@ public class ItemReaderRetryPolicy extends AbstractStatefulRetryPolicy {
|
||||
* @param item
|
||||
* @return
|
||||
*/
|
||||
protected boolean hasFailed(ItemReader provider, Object item) {
|
||||
protected boolean hasFailed(KeyedItemReader provider, Object item) {
|
||||
if (provider instanceof FailedItemIdentifier) {
|
||||
return ((FailedItemIdentifier) provider).hasFailed(item);
|
||||
}
|
||||
|
||||
@@ -41,14 +41,6 @@ public class DelegatingItemReaderIntegrationTests extends AbstractDependencyInje
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* getKey(..) is implemented trivially.
|
||||
*/
|
||||
public void testGetKey() {
|
||||
Object item = new Object();
|
||||
assertSame(item, provider.getKey(item));
|
||||
}
|
||||
|
||||
public void setProvider(ItemReaderAdapter provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@@ -18,11 +18,11 @@ package org.springframework.batch.retry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemRecoverer;
|
||||
import org.springframework.batch.item.KeyedItemReader;
|
||||
import org.springframework.batch.item.reader.ListItemReader;
|
||||
|
||||
public class ListItemReaderRecoverer extends ListItemReader implements ItemReader, ItemRecoverer {
|
||||
public class ListItemReaderRecoverer extends ListItemReader implements KeyedItemReader, ItemRecoverer {
|
||||
|
||||
/**
|
||||
* Delegate to super class constructor.
|
||||
@@ -43,5 +43,14 @@ public class ListItemReaderRecoverer extends ListItemReader implements ItemReade
|
||||
public boolean recover(Object item, Throwable cause) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the item (assume it is its own key).
|
||||
*
|
||||
* @see org.springframework.batch.item.KeyedItemReader#getKey(java.lang.Object)
|
||||
*/
|
||||
public Object getKey(Object item) {
|
||||
return item;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.item.reader.ListItemReader;
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.retry.ListItemReaderRecoverer;
|
||||
import org.springframework.batch.retry.RetryContext;
|
||||
@@ -40,7 +39,7 @@ public class ItemReaderRetryCallbackTests extends TestCase {
|
||||
|
||||
RetryTemplate template;
|
||||
|
||||
ListItemReader provider;
|
||||
ListItemReaderRecoverer provider;
|
||||
|
||||
ItemReaderRetryCallback callback;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.List;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.item.FailedItemIdentifier;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.KeyedItemReader;
|
||||
import org.springframework.batch.item.reader.ListItemReader;
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
@@ -41,7 +41,7 @@ public class ItemReaderRetryPolicyTests extends TestCase {
|
||||
|
||||
private ItemReaderRetryPolicy policy = new ItemReaderRetryPolicy();
|
||||
|
||||
private ItemReader provider;
|
||||
private org.springframework.batch.item.KeyedItemReader provider;
|
||||
|
||||
private int count = 0;
|
||||
|
||||
@@ -299,7 +299,7 @@ public class ItemReaderRetryPolicyTests extends TestCase {
|
||||
assertTrue(policy.hasFailed(provider, "foo"));
|
||||
}
|
||||
|
||||
private static class MockFailedItemProvider extends ListItemReader implements FailedItemIdentifier {
|
||||
private static class MockFailedItemProvider extends ListItemReader implements KeyedItemReader, FailedItemIdentifier {
|
||||
|
||||
private int hasFailedCount = 0;
|
||||
|
||||
|
||||
@@ -21,5 +21,8 @@ import org.springframework.batch.item.reader.AbstractItemReader;
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractItemReaderRecoverer extends AbstractItemReader implements ItemRecoverer {
|
||||
public abstract class AbstractItemReaderRecoverer extends AbstractItemReader implements KeyedItemReader, ItemRecoverer {
|
||||
public Object getKey(Object item) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.util.List;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.batch.item.AbstractItemReaderRecoverer;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.KeyedItemReader;
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.RepeatCallback;
|
||||
@@ -48,7 +48,7 @@ public class ExternalRetryInBatchTests extends AbstractDependencyInjectionSpring
|
||||
|
||||
private RepeatTemplate repeatTemplate;
|
||||
|
||||
private ItemReader provider;
|
||||
private KeyedItemReader provider;
|
||||
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.util.List;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.batch.item.AbstractItemReaderRecoverer;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.KeyedItemReader;
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.retry.callback.ItemReaderRetryCallback;
|
||||
import org.springframework.batch.retry.policy.ItemReaderRetryPolicy;
|
||||
@@ -41,7 +41,7 @@ public class ExternalRetryTests extends AbstractDependencyInjectionSpringContext
|
||||
|
||||
private RetryTemplate retryTemplate;
|
||||
|
||||
private ItemReader provider;
|
||||
private KeyedItemReader provider;
|
||||
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.execution.scope.StepContext;
|
||||
import org.springframework.batch.execution.scope.StepContextAware;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.KeyedItemReader;
|
||||
import org.springframework.batch.item.ResourceLifecycle;
|
||||
import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationManager;
|
||||
import org.springframework.batch.sample.item.writer.StagingItemWriter;
|
||||
@@ -26,7 +26,7 @@ import org.springframework.transaction.support.TransactionSynchronizationAdapter
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class StagingItemReader extends JdbcDaoSupport implements ItemReader, ResourceLifecycle, DisposableBean,
|
||||
public class StagingItemReader extends JdbcDaoSupport implements KeyedItemReader, ResourceLifecycle, DisposableBean,
|
||||
StepContextAware {
|
||||
|
||||
// Key for buffer in transaction synchronization manager
|
||||
|
||||
Reference in New Issue
Block a user