diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/validator/ValidatingItemProcessor.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/validator/ValidatingItemProcessor.java index 66d2d4376..e43e85416 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/validator/ValidatingItemProcessor.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/validator/ValidatingItemProcessor.java @@ -30,6 +30,8 @@ public class ValidatingItemProcessor implements ItemProcessor { private Validator validator; + private boolean filter = false; + public ValidatingItemProcessor(Validator validator){ Assert.notNull(validator, "Validator must not be null."); this.validator = validator; @@ -44,6 +46,15 @@ public class ValidatingItemProcessor implements ItemProcessor { this.validator = validator; } + /** + * Should the processor filter invalid records instead of skipping them? + * + * @param filter + */ + public void setFilter(boolean filter) { + this.filter = filter; + } + /** * Validate the item and return it unmodified * @@ -51,7 +62,16 @@ public class ValidatingItemProcessor implements ItemProcessor { * @throws ValidationException if validation fails */ public T process(T item) throws ValidationException { - validator.validate(item); + try { + validator.validate(item); + } catch (ValidationException e) { + if (filter) { + return null; // filter the item + } + else { + throw e; // skip the item + } + } return item; } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemProcessorTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemProcessorTests.java index de5f549b6..416e94003 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemProcessorTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/validator/ValidatingItemProcessorTests.java @@ -4,6 +4,7 @@ import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import org.junit.Test; @@ -15,30 +16,45 @@ public class ValidatingItemProcessorTests { @SuppressWarnings("unchecked") private Validator validator = createMock(Validator.class); - - private ValidatingItemProcessor tested = new ValidatingItemProcessor(validator); - - private String item = "item"; - + + private static final String ITEM = "item"; + @Test public void testSuccessfulValidation() throws Exception { - - validator.validate(item); + + ValidatingItemProcessor tested = new ValidatingItemProcessor(validator); + + validator.validate(ITEM); expectLastCall(); replay(validator); - - assertSame(item, tested.process(item)); - + + assertSame(ITEM, tested.process(ITEM)); + verify(validator); } - - @Test(expected=ValidationException.class) + + @Test(expected = ValidationException.class) public void testFailedValidation() throws Exception { - - validator.validate(item); + + ValidatingItemProcessor tested = new ValidatingItemProcessor(validator); + + processFailedValidation(tested); + } + + @Test + public void testFailedValidation_Filter() throws Exception { + + ValidatingItemProcessor tested = new ValidatingItemProcessor(validator); + tested.setFilter(true); + + assertNull(processFailedValidation(tested)); + } + + private String processFailedValidation(ValidatingItemProcessor tested) { + validator.validate(ITEM); expectLastCall().andThrow(new ValidationException("invalid item")); replay(validator); - - tested.process(item); + + return tested.process(ITEM); } }