Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
* @author Mahmoud Ben Hassine
* @author Drummond Dawson
* @author Stefano Cordio
* @author Hyunggeol Lee
* @since 4.0
* @see FlatFileItemWriter
*/
Expand Down Expand Up @@ -394,7 +395,11 @@ public FormatterLineAggregator<T> build() {

if (this.fieldExtractor == null) {
if (this.sourceType != null && this.sourceType.isRecord()) {
this.fieldExtractor = new RecordFieldExtractor<>(this.sourceType);
RecordFieldExtractor<T> recordFieldExtractor = new RecordFieldExtractor<>(this.sourceType);
if (!this.names.isEmpty()) {
recordFieldExtractor.setNames(this.names.toArray(new String[0]));
}
this.fieldExtractor = recordFieldExtractor;
}
else {
BeanWrapperFieldExtractor<T> beanWrapperFieldExtractor = new BeanWrapperFieldExtractor<>();
Expand Down Expand Up @@ -511,7 +516,11 @@ public DelimitedLineAggregator<T> build() {

if (this.fieldExtractor == null) {
if (this.sourceType != null && this.sourceType.isRecord()) {
this.fieldExtractor = new RecordFieldExtractor<>(this.sourceType);
RecordFieldExtractor<T> recordFieldExtractor = new RecordFieldExtractor<>(this.sourceType);
if (!this.names.isEmpty()) {
recordFieldExtractor.setNames(this.names.toArray(new String[0]));
}
this.fieldExtractor = recordFieldExtractor;
}
else {
BeanWrapperFieldExtractor<T> beanWrapperFieldExtractor = new BeanWrapperFieldExtractor<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2023 the original author or authors.
* Copyright 2016-2025 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 @@ -20,6 +20,7 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -48,6 +49,7 @@
* @author Mahmoud Ben Hassine
* @author Drummond Dawson
* @author Glenn Renfro
* @author Hyunggeol Lee
*/
class FlatFileItemWriterBuilderTests {

Expand Down Expand Up @@ -485,6 +487,191 @@ void testSetupFormatterLineAggregatorWithNoItemType() throws IOException {
assertInstanceOf(BeanWrapperFieldExtractor.class, fieldExtractor);
}

@Test
void testDelimitedWithRecordAndSelectedFields() throws IOException {
// given
WritableResource output = new FileSystemResource(File.createTempFile("delimited-selected", "csv"));
record Person(int id, String name, String email, int age) {
}

// when
FlatFileItemWriter<Person> writer = new FlatFileItemWriterBuilder<Person>().name("personWriter")
.resource(output)
.delimited()
.delimiter(",")
.sourceType(Person.class)
.names("name", "age")
.build();

// then
Object lineAggregator = ReflectionTestUtils.getField(writer, "lineAggregator");
assertNotNull(lineAggregator);
assertInstanceOf(DelimitedLineAggregator.class, lineAggregator);

Object fieldExtractor = ReflectionTestUtils.getField(lineAggregator, "fieldExtractor");
assertNotNull(fieldExtractor);
assertInstanceOf(RecordFieldExtractor.class, fieldExtractor);

Object names = ReflectionTestUtils.getField(fieldExtractor, "names");
assertEquals(Arrays.asList("name", "age"), names);
}

@Test
void testDelimitedWithRecordFieldReordering() throws IOException {
// given
WritableResource output = new FileSystemResource(File.createTempFile("delimited-reorder", "csv"));
record Employee(int id, String firstName, String lastName, String dept) {
}

// when
FlatFileItemWriter<Employee> writer = new FlatFileItemWriterBuilder<Employee>().name("employeeWriter")
.resource(output)
.delimited()
.delimiter("|")
.sourceType(Employee.class)
.names("lastName", "firstName", "id")
.build();

// then
Object lineAggregator = ReflectionTestUtils.getField(writer, "lineAggregator");
assertNotNull(lineAggregator);
assertInstanceOf(DelimitedLineAggregator.class, lineAggregator);

Object delimiter = ReflectionTestUtils.getField(lineAggregator, "delimiter");
assertEquals("|", delimiter);

Object fieldExtractor = ReflectionTestUtils.getField(lineAggregator, "fieldExtractor");
assertNotNull(fieldExtractor);
assertInstanceOf(RecordFieldExtractor.class, fieldExtractor);

Object names = ReflectionTestUtils.getField(fieldExtractor, "names");
assertEquals(Arrays.asList("lastName", "firstName", "id"), names);
}

@Test
void testDelimitedWithRecordAllFields() throws IOException {
// given
WritableResource output = new FileSystemResource(File.createTempFile("delimited-all", "csv"));
record Product(String code, String name, double price) {
}

// when
FlatFileItemWriter<Product> writer = new FlatFileItemWriterBuilder<Product>().name("productWriter")
.resource(output)
.delimited()
.sourceType(Product.class)
.names("code", "name", "price")
.build();

// then
Object lineAggregator = ReflectionTestUtils.getField(writer, "lineAggregator");
assertNotNull(lineAggregator);
assertInstanceOf(DelimitedLineAggregator.class, lineAggregator);

Object fieldExtractor = ReflectionTestUtils.getField(lineAggregator, "fieldExtractor");
assertNotNull(fieldExtractor);
assertInstanceOf(RecordFieldExtractor.class, fieldExtractor);

Object names = ReflectionTestUtils.getField(fieldExtractor, "names");
assertEquals(Arrays.asList("code", "name", "price"), names);
}

@Test
void testFormattedWithRecordAndSelectedFields() throws IOException {
// given
WritableResource output = new FileSystemResource(File.createTempFile("formatted-selected", "txt"));
record Person(int id, String name, String email) {
}

// when
FlatFileItemWriter<Person> writer = new FlatFileItemWriterBuilder<Person>().name("personWriter")
.resource(output)
.formatted()
.format("%-10s%3d")
.sourceType(Person.class)
.names("name", "id")
.build();

// then
Object lineAggregator = ReflectionTestUtils.getField(writer, "lineAggregator");
assertNotNull(lineAggregator);
assertInstanceOf(FormatterLineAggregator.class, lineAggregator);

Object format = ReflectionTestUtils.getField(lineAggregator, "format");
assertEquals("%-10s%3d", format);

Object fieldExtractor = ReflectionTestUtils.getField(lineAggregator, "fieldExtractor");
assertNotNull(fieldExtractor);
assertInstanceOf(RecordFieldExtractor.class, fieldExtractor);

Object names = ReflectionTestUtils.getField(fieldExtractor, "names");
assertEquals(Arrays.asList("name", "id"), names);
}

@Test
void testFormattedWithRecordFieldReordering() throws IOException {
// given
WritableResource output = new FileSystemResource(File.createTempFile("formatted-reorder", "txt"));
record Employee(int id, String firstName, String lastName, String dept) {
}

// when
FlatFileItemWriter<Employee> writer = new FlatFileItemWriterBuilder<Employee>().name("employeeWriter")
.resource(output)
.formatted()
.format("%-15s%-15s%5d")
.sourceType(Employee.class)
.names("lastName", "firstName", "id")
.build();

// then
Object lineAggregator = ReflectionTestUtils.getField(writer, "lineAggregator");
assertNotNull(lineAggregator);
assertInstanceOf(FormatterLineAggregator.class, lineAggregator);

Object format = ReflectionTestUtils.getField(lineAggregator, "format");
assertEquals("%-15s%-15s%5d", format);

Object fieldExtractor = ReflectionTestUtils.getField(lineAggregator, "fieldExtractor");
assertNotNull(fieldExtractor);
assertInstanceOf(RecordFieldExtractor.class, fieldExtractor);

Object names = ReflectionTestUtils.getField(fieldExtractor, "names");
assertEquals(Arrays.asList("lastName", "firstName", "id"), names);
}

@Test
void testFormattedWithRecordAllFields() throws IOException {
// given
WritableResource output = new FileSystemResource(File.createTempFile("formatted-all", "txt"));
record Product(String code, String name, double price) {
}

// when
FlatFileItemWriter<Product> writer = new FlatFileItemWriterBuilder<Product>().name("productWriter")
.resource(output)
.formatted()
.format("%-10s%-20s%10.2f")
.sourceType(Product.class)
.names("code", "name", "price")
.build();

// then
Object lineAggregator = ReflectionTestUtils.getField(writer, "lineAggregator");
assertNotNull(lineAggregator);
assertInstanceOf(FormatterLineAggregator.class, lineAggregator);

Object format = ReflectionTestUtils.getField(lineAggregator, "format");
assertEquals("%-10s%-20s%10.2f", format);

Object fieldExtractor = ReflectionTestUtils.getField(lineAggregator, "fieldExtractor");
assertNotNull(fieldExtractor);
assertInstanceOf(RecordFieldExtractor.class, fieldExtractor);

Object names = ReflectionTestUtils.getField(fieldExtractor, "names");
assertEquals(Arrays.asList("code", "name", "price"), names);
}

private void validateBuilderFlags(FlatFileItemWriter<Foo> writer, String encoding) {
assertFalse((Boolean) ReflectionTestUtils.getField(writer, "saveState"));
assertTrue((Boolean) ReflectionTestUtils.getField(writer, "append"));
Expand Down