diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/CompositeItemProcessor.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/CompositeItemProcessor.java index c2ce4717b..6366ca0f2 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/CompositeItemProcessor.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/CompositeItemProcessor.java @@ -67,8 +67,14 @@ public class CompositeItemProcessor implements ItemProcessor, Initia Assert.notEmpty(delegates, "The 'delegates' may not be empty"); } + /** + * Establishes the {@link ItemProcessor} delegates that will work on the item to be + * processed. + * @param delegates list of {@link ItemProcessor} delegates that will work on the + * item. + */ public void setDelegates(List> delegates) { this.delegates = delegates; - } + } } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/builder/CompositeItemProcessorBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/builder/CompositeItemProcessorBuilder.java new file mode 100644 index 000000000..f0578e640 --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/builder/CompositeItemProcessorBuilder.java @@ -0,0 +1,60 @@ +/* + * Copyright 2017 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.item.support.builder; + +import java.util.List; + +import org.springframework.batch.item.ItemProcessor; +import org.springframework.batch.item.support.CompositeItemProcessor; +import org.springframework.util.Assert; + +/** + * Creates a fully qualified {@link CompositeItemProcessorBuilder}. + * + * @author Glenn Renfro + * + * @since 4.0 + */ +public class CompositeItemProcessorBuilder { + private List> delegates; + + /** + * Establishes the {@link ItemProcessor} delegates that will work on the item to be processed. + * @param delegates list of {@link ItemProcessor} delegates that will work on the item. + * @return this instance for method chaining. + * @see CompositeItemProcessor#setDelegates(List) + */ + public CompositeItemProcessorBuilder delegates(List> delegates) { + this.delegates = delegates; + + return this; + } + + /** + * Returns a fully constructed {@link CompositeItemProcessor}. + * + * @return a new {@link CompositeItemProcessor} + */ + public CompositeItemProcessor build() { + Assert.notNull(delegates, "A list of delegates is required."); + Assert.notEmpty(delegates, "The delegates list must have one or more delegates."); + + CompositeItemProcessor processor = new CompositeItemProcessor<>(); + processor.setDelegates(this.delegates); + return processor; + } +} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/builder/CompositeItemProcessorBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/builder/CompositeItemProcessorBuilderTests.java new file mode 100644 index 000000000..9b2c49518 --- /dev/null +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/builder/CompositeItemProcessorBuilderTests.java @@ -0,0 +1,89 @@ +/* + * Copyright 2017 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.item.support.builder; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import org.springframework.batch.item.ItemProcessor; +import org.springframework.batch.item.support.CompositeItemProcessor; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.when; + +/** + * @author Glenn Renfro + */ +public class CompositeItemProcessorBuilderTests { + + @Mock + private ItemProcessor processor1; + + @Mock + private ItemProcessor processor2; + + private List> processors; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + + this.processors = new ArrayList<>(); + this.processors.add(processor1); + this.processors.add(processor2); + } + + @Test + public void testTransform() throws Exception { + Object item = new Object(); + Object itemAfterFirstTransfromation = new Object(); + Object itemAfterSecondTransformation = new Object(); + CompositeItemProcessor composite = new CompositeItemProcessorBuilder<>() + .delegates(this.processors).build(); + + when(processor1.process(item)).thenReturn(itemAfterFirstTransfromation); + when(processor2.process(itemAfterFirstTransfromation)).thenReturn(itemAfterSecondTransformation); + + assertSame(itemAfterSecondTransformation, composite.process(item)); + } + + @Test + public void testNullOrEmptyDelegates() throws Exception { + validateExceptionMessage(new CompositeItemProcessorBuilder<>().delegates(new ArrayList<>()), + "The delegates list must have one or more delegates."); + validateExceptionMessage(new CompositeItemProcessorBuilder<>(), + "A list of delegates is required."); + } + + private void validateExceptionMessage(CompositeItemProcessorBuilder builder, String message) { + try { + builder.build(); + fail("IllegalArgumentException should have been thrown"); + } + catch (IllegalArgumentException iae) { + assertEquals("IllegalArgumentException message did not match the expected result.", message, + iae.getMessage()); + } + } +}