diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/function/ConsumerItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/function/ConsumerItemWriter.java new file mode 100644 index 000000000..5095659bb --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/function/ConsumerItemWriter.java @@ -0,0 +1,49 @@ +/* + * Copyright 2024 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 + * + * https://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.item.function; + +import java.util.function.Consumer; + +import org.springframework.batch.item.Chunk; +import org.springframework.batch.item.ItemWriter; +import org.springframework.util.Assert; + +/** + * Adapter for a {@link Consumer} to an {@link ItemWriter}. + * + * @param type of items to write + * @author Mahmoud Ben Hassine + * @since 5.2 + */ +public class ConsumerItemWriter implements ItemWriter { + + private final Consumer consumer; + + /** + * Create a new {@link ConsumerItemWriter}. + * @param consumer the consumer to use to write items. Must not be {@code null}. + */ + public ConsumerItemWriter(Consumer consumer) { + Assert.notNull(consumer, "A consumer is required"); + this.consumer = consumer; + } + + @Override + public void write(Chunk items) throws Exception { + items.forEach(this.consumer); + } + +} \ No newline at end of file diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/function/PredicateFilteringItemProcessor.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/function/PredicateFilteringItemProcessor.java new file mode 100644 index 000000000..553c85a79 --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/function/PredicateFilteringItemProcessor.java @@ -0,0 +1,49 @@ +/* + * Copyright 2024 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 + * + * https://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.item.function; + +import java.util.function.Predicate; + +import org.springframework.batch.item.ItemProcessor; +import org.springframework.util.Assert; + +/** + * A filtering {@link ItemProcessor} that is based on a {@link Predicate}. Items for which + * the predicate returns {@code true} will be filtered. + * + * @param type of item to process + * @author Mahmoud Ben Hassine + * @since 5.2 + */ +public class PredicateFilteringItemProcessor implements ItemProcessor { + + private final Predicate predicate; + + /** + * Create a new {@link PredicateFilteringItemProcessor}. + * @param predicate the predicate to use to filter items. Must not be {@code null}. + */ + public PredicateFilteringItemProcessor(Predicate predicate) { + Assert.notNull(predicate, "A predicate is required"); + this.predicate = predicate; + } + + @Override + public T process(T item) throws Exception { + return this.predicate.test(item) ? null : item; + } + +} \ No newline at end of file diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/function/SupplierItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/function/SupplierItemReader.java new file mode 100644 index 000000000..48dd87e89 --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/function/SupplierItemReader.java @@ -0,0 +1,48 @@ +/* + * Copyright 2024 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 + * + * https://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.item.function; + +import java.util.function.Supplier; + +import org.springframework.batch.item.ItemReader; +import org.springframework.util.Assert; + +/** + * Adapter for a {@link Supplier} to an {@link ItemReader}. + * + * @param type of items to read + * @author Mahmoud Ben Hassine + * @since 5.2 + */ +public class SupplierItemReader implements ItemReader { + + private final Supplier supplier; + + /** + * Create a new {@link SupplierItemReader}. + * @param supplier the supplier to use to read items. Must not be {@code null}. + */ + public SupplierItemReader(Supplier supplier) { + Assert.notNull(supplier, "A supplier is required"); + this.supplier = supplier; + } + + @Override + public T read() throws Exception { + return this.supplier.get(); + } + +} \ No newline at end of file diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/function/ConsumerItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/function/ConsumerItemWriterTests.java new file mode 100644 index 000000000..4fef1da57 --- /dev/null +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/function/ConsumerItemWriterTests.java @@ -0,0 +1,57 @@ +/* + * Copyright 2024 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 + * + * https://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.item.function; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import org.springframework.batch.item.Chunk; + +/** + * Test class for {@link ConsumerItemWriter}. + * + * @author Mahmoud Ben Hassine + */ +class ConsumerItemWriterTests { + + private final List items = new ArrayList<>(); + + private final Consumer consumer = items::add; + + @Test + void testMandatoryConsumer() { + Assertions.assertThrows(IllegalArgumentException.class, () -> new ConsumerItemWriter(null), + "A consumer is required"); + } + + @Test + void testWrite() throws Exception { + // given + Chunk chunk = Chunk.of("foo", "bar"); + ConsumerItemWriter consumerItemWriter = new ConsumerItemWriter<>(this.consumer); + + // when + consumerItemWriter.write(chunk); + + // then + Assertions.assertIterableEquals(chunk, this.items); + } + +} \ No newline at end of file diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/function/PredicateFilteringItemProcessorTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/function/PredicateFilteringItemProcessorTests.java new file mode 100644 index 000000000..aa6b79d45 --- /dev/null +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/function/PredicateFilteringItemProcessorTests.java @@ -0,0 +1,49 @@ +/* + * Copyright 2024 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 + * + * https://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.item.function; + +import java.util.function.Predicate; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Test class for {@link PredicateFilteringItemProcessor}. + * + * @author Mahmoud Ben Hassine + */ +class PredicateFilteringItemProcessorTests { + + private final Predicate foos = item -> item.startsWith("foo"); + + @Test + void testMandatoryPredicate() { + Assertions.assertThrows(IllegalArgumentException.class, () -> new PredicateFilteringItemProcessor(null), + "A predicate is required"); + } + + @Test + void testProcess() throws Exception { + // given + PredicateFilteringItemProcessor processor = new PredicateFilteringItemProcessor<>(this.foos); + + // when & then + Assertions.assertNull(processor.process("foo1")); + Assertions.assertNull(processor.process("foo2")); + Assertions.assertEquals("bar", processor.process("bar")); + } + +} \ No newline at end of file diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/function/SupplierItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/function/SupplierItemReaderTests.java new file mode 100644 index 000000000..f7587661d --- /dev/null +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/function/SupplierItemReaderTests.java @@ -0,0 +1,56 @@ +/* + * Copyright 2024 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 + * + * https://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.item.function; + +import java.util.function.Supplier; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Test class for {@link SupplierItemReader}. + * + * @author Mahmoud Ben Hassine + */ +class SupplierItemReaderTests { + + private final Supplier supplier = new Supplier<>() { + private int count = 1; + + @Override + public String get() { + return count <= 2 ? "foo" + count++ : null; + } + }; + + @Test + void testMandatorySupplier() { + Assertions.assertThrows(IllegalArgumentException.class, () -> new SupplierItemReader(null), + "A supplier is required"); + } + + @Test + void testRead() throws Exception { + // given + SupplierItemReader supplierItemReader = new SupplierItemReader<>(supplier); + + // when & then + Assertions.assertEquals("foo1", supplierItemReader.read()); + Assertions.assertEquals("foo2", supplierItemReader.read()); + Assertions.assertNull(supplierItemReader.read()); + } + +} \ No newline at end of file