RESOLVED - issue BATCH-293: ResourceLineReader eats newlines within a record's field

http://jira.springframework.org/browse/BATCH-293

Fixed using Java 2 features (not using the patch as such) - (implicit) StringBuffer instead of StringBuilder.
This commit is contained in:
dsyer
2008-01-16 14:19:07 +00:00
parent 1ca8796ab6
commit 5627d28945
3 changed files with 56 additions and 44 deletions

View File

@@ -40,7 +40,8 @@ public interface RecordSeparatorPolicy {
boolean isEndOfRecord(String line);
/**
* Give the policy a chance to postprocess a record, e.g. remove a suffix.
* Give the policy a chance to post-process a complete record, e.g. remove a
* suffix.
*
* @param record the complete record.
* @return a modified version of the record if desired.
@@ -48,12 +49,14 @@ public interface RecordSeparatorPolicy {
String postProcess(String record);
/**
* Preprocess a line before it is appended to a record. Can be used to
* remove a prefix or line-continuation marker.
* Pre-process a record before another line is appended, in the case of a
* multi-line record. Can be used to remove a prefix or line-continuation
* marker. If a record is a single line this callback is not used (but
* {@link #postProcess(String)} will be).
*
* @param line the current line.
* @param record the current record.
* @return the line as it should be appended to a record.
*/
String preProcess(String line);
String preProcess(String record);
}

View File

@@ -59,8 +59,7 @@ import org.springframework.util.Assert;
public class ResourceLineReader extends AbstractItemReader implements LineReader, ResourceLifecycle, ItemReader,
DisposableBean {
private static final Collection DEFAULT_COMMENTS = Collections
.singleton("#");
private static final Collection DEFAULT_COMMENTS = Collections.singleton("#");
private static final String DEFAULT_ENCODING = "ISO-8859-1";
@@ -93,11 +92,9 @@ public class ResourceLineReader extends AbstractItemReader implements LineReader
* {@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}
* @param recordSeparatorPolicy the new {@link RecordSeparatorPolicy}
*/
public void setRecordSeparatorPolicy(
RecordSeparatorPolicy 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
@@ -110,8 +107,7 @@ public class ResourceLineReader extends AbstractItemReader implements LineReader
* 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.
* @param comments an array of comment line prefixes.
*/
public void setComments(String[] comments) {
this.comments = new HashSet(Arrays.asList(comments));
@@ -123,9 +119,8 @@ public class ResourceLineReader extends AbstractItemReader implements LineReader
*
* @return a String.
*
* @throws BatchEnvironmentException
* if there is an IOException while accessing the input
* resource.
* @throws BatchEnvironmentException if there is an IOException while
* accessing the input resource.
*
* @see org.springframework.batch.item.reader.support.ItemReader#read()
*/
@@ -136,11 +131,9 @@ public class ResourceLineReader extends AbstractItemReader implements LineReader
String line = readLine();
String record = line;
if (line != null) {
StringBuffer buffer = new StringBuffer(record);
while (line != null && !recordSeparatorPolicy.isEndOfRecord(record)) {
buffer.append(recordSeparatorPolicy
.preProcess(line = readLine()));
record = buffer.toString();
record = recordSeparatorPolicy.preProcess(record) + (line = readLine());
// record = new StringBuilder(recordSeparatorPolicy.preProcess(record)).append(line = readLine()).toString();
}
}
return recordSeparatorPolicy.postProcess(record);
@@ -179,9 +172,8 @@ public class ResourceLineReader extends AbstractItemReader implements LineReader
* Close the reader associated with this input source.
*
* @see org.springframework.batch.io.ItemReader#close()
* @throws BatchEnvironmentException
* if there is an {@link IOException} during the close
* operation.
* @throws BatchEnvironmentException if there is an {@link IOException}
* during the close operation.
*/
public synchronized void close() {
if (state == null) {
@@ -189,7 +181,8 @@ public class ResourceLineReader extends AbstractItemReader implements LineReader
}
try {
state.close();
} finally {
}
finally {
state = null;
}
}
@@ -219,8 +212,7 @@ public class ResourceLineReader extends AbstractItemReader implements LineReader
*
* @see #reset()
*
* @throws BatchEnvironmentException
* if the mark could not be set.
* @throws BatchEnvironmentException if the mark could not be set.
*/
public synchronized void mark() {
getState().mark();
@@ -231,9 +223,8 @@ public class ResourceLineReader extends AbstractItemReader implements LineReader
*
* @see #mark()
*
* @throws BatchEnvironmentException
* if the reset is unsuccessful, e.g. if the read-ahead limit
* was breached.
* @throws BatchEnvironmentException if the reset is unsuccessful, e.g. if
* the read-ahead limit was breached.
*/
public synchronized void reset() {
getState().reset();
@@ -275,10 +266,10 @@ public class ResourceLineReader extends AbstractItemReader implements LineReader
}
currentLineCount++;
}
} catch (IOException e) {
throw new BatchEnvironmentException(
"Unable to read from resource '" + resource
+ "' at line " + currentLineCount, e);
}
catch (IOException e) {
throw new BatchEnvironmentException("Unable to read from resource '" + resource + "' at line "
+ currentLineCount, e);
}
return line;
}
@@ -288,12 +279,11 @@ public class ResourceLineReader extends AbstractItemReader implements LineReader
*/
public void open() {
try {
reader = new BufferedReader(new InputStreamReader(resource
.getInputStream(), encoding));
reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), encoding));
mark();
} catch (IOException e) {
throw new BatchEnvironmentException("Could not open resource",
e);
}
catch (IOException e) {
throw new BatchEnvironmentException("Could not open resource", e);
}
}
@@ -307,9 +297,11 @@ public class ResourceLineReader extends AbstractItemReader implements LineReader
}
try {
reader.close();
} catch (IOException e) {
}
catch (IOException e) {
throw new BatchEnvironmentException("Could not close reader", e);
} finally {
}
finally {
currentLineCount = 0;
markedLineCount = -1;
}
@@ -330,7 +322,8 @@ public class ResourceLineReader extends AbstractItemReader implements LineReader
try {
reader.mark(READ_AHEAD_LIMIT);
markedLineCount = currentLineCount;
} catch (IOException e) {
}
catch (IOException e) {
throw new BatchEnvironmentException("Could not mark reader", e);
}
}
@@ -347,7 +340,8 @@ public class ResourceLineReader extends AbstractItemReader implements LineReader
try {
this.reader.reset();
currentLineCount = markedLineCount;
} catch (IOException e) {
}
catch (IOException e) {
throw new BatchEnvironmentException("Could not reset reader", e);
}