REOPENED - issue BATCH-640: FieldSetMapper.mapLine() should contain the line number

OPEN - issue BATCH-278: Allow FixedLengthLineAggregator to be configured with different padding/alignment for specific columns

Remove FieldSetCreator and replace with new LineAggregator interface
This commit is contained in:
dsyer
2008-08-07 12:44:08 +00:00
parent 754d3254cd
commit c56cfc84fd
31 changed files with 568 additions and 1055 deletions

View File

@@ -26,10 +26,8 @@ import junit.framework.TestCase;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.file.mapping.DefaultFieldSet;
import org.springframework.batch.item.file.mapping.FieldSet;
import org.springframework.batch.item.file.mapping.FieldSetCreator;
import org.springframework.batch.item.file.mapping.PassThroughFieldSetCreator;
import org.springframework.batch.item.file.transform.LineAggregator;
import org.springframework.batch.item.file.transform.PassThroughLineAggregator;
import org.springframework.core.io.FileSystemResource;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
@@ -74,7 +72,7 @@ public class FlatFileItemWriterTests extends TestCase {
outputFile = File.createTempFile("flatfile-test-output-", ".tmp");
writer.setResource(new FileSystemResource(outputFile));
writer.setFieldSetCreator(new PassThroughFieldSetCreator<String>());
writer.setLineAggregator(new PassThroughLineAggregator<String>());
writer.afterPropertiesSet();
writer.setSaveState(true);
executionContext = new ExecutionContext();
@@ -144,9 +142,9 @@ public class FlatFileItemWriterTests extends TestCase {
* @throws Exception
*/
public void testWriteWithConverter() throws Exception {
writer.setFieldSetCreator(new FieldSetCreator<String>() {
public FieldSet mapItem(String data) {
return new DefaultFieldSet(new String[] { "FOO:" + data });
writer.setLineAggregator(new LineAggregator<String>() {
public String aggregate(String item) {
return "FOO:" + item;
}
});
String data = "string";
@@ -164,9 +162,9 @@ public class FlatFileItemWriterTests extends TestCase {
* @throws Exception
*/
public void testWriteWithConverterAndString() throws Exception {
writer.setFieldSetCreator(new FieldSetCreator<String>() {
public FieldSet mapItem(String data) {
return new DefaultFieldSet(new String[] { "FOO:" + data });
writer.setLineAggregator(new LineAggregator<String>() {
public String aggregate(String item) {
return "FOO:" + item;
}
});
writer.open(executionContext);
@@ -278,7 +276,7 @@ public class FlatFileItemWriterTests extends TestCase {
public void testOpenWithNonWritableFile() throws Exception {
writer = new FlatFileItemWriter<String>();
writer.setFieldSetCreator(new PassThroughFieldSetCreator<String>());
writer.setLineAggregator(new PassThroughLineAggregator<String>());
FileSystemResource file = new FileSystemResource("target/no-such-file.foo");
writer.setResource(file);
new File(file.getFile().getParent()).mkdirs();
@@ -310,7 +308,7 @@ public class FlatFileItemWriterTests extends TestCase {
public void testDefaultStreamContext() throws Exception {
writer = new FlatFileItemWriter<String>();
writer.setResource(new FileSystemResource(outputFile));
writer.setFieldSetCreator(new PassThroughFieldSetCreator<String>());
writer.setLineAggregator(new PassThroughLineAggregator<String>());
writer.afterPropertiesSet();
writer.setSaveState(true);
writer.open(executionContext);

View File

@@ -1,34 +0,0 @@
package org.springframework.batch.item.file.mapping;
import junit.framework.TestCase;
public class PassThroughFieldSetCreatorTests extends TestCase {
private PassThroughFieldSetCreator<Object> mapper = new PassThroughFieldSetCreator<Object>();
/**
* Test method for
* {@link org.springframework.batch.item.file.mapping.PassThroughFieldSetCreator#mapItem(Object)}.
*/
public void testUnmapItemAsFieldSet() {
FieldSet fieldSet = new DefaultFieldSet(new String[] { "foo", "bar" });
assertEquals(fieldSet, mapper.mapItem(fieldSet));
}
/**
* Test method for
* {@link org.springframework.batch.item.file.mapping.PassThroughFieldSetCreator#mapItem(java.lang.Object)}.
*/
public void testUnmapItemAsString() {
assertEquals(new DefaultFieldSet(new String[] { "foo" }), mapper.mapItem("foo"));
}
/**
* Test method for
* {@link org.springframework.batch.item.file.mapping.PassThroughFieldSetCreator#mapItem(java.lang.Object)}.
*/
public void testUnmapItemAsNonString() {
Object object = new Object();
assertEquals(new DefaultFieldSet(new String[] { "" + object }), mapper.mapItem(object));
}
}

View File

@@ -1,41 +0,0 @@
/*
* Copyright 2006-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.item.file.transform;
import junit.framework.TestCase;
import org.springframework.batch.item.file.mapping.DefaultFieldSet;
/**
* Unit tests for {@link DelimitedLineAggregator}
*
* @author robert.kasanicky
*/
public class DelimitedLineAggregatorTests extends TestCase {
private DelimitedLineAggregator aggregator;
public void testAggregate() {
aggregator = new DelimitedLineAggregator();
aggregator.setDelimiter(":");
String[] args = { "a", "bc", "def" };
String expectedResult = "a:bc:def";
String result = aggregator.aggregate(new DefaultFieldSet(args));
assertEquals(result, expectedResult);
}
}

View File

@@ -1,157 +0,0 @@
/*
* Copyright 2006-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.item.file.transform;
import junit.framework.TestCase;
import org.springframework.batch.item.file.mapping.DefaultFieldSet;
/**
* Unit tests for {@link FixedLengthLineAggregator}
*
* @author robert.kasanicky
* @author peter.zozom
*/
public class FixedLengthLineAggregatorTests extends TestCase {
// object under test
private FixedLengthLineAggregator aggregator = new FixedLengthLineAggregator();
/**
* If no ranges are specified, IllegalArgumentException is thrown
*/
public void testAggregateNullRecordDescriptor() {
String[] args = { "does not matter what is here" };
try {
aggregator.aggregate(new DefaultFieldSet(args));
fail("should not work with no ranges specified");
}
catch (IllegalArgumentException expected) {
// expected
}
}
/**
* Count of aggregated strings does not match the number of columns
*/
public void testAggregateWrongArgumentCount() {
String[] string = { "only one test string" };
aggregator.setColumns(new Range[0]);
try {
aggregator.aggregate(new DefaultFieldSet(string));
fail("Exception expected: count of aggregated strings"
+ " does not match the number of columns");
}
catch (IllegalArgumentException expected) {
// expected
}
}
/**
* Text length exceeds the length of the column.
*/
public void testAggregateInvalidInputLength() {
String[] args = { "Oversize" };
aggregator.setColumns(new Range[] {new Range(1,args[0].length()-1)});
try {
aggregator.aggregate(new DefaultFieldSet(args));
fail("Invalid text length, exception should have been thrown");
}
catch (IllegalArgumentException expected) {
// expected
}
}
/**
* Test aggregation
*/
public void testAggregate() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setColumns(new Range[] {new Range(1,9), new Range(10,18)});
String result = aggregator.aggregate(new DefaultFieldSet(args));
assertEquals("MatchsizeSmallsize", result);
}
/**
* Test aggregation with last range unbound
*/
public void testAggregateWithLastRangeUnbound() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setColumns(new Range[] {new Range(1,12), new Range(13)});
String result = aggregator.aggregate(new DefaultFieldSet(args));
assertEquals("Matchsize Smallsize", result);
}
/**
* Test aggregation with right alignment
*/
public void testAggregateFormattedRight() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setAlignment(Alignment.RIGHT);
aggregator.setColumns(new Range[] {new Range(1,13), new Range(14,23)});
String result = aggregator.aggregate(new DefaultFieldSet(args));
assertEquals(23,result.length());
assertEquals(result, " Matchsize Smallsize");
}
/**
* Test aggregation with center alignment
*/
public void testAggregateFormattedCenter() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setAlignment(Alignment.CENTER);
aggregator.setColumns(new Range[] {new Range(1,13), new Range(14,25)});
String result = aggregator.aggregate(new DefaultFieldSet(args));
assertEquals(result, " Matchsize Smallsize ");
}
/**
* Test aggregation with left alignment
*/
public void testAggregateWithCustomPadding() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setPadding('.');
aggregator.setAlignment(Alignment.LEFT);
aggregator.setColumns(new Range[] {new Range(1,13), new Range(14,24)});
String result = aggregator.aggregate(new DefaultFieldSet(args));
assertEquals(result, "Matchsize....Smallsize..");
}
/**
* Test aggregation with left alignment
*/
public void testAggregateFormattedLeft() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setAlignment(Alignment.LEFT);
aggregator.setColumns(new Range[] {new Range(1,13), new Range(14,24)});
String result = aggregator.aggregate(new DefaultFieldSet(args));
assertEquals(result, "Matchsize Smallsize ");
}
/**
* If one of the passed arguments is null, string filled with spaces should
* be returned
*/
public void testAggregateNullArgument() {
String[] args = { null };
aggregator.setColumns(new Range[] {new Range(1,3)});
assertEquals(" ", aggregator.aggregate(new DefaultFieldSet(args)));
}
}

View File

@@ -0,0 +1,188 @@
/*
* Copyright 2006-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.item.file.transform;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.junit.Test;
/**
* Unit tests for {@link FormatterLineAggregator}
*
* @author Dave Syer
*/
public class FormatterLineAggregatorTests {
// object under test
private FormatterLineAggregator<String[]> aggregator = new FormatterLineAggregator<String[]>();
/**
* If no ranges are specified, IllegalArgumentException is thrown
*/
@Test
public void testAggregateNullRecordDescriptor() {
String[] args = { "does not matter what is here" };
try {
aggregator.aggregate(args);
fail("should not work with no format specified");
}
catch (IllegalArgumentException expected) {
// expected
}
}
/**
* Text length exceeds the length of the column.
*/
@Test
public void testAggregateInvalidInputLength() {
String[] args = { "Oversize" };
aggregator.setMaximumLength(3);
aggregator.setFormat("%3s");
try {
aggregator.aggregate(args);
fail("Invalid text length, exception should have been thrown");
}
catch (IllegalStateException expected) {
// expected
}
}
/**
* Test aggregation
*/
@Test
public void testAggregate() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setFormat("%9s%9s");
String result = aggregator.aggregate(args);
assertEquals("MatchsizeSmallsize", result);
}
/**
* Test aggregation with last range unbound
*/
@Test
public void testAggregateWithLastRangeUnbound() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setFormat("%-12s%s");
String result = aggregator.aggregate(args);
assertEquals("Matchsize Smallsize", result);
}
/**
* Test aggregation with right alignment
*/
@Test
public void testAggregateFormattedRight() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setFormat("%13s%10s");
String result = aggregator.aggregate(args);
assertEquals(23, result.length());
assertEquals(" Matchsize Smallsize", result);
}
/**
* Test aggregation with center alignment
*/
@Test
public void testAggregateFormattedCenter() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setFormat("%13s%12s");
aggregator.setMinimumLength(25);
aggregator.setMaximumLength(25);
aggregator.setFieldExtractor(new FieldExtractor<String[]>() {
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]) {
StringBuffer buffer = new StringBuffer(strings[i]);
for (int j = 0; j<(widths[i]-item[i].length()+1)/2; j++) {
buffer.append(" ");
}
strings[i] = buffer.toString();
}
}
return strings;
}
});
String result = aggregator.aggregate(args);
assertEquals(" Matchsize Smallsize ", result);
}
/**
* Test aggregation with left alignment
*/
@Test
public void testAggregateWithCustomPadding() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setFormat("%13s%11s");
aggregator.setMinimumLength(24);
aggregator.setMaximumLength(24);
aggregator.setFieldExtractor(new FieldExtractor<String[]>() {
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]) {
StringBuffer buffer = new StringBuffer(strings[i]);
for (int j = 0; j<widths[i]-item[i].length(); j++) {
buffer.append(".");
}
strings[i] = buffer.toString();
}
}
return strings;
}
});
String result = aggregator.aggregate(args);
assertEquals("Matchsize....Smallsize..", result);
}
/**
* Test aggregation with left alignment
*/
@Test
public void testAggregateFormattedLeft() {
String[] args = { "Matchsize", "Smallsize" };
aggregator.setFormat("%-13s%-11s");
String result = aggregator.aggregate(args);
assertEquals("Matchsize Smallsize ", result);
}
/**
* If one of the passed arguments is null, string filled with spaces should
* be returned
*/
@Test
public void testAggregateNullArgument() {
String[] args = { null };
aggregator.setFormat("%3s");
assertEquals(" ", aggregator.aggregate(args));
}
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright 2006-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.item.file.transform;
import junit.framework.TestCase;
import org.springframework.batch.item.file.mapping.FieldSet;
/**
* @author Dave Syer
*
*/
public class LineAggregatorItemTransformerTests extends TestCase {
private LineAggregatorItemTransformer<String[]> transformer = new LineAggregatorItemTransformer<String[]>();
/**
* Test method for {@link org.springframework.batch.item.file.transform.LineAggregatorItemTransformer#setAggregator(org.springframework.batch.item.file.transform.LineAggregator)}.
* @throws Exception
*/
public void testSetAggregator() throws Exception {
transformer.setAggregator(new LineAggregator() {
public String aggregate(FieldSet fieldSet) {
return "foo";
}
});
String value = (String) transformer.transform(new String[] {"a", "b"});
assertEquals("foo", value);
}
/**
* Test method for {@link org.springframework.batch.item.file.transform.LineAggregatorItemTransformer#transform(java.lang.Object)}.
* @throws Exception
*/
public void testTransform() throws Exception {
String value = (String) transformer.transform(new String[] {"a", "b"});
assertTrue("Wrong value: "+value, value.startsWith("a,b"));
}
}

