1 package org.springmodules.validation.bean.conf.loader.xml.handler;
2
3 import org.springframework.util.ObjectUtils;
4 import org.springframework.util.StringUtils;
5 import org.springmodules.validation.bean.conf.MutableBeanValidationConfiguration;
6 import org.springmodules.validation.bean.rule.AbstractValidationRule;
7 import org.springmodules.validation.bean.rule.resolver.ErrorArgumentsResolver;
8 import org.springmodules.validation.bean.rule.resolver.FunctionErrorArgumentsResolver;
9 import org.springmodules.validation.util.cel.ConditionExpressionBased;
10 import org.springmodules.validation.util.cel.ConditionExpressionParser;
11 import org.springmodules.validation.util.cel.valang.ValangConditionExpressionParser;
12 import org.springmodules.validation.util.condition.Condition;
13 import org.springmodules.validation.util.fel.FunctionExpressionBased;
14 import org.springmodules.validation.util.fel.FunctionExpressionParser;
15 import org.springmodules.validation.util.fel.parser.ValangFunctionExpressionParser;
16 import org.w3c.dom.Element;
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 public abstract class AbstractClassValidationElementHandler
37 implements ClassValidationElementHandler, ConditionExpressionBased, FunctionExpressionBased {
38
39 private static final String ERROR_CODE_ATTR = "code";
40
41 private static final String MESSAGE_ATTR = "message";
42
43 private static final String ARGS_ATTR = "args";
44
45 private static final String APPLY_IF_ATTR = "apply-if";
46
47 private static final String CONTEXTS_ATTR = "contexts";
48
49 private String elementName;
50
51 private String namespaceUrl;
52
53 private ConditionExpressionParser conditionExpressionParser;
54
55 private FunctionExpressionParser functionExpressionParser;
56
57
58
59
60
61
62 public AbstractClassValidationElementHandler(String elementName) {
63 this(elementName, null);
64 }
65
66
67
68
69
70
71
72 public AbstractClassValidationElementHandler(String elementName, String namespace) {
73 this(elementName, namespace, new ValangConditionExpressionParser(), new ValangFunctionExpressionParser());
74 }
75
76
77
78
79
80
81
82
83
84
85 public AbstractClassValidationElementHandler(
86 String elementName,
87 String namespace,
88 ConditionExpressionParser conditionExpressionParser,
89 FunctionExpressionParser functionExpressionParser) {
90
91 this.elementName = elementName;
92 this.namespaceUrl = namespace;
93 this.conditionExpressionParser = conditionExpressionParser;
94 this.functionExpressionParser = functionExpressionParser;
95 }
96
97
98
99
100
101
102
103 public boolean supports(Element element, Class clazz) {
104 String localName = element.getLocalName();
105 if (!localName.equals(elementName)) {
106 return false;
107 }
108 String ns = element.getNamespaceURI();
109 return ObjectUtils.nullSafeEquals(ns, namespaceUrl);
110 }
111
112
113
114
115
116
117
118 public void handle(Element element, MutableBeanValidationConfiguration configuration) {
119
120 AbstractValidationRule rule = createValidationRule(element);
121
122 String errorCode = extractErrorCode(element);
123 if (errorCode != null) {
124 rule.setErrorCode(errorCode);
125 }
126
127 String message = extractMessage(element);
128 if (message != null) {
129 rule.setDefaultErrorMessage(message);
130 }
131
132 ErrorArgumentsResolver argumentsResolver = extractArgumentsResolver(element);
133 if (argumentsResolver != null) {
134 rule.setErrorArgumentsResolver(argumentsResolver);
135 }
136
137 Condition applicabilityCondition = extractApplicabilityCondition(element);
138 if (applicabilityCondition != null) {
139 rule.setApplicabilityCondition(applicabilityCondition);
140 }
141
142 String[] applicableContexts = extractApplicableContexts(element);
143 if (applicableContexts != null) {
144 rule.setContextTokens(applicableContexts);
145 }
146
147 configuration.addGlobalRule(rule);
148 }
149
150
151
152
153
154 public boolean isConditionGloballyScoped() {
155 return false;
156 }
157
158
159
160
161
162
163
164
165 protected String extractErrorCode(Element element) {
166 String code = element.getAttribute(AbstractClassValidationElementHandler.ERROR_CODE_ATTR);
167 return (StringUtils.hasLength(code)) ? code : null;
168 }
169
170
171
172
173
174
175
176
177 protected String extractMessage(Element element) {
178 String message = element.getAttribute(AbstractClassValidationElementHandler.MESSAGE_ATTR);
179 return (StringUtils.hasLength(message)) ? message : null;
180 }
181
182
183
184
185
186
187
188
189 protected ErrorArgumentsResolver extractArgumentsResolver(Element element) {
190 String argsString = element.getAttribute(AbstractClassValidationElementHandler.ARGS_ATTR);
191 String[] expressions = (argsString == null) ? new String[0] : StringUtils.tokenizeToStringArray(argsString, ", ");
192 if (expressions.length == 0) {
193 return null;
194 }
195 return new FunctionErrorArgumentsResolver(expressions, functionExpressionParser);
196 }
197
198
199
200
201
202
203
204
205 protected Condition extractApplicabilityCondition(Element element) {
206 String expression = element.getAttribute(AbstractClassValidationElementHandler.APPLY_IF_ATTR);
207 return (StringUtils.hasText(expression)) ? conditionExpressionParser.parse(expression) : null;
208 }
209
210
211
212
213
214
215
216
217
218
219 protected String[] extractApplicableContexts(Element element) {
220 String contextString = element.getAttribute(CONTEXTS_ATTR);
221 return (StringUtils.hasText(contextString)) ? StringUtils.commaDelimitedListToStringArray(contextString) : null;
222 }
223
224
225
226
227 public void setConditionExpressionParser(ConditionExpressionParser conditionExpressionParser) {
228 this.conditionExpressionParser = conditionExpressionParser;
229 }
230
231
232
233
234
235
236 protected ConditionExpressionParser getConditionExpressionParser() {
237 return conditionExpressionParser;
238 }
239
240
241
242
243 public void setFunctionExpressionParser(FunctionExpressionParser functionExpressionParser) {
244 this.functionExpressionParser = functionExpressionParser;
245 }
246
247
248
249
250
251
252 protected FunctionExpressionParser getFunctionExpressionParser() {
253 return functionExpressionParser;
254 }
255
256
257
258
259
260
261
262
263 protected boolean isNullSupported() {
264 return false;
265 }
266
267
268
269
270
271
272
273 protected abstract AbstractValidationRule createValidationRule(Element element);
274
275 }