[BATCH-430] Incremental commit of exception moving

This commit is contained in:
nebhale
2008-03-07 11:54:20 +00:00
parent a60fc1e621
commit 8c2901093e
106 changed files with 736 additions and 848 deletions

View File

@@ -16,12 +16,12 @@
package org.springframework.batch.execution.step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.item.ClearFailedException;
import org.springframework.batch.item.FlushFailedException;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
import org.springframework.batch.item.exception.FlushFailedException;
import org.springframework.batch.item.exception.MarkFailedException;
import org.springframework.batch.item.exception.ResetFailedException;
import org.springframework.batch.item.MarkFailedException;
import org.springframework.batch.item.ResetFailedException;
import org.springframework.batch.repeat.ExitStatus;
/**

View File

@@ -39,7 +39,6 @@ import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.CommitFailedException;
import org.springframework.batch.item.stream.CompositeItemStream;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatCallback;
@@ -51,20 +50,16 @@ import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
/**
* Simple implementation of executing the step as a set of chunks, each chunk
* surrounded by a transaction. The structure is therefore that of two nested
* loops, with transaction boundary around the whole inner loop. The outer loop
* is controlled by the step operations ({@link #setStepOperations(RepeatOperations)}),
* and the inner loop by the chunk operations ({@link #setChunkOperations(RepeatOperations)}).
* The inner loop should always be executed in a single thread, so the chunk
* operations should not do any concurrent execution. N.B. usually that means
* that the chunk operations should be a {@link RepeatTemplate} (which is the
* default).<br/>
* Simple implementation of executing the step as a set of chunks, each chunk surrounded by a transaction. The structure
* is therefore that of two nested loops, with transaction boundary around the whole inner loop. The outer loop is
* controlled by the step operations ({@link #setStepOperations(RepeatOperations)}), and the inner loop by the chunk
* operations ({@link #setChunkOperations(RepeatOperations)}). The inner loop should always be executed in a single
* thread, so the chunk operations should not do any concurrent execution. N.B. usually that means that the chunk
* operations should be a {@link RepeatTemplate} (which is the default).<br/>
*
* Clients can use interceptors in the step operations to intercept or listen to
* the iteration on a step-wide basis, for instance to get a callback when the
* step is complete. Those that want callbacks at the level of an individual
* tasks, can specify interceptors for the chunk operations.
* Clients can use interceptors in the step operations to intercept or listen to the iteration on a step-wide basis, for
* instance to get a callback when the step is complete. Those that want callbacks at the level of an individual tasks,
* can specify interceptors for the chunk operations.
*
* @author Dave Syer
* @author Lucas Ward
@@ -122,6 +117,7 @@ public class ItemOrientedStep extends AbstractStep {
/**
* Public setter for the {@link ItemHandler}.
*
* @param itemHandler the {@link ItemHandler} to set
*/
public void setItemHandler(ItemHandler itemHandler) {
@@ -129,13 +125,10 @@ public class ItemOrientedStep extends AbstractStep {
}
/**
* Register each of the streams for callbacks at the appropriate time in the
* step. The {@link ItemReader} and {@link ItemWriter} are automatically
* registered, but it doesn't hurt to also register them here. Injected
* dependencies of the reader and writer are not automatically registered,
* so if you implement {@link ItemWriter} using delegation to another object
* which itself is a {@link ItemStream}, you need to register the delegate
* here.
* Register each of the streams for callbacks at the appropriate time in the step. The {@link ItemReader} and
* {@link ItemWriter} are automatically registered, but it doesn't hurt to also register them here. Injected
* dependencies of the reader and writer are not automatically registered, so if you implement {@link ItemWriter}
* using delegation to another object which itself is a {@link ItemStream}, you need to register the delegate here.
*
* @param streams an array of {@link ItemStream} objects.
*/
@@ -146,8 +139,8 @@ public class ItemOrientedStep extends AbstractStep {
}
/**
* Register a single {@link ItemStream} for callbacks to the stream
* interface.
* Register a single {@link ItemStream} for callbacks to the stream interface.
*
* @param stream
*/
public void registerStream(ItemStream stream) {
@@ -155,11 +148,9 @@ public class ItemOrientedStep extends AbstractStep {
}
/**
* Register each of the objects as listeners. If the {@link ItemReader} or
* {@link ItemWriter} themselves implements this interface they will be
* registered automatically, but their injected dependencies will not be.
* This is a good way to get access to job parameters and execution context
* if the tasklet is parameterised.
* Register each of the objects as listeners. If the {@link ItemReader} or {@link ItemWriter} themselves implements
* this interface they will be registered automatically, but their injected dependencies will not be. This is a good
* way to get access to job parameters and execution context if the tasklet is parameterised.
*
* @param listeners an array of listener objects of known types.
*/
@@ -170,8 +161,7 @@ public class ItemOrientedStep extends AbstractStep {
}
/**
* Register a step listener for callbacks at the appropriate stages in a
* step execution.
* Register a step listener for callbacks at the appropriate stages in a step execution.
*
* @param listener a {@link StepListener}
*/
@@ -180,9 +170,8 @@ public class ItemOrientedStep extends AbstractStep {
}
/**
* The {@link RepeatOperations} to use for the outer loop of the batch
* processing. Should be set up by the caller through a factory. Defaults to
* a plain {@link RepeatTemplate}.
* The {@link RepeatOperations} to use for the outer loop of the batch processing. Should be set up by the caller
* through a factory. Defaults to a plain {@link RepeatTemplate}.
*
* @param stepOperations a {@link RepeatOperations} instance.
*/
@@ -191,9 +180,8 @@ public class ItemOrientedStep extends AbstractStep {
}
/**
* The {@link RepeatOperations} to use for the inner loop of the batch
* processing. should be set up by the caller through a factory. defaults to
* a plain {@link RepeatTemplate}.
* The {@link RepeatOperations} to use for the inner loop of the batch processing. should be set up by the caller
* through a factory. defaults to a plain {@link RepeatTemplate}.
*
* @param chunkOperations a {@link RepeatOperations} instance.
*/
@@ -202,9 +190,8 @@ public class ItemOrientedStep extends AbstractStep {
}
/**
* Setter for the {@link StepInterruptionPolicy}. The policy is used to
* check whether an external request has been made to interrupt the job
* execution.
* Setter for the {@link StepInterruptionPolicy}. The policy is used to check whether an external request has been
* made to interrupt the job execution.
*
* @param interruptionPolicy a {@link StepInterruptionPolicy}
*/
@@ -213,8 +200,8 @@ public class ItemOrientedStep extends AbstractStep {
}
/**
* Setter for the {@link ExitStatusExceptionClassifier} that will be used to
* classify any exception that causes a job to fail.
* Setter for the {@link ExitStatusExceptionClassifier} that will be used to classify any exception that causes a
* job to fail.
*
* @param exceptionClassifier
*/
@@ -223,9 +210,9 @@ public class ItemOrientedStep extends AbstractStep {
}
/**
* Mostly useful for testing, but could be used to remove dependence on
* backport concurrency utilities. Public setter for the
* {@link StepExecutionSynchronizer}.
* Mostly useful for testing, but could be used to remove dependence on backport concurrency utilities. Public
* setter for the {@link StepExecutionSynchronizer}.
*
* @param synchronizer the {@link StepExecutionSynchronizer} to set
*/
public void setSynchronizer(StepExecutionSynchronizer synchronizer) {
@@ -233,18 +220,14 @@ public class ItemOrientedStep extends AbstractStep {
}
/**
* Process the step and update its context so that progress can be monitored
* by the caller. The step is broken down into chunks, each one executing in
* a transaction. The step and its execution and execution context are all
* given an up to date {@link BatchStatus}, and the {@link JobRepository}
* is used to store the result. Various reporting information are also added
* to the current context (the {@link RepeatContext} governing the step
* execution, which would normally be available to the caller somehow
* through the step's {@link JobExecutionContext}.<br/>
* Process the step and update its context so that progress can be monitored by the caller. The step is broken down
* into chunks, each one executing in a transaction. The step and its execution and execution context are all given
* an up to date {@link BatchStatus}, and the {@link JobRepository} is used to store the result. Various reporting
* information are also added to the current context (the {@link RepeatContext} governing the step execution, which
* would normally be available to the caller somehow through the step's {@link JobExecutionContext}.<br/>
*
* @throws JobInterruptedException if the step or a chunk is interrupted
* @throws RuntimeException if there is an exception during a chunk
* execution
* @throws RuntimeException if there is an exception during a chunk execution
* @see StepExecutor#execute(StepExecution)
*/
public void execute(final StepExecution stepExecution) throws InfrastructureException, JobInterruptedException {
@@ -267,8 +250,7 @@ public class ItemOrientedStep extends AbstractStep {
if (isRestart && lastStepExecution != null) {
stepExecution.setExecutionContext(lastStepExecution.getExecutionContext());
}
else {
} else {
stepExecution.setExecutionContext(new ExecutionContext());
}
@@ -291,7 +273,7 @@ public class ItemOrientedStep extends AbstractStep {
ExitStatus result = ExitStatus.CONTINUABLE;
TransactionStatus transaction = transactionManager
.getTransaction(new DefaultTransactionDefinition());
.getTransaction(new DefaultTransactionDefinition());
try {
@@ -304,8 +286,7 @@ public class ItemOrientedStep extends AbstractStep {
// minimum).
try {
synchronizer.lock(stepExecution);
}
catch (InterruptedException e) {
} catch (InterruptedException e) {
stepExecution.setStatus(BatchStatus.STOPPED);
Thread.currentThread().interrupt();
}
@@ -317,36 +298,30 @@ public class ItemOrientedStep extends AbstractStep {
stream.update(stepExecution.getExecutionContext());
try {
jobRepository.saveOrUpdateExecutionContext(stepExecution);
}
catch (Exception e) {
} catch (Exception e) {
fatalException.setException(e);
stepExecution.setStatus(BatchStatus.UNKNOWN);
throw new CommitFailedException(
"Fatal error detected during save of step execution context", e);
"Fatal error detected during save of step execution context", e);
}
try {
itemHandler.mark();
itemHandler.flush();
transactionManager.commit(transaction);
}
catch (Exception e) {
} catch (Exception e) {
fatalException.setException(e);
stepExecution.setStatus(BatchStatus.UNKNOWN);
throw new CommitFailedException("Fatal error detected during commit", e);
}
}
catch (CommitFailedException e) {
} catch (CommitFailedException e) {
throw e;
}
catch (Throwable t) {
} catch (Throwable t) {
/*
* Any exception thrown within the transaction template
* will automatically cause the transaction to rollback.
* We need to include exceptions during an attempted
* commit (e.g. Hibernate flush) so this catch block
* comes outside the transaction.
* Any exception thrown within the transaction template will automatically cause the transaction
* to rollback. We need to include exceptions during an attempted commit (e.g. Hibernate flush)
* so this catch block comes outside the transaction.
*/
stepExecution.rollback();
@@ -354,21 +329,18 @@ public class ItemOrientedStep extends AbstractStep {
itemHandler.reset();
itemHandler.clear();
transactionManager.rollback(transaction);
}
catch (Exception e) {
} catch (Exception e) {
fatalException.setException(e);
stepExecution.setStatus(BatchStatus.UNKNOWN);
}
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
else {
throw new RuntimeException(t);
} else {
throw new RuntimeException(t);
}
}
finally {
} finally {
synchronizer.release(stepExecution);
}
@@ -383,12 +355,10 @@ public class ItemOrientedStep extends AbstractStep {
});
fatalException.setException(updateStatus(stepExecution, BatchStatus.COMPLETED));
}
catch (CommitFailedException e) {
} catch (CommitFailedException e) {
logger.error("Fatal error detected during commit.");
throw e;
}
catch (RuntimeException e) {
} catch (RuntimeException e) {
// classify exception so an exit code can be stored.
status = exceptionClassifier.classifyForExitCode(e);
@@ -396,29 +366,24 @@ public class ItemOrientedStep extends AbstractStep {
if (e.getCause() instanceof JobInterruptedException) {
updateStatus(stepExecution, BatchStatus.STOPPED);
throw (JobInterruptedException) e.getCause();
}
else if (!fatalException.hasException()) {
} else if (!fatalException.hasException()) {
try {
status = status.and(listener.onErrorInStep(stepExecution, e));
}
catch (RuntimeException ex) {
} catch (RuntimeException ex) {
logger.error("Unexpected error in listener on error in step.", ex);
}
updateStatus(stepExecution, BatchStatus.FAILED);
throw e;
}
else {
} else {
logger.error("Fatal error detected during rollback caused by underlying exception: ", e);
throw e;
}
}
finally {
} finally {
try {
status = status.and(listener.afterStep(stepExecution));
}
catch (RuntimeException e) {
} catch (RuntimeException e) {
logger.error("Unexpected error in listener after step.", e);
}
@@ -427,8 +392,7 @@ public class ItemOrientedStep extends AbstractStep {
try {
jobRepository.saveOrUpdate(stepExecution);
}
catch (RuntimeException e) {
} catch (RuntimeException e) {
String msg = "Fatal error detected during final save of meta data";
logger.error(msg, e);
if (!fatalException.hasException()) {
@@ -439,10 +403,9 @@ public class ItemOrientedStep extends AbstractStep {
try {
stream.close(stepExecution.getExecutionContext());
}
catch (RuntimeException e) {
} catch (RuntimeException e) {
String msg = "Fatal error detected during close of streams. "
+ "The job execution completed (possibly unsuccessfully but with consistent meta-data).";
+ "The job execution completed (possibly unsuccessfully but with consistent meta-data).";
logger.error(msg, e);
if (!fatalException.hasException()) {
fatalException.setException(e);
@@ -452,7 +415,7 @@ public class ItemOrientedStep extends AbstractStep {
if (fatalException.hasException()) {
throw new InfrastructureException("Encountered an error saving batch meta data.", fatalException
.getException());
.getException());
}
}
@@ -460,13 +423,11 @@ public class ItemOrientedStep extends AbstractStep {
}
/**
* Execute a bunch of identical business logic operations all within a
* transaction. The transaction is programmatically started and stopped
* outside this method, so subclasses that override do not need to create a
* Execute a bunch of identical business logic operations all within a transaction. The transaction is
* programmatically started and stopped outside this method, so subclasses that override do not need to create a
* transaction.
*
* @param step the current step containing the {@link Tasklet} with the
* business logic.
* @param step the current step containing the {@link Tasklet} with the business logic.
* @return true if there is more data to process.
*/
protected ExitStatus processChunk(final StepContribution contribution) {
@@ -499,8 +460,7 @@ public class ItemOrientedStep extends AbstractStep {
try {
jobRepository.saveOrUpdate(stepExecution);
return null;
}
catch (Exception e) {
} catch (Exception e) {
return e;
}
@@ -534,4 +494,11 @@ public class ItemOrientedStep extends AbstractStep {
}
private class CommitFailedException extends RuntimeException {
public CommitFailedException(String string, Exception e) {
super(string, e);
}
}
}

View File

@@ -17,12 +17,12 @@ package org.springframework.batch.execution.step.support;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.execution.step.ItemHandler;
import org.springframework.batch.item.ClearFailedException;
import org.springframework.batch.item.FlushFailedException;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
import org.springframework.batch.item.exception.FlushFailedException;
import org.springframework.batch.item.exception.MarkFailedException;
import org.springframework.batch.item.exception.ResetFailedException;
import org.springframework.batch.item.MarkFailedException;
import org.springframework.batch.item.ResetFailedException;
import org.springframework.batch.repeat.ExitStatus;
/**

View File

@@ -21,9 +21,9 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.item.ClearFailedException;
import org.springframework.batch.item.FlushFailedException;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
import org.springframework.batch.item.exception.FlushFailedException;
import org.springframework.batch.support.transaction.TransactionAwareProxyFactory;
import org.springframework.beans.factory.InitializingBean;

View File

@@ -44,9 +44,9 @@ import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.MarkFailedException;
import org.springframework.batch.item.exception.ResetFailedException;
import org.springframework.batch.item.exception.StreamException;
import org.springframework.batch.item.MarkFailedException;
import org.springframework.batch.item.ResetFailedException;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.reader.AbstractItemReader;
import org.springframework.batch.item.reader.ListItemReader;
import org.springframework.batch.item.stream.ItemStreamSupport;
@@ -380,7 +380,7 @@ public class ItemOrientedStepTests extends TestCase {
public void beforeStep(StepExecution stepExecution) {
list.add("foo");
}
public void open(ExecutionContext executionContext) throws StreamException {
public void open(ExecutionContext executionContext) throws ItemStreamException {
assertEquals(1, list.size());
}
};
@@ -633,7 +633,7 @@ public class ItemOrientedStepTests extends TestCase {
public void testStatusForCloseFailedException() throws Exception {
MockRestartableItemReader itemReader = new MockRestartableItemReader() {
public void close(ExecutionContext executionContext) throws StreamException {
public void close(ExecutionContext executionContext) throws ItemStreamException {
super.close(executionContext);
// Simulate failure on rollback when stream resets
throw new RuntimeException("Bar");

View File

@@ -16,8 +16,8 @@
package org.springframework.batch.execution.step.support;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.exception.MarkFailedException;
import org.springframework.batch.item.exception.ResetFailedException;
import org.springframework.batch.item.MarkFailedException;
import org.springframework.batch.item.ResetFailedException;
public class MockItemReader implements ItemReader {

View File

@@ -33,7 +33,7 @@ import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ExecutionContextUserSupport;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.exception.ResetFailedException;
import org.springframework.batch.item.ResetFailedException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
@@ -48,62 +48,52 @@ import org.springframework.util.StringUtils;
/**
* <p>
* 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.
* 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.
* </p>
*
* <p>
* 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.
* 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.
* </p>
*
* <p>
* {@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
* {@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.
* </p>
*
* <p>
* 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.
* 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.
* </p>
*
* <p>
* 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 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.
* </p>
*
* <p>
* 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.
* 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.
* </p>
*
* @author Lucas Ward
* @author Peter Zozom
*/
public class JdbcCursorItemReader extends ExecutionContextUserSupport implements ItemReader, InitializingBean, ItemStream, Skippable {
public class JdbcCursorItemReader extends ExecutionContextUserSupport implements ItemReader, InitializingBean,
ItemStream, Skippable {
private static Log log = LogFactory.getLog(JdbcCursorItemReader.class);
@@ -151,7 +141,7 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
private boolean initialized = false;
private boolean saveState = false;
public JdbcCursorItemReader() {
setName(JdbcCursorItemReader.class.getSimpleName());
}
@@ -159,8 +149,7 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
/**
* Assert that mandatory properties are set.
*
* @throws IllegalArgumentException if either data source or sql properties
* not set.
* @throws IllegalArgumentException if either data source or sql properties not set.
*/
public void afterPropertiesSet() throws Exception {
Assert.notNull(dataSource, "DataSOurce must be provided");
@@ -177,11 +166,10 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
}
/**
* Increment the cursor to the next row, validating the cursor position and
* passing the resultset to the RowMapper. If read has not been called on
* this instance before, the cursor will be opened. If there are skipped
* records for this commit scope, an internal list of skipped records will
* be checked to ensure that only a valid row is given to the mapper.
* Increment the cursor to the next row, validating the cursor position and passing the resultset to the RowMapper.
* If read has not been called on this instance before, the cursor will be opened. If there are skipped records for
* this commit scope, an internal list of skipped records will be checked to ensure that only a valid row is given
* to the mapper.
*
* @returns Object returned by RowMapper
* @throws DataAccessException
@@ -198,8 +186,7 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
try {
if (!rs.next()) {
return null;
}
else {
} else {
currentProcessedRow++;
if (!skippedRows.isEmpty()) {
// while is necessary to handle successive skips.
@@ -217,8 +204,7 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
return mappedResult;
}
}
catch (SQLException se) {
} catch (SQLException se) {
throw getExceptionTranslator().translate("Trying to process next row", sql, se);
}
@@ -229,8 +215,7 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
}
/**
* Mark the current row. Calling reset will cause the result set to be set
* to the current row when mark was called.
* Mark the current row. Calling reset will cause the result set to be set to the current row when mark was called.
*/
public void mark() {
lastCommittedRow = currentProcessedRow;
@@ -247,22 +232,19 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
currentProcessedRow = lastCommittedRow;
if (currentProcessedRow > 0) {
rs.absolute((int) currentProcessedRow);
}
else {
} else {
rs.beforeFirst();
}
}
catch (SQLException se) {
throw new ResetFailedException(getExceptionTranslator().translate(
"Attempted to move ResultSet to last committed row", sql, se));
} catch (SQLException se) {
throw new ResetFailedException("Illegal modification of the result set cursor", getExceptionTranslator()
.translate("Attempted to move ResultSet to last committed row", sql, se));
}
}
/**
* Close this input source. The ResultSet, Statement and Connection created
* will be closed. This must be called or the connection and cursor will be
* held open indefinitely!
* Close this input source. The ResultSet, Statement and Connection created will be closed. This must be called or
* the connection and cursor will be held open indefinitely!
*
* @see org.springframework.batch.item.ResourceLifecycle#close(ExecutionContext)
*/
@@ -288,11 +270,10 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
}
/*
* Executes the provided SQL query. The statement is created with
* 'READ_ONLY' and 'HOLD_CUSORS_OVER_COMMIT' set to true. This is extremely
* important, since a non read-only cursor may lock tables that shouldn't be
* locked, and not holding the cursor open over a commit would require it to
* be reopened after each commit, which would destroy performance.
* Executes the provided SQL query. The statement is created with 'READ_ONLY' and 'HOLD_CUSORS_OVER_COMMIT' set to
* true. This is extremely important, since a non read-only cursor may lock tables that shouldn't be locked, and not
* holding the cursor open over a commit would require it to be reopened after each commit, which would destroy
* performance.
*/
private void executeQuery() {
@@ -301,12 +282,11 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
try {
this.con = dataSource.getConnection();
this.stmt = this.con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
ResultSet.HOLD_CURSORS_OVER_COMMIT);
applyStatementSettings(this.stmt);
this.rs = this.stmt.executeQuery(sql);
handleWarnings(this.stmt.getWarnings());
}
catch (SQLException se) {
} catch (SQLException se) {
close(null);
throw getExceptionTranslator().translate("Executing query", sql, se);
}
@@ -314,10 +294,8 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
}
/*
* Prepare the given JDBC Statement (or PreparedStatement or
* CallableStatement), applying statement settings such as fetch size, max
* rows, and query timeout. @param stmt the JDBC Statement to prepare
* @throws SQLException
* Prepare the given JDBC Statement (or PreparedStatement or CallableStatement), applying statement settings such as
* fetch size, max rows, and query timeout. @param stmt the JDBC Statement to prepare @throws SQLException
*
* @see #setFetchSize
* @see #setMaxRows
@@ -337,16 +315,14 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
}
/*
* Return the exception translator for this instance. <p>Creates a default
* SQLErrorCodeSQLExceptionTranslator for the specified DataSource if none
* is set.
* Return the exception translator for this instance. <p>Creates a default SQLErrorCodeSQLExceptionTranslator for
* the specified DataSource if none is set.
*/
protected SQLExceptionTranslator getExceptionTranslator() {
if (exceptionTranslator == null) {
if (dataSource != null) {
exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource);
}
else {
} else {
exceptionTranslator = new SQLStateSQLExceptionTranslator();
}
}
@@ -354,11 +330,10 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
}
/*
* Throw a SQLWarningException if we're not ignoring warnings, else log the
* warnings (at debug level).
* Throw a SQLWarningException if we're not ignoring warnings, else log the warnings (at debug level).
*
* @param warning the warnings object from the current statement. May be
* <code>null</code>, in which case this method does nothing.
* @param warning the warnings object from the current statement. May be <code>null</code>, in which case this
* method does nothing.
*
* @see org.springframework.jdbc.SQLWarningException
*/
@@ -367,17 +342,17 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
SQLWarning warningToLog = warnings;
while (warningToLog != null) {
log.debug("SQLWarning ignored: SQL state '" + warningToLog.getSQLState() + "', error code '"
+ warningToLog.getErrorCode() + "', message [" + warningToLog.getMessage() + "]");
+ warningToLog.getErrorCode() + "', message [" + warningToLog.getMessage() + "]");
warningToLog = warningToLog.getNextWarning();
}
}
else if (warnings != null) {
} else if (warnings != null) {
throw new SQLWarningException("Warning not ignored", warnings);
}
}
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.stream.ItemStreamAdapter#getExecutionContext()
*/
public void update(ExecutionContext executionContext) {
@@ -392,6 +367,7 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.stream.ItemStreamAdapter#restoreFrom(org.springframework.batch.item.ExecutionContext)
*/
public void open(ExecutionContext context) {
@@ -409,8 +385,7 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
try {
this.currentProcessedRow = context.getLong(getKey(CURRENT_PROCESSED_ROW));
rs.absolute((int) currentProcessedRow);
}
catch (SQLException se) {
} catch (SQLException se) {
throw getExceptionTranslator().translate("Attempted to move ResultSet to last committed row", sql, se);
}
@@ -425,10 +400,9 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
}
/**
* Skip the current row. If the transaction is rolled back, this row will
* not be represented to the RowMapper when read() is called. For example,
* if you read in row 2, find the data to be bad, and call skip(), then
* continue processing and find
* Skip the current row. If the transaction is rolled back, this row will not be represented to the RowMapper when
* read() is called. For example, if you read in row 2, find the data to be bad, and call skip(), then continue
* processing and find
*/
public void skip() {
skippedRows.add(new Long(currentProcessedRow));
@@ -436,10 +410,9 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
}
/**
* Gives the JDBC driver a hint as to the number of rows that should be
* fetched from the database when more rows are needed for this
* <code>ResultSet</code> object. If the fetch size specified is zero, the
* JDBC driver ignores the value.
* Gives the JDBC driver a hint as to the number of rows that should be fetched from the database when more rows are
* needed for this <code>ResultSet</code> object. If the fetch size specified is zero, the JDBC driver ignores the
* value.
*
* @param fetchSize the number of rows to fetch
* @see ResultSet#setFetchSize(int)
@@ -449,8 +422,8 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
}
/**
* Sets the limit for the maximum number of rows that any
* <code>ResultSet</code> object can contain to the given number.
* Sets the limit for the maximum number of rows that any <code>ResultSet</code> object can contain to the given
* number.
*
* @param maxRows the new max rows limit; zero means there is no limit
* @see Statement#setMaxRows(int)
@@ -460,13 +433,10 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
}
/**
* Sets the number of seconds the driver will wait for a
* <code>Statement</code> object to execute to the given number of
* seconds. If the limit is exceeded, an <code>SQLException</code> is
* thrown.
* Sets the number of seconds the driver will wait for a <code>Statement</code> object to execute to the given
* number of seconds. If the limit is exceeded, an <code>SQLException</code> is thrown.
*
* @param queryTimeout seconds the new query timeout limit in seconds; zero
* means there is no limit
* @param queryTimeout seconds the new query timeout limit in seconds; zero means there is no limit
* @see Statement#setQueryTimeout(int)
*/
public void setQueryTimeout(int queryTimeout) {
@@ -474,8 +444,7 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
}
/**
* Set whether SQLWarnings should be ignored (only logged) or exception
* should be thrown.
* Set whether SQLWarnings should be ignored (only logged) or exception should be thrown.
*
* @param ignoreWarnings if TRUE, warnings are ignored
*/
@@ -484,8 +453,8 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
}
/**
* Allow verification of cursor position after current row is processed by
* RowMapper or RowCallbackHandler. Default value is TRUE.
* Allow verification of cursor position after current row is processed by RowMapper or RowCallbackHandler. Default
* value is TRUE.
*
* @param verifyCursorPosition if true, cursor position is verified
*/
@@ -503,9 +472,8 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
}
/**
* Set the sql statement to be used when creating the cursor. This statement
* should be a complete and valid Sql statement, as it will be run directly
* without any modification.
* Set the sql statement to be used when creating the cursor. This statement should be a complete and valid Sql
* statement, as it will be run directly without any modification.
*
* @param sql
*/

View File

@@ -21,7 +21,7 @@ import java.util.List;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.exception.NoWorkFoundException;
import org.springframework.batch.item.NoWorkFoundException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

View File

@@ -35,28 +35,27 @@ import org.springframework.batch.io.file.transform.LineTokenizer;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ExecutionContextUserSupport;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemReaderException;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.exception.StreamException;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ReaderNotOpenException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
/**
* This class represents a {@link ItemReader}, that reads lines from text file,
* tokenizes them to structured tuples ({@link FieldSet}s) instances and maps
* the {@link FieldSet}s to domain objects. The location of the file is defined
* by the resource property. To separate the structure of the file,
* {@link LineTokenizer} is used to parse data obtained from the file. <br/>
* This class represents a {@link ItemReader}, that reads lines from text file, tokenizes them to structured tuples ({@link FieldSet}s)
* instances and maps the {@link FieldSet}s to domain objects. The location of the file is defined by the resource
* property. To separate the structure of the file, {@link LineTokenizer} is used to parse data obtained from the file.
* <br/>
*
* A {@link FlatFileItemReader} is not thread safe because it maintains state in
* the form of a {@link ResourceLineReader}. Be careful to configure a
* {@link FlatFileItemReader} using an appropriate factory or scope so that it
* is not shared between threads.<br/>
* A {@link FlatFileItemReader} is not thread safe because it maintains state in the form of a
* {@link ResourceLineReader}. Be careful to configure a {@link FlatFileItemReader} using an appropriate factory or
* scope so that it is not shared between threads.<br/>
*
* <p>
* This class supports restart, skipping invalid lines and storing statistics.
* It can be configured to setup {@link FieldSet} column names from the file
* header, skip given number of lines at the beginning of the file.
* This class supports restart, skipping invalid lines and storing statistics. It can be configured to setup
* {@link FieldSet} column names from the file header, skip given number of lines at the beginning of the file.
* </p>
*
* @author Waseem Malik
@@ -64,7 +63,8 @@ import org.springframework.util.Assert;
* @author Robert Kasanicky
* @author Dave Syer
*/
public class FlatFileItemReader extends ExecutionContextUserSupport implements ItemReader, Skippable, ItemStream, InitializingBean {
public class FlatFileItemReader extends ExecutionContextUserSupport implements ItemReader, Skippable, ItemStream,
InitializingBean {
private static Log log = LogFactory.getLog(FlatFileItemReader.class);
@@ -96,20 +96,20 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
private FieldSetMapper fieldSetMapper;
/**
* Encapsulates the state of the input source. If it is null then we are
* uninitialized.
* Encapsulates the state of the input source. If it is null then we are uninitialized.
*/
private LineReader reader;
public FlatFileItemReader() {
setName(FlatFileItemReader.class.getSimpleName());
}
/**
* Initialize the reader if necessary.
*
* @throws IllegalStateException if the resource cannot be opened
*/
public void open(ExecutionContext executionContext) throws StreamException {
public void open(ExecutionContext executionContext) throws ItemStreamException {
Assert.state(resource.exists(), "Resource must exist: [" + resource + "]");
@@ -140,14 +140,14 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
((AbstractLineTokenizer) tokenizer).setNames(names);
}
}
if (executionContext.containsKey(getKey(READ_STATISTICS_NAME))) {
if (executionContext.containsKey(getKey(READ_STATISTICS_NAME))) {
log.debug("Initializing for restart. Restart data is: " + executionContext);
long lineCount = executionContext.getLong(getKey(READ_STATISTICS_NAME));
LineReader reader = getReader();
Object record = "";
while (reader.getPosition() < lineCount && record != null) {
record = readLine();
@@ -158,23 +158,23 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
/**
* Close and null out the reader.
*
* @throws Exception
*/
public void close(ExecutionContext executionContext) throws StreamException {
public void close(ExecutionContext executionContext) throws ItemStreamException {
try {
if (reader != null) {
log.debug("Closing flat file for reading: " + resource);
reader.close(null);
}
}
finally {
} finally {
reader = null;
}
}
/**
* Reads a line from input, tokenizes is it using the {@link #tokenizer} and
* maps to domain object using {@link #fieldSetMapper}.
* Reads a line from input, tokenizes is it using the {@link #tokenizer} and maps to domain object using
* {@link #fieldSetMapper}.
*
* @see org.springframework.batch.io.ItemReader#read()
*/
@@ -185,25 +185,23 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
try {
FieldSet tokenizedLine = tokenizer.tokenize(line);
return fieldSetMapper.mapLine(tokenizedLine);
}
catch (RuntimeException ex) {
} catch (RuntimeException ex) {
// add current line count to message and re-throw
int lineCount = getReader().getPosition();
throw new FlatFileParsingException("Parsing error at line: " + lineCount + " in resource=" + path
+ ", input=[" + line + "]", ex, line, lineCount);
+ ", input=[" + line + "]", ex, line, lineCount);
}
}
return null;
}
/**
* This method returns the execution attributes for the reader. It returns
* the current Line Count which can be used to reinitialise the batch job in
* case of restart.
* This method returns the execution attributes for the reader. It returns the current Line Count which can be used
* to reinitialise the batch job in case of restart.
*/
public void update(ExecutionContext executionContext) {
if (reader == null) {
throw new StreamException("ItemStream not open or already closed.");
throw new ItemStreamException("ItemStream not open or already closed.");
}
Assert.notNull(executionContext, "ExecutionContext must not be null");
executionContext.putLong(getKey(READ_STATISTICS_NAME), reader.getPosition());
@@ -211,10 +209,8 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
}
/**
* Mark is supported as long as this {@link ItemStream} is used in a
* single-threaded environment. The state backing the mark is a single
* counter, keeping track of the current position, so multiple threads
* cannot be accommodated.
* Mark is supported as long as this {@link ItemStream} is used in a single-threaded environment. The state backing
* the mark is a single counter, keeping track of the current position, so multiple threads cannot be accommodated.
*
* @see org.springframework.batch.item.ItemReader#mark()
*/
@@ -224,6 +220,7 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
/*
* (non-Javadoc)
*
* @see org.springframework.batch.item.ItemStream#reset(org.springframework.batch.item.ExecutionContext)
*/
public void reset() {
@@ -241,8 +238,7 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
}
/**
* @return next line to be tokenized and mapped (possibly skips multiple
* lines).
* @return next line to be tokenized and mapped (possibly skips multiple lines).
*/
protected String readLine() {
String line = nextLine();
@@ -259,8 +255,9 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
private String nextLine() {
try {
return (String) getReader().read();
}
catch (StreamException e) {
} catch (ItemStreamException e) {
throw e;
} catch (ItemReaderException e) {
throw e;
}
catch (Exception e) {
@@ -273,15 +270,14 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
*/
protected LineReader getReader() {
if (reader == null) {
throw new StreamException("ItemStream must be open before it can be read.");
throw new ReaderNotOpenException("Reader must be open before it can be read.");
// reader is now not null, or else an exception is thrown
}
return reader;
}
/**
* Setter for resource property. The location of an input stream that can be
* read.
* Setter for resource property. The location of an input stream that can be read.
*
* @param resource
* @throws IOException
@@ -295,9 +291,8 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
}
/**
* Public setter for the recordSeparatorPolicy. Used to determine where the
* line endings are and do things like continue over a line ending if inside
* a quoted string.
* Public setter for the recordSeparatorPolicy. Used to determine where the line endings are and do things like
* continue over a line ending if inside a quoted string.
*
* @param recordSeparatorPolicy the recordSeparatorPolicy to set
*/
@@ -306,8 +301,8 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
}
/**
* Setter for comment prefixes. Can be used to ignore header lines as well
* by using e.g. the first couple of column names as a prefix.
* Setter for comment prefixes. Can be used to ignore header lines as well by using e.g. the first couple of column
* names as a prefix.
*
* @param comments an array of comment line prefixes.
*/
@@ -317,10 +312,8 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
}
/**
* Indicates whether first line is a header. If the tokenizer is an
* {@link AbstractLineTokenizer} and the column names haven't been set
* already then the header will be used to setup column names. Default is
* <code>false</code>.
* Indicates whether first line is a header. If the tokenizer is an {@link AbstractLineTokenizer} and the column
* names haven't been set already then the header will be used to setup column names. Default is <code>false</code>.
*/
public void setFirstLineIsHeader(boolean firstLineIsHeader) {
this.firstLineIsHeader = firstLineIsHeader;
@@ -343,10 +336,8 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
}
/**
* Public setter for the number of lines to skip at the start of a file. Can
* be used if the file contains a header without useful (column name)
* information, and without a comment delimiter at the beginning of the
* lines.
* Public setter for the number of lines to skip at the start of a file. Can be used if the file contains a header
* without useful (column name) information, and without a comment delimiter at the beginning of the lines.
*
* @param linesToSkip the number of lines to skip
*/
@@ -355,11 +346,9 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
}
/**
* Setter for the encoding for this input source. Default value is
* {@value #DEFAULT_CHARSET}.
* Setter for the encoding for this input source. Default value is {@value #DEFAULT_CHARSET}.
*
* @param encoding a properties object which possibly contains the encoding
* for this input file;
* @param encoding a properties object which possibly contains the encoding for this input file;
*/
public void setEncoding(String encoding) {
this.encoding = encoding;

View File

@@ -31,34 +31,30 @@ import org.springframework.batch.io.file.mapping.FieldSet;
import org.springframework.batch.io.file.mapping.FieldSetCreator;
import org.springframework.batch.io.file.transform.DelimitedLineAggregator;
import org.springframework.batch.io.file.transform.LineAggregator;
import org.springframework.batch.item.ClearFailedException;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ExecutionContextUserSupport;
import org.springframework.batch.item.FlushFailedException;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
import org.springframework.batch.item.exception.FlushFailedException;
import org.springframework.batch.item.exception.ResetFailedException;
import org.springframework.batch.item.exception.StreamException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.util.Assert;
/**
* This class is an output target that writes data to a file or stream. The
* writer also provides restart, statistics and transaction features by
* implementing corresponding interfaces where possible (with a file). The
* location of the file is defined by a {@link Resource} and must represent a
* writable file.<br/>
* This class is an output target that writes data to a file or stream. The writer also provides restart, statistics and
* transaction features by implementing corresponding interfaces where possible (with a file). The location of the file
* is defined by a {@link Resource} and must represent a writable file.<br/>
*
* Uses buffered writer to improve performance.<br/>
*
* Use {@link #write(String)} method to output a line to an item writer.
*
* <p>
* This class will be updated in the future to use a buffering approach to
* handling transactions, rather than outputting directly to the file and
* truncating on rollback
* This class will be updated in the future to use a buffering approach to handling transactions, rather than outputting
* directly to the file and truncating on rollback
* </p>
*
* @author Waseem Malik
@@ -66,8 +62,7 @@ import org.springframework.util.Assert;
* @author Robert Kasanicky
* @author Dave Syer
*/
public class FlatFileItemWriter extends ExecutionContextUserSupport implements ItemWriter, ItemStream,
InitializingBean {
public class FlatFileItemWriter extends ExecutionContextUserSupport implements ItemWriter, ItemStream, InitializingBean {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
@@ -84,13 +79,14 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
private LineAggregator lineAggregator = new DelimitedLineAggregator();
private FieldSetCreator fieldSetCreator;
public FlatFileItemWriter() {
setName(FlatFileItemWriter.class.getSimpleName());
}
/**
* Assert that mandatory properties (resource) are set.
*
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
@@ -101,8 +97,8 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
}
/**
* Public setter for the {@link LineAggregator}. This will be used to
* translate a {@link FieldSet} into a line for output.
* Public setter for the {@link LineAggregator}. This will be used to translate a {@link FieldSet} into a line for
* output.
*
* @param lineAggregator the {@link LineAggregator} to set
*/
@@ -111,9 +107,8 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
}
/**
* Public setter for the {@link FieldSetCreator}. This will be used to
* transform the item into a {@link FieldSet} before it is aggregated by the
* {@link LineAggregator}.
* Public setter for the {@link FieldSetCreator}. This will be used to transform the item into a {@link FieldSet}
* before it is aggregated by the {@link LineAggregator}.
*
* @param fieldSetCreator the {@link FieldSetCreator} to set
*/
@@ -131,16 +126,13 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
}
/**
* Writes out a string followed by a "new line", where the format of the new
* line separator is determined by the underlying operating system. If the
* input is not a String and a converter is available the converter will be
* applied and then this method recursively called with the result. If the
* input is an array or collection each value will be written to a separate
* line (recursively calling this method for each value). If no converter is
* Writes out a string followed by a "new line", where the format of the new line separator is determined by the
* underlying operating system. If the input is not a String and a converter is available the converter will be
* applied and then this method recursively called with the result. If the input is an array or collection each
* value will be written to a separate line (recursively calling this method for each value). If no converter is
* supplied the input object's toString method will be used.<br/>
*
* @param data Object (a String or Object that can be converted) to be
* written to output stream
* @param data Object (a String or Object that can be converted) to be written to output stream
* @throws Exception if the transformer or file output fail
*/
public void write(Object data) throws Exception {
@@ -181,11 +173,12 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
/**
* Initialize the Output Template.
*
* @see ResourceLifecycle#open()
*/
public void open(ExecutionContext executionContext) {
OutputState outputState = getOutputState();
if(executionContext.containsKey(getKey(RESTART_DATA_NAME))){
if (executionContext.containsKey(getKey(RESTART_DATA_NAME))) {
outputState.restoreFrom(executionContext);
}
}
@@ -195,7 +188,7 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
*/
public void update(ExecutionContext executionContext) {
if (state == null) {
throw new StreamException("ItemStream not open or already closed.");
throw new ItemStreamException("ItemStream not open or already closed.");
}
Assert.notNull(executionContext, "ExecutionContext must not be null");
executionContext.putLong(getKey(RESTART_DATA_NAME), state.position());
@@ -212,8 +205,7 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
}
/**
* Encapsulates the runtime state of the writer. All state changing
* operations on the writer go through this class.
* Encapsulates the runtime state of the writer. All state changing operations on the writer go through this class.
*/
private class OutputState {
// default encoding for writing to output files - set to UTF-8.
@@ -246,8 +238,7 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
boolean shouldDeleteIfExists = true;
/**
* Return the byte offset position of the cursor in the output file as a
* long integer.
* Return the byte offset position of the cursor in the output file as a long integer.
*/
public long position() {
long pos = 0;
@@ -259,8 +250,7 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
try {
outputBufferedWriter.flush();
pos = fileChannel.position();
}
catch (IOException e) {
} catch (IOException e) {
throw new InfrastructureException("An Error occured while trying to get filechannel position", e);
}
@@ -309,9 +299,8 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
}
outputBufferedWriter.close();
fileChannel.close();
}
catch (IOException ioe) {
throw new StreamException("Unable to close the the ItemWriter", ioe);
} catch (IOException ioe) {
throw new ItemStreamException("Unable to close the the ItemWriter", ioe);
}
}
@@ -329,8 +318,7 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
outputBufferedWriter.write(line);
outputBufferedWriter.flush();
linesWritten++;
}
catch (IOException e) {
} catch (IOException e) {
throw new InfrastructureException("An Error occured while trying to write to FlatFileItemWriter", e);
}
}
@@ -342,8 +330,7 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
try {
fileChannel.truncate(lastMarkedByteOffsetPosition);
fileChannel.position(lastMarkedByteOffsetPosition);
}
catch (IOException e) {
} catch (IOException e) {
throw new InfrastructureException("An Error occured while truncating output file", e);
}
}
@@ -356,8 +343,7 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
}
/**
* Creates the buffered writer for the output file channel based on
* configuration information.
* Creates the buffered writer for the output file channel based on configuration information.
*/
private void initializeBufferedWriter() {
File file;
@@ -376,9 +362,8 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
if (file.exists()) {
if (shouldDeleteIfExists) {
file.delete();
}
else {
throw new StreamException("Resource already exists: " + resource);
} else {
throw new ItemStreamException("Resource already exists: " + resource);
}
}
String parent = file.getParent();
@@ -388,16 +373,14 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
file.createNewFile();
}
}
catch (IOException ioe) {
} catch (IOException ioe) {
throw new DataAccessResourceFailureException("Unable to write to file resource: [" + resource + "]",
ioe);
ioe);
}
try {
fileChannel = (new FileOutputStream(file.getAbsolutePath(), true)).getChannel();
}
catch (FileNotFoundException fnfe) {
} catch (FileNotFoundException fnfe) {
throw new ConfigurationException("Bad filename property parameter " + file, fnfe);
}
@@ -413,8 +396,8 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
}
/**
* Returns the buffered writer opened to the beginning of the file
* specified by the absolute path name contained in absoluteFileName.
* Returns the buffered writer opened to the beginning of the file specified by the absolute path name contained
* in absoluteFileName.
*/
private BufferedWriter getBufferedWriter(FileChannel fileChannel, String encoding, int bufferSize) {
try {
@@ -424,25 +407,21 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
// If a buffer was requested, allocate.
if (bufferSize > 0) {
outputBufferedWriter = new BufferedWriter(Channels.newWriter(fileChannel, encoding), bufferSize);
}
else {
} else {
outputBufferedWriter = new BufferedWriter(Channels.newWriter(fileChannel, encoding));
}
return outputBufferedWriter;
}
catch (UnsupportedCharsetException ucse) {
throw new StreamException("Bad encoding configuration for output file " + fileChannel, ucse);
} catch (UnsupportedCharsetException ucse) {
throw new ItemStreamException("Bad encoding configuration for output file " + fileChannel, ucse);
}
}
/**
* Resets the file writer's current position to the point stored in the
* last marked byte offset position variable. It first checks to make
* sure the current size of the file is not less than the byte position
* to be moved to (if it is, throws an environment exception), then it
* truncates the file to that reset position, and set the cursor to
* start writing at that point.
* Resets the file writer's current position to the point stored in the last marked byte offset position
* variable. It first checks to make sure the current size of the file is not less than the byte position to be
* moved to (if it is, throws an environment exception), then it truncates the file to that reset position, and
* set the cursor to start writing at that point.
*/
public void reset() throws InfrastructureException {
checkFileSize();
@@ -450,10 +429,9 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
}
/**
* Checks (on setState) to make sure that the current output file's size
* is not smaller than the last saved commit point. If it is, then the
* file has been damaged in some way and whole task must be started over
* again from the beginning.
* Checks (on setState) to make sure that the current output file's size is not smaller than the last saved
* commit point. If it is, then the file has been damaged in some way and whole task must be started over again
* from the beginning.
*/
private void checkFileSize() {
long size = -1;
@@ -461,8 +439,7 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
try {
outputBufferedWriter.flush();
size = fileChannel.size();
}
catch (IOException e) {
} catch (IOException e) {
throw new InfrastructureException("An Error occured while checking file size", e);
}
@@ -476,14 +453,13 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
public void clear() throws ClearFailedException {
try {
getOutputState().reset();
}
catch (InfrastructureException e) {
throw new ResetFailedException(e);
} catch (InfrastructureException e) {
throw new ClearFailedException("Could not reset the state of the writer", e);
}
}
public void flush() throws FlushFailedException {
getOutputState().mark();
}
}

View File

@@ -28,9 +28,10 @@ import java.util.Iterator;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.exception.MarkFailedException;
import org.springframework.batch.item.exception.ResetFailedException;
import org.springframework.batch.item.exception.StreamException;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.MarkFailedException;
import org.springframework.batch.item.ResetFailedException;
import org.springframework.batch.item.UnexpectedInputException;
import org.springframework.batch.item.stream.ItemStreamSupport;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
@@ -38,22 +39,17 @@ import org.springframework.util.Assert;
/**
* An input source that reads lines one by one from a resource. <br/>
*
* A line can consist of multiple lines in the input resource, according to the
* {@link RecordSeparatorPolicy} in force. By default a line is either
* terminated by a newline (as per {@link BufferedReader#readLine()}), or can
* be continued onto the next line if a field surrounded by quotes (\") contains
* a newline.<br/>
* A line can consist of multiple lines in the input resource, according to the {@link RecordSeparatorPolicy} in force.
* By default a line is either terminated by a newline (as per {@link BufferedReader#readLine()}), or can be continued
* onto the next line if a field surrounded by quotes (\") contains a newline.<br/>
*
* Comment lines can be indicated using a line prefix (or collection of
* prefixes) and they will be ignored. The default is "#", so lines starting
* with a pound sign will be ignored.<br/>
* Comment lines can be indicated using a line prefix (or collection of prefixes) and they will be ignored. The default
* is "#", so lines starting with a pound sign will be ignored.<br/>
*
* All the public methods that interact with the underlying resource (open,
* close, read etc.) are synchronized on this.<br/>
* All the public methods that interact with the underlying resource (open, close, read etc.) are synchronized on this.<br/>
*
* Package private because this is not intended to be a public API - used
* internally by the flat file input sources. That makes abuses of the fact that
* it is stateful easier to control.<br/>
* Package private because this is not intended to be a public API - used internally by the flat file input sources.
* That makes abuses of the fact that it is stateful easier to control.<br/>
*
* @author Dave Syer
* @author Rob Harrop
@@ -89,24 +85,22 @@ public class ResourceLineReader extends ItemStreamSupport implements LineReader,
}
/**
* Setter for the {@link RecordSeparatorPolicy}. Default value is a
* {@link DefaultRecordSeparatorPolicy}. Ideally should not be changed once
* a reader is in use, but it would not be fatal if it was.
* Setter for the {@link RecordSeparatorPolicy}. Default value is a {@link DefaultRecordSeparatorPolicy}. Ideally
* should not be changed once a reader is in use, but it would not be fatal if it was.
*
* @param recordSeparatorPolicy the new {@link RecordSeparatorPolicy}
*/
public void setRecordSeparatorPolicy(RecordSeparatorPolicy recordSeparatorPolicy) {
/*
* The rest of the code accesses the policy in synchronized blocks,
* copying the reference before using it. So in principle it can be
* changed in flight - the results might not be what the user expected!
* The rest of the code accesses the policy in synchronized blocks, copying the reference before using it. So in
* principle it can be changed in flight - the results might not be what the user expected!
*/
this.recordSeparatorPolicy = recordSeparatorPolicy;
}
/**
* Setter for comment prefixes. Can be used to ignore header lines as well
* by using e.g. the first couple of column names as a prefix.
* Setter for comment prefixes. Can be used to ignore header lines as well by using e.g. the first couple of column
* names as a prefix.
*
* @param comments an array of comment line prefixes.
*/
@@ -115,8 +109,7 @@ public class ResourceLineReader extends ItemStreamSupport implements LineReader,
}
/**
* Read the next line from the input resource, ignoring comments, and
* according to the {@link RecordSeparatorPolicy}.
* Read the next line from the input resource, ignoring comments, and according to the {@link RecordSeparatorPolicy}.
*
* @return a String.
*
@@ -154,8 +147,7 @@ public class ResourceLineReader extends ItemStreamSupport implements LineReader,
}
/**
* A no-op because the oobject is initialized with all it needs to open in
* the constructor.
* A no-op because the oobject is initialized with all it needs to open in the constructor.
*
* @see org.springframework.batch.item.ResourceLifecycle#open()
*/
@@ -175,8 +167,7 @@ public class ResourceLineReader extends ItemStreamSupport implements LineReader,
}
try {
state.close();
}
finally {
} finally {
state = null;
}
}
@@ -191,14 +182,11 @@ public class ResourceLineReader extends ItemStreamSupport implements LineReader,
}
/**
* Mark the state for return later with reset. Uses the read-ahead limit
* from an underlying {@link BufferedReader}, which means that there is a
* limit to how much data can be recovered if the mark needs to be reset.<br/>
* Mark the state for return later with reset. Uses the read-ahead limit from an underlying {@link BufferedReader},
* which means that there is a limit to how much data can be recovered if the mark needs to be reset.<br/>
*
* Mark is supported as long as this {@link ItemStream} is used in a
* single-threaded environment. The state backing the mark is a single
* counter, keeping track of the current position, so multiple threads
* cannot be accommodated.
* Mark is supported as long as this {@link ItemStream} is used in a single-threaded environment. The state backing
* the mark is a single counter, keeping track of the current position, so multiple threads cannot be accommodated.
*
* @see #reset()
*
@@ -213,8 +201,7 @@ public class ResourceLineReader extends ItemStreamSupport implements LineReader,
*
* @see #mark()
*
* @throws ResetFailedException if the reset is unsuccessful, e.g. if
* the read-ahead limit was breached.
* @throws ResetFailedException if the reset is unsuccessful, e.g. if the read-ahead limit was breached.
*/
public synchronized void reset() throws ResetFailedException {
getState().reset();
@@ -253,10 +240,9 @@ public class ResourceLineReader extends ItemStreamSupport implements LineReader,
}
currentLineCount++;
}
}
catch (IOException e) {
throw new StreamException("Unable to read from resource '" + resource + "' at line "
+ currentLineCount, e);
} catch (IOException e) {
throw new UnexpectedInputException("Unable to read from resource '" + resource + "' at line "
+ currentLineCount, e);
}
return line;
}
@@ -268,9 +254,8 @@ public class ResourceLineReader extends ItemStreamSupport implements LineReader,
try {
reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), encoding));
mark();
}
catch (IOException e) {
throw new StreamException("Could not open resource", e);
} catch (IOException e) {
throw new ItemStreamException("Could not open resource", e);
}
}
@@ -284,11 +269,9 @@ public class ResourceLineReader extends ItemStreamSupport implements LineReader,
}
try {
reader.close();
}
catch (IOException e) {
throw new StreamException("Could not close reader", e);
}
finally {
} catch (IOException e) {
throw new ItemStreamException("Could not close reader", e);
} finally {
currentLineCount = 0;
markedLineCount = -1;
}
@@ -309,15 +292,13 @@ public class ResourceLineReader extends ItemStreamSupport implements LineReader,
try {
reader.mark(READ_AHEAD_LIMIT);
markedLineCount = currentLineCount;
}
catch (IOException e) {
} catch (IOException e) {
throw new MarkFailedException("Could not mark reader", e);
}
}
/**
* Reset the reader and line counters to the last marked position if
* possible.
* Reset the reader and line counters to the last marked position if possible.
*/
public void reset() throws ResetFailedException {
@@ -327,8 +308,7 @@ public class ResourceLineReader extends ItemStreamSupport implements LineReader,
try {
this.reader.reset();
currentLineCount = markedLineCount;
}
catch (IOException e) {
} catch (IOException e) {
throw new ResetFailedException("Could not reset reader", e);
}

View File

@@ -21,9 +21,9 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.springframework.batch.item.ClearFailedException;
import org.springframework.batch.item.FlushFailedException;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
import org.springframework.batch.item.exception.FlushFailedException;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.synch.RepeatSynchronizationManager;
import org.springframework.beans.factory.InitializingBean;

View File

@@ -19,9 +19,9 @@ import java.util.HashSet;
import java.util.Set;
import org.hibernate.SessionFactory;
import org.springframework.batch.item.ClearFailedException;
import org.springframework.batch.item.FlushFailedException;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
import org.springframework.batch.item.exception.FlushFailedException;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.synch.RepeatSynchronizationManager;
import org.springframework.beans.factory.InitializingBean;

View File

@@ -20,7 +20,8 @@ import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ExecutionContextUserSupport;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.exception.StreamException;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ReaderNotOpenException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessResourceFailureException;
@@ -75,7 +76,7 @@ public class StaxEventItemReader extends ExecutionContextUserSupport implements
*/
public Object read() {
if (!initialized) {
throw new StreamException("ItemStream must be open before it can be read.");
throw new ReaderNotOpenException("Reader must be open before it can be read.");
}
Object item = null;
@@ -141,7 +142,7 @@ public class StaxEventItemReader extends ExecutionContextUserSupport implements
txReader.onCommit(); // reset the history buffer
}
if (!fragmentReader.hasNext()) {
throw new StreamException("Restore point must be before end of input");
throw new ItemStreamException("Restore point must be before end of input");
}
fragmentReader.next();
moveCursorToNextFragment(fragmentReader);

View File

@@ -17,12 +17,12 @@ import javax.xml.stream.XMLStreamException;
import org.springframework.batch.io.support.FileUtils;
import org.springframework.batch.io.xml.stax.NoStartEndDocumentStreamWriter;
import org.springframework.batch.item.ClearFailedException;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ExecutionContextUserSupport;
import org.springframework.batch.item.FlushFailedException;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
import org.springframework.batch.item.exception.FlushFailedException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessResourceFailureException;

View File

@@ -13,39 +13,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.item.exception;
import org.springframework.batch.item.ItemWriter;
package org.springframework.batch.item;
/**
* Unchecked exception indicating that an error has occured while
* trying to call {@link ItemWriter#clear()}
* Unchecked exception indicating that an error has occurred while trying to call {@link ItemWriter#clear()}
*
* @author Lucas Ward
*
* @author Ben Hale
*/
public class ClearFailedException extends StreamException {
public class ClearFailedException extends ItemWriterException {
/**
* @param message
* Create a new {@link ClearFailedException} based on a message and another exception.
*
* @param message the message for this exception
* @param cause the other exception
*/
public ClearFailedException(String message, Throwable cause) {
super(message, cause);
}
/**
* Create a new {@link ClearFailedException} based on a message.
*
* @param message the message for this exception
*/
public ClearFailedException(String message) {
super(message);
}
/**
* @param msg
* @param nested
*/
public ClearFailedException(String msg, Throwable nested) {
super(msg, nested);
}
/**
* @param msg
* @param nested
*/
public ClearFailedException(Throwable nested) {
super(nested);
}
}

View File

@@ -13,38 +13,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.item.exception;
import org.springframework.batch.item.ItemWriter;
package org.springframework.batch.item;
/**
* Unchecked exception indicating that an error has occured while
* trying to call {@link ItemWriter#flush()}
* Unchecked exception indicating that an error has occurred while trying to call {@link ItemWriter#flush()}
*
* @author Lucas Ward
*
* @author Ben Hale
*/
public class FlushFailedException extends StreamException {
public class FlushFailedException extends ItemWriterException {
/**
* @param message
* Create a new {@link FlushFailedException} based on a message and another exception.
*
* @param message the message for this exception
* @param cause the other exception
*/
public FlushFailedException(String message, Throwable cause) {
super(message, cause);
}
/**
* Create a new {@link FlushFailedException} based on a message.
*
* @param message the message for this exception
*/
public FlushFailedException(String message) {
super(message);
}
/**
* @param msg
* @param nested
*/
public FlushFailedException(String msg, Throwable nested) {
super(msg, nested);
}
/**
* @param msg
* @param nested
*/
public FlushFailedException(Throwable nested) {
super(nested);
}
}

View File

@@ -16,8 +16,6 @@
package org.springframework.batch.item;
import org.springframework.batch.item.exception.MarkFailedException;
import org.springframework.batch.item.exception.ResetFailedException;
import org.springframework.batch.item.reader.AbstractItemReader;
/**
@@ -51,7 +49,7 @@ public interface ItemReader {
*
* @throws Exception if an underlying resource is unavailable.
*/
Object read() throws Exception;
Object read() throws Exception, UnexpectedInputException, NoWorkFoundException;
/**
* Mark the stream so that it can be reset later and the items backed out.<br/>

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2002-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;
/**
* A base exception class that all exceptions thrown from an {@link ItemReader} extend.
*
* @author Ben Hale
*/
public abstract class ItemReaderException extends RuntimeException {
/**
* Create a new {@link ItemReaderException} based on a message and another exception.
*
* @param message the message for this exception
* @param cause the other exception
*/
public ItemReaderException(String message, Throwable cause) {
super(message, cause);
}
/**
* Create a new {@link ItemReaderException} based on a message.
*
* @param message the message for this exception
*/
public ItemReaderException(String message) {
super(message);
}
}

View File

@@ -16,12 +16,10 @@
package org.springframework.batch.item;
import org.springframework.batch.item.exception.StreamException;
/**
* <p>
* Marker interface defining a contract for periodically storing state and
* restoring from that state should an error occur.
* Marker interface defining a contract for periodically storing state and restoring from that state should an error
* occur.
* <p>
*
* @author Dave Syer
@@ -35,23 +33,22 @@ public interface ItemStream {
*
* @throws IllegalArgumentException if context is null
*/
void open(ExecutionContext executionContext) throws StreamException;
void open(ExecutionContext executionContext) throws ItemStreamException;
/**
* Indicates that the execution context provided during open
* is about to be saved. If any state is remaining, but
* has not been put in the context, it should be added
* here.
* Indicates that the execution context provided during open is about to be saved. If any state is remaining, but
* has not been put in the context, it should be added here.
*
* @param executionContext to be updated
* @throws IllegalArgumentException if executionContext is null.
*/
void update(ExecutionContext executionContext);
void update(ExecutionContext executionContext) throws ItemStreamException;
/**
* If any resources are needed for the stream to operate they need to be
* destroyed here. Once this method has been called all other methods
* (except open) may throw an exception.
* If any resources are needed for the stream to operate they need to be destroyed here. Once this method has been
* called all other methods (except open) may throw an exception.
*
* @param executionContext TODO
*/
void close(ExecutionContext executionContext) throws StreamException;
void close(ExecutionContext executionContext) throws ItemStreamException;
}

View File

@@ -13,40 +13,37 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.item.exception;
import org.springframework.batch.io.exception.InfrastructureException;
package org.springframework.batch.item;
/**
* Exception representing any errors encountered while processing
* a stream.
* Exception representing any errors encountered while processing a stream.
*
* @author Dave Syer
* @author Lucas Ward
*/
public class StreamException extends InfrastructureException {
public class ItemStreamException extends RuntimeException {
/**
* @param message
*/
public StreamException(String message) {
public ItemStreamException(String message) {
super(message);
}
/**
* Constructs a new instance with a message and nested exception.
*
* @param msg the exception message.
*
*/
public StreamException(String msg, Throwable nested) {
public ItemStreamException(String msg, Throwable nested) {
super(msg, nested);
}
/**
* Constructs a new instance with a nested exception and empty message.
*/
public StreamException(Throwable nested) {
public ItemStreamException(Throwable nested) {
super(nested);
}
}

View File

@@ -16,8 +16,6 @@
package org.springframework.batch.item;
import org.springframework.batch.item.exception.ClearFailedException;
import org.springframework.batch.item.exception.FlushFailedException;
/**
* <p>Basic interface for generic output operations. Class implementing this

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2002-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;
/**
* A base exception class that all exceptions thrown from an {@link ItemWriter} extend.
*
* @author Ben Hale
*/
public abstract class ItemWriterException extends RuntimeException {
/**
* Create a new {@link ItemWriterException} based on a message and another exception.
*
* @param message the message for this exception
* @param cause the other exception
*/
public ItemWriterException(String message, Throwable cause) {
super(message, cause);
}
/**
* Create a new {@link ItemWriterException} based on a message.
*
* @param message the message for this exception
*/
public ItemWriterException(String message) {
super(message);
}
}

View File

@@ -13,35 +13,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.item.exception;
package org.springframework.batch.item;
/**
* An exception class thrown when an {@link ItemReader} fails to mark its current state for future retry.
*
* @author Dave Syer
*
* @author Ben Hale
*/
public class MarkFailedException extends StreamException {
public class MarkFailedException extends ItemReaderException {
/**
* @param message
* Create a new {@link MarkFailedException} based on a message.
*
* @param message the message for this exception
*/
public MarkFailedException(String message) {
super(message);
}
/**
* @param msg
* @param nested
* Create a new {@link MarkFailedException} based on a message and another exception.
*
* @param message the message for this exception
* @param cause the other exception
*/
public MarkFailedException(String msg, Throwable nested) {
super(msg, nested);
}
/**
* @param msg
* @param nested
*/
public MarkFailedException(Throwable nested) {
super(nested);
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2006-2008 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;
/**
* Exception indicating that an {@link ItemReader} found no work to process while initializing.
*
* @author Lucas Ward
* @author Ben Hale
*/
public class NoWorkFoundException extends ItemReaderException {
/**
* Create a new {@link NoWorkFoundException} based on a message.
*
* @param message the message for this exception
*/
public NoWorkFoundException(String message) {
super(message);
}
/**
* Create a new {@link NoWorkFoundException} based on a message and another exception.
*
* @param message the message for this exception
* @param cause the other exception
*/
public NoWorkFoundException(String msg, Throwable nested) {
super(msg, nested);
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2006-2008 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;
/**
* Exception indicating that an {@link ItemReader} needed to be opened before read.
*
* @author Ben Hale
*/
public class ReaderNotOpenException extends ItemReaderException {
/**
* Create a new {@link ReaderNotOpenException} based on a message.
*
* @param message the message for this exception
*/
public ReaderNotOpenException(String message) {
super(message);
}
/**
* Create a new {@link ReaderNotOpenException} based on a message and another exception.
*
* @param message the message for this exception
* @param cause the other exception
*/
public ReaderNotOpenException(String msg, Throwable nested) {
super(msg, nested);
}
}

View File

@@ -13,37 +13,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.item.exception;
package org.springframework.batch.item;
/**
* An exception class thrown when an {@link ItemReader} fails to reset its state based on the previous mark.
*
* @author Dave Syer
*
* @author Ben Hale
*/
public class ResetFailedException extends StreamException {
public class ResetFailedException extends ItemReaderException {
/**
* @param message
* Create a new {@link ResetFailedException} based on a message.
*
* @param message the message for this exception
*/
public ResetFailedException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
/**
* @param msg
* @param nested
* Create a new {@link ResetFailedException} based on a message and another exception.
*
* @param message the message for this exception
* @param cause the other exception
*/
public ResetFailedException(String msg, Throwable nested) {
super(msg, nested);
}
/**
* @param msg
* @param nested
*/
public ResetFailedException(Throwable nested) {
super(nested);
}
}

View File

@@ -0,0 +1,46 @@
/*
* 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;
/**
* Used to signal an unexpected end of an input or message stream. This is an abnormal condition, not just the end of
* the data - e.g. if a resource becomes unavailable, or a stream becomes unreadable.
*
* @author Dave Syer
* @author Ben Hale
*/
public class UnexpectedInputException extends ItemReaderException {
/**
* Create a new {@link UnexpectedInputException} based on a message.
*
* @param message the message for this exception
*/
public UnexpectedInputException(String message) {
super(message);
}
/**
* Create a new {@link UnexpectedInputException} based on a message and another exception.
*
* @param message the message for this exception
* @param cause the other exception
*/
public UnexpectedInputException(String msg, Throwable nested) {
super(msg, nested);
}
}

View File

@@ -1,46 +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.exception;
/**
* @author Dave Syer
*
*/
public class CommitFailedException extends StreamException {
/**
* @param message
*/
public CommitFailedException(String message) {
super(message);
}
/**
* @param msg
* @param nested
*/
public CommitFailedException(String msg, Throwable nested) {
super(msg, nested);
}
/**
* @param msg
* @param nested
*/
public CommitFailedException(Throwable nested) {
super(nested);
}
}

View File

@@ -1,30 +0,0 @@
/*
* Copyright 2006-2008 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.exception;
/**
* Exception indicating that an {@link ItemReader} found
* no work to process while initializing.
*
* @author Lucas Ward
*
*/
public class NoWorkFoundException extends StreamException {
public NoWorkFoundException(String msg) {
super(msg);
}
}

View File

@@ -1,37 +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.exception;
/**
* Used to signal an unexpected end of an input or message stream. This is an
* abnormal condition, not just the end of the data - e.g. if a resource becomes
* unavailable, or a stream becomes unreadable.
*
* @author Dave Syer
*/
public class UnexpectedInputException extends StreamException {
/**
* Generated serial UID.
*/
private static final long serialVersionUID = -8325588758094208905L;
public UnexpectedInputException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -1,7 +0,0 @@
<html>
<body>
<p>
Infrastructure implementations of item exception concerns.
</p>
</body>
</html>

View File

@@ -17,8 +17,8 @@
package org.springframework.batch.item.reader;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.exception.MarkFailedException;
import org.springframework.batch.item.exception.ResetFailedException;
import org.springframework.batch.item.MarkFailedException;
import org.springframework.batch.item.ResetFailedException;
/**
* Base class for {@link ItemReader} implementations.

View File

@@ -18,9 +18,9 @@ package org.springframework.batch.item.reader;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.exception.MarkFailedException;
import org.springframework.batch.item.exception.ResetFailedException;
import org.springframework.batch.item.exception.StreamException;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.MarkFailedException;
import org.springframework.batch.item.ResetFailedException;
import org.springframework.batch.support.AbstractMethodInvokingDelegator;
/**
@@ -43,7 +43,7 @@ public class ItemReaderAdapter extends AbstractMethodInvokingDelegator implement
*
* @see org.springframework.batch.item.ItemReader#close(ExecutionContext)
*/
public void close() throws StreamException {
public void close() throws ItemStreamException {
}

View File

@@ -26,7 +26,7 @@ import org.springframework.batch.item.FailedItemIdentifier;
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.batch.item.UnexpectedInputException;
import org.springframework.jms.JmsException;
import org.springframework.jms.core.JmsOperations;
import org.springframework.jms.core.JmsTemplate;

View File

@@ -22,7 +22,7 @@ import java.util.List;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.exception.StreamException;
import org.springframework.batch.item.ItemStreamException;
/**
* Simple {@link ItemStream} that delegates to a list of other streams.
@@ -83,9 +83,9 @@ public class CompositeItemStream implements ItemStream {
/**
* Broadcast the call to close from this {@link StreamManager}.
* @throws StreamException
* @throws ItemStreamException
*/
public void close(ExecutionContext executionContext) throws StreamException {
public void close(ExecutionContext executionContext) throws ItemStreamException {
synchronized (streams) {
for (Iterator it = streams.iterator(); it.hasNext();) {
ItemStream itemStream = (ItemStream) it.next();
@@ -96,9 +96,9 @@ public class CompositeItemStream implements ItemStream {
/**
* Broadcast the call to open from this {@link StreamManager}.
* @throws StreamException
* @throws ItemStreamException
*/
public void open(ExecutionContext executionContext) throws StreamException {
public void open(ExecutionContext executionContext) throws ItemStreamException {
synchronized (streams) {
for (Iterator it = streams.iterator(); it.hasNext();) {
ItemStream itemStream = (ItemStream) it.next();

View File

@@ -17,7 +17,7 @@ package org.springframework.batch.item.stream;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.exception.StreamException;
import org.springframework.batch.item.ItemStreamException;
/**
* Empty method implementation of {@link ItemStream}.
@@ -31,14 +31,14 @@ public class ItemStreamSupport implements ItemStream {
* No-op.
* @see org.springframework.batch.item.ItemStream#close(ExecutionContext)
*/
public void close(ExecutionContext executionContext) throws StreamException {
public void close(ExecutionContext executionContext) throws ItemStreamException {
}
/**
* No-op.
* @see org.springframework.batch.item.ItemStream#open()
*/
public void open(ExecutionContext executionContext) throws StreamException {
public void open(ExecutionContext executionContext) throws ItemStreamException {
}
/**

View File

@@ -15,9 +15,9 @@
*/
package org.springframework.batch.item.writer;
import org.springframework.batch.item.ClearFailedException;
import org.springframework.batch.item.FlushFailedException;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
import org.springframework.batch.item.exception.FlushFailedException;
/**
* Abstract {@link ItemWriter} that allows for base classes to only

View File

@@ -1,8 +1,8 @@
package org.springframework.batch.item.writer;
import org.springframework.batch.item.ClearFailedException;
import org.springframework.batch.item.FlushFailedException;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
import org.springframework.batch.item.exception.FlushFailedException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

View File

@@ -16,9 +16,9 @@
package org.springframework.batch.item.writer;
import org.springframework.batch.item.ClearFailedException;
import org.springframework.batch.item.FlushFailedException;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
import org.springframework.batch.item.exception.FlushFailedException;
import org.springframework.batch.support.AbstractMethodInvokingDelegator;

View File

@@ -16,9 +16,9 @@
package org.springframework.batch.item.writer;
import org.springframework.batch.item.ClearFailedException;
import org.springframework.batch.item.FlushFailedException;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
import org.springframework.batch.item.exception.FlushFailedException;
import org.springframework.batch.support.AbstractMethodInvokingDelegator;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

View File

@@ -10,7 +10,7 @@ import org.springframework.batch.io.sample.domain.Foo;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.exception.NoWorkFoundException;
import org.springframework.batch.item.NoWorkFoundException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;

View File

@@ -25,11 +25,6 @@ public abstract class AbstractExceptionTests extends TestCase {
assertEquals("foo", exception.getMessage());
}
public void testExceptionThrowable() throws Exception {
Exception exception = getException(new RuntimeException("foo"));
assertEquals("foo", exception.getCause().getMessage());
}
public void testExceptionStringThrowable() throws Exception {
Exception exception = getException("foo", new IllegalStateException());
assertEquals("foo", exception.getMessage().substring(0, 3));
@@ -37,8 +32,6 @@ public abstract class AbstractExceptionTests extends TestCase {
public abstract Exception getException(String msg) throws Exception;
public abstract Exception getException(Throwable t) throws Exception;
public abstract Exception getException(String msg, Throwable t) throws Exception;
}

View File

@@ -16,7 +16,6 @@
package org.springframework.batch.io.exception;
import org.springframework.batch.io.exception.ConfigurationException;
public class ConfigurationExceptionTests extends AbstractExceptionTests {

View File

@@ -29,7 +29,8 @@ import org.springframework.batch.io.file.separator.DefaultRecordSeparatorPolicy;
import org.springframework.batch.io.file.transform.DelimitedLineTokenizer;
import org.springframework.batch.io.file.transform.LineTokenizer;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.exception.StreamException;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ReaderNotOpenException;
import org.springframework.core.io.AbstractResource;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
@@ -148,8 +149,8 @@ public class FlatFileItemReaderBasicTests extends TestCase {
itemReader.setFieldSetMapper(fieldSetMapper);
try {
itemReader.read();
fail("Expected StreamException");
} catch (StreamException e) {
fail("Expected ReaderNotOpenException");
} catch (ReaderNotOpenException e) {
assertTrue(e.getMessage().contains("open"));
}
}
@@ -210,7 +211,7 @@ public class FlatFileItemReaderBasicTests extends TestCase {
itemReader.open(executionContext);
fail("Expected BatchEnvironmentException");
}
catch (StreamException e) {
catch (ItemStreamException e) {
// expected
assertEquals("foo", e.getCause().getMessage());
}

View File

@@ -23,7 +23,8 @@ import junit.framework.TestCase;
import org.springframework.batch.io.file.separator.ResourceLineReader;
import org.springframework.batch.io.file.separator.SuffixRecordSeparatorPolicy;
import org.springframework.batch.item.exception.StreamException;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.UnexpectedInputException;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
@@ -41,9 +42,9 @@ public class ResourceLineReaderTests extends TestCase {
}));
try {
reader.read();
fail("Expected InputException");
fail("Expected UnexpectedInputException");
}
catch (StreamException e) {
catch (UnexpectedInputException e) {
// expected
assertTrue(e.getMessage().startsWith("Unable to read"));
}

View File

@@ -16,8 +16,6 @@
package org.springframework.batch.io.file.mapping;
import org.springframework.batch.io.file.mapping.PropertyMatches;
import junit.framework.TestCase;
public class PropertyMatchesTests extends TestCase {

View File

@@ -16,8 +16,6 @@
package org.springframework.batch.io.file.separator;
import org.springframework.batch.io.file.separator.DefaultRecordSeparatorPolicy;
import junit.framework.TestCase;
public class DefaultRecordSeparatorPolicyTests extends TestCase {

View File

@@ -16,8 +16,6 @@
package org.springframework.batch.io.file.separator;
import org.springframework.batch.io.file.separator.SimpleRecordSeparatorPolicy;
import junit.framework.TestCase;
public class SimpleRecordSeparatorPolicyTests extends TestCase {

View File

@@ -16,8 +16,6 @@
package org.springframework.batch.io.file.separator;
import org.springframework.batch.io.file.separator.SuffixRecordSeparatorPolicy;
import junit.framework.TestCase;
public class SuffixRecordSeparatorPolicyTests extends TestCase {

View File

@@ -2,8 +2,6 @@ package org.springframework.batch.io.file.transform;
import java.util.List;
import org.springframework.batch.io.file.transform.AbstractLineTokenizer;
import junit.framework.TestCase;
/**

View File

@@ -19,8 +19,6 @@ package org.springframework.batch.io.file.transform;
import junit.framework.TestCase;
import org.springframework.batch.io.file.mapping.FieldSet;
import org.springframework.batch.io.file.transform.AbstractLineTokenizer;
import org.springframework.batch.io.file.transform.DelimitedLineTokenizer;
public class DelimitedLineTokenizerTests extends TestCase {

View File

@@ -16,12 +16,10 @@
package org.springframework.batch.io.file.transform;
import org.springframework.batch.io.file.mapping.DefaultFieldSet;
import org.springframework.batch.io.file.transform.FixedLengthLineAggregator;
import org.springframework.batch.io.file.transform.Range;
import junit.framework.TestCase;
import org.springframework.batch.io.file.mapping.DefaultFieldSet;
/**
* Unit tests for {@link FixedLengthLineAggregator}
*

View File

@@ -19,8 +19,6 @@ package org.springframework.batch.io.file.transform;
import junit.framework.TestCase;
import org.springframework.batch.io.file.mapping.FieldSet;
import org.springframework.batch.io.file.transform.FixedLengthTokenizer;
import org.springframework.batch.io.file.transform.Range;
public class FixedLengthTokenizerTests extends TestCase {

View File

@@ -15,10 +15,10 @@
*/
package org.springframework.batch.io.file.transform;
import org.springframework.batch.io.file.mapping.FieldSet;
import junit.framework.TestCase;
import org.springframework.batch.io.file.mapping.FieldSet;
/**
* @author Dave Syer
*

View File

@@ -25,8 +25,6 @@ import junit.framework.TestCase;
import org.springframework.batch.io.file.mapping.DefaultFieldSet;
import org.springframework.batch.io.file.mapping.FieldSet;
import org.springframework.batch.io.file.transform.DelimitedLineTokenizer;
import org.springframework.batch.io.file.transform.PrefixMatchingCompositeLineTokenizer;
public class PrefixMatchingCompositeLineTokenizerTests extends TestCase {

View File

@@ -1,8 +1,5 @@
package org.springframework.batch.io.file.transform;
import org.springframework.batch.io.file.transform.Range;
import org.springframework.batch.io.file.transform.RangeArrayPropertyEditor;
import junit.framework.TestCase;
public class RangeArrayPropertyEditorTests extends TestCase {

View File

@@ -18,11 +18,11 @@ package org.springframework.batch.io.file.transform;
import java.util.Arrays;
import java.util.Collections;
import junit.framework.TestCase;
import org.springframework.batch.item.writer.ItemTransformer;
import org.springframework.util.StringUtils;
import junit.framework.TestCase;
/**
* @author Dave Syer
*

View File

@@ -5,11 +5,11 @@ import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import junit.framework.TestCase;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.util.Assert;
import junit.framework.TestCase;
/**
* Tests for {@link FileUtils}
*

View File

@@ -22,9 +22,9 @@ import java.util.Map;
import junit.framework.TestCase;
import org.springframework.batch.item.ClearFailedException;
import org.springframework.batch.item.FlushFailedException;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
import org.springframework.batch.item.exception.FlushFailedException;
import org.springframework.batch.repeat.context.RepeatContextSupport;
import org.springframework.batch.repeat.synch.RepeatSynchronizationManager;
import org.springframework.dao.DataAccessException;

View File

@@ -15,7 +15,8 @@ import javax.xml.stream.events.XMLEvent;
import junit.framework.TestCase;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.exception.StreamException;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ReaderNotOpenException;
import org.springframework.core.io.AbstractResource;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
@@ -139,7 +140,7 @@ public class StaxEventItemReaderTests extends TestCase {
source.open(context);
fail("Expected StreamException");
}
catch (StreamException e) {
catch (ItemStreamException e) {
// expected
String message = e.getMessage();
assertTrue("Wrong message: "+message, message.contains("must be before"));
@@ -241,9 +242,9 @@ public class StaxEventItemReaderTests extends TestCase {
// calling read again should require re-initialization because of close
try {
item = newSource.read();
fail("Expected StreamException");
fail("Expected ReaderNotOpenException");
}
catch (StreamException e) {
catch (ReaderNotOpenException e) {
// expected
}
}

View File

@@ -26,7 +26,6 @@ import javax.xml.transform.Result;
import junit.framework.TestCase;
import org.springframework.batch.io.xml.oxm.MarshallingEventWriterSerializer;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.XmlMappingException;

View File

@@ -8,7 +8,6 @@ import javax.xml.stream.XMLInputFactory;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.io.xml.oxm.UnmarshallingEventReaderDeserializer;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessException;

View File

@@ -22,7 +22,6 @@ import javax.xml.stream.events.XMLEvent;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.io.xml.stax.AbstractEventReaderWrapper;
import com.bea.xml.stream.events.StartDocumentEvent;

View File

@@ -24,7 +24,6 @@ import javax.xml.stream.events.XMLEvent;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.io.xml.stax.AbstractEventWriterWrapper;
import com.bea.xml.stream.events.StartDocumentEvent;
import com.bea.xml.stream.util.NamespaceContextImpl;

View File

@@ -10,8 +10,6 @@ import javax.xml.stream.events.XMLEvent;
import junit.framework.TestCase;
import org.springframework.batch.io.xml.EventHelper;
import org.springframework.batch.io.xml.stax.DefaultFragmentEventReader;
import org.springframework.batch.io.xml.stax.DefaultTransactionalEventReader;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;

View File

@@ -6,7 +6,6 @@ import javax.xml.stream.XMLInputFactory;
import junit.framework.TestCase;
import org.springframework.batch.io.xml.EventHelper;
import org.springframework.batch.io.xml.stax.DefaultTransactionalEventReader;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;

View File

@@ -3,8 +3,6 @@ package org.springframework.batch.io.xml.stax;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.events.XMLEvent;
import org.springframework.batch.io.xml.stax.EventSequence;
import junit.framework.TestCase;
/**

View File

@@ -7,7 +7,6 @@ import javax.xml.stream.events.XMLEvent;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.io.xml.stax.NoStartEndDocumentStreamWriter;
/**
* Tests for {@link NoStartEndDocumentStreamWriter}

View File

@@ -14,23 +14,22 @@
* limitations under the License.
*/
package org.springframework.batch.item.exception;
package org.springframework.batch.item;
import org.springframework.batch.io.exception.AbstractExceptionTests;
public class StreamExceptionTests extends AbstractExceptionTests {
public class ItemStreamExceptionTests extends AbstractExceptionTests {
public Exception getException(String msg) throws Exception {
return new StreamException(msg);
return new ItemStreamException(msg);
}
public Exception getException(Throwable t) throws Exception {
return new StreamException(t);
return new ItemStreamException(t);
}
public Exception getException(String msg, Throwable t) throws Exception {
return new StreamException(msg, t);
return new ItemStreamException(msg, t);
}
}

View File

@@ -14,21 +14,16 @@
* limitations under the License.
*/
package org.springframework.batch.item.exception;
package org.springframework.batch.item;
import org.springframework.batch.io.exception.AbstractExceptionTests;
public class MarkFailedExceptionTests extends AbstractExceptionTests {
public Exception getException(String msg) throws Exception {
return new MarkFailedException(msg);
}
public Exception getException(Throwable t) throws Exception {
return new MarkFailedException(t);
}
public Exception getException(String msg, Throwable t) throws Exception {
return new MarkFailedException(msg, t);
}

View File

@@ -14,21 +14,16 @@
* limitations under the License.
*/
package org.springframework.batch.item.exception;
package org.springframework.batch.item;
import org.springframework.batch.io.exception.AbstractExceptionTests;
public class ResetFailedExceptionTests extends AbstractExceptionTests {
public Exception getException(String msg) throws Exception {
return new ResetFailedException(msg);
}
public Exception getException(Throwable t) throws Exception {
return new ResetFailedException(t);
}
public Exception getException(String msg, Throwable t) throws Exception {
return new ResetFailedException(msg, t);
}

View File

@@ -14,9 +14,8 @@
* limitations under the License.
*/
package org.springframework.batch.item.exception;
package org.springframework.batch.item;
import org.springframework.batch.item.exception.UnexpectedInputException;
import org.springframework.batch.repeat.exception.AbstractExceptionTests;
public class UnexpectedInputExceptionTests extends AbstractExceptionTests {

View File

@@ -7,7 +7,6 @@ import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.reader.AggregateItemReader;
public class AggregateItemReaderTests extends TestCase {

View File

@@ -25,7 +25,6 @@ import javax.jms.Queue;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.item.reader.JmsItemReader;
import org.springframework.jms.core.JmsOperations;
public class JmsItemReaderTests extends TestCase {

View File

@@ -20,8 +20,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.batch.item.reader.ListItemReader;
import junit.framework.TestCase;
public class ListItemReaderTests extends TestCase {

View File

@@ -22,7 +22,6 @@ import java.util.List;
import junit.framework.TestCase;
import org.springframework.batch.item.reader.ListItemReader;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.batch.support.transaction.TransactionAwareProxyFactory;
import org.springframework.transaction.PlatformTransactionManager;

View File

@@ -20,8 +20,6 @@ import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.io.exception.ValidationException;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.reader.AbstractItemReader;
import org.springframework.batch.item.reader.ValidatingItemReader;
import org.springframework.batch.item.validator.Validator;
/**

View File

@@ -22,7 +22,7 @@ import junit.framework.TestCase;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.exception.StreamException;
import org.springframework.batch.item.ItemStreamException;
/**
* @author Dave Syer
@@ -40,7 +40,7 @@ public class SimpleStreamManagerTests extends TestCase {
*/
public void testRegisterAndOpen() {
ItemStreamSupport stream = new ItemStreamSupport() {
public void open(ExecutionContext executionContext) throws StreamException {
public void open(ExecutionContext executionContext) throws ItemStreamException {
list.add("bar");
}
};
@@ -55,7 +55,7 @@ public class SimpleStreamManagerTests extends TestCase {
*/
public void testRegisterTwice() {
ItemStreamSupport stream = new ItemStreamSupport() {
public void open(ExecutionContext executionContext) throws StreamException {
public void open(ExecutionContext executionContext) throws ItemStreamException {
list.add("bar");
}
};
@@ -85,7 +85,7 @@ public class SimpleStreamManagerTests extends TestCase {
*/
public void testClose() {
manager.register(new ItemStreamSupport() {
public void close(ExecutionContext executionContext) throws StreamException {
public void close(ExecutionContext executionContext) throws ItemStreamException {
list.add("bar");
}
});
@@ -99,7 +99,7 @@ public class SimpleStreamManagerTests extends TestCase {
*/
public void testCloseDoesNotUnregister() {
manager.setStreams(new ItemStream[] { new ItemStreamSupport() {
public void open(ExecutionContext executionContext) throws StreamException {
public void open(ExecutionContext executionContext) throws ItemStreamException {
list.add("bar");
}
} });

View File

@@ -19,7 +19,6 @@ package org.springframework.batch.item.validator;
import junit.framework.TestCase;
import org.springframework.batch.io.exception.ValidationException;
import org.springframework.batch.item.validator.SpringValidator;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

View File

@@ -5,8 +5,6 @@ import java.util.ArrayList;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.item.writer.CompositeItemTransformer;
import org.springframework.batch.item.writer.ItemTransformer;
/**
* Tests for {@link CompositeItemTransformer}.

View File

@@ -15,11 +15,11 @@
*/
package org.springframework.batch.item.writer;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.item.ItemWriter;
import junit.framework.TestCase;
/**
* @author Lucas Ward
*

View File

@@ -4,8 +4,6 @@ import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.writer.ItemTransformer;
import org.springframework.batch.item.writer.ItemTransformerItemWriter;
/**
* Tests for {@link ItemTransformerItemWriter}.

View File

@@ -4,7 +4,6 @@ import java.util.List;
import org.springframework.batch.io.sample.domain.Foo;
import org.springframework.batch.io.sample.domain.FooService;
import org.springframework.batch.item.writer.PropertyExtractingDelegatingItemWriter;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
/**

View File

@@ -15,10 +15,10 @@
*/
package org.springframework.batch.repeat;
import org.apache.commons.lang.SerializationUtils;
import junit.framework.TestCase;
import org.apache.commons.lang.SerializationUtils;
/**
* @author Dave Syer
*

View File

@@ -18,9 +18,9 @@ package org.springframework.batch.repeat.callback;
import junit.framework.TestCase;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatCallback;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.support.RepeatTemplate;
public class NestedRepeatCallbackTests extends TestCase {

View File

@@ -19,8 +19,6 @@ package org.springframework.batch.repeat.context;
import junit.framework.TestCase;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.context.RepeatContextCounter;
import org.springframework.batch.repeat.context.RepeatContextSupport;
public class RepeatContextCounterTests extends TestCase {

View File

@@ -23,7 +23,6 @@ import java.util.Map;
import junit.framework.TestCase;
import org.springframework.batch.repeat.context.SynchronizedAttributeAccessor;
import org.springframework.core.AttributeAccessorSupport;
public class SynchronizedAttributeAccessorTests extends TestCase {

View File

@@ -23,8 +23,6 @@ import junit.framework.TestCase;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.RepeatListener;
import org.springframework.batch.repeat.context.RepeatContextSupport;
import org.springframework.batch.repeat.listener.CompositeRepeatListener;
import org.springframework.batch.repeat.listener.RepeatListenerSupport;
/**
* @author Dave Syer

View File

@@ -25,7 +25,6 @@ import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatCallback;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.RepeatListener;
import org.springframework.batch.repeat.listener.RepeatListenerSupport;
import org.springframework.batch.repeat.support.RepeatTemplate;
import org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate;
import org.springframework.core.task.SimpleAsyncTaskExecutor;

View File

@@ -18,9 +18,9 @@ package org.springframework.batch.repeat.policy;
import junit.framework.TestCase;
import org.springframework.batch.repeat.CompletionPolicy;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.CompletionPolicy;
public class CompositeCompletionPolicyTests extends TestCase {

View File

@@ -19,9 +19,9 @@ package org.springframework.batch.repeat.support;
import java.util.HashSet;
import java.util.Set;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatCallback;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.callback.ItemReaderRepeatCallback;
import org.springframework.core.task.SimpleAsyncTaskExecutor;

View File

@@ -18,9 +18,9 @@ package org.springframework.batch.repeat.support;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.reader.AbstractItemReader;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatCallback;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.callback.ItemReaderRepeatCallback;
import org.springframework.batch.repeat.callback.NestedRepeatCallback;
import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;

View File

@@ -19,9 +19,9 @@ package org.springframework.batch.repeat.support;
import java.util.ArrayList;
import java.util.List;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatCallback;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.callback.ItemReaderRepeatCallback;
import org.springframework.batch.repeat.callback.NestedRepeatCallback;
import org.springframework.batch.repeat.context.RepeatContextSupport;

View File

@@ -20,7 +20,6 @@ import junit.framework.TestCase;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.context.RepeatContextSupport;
import org.springframework.batch.repeat.synch.RepeatSynchronizationManager;
public class RepeatSynchronizationManagerTests extends TestCase {

View File

@@ -16,8 +16,6 @@
package org.springframework.batch.retry.listener;
import org.springframework.batch.retry.listener.RetryListenerSupport;
import junit.framework.TestCase;
public class RetryListenerSupportTests extends TestCase {

View File

@@ -18,8 +18,6 @@ package org.springframework.batch.support;
import java.util.Properties;
import org.springframework.batch.support.PropertiesConverter;
import junit.framework.TestCase;
/**

View File

@@ -1,8 +1,8 @@
package org.springframework.batch.sample.dao;
import org.springframework.batch.item.ClearFailedException;
import org.springframework.batch.item.FlushFailedException;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
import org.springframework.batch.item.exception.FlushFailedException;
import org.springframework.batch.sample.domain.Game;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.util.Assert;

View File

@@ -1,8 +1,8 @@
package org.springframework.batch.sample.dao;
import org.springframework.batch.item.ClearFailedException;
import org.springframework.batch.item.FlushFailedException;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.exception.ClearFailedException;
import org.springframework.batch.item.exception.FlushFailedException;
import org.springframework.batch.sample.domain.PlayerSummary;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.util.Assert;

View File

@@ -4,8 +4,8 @@ import java.math.BigDecimal;
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.MarkFailedException;
import org.springframework.batch.item.ResetFailedException;
import org.springframework.batch.sample.domain.Trade;
/**

Some files were not shown because too many files have changed in this diff Show More