OPEN - issue BATCH-371: FlatFileItemWriter no longer uses LineAggregator

http://jira.springframework.org/browse/BATCH-371

Moved existing default transformer out to a top level class, and introduce lineAggregatorItemTransformer as an option.  I still don't see a good way to get a String[] in to it reliably.
This commit is contained in:
dsyer
2008-02-19 21:40:44 +00:00
parent 10d4632dcb
commit 91a9e94590
5 changed files with 207 additions and 124 deletions

View File

@@ -24,12 +24,11 @@ import java.io.IOException;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.charset.UnsupportedCharsetException;
import java.util.Collection;
import java.util.Iterator;
import java.util.Properties;
import org.springframework.batch.io.exception.BatchCriticalException;
import org.springframework.batch.io.exception.BatchEnvironmentException;
import org.springframework.batch.io.file.transform.RecursiveCollectionItemTransformer;
import org.springframework.batch.io.support.AbstractTransactionalIoSource;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStream;
@@ -75,15 +74,7 @@ public class FlatFileItemWriter extends AbstractTransactionalIoSource implements
private OutputState state = null;
private ItemTransformer transformer = new ItemTransformer() {
public Object transform(Object input) {
return "" + input;
}
};
private static class BooleanHolder {
public boolean value;
}
private ItemTransformer transformer = new RecursiveCollectionItemTransformer();
/**
* Assert that mandatory properties (resource) are set.
@@ -128,51 +119,7 @@ public class FlatFileItemWriter extends AbstractTransactionalIoSource implements
* @throws Exception if the transformer or file output fail
*/
public void write(Object data) throws Exception {
transformAndWrite(data, new BooleanHolder());
}
/**
* Convert the date to a format that can be output and then write it out.
* @param data
* @param converted
* @throws Exception
*/
private void transformAndWrite(Object data, BooleanHolder converted) throws Exception {
if (data instanceof Collection) {
converted.value = false;
for (Iterator iterator = ((Collection) data).iterator(); iterator.hasNext();) {
Object value = (Object) iterator.next();
// (recursive)
write(value);
}
return;
}
if (data.getClass().isArray()) {
converted.value = false;
Object[] array = (Object[]) data;
for (int i = 0; i < array.length; i++) {
Object value = array[i];
// (recursive)
write(value);
}
return;
}
if (data instanceof String) {
// This is where the output stream is actually written to
getOutputState().write(data + LINE_SEPARATOR);
}
else if (!converted.value) {
// (recursive)
converted.value = true;
transformAndWrite(transformer.transform(data), converted);
return;
}
else {
// Should not happen...
throw new IllegalStateException(
"Infinite loop detected - converter did not convert to String or collection/array of objects convertible to String.");
}
getOutputState().write(transformer.transform(data) + LINE_SEPARATOR);
}
/**

View File

@@ -0,0 +1,48 @@
/*
* 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.io.file.transform;
import org.springframework.batch.item.writer.ItemTransformer;
/**
* An {@link ItemTransformer} that expects a String[] as input and delegates to
* a {@link LineAggregator}.
*
* @author Dave Syer
*
*/
public class LineAggregatorItemTransformer implements ItemTransformer {
private LineAggregator aggregator = new DelimitedLineAggregator();
/**
* Public setter for the {@link LineAggregator}.
* @param aggregator the aggregator to set
*/
public void setAggregator(LineAggregator aggregator) {
this.aggregator = aggregator;
}
/**
* Assume the item is an array of String (no check is made) and delegate to
* the aggregator.
*
* @see org.springframework.batch.item.writer.ItemTransformer#transform(java.lang.Object)
*/
public Object transform(Object item) throws Exception {
return aggregator.aggregate((String[]) item);
}
}

View File

@@ -0,0 +1,91 @@
package org.springframework.batch.io.file.transform;
import java.util.Collection;
import java.util.Iterator;
import org.springframework.batch.item.writer.ItemTransformer;
/**
* An implementation of {@link ItemTransformer} that just calls toString() on
* its argument, unless it it an array or collection, in which case it loops
* though, calling itself on each member in turn, concatenating the result with
* line separators.
*
* @author Dave Syer
*
*/
public class RecursiveCollectionItemTransformer implements ItemTransformer {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
/* (non-Javadoc)
* @see org.springframework.batch.item.writer.ItemTransformer#transform(java.lang.Object)
*/
public Object transform(Object input) {
TransformHolder holder = new TransformHolder();
transformRecursively(input, holder);
String result = holder.builder.toString();
return result.substring(0, result.lastIndexOf(LINE_SEPARATOR));
}
public String stringify(Object input) {
return "" + input;
}
/**
* Convert the date to a format that can be output and then write it out.
* @param data
* @param converted
* @throws Exception
*/
private void transformRecursively(Object data, TransformHolder converted) {
if (data instanceof Collection) {
converted.value = false;
for (Iterator iterator = ((Collection) data).iterator(); iterator.hasNext();) {
Object value = (Object) iterator.next();
// (recursive)
transformRecursively(value, new TransformHolder(converted.builder));
}
return;
}
if (data.getClass().isArray()) {
converted.value = false;
Object[] array = (Object[]) data;
for (int i = 0; i < array.length; i++) {
Object value = array[i];
// (recursive)
transformRecursively(value, new TransformHolder(converted.builder));
}
return;
}
if (data instanceof String) {
// This is where the output stream is actually written to
converted.builder.append(data + LINE_SEPARATOR);
}
else if (!converted.value) {
// (recursive)
converted.value = true;
transformRecursively(stringify(data), converted);
return;
}
else {
// Should not happen...
throw new IllegalStateException(
"Infinite loop detected - converter did not convert to String or collection/array of objects convertible to String.");
}
}
private static class TransformHolder {
boolean value;
StringBuilder builder = new StringBuilder();
TransformHolder() {
}
TransformHolder(StringBuilder builder) {
this.builder = builder;
}
}
}