EMMA Coverage Report (generated Fri Aug 21 15:59:46 BST 2009)
[all classes][org.springframework.batch.core.configuration.xml]

COVERAGE SUMMARY FOR SOURCE FILE [StepParserStepFactoryBean.java]

nameclass, %method, %block, %line, %
StepParserStepFactoryBean.java100% (2/2)98%  (44/45)92%  (662/720)96%  (180.4/188)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class StepParserStepFactoryBean100% (1/1)98%  (42/43)92%  (645/703)96%  (178.4/186)
setThrottleLimit (Integer): void 0%   (0/1)0%   (0/4)0%   (0/2)
validateDependency (String, Object, String, Object, boolean): void 100% (1/1)30%  (19/63)43%  (3/7)
isTrue (Boolean): boolean 100% (1/1)44%  (4/9)44%  (0.4/1)
configureSimple (SimpleStepFactoryBean): void 100% (1/1)96%  (120/125)97%  (34/35)
StepParserStepFactoryBean (): void 100% (1/1)100% (6/6)100% (2/2)
configureFaultTolerant (FaultTolerantStepFactoryBean): void 100% (1/1)100% (68/68)100% (19/19)
configureTaskletStep (TaskletStep): void 100% (1/1)100% (145/145)100% (32/32)
getJobRepository (): JobRepository 100% (1/1)100% (3/3)100% (1/1)
getObject (): Object 100% (1/1)100% (70/70)100% (18/18)
getObjectType (): Class 100% (1/1)100% (2/2)100% (1/1)
getTransactionManager (): PlatformTransactionManager 100% (1/1)100% (3/3)100% (1/1)
isFaultTolerant (): boolean 100% (1/1)100% (24/24)100% (2/2)
isPositive (Integer): boolean 100% (1/1)100% (9/9)100% (1/1)
isPresent (Object): boolean 100% (1/1)100% (14/14)100% (3/3)
isSingleton (): boolean 100% (1/1)100% (2/2)100% (1/1)
setAllowStartIfComplete (boolean): void 100% (1/1)100% (5/5)100% (2/2)
setBeanName (String): void 100% (1/1)100% (7/7)100% (3/3)
setCacheCapacity (int): void 100% (1/1)100% (5/5)100% (2/2)
setChunkCompletionPolicy (CompletionPolicy): void 100% (1/1)100% (4/4)100% (2/2)
setCommitInterval (int): void 100% (1/1)100% (5/5)100% (2/2)
setFatalExceptionClasses (Collection): void 100% (1/1)100% (4/4)100% (2/2)
setHasChunkElement (boolean): void 100% (1/1)100% (4/4)100% (2/2)
setIsReaderTransactionalQueue (boolean): void 100% (1/1)100% (5/5)100% (2/2)
setIsolation (Isolation): void 100% (1/1)100% (4/4)100% (2/2)
setItemProcessor (ItemProcessor): void 100% (1/1)100% (4/4)100% (2/2)
setItemReader (ItemReader): void 100% (1/1)100% (4/4)100% (2/2)
setItemWriter (ItemWriter): void 100% (1/1)100% (4/4)100% (2/2)
setJobRepository (JobRepository): void 100% (1/1)100% (4/4)100% (2/2)
setListeners (StepListener []): void 100% (1/1)100% (4/4)100% (2/2)
setNoRollbackExceptionClasses (Collection): void 100% (1/1)100% (4/4)100% (2/2)
setPropagation (Propagation): void 100% (1/1)100% (4/4)100% (2/2)
setRetryLimit (int): void 100% (1/1)100% (5/5)100% (2/2)
setRetryListeners (RetryListener []): void 100% (1/1)100% (4/4)100% (2/2)
setRetryableExceptionClasses (Collection): void 100% (1/1)100% (4/4)100% (2/2)
setSkipLimit (int): void 100% (1/1)100% (5/5)100% (2/2)
setSkippableExceptionClasses (Collection): void 100% (1/1)100% (4/4)100% (2/2)
setStartLimit (int): void 100% (1/1)100% (5/5)100% (2/2)
setStreams (ItemStream []): void 100% (1/1)100% (4/4)100% (2/2)
setTaskExecutor (TaskExecutor): void 100% (1/1)100% (4/4)100% (2/2)
setTasklet (Tasklet): void 100% (1/1)100% (4/4)100% (2/2)
setTransactionManager (PlatformTransactionManager): void 100% (1/1)100% (4/4)100% (2/2)
setTransactionTimeout (int): void 100% (1/1)100% (5/5)100% (2/2)
validateFaultTolerantSettings (): void 100% (1/1)100% (37/37)100% (5/5)
     
