diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/support/AbstractStepFactoryBean.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/support/AbstractStepFactoryBean.java new file mode 100644 index 000000000..21e641b45 --- /dev/null +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/support/AbstractStepFactoryBean.java @@ -0,0 +1,173 @@ +/* + * 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.execution.step.support; + +import org.springframework.batch.core.domain.Step; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.execution.step.ItemOrientedStep; +import org.springframework.batch.item.ItemReader; +import org.springframework.batch.item.ItemWriter; +import org.springframework.beans.factory.BeanNameAware; +import org.springframework.beans.factory.config.AbstractFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.util.Assert; + +/** + * Base class for factory beans for {@link ItemOrientedStep}. Ensures that all + * the mandatory properties are set, and provides basic support for the + * {@link Step} interface responsibilities like start limit. + * + * @author Dave Syer + * + */ +public abstract class AbstractStepFactoryBean extends AbstractFactoryBean implements BeanNameAware { + + private String name; + + private int startLimit = Integer.MAX_VALUE; + + private boolean allowStartIfComplete; + + private ItemReader itemReader; + + private ItemWriter itemWriter; + + private PlatformTransactionManager transactionManager; + + private JobRepository jobRepository; + + /** + * + */ + public AbstractStepFactoryBean() { + super(); + } + + /** + * Set the bean name property, which will become the name of the + * {@link Step} when it is created. + * + * @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String) + */ + public void setBeanName(String name) { + this.name = name; + } + + /** + * Public getter for the String. + * @return the name + */ + public String getName() { + return name; + } + + /** + * Public setter for the startLimit. + * + * @param startLimit the startLimit to set + */ + public void setStartLimit(int startLimit) { + this.startLimit = startLimit; + } + + /** + * Public setter for the shouldAllowStartIfComplete. + * + * @param allowStartIfComplete the shouldAllowStartIfComplete to set + */ + public void setAllowStartIfComplete(boolean allowStartIfComplete) { + this.allowStartIfComplete = allowStartIfComplete; + } + + /** + * @param itemReader the itemReader to set + */ + public void setItemReader(ItemReader itemReader) { + this.itemReader = itemReader; + } + + /** + * @param itemWriter the itemWriter to set + */ + public void setItemWriter(ItemWriter itemWriter) { + this.itemWriter = itemWriter; + } + + /** + * Public setter for {@link JobRepository}. + * + * @param jobRepository is a mandatory dependence (no default). + */ + public void setJobRepository(JobRepository jobRepository) { + this.jobRepository = jobRepository; + } + + /** + * Public setter for the {@link PlatformTransactionManager}. + * + * @param transactionManager the transaction manager to set + */ + public void setTransactionManager(PlatformTransactionManager transactionManager) { + this.transactionManager = transactionManager; + } + + protected Object createInstance() throws Exception { + ItemOrientedStep step = new ItemOrientedStep(getName()); + applyConfiguration(step); + return step; + } + + /** + * @param step + * + */ + protected void applyConfiguration(ItemOrientedStep step) { + + Assert.notNull(getItemReader(), "ItemReader must be provided"); + Assert.notNull(getItemWriter(), "ItemWriter must be provided"); + Assert.notNull(jobRepository, "JobRepository must be provided"); + Assert.notNull(transactionManager, "TransactionManager must be provided"); + + step.setItemReader(getItemReader()); + step.setItemWriter(getItemWriter()); + step.setTransactionManager(transactionManager); + step.setJobRepository(jobRepository); + step.setStartLimit(startLimit); + step.setAllowStartIfComplete(allowStartIfComplete); + + } + + public Class getObjectType() { + return Step.class; + } + + /** + * Public getter for the ItemReader. + * @return the itemReader + */ + public ItemReader getItemReader() { + return itemReader; + } + + /** + * Public getter for the ItemWriter. + * @return the itemWriter + */ + public ItemWriter getItemWriter() { + return itemWriter; + } + +} \ No newline at end of file diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/support/KitchenSinkStepFactoryBean.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/support/KitchenSinkStepFactoryBean.java new file mode 100644 index 000000000..144b84fca --- /dev/null +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/support/KitchenSinkStepFactoryBean.java @@ -0,0 +1,160 @@ +/* + * 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.execution.step.support; + +import org.springframework.batch.core.domain.ItemSkipPolicy; +import org.springframework.batch.execution.step.ItemOrientedStep; +import org.springframework.batch.item.ItemKeyGenerator; +import org.springframework.batch.repeat.RepeatOperations; +import org.springframework.batch.repeat.exception.handler.ExceptionHandler; +import org.springframework.batch.repeat.policy.SimpleCompletionPolicy; +import org.springframework.batch.repeat.support.RepeatTemplate; +import org.springframework.batch.retry.RetryPolicy; +import org.springframework.batch.retry.callback.ItemReaderRetryCallback; +import org.springframework.batch.retry.policy.ItemReaderRetryPolicy; +import org.springframework.batch.retry.support.RetryTemplate; + +/** + * @author Dave Syer + * + */ +public class KitchenSinkStepFactoryBean extends AbstractStepFactoryBean { + + private int commitInterval = 0; + + private Object[] listeners = new Object[0]; + + private ItemSkipPolicy itemSkipPolicy = new NeverSkipItemSkipPolicy(); + + private RepeatOperations stepOperations = new RepeatTemplate(); + + private RetryPolicy retryPolicy = null; + + private ExceptionHandler exceptionHandler; + + private ItemKeyGenerator itemKeyGenerator; + + /** + * Set the commit interval. + * + * @param commitInterval + */ + public void setCommitInterval(int commitInterval) { + this.commitInterval = commitInterval; + } + + /** + * @param listeners + */ + public void setListeners(Object[] listeners) { + this.listeners = listeners; + } + + /** + * @param itemSkipPolicy + */ + public void setItemSkipPolicy(ItemSkipPolicy itemSkipPolicy) { + this.itemSkipPolicy = itemSkipPolicy; + } + + /** + * Public setter for the RepeatOperations. + * @param stepOperations the stepOperations to set + */ + public void setStepOperations(RepeatOperations stepOperations) { + this.stepOperations = stepOperations; + } + + /** + * Public setter for the {@link RetryPolicy}. + * @param retryPolicy the {@link RetryPolicy} to set + */ + public void setRetryPolicy(RetryPolicy retryPolicy) { + this.retryPolicy = retryPolicy; + } + + /** + * Set the {@link ExceptionHandler} for the step operations (outer loop). + * @param exceptionHandler + */ + public void setExceptionHandler(ExceptionHandler exceptionHandler) { + this.exceptionHandler = exceptionHandler; + } + + /** + * Public setter for the {@link ItemKeyGenerator}. If it is not injected + * but the reader or writer implement {@link ItemKeyGenerator}, one of + * those will be used instead (preferring the reader to the writer if both + * would be appropriate). + * + * @param itemKeyGenerator the {@link ItemKeyGenerator} to set + */ + public void setItemKeyGenerator(ItemKeyGenerator itemKeyGenerator) { + this.itemKeyGenerator = itemKeyGenerator; + } + + /** + * @param step + * + */ + protected void applyConfiguration(ItemOrientedStep step) { + + super.applyConfiguration(step); + + step.setListeners(listeners); + step.setItemSkipPolicy(itemSkipPolicy); + + if (retryPolicy != null) { + ItemReaderRetryCallback retryCallback = new ItemReaderRetryCallback(getItemReader(), getKeyGenerator(), + getItemWriter()); + ItemReaderRetryPolicy itemProviderRetryPolicy = new ItemReaderRetryPolicy(retryPolicy); + RetryTemplate template = new RetryTemplate(); + template.setRetryPolicy(itemProviderRetryPolicy); + step.setRetryOperations(template); + step.setRetryCallback(retryCallback); + } + + if (commitInterval > 0) { + RepeatTemplate chunkOperations = new RepeatTemplate(); + chunkOperations.setCompletionPolicy(new SimpleCompletionPolicy(commitInterval)); + step.setChunkOperations(chunkOperations); + } + + if (exceptionHandler != null && stepOperations instanceof RepeatTemplate) { + ((RepeatTemplate) stepOperations).setExceptionHandler(exceptionHandler); + step.setStepOperations(stepOperations); + } + } + + /** + * @return an {@link ItemKeyGenerator} or null if none is found. + */ + private ItemKeyGenerator getKeyGenerator() { + + if (itemKeyGenerator != null) { + return itemKeyGenerator; + } + if (getItemReader() instanceof ItemKeyGenerator) { + return (ItemKeyGenerator) getItemReader(); + } + if (getItemWriter() instanceof ItemKeyGenerator) { + return (ItemKeyGenerator) getItemWriter(); + } + return null; + + } + +} diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobTests.java index e61412f5d..d22a601fa 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobTests.java @@ -36,6 +36,7 @@ import org.springframework.batch.execution.repository.dao.MapJobInstanceDao; import org.springframework.batch.execution.repository.dao.MapStepExecutionDao; import org.springframework.batch.execution.step.AbstractStep; import org.springframework.batch.execution.step.ItemOrientedStep; +import org.springframework.batch.execution.step.support.AbstractStepFactoryBean; import org.springframework.batch.execution.step.support.SimpleStepFactoryBean; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; @@ -82,7 +83,7 @@ public class SimpleJobTests extends TestCase { } private ItemOrientedStep getStep(String[] args) throws Exception { - SimpleStepFactoryBean factory = new SimpleStepFactoryBean(); + AbstractStepFactoryBean factory = new SimpleStepFactoryBean(); factory.setSingleton(false); List items = TransactionAwareProxyFactory.createTransactionalList(); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/support/SimpleStepFactoryBeanTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/support/SimpleStepFactoryBeanTests.java index 7fb0810b0..a8bae7db3 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/support/SimpleStepFactoryBeanTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/support/SimpleStepFactoryBeanTests.java @@ -25,7 +25,7 @@ import org.springframework.batch.core.domain.Step; */ public class SimpleStepFactoryBeanTests extends TestCase { - private SimpleStepFactoryBean factory = new SimpleStepFactoryBean(); + private AbstractStepFactoryBean factory = new KitchenSinkStepFactoryBean(); public void testType() throws Exception { assertEquals(Step.class, factory.getObjectType()); diff --git a/spring-batch-execution/src/test/resources/job-configuration.xml b/spring-batch-execution/src/test/resources/job-configuration.xml index a624e785f..289e54d50 100644 --- a/spring-batch-execution/src/test/resources/job-configuration.xml +++ b/spring-batch-execution/src/test/resources/job-configuration.xml @@ -29,6 +29,10 @@ + + diff --git a/spring-batch-execution/src/test/resources/org/springframework/batch/execution/configuration/test-context.xml b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/configuration/test-context.xml index dcb20a8a6..a46d69055 100644 --- a/spring-batch-execution/src/test/resources/org/springframework/batch/execution/configuration/test-context.xml +++ b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/configuration/test-context.xml @@ -20,7 +20,7 @@ - + diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/io/cursor/JdbcCursorItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/io/cursor/JdbcCursorItemReader.java index 116794663..672869219 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/io/cursor/JdbcCursorItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/io/cursor/JdbcCursorItemReader.java @@ -30,7 +30,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.batch.io.Skippable; import org.springframework.batch.item.ExecutionContext; -import org.springframework.batch.item.ItemKeyGenerator; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemStream; import org.springframework.batch.item.exception.ResetFailedException; @@ -48,68 +47,62 @@ import org.springframework.util.StringUtils; /** *

- * Simple input source that opens a Sql Cursor and continually retrieves the + * Simple input source that opens a JDBC cursor and continually retrieves the * next row in the ResultSet. It is extremely important to note that the * JdbcDriver used must be version 3.0 or higher. This is because earlier * versions do not support holding a ResultSet open over commits. *

* *

- * Each call to read() will call the provided RowMapper, (NOTE: Calling read() - * without setting a RowMapper will result in an IllegalStateException!) passing - * in the ResultSet. If this is the first call to read(), the provided query - * will be run in order to open the cursor. There is currently no wrapping of - * the ResultSet to suppress calls to next(). However, if the RowMapper - * increments the current row, the next call to read will verify that the - * current row is at the expected position and throw a DataAccessException if it - * is not. This means that, in theory, a RowMapper could read ahead, as long as - * it returns the row back to it's correct position before returning. The reason - * for such strictness on the ResultSet is due to the need to maintain strict - * control for Transactions, restartability and skippability. This ensures that - * each call to read() returns the ResultSet at the correct line, regardless of + * Each call to {@link #read()} will call the provided RowMapper, passing in the + * ResultSet. There is currently no wrapping of the ResultSet to suppress calls + * to next(). However, if the RowMapper (mistakenly) increments the current row, + * the next call to read will verify that the current row is at the expected + * position and throw a DataAccessException if it is not. This means that, in + * theory, a RowMapper could read ahead, as long as it returns the row back to + * the correct position before returning. The reason for such strictness on the + * ResultSet is due to the need to maintain control for transactions, + * restartability and skippability. This ensures that each call to + * {@link #read()} returns the ResultSet at the correct line, regardless of * rollbacks, restarts, or skips. *

* *

- * {@link ExecutionContext}: The current row is returned as restart data, - * and when restored from that same data, the cursor is opened and the current - * row set to the value within the restart data. There are also two statistics - * returned by this input source: the current line being processed and the - * number of lines that have been skipped. + * {@link ExecutionContext}: The current row is returned as restart data, and + * when restored from that same data, the cursor is opened and the current row + * set to the value within the restart data. Two values are stored: the current + * line being processed and the number of lines that have been skipped. *

* *

- * Transactions: At first glance, it may appear odd that Spring's - * TransactionSynchronization abstraction is used for something that is reading - * from the database, however, it is important because the same resultset is - * held open regardless of commits or roll backs. This means that when a - * transaction is committed, the input source is notified so that it can save - * it's current row number. Later, if the transaction is rolled back, the - * current row can be moved back to the same row number as it was on when commit - * was called. + * Transactions: The same ResultSet is held open regardless of commits or roll + * backs in a surrounding transaction. This means that when such a transaction + * is committed, the input source is notified through the {@link #mark()} and + * {@link #reset()} so that it can save it's current row number. Later, if the + * transaction is rolled back, the current row can be moved back to the same row + * number as it was on when commit was called. *

* *

- * Calling skip will indicate to the input source that a record is bad and - * should not be represented to the user if the transaction is rolled back. For - * example, if row 2 is read in, and found to be bad, calling skip will inform - * the Input Source. If reading is then continued, and a rollback is necessary - * because of an error on output, the input source will be returned to row 1. - * Calling read while on row 1 will move the current row to 3, not 2, because 2 - * has been marked as skipped. + * Calling skip will indicate that a record is bad and should not be + * re-presented to the user if the transaction is rolled back. For example, if + * row 2 is read in, and found to be bad, calling skip will inform the + * {@link ItemReader}. If reading is then continued, and a rollback is + * necessary because of an error on output, the input source will be returned to + * row 1. Calling read while on row 1 will move the current row to 3, not 2, + * because 2 has been marked as skipped. *

* *

- * Calling close on this Input Source will cause all resources it is currently - * using to be freed. (Connection, resultset, etc). If read() is called on the - * same instance again, the cursor will simply be reopened starting at row 0. + * Calling close on this {@link ItemStream} will cause all resources it is + * currently using to be freed. (Connection, ResultSet, etc). It is then illegal + * to call {@link #read()} again until it has been opened. *

* * @author Lucas Ward * @author Peter Zozom */ -public class JdbcCursorItemReader implements ItemReader, ItemKeyGenerator, InitializingBean, - ItemStream, Skippable { +public class JdbcCursorItemReader implements ItemReader, InitializingBean, ItemStream, Skippable { private static Log log = LogFactory.getLog(JdbcCursorItemReader.class); @@ -155,9 +148,9 @@ public class JdbcCursorItemReader implements ItemReader, ItemKeyGenerator, Initi private RowMapper mapper; private boolean initialized = false; - + private boolean saveState = false; - + private String name = JdbcCursorItemReader.class.getName(); /** @@ -385,7 +378,7 @@ public class JdbcCursorItemReader implements ItemReader, ItemKeyGenerator, Initi * @see org.springframework.batch.item.stream.ItemStreamAdapter#getExecutionContext() */ public void update(ExecutionContext executionContext) { - if(saveState){ + if (saveState) { Assert.notNull(executionContext, "ExecutionContext must not be null"); String skipped = skippedRows.toString(); executionContext.putString(addName(SKIPPED_ROWS), skipped.substring(1, skipped.length() - 1)); @@ -517,22 +510,14 @@ public class JdbcCursorItemReader implements ItemReader, ItemKeyGenerator, Initi this.sql = sql; } - /** - * Return the item itself (which is already a key). - * @see org.springframework.batch.item.ItemReader#getKey(java.lang.Object) - */ - public Object getKey(Object item) { - return item; - } - public void setName(String name) { this.name = name; } - - public String addName(String key){ + + public String addName(String key) { return name + "." + key; } - + public void setSaveState(boolean saveState) { this.saveState = saveState; } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/io/driving/DrivingQueryItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/io/driving/DrivingQueryItemReader.java index 907b3b0b7..ef703b930 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/io/driving/DrivingQueryItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/io/driving/DrivingQueryItemReader.java @@ -19,7 +19,6 @@ import java.util.Iterator; import java.util.List; import org.springframework.batch.item.ExecutionContext; -import org.springframework.batch.item.ItemKeyGenerator; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemStream; import org.springframework.beans.factory.InitializingBean; @@ -47,7 +46,7 @@ import org.springframework.util.Assert; * @author Lucas Ward * @since 1.0 */ -public class DrivingQueryItemReader implements ItemReader, ItemKeyGenerator, InitializingBean, +public class DrivingQueryItemReader implements ItemReader, InitializingBean, ItemStream { private boolean initialized = false; @@ -174,15 +173,6 @@ public class DrivingQueryItemReader implements ItemReader, ItemKeyGenerator, Ini reset(); } - /** - * Return the item itself (which is already a key). - * - * @see org.springframework.batch.item.ItemReader#getKey(java.lang.Object) - */ - public Object getKey(Object item) { - return item; - } - /** * Mark is supported as long as this {@link ItemStream} is used in a * single-threaded environment. The state backing the mark is a single diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/io/xml/StaxEventItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/io/xml/StaxEventItemReader.java index bf5e9ef9e..aaf367b40 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/io/xml/StaxEventItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/io/xml/StaxEventItemReader.java @@ -20,7 +20,6 @@ import org.springframework.batch.item.ExecutionContext; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemStream; import org.springframework.batch.item.exception.StreamException; -import org.springframework.batch.item.reader.AbstractItemReader; import org.springframework.beans.factory.InitializingBean; import org.springframework.core.io.Resource; import org.springframework.dao.DataAccessResourceFailureException; @@ -36,7 +35,7 @@ import org.springframework.util.Assert; * * @author Robert Kasanicky */ -public class StaxEventItemReader extends AbstractItemReader implements ItemReader, Skippable, ItemStream, +public class StaxEventItemReader implements ItemReader, Skippable, ItemStream, InitializingBean { public static final String READ_COUNT_STATISTICS_NAME = "StaxEventReaderItemReader.readCount"; diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/reader/AbstractItemReaderRecoverer.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/reader/AbstractItemReaderRecoverer.java deleted file mode 100644 index 190806f19..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/reader/AbstractItemReaderRecoverer.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.reader; - -import org.springframework.batch.item.ItemRecoverer; -import org.springframework.batch.item.ItemKeyGenerator; - - -/** - * @author Dave Syer - * - */ -public abstract class AbstractItemReaderRecoverer extends AbstractItemReader implements ItemKeyGenerator, ItemRecoverer { - public Object getKey(Object item) { - return item; - } -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/reader/DelegatingItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/reader/DelegatingItemReader.java index 0f8a28e8b..38b8e42fc 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/reader/DelegatingItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/reader/DelegatingItemReader.java @@ -18,7 +18,6 @@ package org.springframework.batch.item.reader; import org.springframework.batch.io.Skippable; import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.ItemKeyGenerator; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; @@ -29,7 +28,7 @@ import org.springframework.util.Assert; * * @author Dave Syer */ -public class DelegatingItemReader extends AbstractItemReader implements Skippable, InitializingBean, ItemKeyGenerator { +public class DelegatingItemReader extends AbstractItemReader implements Skippable, InitializingBean { private ItemReader itemReader; @@ -54,13 +53,6 @@ public class DelegatingItemReader extends AbstractItemReader implements Skippabl this.itemReader = source; } - /* (non-Javadoc) - * @see org.springframework.batch.item.KeyedItemReader#getKey(java.lang.Object) - */ - public Object getKey(Object item) { - return item; - } - public void skip() { if (itemReader instanceof Skippable) { ((Skippable) itemReader).skip(); diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/reader/JmsItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/reader/JmsItemReader.java index 007259119..7b80e8f3c 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/reader/JmsItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/reader/JmsItemReader.java @@ -23,8 +23,9 @@ import javax.jms.Message; 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.ItemKeyGenerator; +import org.springframework.batch.item.ItemReader; +import org.springframework.batch.item.ItemRecoverer; import org.springframework.batch.item.exception.UnexpectedInputException; import org.springframework.jms.JmsException; import org.springframework.jms.core.JmsOperations; @@ -40,7 +41,7 @@ import org.springframework.util.Assert; * @author Dave Syer * */ -public class JmsItemReader extends AbstractItemReader implements ItemKeyGenerator, FailedItemIdentifier { +public class JmsItemReader extends AbstractItemReader implements ItemRecoverer, ItemKeyGenerator, FailedItemIdentifier { protected Log logger = LogFactory.getLog(getClass()); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/io/driving/FooInputSource.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/io/driving/FooInputSource.java index 9d826f2d7..ab9adedd4 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/io/driving/FooInputSource.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/io/driving/FooInputSource.java @@ -1,14 +1,13 @@ package org.springframework.batch.io.driving; +import org.springframework.batch.item.ExecutionContext; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemStream; -import org.springframework.batch.item.ExecutionContext; -import org.springframework.batch.item.reader.AbstractItemReader; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.jdbc.core.JdbcTemplate; -class FooItemReader extends AbstractItemReader implements ItemStream, ItemReader, DisposableBean, InitializingBean { +class FooItemReader implements ItemStream, ItemReader, DisposableBean, InitializingBean { DrivingQueryItemReader inputSource; diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/retry/ListItemReaderRecoverer.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/retry/ListItemReaderRecoverer.java index 1d3b6ba5c..f8a001463 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/retry/ListItemReaderRecoverer.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/retry/ListItemReaderRecoverer.java @@ -18,11 +18,11 @@ package org.springframework.batch.retry; import java.util.List; -import org.springframework.batch.item.ItemRecoverer; import org.springframework.batch.item.ItemKeyGenerator; +import org.springframework.batch.item.ItemRecoverer; import org.springframework.batch.item.reader.ListItemReader; -public class ListItemReaderRecoverer extends ListItemReader implements ItemKeyGenerator, ItemRecoverer { +public class ListItemReaderRecoverer extends ListItemReader implements ItemRecoverer, ItemKeyGenerator { /** * Delegate to super class constructor. diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/jms/ExternalRetryInBatchTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/jms/ExternalRetryInBatchTests.java index c74d3fec3..d6db012d6 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/jms/ExternalRetryInBatchTests.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/jms/ExternalRetryInBatchTests.java @@ -22,7 +22,8 @@ import java.util.List; import javax.sql.DataSource; import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.reader.AbstractItemReaderRecoverer; +import org.springframework.batch.item.ItemRecoverer; +import org.springframework.batch.item.reader.AbstractItemReader; import org.springframework.batch.item.writer.AbstractItemWriter; import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.RepeatCallback; @@ -80,7 +81,7 @@ public class ExternalRetryInBatchTests extends AbstractDependencyInjectionSpring jdbcTemplate.execute("delete from T_FOOS"); jmsTemplate.convertAndSend("queue", "foo"); jmsTemplate.convertAndSend("queue", "bar"); - provider = new AbstractItemReaderRecoverer() { + provider = new ItemReaderRecoverer() { public Object read() { String text = (String) jmsTemplate.receiveAndConvert("queue"); list.add(text); @@ -138,7 +139,7 @@ public class ExternalRetryInBatchTests extends AbstractDependencyInjectionSpring repeatTemplate.iterate(new RepeatCallback() { public ExitStatus doInIteration(RepeatContext context) throws Exception { - return new ExitStatus(retryTemplate.execute(callback)!=null); + return new ExitStatus(retryTemplate.execute(callback) != null); } }); @@ -193,4 +194,8 @@ public class ExternalRetryInBatchTests extends AbstractDependencyInjectionSpring } return msgs; } + + private abstract class ItemReaderRecoverer extends AbstractItemReader implements ItemRecoverer { + + } } diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java index 44ecc827c..f63bb6230 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java @@ -22,7 +22,8 @@ import java.util.List; import javax.sql.DataSource; import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.reader.AbstractItemReaderRecoverer; +import org.springframework.batch.item.ItemRecoverer; +import org.springframework.batch.item.reader.AbstractItemReader; import org.springframework.batch.item.writer.AbstractItemWriter; import org.springframework.batch.retry.callback.ItemReaderRetryCallback; import org.springframework.batch.retry.policy.ItemReaderRetryPolicy; @@ -68,7 +69,7 @@ public class ExternalRetryTests extends AbstractDependencyInjectionSpringContext getMessages(); // drain queue jdbcTemplate.execute("delete from T_FOOS"); jmsTemplate.convertAndSend("queue", "foo"); - provider = new AbstractItemReaderRecoverer() { + provider = new ItemReaderRecoverer() { public Object read() { String text = (String) jmsTemplate.receiveAndConvert("queue"); list.add(text); @@ -230,4 +231,9 @@ public class ExternalRetryTests extends AbstractDependencyInjectionSpringContext } return msgs; } + + private abstract class ItemReaderRecoverer extends AbstractItemReader implements ItemRecoverer { + + } + } diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/item/reader/GeneratingItemReader.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/item/reader/GeneratingItemReader.java index 58f982e4f..36875adc7 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/item/reader/GeneratingItemReader.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/item/reader/GeneratingItemReader.java @@ -2,10 +2,10 @@ package org.springframework.batch.sample.item.reader; import java.math.BigDecimal; -import org.springframework.batch.item.ExecutionContext; +import org.springframework.batch.item.ItemReader; +import org.springframework.batch.item.ItemRecoverer; import org.springframework.batch.item.exception.MarkFailedException; import org.springframework.batch.item.exception.ResetFailedException; -import org.springframework.batch.item.reader.AbstractItemReaderRecoverer; import org.springframework.batch.sample.domain.Trade; /** @@ -13,7 +13,7 @@ import org.springframework.batch.sample.domain.Trade; * * @author Robert Kasanicky */ -public class GeneratingItemReader extends AbstractItemReaderRecoverer { +public class GeneratingItemReader implements ItemReader, ItemRecoverer { private int limit = 1; @@ -70,10 +70,4 @@ public class GeneratingItemReader extends AbstractItemReaderRecoverer { this.counter = this.marked; } - /* (non-Javadoc) - * @see org.springframework.batch.item.ItemStream#restoreFrom(org.springframework.batch.item.ExecutionContext) - */ - public void restoreFrom(ExecutionContext context) { - } - } diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/item/reader/StagingItemReader.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/item/reader/StagingItemReader.java index a0a3c936e..8a257ce76 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/item/reader/StagingItemReader.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/item/reader/StagingItemReader.java @@ -12,7 +12,6 @@ import org.apache.commons.logging.LogFactory; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepListener; import org.springframework.batch.item.ExecutionContext; -import org.springframework.batch.item.ItemKeyGenerator; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemStream; import org.springframework.batch.item.exception.StreamException; @@ -26,7 +25,7 @@ import org.springframework.jdbc.support.lob.LobHandler; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.util.Assert; -public class StagingItemReader extends JdbcDaoSupport implements ItemStream, ItemReader, ItemKeyGenerator, StepListener { +public class StagingItemReader extends JdbcDaoSupport implements ItemStream, ItemReader, StepListener { // Key for buffer in transaction synchronization manager private static final String BUFFER_KEY = StagingItemReader.class.getName() + ".BUFFER"; @@ -100,10 +99,6 @@ public class StagingItemReader extends JdbcDaoSupport implements ItemStream, Ite } - public Object getKey(Object item) { - return item; - } - public Object read() throws Exception { Long id = doRead(); diff --git a/spring-batch-samples/src/main/resources/simple-container-definition.xml b/spring-batch-samples/src/main/resources/simple-container-definition.xml index fa69c4321..8dcee6f10 100644 --- a/spring-batch-samples/src/main/resources/simple-container-definition.xml +++ b/spring-batch-samples/src/main/resources/simple-container-definition.xml @@ -95,7 +95,7 @@