View File

@@ -0,0 +1,21 @@
package org.springframework.batch.item.file.transform;
import junit.framework.TestCase;
import org.springframework.batch.item.file.transform.LineAggregator;
import org.springframework.batch.item.file.transform.PassThroughLineAggregator;
public class PassThroughLineAggregatorTests extends TestCase {
private LineAggregator<Object> mapper = new PassThroughLineAggregator<Object>();
public void testUnmapItemAsFieldSet() {
Object item = new Object();
assertEquals(item.toString(), mapper.aggregate(item));
}
public void testUnmapItemAsString() {
assertEquals("foo", mapper.aggregate("foo"));
}
}

View File

@@ -16,12 +16,10 @@
package org.springframework.batch.item.file.transform;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import junit.framework.TestCase;
import org.springframework.batch.item.transform.ItemTransformer;
import org.springframework.util.StringUtils;
/**
@@ -32,97 +30,22 @@ public class RecursiveCollectionItemTransformerTests extends TestCase {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
private RecursiveCollectionItemTransformer transformer = new RecursiveCollectionItemTransformer();
private RecursiveCollectionLineAggregator<String> aggregator = new RecursiveCollectionLineAggregator<String>();
/**
* Test method for
* {@link org.springframework.batch.item.file.transform.RecursiveCollectionItemTransformer#setDelegate(org.springframework.batch.item.transform.ItemTransformer)}.
* @throws Exception
*/
public void testSetDelegate() throws Exception {
transformer.setDelegate(new ItemTransformer<Object, String>() {
public String transform(Object item) throws Exception {
return "bar";
}
});
assertEquals("bar", transformer.transform(new Object()));
}
/**
* Test method for
* {@link org.springframework.batch.item.file.transform.RecursiveCollectionItemTransformer#setDelegate(org.springframework.batch.item.transform.ItemTransformer)}.
* @throws Exception
*/
public void testSetDelegateAndPassInString() throws Exception {
transformer.setDelegate(new ItemTransformer<Object, String>() {
public String transform(Object item) throws Exception {
aggregator.setDelegate(new LineAggregator<String>() {
public String aggregate(String item) {
return "bar";
}
});
assertEquals("foo", transformer.transform("foo"));
assertEquals("bar", aggregator.aggregate(Collections.singleton("foo")));
}
/**
* Test method for
* {@link org.springframework.batch.item.file.transform.RecursiveCollectionItemTransformer#setDelegate(org.springframework.batch.item.transform.ItemTransformer)}.
* @throws Exception
*/
public void testSetDelegateReturnsList() throws Exception {
transformer.setDelegate(new ItemTransformer<Object, Collection<String>>() {
public Collection<String> transform(Object item) throws Exception {
return Collections.singletonList("bar");
}
});
// The result of the delegate is a list, which will simply be
// converted to a string by concatenating with "":
assertEquals("[bar]", transformer.transform(new Object()));
}
/**
* Test method for
* {@link org.springframework.batch.item.file.transform.RecursiveCollectionItemTransformer#transform(java.lang.Object)}.
* @throws Exception
*/
public void testTransformString() throws Exception {
assertEquals("foo", transformer.transform("foo"));
}
/**
* Test method for
* {@link org.springframework.batch.item.file.transform.RecursiveCollectionItemTransformer#transform(java.lang.Object)}.
* @throws Exception
*/
public void testTransformArray() throws Exception {
String result = (String) transformer.transform(StringUtils.commaDelimitedListToStringArray("foo,bar"));
String[] array = StringUtils.delimitedListToStringArray(result, LINE_SEPARATOR);
assertEquals("foo", array[0]);
assertEquals("bar", array[1]);
}
/**
* Test method for
* {@link org.springframework.batch.item.file.transform.RecursiveCollectionItemTransformer#transform(java.lang.Object)}.
* @throws Exception
*/
public void testTransformList() throws Exception {
String result = (String) transformer.transform(Arrays.asList(StringUtils.commaDelimitedListToStringArray("foo,bar")));
String result = aggregator.aggregate(Arrays.asList(StringUtils.commaDelimitedListToStringArray("foo,bar")));
String[] array = StringUtils.delimitedListToStringArray(result, LINE_SEPARATOR);
assertEquals("foo", array[0]);
assertEquals("bar", array[1]);
}
/**
* Test method for
* {@link org.springframework.batch.item.file.transform.RecursiveCollectionItemTransformer#transform(java.lang.Object)}.
* @throws Exception
*/
public void testTransformArrayOfArrays() throws Exception {
String[][] input = new String[][] { StringUtils.commaDelimitedListToStringArray("foo,bar"),
StringUtils.commaDelimitedListToStringArray("spam,bucket") };
String result = (String) transformer.transform(input);
String[] array = StringUtils.delimitedListToStringArray(result, LINE_SEPARATOR);
assertEquals(4,array.length);
assertEquals("foo", array[0]);
assertEquals("spam", array[2]);
}
}

View File

@@ -1,41 +0,0 @@
/*
* Copyright 2006-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.item.file.transform;
import org.springframework.batch.item.file.mapping.FieldSet;
/**
* Stub implementation of {@link LineAggregator} interface for testing purposes.
*
* @author robert.kasanicky
*/
public class StubLineAggregator implements LineAggregator {
/**
* Concatenates arguments.
*/
public String aggregate(FieldSet fieldSet) {
String result = "";
for (int i = 1; i < fieldSet.getFieldCount(); i++) {
result = result + fieldSet.readString(i);
}
return result;
}
}