Skip to content

Commit 94d4437

Browse files
author
dsyer
committed
BATCH-1603: change item readers so they can still read after open fails
1 parent df1783a commit 94d4437

File tree

6 files changed

+97
-26
lines changed

6 files changed

+97
-26
lines changed

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemReader.java

+21-20
Original file line numberDiff line numberDiff line change
@@ -179,17 +179,17 @@ protected T doRead() throws Exception {
179179
}
180180

181181
String line = readLine();
182-
182+
183183
if (line == null) {
184184
return null;
185185
}
186186
else {
187-
try{
187+
try {
188188
return lineMapper.mapLine(line, lineCount);
189189
}
190-
catch(Exception ex){
191-
logger.error("Parsing error at line: " + lineCount + " in resource=" +
192-
resource.getDescription() + ", input=[" + line + "]", ex);
190+
catch (Exception ex) {
191+
logger.error("Parsing error at line: " + lineCount + " in resource=" + resource.getDescription()
192+
+ ", input=[" + line + "]", ex);
193193
throw ex;
194194
}
195195
}
@@ -219,7 +219,7 @@ private String readLine() {
219219
}
220220
lineCount++;
221221
}
222-
222+
223223
line = applyRecordSeparatorPolicy(line);
224224
}
225225
catch (IOException e) {
@@ -250,21 +250,20 @@ protected void doOpen() throws Exception {
250250
Assert.notNull(resource, "Input resource must be set");
251251
Assert.notNull(recordSeparatorPolicy, "RecordSeparatorPolicy must be set");
252252

253-
noInput = false;
253+
noInput = true;
254254
if (!resource.exists()) {
255255
if (strict) {
256256
throw new IllegalStateException("Input resource must exist (reader is in 'strict' mode): " + resource);
257257
}
258-
noInput = true;
259258
logger.warn("Input resource does not exist " + resource.getDescription());
260259
return;
261260
}
262261

263262
if (!resource.isReadable()) {
264263
if (strict) {
265-
throw new IllegalStateException("Input resource must be readable (reader is in 'strict' mode): " + resource);
264+
throw new IllegalStateException("Input resource must be readable (reader is in 'strict' mode): "
265+
+ resource);
266266
}
267-
noInput = true;
268267
logger.warn("Input resource is not readable " + resource.getDescription());
269268
return;
270269
}
@@ -276,21 +275,22 @@ protected void doOpen() throws Exception {
276275
skippedLinesCallback.handleLine(line);
277276
}
278277
}
278+
noInput = false;
279279
}
280280

281281
public void afterPropertiesSet() throws Exception {
282282
Assert.notNull(lineMapper, "LineMapper is required");
283283
}
284-
284+
285285
@Override
286286
protected void jumpToItem(int itemIndex) throws Exception {
287287
for (int i = 0; i < itemIndex; i++) {
288288
readLine();
289289
}
290290
}
291-
292-
private String applyRecordSeparatorPolicy(String line) throws IOException{
293-
291+
292+
private String applyRecordSeparatorPolicy(String line) throws IOException {
293+
294294
String record = line;
295295
while (line != null && !recordSeparatorPolicy.isEndOfRecord(record)) {
296296
line = this.reader.readLine();
@@ -302,18 +302,19 @@ private String applyRecordSeparatorPolicy(String line) throws IOException{
302302
}
303303
else {
304304
// Record has no text but it might still be post processed
305-
// to something (skipping preProcess since that was already done)
305+
// to something (skipping preProcess since that was already
306+
// done)
306307
break;
307308
}
308-
} else {
309+
}
310+
else {
309311
lineCount++;
310-
}
312+
}
311313
record = recordSeparatorPolicy.preProcess(record) + line;
312314
}
313-
315+
314316
return recordSeparatorPolicy.postProcess(record);
315-
316-
}
317317

318+
}
318319

319320
}

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java

