diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DelimitedLineAggregator.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DelimitedLineAggregator.java index e96bd5429..4d6c1a1c1 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DelimitedLineAggregator.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DelimitedLineAggregator.java @@ -22,12 +22,12 @@ import org.springframework.util.StringUtils; * delimited list of strings. The default delimiter is a comma. * * @author Dave Syer - * + * */ public class DelimitedLineAggregator extends ExtractorLineAggregator { private String delimiter = ","; - + /** * Public setter for the delimiter. * @param delimiter the delimiter to set @@ -36,11 +36,9 @@ public class DelimitedLineAggregator extends ExtractorLineAggregator { this.delimiter = delimiter; } - /** - * @see org.springframework.batch.item.file.transform.ExtractorLineAggregator#doAggregate(java.lang.Object[]) - */ - public String doAggregate(Object[] item) { - return StringUtils.arrayToDelimitedString(item, this.delimiter); + @Override + public String doAggregate(Object[] fields) { + return StringUtils.arrayToDelimitedString(fields, this.delimiter); } } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/ExtractorLineAggregator.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/ExtractorLineAggregator.java index 2679492b0..a2277def7 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/ExtractorLineAggregator.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/ExtractorLineAggregator.java @@ -43,13 +43,29 @@ public abstract class ExtractorLineAggregator implements LineAggregator { /** * Extract fields from the given item using the {@link FieldExtractor} and - * then aggregate them. Null items are not allowed. + * then aggregate them. Any null field returned by the extractor will be + * replaced by an empty String. Null items are not allowed. * * @see org.springframework.batch.item.file.transform.LineAggregator#aggregate(java.lang.Object) */ public String aggregate(T item) { Assert.notNull(item); - return this.doAggregate(this.fieldExtractor.extract(item)); + Object[] fields = this.fieldExtractor.extract(item); + + // + // Replace nulls with empty strings + // + Object[] args = new Object[fields.length]; + for (int i = 0; i < fields.length; i++) { + if (fields[i] == null) { + args[i] = ""; + } + else { + args[i] = fields[i]; + } + } + + return this.doAggregate(args); } /** diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/FormatterLineAggregator.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/FormatterLineAggregator.java index 32bbf0df3..063df94dc 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/FormatterLineAggregator.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/FormatterLineAggregator.java @@ -67,7 +67,6 @@ public class FormatterLineAggregator extends ExtractorLineAggregator { this.format = format; } - /** * Public setter for the locale. * @param locale the locale to set @@ -76,9 +75,7 @@ public class FormatterLineAggregator extends ExtractorLineAggregator { this.locale = locale; } - /** - * @see org.springframework.batch.item.file.transform.ExtractorLineAggregator#doAggregate(java.lang.Object[]) - */ + @Override protected String doAggregate(Object[] fields) { Assert.notNull(format); diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/PassThroughFieldExtractor.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/PassThroughFieldExtractor.java index 773699609..06236d0f0 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/PassThroughFieldExtractor.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/PassThroughFieldExtractor.java @@ -34,31 +34,13 @@ public class PassThroughFieldExtractor implements FieldExtractor { public Object[] extract(T item) { if (item.getClass().isArray()) { - Object[] items = (Object[]) item; - Object[] args = new Object[items.length]; - for (int i = 0; i < items.length; i++) { - if (items[i] == null) - args[i] = ""; - else - args[i] = items[i]; - } - return args; + return (Object[]) item; } if (item instanceof Collection) { - Collection items = (Collection) item; - Object[] args = new Object[items.size()]; - int i = 0; - for (Object object : items) { - if (object == null) - args[i] = ""; - else - args[i] = object; - i++; - } - return args; + return ((Collection) item).toArray(); } - + if (item instanceof FieldSet) { return ((FieldSet) item).getValues(); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/transform/DelimitedLineAggregatorTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/transform/DelimitedLineAggregatorTests.java index e14a86fa4..c390e6c7c 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/transform/DelimitedLineAggregatorTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/transform/DelimitedLineAggregatorTests.java @@ -15,8 +15,9 @@ */ package org.springframework.batch.item.file.transform; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import org.junit.Before; import org.junit.Test; /** @@ -25,7 +26,19 @@ import org.junit.Test; */ public class DelimitedLineAggregatorTests { - private DelimitedLineAggregator aggregator = new DelimitedLineAggregator(); + private static DelimitedLineAggregator aggregator; + + private FieldExtractor defaultFieldExtractor = new FieldExtractor() { + public Object[] extract(String[] item) { + return item; + } + }; + + @Before + public void setup() { + aggregator = new DelimitedLineAggregator(); + aggregator.setFieldExtractor(defaultFieldExtractor); + } @Test public void testSetDelimiter() { @@ -38,4 +51,8 @@ public class DelimitedLineAggregatorTests { assertEquals("foo,bar", aggregator.aggregate(new String[] { "foo", "bar" })); } + @Test + public void testAggregateWithNull() { + assertEquals("foo,,bar", aggregator.aggregate(new String[] { "foo", null, "bar" })); + } } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/transform/FormatterLineAggregatorTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/transform/FormatterLineAggregatorTests.java index a5f0928c1..f284ae4c9 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/transform/FormatterLineAggregatorTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/transform/FormatterLineAggregatorTests.java @@ -19,6 +19,7 @@ package org.springframework.batch.item.file.transform; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import org.junit.Before; import org.junit.Test; /** @@ -29,7 +30,19 @@ import org.junit.Test; public class FormatterLineAggregatorTests { // object under test - private FormatterLineAggregator aggregator = new FormatterLineAggregator(); + private FormatterLineAggregator aggregator; + + private FieldExtractor defaultFieldExtractor = new FieldExtractor() { + public Object[] extract(String[] item) { + return item; + } + }; + + @Before + public void setup() { + aggregator = new FormatterLineAggregator(); + aggregator.setFieldExtractor(defaultFieldExtractor); + } /** * If no ranges are specified, IllegalArgumentException is thrown @@ -110,17 +123,18 @@ public class FormatterLineAggregatorTests { aggregator.setMaximumLength(25); aggregator.setFieldExtractor(new FieldExtractor() { - private int[] widths = new int[] {13,12}; + private int[] widths = new int[] { 13, 12 }; + public Object[] extract(String[] item) { String[] strings = new String[item.length]; for (int i = 0; i < strings.length; i++) { strings[i] = item[i]; - if (item[i].length()() { - private int[] widths = new int[] {13,11}; + private int[] widths = new int[] { 13, 11 }; + public Object[] extract(String[] item) { String[] strings = new String[item.length]; for (int i = 0; i < strings.length; i++) { strings[i] = item[i]; - if (item[i].length() extractor = new PassThroughFieldExtractor(); Object[] result = extractor.extract(new String[] { "a", "b", null, "d" }); - assertTrue(Arrays.equals(new Object[] { "a", "b", "", "d" }, result)); + assertTrue(Arrays.equals(new Object[] { "a", "b", null, "d" }, result)); } @Test @@ -53,6 +53,6 @@ public class PassThroughFieldExtractorTests { public void testExtractCollection() { PassThroughFieldExtractor> extractor = new PassThroughFieldExtractor>(); Object[] result = extractor.extract(Arrays.asList("a", "b", null, "d")); - assertTrue(Arrays.equals(new Object[] { "a", "b", "", "d" }, result)); + assertTrue(Arrays.equals(new Object[] { "a", "b", null, "d" }, result)); } }