BATCH-7: Remove transaction synchronization and state management from input/output sources (formerly buffering)

http://jira.springframework.org/browse/BATCH-7

Rename Restartable to ItemStream
This commit is contained in:
dsyer
2008-01-30 17:56:56 +00:00
parent 02f1ae5c0c
commit a2117e4f22
50 changed files with 398 additions and 403 deletions

View File

@@ -28,9 +28,9 @@ import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ResourceLifecycle;
import org.springframework.batch.item.reader.AbstractItemReader;
import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationManager;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.batch.stream.GenericStreamContext;
import org.springframework.batch.stream.ItemStream;
import org.springframework.batch.stream.StreamContext;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.transaction.support.TransactionSynchronization;
@@ -57,7 +57,7 @@ import org.springframework.util.StringUtils;
* @author Robert Kasanicky
* @author Dave Syer
*/
public class HibernateCursorItemReader extends AbstractItemReader implements ItemReader, Restartable,
public class HibernateCursorItemReader extends AbstractItemReader implements ItemReader, ItemStream,
Skippable, InitializingBean, DisposableBean, ResourceLifecycle {
private static final String RESTART_DATA_ROW_NUMBER_KEY = ClassUtils
@@ -187,20 +187,20 @@ public class HibernateCursorItemReader extends AbstractItemReader implements Ite
/**
* @return the current row number wrapped as <code>RestartData</code>
*/
public RestartData getRestartData() {
public StreamContext getRestartData() {
Properties props = new Properties();
props.setProperty(RESTART_DATA_ROW_NUMBER_KEY, ""+currentProcessedRow);
String skipped = skippedRows.toString();
props.setProperty(SKIPPED_ROWS, skipped.substring(1,
skipped.length() - 1));
return new GenericRestartData(props);
return new GenericStreamContext(props);
}
/**
* Sets the cursor to the received row number.
*/
public void restoreFrom(RestartData data) {
public void restoreFrom(StreamContext data) {
Assert
.state(!initialized,
"Cannot restore when already intialized. Call close() first before restore()");

View File

@@ -33,10 +33,10 @@ import org.springframework.batch.io.Skippable;
import org.springframework.batch.io.support.AbstractTransactionalIoSource;
import org.springframework.batch.item.KeyedItemReader;
import org.springframework.batch.item.ResourceLifecycle;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.batch.statistics.StatisticsProvider;
import org.springframework.batch.stream.GenericStreamContext;
import org.springframework.batch.stream.ItemStream;
import org.springframework.batch.stream.StreamContext;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataAccessException;
@@ -118,7 +118,7 @@ import org.springframework.util.StringUtils;
*/
public class JdbcCursorItemReader extends AbstractTransactionalIoSource
implements KeyedItemReader, ResourceLifecycle, DisposableBean,
InitializingBean, Restartable, StatisticsProvider, Skippable {
InitializingBean, ItemStream, StatisticsProvider, Skippable {
private static Log log = LogFactory.getLog(JdbcCursorItemReader.class);
@@ -406,11 +406,11 @@ public class JdbcCursorItemReader extends AbstractTransactionalIoSource
*
* @see org.springframework.batch.restart.Restartable#getRestartData()
*/
public RestartData getRestartData() {
public StreamContext getRestartData() {
String skipped = skippedRows.toString();
Properties statistics = getStatistics();
statistics.setProperty(SKIPPED_ROWS, skipped.substring(1,skipped.length()-1));
return new GenericRestartData(statistics);
return new GenericStreamContext(statistics);
}
/*
@@ -418,7 +418,7 @@ public class JdbcCursorItemReader extends AbstractTransactionalIoSource
*
* @see org.springframework.batch.restart.Restartable#restoreFrom(org.springframework.batch.restart.RestartData)
*/
public void restoreFrom(RestartData data) {
public void restoreFrom(StreamContext data) {
Assert.state(!initialized);
if (data == null)

View File

@@ -22,8 +22,8 @@ import org.springframework.batch.io.support.AbstractTransactionalIoSource;
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;
import org.springframework.batch.restart.Restartable;
import org.springframework.batch.stream.ItemStream;
import org.springframework.batch.stream.StreamContext;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
@@ -52,7 +52,7 @@ import org.springframework.util.Assert;
*/
public class DrivingQueryItemReader extends AbstractTransactionalIoSource
implements KeyedItemReader, ResourceLifecycle, InitializingBean,
DisposableBean, Restartable {
DisposableBean, ItemStream {
private boolean initialized = false;
@@ -171,7 +171,7 @@ public class DrivingQueryItemReader extends AbstractTransactionalIoSource
* @throws IllegalStateException
* if the input source has already been initialized.
*/
public final void restoreFrom(RestartData data) {
public final void restoreFrom(StreamContext data) {
Assert.notNull(data, "RestartData must not be null.");
Assert.notNull(data.getProperties(),
@@ -192,7 +192,7 @@ public class DrivingQueryItemReader extends AbstractTransactionalIoSource
}
}
public RestartData getRestartData() {
public StreamContext getRestartData() {
return keyGenerator.getKeyAsRestartData(getCurrentKey());
}

View File

@@ -2,7 +2,7 @@ package org.springframework.batch.io.driving;
import java.util.List;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.stream.StreamContext;
/**
* Strategy interface used to generate keys in driving query input.
@@ -24,7 +24,7 @@ public interface KeyGenerator {
* @return a list of keys.
* @throws IllegalArgumentException is restartData is null.
*/
List restoreKeys(RestartData restartData);
List restoreKeys(StreamContext streamContext);
/**
* Return the provided key as restart data.
@@ -34,5 +34,5 @@ public interface KeyGenerator {
* @throws IllegalArgumentException if key is null.
* @throws IllegalArgumentException if key is an incompatible type.
*/
RestartData getKeyAsRestartData(Object key);
StreamContext getKeyAsRestartData(Object key);
}

View File

@@ -12,7 +12,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.Map.Entry;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.stream.StreamContext;
import org.springframework.core.CollectionFactory;
import org.springframework.jdbc.core.ColumnMapRowMapper;
import org.springframework.jdbc.core.PreparedStatementSetter;
@@ -38,9 +38,9 @@ public class ColumnMapRestartDataRowMapper extends ColumnMapRowMapper implements
static final String KEY = ClassUtils.getQualifiedName(ColumnMapRestartDataRowMapper.class) + ".KEY.";
public PreparedStatementSetter createSetter(RestartData restartData) {
public PreparedStatementSetter createSetter(StreamContext streamContext) {
ColumnMapRestartData columnData = new ColumnMapRestartData(restartData.getProperties());
ColumnMapRestartData columnData = new ColumnMapRestartData(streamContext.getProperties());
List columns = new ArrayList();
for (Iterator iterator = columnData.keys.values().iterator(); iterator.hasNext();) {
@@ -51,7 +51,7 @@ public class ColumnMapRestartDataRowMapper extends ColumnMapRowMapper implements
return new ArgPreparedStatementSetter(columns.toArray());
}
public RestartData createRestartData(Object key) {
public StreamContext createRestartData(Object key) {
Assert.isInstanceOf(Map.class, key, "Key must be of type Map.");
Map keys = (Map)key;
@@ -60,7 +60,7 @@ public class ColumnMapRestartDataRowMapper extends ColumnMapRowMapper implements
}
private static class ColumnMapRestartData implements RestartData{
private static class ColumnMapRestartData implements StreamContext{
private final Map keys;

View File

@@ -5,8 +5,8 @@ import java.util.Properties;
import org.springframework.batch.io.driving.DrivingQueryItemReader;
import org.springframework.batch.io.driving.KeyGenerator;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.stream.GenericStreamContext;
import org.springframework.batch.stream.StreamContext;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.util.Assert;
@@ -44,19 +44,19 @@ public class IbatisKeyGenerator implements KeyGenerator {
*
* @see org.springframework.batch.restart.Restartable#getRestartData()
*/
public RestartData getKeyAsRestartData(Object key) {
public StreamContext getKeyAsRestartData(Object key) {
Properties props = new Properties();
props.setProperty(RESTART_KEY, key.toString());
return new GenericRestartData(props);
return new GenericStreamContext(props);
}
/**
* Restore the keys list given the provided restart data.
*
* @see org.springframework.batch.io.driving.DrivingQueryItemReader#restoreKeys(org.springframework.batch.restart.RestartData)
* @see org.springframework.batch.io.driving.DrivingQueryItemReader#restoreKeys(org.springframework.batch.stream.StreamContext)
*/
public List restoreKeys(RestartData data) {
public List restoreKeys(StreamContext data) {
Properties props = data.getProperties();
Object key = props.getProperty(RESTART_KEY);

View File

@@ -20,7 +20,7 @@ import java.util.List;
import org.springframework.batch.io.driving.DrivingQueryItemReader;
import org.springframework.batch.io.driving.KeyGenerator;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.stream.StreamContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -80,14 +80,14 @@ public class MultipleColumnJdbcKeyGenerator implements
/* (non-Javadoc)
* @see org.springframework.batch.io.sql.scratch.AbstractDrivingQueryItemReader#restoreKeys(org.springframework.batch.restart.RestartData)
*/
public List restoreKeys(RestartData restartData) {
public List restoreKeys(StreamContext streamContext) {
Assert.state(keyMapper != null, "KeyMapper must not be null.");
Assert.state(StringUtils.hasText(restartSql), "The RestartQuery must not be null or empty" +
" in order to restart.");
if (restartData.getProperties() != null) {
return jdbcTemplate.query(restartSql, keyMapper.createSetter(restartData), keyMapper);
if (streamContext.getProperties() != null) {
return jdbcTemplate.query(restartSql, keyMapper.createSetter(streamContext), keyMapper);
}
return new ArrayList();
@@ -96,7 +96,7 @@ public class MultipleColumnJdbcKeyGenerator implements
/* (non-Javadoc)
* @see org.springframework.batch.restart.Restartable#getRestartData()
*/
public RestartData getKeyAsRestartData(Object key) {
public StreamContext getKeyAsRestartData(Object key) {
Assert.state(keyMapper != null, "RestartDataConverter must not be null.");
return keyMapper.createRestartData(key);
}

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.batch.io.driving.support;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.stream.StreamContext;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.RowMapper;
@@ -40,14 +40,14 @@ public interface RestartDataRowMapper extends RowMapper {
* @return ResartData representing the composite key.
* @throws IllegalArgumentException if key is null or of an unsupported type.
*/
public RestartData createRestartData(Object key);
public StreamContext createRestartData(Object key);
/**
* Given the provided restart data, return a PreparedStatementSeter that can
* be used as parameters to a JdbcTemplate.
*
* @param restartData
* @param streamContext
* @return an array of objects that can be used as arguments to a JdbcTemplate.
*/
public PreparedStatementSetter createSetter(RestartData restartData);
public PreparedStatementSetter createSetter(StreamContext streamContext);
}

View File

@@ -21,8 +21,8 @@ import java.util.Properties;
import org.apache.commons.lang.ClassUtils;
import org.springframework.batch.io.driving.KeyGenerator;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.stream.GenericStreamContext;
import org.springframework.batch.stream.StreamContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SingleColumnRowMapper;
@@ -94,34 +94,34 @@ public class SingleColumnJdbcKeyGenerator implements KeyGenerator {
* @see KeyGenerator#getKeyAsRestartData()
* @throws IllegalArgumentException if key is null.
*/
public RestartData getKeyAsRestartData(Object key) {
public StreamContext getKeyAsRestartData(Object key) {
Assert.notNull(key, "The key must not be null.");
Properties props = new Properties();
props.setProperty(RESTART_KEY, key.toString());
return new GenericRestartData(props);
return new GenericStreamContext(props);
}
/**
* Return the remaining to be processed for the provided {@link RestartData}.
* Return the remaining to be processed for the provided {@link StreamContext}.
* The RestartData attempting to be restored from must have been obtained from the
* <strong>same KeyGenerationStrategy as the one
* being restored from</strong> otherwise it is invalid.
*
* @param RestartData obtained by calling getRestartData during a previous
* @param StreamContext obtained by calling getRestartData during a previous
* run.
* @throws IllegalStateException if restart sql statement is null.
* @throws IllegalArgumentException if restart data is null.
* @see KeyGenerator#restoreKeys(org.springframework.batch.restart.RestartData)
* @see KeyGenerator#restoreKeys(org.springframework.batch.stream.StreamContext)
*/
public List restoreKeys(RestartData restartData) {
public List restoreKeys(StreamContext streamContext) {
Assert.notNull(restartData, "The restart data must not be null.");
Assert.notNull(streamContext, "The restart data must not be null.");
Assert.state(StringUtils.hasText(restartSql), "The RestartQuery must not be null or empty" +
" in order to restart.");
String lastProcessedKey = restartData.getProperties().getProperty(RESTART_KEY);
String lastProcessedKey = streamContext.getProperties().getProperty(RESTART_KEY);
if (lastProcessedKey != null) {
return jdbcTemplate.query(restartSql, new Object[] { lastProcessedKey }, keyMapper);

View File

@@ -25,10 +25,10 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.batch.io.Skippable;
import org.springframework.batch.io.file.separator.LineReader;
import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationManager;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.batch.statistics.StatisticsProvider;
import org.springframework.batch.stream.GenericStreamContext;
import org.springframework.batch.stream.ItemStream;
import org.springframework.batch.stream.StreamContext;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
@@ -42,7 +42,7 @@ import org.springframework.transaction.support.TransactionSynchronizationAdapter
* @author Tomas Slanina
* @author Robert Kasanicky
*/
public class DefaultFlatFileItemReader extends SimpleFlatFileItemReader implements Skippable, Restartable,
public class DefaultFlatFileItemReader extends SimpleFlatFileItemReader implements Skippable, ItemStream,
StatisticsProvider {
private static Log log = LogFactory.getLog(DefaultFlatFileItemReader.class);
@@ -77,7 +77,7 @@ public class DefaultFlatFileItemReader extends SimpleFlatFileItemReader implemen
*
* @param restartData restartData information
*/
public void restoreFrom(RestartData data) {
public void restoreFrom(StreamContext data) {
if (data==null ||
data.getProperties() == null ||
@@ -104,8 +104,8 @@ public class DefaultFlatFileItemReader extends SimpleFlatFileItemReader implemen
* current Line Count which can be used to re initialise the batch job in
* case of restart.
*/
public RestartData getRestartData() {
return new GenericRestartData(getStatistics());
public StreamContext getRestartData() {
return new GenericStreamContext(getStatistics());
}
/**

View File

@@ -34,10 +34,10 @@ import org.springframework.batch.io.support.AbstractTransactionalIoSource;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.ResourceLifecycle;
import org.springframework.batch.item.writer.ItemTransformer;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.batch.statistics.StatisticsProvider;
import org.springframework.batch.stream.GenericStreamContext;
import org.springframework.batch.stream.ItemStream;
import org.springframework.batch.stream.StreamContext;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
@@ -61,7 +61,7 @@ import org.springframework.util.Assert;
* @author Dave Syer
*/
public class FlatFileItemWriter extends AbstractTransactionalIoSource implements
ItemWriter, ResourceLifecycle, Restartable, StatisticsProvider, InitializingBean,
ItemWriter, ResourceLifecycle, ItemStream, StatisticsProvider, InitializingBean,
DisposableBean {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
@@ -76,7 +76,7 @@ public class FlatFileItemWriter extends AbstractTransactionalIoSource implements
private Properties statistics = new Properties();
private RestartData restartData = new GenericRestartData(new Properties());
private StreamContext streamContext = new GenericStreamContext(new Properties());
private OutputState state = new OutputState();
@@ -258,19 +258,19 @@ public class FlatFileItemWriter extends AbstractTransactionalIoSource implements
}
/**
* @see Restartable#getRestartData()
* @see ItemStream#getRestartData()
*/
public RestartData getRestartData() {
public StreamContext getRestartData() {
final OutputState os = getOutputState();
restartData.getProperties().setProperty(RESTART_DATA_NAME, String.valueOf(os.position()));
return restartData;
streamContext.getProperties().setProperty(RESTART_DATA_NAME, String.valueOf(os.position()));
return streamContext;
}
/**
* @see Restartable#restoreFrom(RestartData)
* @see ItemStream#restoreFrom(StreamContext)
*/
public void restoreFrom(RestartData data) {
public void restoreFrom(StreamContext data) {
if (data == null)
return;

View File

@@ -21,10 +21,10 @@ import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ResourceLifecycle;
import org.springframework.batch.item.reader.AbstractItemReader;
import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationManager;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.batch.statistics.StatisticsProvider;
import org.springframework.batch.stream.GenericStreamContext;
import org.springframework.batch.stream.ItemStream;
import org.springframework.batch.stream.StreamContext;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
@@ -44,7 +44,7 @@ import org.springframework.util.Assert;
* @author Robert Kasanicky
*/
public class StaxEventItemReader extends AbstractItemReader implements ItemReader, ResourceLifecycle,
Skippable, Restartable, StatisticsProvider, InitializingBean, DisposableBean {
Skippable, ItemStream, StatisticsProvider, InitializingBean, DisposableBean {
public static final String READ_COUNT_STATISTICS_NAME = "StaxEventReaderItemReader.readCount";
@@ -192,26 +192,26 @@ public class StaxEventItemReader extends AbstractItemReader implements ItemReade
/**
* @return wrapped count of records read so far.
* @see Restartable#getRestartData()
* @see ItemStream#getRestartData()
*/
public RestartData getRestartData() {
public StreamContext getRestartData() {
Properties restartData = new Properties();
restartData.setProperty(RESTART_DATA_NAME, String.valueOf(currentRecordCount));
return new GenericRestartData(restartData);
return new GenericStreamContext(restartData);
}
/**
* Restores the input source for the given restart data by rereading and
* skipping the number of records stored in the RestartData.
*
* @param RestartData that holds the line count from the last commit.
* @param StreamContext that holds the line count from the last commit.
* @throws IllegalStateException if the ItemReader has already been
* initialized or if the number of records to read and skip exceeds the
* available records.
*/
public void restoreFrom(RestartData data) {
public void restoreFrom(StreamContext data) {
Assert.state(!initialized);
if (data == null || data.getProperties() == null || data.getProperties().getProperty(RESTART_DATA_NAME) == null) {
return;

View File

@@ -19,10 +19,10 @@ import org.springframework.batch.io.xml.stax.NoStartEndDocumentStreamWriter;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.ResourceLifecycle;
import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationManager;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.batch.statistics.StatisticsProvider;
import org.springframework.batch.stream.GenericStreamContext;
import org.springframework.batch.stream.ItemStream;
import org.springframework.batch.stream.StreamContext;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
@@ -42,7 +42,7 @@ import org.springframework.util.CollectionUtils;
* @author Peter Zozom
*
*/
public class StaxEventItemWriter implements ItemWriter, ResourceLifecycle, Restartable,
public class StaxEventItemWriter implements ItemWriter, ResourceLifecycle, ItemStream,
StatisticsProvider, InitializingBean, DisposableBean {
// default encoding
@@ -380,23 +380,23 @@ public class StaxEventItemWriter implements ItemWriter, ResourceLifecycle, Resta
/**
* Get the restart data.
* @return the restart data
* @see org.springframework.batch.restart.Restartable#getRestartData()
* @see org.springframework.batch.stream.ItemStream#getRestartData()
*/
public RestartData getRestartData() {
public StreamContext getRestartData() {
Properties properties = new Properties();
properties.setProperty(RESTART_DATA_NAME, String.valueOf(getPosition()));
return new GenericRestartData(properties);
return new GenericStreamContext(properties);
}
/**
* Restore processing from provided restart data.
* @param data the restart data
* @see org.springframework.batch.restart.Restartable#restoreFrom(org.springframework.batch.restart.RestartData)
* @see org.springframework.batch.stream.ItemStream#restoreFrom(org.springframework.batch.stream.StreamContext)
*/
public void restoreFrom(RestartData data) {
public void restoreFrom(StreamContext data) {
long startAtPosition = 0;

View File

@@ -18,8 +18,8 @@ package org.springframework.batch.item.reader;
import org.springframework.batch.io.Skippable;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.batch.stream.ItemStream;
import org.springframework.batch.stream.StreamContext;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
@@ -30,7 +30,7 @@ import org.springframework.util.Assert;
*
* @author Dave Syer
*/
public class DelegatingItemReader extends AbstractItemReader implements Restartable, Skippable, InitializingBean{
public class DelegatingItemReader extends AbstractItemReader implements ItemStream, Skippable, InitializingBean{
private ItemReader inputSource;
@@ -47,27 +47,27 @@ public class DelegatingItemReader extends AbstractItemReader implements Restarta
}
/**
* @see Restartable#getRestartData()
* @see ItemStream#getRestartData()
* @throws IllegalStateException if the parent template is not itself
* {@link Restartable}.
* {@link ItemStream}.
*/
public RestartData getRestartData() {
if (!(inputSource instanceof Restartable)) {
public StreamContext getRestartData() {
if (!(inputSource instanceof ItemStream)) {
throw new IllegalStateException("Input Template is not Restartable");
}
return ((Restartable) inputSource).getRestartData();
return ((ItemStream) inputSource).getRestartData();
}
/**
* @see Restartable#restoreFrom(RestartData)
* @see ItemStream#restoreFrom(StreamContext)
* @throws IllegalStateException if the parent template is not itself
* {@link Restartable}.
* {@link ItemStream}.
*/
public void restoreFrom(RestartData data) {
if (!(inputSource instanceof Restartable)) {
public void restoreFrom(StreamContext data) {
if (!(inputSource instanceof ItemStream)) {
throw new IllegalStateException("Input Template is not Restartable");
}
((Restartable) inputSource).restoreFrom(data);
((ItemStream) inputSource).restoreFrom(data);
}
/**

View File

@@ -8,16 +8,16 @@ import java.util.Properties;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.batch.stream.GenericStreamContext;
import org.springframework.batch.stream.ItemStream;
import org.springframework.batch.stream.StreamContext;
/**
* Runs a collection of ItemProcessors in fixed-order sequence.
*
* @author Robert Kasanicky
*/
public class CompositeItemWriter implements ItemWriter, Restartable {
public class CompositeItemWriter implements ItemWriter, ItemStream {
private static final String SEPARATOR = "#";
@@ -36,25 +36,25 @@ public class CompositeItemWriter implements ItemWriter, Restartable {
* Compound restart data of all injected (Restartable) ItemProcessors,
* property keys are prefixed with list index of the ItemProcessor.
*/
public RestartData getRestartData() {
public StreamContext getRestartData() {
Properties props = createCompoundProperties(new PropertiesExtractor() {
public Properties extractProperties(Object o) {
if (o instanceof Restartable) {
return ((Restartable) o).getRestartData().getProperties();
if (o instanceof ItemStream) {
return ((ItemStream) o).getRestartData().getProperties();
}
else {
return null;
}
}
});
return new GenericRestartData(props);
return new GenericStreamContext(props);
}
/**
* @param data contains values of restart data, property keys are expected
* to be prefixed with list index of the ItemProcessor.
*/
public void restoreFrom(RestartData data) {
public void restoreFrom(StreamContext data) {
if (data == null || data.getProperties() == null) {
// do nothing
return;
@@ -64,8 +64,8 @@ public class CompositeItemWriter implements ItemWriter, Restartable {
// iterators would make the loop below less readable
for (int i = 0; i < delegates.size(); i++) {
if (delegates.get(i) instanceof Restartable) {
((Restartable) delegates.get(i)).restoreFrom((RestartData) restartDataList.get(i));
if (delegates.get(i) instanceof ItemStream) {
((ItemStream) delegates.get(i)).restoreFrom((StreamContext) restartDataList.get(i));
}
}
@@ -81,7 +81,7 @@ public class CompositeItemWriter implements ItemWriter, Restartable {
private List parseProperties(Properties props) {
List restartDataList = new ArrayList(delegates.size());
for (int i = 0; i < delegates.size(); i++) {
restartDataList.add(new GenericRestartData(new Properties()));
restartDataList.add(new GenericStreamContext(new Properties()));
}
for (Iterator iterator = props.entrySet().iterator(); iterator.hasNext();) {
@@ -90,7 +90,7 @@ public class CompositeItemWriter implements ItemWriter, Restartable {
String value = (String) entry.getValue();
int separatorIndex = key.indexOf(SEPARATOR);
int i = Integer.valueOf(key.substring(0, separatorIndex)).intValue();
((RestartData) restartDataList.get(i)).getProperties()
((StreamContext) restartDataList.get(i)).getProperties()
.setProperty(key.substring(separatorIndex + 1), value);
}
return restartDataList;

View File

@@ -4,20 +4,20 @@ import java.util.Properties;
import org.springframework.batch.io.Skippable;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.batch.stream.GenericStreamContext;
import org.springframework.batch.stream.ItemStream;
import org.springframework.batch.stream.StreamContext;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
/**
* Simple wrapper around {@link ItemWriter} providing {@link Restartable} where
* Simple wrapper around {@link ItemWriter} providing {@link ItemStream} where
* the {@link ItemWriter} does. To make sure
*
* @author Dave Syer
* @author Robert Kasanicky
*/
public class DelegatingItemWriter implements ItemWriter, Restartable, Skippable, InitializingBean {
public class DelegatingItemWriter implements ItemWriter, ItemStream, Skippable, InitializingBean {
private ItemWriter writer;
@@ -50,29 +50,29 @@ public class DelegatingItemWriter implements ItemWriter, Restartable, Skippable,
}
/**
* @see Restartable#getRestartData()
* @see ItemStream#getRestartData()
*/
public RestartData getRestartData() {
public StreamContext getRestartData() {
Assert.state(writer != null, "Source must not be null.");
if (writer instanceof Restartable) {
return ((Restartable) writer).getRestartData();
if (writer instanceof ItemStream) {
return ((ItemStream) writer).getRestartData();
}
else {
return new GenericRestartData(new Properties());
return new GenericStreamContext(new Properties());
}
}
/**
* @see Restartable#restoreFrom(RestartData)
* @see ItemStream#restoreFrom(StreamContext)
*/
public void restoreFrom(RestartData data) {
public void restoreFrom(StreamContext data) {
Assert.state(writer != null, "Source must not be null.");
if (writer instanceof Restartable) {
((Restartable) writer).restoreFrom(data);
if (writer instanceof ItemStream) {
((ItemStream) writer).restoreFrom(data);
}
}

View File

@@ -1,56 +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.restart;
/**
* <p>Marker interface defining a contract for periodically storing
* state and restoring from that state should an error occur.
* <p>
*
* <p>The state that is stored is represented as {@link RestartData}
* which enforces a requirement that any restart data can be represented
* by a Properties object. In general, the contract is that RestartData
* that is returned via the getRestartData method will be given back to
* the restoreFrom method, exactly as it was provided. However, since
* it is primarily stored in a database, there is almost no way to know
* the whether a blank column in the database refers to null data,
* null properties, or empty properties. Therefore, any class implementing
* this interface should assume that no restart data is equivalent to
* data with empty Properties.
* </p>
*
* @author Lucas Ward
*
*/
public interface Restartable {
/**
* Get RestartData representing this object's current state. Ideally,
* if no state should be stored, RestartData.getProperties should return
* an empty Properties object.
*
* @return RestartData representing current state.
*/
RestartData getRestartData();
/**
* Restart state given the provided RestartData.
*
* @param data
*/
void restoreFrom(RestartData data);
}

View File

@@ -14,15 +14,15 @@
* limitations under the License.
*/
package org.springframework.batch.restart;
package org.springframework.batch.stream;
import java.util.Properties;
public class GenericRestartData implements RestartData {
public class GenericStreamContext implements StreamContext {
private Properties data;
public GenericRestartData(Properties data){
public GenericStreamContext(Properties data){
this.data = data;
}

View File

@@ -0,0 +1,53 @@
/*
* 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.stream;
/**
* <p>
* Marker interface defining a contract for periodically storing state and
* restoring from that state should an error occur.
* <p>
*
* <p>
* The state that is stored is represented as {@link StreamContext} which
* enforces a requirement that any restart data can be represented by a
* Properties object. In general, the contract is that {@link StreamContext}
* that is returned via the {@link #getRestartData()} method will be given back
* to the {@link #restoreFrom(StreamContext)} method, exactly as it was
* provided.
* </p>
*
* @author Lucas Ward
*
*/
public interface ItemStream {
/**
* Get {@link StreamContext} representing this object's current state.
* Should not return null even if there is no state.
*
* @return {@link StreamContext} representing current state.
*/
StreamContext getRestartData();
/**
* Restart state given the provided {@link StreamContext}.
*
* @param data
*/
void restoreFrom(StreamContext data);
}

View File

@@ -14,14 +14,14 @@
* limitations under the License.
*/
package org.springframework.batch.restart;
package org.springframework.batch.stream;
import java.util.Properties;
/**
* Interface for representing data necessary to recover state after restart.
*/
public interface RestartData {
public interface StreamContext {
Properties getProperties();
}