From 4b24ef866c4adebf05932dab70ba01a98dbabd74 Mon Sep 17 00:00:00 2001
From: lucasward
Date: Mon, 8 Oct 2007 04:28:31 +0000
Subject: [PATCH] BATCH-140: Modified file input sources to no longer
implemented FieldSet and now accept an injected mapper.
---
.../exception/FlatFileParsingException.java | 62 +++++
.../ParsingException.java} | 73 +++---
.../support/DefaultFlatFileInputSource.java | 19 +-
.../support/SimpleFlatFileInputSource.java | 55 ++---
.../AbstractFieldSetItemProvider.java | 74 ------
.../item/provider/FlatFileItemProvider.java | 116 ----------
.../provider/InputSourceItemProvider.java | 35 +--
.../item/provider/ValidatingItemProvider.java | 59 +++++
.../DefaultFlatFileInputSourceTests.java | 103 +++++----
.../SimpleFlatFileInputSourceTests.java | 118 ++++++----
.../AbstractFieldSetItemProviderTests.java | 59 -----
.../provider/FieldSetItemProviderTests.java | 54 -----
.../provider/FlatFileItemProviderTests.java | 217 ------------------
.../InputSourceItemProviderTests.java | 21 +-
.../provider/ValidatingItemProviderTests.java | 114 +++++++++
.../support/AbstractTradeBatchTests.java | 24 +-
16 files changed, 488 insertions(+), 715 deletions(-)
create mode 100644 infrastructure/src/main/java/org/springframework/batch/io/exception/FlatFileParsingException.java
rename infrastructure/src/main/java/org/springframework/batch/io/{file/FieldSetInputSource.java => exception/ParsingException.java} (54%)
delete mode 100644 infrastructure/src/main/java/org/springframework/batch/item/provider/AbstractFieldSetItemProvider.java
delete mode 100644 infrastructure/src/main/java/org/springframework/batch/item/provider/FlatFileItemProvider.java
create mode 100644 infrastructure/src/main/java/org/springframework/batch/item/provider/ValidatingItemProvider.java
delete mode 100644 infrastructure/src/test/java/org/springframework/batch/item/provider/AbstractFieldSetItemProviderTests.java
delete mode 100644 infrastructure/src/test/java/org/springframework/batch/item/provider/FieldSetItemProviderTests.java
delete mode 100644 infrastructure/src/test/java/org/springframework/batch/item/provider/FlatFileItemProviderTests.java
create mode 100644 infrastructure/src/test/java/org/springframework/batch/item/provider/ValidatingItemProviderTests.java
diff --git a/infrastructure/src/main/java/org/springframework/batch/io/exception/FlatFileParsingException.java b/infrastructure/src/main/java/org/springframework/batch/io/exception/FlatFileParsingException.java
new file mode 100644
index 000000000..c3cf23adf
--- /dev/null
+++ b/infrastructure/src/main/java/org/springframework/batch/io/exception/FlatFileParsingException.java
@@ -0,0 +1,62 @@
+/*
+ * 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.io.exception;
+
+/**
+ * Exception thrown when errors are encountered
+ * parsing flat files. The original input, typically
+ * a line, can be passed in, so that latter catches
+ * can write out the original input to a log, or
+ * an error table.
+ *
+ * @author Lucas Ward
+ *
+ */
+public class FlatFileParsingException extends ParsingException {
+
+ private String input;
+ private int lineNumber;
+
+ public FlatFileParsingException(String message, String input) {
+ super(message);
+ this.input = input;
+ }
+
+ public FlatFileParsingException(String message, String input, int lineNumber) {
+ super(message);
+ this.input = input;
+ this.lineNumber = lineNumber;
+ }
+
+ public FlatFileParsingException(String message, Throwable cause, String input, int lineNumber) {
+ super(message, cause);
+ this.input = input;
+ this.lineNumber = lineNumber;
+ }
+
+ public FlatFileParsingException(Throwable cause, String input) {
+ super(cause);
+ this.input = input;
+ }
+
+ public String getInput() {
+ return input;
+ }
+
+ public int getLineNumber() {
+ return lineNumber;
+ }
+}
diff --git a/infrastructure/src/main/java/org/springframework/batch/io/file/FieldSetInputSource.java b/infrastructure/src/main/java/org/springframework/batch/io/exception/ParsingException.java
similarity index 54%
rename from infrastructure/src/main/java/org/springframework/batch/io/file/FieldSetInputSource.java
rename to infrastructure/src/main/java/org/springframework/batch/io/exception/ParsingException.java
index fea876ef7..9bf5c3271 100644
--- a/infrastructure/src/main/java/org/springframework/batch/io/file/FieldSetInputSource.java
+++ b/infrastructure/src/main/java/org/springframework/batch/io/exception/ParsingException.java
@@ -1,35 +1,38 @@
-/*
- * 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.io.file;
-
-import org.springframework.batch.io.InputSource;
-
-/**
- * Common interface for reading input e.g. from a file or other stream-based
- * resource. Providers are expected to use this interface to access an input
- * source.
- *
- * If we had generics this would be a parameterised input source, but
- * for type safety with the current constraints we are going to use this
- * interface.
- *
- */
-public interface FieldSetInputSource extends InputSource {
-
- public FieldSet readFieldSet();
-
-}
+/*
+ * 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.io.exception;
+
+/**
+ * Exception indicating that an error has been encountered
+ * parsing io, typically from a file.
+ *
+ * @author Lucas Ward
+ *
+ */
+public class ParsingException extends RuntimeException {
+
+ public ParsingException(String message) {
+ super(message);
+ }
+
+ public ParsingException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ParsingException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/infrastructure/src/main/java/org/springframework/batch/io/file/support/DefaultFlatFileInputSource.java b/infrastructure/src/main/java/org/springframework/batch/io/file/support/DefaultFlatFileInputSource.java
index 2c4e3802a..6206e31e5 100644
--- a/infrastructure/src/main/java/org/springframework/batch/io/file/support/DefaultFlatFileInputSource.java
+++ b/infrastructure/src/main/java/org/springframework/batch/io/file/support/DefaultFlatFileInputSource.java
@@ -23,7 +23,6 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.io.Skippable;
-import org.springframework.batch.io.file.FieldSetInputSource;
import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationManager;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
@@ -37,7 +36,7 @@ import org.springframework.transaction.support.TransactionSynchronizationAdapter
* This class is a {@link FieldSetInputSource} that supports restart,
* skipping invalid lines and storing statistics.
*
- *
+ *
* @author Waseem Malik
* @author Tomas Slanina
* @author Robert Kasanicky
@@ -49,13 +48,13 @@ public class DefaultFlatFileInputSource extends SimpleFlatFileInputSource implem
public static final String READ_STATISTICS_NAME = "lines.read.count";
public static final String SKIPPED_STATISTICS_NAME = "skipped.lines.count";
-
+
private Set skippedLines = new HashSet();
private TransactionSynchronization transactionSynchronization = new ResourceLineReaderTransactionSynchronization();
-
+
private Properties statistics = new Properties();
-
+
/**
* Initialize the input source.
*/
@@ -73,14 +72,14 @@ public class DefaultFlatFileInputSource extends SimpleFlatFileInputSource implem
* This method initialises the Input Source for Restart. It opens the input
* file and position the buffer reader according to information provided by
* the restart data
- *
+ *
* @param restartData restartData information
*/
public void restoreFrom(RestartData data) {
-
+
//TODO this does not look very nice...
- if (data==null ||
- data.getProperties() == null ||
+ if (data==null ||
+ data.getProperties() == null ||
data.getProperties().getProperty(READ_STATISTICS_NAME) == null ||
getReader()==null) {
// do nothing
@@ -173,7 +172,7 @@ public class DefaultFlatFileInputSource extends SimpleFlatFileInputSource implem
/**
* TransactionSynchronization method indicating that a transaction has
* completed.
- *
+ *
* @param status indicates whether it was a rollback or commit
*/
public void afterCompletion(int status) {
diff --git a/infrastructure/src/main/java/org/springframework/batch/io/file/support/SimpleFlatFileInputSource.java b/infrastructure/src/main/java/org/springframework/batch/io/file/support/SimpleFlatFileInputSource.java
index 19bef828a..17ea0994c 100644
--- a/infrastructure/src/main/java/org/springframework/batch/io/file/support/SimpleFlatFileInputSource.java
+++ b/infrastructure/src/main/java/org/springframework/batch/io/file/support/SimpleFlatFileInputSource.java
@@ -19,9 +19,10 @@ package org.springframework.batch.io.file.support;
import java.io.IOException;
import org.springframework.batch.io.InputSource;
+import org.springframework.batch.io.exception.FlatFileParsingException;
import org.springframework.batch.io.exception.ValidationException;
import org.springframework.batch.io.file.FieldSet;
-import org.springframework.batch.io.file.FieldSetInputSource;
+import org.springframework.batch.io.file.FieldSetMapper;
import org.springframework.batch.io.file.support.separator.RecordSeparatorPolicy;
import org.springframework.batch.io.file.support.transform.DelimitedLineTokenizer;
import org.springframework.batch.io.file.support.transform.LineTokenizer;
@@ -37,17 +38,17 @@ import org.springframework.util.Assert;
* 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.
- *
+ *
* A {@link SimpleFlatFileInputSource} is not thread safe because it maintains
* state in the form of a {@link ResourceLineReader}. Be careful to configure a
* {@link SimpleFlatFileInputSource} using an appropriate factory or scope so
* that it is not shared between threads.
- *
+ *
* @see FieldSetInputSource
- *
+ *
* @author Dave Syer
*/
-public class SimpleFlatFileInputSource implements ResourceLifecycle, FieldSetInputSource, InitializingBean, DisposableBean {
+public class SimpleFlatFileInputSource implements InputSource, InitializingBean, DisposableBean {
// default encoding for input files - set to ISO-8859-1
public static final String DEFAULT_CHARSET = "ISO-8859-1";
@@ -64,6 +65,8 @@ public class SimpleFlatFileInputSource implements ResourceLifecycle, FieldSetInp
private LineTokenizer tokenizer = new DelimitedLineTokenizer();
+ private FieldSetMapper fieldSetMapper;
+
private String encoding = DEFAULT_CHARSET;
/**
@@ -80,7 +83,7 @@ public class SimpleFlatFileInputSource implements ResourceLifecycle, FieldSetInp
* 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
*/
public void setRecordSeparatorPolicy(RecordSeparatorPolicy recordSeparatorPolicy) {
@@ -90,6 +93,7 @@ public class SimpleFlatFileInputSource implements ResourceLifecycle, FieldSetInp
public void afterPropertiesSet() throws Exception {
Assert.notNull(resource);
Assert.state(resource.exists(), "Resource must exist: [" + resource + "]");
+ Assert.notNull(fieldSetMapper, "FieldSetMapper must not be null.");
}
/**
@@ -107,7 +111,7 @@ public class SimpleFlatFileInputSource implements ResourceLifecycle, FieldSetInp
/**
* Close and null out the reader.
- *
+ *
* @see ResourceLifecycle
*/
public void close() {
@@ -124,7 +128,7 @@ public class SimpleFlatFileInputSource implements ResourceLifecycle, FieldSetInp
/**
* Calls close to ensure that bean factories can close and always release
* resources.
- *
+ *
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
public void destroy() throws Exception {
@@ -139,31 +143,21 @@ public class SimpleFlatFileInputSource implements ResourceLifecycle, FieldSetInp
/**
* A wrapper for {@link #readFieldSet()} to make this into a real
* {@link InputSource}.
- *
+ *
* @see org.springframework.batch.io.InputSource#read()
*/
- public final Object read() {
- return readFieldSet();
- }
-
- /**
- * Get the next {@link FieldSet} from the input.
- *
- * @see org.springframework.batch.io.file.FieldSetInputSource#readFieldSet()
- */
- public FieldSet readFieldSet() {
+ public Object read() {
String line = readLine();
if (line != null) {
try {
- return this.tokenizer.tokenize(line);
+ FieldSet tokenizedLine = tokenizer.tokenize(line);
+ return fieldSetMapper.mapLine(tokenizedLine);
}
- catch (RuntimeException ve) {
+ catch (RuntimeException ex) {
// add current line count to message and re-throw
- // TODO: wrap the exception more carefully to preserve type etc.
- ValidationException newVe = new ValidationException("Validation error at line "
- + getReader().getCurrentLineCount() + ": " + ve.getMessage());
- throw newVe;
+ throw new FlatFileParsingException("Parsing error", ex, line,
+ getReader().getCurrentLineCount());
}
}
return null;
@@ -172,7 +166,7 @@ public class SimpleFlatFileInputSource implements ResourceLifecycle, FieldSetInp
/**
* 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;
*/
@@ -187,6 +181,15 @@ public class SimpleFlatFileInputSource implements ResourceLifecycle, FieldSetInp
this.tokenizer = lineTokenizer;
}
+ /**
+ * Set the FieldSetMapper to be used for each line.
+ *
+ * @param fieldSetMapper
+ */
+ public void setFieldSetMapper(FieldSetMapper fieldSetMapper) {
+ this.fieldSetMapper = fieldSetMapper;
+ }
+
// Returns object representing state of the input template.
protected ResourceLineReader getReader() {
if (reader == null) {
diff --git a/infrastructure/src/main/java/org/springframework/batch/item/provider/AbstractFieldSetItemProvider.java b/infrastructure/src/main/java/org/springframework/batch/item/provider/AbstractFieldSetItemProvider.java
deleted file mode 100644
index 2976fd313..000000000
--- a/infrastructure/src/main/java/org/springframework/batch/item/provider/AbstractFieldSetItemProvider.java
+++ /dev/null
@@ -1,74 +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.provider;
-
-import org.springframework.batch.io.file.FieldSet;
-import org.springframework.batch.io.file.FieldSetInputSource;
-import org.springframework.batch.item.ItemProvider;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.util.Assert;
-
-/**
- * {@link ItemProvider} based on {@link FieldSetInputSource}. Not restartable
- * or transaction aware, but can be used by multiple concurrent threads, so
- * useful as a base class or for testing.
- *
- * @author Rob Harrop
- * @author Dave Syer
- */
-public abstract class AbstractFieldSetItemProvider extends AbstractItemProvider implements InitializingBean {
-
- protected FieldSetInputSource source;
-
- private Object mutex = new Object();
-
- /**
- * Make sure mandatory properties are set.
- * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
- */
- public void afterPropertiesSet() throws Exception {
- Assert.notNull(source);
- }
-
- /**
- * Setter for the input source. Mandatory with no default.
- * @param source
- */
- public void setSource(FieldSetInputSource source) {
- this.source = source;
- }
-
- /**
- * Get the next field set from the input source, and then call
- * {@link #transform(FieldSet)} on the result. Synchronizes access to the
- * input source using an internal mutex as a lock.
- *
- * @see org.springframework.batch.item.ItemProvider#next()
- */
- public final Object next() {
- FieldSet fieldSet;
- synchronized (mutex) {
- fieldSet = this.source.readFieldSet();
- if (fieldSet != null) {
- return transform(fieldSet);
- }
- }
- return null;
- }
-
- protected abstract Object transform(FieldSet fieldSet);
-}
diff --git a/infrastructure/src/main/java/org/springframework/batch/item/provider/FlatFileItemProvider.java b/infrastructure/src/main/java/org/springframework/batch/item/provider/FlatFileItemProvider.java
deleted file mode 100644
index 69f48d79f..000000000
--- a/infrastructure/src/main/java/org/springframework/batch/item/provider/FlatFileItemProvider.java
+++ /dev/null
@@ -1,116 +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.provider;
-
-import java.util.Properties;
-
-import org.springframework.batch.io.Skippable;
-import org.springframework.batch.io.file.FieldSet;
-import org.springframework.batch.io.file.FieldSetMapper;
-import org.springframework.batch.item.validator.Validator;
-import org.springframework.batch.restart.RestartData;
-import org.springframework.batch.restart.Restartable;
-import org.springframework.batch.statistics.StatisticsProvider;
-
-/**
- *
- * Uses a {@link FieldSetMapper} to convert each line from an input source. Also
- * adds {@link Restartable} as mandatory behaviour, delegating to the parent
- * provider's input source.
- *
- * @author Dave Syer
- */
-public class FlatFileItemProvider extends AbstractFieldSetItemProvider implements Restartable,
- StatisticsProvider, Skippable {
-
- private FieldSetMapper mapper;
- private Validator validator;
-
- /*
- * (non-Javadoc)
- * @see org.springframework.batch.item.provider.AbstractFieldSetItemProvider#doNext(org.springframework.batch.io.line.FieldSet)
- */
- protected Object transform(FieldSet fieldSet) {
- Object value = mapper.mapLine(fieldSet);
- if (validator!=null) {
- validator.validate(value);
- }
- return value;
- }
-
- /**
- * @param mapper the mapper to set
- */
- public void setMapper(FieldSetMapper mapper) {
- this.mapper = mapper;
- }
-
- /**
- * @param validator the validator to set
- */
- public void setValidator(Validator validator) {
- this.validator = validator;
- }
-
- /**
- * @see Restartable#getRestartData()
- * @throws IllegalStateException if the parent template is not itself
- * {@link Restartable}.
- */
- public RestartData getRestartData() {
- if (!(source instanceof Restartable)) {
- throw new IllegalStateException("Input Template is not Restartable");
- }
- return ((Restartable) source).getRestartData();
- }
-
- /**
- * @see Restartable#restoreFrom(RestartData)
- * @throws IllegalStateException if the parent template is not itself
- * {@link Restartable}.
- */
- public void restoreFrom(RestartData data) {
- if (!(source instanceof Restartable)) {
- throw new IllegalStateException("Input Template is not Restartable");
- }
- ((Restartable) source).restoreFrom(data);
- }
-
- /**
- * @return delegates to the parent template of it is a
- * {@link StatisticsProvider}, otherwise returns an empty
- * {@link Properties} instance.
- * @see StatisticsProvider#getStatistics()
- */
- public Properties getStatistics() {
- if (!(source instanceof StatisticsProvider)) {
- return new Properties();
- }
- return ((StatisticsProvider) source).getStatistics();
- }
-
- /**
- * @return delegates to the input source if it is a
- * {@link Skippable}.
- * @see Skippable#skip()
- */
- public void skip() {
- if (source instanceof Skippable) {
- ((Skippable) source).skip();
- }
- }
-}
diff --git a/infrastructure/src/main/java/org/springframework/batch/item/provider/InputSourceItemProvider.java b/infrastructure/src/main/java/org/springframework/batch/item/provider/InputSourceItemProvider.java
index 9eec73921..502cdc25f 100644
--- a/infrastructure/src/main/java/org/springframework/batch/item/provider/InputSourceItemProvider.java
+++ b/infrastructure/src/main/java/org/springframework/batch/item/provider/InputSourceItemProvider.java
@@ -23,24 +23,29 @@ import org.springframework.batch.io.Skippable;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.restart.Restartable;
import org.springframework.batch.statistics.StatisticsProvider;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.util.Assert;
/**
* Simple wrapper around {@link InputSource}. The input source is expected to
* take care of open and close operations. If necessary it should be registered
* as a step scoped bean to ensure that the lifecycle methods are called.
- *
+ *
* @author Dave Syer
*/
-public class InputSourceItemProvider extends AbstractItemProvider implements Restartable, StatisticsProvider, Skippable {
+public class InputSourceItemProvider extends AbstractItemProvider implements Restartable, StatisticsProvider, Skippable, InitializingBean{
- private InputSource source;
+ private InputSource inputSource;
+ public void afterPropertiesSet() throws Exception {
+ Assert.notNull(inputSource, "InputSource must not be null.");
+ }
/**
* Get the next object from the input source.
* @see org.springframework.batch.item.ItemProvider#next()
*/
public Object next() {
- Object value = source.read();
+ Object value = inputSource.read();
return value;
}
@@ -50,10 +55,10 @@ public class InputSourceItemProvider extends AbstractItemProvider implements Res
* {@link Restartable}.
*/
public RestartData getRestartData() {
- if (!(source instanceof Restartable)) {
+ if (!(inputSource instanceof Restartable)) {
throw new IllegalStateException("Input Template is not Restartable");
}
- return ((Restartable) source).getRestartData();
+ return ((Restartable) inputSource).getRestartData();
}
/**
@@ -62,10 +67,10 @@ public class InputSourceItemProvider extends AbstractItemProvider implements Res
* {@link Restartable}.
*/
public void restoreFrom(RestartData data) {
- if (!(source instanceof Restartable)) {
+ if (!(inputSource instanceof Restartable)) {
throw new IllegalStateException("Input Template is not Restartable");
}
- ((Restartable) source).restoreFrom(data);
+ ((Restartable) inputSource).restoreFrom(data);
}
/**
@@ -75,10 +80,10 @@ public class InputSourceItemProvider extends AbstractItemProvider implements Res
* @see StatisticsProvider#getStatistics()
*/
public Properties getStatistics() {
- if (!(source instanceof StatisticsProvider)) {
+ if (!(inputSource instanceof StatisticsProvider)) {
return new Properties();
}
- return ((StatisticsProvider) source).getStatistics();
+ return ((StatisticsProvider) inputSource).getStatistics();
}
/**
@@ -86,12 +91,16 @@ public class InputSourceItemProvider extends AbstractItemProvider implements Res
* @param source
*/
public void setInputSource(InputSource source) {
- this.source = source;
+ this.inputSource = source;
+ }
+
+ public InputSource getInputSource() {
+ return inputSource;
}
public void skip() {
- if (source instanceof Skippable) {
- ((Skippable)source).skip();
+ if (inputSource instanceof Skippable) {
+ ((Skippable)inputSource).skip();
}
}
}
diff --git a/infrastructure/src/main/java/org/springframework/batch/item/provider/ValidatingItemProvider.java b/infrastructure/src/main/java/org/springframework/batch/item/provider/ValidatingItemProvider.java
new file mode 100644
index 000000000..6acab044a
--- /dev/null
+++ b/infrastructure/src/main/java/org/springframework/batch/item/provider/ValidatingItemProvider.java
@@ -0,0 +1,59 @@
+/*
+ * 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.provider;
+
+import org.springframework.batch.item.validator.Validator;
+import org.springframework.util.Assert;
+
+/**
+ * Simple extension of InputsourceItemProvider that provides for
+ * validation before returning input.
+ *
+ * @author Lucas Ward
+ *
+ */
+public class ValidatingItemProvider extends InputSourceItemProvider {
+
+ private Validator validator;
+
+ /* (non-Javadoc)
+ * @see org.springframework.batch.item.provider.InputSourceItemProvider#afterPropertiesSet()
+ */
+ public void afterPropertiesSet() throws Exception {
+ super.afterPropertiesSet();
+ Assert.notNull(validator, "Validator must not be null.");
+ }
+
+ /* (non-Javadoc)
+ * @see org.springframework.batch.item.provider.InputSourceItemProvider#next()
+ */
+ public Object next() {
+ Object input = super.next();
+ if(input != null){
+ validator.validate(input);
+ }
+ return input;
+ }
+
+ /**
+ * Set the validator used to validate each item.
+ *
+ * @param validator
+ */
+ public void setValidator(Validator validator) {
+ this.validator = validator;
+ }
+}
diff --git a/infrastructure/src/test/java/org/springframework/batch/io/file/support/DefaultFlatFileInputSourceTests.java b/infrastructure/src/test/java/org/springframework/batch/io/file/support/DefaultFlatFileInputSourceTests.java
index abdda38f6..cd8789c7a 100644
--- a/infrastructure/src/test/java/org/springframework/batch/io/file/support/DefaultFlatFileInputSourceTests.java
+++ b/infrastructure/src/test/java/org/springframework/batch/io/file/support/DefaultFlatFileInputSourceTests.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import junit.framework.TestCase;
import org.springframework.batch.io.file.FieldSet;
+import org.springframework.batch.io.file.FieldSetMapper;
import org.springframework.batch.io.file.support.DefaultFlatFileInputSource;
import org.springframework.batch.io.file.support.transform.LineTokenizer;
import org.springframework.batch.restart.RestartData;
@@ -30,16 +31,16 @@ import org.springframework.transaction.support.TransactionSynchronization;
/**
* Tests for {@link DefaultFlatFileInputSource}
- *
+ *
* @author robert.kasanicky
- *
+ *
* TODO only regular reading is tested currently, add exception cases, restart,
* skip, validation...
*/
public class DefaultFlatFileInputSourceTests extends TestCase {
// object under test
- private DefaultFlatFileInputSource template = new DefaultFlatFileInputSource();
+ private DefaultFlatFileInputSource inputSource = new DefaultFlatFileInputSource();
// common value used for writing to a file
private String TEST_STRING = "FlatFileInputTemplate-TestData";
@@ -51,25 +52,31 @@ public class DefaultFlatFileInputSourceTests extends TestCase {
}
};
+ private FieldSetMapper fieldSetMapper = new FieldSetMapper(){
+ public Object mapLine(FieldSet fs) {
+ return fs;
+ }
+ };
+
/**
* Create inputFile, inject mock/stub dependencies for tested object,
* initialize the tested object
*/
protected void setUp() throws Exception {
- template.setResource(getInputResource(TEST_STRING));
- template.setTokenizer(tokenizer);
-
+ inputSource.setResource(getInputResource(TEST_STRING));
+ inputSource.setTokenizer(tokenizer);
+ inputSource.setFieldSetMapper(fieldSetMapper);
// context argument is necessary only for the FileLocator, which
// is mocked
- template.open();
+ inputSource.open();
}
/**
* Release resources and delete the temporary file
*/
protected void tearDown() throws Exception {
- template.close();
+ inputSource.close();
}
private Resource getInputResource(String input) {
@@ -82,25 +89,25 @@ public class DefaultFlatFileInputSourceTests extends TestCase {
*/
public void testSkip() throws IOException {
- template.close();
- template.setResource(getInputResource("testLine1\ntestLine2\ntestLine3\ntestLine4\ntestLine5\ntestLine6"));
- template.open();
+ inputSource.close();
+ inputSource.setResource(getInputResource("testLine1\ntestLine2\ntestLine3\ntestLine4\ntestLine5\ntestLine6"));
+ inputSource.open();
// read some records
- template.readFieldSet(); // #1
- template.readFieldSet(); // #2
+ inputSource.read(); // #1
+ inputSource.read(); // #2
// commit them
- template.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
+ inputSource.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
// read next record
- template.readFieldSet(); // # 3
+ inputSource.read(); // # 3
// mark record as skipped
- template.skip();
+ inputSource.skip();
// read next records
- template.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
+ inputSource.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
// we should now process all records after first commit point, that are
// not marked as skipped
- assertEquals("[testLine4]", template.readFieldSet().toString());
+ assertEquals("[testLine4]", inputSource.read().toString());
// TODO update
// Map statistics = template.getStatistics();
@@ -117,14 +124,14 @@ public class DefaultFlatFileInputSourceTests extends TestCase {
*/
public void testTransactionSynchronizationUnknown() throws IOException {
- template.close();
- template.setResource(getInputResource("testLine1\ntestLine2\ntestLine3\ntestLine4\ntestLine5\ntestLine6"));
- template.open();
+ inputSource.close();
+ inputSource.setResource(getInputResource("testLine1\ntestLine2\ntestLine3\ntestLine4\ntestLine5\ntestLine6"));
+ inputSource.open();
// read some records
- template.readFieldSet();
- template.skip();
- template.readFieldSet();
+ inputSource.read();
+ inputSource.skip();
+ inputSource.read();
// TODO
// statistics = template.getStatistics();
// skipped = (String)
@@ -134,7 +141,7 @@ public class DefaultFlatFileInputSourceTests extends TestCase {
// call unknown, which has no influence and therefore statistics should
// be the same
- template.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_UNKNOWN);
+ inputSource.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_UNKNOWN);
// TODO
// statistics = template.getStatistics();
// assertEquals(skipped, (String)
@@ -142,51 +149,51 @@ public class DefaultFlatFileInputSourceTests extends TestCase {
// assertEquals(read, (String)
// statistics.get(FlatFileInputTemplate.READ_STATISTICS_NAME));
}
-
+
public void testRestartFromNullData() throws Exception {
- template.restoreFrom(null);
- assertEquals("[FlatFileInputTemplate-TestData]", template.readFieldSet().toString());
+ inputSource.restoreFrom(null);
+ assertEquals("[FlatFileInputTemplate-TestData]", inputSource.read().toString());
}
-
+
public void testRestartWithNullReader() throws Exception {
- template = new DefaultFlatFileInputSource();
- template.setResource(getInputResource(TEST_STRING));
+ inputSource = new DefaultFlatFileInputSource();
+ inputSource.setResource(getInputResource(TEST_STRING));
// do not open the template...
- template.restoreFrom(template.getRestartData());
- assertEquals("[FlatFileInputTemplate-TestData]", template.readFieldSet().toString());
+ inputSource.restoreFrom(inputSource.getRestartData());
+ assertEquals("[FlatFileInputTemplate-TestData]", inputSource.read().toString());
}
public void testRestart() throws IOException {
- template.close();
- template.setResource(getInputResource("testLine1\ntestLine2\ntestLine3\ntestLine4\ntestLine5\ntestLine6"));
- template.open();
+ inputSource.close();
+ inputSource.setResource(getInputResource("testLine1\ntestLine2\ntestLine3\ntestLine4\ntestLine5\ntestLine6"));
+ inputSource.open();
// read some records
- template.readFieldSet();
- template.readFieldSet();
+ inputSource.read();
+ inputSource.read();
// commit them
- template.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
+ inputSource.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
// read next two records
- template.readFieldSet();
- template.readFieldSet();
+ inputSource.read();
+ inputSource.read();
// get restart data
- RestartData restartData = template.getRestartData();
+ RestartData restartData = inputSource.getRestartData();
// TODO
// assertEquals("4", (String) restartData);
// close input
- template.close();
+ inputSource.close();
- template.setResource(getInputResource("testLine1\ntestLine2\ntestLine3\ntestLine4\ntestLine5\ntestLine6"));
+ inputSource.setResource(getInputResource("testLine1\ntestLine2\ntestLine3\ntestLine4\ntestLine5\ntestLine6"));
// init for restart
- template.open();
- template.restoreFrom(restartData);
+ inputSource.open();
+ inputSource.restoreFrom(restartData);
// read remaining records
- assertEquals("[testLine5]", template.readFieldSet().toString());
- assertEquals("[testLine6]", template.readFieldSet().toString());
+ assertEquals("[testLine5]", inputSource.read().toString());
+ assertEquals("[testLine6]", inputSource.read().toString());
// TODO
// Map statistics = template.getStatistics();
diff --git a/infrastructure/src/test/java/org/springframework/batch/io/file/support/SimpleFlatFileInputSourceTests.java b/infrastructure/src/test/java/org/springframework/batch/io/file/support/SimpleFlatFileInputSourceTests.java
index 50b770561..191f6a51f 100644
--- a/infrastructure/src/test/java/org/springframework/batch/io/file/support/SimpleFlatFileInputSourceTests.java
+++ b/infrastructure/src/test/java/org/springframework/batch/io/file/support/SimpleFlatFileInputSourceTests.java
@@ -23,8 +23,10 @@ import java.util.List;
import junit.framework.TestCase;
import org.springframework.batch.io.exception.BatchEnvironmentException;
+import org.springframework.batch.io.exception.FlatFileParsingException;
import org.springframework.batch.io.exception.ValidationException;
import org.springframework.batch.io.file.FieldSet;
+import org.springframework.batch.io.file.FieldSetMapper;
import org.springframework.batch.io.file.support.separator.DefaultRecordSeparatorPolicy;
import org.springframework.batch.io.file.support.transform.LineTokenizer;
import org.springframework.core.io.ByteArrayResource;
@@ -33,14 +35,14 @@ import org.springframework.core.io.Resource;
/**
* Tests for {@link SimpleFlatFileInputSourceTests}
- *
+ *
* @author Dave Syer
- *
+ *
*/
public class SimpleFlatFileInputSourceTests extends TestCase {
// object under test
- private SimpleFlatFileInputSource template = new SimpleFlatFileInputSource();
+ private SimpleFlatFileInputSource inputSource = new SimpleFlatFileInputSource();
// common value used for writing to a file
private String TEST_STRING = "FlatFileInputTemplate-TestData";
@@ -52,101 +54,117 @@ public class SimpleFlatFileInputSourceTests extends TestCase {
}
};
+ private FieldSetMapper fieldSetMapper = new FieldSetMapper(){
+ public Object mapLine(FieldSet fs) {
+ return fs;
+ }
+ };
+
/**
* Create inputFile, inject mock/stub dependencies for tested object,
* initialize the tested object
*/
protected void setUp() throws Exception {
- template.setResource(getInputResource(TEST_STRING));
- template.setTokenizer(tokenizer);
- template.afterPropertiesSet();
+ inputSource.setResource(getInputResource(TEST_STRING));
+ inputSource.setTokenizer(tokenizer);
+ inputSource.setFieldSetMapper(fieldSetMapper);
+ inputSource.afterPropertiesSet();
// context argument is necessary only for the FileLocator, which
// is mocked
- template.open();
+ inputSource.open();
}
/**
* Release resources.
*/
protected void tearDown() throws Exception {
- template.close();
+ inputSource.close();
}
private Resource getInputResource(String input) {
return new ByteArrayResource(input.getBytes());
}
- /**
- * Regular usage of read method
- */
- public void testReadFieldSet() throws IOException {
- assertEquals("[FlatFileInputTemplate-TestData]", template.readFieldSet().toString());
- }
-
/**
* Regular usage of read method
*/
public void testRead() throws IOException {
- assertEquals("[FlatFileInputTemplate-TestData]", template.read().toString());
+ assertEquals("[FlatFileInputTemplate-TestData]", inputSource.read().toString());
}
/**
* Regular usage of read method
*/
public void testReadExhausted() throws IOException {
- assertEquals("[FlatFileInputTemplate-TestData]", template.read().toString());
- assertEquals(null, template.read());
+ assertEquals("[FlatFileInputTemplate-TestData]", inputSource.read().toString());
+ assertEquals(null, inputSource.read());
}
/**
* Regular usage of read method
*/
- public void testReadWithError() throws IOException {
- template.setTokenizer(new LineTokenizer() {
+ public void testReadWithTokenizerError() throws IOException {
+ inputSource.setTokenizer(new LineTokenizer() {
public FieldSet tokenize(String line) {
throw new RuntimeException("foo");
}
});
try {
- template.read();
- fail("Expected ValidationException");
- } catch (ValidationException e) {
- assertTrue(e.getMessage().indexOf("at line")>=0);
- assertTrue(e.getMessage().indexOf("at line 1")>=0);
+ inputSource.read();
+ fail("Expected ParsingException");
+ } catch (FlatFileParsingException e) {
+ assertEquals(e.getInput(), TEST_STRING);
+ assertEquals(e.getLineNumber(), 1);
+ }
+ }
+
+ public void testReadWithMapperError() throws IOException {
+ inputSource.setFieldSetMapper(new FieldSetMapper(){
+ public Object mapLine(FieldSet fs) {
+ throw new RuntimeException("foo");
+ }
+ });
+
+ try {
+ inputSource.read();
+ fail("Expected ParsingException");
+ } catch (FlatFileParsingException e) {
+ assertEquals(e.getInput(), TEST_STRING);
+ assertEquals(e.getLineNumber(), 1);
}
}
public void testReadBeforeOpen() throws Exception {
- template = new SimpleFlatFileInputSource();
- template.setResource(getInputResource(TEST_STRING));
- assertEquals("[FlatFileInputTemplate-TestData]", template.readFieldSet().toString());
+ inputSource = new SimpleFlatFileInputSource();
+ inputSource.setResource(getInputResource(TEST_STRING));
+ assertEquals("[FlatFileInputTemplate-TestData]", inputSource.read().toString());
}
public void testCloseBeforeOpen() throws Exception {
- template = new SimpleFlatFileInputSource();
- template.setResource(getInputResource(TEST_STRING));
- template.close();
+ inputSource = new SimpleFlatFileInputSource();
+ inputSource.setResource(getInputResource(TEST_STRING));
+ inputSource.close();
// The open still happens automatically on a read...
- assertEquals("[FlatFileInputTemplate-TestData]", template.readFieldSet().toString());
+ assertEquals("[FlatFileInputTemplate-TestData]", inputSource.read().toString());
}
public void testCloseOnDestroy() throws Exception {
final List list = new ArrayList();
- template = new SimpleFlatFileInputSource() {
+ inputSource = new SimpleFlatFileInputSource() {
public void close() {
list.add("close");
}
};
- template.destroy();
+ inputSource.destroy();
assertEquals(1, list.size());
}
public void testInitializationWithNullResource() throws Exception {
- template = new SimpleFlatFileInputSource();
+ inputSource = new SimpleFlatFileInputSource();
try {
- template.afterPropertiesSet();
+ inputSource.afterPropertiesSet();
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException e) {
@@ -155,23 +173,23 @@ public class SimpleFlatFileInputSourceTests extends TestCase {
}
public void testOpenTwiceHasNoEffect() throws Exception {
- template.open();
+ inputSource.open();
testRead();
}
public void testSetValidEncoding() throws Exception {
- template = new SimpleFlatFileInputSource();
- template.setEncoding("UTF-8");
- template.setResource(getInputResource(TEST_STRING));
+ inputSource = new SimpleFlatFileInputSource();
+ inputSource.setEncoding("UTF-8");
+ inputSource.setResource(getInputResource(TEST_STRING));
testRead();
}
public void testSetNullEncoding() throws Exception {
- template = new SimpleFlatFileInputSource();
- template.setEncoding(null);
- template.setResource(getInputResource(TEST_STRING));
+ inputSource = new SimpleFlatFileInputSource();
+ inputSource.setEncoding(null);
+ inputSource.setResource(getInputResource(TEST_STRING));
try {
- template.open();
+ inputSource.open();
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException e) {
@@ -180,11 +198,11 @@ public class SimpleFlatFileInputSourceTests extends TestCase {
}
public void testSetInvalidEncoding() throws Exception {
- template = new SimpleFlatFileInputSource();
- template.setEncoding("foo");
- template.setResource(getInputResource(TEST_STRING));
+ inputSource = new SimpleFlatFileInputSource();
+ inputSource.setEncoding("foo");
+ inputSource.setResource(getInputResource(TEST_STRING));
try {
- template.open();
+ inputSource.open();
fail("Expected BatchEnvironmentException");
}
catch (BatchEnvironmentException e) {
@@ -194,12 +212,12 @@ public class SimpleFlatFileInputSourceTests extends TestCase {
}
public void testEncoding() throws Exception {
- template.setEncoding("UTF-8");
+ inputSource.setEncoding("UTF-8");
testRead();
}
public void testRecordSeparator() throws Exception {
- template.setRecordSeparatorPolicy(new DefaultRecordSeparatorPolicy());
+ inputSource.setRecordSeparatorPolicy(new DefaultRecordSeparatorPolicy());
testRead();
}
diff --git a/infrastructure/src/test/java/org/springframework/batch/item/provider/AbstractFieldSetItemProviderTests.java b/infrastructure/src/test/java/org/springframework/batch/item/provider/AbstractFieldSetItemProviderTests.java
deleted file mode 100644
index 0f313ed08..000000000
--- a/infrastructure/src/test/java/org/springframework/batch/item/provider/AbstractFieldSetItemProviderTests.java
+++ /dev/null
@@ -1,59 +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.provider;
-
-import junit.framework.TestCase;
-
-import org.springframework.batch.io.file.FieldSet;
-import org.springframework.batch.io.file.FieldSetInputSource;
-import org.springframework.batch.io.file.support.SimpleFlatFileInputSource;
-import org.springframework.core.io.ByteArrayResource;
-
-/**
- * @author Dave Syer
- *
- */
-public class AbstractFieldSetItemProviderTests extends TestCase {
-
- public void testNotOpen() throws Exception {
- TestItemProvider provider = new TestItemProvider();
- provider.setSource(getInputSource("one\ntwo\nthree"));
- assertNotNull(provider.next());
- }
-
- public void testAfterPropertiesSet() throws Exception {
- TestItemProvider provider = new TestItemProvider();
- try {
- provider.afterPropertiesSet();
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- private static class TestItemProvider extends AbstractFieldSetItemProvider {
- protected Object transform(FieldSet fieldSet) {
- return fieldSet.toString();
- }
- }
-
- private FieldSetInputSource getInputSource(String data) throws Exception {
- SimpleFlatFileInputSource template = new SimpleFlatFileInputSource();
- template.setResource(new ByteArrayResource(data.getBytes()));
- template.afterPropertiesSet();
- return template;
- }
-}
diff --git a/infrastructure/src/test/java/org/springframework/batch/item/provider/FieldSetItemProviderTests.java b/infrastructure/src/test/java/org/springframework/batch/item/provider/FieldSetItemProviderTests.java
deleted file mode 100644
index 6c5cf7bdc..000000000
--- a/infrastructure/src/test/java/org/springframework/batch/item/provider/FieldSetItemProviderTests.java
+++ /dev/null
@@ -1,54 +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.provider;
-
-import junit.framework.TestCase;
-
-import org.springframework.batch.io.file.FieldSet;
-import org.springframework.batch.io.file.support.SimpleFlatFileInputSource;
-import org.springframework.core.io.ByteArrayResource;
-
-public class FieldSetItemProviderTests extends TestCase {
-
- public void testNotOpen() throws Exception {
- TestItemProvider provider = new TestItemProvider("one\ntwo\nthree");
- assertNotNull(provider.next());
- }
-
- public void testNext() throws Exception {
- TestItemProvider provider = new TestItemProvider("one\ntwo\nthree");
- assertEquals("[one]", provider.next());
- assertEquals("[two]", provider.next());
- assertEquals("[three]", provider.next());
- assertEquals(null, provider.next());
- }
-
- private static class TestItemProvider extends AbstractFieldSetItemProvider {
- public TestItemProvider(String data) throws Exception {
- super();
- SimpleFlatFileInputSource template = new SimpleFlatFileInputSource();
- template.setResource(new ByteArrayResource(data.getBytes()));
- template.afterPropertiesSet();
- setSource(template);
- }
-
- protected Object transform(FieldSet fieldSet) {
- return fieldSet.toString();
- }
- }
-
-}
diff --git a/infrastructure/src/test/java/org/springframework/batch/item/provider/FlatFileItemProviderTests.java b/infrastructure/src/test/java/org/springframework/batch/item/provider/FlatFileItemProviderTests.java
deleted file mode 100644
index f872491f5..000000000
--- a/infrastructure/src/test/java/org/springframework/batch/item/provider/FlatFileItemProviderTests.java
+++ /dev/null
@@ -1,217 +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.provider;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-
-import junit.framework.TestCase;
-
-import org.springframework.batch.io.Skippable;
-import org.springframework.batch.io.exception.ValidationException;
-import org.springframework.batch.io.file.FieldSet;
-import org.springframework.batch.io.file.FieldSetInputSource;
-import org.springframework.batch.io.file.FieldSetMapper;
-import org.springframework.batch.io.file.support.DefaultFlatFileInputSource;
-import org.springframework.batch.item.provider.FlatFileItemProvider;
-import org.springframework.batch.item.validator.Validator;
-import org.springframework.batch.restart.GenericRestartData;
-import org.springframework.batch.restart.RestartData;
-import org.springframework.batch.restart.Restartable;
-import org.springframework.batch.statistics.StatisticsProvider;
-import org.springframework.batch.support.PropertiesConverter;
-import org.springframework.core.io.ByteArrayResource;
-
-/**
- * Unit tests for {@link FlatFileItemProvider}
- *
- * @author Robert Kasanicky
- * @author Dave Syer
- */
-public class FlatFileItemProviderTests extends TestCase {
-
- public static String FOO = "foo";
- // object under test
- private FlatFileItemProvider itemProvider = new FlatFileItemProvider();
-
- // Input source
- private DefaultFlatFileInputSource source;
-
- // mock mapper
- private FieldSetMapper mapper;
-
- private List list = new ArrayList();
-
- // create mock objects and inject them into data provider
- protected void setUp() throws Exception {
- source = new DefaultFlatFileInputSource() {
- public void skip() {
- super.skip();
- list.add("skipped");
- }
- };
- source.setResource(new ByteArrayResource("a,b".getBytes()));
- mapper = new FieldSetMapper() {
- public Object mapLine(FieldSet fs) {
- return FOO;
- }
- };
- itemProvider.setSource(source);
- itemProvider.setMapper(mapper);
- assertTrue(Restartable.class
- .isAssignableFrom(DefaultFlatFileInputSource.class));
- assertTrue(Skippable.class
- .isAssignableFrom(DefaultFlatFileInputSource.class));
- assertTrue(FieldSetInputSource.class
- .isAssignableFrom(DefaultFlatFileInputSource.class));
- assertTrue(StatisticsProvider.class
- .isAssignableFrom(DefaultFlatFileInputSource.class));
- }
-
- /**
- * Uses input template to provide the domain object.
- */
- public void testNext() {
- Object result = itemProvider.next();
- assertSame("domain object is provided by the input template", FOO,
- result);
- }
-
- /**
- * Uses input template to provide the domain object.
- */
- public void testNextWithValidator() {
- itemProvider.setValidator(new Validator() {
- public void validate(Object value) throws ValidationException {
- list.add(value);
- }
- });
- itemProvider.next();
- assertSame("domain object is provided by the input template", FOO, list
- .get(0));
- }
-
- /**
- * Uses input template to provide the domain object.
- */
- public void testNextWithValidatorAndInvalidData() {
- itemProvider.setValidator(new Validator() {
- public void validate(Object value) throws ValidationException {
- throw new ValidationException("Invalid input");
- }
- });
- try {
- itemProvider.next();
- fail("Expected ValidationException");
- } catch (ValidationException e) {
- // expected
- assertEquals("Invalid input", e.getMessage());
- }
- }
-
- /**
- * Gets statistics from the input template
- */
- public void testGetStatistics() {
- Properties statistics = ((StatisticsProvider) source).getStatistics();
- assertEquals(statistics, itemProvider.getStatistics());
- }
-
- /**
- * Gets statistics from the input template
- */
- public void testGetStatisticsWithoutStatisticsProvider() {
- itemProvider.setSource(null);
- Properties props = itemProvider.getStatistics();
- assertEquals(null, props.getProperty("a"));
- }
-
- /**
- * Gets restart data from the input template
- */
- public void testGetRestartData() {
- RestartData data = ((Restartable) source).getRestartData();
- assertEquals(data.getProperties(), itemProvider.getRestartData()
- .getProperties());
- }
-
- /**
- * Forwarded restart data to input template
- */
- public void testRestoreFrom() {
-
- final List list = new ArrayList();
-
- RestartData data = new RestartData() {
-
- public Properties getProperties() {
- list.add(FOO);
- return ((Restartable) source).getRestartData().getProperties();
- }
- };
-
- itemProvider.restoreFrom(data);
-
- // assertEquals(1, list.size()); getProperties are called multiple times
- // due to null checks
- assertTrue(list.size() > 0);
- }
-
- /**
- * Forward restart data to input template
- *
- * @throws Exception
- */
- public void testRestoreFromWithoutRestartable() throws Exception {
- itemProvider.setSource(null);
- try {
- itemProvider.restoreFrom(new GenericRestartData(PropertiesConverter
- .stringToProperties("value=bar")));
- fail("Expected IllegalStateException");
- } catch (IllegalStateException e) {
- // expected
- }
- }
-
- /**
- * Forward restart data to input template
- *
- * @throws Exception
- */
- public void testGetRestartDataWithoutRestartable() throws Exception {
- itemProvider.setSource(null);
- try {
- itemProvider.getRestartData();
- fail("Expected IllegalStateException");
- } catch (IllegalStateException e) {
- // expected
- }
- }
-
- /**
- * Forward restart data to input template
- *
- * @throws Exception
- */
- public void testSkippable() throws Exception {
- assertEquals(0, list.size());
- itemProvider.skip();
- assertEquals(1, list.size());
- }
-
-}
diff --git a/infrastructure/src/test/java/org/springframework/batch/item/provider/InputSourceItemProviderTests.java b/infrastructure/src/test/java/org/springframework/batch/item/provider/InputSourceItemProviderTests.java
index 1157fece8..099819f58 100644
--- a/infrastructure/src/test/java/org/springframework/batch/item/provider/InputSourceItemProviderTests.java
+++ b/infrastructure/src/test/java/org/springframework/batch/item/provider/InputSourceItemProviderTests.java
@@ -31,7 +31,7 @@ import org.springframework.batch.support.PropertiesConverter;
/**
* Unit test for {@link InputSourceItemProvider}
- *
+ *
* @author Robert Kasanicky
*/
public class InputSourceItemProviderTests extends TestCase {
@@ -47,6 +47,21 @@ public class InputSourceItemProviderTests extends TestCase {
itemProvider.setInputSource(source);
}
+ public void testAfterPropertiesSet()throws Exception{
+ //shouldn't throw an exception since the input source is set
+ itemProvider.afterPropertiesSet();
+ }
+
+ public void testNullInputSource(){
+ try{
+ itemProvider.setInputSource(null);
+ itemProvider.afterPropertiesSet();
+ fail();
+ }catch(Exception ex){
+ assertTrue(ex instanceof IllegalArgumentException);
+ }
+ }
+
/**
* Uses input template to provide the domain object.
*/
@@ -78,7 +93,7 @@ public class InputSourceItemProviderTests extends TestCase {
itemProvider.restoreFrom(new GenericRestartData(PropertiesConverter.stringToProperties("value=bar")));
assertEquals("bar", itemProvider.next());
}
-
+
public void testSkip() {
itemProvider.skip();
assertEquals("after skip", itemProvider.next());
@@ -87,7 +102,7 @@ public class InputSourceItemProviderTests extends TestCase {
private class MockInputSource implements InputSource, StatisticsProvider, Restartable, Skippable {
private Object value;
-
+
public Properties getStatistics() {
return PropertiesConverter.stringToProperties("a=b");
}
diff --git a/infrastructure/src/test/java/org/springframework/batch/item/provider/ValidatingItemProviderTests.java b/infrastructure/src/test/java/org/springframework/batch/item/provider/ValidatingItemProviderTests.java
new file mode 100644
index 000000000..13ebc0769
--- /dev/null
+++ b/infrastructure/src/test/java/org/springframework/batch/item/provider/ValidatingItemProviderTests.java
@@ -0,0 +1,114 @@
+/*
+ * 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.provider;
+
+import org.easymock.MockControl;
+import org.springframework.batch.io.InputSource;
+import org.springframework.batch.io.exception.ValidationException;
+import org.springframework.batch.item.validator.Validator;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Lucas Ward
+ *
+ */
+public class ValidatingItemProviderTests extends TestCase {
+
+ InputSource inputSource;
+ ValidatingItemProvider itemProvider;
+ Validator validator;
+ MockControl validatorControl = MockControl.createControl(Validator.class);
+
+ /* (non-Javadoc)
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ inputSource = new MockInputSource(this);
+ validator = (Validator)validatorControl.getMock();
+ itemProvider = new ValidatingItemProvider();
+ itemProvider.setInputSource(inputSource);
+ itemProvider.setValidator(validator);
+ }
+
+ /*
+ * Super class' afterPropertieSet should be called to
+ * ensure InputSource is set.
+ */
+ public void testInputSourcePropertiesSet(){
+ try{
+ itemProvider.setInputSource(null);
+ itemProvider.afterPropertiesSet();
+ fail();
+ }catch(Exception ex){
+ assertTrue(ex instanceof IllegalArgumentException);
+ }
+ }
+
+ public void testValidatorPropertesSet(){
+ try{
+ itemProvider.setValidator(null);
+ itemProvider.afterPropertiesSet();
+ fail();
+ }catch(Exception ex){
+ assertTrue(ex instanceof IllegalArgumentException);
+ }
+ }
+
+ public void testValidation(){
+
+ validator.validate(this);
+ validatorControl.replay();
+ assertEquals(itemProvider.next(), this);
+ validatorControl.verify();
+ }
+
+ public void testValidationException(){
+
+ validator.validate(this);
+ validatorControl.setThrowable(new ValidationException(""));
+ validatorControl.replay();
+ try{
+ itemProvider.next();
+ fail();
+ }catch(ValidationException ex){
+ //expected
+ }
+ }
+
+ public void testNullInput(){
+ validatorControl.replay();
+ itemProvider.setInputSource(new MockInputSource(null));
+ assertNull(itemProvider.next());
+ //assert validator wasn't called.
+ validatorControl.verify();
+ }
+
+ private class MockInputSource implements InputSource{
+
+ Object value;
+
+ public MockInputSource(Object value){
+ this.value = value;
+ }
+
+ public Object read() {
+ return value;
+ }
+ }
+}
diff --git a/infrastructure/src/test/java/org/springframework/batch/repeat/support/AbstractTradeBatchTests.java b/infrastructure/src/test/java/org/springframework/batch/repeat/support/AbstractTradeBatchTests.java
index 8f265abb8..9d56e0fcb 100644
--- a/infrastructure/src/test/java/org/springframework/batch/repeat/support/AbstractTradeBatchTests.java
+++ b/infrastructure/src/test/java/org/springframework/batch/repeat/support/AbstractTradeBatchTests.java
@@ -19,17 +19,18 @@ package org.springframework.batch.repeat.support;
import junit.framework.TestCase;
import org.springframework.batch.io.file.FieldSet;
+import org.springframework.batch.io.file.FieldSetMapper;
import org.springframework.batch.io.file.support.SimpleFlatFileInputSource;
import org.springframework.batch.item.ItemProcessor;
-import org.springframework.batch.item.provider.AbstractFieldSetItemProvider;
+import org.springframework.batch.item.provider.InputSourceItemProvider;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
/**
* Base class for simple tests with small trade data set.
- *
+ *
* @author Dave Syer
- *
+ *
*/
public abstract class AbstractTradeBatchTests extends TestCase {
@@ -46,18 +47,21 @@ public abstract class AbstractTradeBatchTests extends TestCase {
provider = new TradeItemProvider(resource);
}
- protected static class TradeItemProvider extends AbstractFieldSetItemProvider {
+ protected static class TradeItemProvider extends InputSourceItemProvider {
protected TradeItemProvider(Resource resource) throws Exception {
super();
- SimpleFlatFileInputSource template = new SimpleFlatFileInputSource();
- template.setResource(resource);
- template.afterPropertiesSet();
- setSource(template);
+ SimpleFlatFileInputSource inputSource = new SimpleFlatFileInputSource();
+ inputSource.setResource(resource);
+ inputSource.setFieldSetMapper(new TradeMapper());
+ inputSource.afterPropertiesSet();
+ setInputSource(inputSource);
}
+ }
- protected Object transform(FieldSet fieldSet) {
- return new Trade(fieldSet);
+ protected static class TradeMapper implements FieldSetMapper{
+ public Object mapLine(FieldSet fs) {
+ return new Trade(fs);
}
}