BATCH-1306:
*FieldExtractorLineAggregator now replaces nulls with empty strings before calling doAggregate(). *PassthroughFieldExtractor no longer replaces nulls.
This commit is contained in:
@@ -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<T> extends ExtractorLineAggregator<T> {
|
||||
|
||||
private String delimiter = ",";
|
||||
|
||||
|
||||
/**
|
||||
* Public setter for the delimiter.
|
||||
* @param delimiter the delimiter to set
|
||||
@@ -36,11 +36,9 @@ public class DelimitedLineAggregator<T> extends ExtractorLineAggregator<T> {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,13 +43,29 @@ public abstract class ExtractorLineAggregator<T> implements LineAggregator<T> {
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -67,7 +67,6 @@ public class FormatterLineAggregator<T> extends ExtractorLineAggregator<T> {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Public setter for the locale.
|
||||
* @param locale the locale to set
|
||||
@@ -76,9 +75,7 @@ public class FormatterLineAggregator<T> extends ExtractorLineAggregator<T> {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springframework.batch.item.file.transform.ExtractorLineAggregator#doAggregate(java.lang.Object[])
|
||||
*/
|
||||
@Override
|
||||
protected String doAggregate(Object[] fields) {
|
||||
|
||||
Assert.notNull(format);
|
||||
|
||||
@@ -34,31 +34,13 @@ public class PassThroughFieldExtractor<T> implements FieldExtractor<T> {
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -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<String[]> aggregator = new DelimitedLineAggregator<String[]>();
|
||||
private static DelimitedLineAggregator<String[]> aggregator;
|
||||
|
||||
private FieldExtractor<String[]> defaultFieldExtractor = new FieldExtractor<String[]>() {
|
||||
public Object[] extract(String[] item) {
|
||||
return item;
|
||||
}
|
||||
};
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
aggregator = new DelimitedLineAggregator<String[]>();
|
||||
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" }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String[]> aggregator = new FormatterLineAggregator<String[]>();
|
||||
private FormatterLineAggregator<String[]> aggregator;
|
||||
|
||||
private FieldExtractor<String[]> defaultFieldExtractor = new FieldExtractor<String[]>() {
|
||||
public Object[] extract(String[] item) {
|
||||
return item;
|
||||
}
|
||||
};
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
aggregator = new FormatterLineAggregator<String[]>();
|
||||
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<String[]>() {
|
||||
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()<widths[i]) {
|
||||
if (item[i].length() < widths[i]) {
|
||||
StringBuffer buffer = new StringBuffer(strings[i]);
|
||||
for (int j = 0; j<(widths[i]-item[i].length()+1)/2; j++) {
|
||||
for (int j = 0; j < (widths[i] - item[i].length() + 1) / 2; j++) {
|
||||
buffer.append(" ");
|
||||
}
|
||||
strings[i] = buffer.toString();
|
||||
strings[i] = buffer.toString();
|
||||
}
|
||||
}
|
||||
return strings;
|
||||
@@ -143,17 +157,18 @@ public class FormatterLineAggregatorTests {
|
||||
aggregator.setMaximumLength(24);
|
||||
|
||||
aggregator.setFieldExtractor(new FieldExtractor<String[]>() {
|
||||
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()<widths[i]) {
|
||||
if (item[i].length() < widths[i]) {
|
||||
StringBuffer buffer = new StringBuffer(strings[i]);
|
||||
for (int j = 0; j<widths[i]-item[i].length(); j++) {
|
||||
for (int j = 0; j < widths[i] - item[i].length(); j++) {
|
||||
buffer.append(".");
|
||||
}
|
||||
strings[i] = buffer.toString();
|
||||
strings[i] = buffer.toString();
|
||||
}
|
||||
}
|
||||
return strings;
|
||||
@@ -181,8 +196,9 @@ public class FormatterLineAggregatorTests {
|
||||
*/
|
||||
@Test
|
||||
public void testAggregateNullArgument() {
|
||||
String[] args = { null };
|
||||
aggregator.setFormat("%3s");
|
||||
assertEquals(" ", aggregator.aggregate(args));
|
||||
String[] args = { "foo", null, "bar" };
|
||||
aggregator.setFormat("%3s%3s%3s");
|
||||
assertEquals("foo bar", aggregator.aggregate(args));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class PassThroughFieldExtractorTests {
|
||||
public void testExtractArray() {
|
||||
PassThroughFieldExtractor<String[]> extractor = new PassThroughFieldExtractor<String[]>();
|
||||
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<List<String>> extractor = new PassThroughFieldExtractor<List<String>>();
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user