001/*
002 * Copyright 2006-2011 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.job.builder;
017
018import java.util.ArrayList;
019import java.util.LinkedHashSet;
020import java.util.List;
021import java.util.Set;
022
023import org.apache.commons.logging.Log;
024import org.apache.commons.logging.LogFactory;
025import org.springframework.batch.core.Job;
026import org.springframework.batch.core.JobExecutionListener;
027import org.springframework.batch.core.JobParametersIncrementer;
028import org.springframework.batch.core.JobParametersValidator;
029import org.springframework.batch.core.job.AbstractJob;
030import org.springframework.batch.core.repository.JobRepository;
031
032/**
033 * A base class and utility for other job builders providing access to common properties like job repository.
034 * 
035 * @author Dave Syer
036 * 
037 * @since 2.2
038 */
039public abstract class JobBuilderHelper<B extends JobBuilderHelper<B>> {
040
041        protected final Log logger = LogFactory.getLog(getClass());
042
043        private final CommonJobProperties properties;
044
045        public JobBuilderHelper(String name) {
046                this.properties = new CommonJobProperties();
047                properties.name = name;
048        }
049
050        /**
051         * Create a new builder initialized with any properties in the parent. The parent is copied, so it can be re-used.
052         * 
053         * @param parent a parent helper containing common step properties
054         */
055        protected JobBuilderHelper(JobBuilderHelper<?> parent) {
056                this.properties = new CommonJobProperties(parent.properties);
057        }
058
059        /**
060         * Add a job parameters validator.
061         * 
062         * @param jobParametersValidator a job parameters validator
063         * @return this to enable fluent chaining
064         */
065        public B validator(JobParametersValidator jobParametersValidator) {
066                properties.jobParametersValidator = jobParametersValidator;
067                @SuppressWarnings("unchecked")
068                B result = (B) this;
069                return result;
070        }
071
072        /**
073         * Add a job parameters incrementer.
074         * 
075         * @param jobParametersIncrementer a job parameters incrementer
076         * @return this to enable fluent chaining
077         */
078        public B incrementer(JobParametersIncrementer jobParametersIncrementer) {
079                properties.jobParametersIncrementer = jobParametersIncrementer;
080                @SuppressWarnings("unchecked")
081                B result = (B) this;
082                return result;
083        }
084
085        /**
086         * Sets the job repository for the job.
087         * 
088         * @param jobRepository the job repository (mandatory)
089         * @return this to enable fluent chaining
090         */
091        public B repository(JobRepository jobRepository) {
092                properties.jobRepository = jobRepository;
093                @SuppressWarnings("unchecked")
094                B result = (B) this;
095                return result;
096        }
097
098        /**
099         * Register a job execution listener.
100         * 
101         * @param listener a job execution listener
102         * @return this to enable fluent chaining
103         */
104        public B listener(JobExecutionListener listener) {
105                properties.addJobExecutionListener(listener);
106                @SuppressWarnings("unchecked")
107                B result = (B) this;
108                return result;
109        }
110
111        /**
112         * Set a flag to prevent restart an execution of this job even if it has failed.
113         * 
114         * @return this to enable fluent chaining
115         */
116        public B preventRestart() {
117                properties.restartable = false;
118                @SuppressWarnings("unchecked")
119                B result = (B) this;
120                return result;
121        }
122
123        protected String getName() {
124                return properties.name;
125        }
126
127        protected JobRepository getJobRepository() {
128                return properties.jobRepository;
129        }
130
131        protected boolean isRestartable() {
132                return properties.restartable;
133        }
134
135        protected void enhance(Job target) {
136
137                if (target instanceof AbstractJob) {
138
139                        AbstractJob job = (AbstractJob) target;
140                        job.setJobRepository(properties.getJobRepository());
141
142                        JobParametersIncrementer jobParametersIncrementer = properties.getJobParametersIncrementer();
143                        if (jobParametersIncrementer != null) {
144                                job.setJobParametersIncrementer(jobParametersIncrementer);
145                        }
146                        JobParametersValidator jobParametersValidator = properties.getJobParametersValidator();
147                        if (jobParametersValidator != null) {
148                                job.setJobParametersValidator(jobParametersValidator);
149                        }
150
151                        Boolean restartable = properties.getRestartable();
152                        if (restartable != null) {
153                                job.setRestartable(restartable);
154                        }
155
156                        List<JobExecutionListener> listeners = properties.getJobExecutionListeners();
157                        if (!listeners.isEmpty()) {
158                                job.setJobExecutionListeners(listeners.toArray(new JobExecutionListener[0]));
159                        }
160
161                }
162
163        }
164
165        public static class CommonJobProperties {
166
167                private Set<JobExecutionListener> jobExecutionListeners = new LinkedHashSet<JobExecutionListener>();
168
169                private boolean restartable = true;
170
171                private JobRepository jobRepository;
172
173                private JobParametersIncrementer jobParametersIncrementer;
174
175                private JobParametersValidator jobParametersValidator;
176
177                public CommonJobProperties() {
178                }
179
180                public CommonJobProperties(CommonJobProperties properties) {
181                        this.name = properties.name;
182                        this.restartable = properties.restartable;
183                        this.jobRepository = properties.jobRepository;
184                        this.jobExecutionListeners = new LinkedHashSet<JobExecutionListener>(properties.jobExecutionListeners);
185                        this.jobParametersIncrementer = properties.jobParametersIncrementer;
186                        this.jobParametersValidator = properties.jobParametersValidator;
187                }
188
189                public JobParametersIncrementer getJobParametersIncrementer() {
190                        return jobParametersIncrementer;
191                }
192
193                public void setJobParametersIncrementer(JobParametersIncrementer jobParametersIncrementer) {
194                        this.jobParametersIncrementer = jobParametersIncrementer;
195                }
196
197                public JobParametersValidator getJobParametersValidator() {
198                        return jobParametersValidator;
199                }
200
201                public void setJobParametersValidator(JobParametersValidator jobParametersValidator) {
202                        this.jobParametersValidator = jobParametersValidator;
203                }
204
205                public JobRepository getJobRepository() {
206                        return jobRepository;
207                }
208
209                public void setJobRepository(JobRepository jobRepository) {
210                        this.jobRepository = jobRepository;
211                }
212
213                public String getName() {
214                        return name;
215                }
216
217                public void setName(String name) {
218                        this.name = name;
219                }
220
221                public List<JobExecutionListener> getJobExecutionListeners() {
222                        return new ArrayList<JobExecutionListener>(jobExecutionListeners);
223                }
224
225                public void addStepExecutionListeners(List<JobExecutionListener> jobExecutionListeners) {
226                        this.jobExecutionListeners.addAll(jobExecutionListeners);
227                }
228
229                public void addJobExecutionListener(JobExecutionListener jobExecutionListener) {
230                        this.jobExecutionListeners.add(jobExecutionListener);
231                }
232
233                public boolean getRestartable() {
234                        return restartable;
235                }
236
237                public void setRestartable(boolean restartable) {
238                        this.restartable = restartable;
239                }
240
241                private String name;
242
243        }
244
245}