Skip to content

Commit

Permalink
Add support for quotes in DelimitedLineAggregator
Browse files Browse the repository at this point in the history
Resolves #1139
  • Loading branch information
cppwfs authored and fmbenhassine committed Sep 15, 2023
1 parent 4444e46 commit cc233e6
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.springframework.batch.item.file.transform.RecordFieldExtractor;
import org.springframework.core.io.WritableResource;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
* A builder implementation for the {@link FlatFileItemWriter}
Expand Down Expand Up @@ -424,6 +425,8 @@ public static class DelimitedBuilder<T> {

private String delimiter = ",";

private String quoteCharacter = "";

private FieldExtractor<T> fieldExtractor;

private Class<T> sourceType;
Expand Down Expand Up @@ -457,6 +460,17 @@ public DelimitedBuilder<T> sourceType(Class<T> sourceType) {
return this;
}

/**
* Define the quote character for each delimited field. Default is empty string.
* @param quoteCharacter String used as a quote for the aggregate.
* @return The instance of the builder for chaining.
* @see DelimitedLineAggregator#setQuoteCharacter(String)
*/
public DelimitedBuilder<T> quoteCharacter(String quoteCharacter) {
this.quoteCharacter = quoteCharacter;
return this;
}

/**
* Names of each of the fields within the fields that are returned in the order
* they occur within the delimited file. These names will be used to create a
Expand Down Expand Up @@ -489,6 +503,9 @@ public DelimitedLineAggregator<T> build() {
if (this.delimiter != null) {
delimitedLineAggregator.setDelimiter(this.delimiter);
}
if (StringUtils.hasLength(this.quoteCharacter)) {
delimitedLineAggregator.setQuoteCharacter(this.quoteCharacter);
}

if (this.fieldExtractor == null) {
if (this.sourceType != null && this.sourceType.isRecord()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2007 the original author or authors.
* Copyright 2006-2023 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.
Expand All @@ -15,19 +15,24 @@
*/
package org.springframework.batch.item.file.transform;

import org.springframework.util.StringUtils;
import java.util.Arrays;
import java.util.stream.Collectors;

/**
* A {@link LineAggregator} implementation that converts an object into a delimited list
* of strings. The default delimiter is a comma.
* of strings. The default delimiter is a comma. An optional quote value can be set to add
* surrounding quotes for each element of the list. Default is empty string, which means
* not quotes.
*
* @author Dave Syer
*
* @author Glenn Renfro
*/
public class DelimitedLineAggregator<T> extends ExtractorLineAggregator<T> {

private String delimiter = ",";

private String quoteCharacter = "";

/**
* Public setter for the delimiter.
* @param delimiter the delimiter to set
Expand All @@ -36,9 +41,20 @@ public void setDelimiter(String delimiter) {
this.delimiter = delimiter;
}

/**
* Setter for the quote character.
* @since 5.1
* @param quoteCharacter the quote character to set
*/
public void setQuoteCharacter(String quoteCharacter) {
this.quoteCharacter = quoteCharacter;
}

@Override
public String doAggregate(Object[] fields) {
return StringUtils.arrayToDelimitedString(fields, this.delimiter);
return Arrays.stream(fields)
.map(field -> this.quoteCharacter + field + this.quoteCharacter)
.collect(Collectors.joining(this.delimiter));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,34 @@ void testDelimitedOutputWithEmptyDelimiter() throws Exception {
assertEquals("HEADER$123$456$FOOTER", readLine("UTF-16LE", output));
}

@Test
public void testDelimitedOutputWithEmptyDelimiterAndQuote() throws Exception {

FileSystemResource output = new FileSystemResource(File.createTempFile("foo", "txt"));

FlatFileItemWriter<Foo> writer = new FlatFileItemWriterBuilder<Foo>().name("foo")
.resource(output)
.lineSeparator("$")
.delimited()
.delimiter("")
.quoteCharacter("%")
.names("first", "second", "third")
.encoding("UTF-16LE")
.headerCallback(writer1 -> writer1.append("HEADER"))
.footerCallback(writer12 -> writer12.append("FOOTER"))
.build();

ExecutionContext executionContext = new ExecutionContext();

writer.open(executionContext);

writer.write(new Chunk<>(new Foo(1, 2, "3"), new Foo(4, 5, "6")));

writer.close();

assertEquals("HEADER$%1%%2%%3%$%4%%5%%6%$FOOTER", readLine("UTF-16LE", output));
}

@Test
void testDelimitedOutputWithDefaultFieldExtractor() throws Exception {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2022 the original author or authors.
* Copyright 2006-2023 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.
Expand All @@ -22,6 +22,7 @@

/**
* @author Dave Syer
* @author Glenn Renfro
*
*/
class DelimitedLineAggregatorTests {
Expand All @@ -40,6 +41,13 @@ void testSetDelimiter() {
assertEquals("foo;bar", aggregator.aggregate(new String[] { "foo", "bar" }));
}

@Test
public void testSetDelimiterAndQuote() {
aggregator.setDelimiter(";");
aggregator.setQuoteCharacter("\"");
assertEquals("\"foo\";\"bar\"", aggregator.aggregate(new String[] { "foo", "bar" }));
}

@Test
void testAggregate() {
assertEquals("foo,bar", aggregator.aggregate(new String[] { "foo", "bar" }));
Expand Down

0 comments on commit cc233e6

Please sign in to comment.