1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.dbforms.validation;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.commons.validator.Field;
29 import org.apache.commons.validator.GenericValidator;
30 import org.apache.commons.validator.ValidatorAction;
31
32 import org.dbforms.config.DbFormsErrors;
33 import org.dbforms.config.FieldValue;
34 import org.dbforms.config.FieldValues;
35 import org.dbforms.config.ValidationException;
36
37 import org.dbforms.util.Util;
38
39 import java.io.Serializable;
40
41 import java.util.Locale;
42 import java.util.Vector;
43
44
45
46 /**********************************************************************************************
47 * <p>This class performs validations.
48 * The parameters of methods must match the "methodParams" in "validator-rules.xml" file. </p>
49 *
50 * @author Eric Beaumier
51 *********************************************************************************************/
52 public class DbFormsValidator implements Serializable {
53 private static Log logCat = LogFactory.getLog(DbFormsValidator.class
54 .getName());
55 private static final String REQUIRED = "required";
56 private static final String MASK = "mask";
57 private static final String RANGE = "range";
58 private static final String MINLENGTH = "minlength";
59 private static final String MAXLENGTH = "maxlength";
60 private static final String BYTE = "byte";
61 private static final String SHORT = "short";
62 private static final String LONG = "long";
63 private static final String INTEGER = "integer";
64 private static final String FLOAT = "float";
65 private static final String DOUBLE = "double";
66 private static final String DATE = "date";
67 private static final String CREDITCARD = "creditcard";
68 private static final String EMAIL = "email";
69
70 /*********************************************************************************************
71 * <p>Checks if the field can safely be converted to a byte primitive.</p>
72 *
73 * @param bean The bean validation is being performed on.
74 * @param va The <code>ValidatorAction</code> used to retrieve validator information.
75 * @param field The <code>Field</code> object associated with the current field being validated.
76 * @param errors The <code>Vector</code> object used by DBForms to add errors to if any validation errors occur.
77 * @param locale The <code>Locale</code> object of the Request.
78 * @param dbFormsErrors DbForms Error class to retrieve error message in DbForm-Errors.xml format.
79 ********************************************************************************************/
80 public static boolean validateByte(Object bean,
81 ValidatorAction va,
82 Field field,
83 Vector errors,
84 Locale locale,
85 DbFormsErrors dbFormsErrors) {
86 String value = getValue(bean, field);
87
88 if (!Util.isNull(value)) {
89 if (!GenericValidator.isByte(value)) {
90 errors.add(new ValidationException(dbFormsErrorMessage(BYTE, va,
91 field,
92 locale,
93 dbFormsErrors)));
94
95 return false;
96 } else {
97 return true;
98 }
99 }
100
101 return true;
102 }
103
104
105 /*********************************************************************************************
106 * <p>Checks if the field is a valid credit card number.</p>
107 * <p>Translated to Java by Ted Husted (<a href="mailto:husted@apache.org">husted@apache.org</a>).<br>
108 * Reference Sean M. Burke's script at http://www.ling.nwu.edu/~sburke/pub/luhn_lib.pl</p>
109 *
110 * @param bean The bean validation is being performed on.
111 * @param va The <code>ValidatorAction</code> used to retrieve validator information.
112 * @param field The <code>Field</code> object associated with the current field being validated.
113 * @param errors The <code>Vector</code> object used by DBForms to add errors to if any validation errors occur.
114 * @param locale The <code>Locale</code> object of the Request.
115 * @param dbFormsErrors DbForms Error class to retrieve error message in DbForm-Errors.xml format.
116 ********************************************************************************************/
117 public static boolean validateCreditCard(Object bean,
118 ValidatorAction va,
119 Field field,
120 Vector errors,
121 Locale locale,
122 DbFormsErrors dbFormsErrors) {
123 String value = getValue(bean, field);
124
125 if (!Util.isNull(value)) {
126 if (!GenericValidator.isCreditCard(value)) {
127 errors.add(new ValidationException(dbFormsErrorMessage(CREDITCARD,
128 va, field,
129 locale,
130 dbFormsErrors)));
131
132 return false;
133 }
134 }
135
136 return true;
137 }
138
139
140 /*********************************************************************************************
141 * <p>Checks if the field is a valid date. If the field has a datePattern variable,
142 * that will be used to format <code>java.text.SimpleDateFormat</code>. If the field
143 * has a datePatternStrict variable, that will be used to format
144 * <code>java.text.SimpleDateFormat</code> and the length will be checked so '2/12/1999'
145 * will not pass validation with the format 'MM/dd/yyyy' because the month isn't two digits.
146 * If no datePattern variable is specified, then the field gets the DateFormat.SHORT
147 * format for the locale. The setLenient method is set to <code>false</code> for all
148 * variations.</p>
149 *
150 * @param bean The bean validation is being performed on.
151 * @param va The <code>ValidatorAction</code> used to retrieve validator information.
152 * @param field The <code>Field</code> object associated with the current field being validated.
153 * @param errors The <code>Vector</code> object used by DBForms to add errors to if any validation errors occur.
154 * @param locale The <code>Locale</code> object of the Request.
155 * @param dbFormsErrors DbForms Error class to retrieve error message in DbForm-Errors.xml format.
156 ********************************************************************************************/
157 public static boolean validateDate(Object bean,
158 ValidatorAction va,
159 Field field,
160 Vector errors,
161 Locale locale,
162 DbFormsErrors dbFormsErrors) {
163 boolean bValid = true;
164 String value = getValue(bean, field);
165
166 if (!Util.isNull(value)) {
167 value = ((FieldValues) bean).get(field.getProperty())
168 .getFieldValue();
169
170 String datePattern = field.getVarValue("datePattern");
171 String datePatternStrict = field.getVarValue("datePatternStrict");
172
173 if (!GenericValidator.isBlankOrNull(value)) {
174 try {
175 if ((datePattern != null) && (datePattern.length() > 0)) {
176 bValid = GenericValidator.isDate(value, datePattern, false);
177 } else if (!Util.isNull(datePatternStrict)) {
178 bValid = GenericValidator.isDate(value, datePatternStrict,
179 true);
180 } else {
181 bValid = getValue(bean, field) != null;
182 }
183 } catch (Exception e) {
184 errors.add(new ValidationException(dbFormsErrorMessage(DATE, va,
185 field,
186 locale,
187 dbFormsErrors)));
188 bValid = false;
189 }
190 }
191 }
192
193 if (!bValid) {
194 errors.add(new ValidationException(dbFormsErrorMessage(DATE, va,
195 field, locale,
196 dbFormsErrors)));
197 }
198
199 return bValid;
200 }
201
202
203 /*********************************************************************************************
204 * <p>Checks if the field can safely be converted to a double primitive.</p>
205 *
206 * @param bean The bean validation is being performed on.
207 * @param va The <code>ValidatorAction</code> used to retrieve validator information.
208 * @param field The <code>Field</code> object associated with the current field being validated.
209 * @param errors The <code>Vector</code> object used by DBForms to add errors to if any validation errors occur.
210 * @param locale The <code>Locale</code> object of the Request.
211 * @param dbFormsErrors DbForms Error class to retrieve error message in DbForm-Errors.xml format.
212 ********************************************************************************************/
213 public static boolean validateDouble(Object bean,
214 ValidatorAction va,
215 Field field,
216 Vector errors,
217 Locale locale,
218 DbFormsErrors dbFormsErrors) {
219 String value = getValue(bean, field);
220
221 if (!Util.isNull(value)) {
222 if (!GenericValidator.isDouble(value)) {
223 errors.add(new ValidationException(dbFormsErrorMessage(DOUBLE, va,
224 field,
225 locale,
226 dbFormsErrors)));
227
228 return false;
229 } else {
230 return true;
231 }
232 }
233
234 return true;
235 }
236
237
238 /*********************************************************************************************
239 * <p>Checks if a field has a valid e-mail address.</p>
240 * <p>Based on a script by Sandeep V. Tamhankar (stamhankar@hotmail.com),
241 * http://javascript.internet.com</p>
242 *
243 * @param bean The bean validation is being performed on.
244 * @param va The <code>ValidatorAction</code> used to retrieve validator information.
245 * @param field The <code>Field</code> object associated with the current field being validated.
246 * @param errors The <code>Vector</code> object used by DBForms to add errors to if any validation errors occur.
247 * @param locale The <code>Locale</code> object of the Request.
248 * @param dbFormsErrors DbForms Error class to retrieve error message in DbForm-Errors.xml format.
249 ********************************************************************************************/
250 public static boolean validateEmail(Object bean,
251 ValidatorAction va,
252 Field field,
253 Vector errors,
254 Locale locale,
255 DbFormsErrors dbFormsErrors) {
256 String value = getValue(bean, field);
257
258 if (!Util.isNull(value)) {
259 if (!GenericValidator.isEmail(value)) {
260 errors.add(new ValidationException(dbFormsErrorMessage(EMAIL, va,
261 field,
262 locale,
263 dbFormsErrors)));
264
265 return false;
266 }
267 }
268
269 return true;
270 }
271
272
273 /*********************************************************************************************
274 * <p>Checks if the field can safely be converted to a float primitive.</p>
275 *
276 * @param bean The bean validation is being performed on.
277 * @param va The <code>ValidatorAction</code> used to retrieve validator information.
278 * @param field The <code>Field</code> object associated with the current field being validated.
279 * @param errors The <code>Vector</code> object used by DBForms to add errors to if any validation errors occur.
280 * @param locale The <code>Locale</code> object of the Request.
281 * @param dbFormsErrors DbForms Error class to retrieve error message in DbForm-Errors.xml format.
282 ********************************************************************************************/
283 public static boolean validateFloat(Object bean,
284 ValidatorAction va,
285 Field field,
286 Vector errors,
287 Locale locale,
288 DbFormsErrors dbFormsErrors) {
289 String value = getValue(bean, field);
290
291 if (!Util.isNull(value)) {
292 if (!GenericValidator.isFloat(value)) {
293 errors.add(new ValidationException(dbFormsErrorMessage(FLOAT, va,
294 field,
295 locale,
296 dbFormsErrors)));
297
298 return false;
299 } else {
300 return true;
301 }
302 }
303
304 return true;
305 }
306
307
308 /*********************************************************************************************
309 * <p>Checks if the field can safely be converted to an int primitive.</p>
310 *
311 * @param bean The bean validation is being performed on.
312 * @param va The <code>ValidatorAction</code> used to retrieve validator information.
313 * @param field The <code>Field</code> object associated with the current field being validated.
314 * @param errors The <code>Vector</code> object used by DBForms to add errors to if any validation errors occur.
315 * @param locale The <code>Locale</code> object of the Request.
316 * @param dbFormsErrors DbForms Error class to retrieve error message in DbForm-Errors.xml format.
317 ********************************************************************************************/
318 public static boolean validateInteger(Object bean,
319 ValidatorAction va,
320 Field field,
321 Vector errors,
322 Locale locale,
323 DbFormsErrors dbFormsErrors) {
324 String value = getValue(bean, field);
325
326 if (!Util.isNull(value)) {
327 if (!GenericValidator.isInt(value)) {
328 errors.add(new ValidationException(dbFormsErrorMessage(INTEGER, va,
329 field,
330 locale,
331 dbFormsErrors)));
332
333 return false;
334 } else {
335 return true;
336 }
337 }
338
339 return true;
340 }
341
342
343 /*********************************************************************************************
344 * <p>Checks if the field can safely be converted to a long primitive.</p>
345 *
346 * @param bean The bean validation is being performed on.
347 * @param va The <code>ValidatorAction</code> used to retrieve validator information.
348 * @param field The <code>Field</code> object associated with the current field being validated.
349 * @param errors The <code>Vector</code> object used by DBForms to add errors to if any validation errors occur.
350 * @param locale The <code>Locale</code> object of the Request.
351 * @param dbFormsErrors DbForms Error class to retrieve error message in DbForm-Errors.xml format.
352 ********************************************************************************************/
353 public static boolean validateLong(Object bean,
354 ValidatorAction va,
355 Field field,
356 Vector errors,
357 Locale locale,
358 DbFormsErrors dbFormsErrors) {
359 String value = getValue(bean, field);
360
361 if (!Util.isNull(value)) {
362 if (!GenericValidator.isLong(value)) {
363 errors.add(new ValidationException(dbFormsErrorMessage(LONG, va,
364 field,
365 locale,
366 dbFormsErrors)));
367
368 return false;
369 } else {
370 return true;
371 }
372 }
373
374 return true;
375 }
376
377
378 /**********************************************************************************************
379 * <p>Checks if the field matches the regular expression in the field's mask attribute.</p>
380 *
381 * @param bean The bean validation is being performed on.
382 * @param va The <code>ValidatorAction</code> used to retrieve validator information.
383 * @param field The <code>Field</code> object associated with the current field being validated.
384 * @param errors The <code>Vector</code> object used by DBForms to add errors to if any validation errors occur.
385 * @param locale The <code>Locale</code> object of the Request.
386 * @param dbFormsErrors DbForms Error class to retrieve error message in DbForm-Errors.xml format.
387 ********************************************************************************************/
388 public static boolean validateMask(Object bean,
389 ValidatorAction va,
390 Field field,
391 Vector errors,
392 Locale locale,
393 DbFormsErrors dbFormsErrors) {
394 String value = getValue(bean, field);
395
396 if (!Util.isNull(value)) {
397 String mask = field.getVarValue("mask");
398
399 if (!GenericValidator.isBlankOrNull(value)
400 && !GenericValidator.matchRegexp(value, mask)) {
401 errors.add(new ValidationException(dbFormsErrorMessage(MASK, va,
402 field,
403 locale,
404 dbFormsErrors)));
405
406 return false;
407 } else {
408 return true;
409 }
410 }
411
412 return true;
413 }
414
415
416 /*********************************************************************************************
417 * <p>Checks if the field's length is less than or equal to the maximum value. A <code>Null</code>
418 * will be considered an error.</p>
419 *
420 * @param bean The bean validation is being performed on.
421 * @param va The <code>ValidatorAction</code> used to retrieve validator information.
422 * @param field The <code>Field</code> object associated with the current field being validated.
423 * @param errors The <code>Vector</code> object used by DBForms to add errors to if any validation errors occur.
424 * @param locale The <code>Locale</code> object of the Request.
425 * @param dbFormsErrors DbForms Error class to retrieve error message in DbForm-Errors.xml format.
426 ********************************************************************************************/
427 public static boolean validateMaxLength(Object bean,
428 ValidatorAction va,
429 Field field,
430 Vector errors,
431 Locale locale,
432 DbFormsErrors dbFormsErrors) {
433 String value = getValue(bean, field);
434
435 if (!Util.isNull(value)) {
436 String sMaxLength = field.getVarValue("maxlength");
437 int max = Integer.parseInt(sMaxLength);
438
439 if (!GenericValidator.maxLength(value, max)) {
440 errors.add(new ValidationException(dbFormsErrorMessage(MAXLENGTH,
441 va, field,
442 locale,
443 dbFormsErrors)));
444
445 return false;
446 }
447 }
448
449 return true;
450 }
451
452
453 /*********************************************************************************************
454 * <p>Checks if the field's length is greater than or equal to the minimum value.
455 * A <code>Null</code> will be considered an error.</p>
456 *
457 * @param bean The bean validation is being performed on.
458 * @param va The <code>ValidatorAction</code> used to retrieve validator information.
459 * @param field The <code>Field</code> object associated with the current field being validated.
460 * @param errors The <code>Vector</code> object used by DBForms to add errors to if any validation errors occur.
461 * @param locale The <code>Locale</code> object of the Request.
462 * @param dbFormsErrors DbForms Error class to retrieve error message in DbForm-Errors.xml format.
463 ********************************************************************************************/
464 public static boolean validateMinLength(Object bean,
465 ValidatorAction va,
466 Field field,
467 Vector errors,
468 Locale locale,
469 DbFormsErrors dbFormsErrors) {
470 String value = getValue(bean, field);
471
472 if (!Util.isNull(value)) {
473 String sMinLength = field.getVarValue("minlength");
474
475 int min = Integer.parseInt(sMinLength);
476
477 if (!GenericValidator.minLength(value, min)) {
478 errors.add(new ValidationException(dbFormsErrorMessage(MINLENGTH,
479 va, field,
480 locale,
481 dbFormsErrors)));
482
483 return false;
484 }
485 }
486
487 return true;
488 }
489
490
491 /*********************************************************************************************
492 * <p>Checks if a fields value is within a range (min & max specified
493 * in the vars attribute).</p>
494 *
495 * @param bean The bean validation is being performed on.
496 * @param va The <code>ValidatorAction</code> used to retrieve validator information.
497 * @param field The <code>Field</code> object associated with the current field being validated.
498 * @param errors The <code>Vector</code> object used by DBForms to add errors to if any validation errors occur.
499 * @param locale The <code>Locale</code> object of the Request.
500 * @param dbFormsErrors DbForms Error class to retrieve error message in DbForm-Errors.xml format.
501 ********************************************************************************************/
502 public static boolean validateRange(Object bean,
503 ValidatorAction va,
504 Field field,
505 Vector errors,
506 Locale locale,
507 DbFormsErrors dbFormsErrors) {
508 String value = getValue(bean, field);
509
510 if (!Util.isNull(value)) {
511 String sMin = field.getVarValue("min");
512 String sMax = field.getVarValue("max");
513 double iValue = Double.parseDouble(value);
514 double min = Double.parseDouble(sMin);
515 double max = Double.parseDouble(sMax);
516
517 if (!GenericValidator.isInRange(iValue, min, max)) {
518 errors.add(new ValidationException(dbFormsErrorMessage(RANGE, va,
519 field,
520 locale,
521 dbFormsErrors)));
522
523 return false;
524 }
525 }
526
527 return true;
528 }
529
530
531 /**********************************************************************************************
532 * <p>Checks if the field isn't null and length of the field is greater than zero not
533 * including whitespace.</p>
534 *
535 * @param bean The bean validation is being performed on.
536 * @param va The <code>ValidatorAction</code> used to retrieve validator information.
537 * @param field The <code>Field</code> object associated with the current field being validated.
538 * @param errors The <code>Vector</code> object used by DBForms to add errors to, if any validation errors occur.
539 * @param locale The <code>Locale</code> object of the Request.
540 * @param dbFormsErrors DbForms Error class to retrieve error message in DbForm-Errors.xml format.
541 ********************************************************************************************/
542 public static boolean validateRequired(Object bean,
543 ValidatorAction va,
544 Field field,
545 Vector errors,
546 Locale locale,
547 DbFormsErrors dbFormsErrors) {
548 FieldValues hash = (FieldValues) bean;
549
550 if (Util.isNull(field.getProperty())) {
551 return true;
552 }
553
554 FieldValue f = hash.get(field.getProperty());
555
556 if (f == null) {
557
558
559 return true;
560 }
561
562 /*********************************************
563 * Grunikiewicz.philip@hydro.qc.ca
564 * 2003-12-03
565 *
566 * When a validation returns multiple errors and the user corrects these problems one at a time,
567 * it is important to verify that the value is not null or empty.
568 */
569 if (f.getFieldValue()
570 .equals(f.getOldValue())
571 && !(Util.isNull(f.getFieldValue()))) {
572
573 return true;
574 }
575
576 String value = null;
577 Object obj = f.getFieldValueAsObject();
578
579 if (obj != null) {
580 value = obj.toString();
581 }
582
583 if (GenericValidator.isBlankOrNull(value)) {
584 errors.add(new ValidationException(dbFormsErrorMessage(REQUIRED, va,
585 field, locale,
586 dbFormsErrors)));
587
588 return false;
589 } else {
590 return true;
591 }
592 }
593
594
595 /*********************************************************************************************
596 * <p>Checks if the field can safely be converted to a short primitive.</p>
597 *
598 * @param bean The bean validation is being performed on.
599 * @param va The <code>ValidatorAction</code> used to retrieve validator information.
600 * @param field The <code>Field</code> object associated with the current field being validated.
601 * @param errors The <code>Vector</code> object used by DBForms to add errors to if any validation errors occur.
602 * @param locale The <code>Locale</code> object of the Request.
603 * @param dbFormsErrors DbForms Error class to retrieve error message in DbForm-Errors.xml format.
604 ********************************************************************************************/
605 public static boolean validateShort(Object bean,
606 ValidatorAction va,
607 Field field,
608 Vector errors,
609 Locale locale,
610 DbFormsErrors dbFormsErrors) {
611 String value = getValue(bean, field);
612
613 if (!Util.isNull(value)) {
614 if (!GenericValidator.isShort(value)) {
615 errors.add(new ValidationException(dbFormsErrorMessage(SHORT, va,
616 field,
617 locale,
618 dbFormsErrors)));
619
620 return false;
621 } else {
622 return true;
623 }
624 }
625
626 return true;
627 }
628
629
630 //****************************************************************************************************
631 //*** P R I V A T E
632 //***************************************************************************************************
633 private static String getValue(Object bean,
634 Field field) {
635 try {
636 FieldValues hash = (FieldValues) bean;
637
638 if (Util.isNull(field.getProperty())) {
639 return null;
640 }
641
642 FieldValue f = hash.get(field.getProperty());
643
644 if (f == null) {
645 // Field not found in fieldvector -> so it's not on current page.
646 // So we will not check it!
647 return null;
648 }
649
650 /********************************************
651 * Grunikiewicz.philip@hydro.qc.ca
652 * 2003-12-04
653 *
654 * When inserting new data, it can happen that a default value is assigned.
655 * Hence the old value and new value are identical.
656 * Does this mean that we should not validate it! I don't think so...
657 *
658 * Henner.Kollmann@gmx.de
659 * 2003-12-05
660 *
661 * in isertmode oldvalue is alway empty now, so that check will be true!
662 * if you do not do this compare all values on form will be validated. This
663 * may leed to unexpected validation if the values in the database are wrong
664 */
665 if (f.getFieldValue()
666 .equals(f.getOldValue())) {
667
668 return null;
669 }
670
671 String value = null;
672 Object obj = f.getFieldValueAsObject();
673
674 if (obj != null) {
675 value = obj.toString();
676 } else {
677 value = f.getFieldValue();
678 }
679
680 return value;
681 } catch (Exception e) {
682 logCat.error(e);
683
684 return null;
685 }
686 }
687
688
689 /*********************************************************************************************
690 * <p>Generate error message with the ResourceBundle error format if enable or
691 * DBForms error standard format (dbforms_error.xml).
692 *</p>
693 *
694 * @param type Type name to retrieve <msg name="..."> and <arg name="..."> keys.
695 * @param va The <code>ValidatorAction</code> object associated with the current field.
696 * @param field The <code>Field</code> object associated with the current field being validated.
697 * @param locale The <code>Locale</code> object of the Request.
698 * @param dbFormsErrors DbForms Error class to retrieve error message in DbForm-Errors.xml format.
699 ********************************************************************************************/
700 private static String dbFormsErrorMessage(String type,
701 ValidatorAction va,
702 Field field,
703 Locale locale,
704 DbFormsErrors dbFormsErrors) {
705
706 String message = DbFormsValidatorUtil.getMessage(type, va, locale, field,
707 dbFormsErrors);
708
709 return message;
710 }
711 }