001/* 002 * Copyright 2006-2007 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.batch.item.support; 018 019import org.springframework.batch.item.ItemProcessor; 020import org.springframework.beans.factory.InitializingBean; 021import org.springframework.util.Assert; 022 023import java.util.List; 024 025/** 026 * Composite {@link ItemProcessor} that passes the item through a sequence of 027 * injected <code>ItemTransformer</code>s (return value of previous 028 * transformation is the entry value of the next).<br> 029 * <br> 030 * 031 * Note the user is responsible for injecting a chain of {@link ItemProcessor}s 032 * that conforms to declared input and output types. 033 * 034 * @author Robert Kasanicky 035 */ 036public class CompositeItemProcessor<I, O> implements ItemProcessor<I, O>, InitializingBean { 037 038 private List<? extends ItemProcessor<?, ?>> delegates; 039 040 @Override 041 @SuppressWarnings("unchecked") 042 public O process(I item) throws Exception { 043 Object result = item; 044 045 for (ItemProcessor<?, ?> delegate : delegates) { 046 if (result == null) { 047 return null; 048 } 049 050 result = processItem(delegate, result); 051 } 052 return (O) result; 053 } 054 055 /* 056 * Helper method to work around wildcard capture compiler error: see https://docs.oracle.com/javase/tutorial/java/generics/capture.html 057 * The method process(capture#1-of ?) in the type ItemProcessor<capture#1-of ?,capture#2-of ?> is not applicable for the arguments (Object) 058 */ 059 @SuppressWarnings("unchecked") 060 private <T> Object processItem(ItemProcessor<T, ?> processor, Object input) throws Exception { 061 return processor.process((T) input); 062 } 063 064 @Override 065 public void afterPropertiesSet() throws Exception { 066 Assert.notNull(delegates, "The 'delegates' may not be null"); 067 Assert.notEmpty(delegates, "The 'delegates' may not be empty"); 068 } 069 070 /** 071 * Establishes the {@link ItemProcessor} delegates that will work on the item to be 072 * processed. 073 * @param delegates list of {@link ItemProcessor} delegates that will work on the 074 * item. 075 */ 076 public void setDelegates(List<? extends ItemProcessor<?, ?>> delegates) { 077 this.delegates = delegates; 078 } 079 080}