1 /*
2 * Copyright 2006-2013 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 * https://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.classify;
17
18 import java.util.Collection;
19 import java.util.HashMap;
20 import java.util.Map;
21
22 /**
23 * A {@link Classifier} for exceptions that has only two classes (true and
24 * false). Classifies objects according to their inheritance relation with the
25 * supplied types. If the object to be classified is one of the provided types,
26 * or is a subclass of one of the types, then the non-default value is returned
27 * (usually true).
28 *
29 * @see SubclassClassifier
30 *
31 * @author Dave Syer
32 * @author Gary Russell
33 *
34 */
35 @SuppressWarnings("serial")
36 public class BinaryExceptionClassifier extends SubclassClassifier<Throwable, Boolean> {
37
38 private boolean traverseCauses;
39
40 /**
41 * Create a binary exception classifier with the provided default value.
42 *
43 * @param defaultValue defaults to false
44 */
45 public BinaryExceptionClassifier(boolean defaultValue) {
46 super(defaultValue);
47 }
48
49 /**
50 * Create a binary exception classifier with the provided classes and their
51 * subclasses. The mapped value for these exceptions will be the one
52 * provided (which will be the opposite of the default).
53 *
54 * @param exceptionClasses the exceptions to classify among
55 * @param value the value to classify
56 */
57 public BinaryExceptionClassifier(Collection<Class<? extends Throwable>> exceptionClasses, boolean value) {
58 this(!value);
59 if (exceptionClasses != null) {
60 Map<Class<? extends Throwable>, Boolean> map = new HashMap<Class<? extends Throwable>, Boolean>();
61 for (Class<? extends Throwable> type : exceptionClasses) {
62 map.put(type, !getDefault());
63 }
64 setTypeMap(map);
65 }
66 }
67
68 /**
69 * Create a binary exception classifier with the default value false and
70 * value mapping true for the provided classes and their subclasses.
71 *
72 * @param exceptionClasses the exception types to throw
73 */
74 public BinaryExceptionClassifier(Collection<Class<? extends Throwable>> exceptionClasses) {
75 this(exceptionClasses, true);
76 }
77
78 /**
79 * Create a binary exception classifier using the given classification map
80 * and a default classification of false.
81 * @param typeMap the map of types
82 */
83 public BinaryExceptionClassifier(Map<Class<? extends Throwable>, Boolean> typeMap) {
84 this(typeMap, false);
85 }
86
87 /**
88 * Create a binary exception classifier using the given classification map
89 * and a default classification of false.
90 *
91 * @param defaultValue the default value to use
92 * @param typeMap the map of types to classify
93 */
94 public BinaryExceptionClassifier(Map<Class<? extends Throwable>, Boolean> typeMap, boolean defaultValue) {
95 super(typeMap, defaultValue);
96 }
97
98
99 public void setTraverseCauses(boolean traverseCauses) {
100 this.traverseCauses = traverseCauses;
101 }
102
103 @Override
104 public Boolean classify(Throwable classifiable) {
105 Boolean classified = super.classify(classifiable);
106 if (!this.traverseCauses) {
107 return classified;
108 }
109
110 /*
111 * If the result is the default, we need to find out if it was by default
112 * or so configured; if default, try the cause(es).
113 */
114 if (classified.equals(this.getDefault())) {
115 Throwable cause = classifiable;
116 do {
117 if (this.getClassified().containsKey(cause.getClass())) {
118 return classified; // non-default classification
119 }
120 cause = cause.getCause();
121 classified = super.classify(cause);
122 }
123 while (cause != null && classified.equals(this.getDefault()));
124 }
125
126 return classified;
127 }
128
129 }
130