1 | /* |
2 | * Copyright 2006-2007 the original author or authors. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | package org.springframework.batch.core.step.item; |
17 | |
18 | import org.springframework.batch.core.Step; |
19 | import org.springframework.batch.core.StepExecutionListener; |
20 | import org.springframework.batch.core.StepListener; |
21 | import org.springframework.batch.item.ItemReader; |
22 | import org.springframework.batch.item.ItemStream; |
23 | import org.springframework.batch.item.ItemWriter; |
24 | import org.springframework.batch.repeat.exception.ExceptionHandler; |
25 | import org.springframework.batch.repeat.policy.SimpleCompletionPolicy; |
26 | import org.springframework.batch.repeat.support.RepeatTemplate; |
27 | import org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate; |
28 | import org.springframework.core.task.TaskExecutor; |
29 | import org.springframework.util.Assert; |
30 | |
31 | /** |
32 | * Most common configuration options for simple steps should be found here. Use |
33 | * this factory bean instead of creating a {@link Step} implementation manually. |
34 | * |
35 | * This factory does not support configuration of fault-tolerant behavior, use |
36 | * appropriate subclass of this factory bean to configure skip or retry. |
37 | * |
38 | * @see SkipLimitStepFactoryBean |
39 | * @see StatefulRetryStepFactoryBean |
40 | * |
41 | * @author Dave Syer |
42 | * |
43 | */ |
44 | public class SimpleStepFactoryBean extends AbstractStepFactoryBean { |
45 | |
46 | private int commitInterval = 1; |
47 | |
48 | private ItemStream[] streams = new ItemStream[0]; |
49 | |
50 | private StepListener[] listeners = new StepListener[0]; |
51 | |
52 | private TaskExecutor taskExecutor; |
53 | |
54 | private ItemHandler itemHandler; |
55 | |
56 | private RepeatTemplate stepOperations; |
57 | |
58 | private RepeatTemplate chunkOperations; |
59 | |
60 | private ExceptionHandler exceptionHandler; |
61 | |
62 | |
63 | /** |
64 | * Set the commit interval. |
65 | * |
66 | * @param commitInterval 1 by default |
67 | */ |
68 | public void setCommitInterval(int commitInterval) { |
69 | this.commitInterval = commitInterval; |
70 | } |
71 | |
72 | /** |
73 | * The streams to inject into the {@link Step}. Any instance of |
74 | * {@link ItemStream} can be used, and will then receive callbacks at the |
75 | * appropriate stage in the step. |
76 | * |
77 | * @param streams an array of listeners |
78 | */ |
79 | public void setStreams(ItemStream[] streams) { |
80 | this.streams = streams; |
81 | } |
82 | |
83 | /** |
84 | * The listeners to inject into the {@link Step}. Any instance of |
85 | * {@link StepListener} can be used, and will then receive callbacks at the |
86 | * appropriate stage in the step. |
87 | * |
88 | * @param listeners an array of listeners |
89 | */ |
90 | public void setListeners(StepListener[] listeners) { |
91 | this.listeners = listeners; |
92 | } |
93 | |
94 | /** |
95 | * Protected getter for the {@link StepListener}s. |
96 | * @return the listeners |
97 | */ |
98 | protected StepListener[] getListeners() { |
99 | return listeners; |
100 | } |
101 | |
102 | /** |
103 | * Protected getter for the step operations to make them available in |
104 | * subclasses. |
105 | * @return the step operations |
106 | */ |
107 | protected RepeatTemplate getStepOperations() { |
108 | return stepOperations; |
109 | } |
110 | |
111 | /** |
112 | * Protected getter for the chunk operations to make them available in |
113 | * subclasses. |
114 | * @return the step operations |
115 | */ |
116 | protected RepeatTemplate getChunkOperations() { |
117 | return chunkOperations; |
118 | } |
119 | |
120 | |
121 | /** |
122 | * Public setter for the SimpleLimitExceptionHandler. |
123 | * @param exceptionHandler the exceptionHandler to set |
124 | */ |
125 | public void setExceptionHandler(ExceptionHandler exceptionHandler) { |
126 | this.exceptionHandler = exceptionHandler; |
127 | } |
128 | |
129 | /** |
130 | * Protected getter for the {@link ExceptionHandler}. |
131 | * @return the {@link ExceptionHandler} |
132 | */ |
133 | protected ExceptionHandler getExceptionHandler() { |
134 | return exceptionHandler; |
135 | } |
136 | |
137 | /** |
138 | * Public setter for the {@link TaskExecutor}. If this is set, then it will |
139 | * be used to execute the chunk processing inside the {@link Step}. |
140 | * |
141 | * @param taskExecutor the taskExecutor to set |
142 | */ |
143 | public void setTaskExecutor(TaskExecutor taskExecutor) { |
144 | this.taskExecutor = taskExecutor; |
145 | } |
146 | |
147 | /** |
148 | * Public getter for the ItemHandler. |
149 | * @return the ItemHandler |
150 | */ |
151 | protected ItemHandler getItemHandler() { |
152 | return itemHandler; |
153 | } |
154 | |
155 | /** |
156 | * Public setter for the ItemHandler. |
157 | * @param itemHandler the ItemHandler to set |
158 | */ |
159 | protected void setItemHandler(ItemHandler itemHandler) { |
160 | this.itemHandler = itemHandler; |
161 | } |
162 | |
163 | /** |
164 | * @param step |
165 | * |
166 | */ |
167 | protected void applyConfiguration(ItemOrientedStep step) { |
168 | |
169 | super.applyConfiguration(step); |
170 | |
171 | Assert.isTrue(commitInterval > 0); |
172 | |
173 | step.setStreams(streams); |
174 | |
175 | ItemReader itemReader = getItemReader(); |
176 | ItemWriter itemWriter = getItemWriter(); |
177 | |
178 | // Since we are going to wrap these things with listener callbacks we |
179 | // need to register them here because the step will not know we did |
180 | // that. |
181 | if (itemReader instanceof ItemStream) { |
182 | step.registerStream((ItemStream) itemReader); |
183 | } |
184 | if (itemReader instanceof StepExecutionListener) { |
185 | step.registerStepExecutionListener((StepExecutionListener) itemReader); |
186 | } |
187 | if (itemWriter instanceof ItemStream) { |
188 | step.registerStream((ItemStream) itemWriter); |
189 | } |
190 | if (itemWriter instanceof StepExecutionListener) { |
191 | step.registerStepExecutionListener((StepExecutionListener) itemWriter); |
192 | } |
193 | |
194 | BatchListenerFactoryHelper helper = new BatchListenerFactoryHelper(); |
195 | |
196 | chunkOperations = new RepeatTemplate(); |
197 | chunkOperations.setCompletionPolicy(new SimpleCompletionPolicy(commitInterval)); |
198 | helper.addChunkListeners(chunkOperations, listeners); |
199 | step.setChunkOperations(chunkOperations); |
200 | |
201 | StepExecutionListener[] stepListeners = helper.getStepListeners(listeners); |
202 | itemReader = helper.getItemReader(itemReader, listeners); |
203 | itemWriter = helper.getItemWriter(itemWriter, listeners); |
204 | |
205 | // In case they are used by subclasses: |
206 | setItemReader(itemReader); |
207 | setItemWriter(itemWriter); |
208 | |
209 | step.setStepExecutionListeners(stepListeners); |
210 | |
211 | stepOperations = new RepeatTemplate(); |
212 | |
213 | if (taskExecutor != null) { |
214 | TaskExecutorRepeatTemplate repeatTemplate = new TaskExecutorRepeatTemplate(); |
215 | repeatTemplate.setTaskExecutor(taskExecutor); |
216 | stepOperations = repeatTemplate; |
217 | } |
218 | |
219 | step.setStepOperations(stepOperations); |
220 | |
221 | ItemHandler itemHandler = new SimpleItemHandler(itemReader, itemWriter); |
222 | |
223 | setItemHandler(itemHandler); |
224 | step.setItemHandler(itemHandler); |
225 | |
226 | } |
227 | |
228 | } |