Skip to content

Commit 6859951

Browse files
committed
Add mapping adapter to ItemWriter
Signed-off-by: Stefano Cordio <stefano.cordio@gmail.com>
1 parent 73fbca8 commit 6859951

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemWriter.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.batch.item;
1818

19+
import java.util.function.Function;
20+
1921
import org.springframework.lang.NonNull;
2022

2123
/**
@@ -37,6 +39,7 @@
3739
* @author Lucas Ward
3840
* @author Taeik Lim
3941
* @author Mahmoud Ben Hassine
42+
* @author Stefano Cordio
4043
*/
4144
@FunctionalInterface
4245
public interface ItemWriter<T> {
@@ -50,4 +53,27 @@ public interface ItemWriter<T> {
5053
*/
5154
void write(@NonNull Chunk<? extends T> chunk) throws Exception;
5255

56+
/**
57+
* Adapts an {@code ItemWriter} accepting items of type {@link U} to one accepting
58+
* items of type {@link T} by applying a mapping function to each item before writing.
59+
* <p>
60+
* The {@code mapping()} item writers are most useful when used in combination with a
61+
* {@link org.springframework.batch.item.support.CompositeItemWriter}, where the
62+
* mapping function in front of the downstream writer can be a getter of the input
63+
* item or a more complex transformation logic.
64+
* <p>
65+
* This adapter mimics the behavior of
66+
* {@link java.util.stream.Collectors#mapping(Function, java.util.stream.Collector)}.
67+
* @param <T> the type of the input items
68+
* @param <U> type of items accepted by downstream item writer
69+
* @param mapper a function to be applied to the input items
70+
* @param downstream an item writer which will accept mapped items
71+
* @return an item writer which applies the mapping function to the input items and
72+
* provides the mapped results to the downstream item writer
73+
* @since 6.0
74+
*/
75+
static <T, U> ItemWriter<T> mapping(Function<? super T, ? extends U> mapper, ItemWriter<? super U> downstream) {
76+
return chunk -> downstream.write(new Chunk<>(chunk.getItems().stream().map(mapper).toList()));
77+
}
78+
5379
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2006-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.batch.item;
18+
19+
import org.junit.jupiter.api.Test;
20+
import org.springframework.batch.item.support.CompositeItemWriter;
21+
import org.springframework.batch.item.support.ListItemWriter;
22+
23+
import java.util.List;
24+
25+
import static org.assertj.core.api.Assertions.assertThat;
26+
import static org.springframework.batch.item.ItemWriter.mapping;
27+
28+
class ItemWriterIntegrationTests {
29+
30+
@Test
31+
void testMappingWithCompositeItemWriter() throws Exception {
32+
ListItemWriter<String> nameItemWriter = new ListItemWriter<>();
33+
ListItemWriter<Integer> ageItemWriter = new ListItemWriter<>();
34+
35+
record Person(String name, int age) {
36+
}
37+
38+
ItemWriter<Person> personItemWriter = new CompositeItemWriter<>(List.of( //
39+
mapping(Person::name, nameItemWriter), //
40+
mapping(Person::age, ageItemWriter)));
41+
42+
personItemWriter.write(Chunk.of(new Person("Foo", 42), new Person("Bar", 24)));
43+
personItemWriter.write(Chunk.of(new Person("Baz", 21), new Person("Qux", 12)));
44+
45+
assertThat(nameItemWriter.getWrittenItems()).containsExactly("Foo", "Bar", "Baz", "Qux");
46+
assertThat(ageItemWriter.getWrittenItems()).containsExactly(42, 24, 21, 12);
47+
}
48+
49+
}

0 commit comments

Comments
 (0)