-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import org.springframework.batch.item.ItemStreamException;
3434
import org.springframework.batch.item.WriteFailedException;
3535
import org.springframework.batch.item.WriterNotOpenException;
36-
import org.springframework.batch.item.database.JdbcBatchItemWriter;
3736
import org.springframework.batch.item.file.transform.LineAggregator;
3837
import org.springframework.batch.item.util.ExecutionContextUserSupport;
3938
import org.springframework.batch.item.util.FileUtils;

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemReader.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ protected boolean moveCursorToNextFragment(XMLEventReader reader) {
148148
}
149149
QName startElementName = ((StartElement) reader.peek()).getName();
150150
if (startElementName.getLocalPart().equals(fragmentRootElementName)) {
151-
if (fragmentRootElementNameSpace==null || startElementName.getNamespaceURI().equals(fragmentRootElementNameSpace)) {
151+
if (fragmentRootElementNameSpace == null
152+
|| startElementName.getNamespaceURI().equals(fragmentRootElementNameSpace)) {
152153
return true;
153154
}
154155
}
@@ -180,27 +181,26 @@ protected void doClose() throws Exception {
180181
protected void doOpen() throws Exception {
181182
Assert.notNull(resource, "The Resource must not be null.");
182183

183-
noInput = false;
184+
noInput = true;
184185
if (!resource.exists()) {
185186
if (strict) {
186187
throw new IllegalStateException("Input resource must exist (reader is in 'strict' mode)");
187188
}
188-
noInput = true;
189189
logger.warn("Input resource does not exist " + resource.getDescription());
190190
return;
191191
}
192192
if (!resource.isReadable()) {
193193
if (strict) {
194194
throw new IllegalStateException("Input resource must be readable (reader is in 'strict' mode)");
195195
}
196-
noInput = true;
197196
logger.warn("Input resource is not readable " + resource.getDescription());
198197
return;
199198
}
200199

201200
inputStream = resource.getInputStream();
202201
eventReader = XMLInputFactory.newInstance().createXMLEventReader(inputStream);
203202
fragmentReader = new DefaultFragmentEventReader(eventReader);
203+
noInput = false;
204204

205205
}
206206

spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemReaderTests.java

+31
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,37 @@ public void testNonExistentResource() throws Exception {
302302
reader.close();
303303
}
304304

305+
@Test
306+
public void testOpenBadIOInput() throws Exception {
307+
308+
reader.setResource(new AbstractResource() {
309+
public String getDescription() {
310+
return null;
311+
}
312+
313+
public InputStream getInputStream() throws IOException {
314+
throw new IOException();
315+
}
316+
317+
public boolean exists() {
318+
return true;
319+
}
320+
});
321+
322+
try {
323+
reader.open(executionContext);
324+
fail();
325+
}
326+
catch (ItemStreamException ex) {
327+
// expected
328+
}
329+
330+
// read() should then return a null
331+
assertNull(reader.read());
332+
reader.close();
333+
334+
}
335+
305336
@Test
306337
public void testDirectoryResource() throws Exception {
307338

spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemReaderIntegrationTests.java

+35
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,41 @@ public InputStream getInputStream() throws IOException {
345345
}
346346
}
347347

348+
@Test
349+
public void testBadIOInput() throws Exception {
350+
351+
Resource badResource = new AbstractResource() {
352+
353+
public boolean exists() {
354+
// Looks good ...
355+
return true;
356+
}
357+
358+
public InputStream getInputStream() throws IOException {
359+
// ... but fails during read
360+
throw new RuntimeException();
361+
}
362+
363+
public String getDescription() {return null;}
364+
};
365+
366+
tested.setResources(new Resource[] { badResource, r2, r3, r4, r5 });
367+
368+
tested.open(ctx);
369+
370+
try{
371+
assertEquals("1", tested.read());
372+
fail();
373+
}
374+
catch(ItemStreamException ex){
375+
// expected
376+
}
377+
378+
// Now check the next read gets the next resource
379+
assertEquals("4", tested.read());
380+
381+
}
382+
348383
@Test
349384
public void testGetCurrentResourceBeforeRead() throws Exception {
350385
tested.open(ctx);

spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ public void testClose() throws Exception {
234234
}
235235

236236
@Test
237-
public void testOpenBadIOInput() {
237+
public void testOpenBadIOInput() throws Exception {
238238

239239
source.setResource(new AbstractResource() {
240240
public String getDescription() {
@@ -252,10 +252,15 @@ public boolean exists() {
252252

253253
try {
254254
source.open(executionContext);
255+
fail();
255256
}
256257
catch (ItemStreamException ex) {
257258
// expected
258259
}
260+
261+
// read() should then return a null
262+
assertNull(source.read());
263+
source.close();
259264

260265
}
261266

0 commit comments

Comments
 (0)