RESOLVED - issue BATCH-640: FieldSetMapper.mapLine() should contain the line number
Added rownum parameter to field set mapper (with default value -1 defined as constant in FieldSetMapper)
This commit is contained in:
@@ -179,13 +179,13 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements R
|
||||
String line = readLine();
|
||||
|
||||
if (line != null) {
|
||||
int lineCount = getReader().getPosition();
|
||||
try {
|
||||
FieldSet tokenizedLine = tokenizer.tokenize(line);
|
||||
return fieldSetMapper.mapLine(tokenizedLine);
|
||||
return fieldSetMapper.mapLine(tokenizedLine, lineCount);
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
// add current line count to message and re-throw
|
||||
int lineCount = getReader().getPosition();
|
||||
throw new FlatFileParseException("Parsing error at line: " + lineCount + " in resource="
|
||||
+ resource.getDescription() + ", input=[" + line + "]", ex, line, lineCount);
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ public class BeanWrapperFieldSetMapper extends DefaultPropertyEditorRegistrar im
|
||||
|
||||
/**
|
||||
* The bean name (id) for an object that can be populated from the field set
|
||||
* that will be passed into {@link #mapLine(FieldSet)}. Typically a
|
||||
* that will be passed into {@link #mapLine(FieldSet, int)}. Typically a
|
||||
* prototype scoped bean so that a new instance is returned for each field
|
||||
* set mapped.
|
||||
*
|
||||
@@ -115,7 +115,7 @@ public class BeanWrapperFieldSetMapper extends DefaultPropertyEditorRegistrar im
|
||||
/**
|
||||
* Public setter for the type of bean to create instead of using a prototype
|
||||
* bean. An object of this type will be created from its default constructor
|
||||
* for every call to {@link #mapLine(FieldSet)}.<br/>
|
||||
* for every call to {@link #mapLine(FieldSet, int)}.<br/>
|
||||
*
|
||||
* Either this property or the prototype bean name must be specified, but
|
||||
* not both.
|
||||
@@ -150,9 +150,9 @@ public class BeanWrapperFieldSetMapper extends DefaultPropertyEditorRegistrar im
|
||||
* the {@link DataBinder} from {@link #createBinder(Object)} has errors
|
||||
* after binding).
|
||||
*
|
||||
* @see org.springframework.batch.item.file.mapping.FieldSetMapper#mapLine(org.springframework.batch.item.file.mapping.FieldSet)
|
||||
* @see org.springframework.batch.item.file.mapping.FieldSetMapper#mapLine(org.springframework.batch.item.file.mapping.FieldSet, int)
|
||||
*/
|
||||
public Object mapLine(FieldSet fs) {
|
||||
public Object mapLine(FieldSet fs, int rownum) {
|
||||
Object copy = getBean();
|
||||
DataBinder binder = createBinder(copy);
|
||||
binder.bind(new MutablePropertyValues(getBeanProperties(copy, fs.getProperties())));
|
||||
|
||||
@@ -16,18 +16,31 @@
|
||||
|
||||
package org.springframework.batch.item.file.mapping;
|
||||
|
||||
|
||||
/**
|
||||
* Interface that is used to map data obtained from a file into an object.
|
||||
* Interface that is used to map data obtained from a {@link FieldSet} into an
|
||||
* object.
|
||||
*
|
||||
* @author tomas.slanina
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public interface FieldSetMapper {
|
||||
|
||||
|
||||
/**
|
||||
* Method used to map data obtained from a file into an object.
|
||||
* Constant (negative) value indicating an unknown row number.
|
||||
*/
|
||||
public Object mapLine(FieldSet fs);
|
||||
public final static int ROW_NUMBER_UNKNOWN = -1;
|
||||
|
||||
/**
|
||||
* Method used to map data obtained from a {@link FieldSet} into an object.
|
||||
* Implementations can do whatever they need to to convert the input into an
|
||||
* object of the desired type. Often the row number is not used, and
|
||||
* sometimes it is not available anyway, in which case its value will be
|
||||
* {@link #ROW_NUMBER_UNKNOWN}.
|
||||
*
|
||||
* @param fs the {@link FieldSet} to map
|
||||
* @param rownum the row number for the field set in the input source (if
|
||||
* known)
|
||||
*/
|
||||
public Object mapLine(FieldSet fs, int rownum);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public class PassThroughFieldSetMapper implements FieldSetMapper, FieldSetCreato
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.batch.io.file.FieldSetMapper#mapLine(org.springframework.batch.io.file.FieldSet)
|
||||
*/
|
||||
public Object mapLine(FieldSet fs) {
|
||||
public Object mapLine(FieldSet fs, int rownum) {
|
||||
return fs;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ public class MultiResourceItemReaderFlatFileTests extends CommonItemStreamItemRe
|
||||
FlatFileItemReader fileReader = new FlatFileItemReader();
|
||||
|
||||
fileReader.setFieldSetMapper(new FieldSetMapper() {
|
||||
public Object mapLine(FieldSet fs) {
|
||||
public Object mapLine(FieldSet fs, int rownum) {
|
||||
Foo foo = new Foo();
|
||||
foo.setValue(fs.readInt(0));
|
||||
return foo;
|
||||
|
||||
@@ -52,7 +52,7 @@ public class FlatFileItemReaderAdvancedTests extends TestCase {
|
||||
};
|
||||
|
||||
private FieldSetMapper fieldSetMapper = new FieldSetMapper() {
|
||||
public Object mapLine(FieldSet fs) {
|
||||
public Object mapLine(FieldSet fs, int rownum) {
|
||||
return fs;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -59,7 +59,7 @@ public class FlatFileItemReaderBasicTests extends TestCase {
|
||||
};
|
||||
|
||||
private FieldSetMapper fieldSetMapper = new FieldSetMapper() {
|
||||
public Object mapLine(FieldSet fs) {
|
||||
public Object mapLine(FieldSet fs, int rownum) {
|
||||
return fs;
|
||||
}
|
||||
};
|
||||
@@ -126,7 +126,7 @@ public class FlatFileItemReaderBasicTests extends TestCase {
|
||||
|
||||
public void testReadWithMapperError() throws Exception {
|
||||
itemReader.setFieldSetMapper(new FieldSetMapper() {
|
||||
public Object mapLine(FieldSet fs) {
|
||||
public Object mapLine(FieldSet fs, int rownum) {
|
||||
throw new RuntimeException("foo");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ public class FlatFileItemReaderCommonTests extends CommonItemStreamItemReaderTes
|
||||
Resource resource = new ByteArrayResource(FOOS.getBytes());
|
||||
tested.setResource(resource);
|
||||
tested.setFieldSetMapper(new FieldSetMapper() {
|
||||
public Object mapLine(FieldSet fs) {
|
||||
public Object mapLine(FieldSet fs, int rownum) {
|
||||
Foo foo = new Foo();
|
||||
foo.setValue(fs.readInt(0));
|
||||
return foo;
|
||||
|
||||
@@ -63,7 +63,7 @@ public class BeanWrapperFieldSetMapperTests extends TestCase {
|
||||
|
||||
FieldSet fieldSet = new DefaultFieldSet(new String[] { "This is some dummy string", "true", "C" }, new String[] {
|
||||
"varString", "varBoolean", "varChar" });
|
||||
TestObject result = (TestObject) mapper.mapLine(fieldSet);
|
||||
TestObject result = (TestObject) mapper.mapLine(fieldSet, FieldSetMapper.ROW_NUMBER_UNKNOWN);
|
||||
assertEquals("This is some dummy string", result.getVarString());
|
||||
assertEquals(true, result.isVarBoolean());
|
||||
assertEquals('C', result.getVarChar());
|
||||
@@ -78,7 +78,7 @@ public class BeanWrapperFieldSetMapperTests extends TestCase {
|
||||
|
||||
FieldSet fieldSet = new DefaultFieldSet(new String[] { "This is some dummy string", "true", "C" }, new String[] {
|
||||
"varString", "varBoolean", "varChar" });
|
||||
TestObject result = (TestObject) mapper.mapLine(fieldSet);
|
||||
TestObject result = (TestObject) mapper.mapLine(fieldSet, FieldSetMapper.ROW_NUMBER_UNKNOWN);
|
||||
assertEquals("This is some dummy string", result.getVarString());
|
||||
assertEquals(true, result.isVarBoolean());
|
||||
assertEquals('C', result.getVarChar());
|
||||
@@ -93,7 +93,7 @@ public class BeanWrapperFieldSetMapperTests extends TestCase {
|
||||
|
||||
FieldSet fieldSet = new DefaultFieldSet(new String[] { "This is some dummy string", "true", "C" }, new String[] {
|
||||
"VarString", "VAR_BOOLEAN", "VAR_CHAR" });
|
||||
TestObject result = (TestObject) mapper.mapLine(fieldSet);
|
||||
TestObject result = (TestObject) mapper.mapLine(fieldSet, FieldSetMapper.ROW_NUMBER_UNKNOWN);
|
||||
assertEquals("This is some dummy string", result.getVarString());
|
||||
assertEquals(true, result.isVarBoolean());
|
||||
assertEquals('C', result.getVarChar());
|
||||
@@ -106,7 +106,7 @@ public class BeanWrapperFieldSetMapperTests extends TestCase {
|
||||
|
||||
FieldSet fieldSet = new DefaultFieldSet(new String[] { "This is some dummy string", "true", "C" }, new String[] {
|
||||
"varString", "varBoolean", "varChar" });
|
||||
TestObject result = (TestObject) mapper.mapLine(fieldSet);
|
||||
TestObject result = (TestObject) mapper.mapLine(fieldSet, FieldSetMapper.ROW_NUMBER_UNKNOWN);
|
||||
assertEquals("This is some dummy string", result.getVarString());
|
||||
assertEquals(true, result.isVarBoolean());
|
||||
assertEquals('C', result.getVarChar());
|
||||
@@ -128,7 +128,7 @@ public class BeanWrapperFieldSetMapperTests extends TestCase {
|
||||
FieldSet fieldSet = new DefaultFieldSet(new String[] { "This is some dummy string", "1", "Another dummy", "2" },
|
||||
new String[] { "valueA", "valueB", "testObjectB.valueA", "testObjectB.testObjectC.value" });
|
||||
|
||||
TestNestedA result = (TestNestedA) mapper.mapLine(fieldSet);
|
||||
TestNestedA result = (TestNestedA) mapper.mapLine(fieldSet, FieldSetMapper.ROW_NUMBER_UNKNOWN);
|
||||
|
||||
assertEquals("This is some dummy string", result.getValueA());
|
||||
assertEquals(1, result.getValueB());
|
||||
@@ -148,7 +148,7 @@ public class BeanWrapperFieldSetMapperTests extends TestCase {
|
||||
FieldSet fieldSet = new DefaultFieldSet(new String[] { "This is some dummy string", "1" }, new String[] { "VALUE_A",
|
||||
"VALUE_B" });
|
||||
|
||||
TestNestedA result = (TestNestedA) mapper.mapLine(fieldSet);
|
||||
TestNestedA result = (TestNestedA) mapper.mapLine(fieldSet, FieldSetMapper.ROW_NUMBER_UNKNOWN);
|
||||
|
||||
assertEquals("This is some dummy string", result.getValueA());
|
||||
assertEquals(1, result.getValueB());
|
||||
@@ -165,7 +165,7 @@ public class BeanWrapperFieldSetMapperTests extends TestCase {
|
||||
|
||||
FieldSet fieldSet = new DefaultFieldSet(new String[] { "1" }, new String[] { "foo" });
|
||||
|
||||
TestNestedC result = (TestNestedC) mapper.mapLine(fieldSet);
|
||||
TestNestedC result = (TestNestedC) mapper.mapLine(fieldSet, FieldSetMapper.ROW_NUMBER_UNKNOWN);
|
||||
|
||||
// "foo" is similar enough to "value" that it matches - but only because
|
||||
// nothing else does...
|
||||
@@ -187,7 +187,7 @@ public class BeanWrapperFieldSetMapperTests extends TestCase {
|
||||
FieldSet fieldSet = new DefaultFieldSet(new String[] { "Another dummy", "2" }, new String[] { "TestObjectB.ValueA",
|
||||
"TestObjectB.TestObjectC.Value" });
|
||||
|
||||
TestNestedA result = (TestNestedA) mapper.mapLine(fieldSet);
|
||||
TestNestedA result = (TestNestedA) mapper.mapLine(fieldSet, FieldSetMapper.ROW_NUMBER_UNKNOWN);
|
||||
|
||||
assertEquals("Another dummy", result.getTestObjectB().getValueA());
|
||||
assertEquals(2, result.getTestObjectB().getTestObjectC().getValue());
|
||||
@@ -207,7 +207,7 @@ public class BeanWrapperFieldSetMapperTests extends TestCase {
|
||||
FieldSet fieldSet = new DefaultFieldSet(new String[] { "Another dummy" }, new String[] { "TestObjectB.foo" });
|
||||
|
||||
try {
|
||||
mapper.mapLine(fieldSet);
|
||||
mapper.mapLine(fieldSet, FieldSetMapper.ROW_NUMBER_UNKNOWN);
|
||||
fail("Expected NotWritablePropertyException");
|
||||
}
|
||||
catch (NotWritablePropertyException e) {
|
||||
@@ -229,7 +229,7 @@ public class BeanWrapperFieldSetMapperTests extends TestCase {
|
||||
FieldSet fieldSet = new DefaultFieldSet(new String[] { "2" }, new String[] { "TestObjectA.garbage" });
|
||||
|
||||
try {
|
||||
mapper.mapLine(fieldSet);
|
||||
mapper.mapLine(fieldSet, FieldSetMapper.ROW_NUMBER_UNKNOWN);
|
||||
fail("Expected NotWritablePropertyException");
|
||||
}
|
||||
catch (NotWritablePropertyException e) {
|
||||
@@ -269,7 +269,7 @@ public class BeanWrapperFieldSetMapperTests extends TestCase {
|
||||
FieldSet fieldSet = new DefaultFieldSet(new String[] { "1", "2", "3" }, new String[] { "NestedC[0].Value",
|
||||
"NestedC[1].Value", "NestedC[2].Value" });
|
||||
|
||||
mapper.mapLine(fieldSet);
|
||||
mapper.mapLine(fieldSet, FieldSetMapper.ROW_NUMBER_UNKNOWN);
|
||||
|
||||
assertEquals(1, ((TestNestedC) nestedList.getNestedC().get(0)).getValue());
|
||||
assertEquals(2, ((TestNestedC) nestedList.getNestedC().get(1)).getValue());
|
||||
@@ -285,7 +285,7 @@ public class BeanWrapperFieldSetMapperTests extends TestCase {
|
||||
FieldSet fieldSet = new DefaultFieldSet(new String[] { "00009" }, new String[] { "varLong" });
|
||||
|
||||
try {
|
||||
mapper.mapLine(fieldSet);
|
||||
mapper.mapLine(fieldSet, FieldSetMapper.ROW_NUMBER_UNKNOWN);
|
||||
fail("Expected BindingException");
|
||||
}
|
||||
catch (BindingException e) {
|
||||
@@ -302,7 +302,7 @@ public class BeanWrapperFieldSetMapperTests extends TestCase {
|
||||
|
||||
mapper.setCustomEditors(Collections.singletonMap(Long.TYPE, new CustomNumberEditor(Long.class, NumberFormat
|
||||
.getNumberInstance(), true)));
|
||||
TestObject bean = (TestObject) mapper.mapLine(fieldSet);
|
||||
TestObject bean = (TestObject) mapper.mapLine(fieldSet, FieldSetMapper.ROW_NUMBER_UNKNOWN);
|
||||
|
||||
assertEquals(9, bean.getVarLong());
|
||||
}
|
||||
@@ -316,7 +316,7 @@ public class BeanWrapperFieldSetMapperTests extends TestCase {
|
||||
|
||||
mapper.setCustomEditors(Collections.singletonMap(Long.TYPE, new CustomNumberEditor(Long.class, NumberFormat
|
||||
.getNumberInstance(), true)));
|
||||
TestObject bean = (TestObject) mapper.mapLine(fieldSet);
|
||||
TestObject bean = (TestObject) mapper.mapLine(fieldSet, FieldSetMapper.ROW_NUMBER_UNKNOWN);
|
||||
|
||||
assertEquals(9, bean.getVarLong());
|
||||
assertEquals(78, bean.getVarInt());
|
||||
|
||||
@@ -27,11 +27,11 @@ public class PassThroughFieldSetMapperTests extends TestCase {
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.item.file.mapping.PassThroughFieldSetMapper#mapLine(org.springframework.batch.item.file.mapping.FieldSet)}.
|
||||
* {@link org.springframework.batch.item.file.mapping.PassThroughFieldSetMapper#mapLine(org.springframework.batch.item.file.mapping.FieldSet, int)}.
|
||||
*/
|
||||
public void testMapLine() {
|
||||
FieldSet fieldSet = new DefaultFieldSet(new String[] { "foo", "bar" });
|
||||
assertEquals(fieldSet, mapper.mapLine(fieldSet));
|
||||
assertEquals(fieldSet, mapper.mapLine(fieldSet, FieldSetMapper.ROW_NUMBER_UNKNOWN));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,7 +60,7 @@ public abstract class AbstractTradeBatchTests extends TestCase {
|
||||
}
|
||||
|
||||
protected static class TradeMapper implements FieldSetMapper{
|
||||
public Object mapLine(FieldSet fs) {
|
||||
public Object mapLine(FieldSet fs, int rownum) {
|
||||
return new Trade(fs);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user