001/*
002 * Copyright 2002-2013 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.lang.annotation.Annotation;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import org.springframework.batch.core.ChunkListener;
024import org.springframework.batch.core.ItemProcessListener;
025import org.springframework.batch.core.ItemReadListener;
026import org.springframework.batch.core.ItemWriteListener;
027import org.springframework.batch.core.SkipListener;
028import org.springframework.batch.core.StepExecution;
029import org.springframework.batch.core.StepExecutionListener;
030import org.springframework.batch.core.StepListener;
031import org.springframework.batch.core.annotation.AfterChunk;
032import org.springframework.batch.core.annotation.AfterChunkError;
033import org.springframework.batch.core.annotation.AfterProcess;
034import org.springframework.batch.core.annotation.AfterRead;
035import org.springframework.batch.core.annotation.AfterStep;
036import org.springframework.batch.core.annotation.AfterWrite;
037import org.springframework.batch.core.annotation.BeforeChunk;
038import org.springframework.batch.core.annotation.BeforeProcess;
039import org.springframework.batch.core.annotation.BeforeRead;
040import org.springframework.batch.core.annotation.BeforeStep;
041import org.springframework.batch.core.annotation.BeforeWrite;
042import org.springframework.batch.core.annotation.OnProcessError;
043import org.springframework.batch.core.annotation.OnReadError;
044import org.springframework.batch.core.annotation.OnSkipInProcess;
045import org.springframework.batch.core.annotation.OnSkipInRead;
046import org.springframework.batch.core.annotation.OnSkipInWrite;
047import org.springframework.batch.core.annotation.OnWriteError;
048import org.springframework.batch.core.scope.context.ChunkContext;
049
050/**
051 * Enumeration for {@link StepListener} meta data, which ties together the names
052 * of methods, their interfaces, annotation, and expected arguments.
053 *
054 * @author Lucas Ward
055 * @since 2.0
056 * @see StepListenerFactoryBean
057 */
058public enum StepListenerMetaData implements ListenerMetaData {
059
060        BEFORE_STEP("beforeStep", "before-step-method", BeforeStep.class, StepExecutionListener.class, StepExecution.class),
061        AFTER_STEP("afterStep", "after-step-method", AfterStep.class, StepExecutionListener.class, StepExecution.class),
062        BEFORE_CHUNK("beforeChunk", "before-chunk-method", BeforeChunk.class, ChunkListener.class, ChunkContext.class),
063        AFTER_CHUNK("afterChunk", "after-chunk-method", AfterChunk.class, ChunkListener.class, ChunkContext.class),
064        AFTER_CHUNK_ERROR("afterChunkError", "after-chunk-error-method", AfterChunkError.class, ChunkListener.class, ChunkContext.class),
065        BEFORE_READ("beforeRead", "before-read-method", BeforeRead.class, ItemReadListener.class),
066        AFTER_READ("afterRead", "after-read-method", AfterRead.class, ItemReadListener.class, Object.class),
067        ON_READ_ERROR("onReadError", "on-read-error-method", OnReadError.class, ItemReadListener.class, Exception.class),
068        BEFORE_PROCESS("beforeProcess", "before-process-method", BeforeProcess.class, ItemProcessListener.class, Object.class),
069        AFTER_PROCESS("afterProcess", "after-process-method", AfterProcess.class, ItemProcessListener.class, Object.class, Object.class),
070        ON_PROCESS_ERROR("onProcessError", "on-process-error-method", OnProcessError.class, ItemProcessListener.class, Object.class, Exception.class),
071        BEFORE_WRITE("beforeWrite", "before-write-method", BeforeWrite.class, ItemWriteListener.class, List.class),
072        AFTER_WRITE("afterWrite", "after-write-method", AfterWrite.class, ItemWriteListener.class, List.class),
073        ON_WRITE_ERROR("onWriteError", "on-write-error-method", OnWriteError.class, ItemWriteListener.class, Exception.class, List.class),
074        ON_SKIP_IN_READ("onSkipInRead", "on-skip-in-read-method", OnSkipInRead.class, SkipListener.class, Throwable.class),
075        ON_SKIP_IN_PROCESS("onSkipInProcess", "on-skip-in-process-method", OnSkipInProcess.class, SkipListener.class, Object.class, Throwable.class),
076        ON_SKIP_IN_WRITE("onSkipInWrite", "on-skip-in-write-method", OnSkipInWrite.class, SkipListener.class, Object.class, Throwable.class);
077
078        private final String methodName;
079        private final String propertyName;
080        private final Class<? extends Annotation> annotation;
081        private final Class<? extends StepListener> listenerInterface;
082        private final Class<?>[] paramTypes;
083        private static final Map<String, StepListenerMetaData> propertyMap;
084
085        StepListenerMetaData(String methodName, String propertyName, Class<? extends Annotation> annotation, Class<? extends StepListener> listenerInterface, Class<?>... paramTypes) {
086                this.methodName = methodName;
087                this.propertyName = propertyName;
088                this.annotation = annotation;
089                this.listenerInterface = listenerInterface;
090                this.paramTypes = paramTypes;
091        }
092
093        static{
094                propertyMap = new HashMap<>();
095                for(StepListenerMetaData metaData : values()){
096                        propertyMap.put(metaData.getPropertyName(), metaData);
097                }
098        }
099
100        @Override
101        public String getMethodName() {
102                return methodName;
103        }
104
105        @Override
106        public Class<? extends Annotation> getAnnotation() {
107                return annotation;
108        }
109
110        @Override
111        public Class<?> getListenerInterface() {
112                return listenerInterface;
113        }
114
115        @Override
116        public Class<?>[] getParamTypes() {
117                return paramTypes;
118        }
119
120        @Override
121        public String getPropertyName() {
122                return propertyName;
123        }
124
125        /**
126         * Return the relevant meta data for the provided property name.
127         *
128         * @param propertyName property name to retrieve data for.
129         * @return meta data with supplied property name, null if none exists.
130         */
131        public static StepListenerMetaData fromPropertyName(String propertyName){
132                return propertyMap.get(propertyName);
133        }
134
135        public static ListenerMetaData[] itemListenerMetaData() {
136                return new ListenerMetaData[] {BEFORE_WRITE, AFTER_WRITE, ON_WRITE_ERROR, BEFORE_PROCESS, AFTER_PROCESS, ON_PROCESS_ERROR, BEFORE_READ, AFTER_READ, ON_READ_ERROR, ON_SKIP_IN_WRITE, ON_SKIP_IN_PROCESS, ON_SKIP_IN_READ};
137        }
138
139        public static ListenerMetaData[] stepExecutionListenerMetaData() {
140                return new ListenerMetaData[] {BEFORE_STEP, AFTER_STEP};
141        }
142
143        public static ListenerMetaData[] taskletListenerMetaData() {
144                return new ListenerMetaData[] {BEFORE_CHUNK, AFTER_CHUNK, AFTER_CHUNK_ERROR};
145        }
146
147}