class StepParserStepFactoryBean$1100% (1/1)100% (2/2)100% (17/17)100% (3/3)
StepParserStepFactoryBean$1 (StepParserStepFactoryBean, TransactionAttribute,... 100% (1/1)100% (10/10)100% (2/2)
rollbackOn (Throwable): boolean 100% (1/1)100% (7/7)100% (1/1)

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 
17package org.springframework.batch.core.configuration.xml;
18 
19import java.util.Collection;
20import java.util.HashSet;
21 
22import org.springframework.batch.classify.BinaryExceptionClassifier;
23import org.springframework.batch.core.Step;
24import org.springframework.batch.core.StepExecutionListener;
25import org.springframework.batch.core.StepListener;
26import org.springframework.batch.core.repository.JobRepository;
27import org.springframework.batch.core.step.item.FaultTolerantStepFactoryBean;
28import org.springframework.batch.core.step.item.SimpleStepFactoryBean;
29import org.springframework.batch.core.step.tasklet.Tasklet;
30import org.springframework.batch.core.step.tasklet.TaskletStep;
31import org.springframework.batch.item.ItemProcessor;
32import org.springframework.batch.item.ItemReader;
33import org.springframework.batch.item.ItemStream;
34import org.springframework.batch.item.ItemWriter;
35import org.springframework.batch.repeat.CompletionPolicy;
36import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
37import org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate;
38import org.springframework.batch.retry.RetryListener;
39import org.springframework.batch.retry.policy.MapRetryContextCache;
40import org.springframework.beans.factory.BeanNameAware;
41import org.springframework.beans.factory.FactoryBean;
42import org.springframework.core.task.TaskExecutor;
43import org.springframework.transaction.PlatformTransactionManager;
44import org.springframework.transaction.annotation.Isolation;
45import org.springframework.transaction.annotation.Propagation;
46import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
47import org.springframework.util.Assert;
48 
49/**
50 * This {@link FactoryBean} is used by the batch namespace parser to create
51 * {@link Step} objects. Stores all of the properties that are configurable on
52 * the <step/> (and its inner <tasklet/>). Based on which properties
53 * are configured, the {@link #getObject()} method will delegate to the
54 * appropriate class for generating the {@link Step}.
55 * 
56 * @author Dan Garrette
57 * @since 2.0
58 * @see SimpleStepFactoryBean
59 * @see FaultTolerantStepFactoryBean
60 * @see TaskletStep
61 */
62class StepParserStepFactoryBean<I, O> implements FactoryBean, BeanNameAware {
63 
64        //
65        // Step Attributes
66        //
67        private String name;
68 
69        //
70        // Tasklet Attributes
71        //
72        private Boolean allowStartIfComplete;
73 
74        private JobRepository jobRepository;
75 
76        private Integer startLimit;
77 
78        private Tasklet tasklet;
79 
80        private PlatformTransactionManager transactionManager;
81 
82        //
83        // Tasklet Elements
84        //
85        private StepListener[] listeners;
86 
87        private Collection<Class<? extends Throwable>> noRollbackExceptionClasses;
88 
89        private Integer transactionTimeout;
90 
91        private Propagation propagation;
92 
93        private Isolation isolation;
94 
95        //
96        // Chunk Attributes
97        //
98        private Integer cacheCapacity;
99 
100        private CompletionPolicy chunkCompletionPolicy;
101 
102        private Integer commitInterval;
103 
104        private Boolean isReaderTransactionalQueue;
105 
106        private Integer retryLimit;
107 
108        private Integer skipLimit;
109 
110        private TaskExecutor taskExecutor;
111 
112        private Integer throttleLimit;
113 
114        private ItemReader<? extends I> itemReader;
115 
116        private ItemProcessor<? super I, ? extends O> itemProcessor;
117 
118        private ItemWriter<? super O> itemWriter;
119 
120        //
121        // Chunk Elements
122        //
123        private RetryListener[] retryListeners;
124 
125        private Collection<Class<? extends Throwable>> skippableExceptionClasses;
126 
127        private Collection<Class<? extends Throwable>> retryableExceptionClasses;
128 
129        private Collection<Class<? extends Throwable>> fatalExceptionClasses;
130 
131        private ItemStream[] streams;
132 
133        //
134        // Additional
135        //
136        private boolean hasChunkElement = false;
137 
138        /**
139         * Create a {@link Step} from the configuration provided.
140         * 
141         * @see FactoryBean#getObject()
142         */
143        public final Object getObject() throws Exception {
144                if (hasChunkElement) {
145                        Assert.isNull(tasklet, "Step [" + name
146                                        + "] has both a <chunk/> element and a 'ref' attribute  referencing a Tasklet.");
147 
148                        validateFaultTolerantSettings();
149                        if (isFaultTolerant()) {
150                                FaultTolerantStepFactoryBean<I, O> fb = new FaultTolerantStepFactoryBean<I, O>();
151                                configureSimple(fb);
152                                configureFaultTolerant(fb);
153                                return fb.getObject();
154                        }
155                        else {
156                                SimpleStepFactoryBean<I, O> fb = new SimpleStepFactoryBean<I, O>();
157                                configureSimple(fb);
158                                return fb.getObject();
159                        }
160                }
161                else if (tasklet != null) {
162                        TaskletStep ts = new TaskletStep();
163                        configureTaskletStep(ts);
164                        return ts;
165                }
166                else {
167                        throw new IllegalStateException("Step [" + name
168                                        + "] has neither a <chunk/> element nor a 'ref' attribute referencing a Tasklet.");
169                }
170        }
171 
172        private void configureSimple(SimpleStepFactoryBean<I, O> fb) {
173                if (name != null) {
174                        fb.setBeanName(name);
175                }
176                if (allowStartIfComplete != null) {
177                        fb.setAllowStartIfComplete(allowStartIfComplete);
178                }
179                if (jobRepository != null) {
180                        fb.setJobRepository(jobRepository);
181                }
182                if (startLimit != null) {
183                        fb.setStartLimit(startLimit);
184                }
185                if (transactionManager != null) {
186                        fb.setTransactionManager(transactionManager);
187                }
188                if (listeners != null) {
189                        fb.setListeners(listeners);
190                }
191                if (transactionTimeout != null) {
192                        fb.setTransactionTimeout(transactionTimeout);
193                }
194                if (propagation != null) {
195                        fb.setPropagation(propagation);
196                }
197                if (isolation != null) {
198                        fb.setIsolation(isolation);
199                }
200 
201                if (chunkCompletionPolicy != null) {
202                        fb.setChunkCompletionPolicy(chunkCompletionPolicy);
203                }
204                if (commitInterval != null) {
205                        fb.setCommitInterval(commitInterval);
206                }
207                if (taskExecutor != null) {
208                        fb.setTaskExecutor(taskExecutor);
209                }
210                if (throttleLimit != null) {
211                        fb.setThrottleLimit(throttleLimit);
212                }
213                if (itemReader != null) {
214                        fb.setItemReader(itemReader);
215                }
216                if (itemProcessor != null) {
217                        fb.setItemProcessor(itemProcessor);
218                }
219                if (itemWriter != null) {
220                        fb.setItemWriter(itemWriter);
221                }
222 
223                if (streams != null) {
224                        fb.setStreams(streams);
225                }
226        }
227 
228        private void configureFaultTolerant(FaultTolerantStepFactoryBean<I, O> fb) {
229                if (cacheCapacity != null) {
230                        fb.setCacheCapacity(cacheCapacity);
231                }
232                if (isReaderTransactionalQueue != null) {
233                        fb.setIsReaderTransactionalQueue(isReaderTransactionalQueue);
234                }
235                if (retryLimit != null) {
236                        fb.setRetryLimit(retryLimit);
237                }
238                if (skipLimit != null) {
239                        fb.setSkipLimit(skipLimit);
240                }
241 
242                if (retryListeners != null) {
243                        fb.setRetryListeners(retryListeners);
244                }
245                if (skippableExceptionClasses != null) {
246                        fb.setSkippableExceptionClasses(skippableExceptionClasses);
247                }
248                if (retryableExceptionClasses != null) {
249                        fb.setRetryableExceptionClasses(retryableExceptionClasses);
250                }
251                if (fatalExceptionClasses != null) {
252                        fb.setFatalExceptionClasses(fatalExceptionClasses);
253                }
254                if (noRollbackExceptionClasses != null) {
255                        fb.setNoRollbackExceptionClasses(noRollbackExceptionClasses);
256                }
257        }
258 
259        @SuppressWarnings("serial")
260        private void configureTaskletStep(TaskletStep ts) {
261                if (name != null) {
262                        ts.setName(name);
263                }
264                if (allowStartIfComplete != null) {
265                        ts.setAllowStartIfComplete(allowStartIfComplete);
266                }
267                if (jobRepository != null) {
268                        ts.setJobRepository(jobRepository);
269                }
270                if (startLimit != null) {
271                        ts.setStartLimit(startLimit);
272                }
273                if (tasklet != null) {
274                        ts.setTasklet(tasklet);
275                }
276                if (transactionManager != null) {
277                        ts.setTransactionManager(transactionManager);
278                }
279                if (listeners != null) {
280                        int i = 0;
281                        StepExecutionListener[] newListeners = new StepExecutionListener[listeners.length];
282                        for (StepListener listener : listeners) {
283                                newListeners[i++] = (StepExecutionListener) listener;
284                        }
285                        ts.setStepExecutionListeners((StepExecutionListener[]) newListeners);
286                }
287                if (transactionTimeout != null || propagation != null || isolation != null
288                                || noRollbackExceptionClasses != null) {
289                        DefaultTransactionAttribute attribute = new DefaultTransactionAttribute();
290                        if (propagation != null) {
291                                attribute.setPropagationBehavior(propagation.value());
292                        }
293                        if (isolation != null) {
294                                attribute.setIsolationLevel(isolation.value());
295                        }
296                        if (transactionTimeout != null) {
297                                attribute.setTimeout(transactionTimeout);
298                        }
299                        Collection<Class<? extends Throwable>> exceptions = noRollbackExceptionClasses == null ? new HashSet<Class<? extends Throwable>>()
300                                        : noRollbackExceptionClasses;
301                        final BinaryExceptionClassifier classifier = new BinaryExceptionClassifier(exceptions, false);
302                        ts.setTransactionAttribute(new DefaultTransactionAttribute(attribute) {
303                                @Override
304                                public boolean rollbackOn(Throwable ex) {
305                                        return classifier.classify(ex);
306                                }
307                        });
308                }
309        }
310 
311        private void validateFaultTolerantSettings() {
312                validateDependency("skippable-exception-classes", skippableExceptionClasses, "skip-limit", skipLimit, true);
313                validateDependency("fatal-exception-classes", fatalExceptionClasses, "skip-limit", skipLimit, false);
314                validateDependency("retryable-exception-classes", retryableExceptionClasses, "retry-limit", retryLimit, true);
315                validateDependency("retry-listeners", retryListeners, "retry-limit", retryLimit, false);
316        }
317 
318        private void validateDependency(String dependantName, Object dependantValue, String name, Object value,
319                        boolean twoWayDependency) {
320                if (isPresent(dependantValue) && !isPresent(value)) {
321                        throw new IllegalArgumentException("The field '" + dependantName + "' is not permitted on the step ["
322                                        + this.name + "] because there is no '" + name + "'.");
323                }
324                if (twoWayDependency && isPresent(value) && !isPresent(dependantValue)) {
325                        throw new IllegalArgumentException("The field '" + name + "' is not permitted on the step [" + this.name
326                                        + "] because there is no '" + dependantName + "'.");
327                }
328        }
329 
330        private boolean isPresent(Object o) {
331                if (o instanceof Integer) {
332                        return isPositive((Integer) o);
333                }
334                return o != null;
335        }
336 
337        private boolean isFaultTolerant() {
338                return isPositive(skipLimit) || isPositive(retryLimit) || isPositive(cacheCapacity)
339                                || isTrue(isReaderTransactionalQueue);
340        }
341 
342        private boolean isTrue(Boolean b) {
343                return b != null && b.booleanValue();
344        }
345 
346        private boolean isPositive(Integer n) {
347                return n != null && n > 0;
348        }
349 
350        public Class<TaskletStep> getObjectType() {
351                return TaskletStep.class;
352        }
353 
354        public boolean isSingleton() {
355                return true;
356        }
357 
358        // =========================================================
359        // Step Attributes
360        // =========================================================
361 
362        /**
363         * Set the bean name property, which will become the name of the
364         * {@link Step} when it is created.
365         * 
366         * @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
367         */
368        public void setBeanName(String name) {
369                if (this.name == null) {
370                        this.name = name;
371                }
372        }
373 
374        // =========================================================
375        // Tasklet Attributes
376        // =========================================================
377 
378        /**
379         * Public setter for the flag to indicate that the step should be replayed
380         * on a restart, even if successful the first time.
381         * 
382         * @param allowStartIfComplete the shouldAllowStartIfComplete to set
383         */
384        public void setAllowStartIfComplete(boolean allowStartIfComplete) {
385                this.allowStartIfComplete = allowStartIfComplete;
386 
387        }
388 
389        /**
390         * @return jobRepository
391         */
392        public JobRepository getJobRepository() {
393                return jobRepository;
394        }
395 
396        /**
397         * Public setter for {@link JobRepository}.
398         * 
399         * @param jobRepository
400         */
401        public void setJobRepository(JobRepository jobRepository) {
402                this.jobRepository = jobRepository;
403        }
404 
405        /**
406         * The number of times that the step should be allowed to start
407         * 
408         * @param startLimit
409         */
410        public void setStartLimit(int startLimit) {
411                this.startLimit = startLimit;
412        }
413 
414        /**
415         * A preconfigured {@link Tasklet} to use.
416         * 
417         * @param tasklet
418         */
419        public void setTasklet(Tasklet tasklet) {
420                this.tasklet = tasklet;
421        }
422 
423        /**
424         * @return transactionManager
425         */
426        public PlatformTransactionManager getTransactionManager() {
427                return transactionManager;
428        }
429 
430        /**
431         * @param transactionManager the transaction manager to set
432         */
433        public void setTransactionManager(PlatformTransactionManager transactionManager) {
434                this.transactionManager = transactionManager;
435        }
436 
437        // =========================================================
438        // Tasklet Elements
439        // =========================================================
440 
441        /**
442         * The listeners to inject into the {@link Step}. Any instance of
443         * {@link StepListener} can be used, and will then receive callbacks at the
444         * appropriate stage in the step.
445         * 
446         * @param listeners an array of listeners
447         */
448        public void setListeners(StepListener[] listeners) {
449                this.listeners = listeners;
450        }
451 
452        /**
453         * Exception classes that may not cause a rollback if encountered in the
454         * right place.
455         * 
456         * @param noRollbackExceptionClasses the noRollbackExceptionClasses to set
457         */
458        public void setNoRollbackExceptionClasses(Collection<Class<? extends Throwable>> noRollbackExceptionClasses) {
459                this.noRollbackExceptionClasses = noRollbackExceptionClasses;
460        }
461 
462        /**
463         * @param transactionTimeout the transactionTimeout to set
464         */
465        public void setTransactionTimeout(int transactionTimeout) {
466                this.transactionTimeout = transactionTimeout;
467        }
468 
469        /**
470         * @param isolation the isolation to set
471         */
472        public void setIsolation(Isolation isolation) {
473                this.isolation = isolation;
474        }
475 
476        /**
477         * @param propagation the propagation to set
478         */
479        public void setPropagation(Propagation propagation) {
480                this.propagation = propagation;
481        }
482 
483        // =========================================================
484        // Chunk Attributes
485        // =========================================================
486 
487        /**
488         * Public setter for the capacity of the cache in the retry policy. If more
489         * items than this fail without being skipped or recovered an exception will
490         * be thrown. This is to guard against inadvertent infinite loops generated
491         * by item identity problems.<br/>
492         * 
493         * The default value should be high enough and more for most purposes. To
494         * breach the limit in a single-threaded step typically you have to have
495         * this many failures in a single transaction. Defaults to the value in the
496         * {@link MapRetryContextCache}.<br/>
497         * 
498         * @param cacheCapacity the cache capacity to set (greater than 0 else
499         * ignored)
500         */
501        public void setCacheCapacity(int cacheCapacity) {
502                this.cacheCapacity = cacheCapacity;
503        }
504 
505        /**
506         * Public setter for the {@link CompletionPolicy} applying to the chunk
507         * level. A transaction will be committed when this policy decides to
508         * complete. Defaults to a {@link SimpleCompletionPolicy} with chunk size
509         * equal to the commitInterval property.
510         * 
511         * @param chunkCompletionPolicy the chunkCompletionPolicy to set
512         */
513        public void setChunkCompletionPolicy(CompletionPolicy chunkCompletionPolicy) {
514                this.chunkCompletionPolicy = chunkCompletionPolicy;
515        }
516 
517        /**
518         * Set the commit interval. Either set this or the chunkCompletionPolicy but
519         * not both.
520         * 
521         * @param commitInterval 1 by default
522         */
523        public void setCommitInterval(int commitInterval) {
524                this.commitInterval = commitInterval;
525        }
526 
527        /**
528         * Flag to signal that the reader is transactional (usually a JMS consumer)
529         * so that items are re-presented after a rollback. The default is false and
530         * readers are assumed to be forward-only.
531         * 
532         * @param isReaderTransactionalQueue the value of the flag
533         */
534        public void setIsReaderTransactionalQueue(boolean isReaderTransactionalQueue) {
535                this.isReaderTransactionalQueue = isReaderTransactionalQueue;
536        }
537 
538        /**
539         * Public setter for the retry limit. Each item can be retried up to this
540         * limit. Note this limit includes the initial attempt to process the item,
541         * therefore <code>retryLimit == 1</code> by default.
542         * 
543         * @param retryLimit the retry limit to set, must be greater or equal to 1.
544         */
545        public void setRetryLimit(int retryLimit) {
546                this.retryLimit = retryLimit;
547        }
548 
549        /**
550         * Public setter for a limit that determines skip policy. If this value is
551         * positive then an exception in chunk processing will cause the item to be
552         * skipped and no exception propagated until the limit is reached. If it is
553         * zero then all exceptions will be propagated from the chunk and cause the
554         * step to abort.
555         * 
556         * @param skipLimit the value to set. Default is 0 (never skip).
557         */
558        public void setSkipLimit(int skipLimit) {
559                this.skipLimit = skipLimit;
560        }
561 
562        /**
563         * Public setter for the {@link TaskExecutor}. If this is set, then it will
564         * be used to execute the chunk processing inside the {@link Step}.
565         * 
566         * @param taskExecutor the taskExecutor to set
567         */
568        public void setTaskExecutor(TaskExecutor taskExecutor) {
569                this.taskExecutor = taskExecutor;
570        }
571 
572        /**
573         * Public setter for the throttle limit. This limits the number of tasks
574         * queued for concurrent processing to prevent thread pools from being
575         * overwhelmed. Defaults to
576         * {@link TaskExecutorRepeatTemplate#DEFAULT_THROTTLE_LIMIT}.
577         * 
578         * @param throttleLimit the throttle limit to set.
579         */
580        public void setThrottleLimit(Integer throttleLimit) {
581                this.throttleLimit = throttleLimit;
582        }
583 
584        /**
585         * @param itemReader the {@link ItemReader} to set
586         */
587        public void setItemReader(ItemReader<? extends I> itemReader) {
588                this.itemReader = itemReader;
589        }
590 
591        /**
592         * @param itemProcessor the {@link ItemProcessor} to set
593         */
594        public void setItemProcessor(ItemProcessor<? super I, ? extends O> itemProcessor) {
595                this.itemProcessor = itemProcessor;
596        }
597 
598        /**
599         * @param itemWriter the {@link ItemWriter} to set
600         */
601        public void setItemWriter(ItemWriter<? super O> itemWriter) {
602                this.itemWriter = itemWriter;
603        }
604 
605        // =========================================================
606        // Chunk Elements
607        // =========================================================
608 
609        /**
610         * Public setter for the {@link RetryListener}s.
611         * 
612         * @param retryListeners the {@link RetryListener}s to set
613         */
614        public void setRetryListeners(RetryListener... retryListeners) {
615                this.retryListeners = retryListeners;
616        }
617 
618        /**
619         * Public setter for exception classes that when raised won't crash the job
620         * but will result in transaction rollback and the item which handling
621         * caused the exception will be skipped.
622         * 
623         * @param exceptionClasses
624         */
625        public void setSkippableExceptionClasses(Collection<Class<? extends Throwable>> exceptionClasses) {
626                this.skippableExceptionClasses = exceptionClasses;
627        }
628 
629        /**
630         * Public setter for exception classes that will retry the item when raised.
631         * 
632         * @param retryableExceptionClasses the retryableExceptionClasses to set
633         */
634        public void setRetryableExceptionClasses(Collection<Class<? extends Throwable>> retryableExceptionClasses) {
635                this.retryableExceptionClasses = retryableExceptionClasses;
636        }
637 
638        /**
639         * Public setter for exception classes that should cause immediate failure.
640         * 
641         * @param fatalExceptionClasses
642         */
643        public void setFatalExceptionClasses(Collection<Class<? extends Throwable>> fatalExceptionClasses) {
644                this.fatalExceptionClasses = fatalExceptionClasses;
645        }
646 
647        /**
648         * The streams to inject into the {@link Step}. Any instance of
649         * {@link ItemStream} can be used, and will then receive callbacks at the
650         * appropriate stage in the step.
651         * 
652         * @param streams an array of listeners
653         */
654        public void setStreams(ItemStream[] streams) {
655                this.streams = streams;
656        }
657 
658        // =========================================================
659        // Additional
660        // =========================================================
661 
662        /**
663         * @param hasChunkElement
664         */
665        public void setHasChunkElement(boolean hasChunkElement) {
666                this.hasChunkElement = hasChunkElement;
667        }
668 
669}

[all classes][org.springframework.batch.core.configuration.xml]
EMMA 2.0.5312 (C) Vladimir Roubtsov