RESOLVED - issue BATCH-1417: Error in FlatFileItemReader when RecordSeparatorPolicy.preProcess or readLine returns null
http://jira.springframework.org/browse/BATCH-1417
This commit is contained in:
@@ -31,6 +31,7 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Restartable {@link ItemReader} that reads lines from input
|
||||
@@ -178,14 +179,21 @@ public class FlatFileItemReader<T> extends AbstractItemCountingItemStreamItemRea
|
||||
}
|
||||
String line = readLine();
|
||||
String record = line;
|
||||
if (line != null) {
|
||||
while (line != null && !recordSeparatorPolicy.isEndOfRecord(record)) {
|
||||
line = readLine();
|
||||
if (line==null) {
|
||||
while (line != null && !recordSeparatorPolicy.isEndOfRecord(record)) {
|
||||
line = readLine();
|
||||
if (line == null) {
|
||||
if (StringUtils.hasText(record)) {
|
||||
// A record was partially complete since it hasn't ended but
|
||||
// the line is null
|
||||
throw new FlatFileParseException("Unexpected end of file before record complete", record, lineCount);
|
||||
}
|
||||
record = recordSeparatorPolicy.preProcess(record) + line;
|
||||
else {
|
||||
// Record has no text but it might still be post processed
|
||||
// to something (skipping preProcess since that was already done)
|
||||
break;
|
||||
}
|
||||
}
|
||||
record = recordSeparatorPolicy.preProcess(record) + line;
|
||||
}
|
||||
String logicalLine = recordSeparatorPolicy.postProcess(record);
|
||||
if (logicalLine == null) {
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.springframework.core.io.AbstractResource;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Tests for {@link FlatFileItemReader}.
|
||||
@@ -98,11 +99,12 @@ public class FlatFileItemReaderTests {
|
||||
reader.open(executionContext);
|
||||
|
||||
assertEquals("testLine1testLine2", reader.read());
|
||||
|
||||
|
||||
try {
|
||||
reader.read();
|
||||
fail("Expected Exception");
|
||||
} catch (FlatFileParseException e) {
|
||||
}
|
||||
catch (FlatFileParseException e) {
|
||||
// File ends in the middle of a record
|
||||
assertEquals(3, e.getLineNumber());
|
||||
assertEquals("testLine3", e.getInput());
|
||||
@@ -110,6 +112,66 @@ public class FlatFileItemReaderTests {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomRecordSeparatorBlankLine() throws Exception {
|
||||
|
||||
reader.setRecordSeparatorPolicy(new RecordSeparatorPolicy() {
|
||||
|
||||
public boolean isEndOfRecord(String line) {
|
||||
return StringUtils.hasText(line);
|
||||
}
|
||||
|
||||
public String postProcess(String record) {
|
||||
return StringUtils.hasText(record) ? record : null;
|
||||
}
|
||||
|
||||
public String preProcess(String record) {
|
||||
return record;
|
||||
}
|
||||
});
|
||||
|
||||
reader.setResource(getInputResource("testLine1\ntestLine2\ntestLine3\n\n"));
|
||||
reader.open(executionContext);
|
||||
|
||||
assertEquals("testLine1", reader.read());
|
||||
assertEquals("testLine2", reader.read());
|
||||
assertEquals("testLine3", reader.read());
|
||||
assertEquals(null, reader.read());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomRecordSeparatorMultilineBlankLineAfterEnd() throws Exception {
|
||||
|
||||
reader.setRecordSeparatorPolicy(new RecordSeparatorPolicy() {
|
||||
|
||||
// 1 record = 2 lines
|
||||
boolean pair = true;
|
||||
|
||||
public boolean isEndOfRecord(String line) {
|
||||
if (StringUtils.hasText(line)) {
|
||||
pair = !pair;
|
||||
}
|
||||
return pair;
|
||||
}
|
||||
|
||||
public String postProcess(String record) {
|
||||
return StringUtils.hasText(record) ? record : null;
|
||||
}
|
||||
|
||||
public String preProcess(String record) {
|
||||
return record;
|
||||
}
|
||||
});
|
||||
|
||||
reader.setResource(getInputResource("testLine1\ntestLine2\n\n"));
|
||||
reader.open(executionContext);
|
||||
|
||||
assertEquals("testLine1testLine2", reader.read());
|
||||
assertEquals(null, reader.read());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestartWithSkippedLines() throws Exception {
|
||||
|
||||
@@ -184,7 +246,7 @@ public class FlatFileItemReaderTests {
|
||||
public void testMaxItemCountFromContext() throws Exception {
|
||||
|
||||
reader.setMaxItemCount(2);
|
||||
executionContext.putInt(reader.getClass().getSimpleName()+".read.count.max", Integer.MAX_VALUE);
|
||||
executionContext.putInt(reader.getClass().getSimpleName() + ".read.count.max", Integer.MAX_VALUE);
|
||||
reader.open(executionContext);
|
||||
// read some records
|
||||
reader.read();
|
||||
@@ -199,7 +261,7 @@ public class FlatFileItemReaderTests {
|
||||
public void testCurrentItemCountFromContext() throws Exception {
|
||||
|
||||
reader.setCurrentItemCount(2);
|
||||
executionContext.putInt(reader.getClass().getSimpleName()+".read.count", 3);
|
||||
executionContext.putInt(reader.getClass().getSimpleName() + ".read.count", 3);
|
||||
reader.open(executionContext);
|
||||
// read some records
|
||||
assertEquals("testLine4", reader.read());
|
||||
|
||||
Reference in New Issue
Block a user