001/*
002 * Copyright 2006-2018 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 */
016package org.springframework.batch.core.listener;
017
018import java.util.Iterator;
019import java.util.List;
020
021import org.springframework.batch.core.ItemProcessListener;
022import org.springframework.core.Ordered;
023import org.springframework.lang.Nullable;
024
025/**
026 * @author Dave Syer
027 * @author Mahmoud Ben Hassine
028 *
029 */
030public class CompositeItemProcessListener<T, S> implements ItemProcessListener<T, S> {
031
032        private OrderedComposite<ItemProcessListener<? super T, ? super S>> listeners = new OrderedComposite<ItemProcessListener<? super T, ? super S>>();
033
034        /**
035         * Public setter for the listeners.
036         *
037         * @param itemProcessorListeners list of {@link ItemProcessListener}s to be called when process events occur.
038         */
039        public void setListeners(List<? extends ItemProcessListener<? super T, ? super S>> itemProcessorListeners) {
040                this.listeners.setItems(itemProcessorListeners);
041        }
042
043        /**
044         * Register additional listener.
045         *
046         * @param itemProcessorListener instance  of {@link ItemProcessListener} to be registered.
047         */
048        public void register(ItemProcessListener<? super T, ? super S> itemProcessorListener) {
049                listeners.add(itemProcessorListener);
050        }
051
052        /**
053         * Call the registered listeners in reverse order, respecting and
054         * prioritising those that implement {@link Ordered}.
055         * @see org.springframework.batch.core.ItemProcessListener#afterProcess(java.lang.Object,
056         * java.lang.Object)
057         */
058        @Override
059        public void afterProcess(T item, @Nullable S result) {
060                for (Iterator<ItemProcessListener<? super T, ? super S>> iterator = listeners.reverse(); iterator.hasNext();) {
061                        ItemProcessListener<? super T, ? super S> listener = iterator.next();
062                        listener.afterProcess(item, result);
063                }
064        }
065
066        /**
067         * Call the registered listeners in order, respecting and prioritising those
068         * that implement {@link Ordered}.
069         * @see org.springframework.batch.core.ItemProcessListener#beforeProcess(java.lang.Object)
070         */
071        @Override
072        public void beforeProcess(T item) {
073                for (Iterator<ItemProcessListener<? super T, ? super S>> iterator = listeners.iterator(); iterator.hasNext();) {
074                        ItemProcessListener<? super T, ? super S> listener = iterator.next();
075                        listener.beforeProcess(item);
076                }
077        }
078
079        /**
080         * Call the registered listeners in reverse order, respecting and
081         * prioritising those that implement {@link Ordered}.
082         * @see org.springframework.batch.core.ItemProcessListener#onProcessError(java.lang.Object,
083         * java.lang.Exception)
084         */
085        @Override
086        public void onProcessError(T item, Exception e) {
087                for (Iterator<ItemProcessListener<? super T, ? super S>> iterator = listeners.reverse(); iterator.hasNext();) {
088                        ItemProcessListener<? super T, ? super S> listener = iterator.next();
089                        listener.onProcessError(item, e);
090                }
091        }
092
093}