1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package nl.openedge.baritus;
33
34 import java.util.ArrayList;
35 import java.util.Collection;
36 import java.util.Iterator;
37 import java.util.List;
38 import java.util.Map;
39
40 import nl.openedge.baritus.util.MultiHashMap;
41 import nl.openedge.baritus.validation.FieldValidator;
42 import nl.openedge.baritus.validation.FormValidator;
43 import nl.openedge.baritus.validation.ValidationRuleDependend;
44 import nl.openedge.baritus.validation.ValidationActivationRule;
45
46 import ognl.Ognl;
47
48 import org.apache.commons.logging.Log;
49 import org.apache.commons.logging.LogFactory;
50 import org.infohazard.maverick.flow.ControllerContext;
51
52 /***
53 * @author Eelco Hillenius
54 */
55 public final class DefaultValidatorDelegate implements ValidatorDelegate
56 {
57
58 private ValidatorRegistry validatorRegistry = null;
59
60
61 private FormBeanCtrlBase ctrl = null;
62
63
64 private static Log populationLog = LogFactory.getLog(LogConstants.POPULATION_LOG);
65
66 private static char[] BREAKSYMBOLS = new char[]{'[','('};
67
68 /***
69 * construct with validator registry and instance of ctrl
70 * @param validatorRegistry
71 * @param ctrl
72 */
73 public DefaultValidatorDelegate(
74 ValidatorRegistry validatorRegistry,
75 FormBeanCtrlBase ctrl)
76 {
77 this.validatorRegistry = validatorRegistry;
78 this.ctrl = ctrl;
79 }
80
81 /***
82 * @see nl.openedge.baritus.ValidatorDelegate#doValidation(org.infohazard.maverick.flow.ControllerContext, nl.openedge.baritus.FormBeanContext, nl.openedge.baritus.ExecutionParams, java.util.Map, boolean)
83 */
84 public boolean doValidation(
85 ControllerContext cctx,
86 FormBeanContext formBeanContext,
87 ExecutionParams execParams,
88 Map parameters,
89 boolean succeeded)
90 {
91
92 if(parameters == null) return succeeded;
93
94 MultiHashMap fieldValidators = validatorRegistry.getFieldValidators();
95 List formValidators = validatorRegistry.getFormValidators();
96 List globalValidatorActivationRules =
97 validatorRegistry.getGlobalValidatorActivationRules();
98
99 if( (fieldValidators != null && (!fieldValidators.isEmpty())) ||
100 (formValidators != null && (!formValidators.isEmpty())))
101 {
102
103 boolean doCustomValidation = true;
104
105 if(globalValidatorActivationRules != null && (!globalValidatorActivationRules.isEmpty()))
106 {
107 for(Iterator i = globalValidatorActivationRules.iterator(); i.hasNext(); )
108 {
109 ValidationActivationRule rule = (ValidationActivationRule)i.next();
110 doCustomValidation = rule.allowValidation(cctx, formBeanContext);
111 if(!doCustomValidation) break;
112 }
113 }
114
115 if(doCustomValidation)
116 {
117
118 if(fieldValidators != null && (!fieldValidators.isEmpty()))
119 {
120 Iterator names = parameters.keySet().iterator();
121 while(names.hasNext())
122 {
123 String name = (String)names.next();
124 if (name == null) continue;
125 if(formBeanContext.getOverrideField(name) == null)
126
127 {
128 succeeded = doValidationForOneField(
129 fieldValidators, cctx, formBeanContext, succeeded, name);
130 }
131 }
132 }
133
134 if( (succeeded || execParams.isDoFormValidationIfFieldValidationFailed())
135 && (formValidators != null))
136 {
137
138
139 for(Iterator i = formValidators.iterator(); i.hasNext(); )
140 {
141 FormValidator fValidator = (FormValidator)i.next();
142 succeeded = doFormValidationForOneValidator(
143 cctx, formBeanContext, fValidator, succeeded);
144 }
145 }
146 }
147 }
148
149 return succeeded;
150 }
151
152
153 private boolean doFormValidationForOneValidator(
154 ControllerContext cctx,
155 FormBeanContext formBeanContext,
156 FormValidator fValidator,
157 boolean succeeded)
158 {
159
160 boolean success = true;
161 try
162 {
163 boolean validateForm = true;
164 if(fValidator instanceof ValidationRuleDependend)
165 {
166 ValidationActivationRule fRule =
167 ((ValidationRuleDependend)fValidator).getValidationActivationRule();
168 if(fRule != null)
169 {
170 if(!fRule.allowValidation(cctx, formBeanContext))
171 {
172 validateForm = false;
173 }
174
175 if(populationLog.isDebugEnabled())
176 {
177 populationLog.debug("rule " + fRule +
178 ((validateForm) ? " ALLOWS" : " DISALLOWS") +
179 " validation with " + fValidator);
180 }
181 }
182 }
183 if(validateForm)
184 {
185 success = fValidator.isValid(cctx, formBeanContext);
186
187 if(populationLog.isDebugEnabled())
188 {
189 populationLog.debug( "validation" +
190 ((success) ? " PASSED" : " FAILED") +
191 " using validator " + fValidator);
192 }
193 }
194 }
195 catch (Exception e)
196 {
197 success = false;
198 String msg = "validator " + fValidator + " threw exception: " + e.getMessage();
199 populationLog.error(msg);
200 populationLog.error(e.getMessage(), e);
201 }
202
203 if(!success) succeeded = false;
204
205 return succeeded;
206 }
207
208
209 private boolean doValidationForOneField(
210 MultiHashMap fieldValidators,
211 ControllerContext cctx,
212 FormBeanContext formBeanContext,
213 boolean succeeded,
214 String name)
215 {
216
217 Collection propertyValidators =
218 getFieldValidatorsForField(name, fieldValidators);
219
220
221 if(propertyValidators != null)
222 {
223 try
224 {
225 succeeded = doValidationForOneField(
226 cctx, formBeanContext, succeeded,
227 name, propertyValidators);
228 }
229 catch (Exception e)
230 {
231 succeeded = false;
232 populationLog.error(e.getMessage(), e);
233 }
234 }
235
236 return succeeded;
237 }
238
239
240 private List getFieldValidatorsForField(
241 String name, MultiHashMap fieldValidators)
242 {
243 List propertyValidators = null;
244 propertyValidators = getFieldValidatorsForFieldRecursively(
245 name, fieldValidators, propertyValidators);
246 return propertyValidators;
247 }
248
249
250
251
252
253
254
255
256
257
258
259
260 private List getFieldValidatorsForFieldRecursively(
261 String currentName, MultiHashMap fieldValidators, List propertyValidators)
262 {
263 List validators = (List)fieldValidators.get(currentName);
264 if(validators != null)
265 {
266 if(propertyValidators == null) propertyValidators = new ArrayList();
267 propertyValidators.addAll(validators);
268 }
269
270 int delim = 0;
271 for(int i = 0; i < BREAKSYMBOLS.length; i++)
272 {
273 int ix = currentName.lastIndexOf(BREAKSYMBOLS[i]);
274 if(ix > -1)
275 {
276 delim = ix;
277 break;
278 }
279 }
280
281 if(delim > 0)
282 {
283
284 currentName = currentName.substring(0, delim);
285 propertyValidators = getFieldValidatorsForFieldRecursively(
286 currentName, fieldValidators, propertyValidators);
287 }
288
289 return propertyValidators;
290 }
291
292
293 private boolean doValidationForOneField(
294 ControllerContext cctx,
295 FormBeanContext formBeanContext,
296 boolean succeeded,
297 String name,
298 Collection propertyValidators)
299 throws Exception
300 {
301
302
303
304
305
306
307
308 Object value = Ognl.getValue(name, formBeanContext.getBean());
309
310
311 for(Iterator j = propertyValidators.iterator(); j.hasNext(); )
312 {
313 FieldValidator validator = (FieldValidator)j.next();
314 boolean validateField = true;
315
316 if(validator instanceof ValidationRuleDependend)
317 {
318 ValidationActivationRule rule =
319 ((ValidationRuleDependend)validator)
320 .getValidationActivationRule();
321 if(rule != null)
322 {
323 validateField = rule.allowValidation(cctx, formBeanContext);
324
325 if(populationLog.isDebugEnabled())
326 {
327 populationLog.debug( name + ": rule " + rule +
328 ((validateField) ? " ALLOWS" : " DISALLOWS") +
329 " validation with " + validator);
330 }
331 }
332 }
333
334 if(validateField)
335 {
336
337 boolean success;
338 try
339 {
340 success = validator.isValid(cctx, formBeanContext, name, value);
341 }
342 catch (Exception e)
343 {
344 String msg = "validator " + validator + " threw exception: " +
345 e.getMessage() + " on property " + name + " with value " +
346 value;
347 populationLog.error(msg);
348 throw e;
349 }
350
351 if(populationLog.isDebugEnabled())
352 {
353 populationLog.debug( "validation" +
354 ((success) ? " PASSED" : " FAILED") +
355 " for field " + name + " using validator " + validator);
356 }
357
358 if(!success)
359 {
360 succeeded = false;
361 ctrl.setOverrideField(
362 cctx, formBeanContext, name, value, null, validator);
363 break;
364 }
365 }
366 }
367 return succeeded;
368 }
369
370 /***
371 * @return char[]
372 */
373 public static char[] getBREAKSYMBOLS()
374 {
375 return BREAKSYMBOLS;
376 }
377
378 /***
379 * @param cs
380 */
381 public static void setBREAKSYMBOLS(char[] cs)
382 {
383 BREAKSYMBOLS = cs;
384 }
385
386 }