1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.struts.validator;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.commons.validator.Field;
26 import org.apache.commons.validator.GenericTypeValidator;
27 import org.apache.commons.validator.GenericValidator;
28 import org.apache.commons.validator.UrlValidator;
29 import org.apache.commons.validator.Validator;
30 import org.apache.commons.validator.ValidatorAction;
31 import org.apache.commons.validator.util.ValidatorUtils;
32 import org.apache.struts.action.ActionMessage;
33 import org.apache.struts.action.ActionMessages;
34 import org.apache.struts.util.MessageResources;
35 import org.apache.struts.util.RequestUtils;
36
37 import javax.servlet.http.HttpServletRequest;
38
39 import java.io.Serializable;
40
41 import java.util.Locale;
42 import java.util.StringTokenizer;
43
44 /**
45 * <p> This class contains the default validations that are used in the
46 * validator-rules.xml file. </p> <p> In general passing in a null or blank
47 * will return a null Object or a false boolean. However, nulls and blanks do
48 * not result in an error being added to the errors. </p>
49 *
50 * @since Struts 1.1
51 */
52 public class FieldChecks implements Serializable {
53 /**
54 * Commons Logging instance.
55 */
56 private static final Log log = LogFactory.getLog(FieldChecks.class);
57
58 /**
59 * The message resources for this package.
60 */
61 private static MessageResources sysmsgs =
62 MessageResources.getMessageResources(
63 "org.apache.struts.validator.LocalStrings");
64 public static final String FIELD_TEST_NULL = "NULL";
65 public static final String FIELD_TEST_NOTNULL = "NOTNULL";
66 public static final String FIELD_TEST_EQUAL = "EQUAL";
67
68 /**
69 * Checks if the field isn't null and length of the field is greater than
70 * zero not including whitespace.
71 *
72 * @param bean The bean validation is being performed on.
73 * @param va The <code>ValidatorAction</code> that is currently
74 * being performed.
75 * @param field The <code>Field</code> object associated with the
76 * current field being validated.
77 * @param errors The <code>ActionMessages</code> object to add errors
78 * to if any validation errors occur.
79 * @param validator The <code>Validator</code> instance, used to access
80 * other field values.
81 * @param request Current request object.
82 * @return true if meets stated requirements, false otherwise.
83 */
84 public static boolean validateRequired(Object bean, ValidatorAction va,
85 Field field, ActionMessages errors, Validator validator,
86 HttpServletRequest request) {
87 String value = null;
88
89 value = evaluateBean(bean, field);
90
91 if (GenericValidator.isBlankOrNull(value)) {
92 errors.add(field.getKey(),
93 Resources.getActionMessage(validator, request, va, field));
94
95 return false;
96 } else {
97 return true;
98 }
99 }
100
101 /**
102 * Checks if the field isn't null based on the values of other fields.
103 *
104 * @param bean The bean validation is being performed on.
105 * @param va The <code>ValidatorAction</code> that is currently
106 * being performed.
107 * @param field The <code>Field</code> object associated with the
108 * current field being validated.
109 * @param errors The <code>ActionMessages</code> object to add errors
110 * to if any validation errors occur.
111 * @param validator The <code>Validator</code> instance, used to access
112 * other field values.
113 * @param request Current request object.
114 * @return true if meets stated requirements, false otherwise.
115 */
116 public static boolean validateRequiredIf(Object bean, ValidatorAction va,
117 Field field, ActionMessages errors, Validator validator,
118 HttpServletRequest request) {
119 Object form =
120 validator.getParameterValue(org.apache.commons.validator.Validator.BEAN_PARAM);
121 String value = null;
122 boolean required = false;
123
124 value = evaluateBean(bean, field);
125
126 int i = 0;
127 String fieldJoin = "AND";
128
129 if (!GenericValidator.isBlankOrNull(field.getVarValue("fieldJoin"))) {
130 fieldJoin = field.getVarValue("fieldJoin");
131 }
132
133 if (fieldJoin.equalsIgnoreCase("AND")) {
134 required = true;
135 }
136
137 while (!GenericValidator.isBlankOrNull(field.getVarValue("field[" + i
138 + "]"))) {
139 String dependProp = field.getVarValue("field[" + i + "]");
140 String dependTest = field.getVarValue("fieldTest[" + i + "]");
141 String dependTestValue = field.getVarValue("fieldValue[" + i + "]");
142 String dependIndexed = field.getVarValue("fieldIndexed[" + i + "]");
143
144 if (dependIndexed == null) {
145 dependIndexed = "false";
146 }
147
148 String dependVal = null;
149 boolean thisRequired = false;
150
151 if (field.isIndexed() && dependIndexed.equalsIgnoreCase("true")) {
152 String key = field.getKey();
153
154 if ((key.indexOf("[") > -1) && (key.indexOf("]") > -1)) {
155 String ind = key.substring(0, key.indexOf(".") + 1);
156
157 dependProp = ind + dependProp;
158 }
159 }
160
161 dependVal = ValidatorUtils.getValueAsString(form, dependProp);
162
163 if (dependTest.equals(FIELD_TEST_NULL)) {
164 if ((dependVal != null) && (dependVal.length() > 0)) {
165 thisRequired = false;
166 } else {
167 thisRequired = true;
168 }
169 }
170
171 if (dependTest.equals(FIELD_TEST_NOTNULL)) {
172 if ((dependVal != null) && (dependVal.length() > 0)) {
173 thisRequired = true;
174 } else {
175 thisRequired = false;
176 }
177 }
178
179 if (dependTest.equals(FIELD_TEST_EQUAL)) {
180 thisRequired = dependTestValue.equalsIgnoreCase(dependVal);
181 }
182
183 if (fieldJoin.equalsIgnoreCase("AND")) {
184 required = required && thisRequired;
185 } else {
186 required = required || thisRequired;
187 }
188
189 i++;
190 }
191
192 if (required) {
193 if (GenericValidator.isBlankOrNull(value)) {
194 errors.add(field.getKey(),
195 Resources.getActionMessage(validator, request, va, field));
196
197 return false;
198 } else {
199 return true;
200 }
201 }
202
203 return true;
204 }
205
206 /**
207 * Checks if the field matches the regular expression in the field's mask
208 * attribute.
209 *
210 * @param bean The bean validation is being performed on.
211 * @param va The <code>ValidatorAction</code> that is currently
212 * being performed.
213 * @param field The <code>Field</code> object associated with the
214 * current field being validated.
215 * @param errors The <code>ActionMessages</code> object to add errors
216 * to if any validation errors occur.
217 * @param validator The <code>Validator</code> instance, used to access
218 * other field values.
219 * @param request Current request object.
220 * @return true if field matches mask, false otherwise.
221 */
222 public static boolean validateMask(Object bean, ValidatorAction va,
223 Field field, ActionMessages errors, Validator validator,
224 HttpServletRequest request) {
225 String value = null;
226
227 value = evaluateBean(bean, field);
228
229 try {
230 String mask =
231 Resources.getVarValue("mask", field, validator, request, true);
232
233 if (value != null && value.length()>0
234 && !GenericValidator.matchRegexp(value, mask)) {
235 errors.add(field.getKey(),
236 Resources.getActionMessage(validator, request, va, field));
237
238 return false;
239 } else {
240 return true;
241 }
242 } catch (Exception e) {
243 processFailure(errors, field, "mask", e);
244
245 return false;
246 }
247 }
248
249 /**
250 * Checks if the field can safely be converted to a byte primitive.
251 *
252 * @param bean The bean validation is being performed on.
253 * @param va The <code>ValidatorAction</code> that is currently
254 * being performed.
255 * @param field The <code>Field</code> object associated with the
256 * current field being validated.
257 * @param errors The <code>ActionMessages</code> object to add errors
258 * to if any validation errors occur.
259 * @param validator The <code>Validator</code> instance, used to access
260 * other field values.
261 * @param request Current request object.
262 * @return true if valid, false otherwise.
263 */
264 public static Object validateByte(Object bean, ValidatorAction va,
265 Field field, ActionMessages errors, Validator validator,
266 HttpServletRequest request) {
267 Object result = null;
268 String value = null;
269
270 value = evaluateBean(bean, field);
271
272 if (GenericValidator.isBlankOrNull(value)) {
273 return Boolean.TRUE;
274 }
275
276 result = GenericTypeValidator.formatByte(value);
277
278 if (result == null) {
279 errors.add(field.getKey(),
280 Resources.getActionMessage(validator, request, va, field));
281 }
282
283 return (result == null) ? Boolean.FALSE : result;
284 }
285
286 /**
287 * Checks if the field can safely be converted to a byte primitive.
288 *
289 * @param bean The bean validation is being performed on.
290 * @param va The <code>ValidatorAction</code> that is currently
291 * being performed.
292 * @param field The <code>Field</code> object associated with the
293 * current field being validated.
294 * @param errors The <code>ActionMessages</code> object to add errors
295 * to if any validation errors occur.
296 * @param validator The <code>Validator</code> instance, used to access
297 * other field values.
298 * @param request Current request object.
299 * @return true if valid, false otherwise.
300 */
301 public static Object validateByteLocale(Object bean, ValidatorAction va,
302 Field field, ActionMessages errors, Validator validator,
303 HttpServletRequest request) {
304 Object result = null;
305 String value = null;
306
307 value = evaluateBean(bean, field);
308
309 if (GenericValidator.isBlankOrNull(value)) {
310 return Boolean.TRUE;
311 }
312
313 Locale locale = RequestUtils.getUserLocale(request, null);
314
315 result = GenericTypeValidator.formatByte(value, locale);
316
317 if (result == null) {
318 errors.add(field.getKey(),
319 Resources.getActionMessage(validator, request, va, field));
320 }
321
322 return (result == null) ? Boolean.FALSE : result;
323 }
324
325 /**
326 * @param bean
327 * @param field
328 * @return
329 */
330 private static String evaluateBean(Object bean, Field field) {
331 String value;
332
333 if (isString(bean)) {
334 value = (String) bean;
335 } else {
336 value = ValidatorUtils.getValueAsString(bean, field.getProperty());
337 }
338
339 return value;
340 }
341
342 /**
343 * Checks if the field can safely be converted to a short primitive.
344 *
345 * @param bean The bean validation is being performed on.
346 * @param va The <code>ValidatorAction</code> that is currently
347 * being performed.
348 * @param field The <code>Field</code> object associated with the
349 * current field being validated.
350 * @param errors The <code>ActionMessages</code> object to add errors
351 * to if any validation errors occur.
352 * @param validator The <code>Validator</code> instance, used to access
353 * other field values.
354 * @param request Current request object.
355 * @return true if valid, false otherwise.
356 */
357 public static Object validateShort(Object bean, ValidatorAction va,
358 Field field, ActionMessages errors, Validator validator,
359 HttpServletRequest request) {
360 Object result = null;
361 String value = null;
362
363 value = evaluateBean(bean, field);
364
365 if (GenericValidator.isBlankOrNull(value)) {
366 return Boolean.TRUE;
367 }
368
369 result = GenericTypeValidator.formatShort(value);
370
371 if (result == null) {
372 errors.add(field.getKey(),
373 Resources.getActionMessage(validator, request, va, field));
374 }
375
376 return (result == null) ? Boolean.FALSE : result;
377 }
378
379 /**
380 * Checks if the field can safely be converted to a short primitive.
381 *
382 * @param bean The bean validation is being performed on.
383 * @param va The <code>ValidatorAction</code> that is currently
384 * being performed.
385 * @param field The <code>Field</code> object associated with the
386 * current field being validated.
387 * @param errors The <code>ActionMessages</code> object to add errors
388 * to if any validation errors occur.
389 * @param validator The <code>Validator</code> instance, used to access
390 * other field values.
391 * @param request Current request object.
392 * @return true if valid, false otherwise.
393 */
394 public static Object validateShortLocale(Object bean, ValidatorAction va,
395 Field field, ActionMessages errors, Validator validator,
396 HttpServletRequest request) {
397 Object result = null;
398 String value = null;
399
400 value = evaluateBean(bean, field);
401
402 if (GenericValidator.isBlankOrNull(value)) {
403 return Boolean.TRUE;
404 }
405
406 Locale locale = RequestUtils.getUserLocale(request, null);
407
408 result = GenericTypeValidator.formatShort(value, locale);
409
410 if (result == null) {
411 errors.add(field.getKey(),
412 Resources.getActionMessage(validator, request, va, field));
413 }
414
415 return (result == null) ? Boolean.FALSE : result;
416 }
417
418 /**
419 * Checks if the field can safely be converted to an int primitive.
420 *
421 * @param bean The bean validation is being performed on.
422 * @param va The <code>ValidatorAction</code> that is currently
423 * being performed.
424 * @param field The <code>Field</code> object associated with the
425 * current field being validated.
426 * @param errors The <code>ActionMessages</code> object to add errors
427 * to if any validation errors occur.
428 * @param validator The <code>Validator</code> instance, used to access
429 * other field values.
430 * @param request Current request object.
431 * @return true if valid, false otherwise.
432 */
433 public static Object validateInteger(Object bean, ValidatorAction va,
434 Field field, ActionMessages errors, Validator validator,
435 HttpServletRequest request) {
436 Object result = null;
437 String value = null;
438
439 value = evaluateBean(bean, field);
440
441 if (GenericValidator.isBlankOrNull(value)) {
442 return Boolean.TRUE;
443 }
444
445 result = GenericTypeValidator.formatInt(value);
446
447 if (result == null) {
448 errors.add(field.getKey(),
449 Resources.getActionMessage(validator, request, va, field));
450 }
451
452 return (result == null) ? Boolean.FALSE : result;
453 }
454
455 /**
456 * Checks if the field can safely be converted to an int primitive.
457 *
458 * @param bean The bean validation is being performed on.
459 * @param va The <code>ValidatorAction</code> that is currently
460 * being performed.
461 * @param field The <code>Field</code> object associated with the
462 * current field being validated.
463 * @param errors The <code>ActionMessages</code> object to add errors
464 * to if any validation errors occur.
465 * @param validator The <code>Validator</code> instance, used to access
466 * other field values.
467 * @param request Current request object.
468 * @return true if valid, false otherwise.
469 */
470 public static Object validateIntegerLocale(Object bean, ValidatorAction va,
471 Field field, ActionMessages errors, Validator validator,
472 HttpServletRequest request) {
473 Object result = null;
474 String value = null;
475
476 value = evaluateBean(bean, field);
477
478 if (GenericValidator.isBlankOrNull(value)) {
479 return Boolean.TRUE;
480 }
481
482 Locale locale = RequestUtils.getUserLocale(request, null);
483
484 result = GenericTypeValidator.formatInt(value, locale);
485
486 if (result == null) {
487 errors.add(field.getKey(),
488 Resources.getActionMessage(validator, request, va, field));
489 }
490
491 return (result == null) ? Boolean.FALSE : result;
492 }
493
494 /**
495 * Checks if the field can safely be converted to a long primitive.
496 *
497 * @param bean The bean validation is being performed on.
498 * @param va The <code>ValidatorAction</code> that is currently
499 * being performed.
500 * @param field The <code>Field</code> object associated with the
501 * current field being validated.
502 * @param errors The <code>ActionMessages</code> object to add errors
503 * to if any validation errors occur.
504 * @param validator The <code>Validator</code> instance, used to access
505 * other field values.
506 * @param request Current request object.
507 * @return true if valid, false otherwise.
508 */
509 public static Object validateLong(Object bean, ValidatorAction va,
510 Field field, ActionMessages errors, Validator validator,
511 HttpServletRequest request) {
512 Object result = null;
513 String value = null;
514
515 value = evaluateBean(bean, field);
516
517 if (GenericValidator.isBlankOrNull(value)) {
518 return Boolean.TRUE;
519 }
520
521 result = GenericTypeValidator.formatLong(value);
522
523 if (result == null) {
524 errors.add(field.getKey(),
525 Resources.getActionMessage(validator, request, va, field));
526 }
527
528 return (result == null) ? Boolean.FALSE : result;
529 }
530
531 /**
532 * Checks if the field can safely be converted to a long primitive.
533 *
534 * @param bean The bean validation is being performed on.
535 * @param va The <code>ValidatorAction</code> that is currently
536 * being performed.
537 * @param field The <code>Field</code> object associated with the
538 * current field being validated.
539 * @param errors The <code>ActionMessages</code> object to add errors
540 * to if any validation errors occur.
541 * @param validator The <code>Validator</code> instance, used to access
542 * other field values.
543 * @param request Current request object.
544 * @return true if valid, false otherwise.
545 */
546 public static Object validateLongLocale(Object bean, ValidatorAction va,
547 Field field, ActionMessages errors, Validator validator,
548 HttpServletRequest request) {
549 Object result = null;
550 String value = null;
551
552 value = evaluateBean(bean, field);
553
554 if (GenericValidator.isBlankOrNull(value)) {
555 return Boolean.TRUE;
556 }
557
558 Locale locale = RequestUtils.getUserLocale(request, null);
559
560 result = GenericTypeValidator.formatLong(value, locale);
561
562 if (result == null) {
563 errors.add(field.getKey(),
564 Resources.getActionMessage(validator, request, va, field));
565 }
566
567 return (result == null) ? Boolean.FALSE : result;
568 }
569
570 /**
571 * Checks if the field can safely be converted to a float primitive.
572 *
573 * @param bean The bean validation is being performed on.
574 * @param va The <code>ValidatorAction</code> that is currently
575 * being performed.
576 * @param field The <code>Field</code> object associated with the
577 * current field being validated.
578 * @param errors The <code>ActionMessages</code> object to add errors
579 * to if any validation errors occur.
580 * @param validator The <code>Validator</code> instance, used to access
581 * other field values.
582 * @param request Current request object.
583 * @return true if valid, false otherwise.
584 */
585 public static Object validateFloat(Object bean, ValidatorAction va,
586 Field field, ActionMessages errors, Validator validator,
587 HttpServletRequest request) {
588 Object result = null;
589 String value = null;
590
591 value = evaluateBean(bean, field);
592
593 if (GenericValidator.isBlankOrNull(value)) {
594 return Boolean.TRUE;
595 }
596
597 result = GenericTypeValidator.formatFloat(value);
598
599 if (result == null) {
600 errors.add(field.getKey(),
601 Resources.getActionMessage(validator, request, va, field));
602 }
603
604 return (result == null) ? Boolean.FALSE : result;
605 }
606
607 /**
608 * Checks if the field can safely be converted to a float primitive.
609 *
610 * @param bean The bean validation is being performed on.
611 * @param va The <code>ValidatorAction</code> that is currently
612 * being performed.
613 * @param field The <code>Field</code> object associated with the
614 * current field being validated.
615 * @param errors The <code>ActionMessages</code> object to add errors
616 * to if any validation errors occur.
617 * @param validator The <code>Validator</code> instance, used to access
618 * other field values.
619 * @param request Current request object.
620 * @return true if valid, false otherwise.
621 */
622 public static Object validateFloatLocale(Object bean, ValidatorAction va,
623 Field field, ActionMessages errors, Validator validator,
624 HttpServletRequest request) {
625 Object result = null;
626 String value = null;
627
628 value = evaluateBean(bean, field);
629
630 if (GenericValidator.isBlankOrNull(value)) {
631 return Boolean.TRUE;
632 }
633
634 Locale locale = RequestUtils.getUserLocale(request, null);
635
636 result = GenericTypeValidator.formatFloat(value, locale);
637
638 if (result == null) {
639 errors.add(field.getKey(),
640 Resources.getActionMessage(validator, request, va, field));
641 }
642
643 return (result == null) ? Boolean.FALSE : result;
644 }
645
646 /**
647 * Checks if the field can safely be converted to a double primitive.
648 *
649 * @param bean The bean validation is being performed on.
650 * @param va The <code>ValidatorAction</code> that is currently
651 * being performed.
652 * @param field The <code>Field</code> object associated with the
653 * current field being validated.
654 * @param errors The <code>ActionMessages</code> object to add errors
655 * to if any validation errors occur.
656 * @param validator The <code>Validator</code> instance, used to access
657 * other field values.
658 * @param request Current request object.
659 * @return true if valid, false otherwise.
660 */
661 public static Object validateDouble(Object bean, ValidatorAction va,
662 Field field, ActionMessages errors, Validator validator,
663 HttpServletRequest request) {
664 Object result = null;
665 String value = null;
666
667 value = evaluateBean(bean, field);
668
669 if (GenericValidator.isBlankOrNull(value)) {
670 return Boolean.TRUE;
671 }
672
673 result = GenericTypeValidator.formatDouble(value);
674
675 if (result == null) {
676 errors.add(field.getKey(),
677 Resources.getActionMessage(validator, request, va, field));
678 }
679
680 return (result == null) ? Boolean.FALSE : result;
681 }
682
683 /**
684 * Checks if the field can safely be converted to a double primitive.
685 *
686 * @param bean The bean validation is being performed on.
687 * @param va The <code>ValidatorAction</code> that is currently
688 * being performed.
689 * @param field The <code>Field</code> object associated with the
690 * current field being validated.
691 * @param errors The <code>ActionMessages</code> object to add errors
692 * to if any validation errors occur.
693 * @param validator The <code>Validator</code> instance, used to access
694 * other field values.
695 * @param request Current request object.
696 * @return true if valid, false otherwise.
697 */
698 public static Object validateDoubleLocale(Object bean, ValidatorAction va,
699 Field field, ActionMessages errors, Validator validator,
700 HttpServletRequest request) {
701 Object result = null;
702 String value = null;
703
704 value = evaluateBean(bean, field);
705
706 if (GenericValidator.isBlankOrNull(value)) {
707 return Boolean.TRUE;
708 }
709
710 Locale locale = RequestUtils.getUserLocale(request, null);
711
712 result = GenericTypeValidator.formatDouble(value, locale);
713
714 if (result == null) {
715 errors.add(field.getKey(),
716 Resources.getActionMessage(validator, request, va, field));
717 }
718
719 return (result == null) ? Boolean.FALSE : result;
720 }
721
722 /**
723 * Checks if the field is a valid date. If the field has a datePattern
724 * variable, that will be used to format <code>java.text.SimpleDateFormat</code>.
725 * If the field has a datePatternStrict variable, that will be used to
726 * format <code>java.text.SimpleDateFormat</code> and the length will be
727 * checked so '2/12/1999' will not pass validation with the format
728 * 'MM/dd/yyyy' because the month isn't two digits. If no datePattern
729 * variable is specified, then the field gets the DateFormat.SHORT format
730 * for the locale. The setLenient method is set to <code>false</code> for
731 * all variations.
732 *
733 * @param bean The bean validation is being performed on.
734 * @param va The <code>ValidatorAction</code> that is currently
735 * being performed.
736 * @param field The <code>Field</code> object associated with the
737 * current field being validated.
738 * @param errors The <code>ActionMessages</code> object to add errors
739 * to if any validation errors occur.
740 * @param validator The <code>Validator</code> instance, used to access
741 * other field values.
742 * @param request Current request object.
743 * @return true if valid, false otherwise.
744 */
745 public static Object validateDate(Object bean, ValidatorAction va,
746 Field field, ActionMessages errors, Validator validator,
747 HttpServletRequest request) {
748 Object result = null;
749 String value = null;
750
751 value = evaluateBean(bean, field);
752
753 boolean isStrict = false;
754 String datePattern =
755 Resources.getVarValue("datePattern", field, validator, request,
756 false);
757
758 if (GenericValidator.isBlankOrNull(datePattern)) {
759 datePattern =
760 Resources.getVarValue("datePatternStrict", field, validator,
761 request, false);
762
763 if (!GenericValidator.isBlankOrNull(datePattern)) {
764 isStrict = true;
765 }
766 }
767
768 Locale locale = RequestUtils.getUserLocale(request, null);
769
770 if (GenericValidator.isBlankOrNull(value)) {
771 return Boolean.TRUE;
772 }
773
774 try {
775 if (GenericValidator.isBlankOrNull(datePattern)) {
776 result = GenericTypeValidator.formatDate(value, locale);
777 } else {
778 result =
779 GenericTypeValidator.formatDate(value, datePattern, isStrict);
780 }
781 } catch (Exception e) {
782 log.error(e.getMessage(), e);
783 }
784
785 if (result == null) {
786 errors.add(field.getKey(),
787 Resources.getActionMessage(validator, request, va, field));
788 }
789
790 return (result == null) ? Boolean.FALSE : result;
791 }
792
793 /**
794 * Checks if a fields value is within a range (min & max specified in
795 * the vars attribute).
796 *
797 * @param bean The bean validation is being performed on.
798 * @param va The <code>ValidatorAction</code> that is currently
799 * being performed.
800 * @param field The <code>Field</code> object associated with the
801 * current field being validated.
802 * @param errors The <code>ActionMessages</code> object to add errors
803 * to if any validation errors occur.
804 * @param validator The <code>Validator</code> instance, used to access
805 * other field values.
806 * @param request Current request object.
807 * @return True if in range, false otherwise.
808 */
809 public static boolean validateLongRange(Object bean, ValidatorAction va,
810 Field field, ActionMessages errors, Validator validator,
811 HttpServletRequest request) {
812 String value = null;
813
814 value = evaluateBean(bean, field);
815
816 if (!GenericValidator.isBlankOrNull(value)) {
817 try {
818 String minVar =
819 Resources.getVarValue("min", field, validator, request, true);
820 String maxVar =
821 Resources.getVarValue("max", field, validator, request, true);
822 long longValue = Long.parseLong(value);
823 long min = Long.parseLong(minVar);
824 long max = Long.parseLong(maxVar);
825
826 if (min > max) {
827 throw new IllegalArgumentException(sysmsgs.getMessage(
828 "invalid.range", minVar, maxVar));
829 }
830
831 if (!GenericValidator.isInRange(longValue, min, max)) {
832 errors.add(field.getKey(),
833 Resources.getActionMessage(validator, request, va, field));
834
835 return false;
836 }
837 } catch (Exception e) {
838 processFailure(errors, field, "longRange", e);
839
840 return false;
841 }
842 }
843
844 return true;
845 }
846
847 /**
848 * Checks if a fields value is within a range (min & max specified in
849 * the vars attribute).
850 *
851 * @param bean The bean validation is being performed on.
852 * @param va The <code>ValidatorAction</code> that is currently
853 * being performed.
854 * @param field The <code>Field</code> object associated with the
855 * current field being validated.
856 * @param errors The <code>ActionMessages</code> object to add errors
857 * to if any validation errors occur.
858 * @param validator The <code>Validator</code> instance, used to access
859 * other field values.
860 * @param request Current request object.
861 * @return True if in range, false otherwise.
862 */
863 public static boolean validateIntRange(Object bean, ValidatorAction va,
864 Field field, ActionMessages errors, Validator validator,
865 HttpServletRequest request) {
866 String value = null;
867
868 value = evaluateBean(bean, field);
869
870 if (!GenericValidator.isBlankOrNull(value)) {
871 try {
872 String minVar =
873 Resources.getVarValue("min", field, validator, request, true);
874 String maxVar =
875 Resources.getVarValue("max", field, validator, request, true);
876 int min = Integer.parseInt(minVar);
877 int max = Integer.parseInt(maxVar);
878 int intValue = Integer.parseInt(value);
879
880 if (min > max) {
881 throw new IllegalArgumentException(sysmsgs.getMessage(
882 "invalid.range", minVar, maxVar));
883 }
884
885 if (!GenericValidator.isInRange(intValue, min, max)) {
886 errors.add(field.getKey(),
887 Resources.getActionMessage(validator, request, va, field));
888
889 return false;
890 }
891 } catch (Exception e) {
892 processFailure(errors, field, "intRange", e);
893
894 return false;
895 }
896 }
897
898 return true;
899 }
900
901 /**
902 * Checks if a fields value is within a range (min & max specified in
903 * the vars attribute).
904 *
905 * @param bean The bean validation is being performed on.
906 * @param va The <code>ValidatorAction</code> that is currently
907 * being performed.
908 * @param field The <code>Field</code> object associated with the
909 * current field being validated.
910 * @param errors The <code>ActionMessages</code> object to add errors
911 * to if any validation errors occur.
912 * @param validator The <code>Validator</code> instance, used to access
913 * other field values.
914 * @param request Current request object.
915 * @return True if in range, false otherwise.
916 */
917 public static boolean validateDoubleRange(Object bean, ValidatorAction va,
918 Field field, ActionMessages errors, Validator validator,
919 HttpServletRequest request) {
920 String value = null;
921
922 value = evaluateBean(bean, field);
923
924 if (!GenericValidator.isBlankOrNull(value)) {
925 try {
926 String minVar =
927 Resources.getVarValue("min", field, validator, request, true);
928 String maxVar =
929 Resources.getVarValue("max", field, validator, request, true);
930 double doubleValue = Double.parseDouble(value);
931 double min = Double.parseDouble(minVar);
932 double max = Double.parseDouble(maxVar);
933
934 if (min > max) {
935 throw new IllegalArgumentException(sysmsgs.getMessage(
936 "invalid.range", minVar, maxVar));
937 }
938
939 if (!GenericValidator.isInRange(doubleValue, min, max)) {
940 errors.add(field.getKey(),
941 Resources.getActionMessage(validator, request, va, field));
942
943 return false;
944 }
945 } catch (Exception e) {
946 processFailure(errors, field, "doubleRange", e);
947
948 return false;
949 }
950 }
951
952 return true;
953 }
954
955 /**
956 * Checks if a fields value is within a range (min & max specified in
957 * the vars attribute).
958 *
959 * @param bean The bean validation is being performed on.
960 * @param va The <code>ValidatorAction</code> that is currently
961 * being performed.
962 * @param field The <code>Field</code> object associated with the
963 * current field being validated.
964 * @param errors The <code>ActionMessages</code> object to add errors
965 * to if any validation errors occur.
966 * @param validator The <code>Validator</code> instance, used to access
967 * other field values.
968 * @param request Current request object.
969 * @return True if in range, false otherwise.
970 */
971 public static boolean validateFloatRange(Object bean, ValidatorAction va,
972 Field field, ActionMessages errors, Validator validator,
973 HttpServletRequest request) {
974 String value = null;
975
976 value = evaluateBean(bean, field);
977
978 if (!GenericValidator.isBlankOrNull(value)) {
979 try {
980 String minVar =
981 Resources.getVarValue("min", field, validator, request, true);
982 String maxVar =
983 Resources.getVarValue("max", field, validator, request, true);
984 float floatValue = Float.parseFloat(value);
985 float min = Float.parseFloat(minVar);
986 float max = Float.parseFloat(maxVar);
987
988 if (min > max) {
989 throw new IllegalArgumentException(sysmsgs.getMessage(
990 "invalid.range", minVar, maxVar));
991 }
992
993 if (!GenericValidator.isInRange(floatValue, min, max)) {
994 errors.add(field.getKey(),
995 Resources.getActionMessage(validator, request, va, field));
996
997 return false;
998 }
999 } catch (Exception e) {
1000 processFailure(errors, field, "floatRange", e);
1001
1002 return false;
1003 }
1004 }
1005
1006 return true;
1007 }
1008
1009 /**
1010 * Checks if the field is a valid credit card number.
1011 *
1012 * @param bean The bean validation is being performed on.
1013 * @param va The <code>ValidatorAction</code> that is currently
1014 * being performed.
1015 * @param field The <code>Field</code> object associated with the
1016 * current field being validated.
1017 * @param errors The <code>ActionMessages</code> object to add errors
1018 * to if any validation errors occur.
1019 * @param validator The <code>Validator</code> instance, used to access
1020 * other field values.
1021 * @param request Current request object.
1022 * @return true if valid, false otherwise.
1023 */
1024 public static Object validateCreditCard(Object bean, ValidatorAction va,
1025 Field field, ActionMessages errors, Validator validator,
1026 HttpServletRequest request) {
1027 Object result = null;
1028 String value = null;
1029
1030 value = evaluateBean(bean, field);
1031
1032 if (GenericValidator.isBlankOrNull(value)) {
1033 return Boolean.TRUE;
1034 }
1035
1036 result = GenericTypeValidator.formatCreditCard(value);
1037
1038 if (result == null) {
1039 errors.add(field.getKey(),
1040 Resources.getActionMessage(validator, request, va, field));
1041 }
1042
1043 return (result == null) ? Boolean.FALSE : result;
1044 }
1045
1046 /**
1047 * Checks if a field has a valid e-mail address.
1048 *
1049 * @param bean The bean validation is being performed on.
1050 * @param va The <code>ValidatorAction</code> that is currently
1051 * being performed.
1052 * @param field The <code>Field</code> object associated with the
1053 * current field being validated.
1054 * @param errors The <code>ActionMessages</code> object to add errors
1055 * to if any validation errors occur.
1056 * @param validator The <code>Validator</code> instance, used to access
1057 * other field values.
1058 * @param request Current request object.
1059 * @return True if valid, false otherwise.
1060 */
1061 public static boolean validateEmail(Object bean, ValidatorAction va,
1062 Field field, ActionMessages errors, Validator validator,
1063 HttpServletRequest request) {
1064 String value = null;
1065
1066 value = evaluateBean(bean, field);
1067
1068 if (!GenericValidator.isBlankOrNull(value)
1069 && !GenericValidator.isEmail(value)) {
1070 errors.add(field.getKey(),
1071 Resources.getActionMessage(validator, request, va, field));
1072
1073 return false;
1074 } else {
1075 return true;
1076 }
1077 }
1078
1079 /**
1080 * Checks if the field's length is less than or equal to the maximum
1081 * value. A <code>Null</code> will be considered an error.
1082 *
1083 * @param bean The bean validation is being performed on.
1084 * @param va The <code>ValidatorAction</code> that is currently
1085 * being performed.
1086 * @param field The <code>Field</code> object associated with the
1087 * current field being validated.
1088 * @param errors The <code>ActionMessages</code> object to add errors
1089 * to if any validation errors occur.
1090 * @param validator The <code>Validator</code> instance, used to access
1091 * other field values.
1092 * @param request Current request object.
1093 * @return True if stated conditions met.
1094 */
1095 public static boolean validateMaxLength(Object bean, ValidatorAction va,
1096 Field field, ActionMessages errors, Validator validator,
1097 HttpServletRequest request) {
1098 String value = null;
1099
1100 value = evaluateBean(bean, field);
1101
1102 if (value != null) {
1103 try {
1104 String maxVar =
1105 Resources.getVarValue("maxlength", field, validator,
1106 request, true);
1107 int max = Integer.parseInt(maxVar);
1108
1109 boolean isValid = false;
1110 String endLth = Resources.getVarValue("lineEndLength", field,
1111 validator, request, false);
1112 if (GenericValidator.isBlankOrNull(endLth)) {
1113 isValid = GenericValidator.maxLength(value, max);
1114 } else {
1115 isValid = GenericValidator.maxLength(value, max,
1116 Integer.parseInt(endLth));
1117 }
1118
1119 if (!isValid) {
1120 errors.add(field.getKey(),
1121 Resources.getActionMessage(validator, request, va, field));
1122
1123 return false;
1124 }
1125 } catch (Exception e) {
1126 processFailure(errors, field, "maxlength", e);
1127
1128 return false;
1129 }
1130 }
1131
1132 return true;
1133 }
1134
1135 /**
1136 * Checks if the field's length is greater than or equal to the minimum
1137 * value. A <code>Null</code> will be considered an error.
1138 *
1139 * @param bean The bean validation is being performed on.
1140 * @param va The <code>ValidatorAction</code> that is currently
1141 * being performed.
1142 * @param field The <code>Field</code> object associated with the
1143 * current field being validated.
1144 * @param errors The <code>ActionMessages</code> object to add errors
1145 * to if any validation errors occur.
1146 * @param validator The <code>Validator</code> instance, used to access
1147 * other field values.
1148 * @param request Current request object.
1149 * @return True if stated conditions met.
1150 */
1151 public static boolean validateMinLength(Object bean, ValidatorAction va,
1152 Field field, ActionMessages errors, Validator validator,
1153 HttpServletRequest request) {
1154 String value = null;
1155
1156 value = evaluateBean(bean, field);
1157
1158 if (!GenericValidator.isBlankOrNull(value)) {
1159 try {
1160 String minVar =
1161 Resources.getVarValue("minlength", field, validator,
1162 request, true);
1163 int min = Integer.parseInt(minVar);
1164
1165 boolean isValid = false;
1166 String endLth = Resources.getVarValue("lineEndLength", field,
1167 validator, request, false);
1168 if (GenericValidator.isBlankOrNull(endLth)) {
1169 isValid = GenericValidator.minLength(value, min);
1170 } else {
1171 isValid = GenericValidator.minLength(value, min,
1172 Integer.parseInt(endLth));
1173 }
1174
1175 if (!isValid) {
1176 errors.add(field.getKey(),
1177 Resources.getActionMessage(validator, request, va, field));
1178
1179 return false;
1180 }
1181 } catch (Exception e) {
1182 processFailure(errors, field, "minlength", e);
1183
1184 return false;
1185 }
1186 }
1187
1188 return true;
1189 }
1190
1191 /**
1192 * Checks if a field has a valid url. Four optional variables can be
1193 * specified to configure url validation.
1194 *
1195 * <ul>
1196 *
1197 * <li>Variable <code>allow2slashes</code> can be set to <code>true</code>
1198 * or <code>false</code> to control whether two slashes are allowed -
1199 * default is <code>false</code> (i.e. two slashes are NOT allowed).</li>
1200 *
1201 * <li>Variable <code>nofragments</code> can be set to <code>true</code>
1202 * or <code>false</code> to control whether fragments are allowed -
1203 * default is <code>false</code> (i.e. fragments ARE allowed).</li>
1204 *
1205 * <li>Variable <code>allowallschemes</code> can be set to
1206 * <code>true</code> or <code>false</code> to control if all schemes are
1207 * allowed - default is <code>false</code> (i.e. all schemes are NOT
1208 * allowed).</li>
1209 *
1210 * <li>Variable <code>schemes</code> can be set to a comma delimited list
1211 * of valid schemes. This value is ignored if <code>allowallschemes</code>
1212 * is set to <code>true</code>. Default schemes allowed are "http",
1213 * "https" and "ftp" if this variable is not specified.</li>
1214 *
1215 * </ul>
1216 *
1217 * @param bean The bean validation is being performed on.
1218 * @param va The <code>ValidatorAction</code> that is currently
1219 * being performed.
1220 * @param field The <code>Field</code> object associated with the
1221 * current field being validated.
1222 * @param errors The <code>ActionMessages</code> object to add errors
1223 * to if any validation errors occur.
1224 * @param validator The <code>Validator</code> instance, used to access
1225 * other field values.
1226 * @param request Current request object.
1227 * @return True if valid, false otherwise.
1228 */
1229 public static boolean validateUrl(Object bean, ValidatorAction va,
1230 Field field, ActionMessages errors, Validator validator,
1231 HttpServletRequest request) {
1232 String value = null;
1233
1234 value = evaluateBean(bean, field);
1235
1236 if (GenericValidator.isBlankOrNull(value)) {
1237 return true;
1238 }
1239
1240
1241 String allowallschemesVar =
1242 Resources.getVarValue("allowallschemes", field, validator, request,
1243 false);
1244 boolean allowallschemes = "true".equalsIgnoreCase(allowallschemesVar);
1245 int options = allowallschemes ? UrlValidator.ALLOW_ALL_SCHEMES : 0;
1246
1247 String allow2slashesVar =
1248 Resources.getVarValue("allow2slashes", field, validator, request,
1249 false);
1250
1251 if ("true".equalsIgnoreCase(allow2slashesVar)) {
1252 options += UrlValidator.ALLOW_2_SLASHES;
1253 }
1254
1255 String nofragmentsVar =
1256 Resources.getVarValue("nofragments", field, validator, request,
1257 false);
1258
1259 if ("true".equalsIgnoreCase(nofragmentsVar)) {
1260 options += UrlValidator.NO_FRAGMENTS;
1261 }
1262
1263 String schemesVar =
1264 allowallschemes ? null
1265 : Resources.getVarValue("schemes", field,
1266 validator, request, false);
1267
1268
1269 if ((options == 0) && (schemesVar == null)) {
1270 if (GenericValidator.isUrl(value)) {
1271 return true;
1272 } else {
1273 errors.add(field.getKey(),
1274 Resources.getActionMessage(validator, request, va, field));
1275
1276 return false;
1277 }
1278 }
1279
1280
1281 String[] schemes = null;
1282
1283 if (schemesVar != null) {
1284 StringTokenizer st = new StringTokenizer(schemesVar, ",");
1285
1286 schemes = new String[st.countTokens()];
1287
1288 int i = 0;
1289
1290 while (st.hasMoreTokens()) {
1291 schemes[i++] = st.nextToken().trim();
1292 }
1293 }
1294
1295
1296 UrlValidator urlValidator = new UrlValidator(schemes, options);
1297
1298 if (urlValidator.isValid(value)) {
1299 return true;
1300 } else {
1301 errors.add(field.getKey(),
1302 Resources.getActionMessage(validator, request, va, field));
1303
1304 return false;
1305 }
1306 }
1307
1308 /**
1309 * Process a validation failure.
1310 */
1311 private static void processFailure(ActionMessages errors, Field field,
1312 String validator, Throwable t) {
1313
1314 String logErrorMsg =
1315 sysmsgs.getMessage("validation.failed", validator,
1316 field.getProperty(), t.toString());
1317
1318 log.error(logErrorMsg);
1319
1320
1321 String userErrorMsg = sysmsgs.getMessage("system.error");
1322
1323 errors.add(field.getKey(), new ActionMessage(userErrorMsg, false));
1324 }
1325
1326 /**
1327 * Return <code>true</code> if the specified object is a String or a
1328 * <code>null</code> value.
1329 *
1330 * @param o Object to be tested
1331 * @return The string value
1332 */
1333 protected static boolean isString(Object o) {
1334 return (o == null) ? true : String.class.isInstance(o);
1335 }
1336 }