View Javadoc

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  
17  package org.springframework.batch.repeat.exception;
18  
19  import java.util.Collection;
20  import java.util.Collections;
21  import java.util.HashMap;
22  import java.util.Map;
23  
24  import org.springframework.batch.repeat.RepeatContext;
25  import org.springframework.beans.factory.InitializingBean;
26  
27  /**
28   * Simple implementation of exception handler which looks for given exception
29   * types. If one of the types is found then a counter is incremented and the
30   * limit is checked to determine if it has been exceeded and the Throwable
31   * should be re-thrown. Also allows to specify list of 'fatal' exceptions that
32   * are never subject to counting, but are immediately re-thrown. The fatal list
33   * has higher priority so the two lists needn't be exclusive.
34   * 
35   * @author Dave Syer
36   * @author Robert Kasanicky
37   */
38  public class SimpleLimitExceptionHandler implements ExceptionHandler, InitializingBean {
39  
40  	private RethrowOnThresholdExceptionHandler delegate = new RethrowOnThresholdExceptionHandler();
41  
42  	private Collection<Class<? extends Throwable>> exceptionClasses = Collections
43  			.<Class<? extends Throwable>> singleton(Exception.class);
44  
45  	private Collection<Class<? extends Throwable>> fatalExceptionClasses = Collections
46  			.<Class<? extends Throwable>> singleton(Error.class);
47  
48  	private int limit = 0;
49  
50  	/**
51  	 * Apply the provided properties to create a delegate handler.
52  	 * 
53  	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
54  	 */
55      @Override
56  	public void afterPropertiesSet() throws Exception {
57  		if (limit <= 0) {
58  			return;
59  		}
60  		Map<Class<? extends Throwable>, Integer> thresholds = new HashMap<Class<? extends Throwable>, Integer>();
61  		for (Class<? extends Throwable> type : exceptionClasses) {
62  			thresholds.put(type, limit);
63  		}
64  		// do the fatalExceptionClasses last so they override the others
65  		for (Class<? extends Throwable> type : fatalExceptionClasses) {
66  			thresholds.put(type, 0);
67  		}
68  		delegate.setThresholds(thresholds);
69  	}
70  
71  	/**
72  	 * Flag to indicate the the exception counters should be shared between
73  	 * sibling contexts in a nested batch (i.e. inner loop). Default is false.
74  	 * Set this flag to true if you want to count exceptions for the whole
75  	 * (outer) loop in a typical container.
76  	 * 
77  	 * @param useParent true if the parent context should be used to store the
78  	 * counters.
79  	 */
80  	public void setUseParent(boolean useParent) {
81  		delegate.setUseParent(useParent);
82  	}
83  
84  	/**
85  	 * Convenience constructor for the {@link SimpleLimitExceptionHandler} to
86  	 * set the limit.
87  	 * 
88  	 * @param limit the limit
89  	 */
90  	public SimpleLimitExceptionHandler(int limit) {
91  		this();
92  		this.limit = limit;
93  	}
94  
95  	/**
96  	 * Default constructor for the {@link SimpleLimitExceptionHandler}.
97  	 */
98  	public SimpleLimitExceptionHandler() {
99  		super();
100 	}
101 
102 	/**
103 	 * Rethrows only if the limit is breached for this context on the exception
104 	 * type specified.
105 	 * 
106 	 * @see #setExceptionClasses(Collection)
107 	 * @see #setLimit(int)
108 	 * 
109 	 * @see org.springframework.batch.repeat.exception.ExceptionHandler#handleException(org.springframework.batch.repeat.RepeatContext,
110 	 * Throwable)
111 	 */
112     @Override
113 	public void handleException(RepeatContext context, Throwable throwable) throws Throwable {
114 		delegate.handleException(context, throwable);
115 	}
116 
117 	/**
118 	 * The limit on the given exception type within a single context before it
119 	 * is rethrown.
120 	 * 
121 	 * @param limit the limit
122 	 */
123 	public void setLimit(final int limit) {
124 		this.limit = limit;
125 	}
126 
127 	/**
128 	 * Setter for the exception classes that this handler counts. Defaults to
129 	 * {@link Exception}. If more exceptionClasses are specified handler uses
130 	 * single counter that is incremented when one of the recognized exception
131 	 * exceptionClasses is handled.
132 	 * @param classes exceptionClasses
133 	 */
134 	public void setExceptionClasses(Collection<Class<? extends Throwable>> classes) {
135 		this.exceptionClasses = classes;
136 	}
137 
138 	/**
139 	 * Setter for the exception classes that shouldn't be counted, but rethrown
140 	 * immediately. This list has higher priority than
141 	 * {@link #setExceptionClasses(Collection)}.
142 	 * 
143 	 * @param fatalExceptionClasses defaults to {@link Error}
144 	 */
145 	public void setFatalExceptionClasses(Collection<Class<? extends Throwable>> fatalExceptionClasses) {
146 		this.fatalExceptionClasses = fatalExceptionClasses;
147 	}
148 
149 }