diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/ResourceLineReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/ResourceLineReader.java index 40d471471..e48d8b63d 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/ResourceLineReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/ResourceLineReader.java @@ -59,7 +59,8 @@ public class ResourceLineReader extends AbstractItemCountingItemStreamItemRea } /** - * skippedLinesCallback will be passed the header line before any items are read. + * @param skippedLinesCallback will be called for each one of the initial skipped + * lines before any items are read. */ public void setSkippedLinesCallback(LineCallbackHandler skippedLinesCallback) { this.skippedLinesCallback = skippedLinesCallback; @@ -214,7 +215,9 @@ public class ResourceLineReader extends AbstractItemCountingItemStreamItemRea reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), encoding)); for (int i = 0; i < linesToSkip; i++) { String line = readLine(); - skippedLinesCallback.handleLine(line); + if (skippedLinesCallback != null) { + skippedLinesCallback.handleLine(line); + } } } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/ResourceLineReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/ResourceLineReaderTests.java new file mode 100644 index 000000000..f076bd215 --- /dev/null +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/ResourceLineReaderTests.java @@ -0,0 +1,101 @@ +package org.springframework.batch.item.file; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.batch.item.ExecutionContext; +import org.springframework.batch.item.file.mapping.PassThroughLineMapper; +import org.springframework.batch.item.file.separator.RecordSeparatorPolicy; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.core.io.Resource; +import org.springframework.util.ClassUtils; + +/** + * Tests for {@link ResourceLineReader}. + */ +public class ResourceLineReaderTests { + + private ResourceLineReader reader = new ResourceLineReader(); + + private ExecutionContext executionContext = new ExecutionContext(); + + @Before + public void setUp() { + + reader.setResource(getInputResource("testLine1\ntestLine2\ntestLine3\ntestLine4\ntestLine5\ntestLine6")); + reader.setLineMapper(new PassThroughLineMapper()); + } + + @Test + public void testRestartWithCustomRecordSeparatorPolicy() throws Exception { + + reader.setRecordSeparatorPolicy(new RecordSeparatorPolicy() { + // 1 record = 2 lines + boolean pair = true; + + public boolean isEndOfRecord(String line) { + pair = !pair; + return pair; + } + + public String postProcess(String record) { + return record; + } + + public String preProcess(String record) { + return record; + } + }); + + reader.open(executionContext); + + assertEquals("testLine1testLine2", reader.read().toString()); + assertEquals("testLine3testLine4", reader.read().toString()); + + reader.update(executionContext); + + reader.close(executionContext); + + reader.open(executionContext); + + assertEquals("testLine5testLine6", reader.read().toString()); + } + + @Test + public void testRestartWithSkippedLines() throws Exception { + + reader.setLinesToSkip(2); + reader.open(executionContext); + + // read some records + reader.read(); + reader.read(); + // get restart data + reader.update(executionContext); + // read next two records + reader.read(); + reader.read(); + + assertEquals(2, executionContext.getLong(ClassUtils.getShortName(FlatFileItemReader.class) + ".read.count")); + // close input + reader.close(executionContext); + + reader + .setResource(getInputResource("header\nignoreme\ntestLine1\ntestLine2\ntestLine3\ntestLine4\ntestLine5\ntestLine6")); + + // init for restart + reader.open(executionContext); + + // read remaining records + assertEquals("testLine3", reader.read().toString()); + assertEquals("testLine4", reader.read().toString()); + + reader.update(executionContext); + assertEquals(4, executionContext.getLong(ClassUtils.getShortName(FlatFileItemReader.class) + ".read.count")); + } + + private Resource getInputResource(String input) { + return new ByteArrayResource(input.getBytes()); + } +}