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:
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user