1 package org.andromda.cartridges.jsf.validator;
2
3 import java.io.Serializable;
4 import java.net.URL;
5 import java.text.DateFormat;
6 import java.text.SimpleDateFormat;
7 import java.util.Calendar;
8 import java.util.Collection;
9 import java.util.Date;
10 import java.util.Iterator;
11 import java.util.Locale;
12 import java.util.Map;
13
14 import javax.faces.component.EditableValueHolder;
15 import javax.faces.component.UIComponent;
16 import javax.faces.context.FacesContext;
17
18 import org.apache.commons.lang.ObjectUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.commons.validator.Field;
21 import org.apache.commons.validator.GenericTypeValidator;
22 import org.apache.commons.validator.GenericValidator;
23 import org.apache.commons.validator.ValidatorAction;
24 import org.apache.commons.validator.ValidatorException;
25
26 /**
27 * <p>
28 * This class contains the default validations that are used in the
29 * validator-rules.xml file.
30 * </p>
31 * <p>
32 * In general passing in a null or blank will return a null Object or a false
33 * boolean. However, nulls and blanks do not result in an error being added to
34 * the errors.
35 * </p>
36 */
37 public class ParameterChecks
38 implements Serializable
39 {
40 /**
41 *
42 */
43 private static final long serialVersionUID = 1L;
44 /** NULL */
45 public static final String FIELD_TEST_NULL = "NULL";
46 /** NOTNULL */
47 public static final String FIELD_TEST_NOTNULL = "NOTNULL";
48 /** EQUAL */
49 public static final String FIELD_TEST_EQUAL = "EQUAL";
50
51 /**
52 * Checks if the field isn't null and length of the field is greater than
53 * zero not including whitespace.
54 *
55 * @param context the faces context
56 * @param object the value of the field being validated.
57 * @param parameters Any field parameters from the validation.xml.
58 * @param errors The <code>Map</code> object to add errors to if any
59 * validation errors occur.
60 * @param action The <code>ValidatorAction</code> that is currently being
61 * performed.
62 * @param field The <code>Field</code> object associated with the current
63 * field being validated.
64 */
65 public static void validateRequired(
66 FacesContext context,
67 Object object,
68 Map parameters,
69 Collection errors,
70 ValidatorAction action,
71 Field field)
72 {
73 String value = null;
74 if (object instanceof String)
75 {
76 value = (String)object;
77 }
78 else
79 {
80 value = ObjectUtils.toString(object);
81 }
82 if (StringUtils.isBlank(value))
83 {
84 errors.add(ValidatorMessages.getMessage(
85 action,
86 field,
87 context));
88 }
89 }
90
91 /**
92 * Checks if the parameter isn't null based on the values of other fields.
93 *
94 * @param context the faces context
95 * @param object the value of the field being validated.
96 * @param parameters Any field parameters from the validation.xml.
97 * @param errors The <code>Map</code> object to add errors to if any
98 * validation errors occur.
99 * @param action The <code>ValidatorAction</code> that is currently being
100 * performed.
101 * @param field The <code>Field</code> object associated with the current
102 * field being validated.
103 */
104 public static void validateRequiredIf(
105 FacesContext context,
106 Object object,
107 Map parameters,
108 Collection errors,
109 ValidatorAction action,
110 Field field)
111 {
112 boolean required = false;
113
114 final String value = ObjectUtils.toString(object);
115
116 int ctr = 0;
117 String fieldJoin = "AND";
118 if (!StringUtils.isBlank(field.getVarValue("fieldJoin")))
119 {
120 fieldJoin = field.getVarValue("fieldJoin");
121 }
122
123 if ("AND".equalsIgnoreCase(fieldJoin))
124 {
125 required = true;
126 }
127
128 while (!StringUtils.isBlank(field.getVarValue("field[" + ctr + ']')))
129 {
130 String dependProp = field.getVarValue("field[" + ctr + ']');
131 String dependTest = field.getVarValue("fieldTest[" + ctr + ']');
132 String dependTestValue = field.getVarValue("fieldValue[" + ctr + ']');
133 String dependIndexed = field.getVarValue("fieldIndexed[" + ctr + ']');
134
135 if (dependIndexed == null)
136 {
137 dependIndexed = "false";
138 }
139
140 String dependVal = null;
141 boolean thisRequired = false;
142 if (field.isIndexed() && "true".equalsIgnoreCase(dependIndexed))
143 {
144 String key = field.getKey();
145 if ((key.indexOf('[') > -1) && (key.indexOf(']') > -1))
146 {
147 String ind = key.substring(
148 0,
149 key.indexOf('.') + 1);
150 dependProp = ind + dependProp;
151 }
152 }
153
154 dependVal = (String)parameters.get(dependProp);
155 if (dependTest.equals(FIELD_TEST_NULL))
156 {
157 if ((dependVal != null) && (dependVal.length() > 0))
158 {
159 thisRequired = false;
160 }
161 else
162 {
163 thisRequired = true;
164 }
165 }
166
167 if (dependTest.equals(FIELD_TEST_NOTNULL))
168 {
169 if ((dependVal != null) && (dependVal.length() > 0))
170 {
171 thisRequired = true;
172 }
173 else
174 {
175 thisRequired = false;
176 }
177 }
178
179 if (dependTest.equals(FIELD_TEST_EQUAL))
180 {
181 thisRequired = dependTestValue.equalsIgnoreCase(dependVal);
182 }
183
184 if ("AND".equalsIgnoreCase(fieldJoin))
185 {
186 required = required && thisRequired;
187 }
188 else
189 {
190 required = required || thisRequired;
191 }
192
193 ctr++;
194 }
195
196 if (required)
197 {
198 if (StringUtils.isBlank(value))
199 {
200 errors.add(ValidatorMessages.getMessage(
201 action,
202 field,
203 context));
204 }
205 }
206 }
207
208 /**
209 * Checks if the parameter matches the regular expression in the field's
210 * mask attribute.
211 *
212 * @param context the faces context
213 * @param object the value of the field being validated.
214 * @param parameters Any field parameters from the validation.xml.
215 * @param errors The <code>Map</code> object to add errors to if any
216 * validation errors occur.
217 * @param action The <code>ValidatorAction</code> that is currently being
218 * performed.
219 * @param field The <code>Field</code> object associated with the current
220 * field being validated.
221 */
222 public static void validateMask(
223 FacesContext context,
224 Object object,
225 Map parameters,
226 Collection errors,
227 ValidatorAction action,
228 Field field)
229 {
230 final String mask = field.getVarValue("mask");
231 final String value = ObjectUtils.toString(object);
232 if (StringUtils.isNotBlank(value) && !GenericValidator.matchRegexp(
233 value,
234 mask))
235 {
236 errors.add(ValidatorMessages.getMessage(
237 action,
238 field,
239 context));
240 }
241 }
242
243 /**
244 * Checks if the field can safely be converted to a byte primitive.
245 *
246 * @param context the faces context
247 * @param object the value of the field being validated.
248 * @param parameters Any field parameters from the validation.xml.
249 * @param errors The <code>Map</code> object to add errors to if any
250 * validation errors occur.
251 * @param action The <code>ValidatorAction</code> that is currently being
252 * performed.
253 * @param field The <code>Field</code> object associated with the current
254 * field being validated.
255 */
256 public static void validateByte(
257 FacesContext context,
258 Object object,
259 Map parameters,
260 Collection errors,
261 ValidatorAction action,
262 Field field)
263 {
264 Byte result = null;
265 String value = ObjectUtils.toString(object);
266 if (StringUtils.isNotBlank(value))
267 {
268 result = GenericTypeValidator.formatByte(value);
269
270 if (result == null)
271 {
272 errors.add(ValidatorMessages.getMessage(
273 action,
274 field,
275 context));
276 }
277 }
278 }
279
280 /**
281 * Checks if the field can safely be converted to a short primitive.
282 *
283 * @param context the faces context
284 * @param object the value of the field being validated.
285 * @param parameters Any field parameters from the validation.xml.
286 * @param errors The <code>Map</code> object to add errors to if any
287 * validation errors occur.
288 * @param action The <code>ValidatorAction</code> that is currently being
289 * performed.
290 * @param field The <code>Field</code> object associated with the current
291 * field being validated.
292 */
293 public static void validateShort(
294 FacesContext context,
295 Object object,
296 Map parameters,
297 Collection errors,
298 ValidatorAction action,
299 Field field)
300 {
301 Short result = null;
302 String value = ObjectUtils.toString(object);
303 if (StringUtils.isNotBlank(value))
304 {
305 result = GenericTypeValidator.formatShort(value);
306
307 if (result == null)
308 {
309 errors.add(ValidatorMessages.getMessage(
310 action,
311 field,
312 context));
313 }
314 }
315 }
316
317 /**
318 * Checks if the field can safely be converted to an int primitive.
319 *
320 * @param context the faces context
321 * @param object the value of the field being validated.
322 * @param parameters Any field parameters from the validation.xml.
323 * @param errors The <code>Map</code> object to add errors to if any
324 * validation errors occur.
325 * @param action The <code>ValidatorAction</code> that is currently being
326 * performed.
327 * @param field The <code>Field</code> object associated with the current
328 * field being validated.
329 */
330 public static void validateInteger(
331 FacesContext context,
332 Object object,
333 Map parameters,
334 Collection errors,
335 ValidatorAction action,
336 Field field)
337 {
338 Integer result = null;
339 String value = ObjectUtils.toString(object);
340 if (StringUtils.isNotBlank(value))
341 {
342 result = GenericTypeValidator.formatInt(value);
343 if (result == null)
344 {
345 errors.add(ValidatorMessages.getMessage(
346 action,
347 field,
348 context));
349 }
350 }
351 }
352
353 /**
354 * Checks if the field can safely be converted to a long primitive.
355 *
356 * @param context the faces context
357 * @param object the value of the field being validated.
358 * @param parameters Any field parameters from the validation.xml.
359 * @param errors The <code>Map</code> object to add errors to if any
360 * validation errors occur.
361 * @param action The <code>ValidatorAction</code> that is currently being
362 * performed.
363 * @param field The <code>Field</code> object associated with the current
364 * field being validated.
365 */
366 public static void validateLong(
367 FacesContext context,
368 Object object,
369 Map parameters,
370 Collection errors,
371 ValidatorAction action,
372 Field field)
373 {
374 Long result = null;
375 String value = ObjectUtils.toString(object);
376 if (StringUtils.isNotBlank(value))
377 {
378 result = GenericTypeValidator.formatLong(value);
379 if (result == null)
380 {
381 errors.add(ValidatorMessages.getMessage(
382 action,
383 field,
384 context));
385 }
386 }
387 }
388
389 /**
390 * Checks if the field can safely be converted to a float primitive.
391 *
392 * @param context the faces context
393 * @param object the value of the field being validated.
394 * @param parameters Any field parameters from the validation.xml.
395 * @param errors The <code>Map</code> object to add errors to if any
396 * validation errors occur.
397 * @param action The <code>ValidatorAction</code> that is currently being
398 * performed.
399 * @param field The <code>Field</code> object associated with the current
400 * field being validated.
401 */
402 public static void validateFloat(
403 FacesContext context,
404 Object object,
405 Map parameters,
406 Collection errors,
407 ValidatorAction action,
408 Field field)
409 {
410 Float result = null;
411 String value = ObjectUtils.toString(object);
412 if (StringUtils.isNotBlank(value))
413 {
414 result = GenericTypeValidator.formatFloat(value);
415
416 if (result == null)
417 {
418 errors.add(ValidatorMessages.getMessage(
419 action,
420 field,
421 context));
422 }
423 }
424 }
425
426 /**
427 * Checks if the field can safely be converted to a double primitive.
428 *
429 * @param context the faces context
430 * @param object the value of the field being validated.
431 * @param parameters Any field parameters from the validation.xml.
432 * @param errors The <code>Map</code> object to add errors to if any
433 * validation errors occur.
434 * @param action The <code>ValidatorAction</code> that is currently being
435 * performed.
436 * @param field The <code>Field</code> object associated with the current
437 * field being validated.
438 */
439 public static void validateDouble(
440 FacesContext context,
441 Object object,
442 Map parameters,
443 Collection errors,
444 ValidatorAction action,
445 Field field)
446 {
447 Double result = null;
448 String value = ObjectUtils.toString(object);
449 if (StringUtils.isNotBlank(value))
450 {
451 result = GenericTypeValidator.formatDouble(value);
452
453 if (result == null)
454 {
455 errors.add(ValidatorMessages.getMessage(
456 action,
457 field,
458 context));
459 }
460 }
461 }
462
463 /**
464 * Checks if the field is a valid date. If the field has a datePattern
465 * variable, that will be used to format
466 * <code>java.text.SimpleDateFormat</code>. If the field has a
467 * datePatternStrict variable, that will be used to format
468 * <code>java.text.SimpleDateFormat</code> and the length will be checked
469 * so '2/12/1999' will not pass validation with the format 'MM/dd/yyyy'
470 * because the month isn't two digits. If no datePattern variable is
471 * specified, then the field gets the DateFormat.SHORT format for the
472 * locale. The setLenient method is set to <code>false</code> for all
473 * variations. If the <code>object</code> is a date instance, then validation is not performed.
474 *
475 * @param context the faces context
476 * @param object the value of the field being validated.
477 * @param parameters Any field parameters from the validation.xml.
478 * @param errors The <code>Map</code> object to add errors to if any
479 * validation errors occur.
480 * @param action The <code>ValidatorAction</code> that is currently being
481 * performed.
482 * @param field The <code>Field</code> object associated with the current
483 * field being validated.
484 */
485 public static void validateDate(
486 FacesContext context,
487 Object object,
488 Map parameters,
489 Collection errors,
490 ValidatorAction action,
491 Field field)
492 {
493 // - only validate if the object is not already a date or calendar
494 if (!(object instanceof Date) && ! (object instanceof Calendar))
495 {
496 Date result = null;
497 String value = ObjectUtils.toString(object);
498 String datePattern = field.getVarValue("datePattern");
499 String datePatternStrict = field.getVarValue("datePatternStrict");
500 Locale locale = Locale.getDefault();
501
502 if (StringUtils.isNotBlank(value))
503 {
504 if (StringUtils.isNotBlank(datePattern))
505 {
506 result = GenericTypeValidator.formatDate(
507 value,
508 datePattern,
509 false);
510 }
511 else if (StringUtils.isNotBlank(datePatternStrict))
512 {
513 result = GenericTypeValidator.formatDate(
514 value,
515 datePatternStrict,
516 true);
517 }
518 else
519 {
520 result = GenericTypeValidator.formatDate(
521 value,
522 locale);
523 }
524 if (result == null)
525 {
526 errors.add(ValidatorMessages.getMessage(
527 action,
528 field,
529 context));
530 }
531 }
532 }
533 }
534
535 /**
536 * Checks if a fields value is within a range (min & max specified in
537 * the vars attribute).
538 *
539 * @param context the faces context
540 * @param object the value of the field being validated.
541 * @param parameters Any field parameters from the validation.xml.
542 * @param errors The <code>Map</code> object to add errors to if any
543 * validation errors occur.
544 * @param action The <code>ValidatorAction</code> that is currently being
545 * performed.
546 * @param field The <code>Field</code> object associated with the current
547 * field being validated.
548 */
549 public static void validateLongRange(
550 FacesContext context,
551 Object object,
552 Map parameters,
553 Collection errors,
554 ValidatorAction action,
555 Field field)
556 {
557 final String value = ObjectUtils.toString(object);
558 if (StringUtils.isNotBlank(value))
559 {
560 try
561 {
562 long intValue = Long.parseLong(value);
563 long min = Long.parseLong(field.getVarValue("min"));
564 long max = Long.parseLong(field.getVarValue("max"));
565
566 if (!GenericValidator.isInRange(
567 intValue,
568 min,
569 max))
570 {
571 errors.add(ValidatorMessages.getMessage(
572 action,
573 field,
574 context));
575 }
576 }
577 catch (Exception exception)
578 {
579 errors.add(ValidatorMessages.getMessage(
580 action,
581 field,
582 context));
583 }
584 }
585 }
586
587 /**
588 * Checks if a fields value is within a range (min & max specified in
589 * the vars attribute).
590 *
591 * @param context the faces context
592 * @param object the value of the field being validated.
593 * @param parameters Any field parameters from the validation.xml.
594 * @param errors The <code>Map</code> object to add errors to if any
595 * validation errors occur.
596 * @param action The <code>ValidatorAction</code> that is currently being
597 * performed.
598 * @param field The <code>Field</code> object associated with the current
599 * field being validated.
600 */
601 public static void validateDoubleRange(
602 FacesContext context,
603 Object object,
604 Map parameters,
605 Collection errors,
606 ValidatorAction action,
607 Field field)
608 {
609 final String value = ObjectUtils.toString(object);
610 if (StringUtils.isNotBlank(value))
611 {
612 try
613 {
614 double doubleValue = Double.parseDouble(value);
615 double min = Double.parseDouble(field.getVarValue("min"));
616 double max = Double.parseDouble(field.getVarValue("max"));
617
618 if (!GenericValidator.isInRange(
619 doubleValue,
620 min,
621 max))
622 {
623 errors.add(ValidatorMessages.getMessage(
624 action,
625 field,
626 context));
627 }
628 }
629 catch (Exception exception)
630 {
631 errors.add(ValidatorMessages.getMessage(
632 action,
633 field,
634 context));
635 }
636 }
637 }
638
639 /**
640 * Checks if a fields value is within a range (min & max specified in
641 * the vars attribute).
642 *
643 * @param context the faces context
644 * @param object the value of the field being validated.
645 * @param parameters Any field parameters from the validation.xml.
646 * @param errors The <code>Map</code> object to add errors to if any
647 * validation errors occur.
648 * @param action The <code>ValidatorAction</code> that is currently being
649 * performed.
650 * @param field The <code>Field</code> object associated with the current
651 * field being validated.
652 */
653 public static void validateFloatRange(
654 FacesContext context,
655 Object object,
656 Map parameters,
657 Collection errors,
658 ValidatorAction action,
659 Field field)
660 {
661 final String value = ObjectUtils.toString(object);
662 if (StringUtils.isNotBlank(value))
663 {
664 try
665 {
666 float floatValue = Float.parseFloat(value);
667 float min = Float.parseFloat(field.getVarValue("min"));
668 float max = Float.parseFloat(field.getVarValue("max"));
669
670 if (!GenericValidator.isInRange(
671 floatValue,
672 min,
673 max))
674 {
675 errors.add(ValidatorMessages.getMessage(
676 action,
677 field,
678 context));
679 }
680 }
681 catch (Exception exception)
682 {
683 errors.add(ValidatorMessages.getMessage(
684 action,
685 field,
686 context));
687 }
688 }
689 }
690
691 /**
692 * Checks if the field is a valid credit card number.
693 *
694 * @param context the faces context
695 * @param object the value of the field being validated.
696 * @param parameters Any field parameters from the validation.xml.
697 * @param errors The <code>Map</code> object to add errors to if any
698 * validation errors occur.
699 * @param action The <code>ValidatorAction</code> that is currently being
700 * performed.
701 * @param field The <code>Field</code> object associated with the current
702 * field being validated.
703 */
704 public static void validateCreditCard(
705 FacesContext context,
706 Object object,
707 Map parameters,
708 Collection errors,
709 ValidatorAction action,
710 Field field)
711 {
712 Long result = null;
713 final String value = ObjectUtils.toString(object);
714 if (StringUtils.isNotBlank(value))
715 {
716 result = GenericTypeValidator.formatCreditCard(value);
717
718 if (result == null)
719 {
720 errors.add(ValidatorMessages.getMessage(
721 action,
722 field,
723 context));
724 }
725 }
726 }
727
728 /**
729 * Checks if a field has a valid exception-mail address.
730 *
731 * @param context the faces context
732 * @param object the value of the field being validated.
733 * @param parameters Any field parameters from the validation.xml.
734 * @param errors The <code>Map</code> object to add errors to if any
735 * validation errors occur.
736 * @param action The <code>ValidatorAction</code> that is currently being
737 * performed.
738 * @param field The <code>Field</code> object associated with the current
739 * field being validated.
740 */
741 public static void validateEmail(
742 FacesContext context,
743 Object object,
744 Map parameters,
745 Collection errors,
746 ValidatorAction action,
747 Field field)
748 {
749 final String value = ObjectUtils.toString(object);
750 if (StringUtils.isNotBlank(value) && !GenericValidator.isEmail(value))
751 {
752 errors.add(ValidatorMessages.getMessage(
753 action,
754 field,
755 context));
756 }
757 }
758
759 /**
760 * Checks if the field's length is less than or equal to the maximum value.
761 * A <code>Null</code> will be considered an error.
762 *
763 * @param context the faces context
764 * @param object the value of the field being validated.
765 * @param parameters Any field parameters from the validation.xml.
766 * @param errors The <code>Map</code> object to add errors to if any
767 * validation errors occur.
768 * @param action The <code>ValidatorAction</code> that is currently being
769 * performed.
770 * @param field The <code>Field</code> object associated with the current
771 * field being validated.
772 */
773 public static void validateMaxLength(
774 FacesContext context,
775 Object object,
776 Map parameters,
777 Collection errors,
778 ValidatorAction action,
779 Field field)
780 {
781 final String value = ObjectUtils.toString(object);
782 if (StringUtils.isNotBlank(value))
783 {
784 try
785 {
786 int max = Integer.parseInt(field.getVarValue("maxlength"));
787
788 if (!GenericValidator.maxLength(
789 value,
790 max))
791 {
792 errors.add(ValidatorMessages.getMessage(
793 action,
794 field,
795 context));
796 }
797 }
798 catch (Exception exception)
799 {
800 errors.add(ValidatorMessages.getMessage(
801 action,
802 field,
803 context));
804 }
805 }
806 }
807
808 /**
809 * Checks if the field's length is greater than or equal to the minimum
810 * value. A <code>Null</code> will be considered an error.
811 *
812 * @param context the faces context
813 * @param object the value of the field being validated.
814 * @param parameters Any field parameters from the validation.xml.
815 * @param errors The <code>Map</code> object to add errors to if any
816 * validation errors occur.
817 * @param action The <code>ValidatorAction</code> that is currently being
818 * performed.
819 * @param field The <code>Field</code> object associated with the current
820 * field being validated.
821 */
822 public static void validateMinLength(
823 FacesContext context,
824 Object object,
825 Map parameters,
826 Collection errors,
827 ValidatorAction action,
828 Field field)
829 {
830 String value = ObjectUtils.toString(object);
831 if (!StringUtils.isBlank(value))
832 {
833 try
834 {
835 int min = Integer.parseInt(field.getVarValue("minlength"));
836 if (!GenericValidator.minLength(
837 value,
838 min))
839 {
840 errors.add(ValidatorMessages.getMessage(
841 action,
842 field,
843 context));
844 }
845 }
846 catch (Exception exception)
847 {
848 errors.add(ValidatorMessages.getMessage(
849 action,
850 field,
851 context));
852 }
853 }
854 }
855
856 /**
857 * <p>
858 * Validates whether the URL string passed in is a valid URL or not. Does
859 * this by attempting to construct a java.net.URL instance and checking
860 * whether or not, it's valid.
861 * </p>
862 *
863 * @param context the faces context
864 * @param object the value of the field being validated.
865 * @param parameters Any field parameters from the validation.xml.
866 * @param errors The <code>Map</code> object to add errors to if any
867 * validation errors occur.
868 * @param action The <code>ValidatorAction</code> that is currently being
869 * performed.
870 * @param field The <code>Field</code> object associated with the current
871 * field being validated.
872 */
873 @SuppressWarnings("unused")
874 public static void validateUrl(
875 FacesContext context,
876 Object object,
877 Map parameters,
878 Collection errors,
879 ValidatorAction action,
880 Field field)
881 {
882 boolean valid = true;
883 String urlString = ObjectUtils.toString(object);
884 try
885 {
886 new URL(urlString);
887 }
888 catch (Exception exception)
889 {
890 valid = false;
891 }
892 if (!valid)
893 {
894 errors.add(ValidatorMessages.getMessage(
895 action,
896 field,
897 context));
898 }
899 }
900
901 /**
902 * Checks if the field is a valid time. If the field has a timePattern variable,
903 * that will be used to format <code>java.text.SimpleDateFormat</code>.
904 *
905 * @param context the faces context
906 * @param object the value of the field being validated.
907 * @param parameters Any field parameters from the validation.xml.
908 * @param errors The <code>Map</code> object to add errors to if any
909 * validation errors occur.
910 * @param action The <code>ValidatorAction</code> that is currently being
911 * performed.
912 * @param field The <code>Field</code> object associated with the current
913 * field being validated.
914 */
915 public static void validateTime(
916 FacesContext context,
917 Object object,
918 Map parameters,
919 Collection errors,
920 ValidatorAction action,
921 Field field)
922 {
923 // - only validate if the object is not already a date
924 if (!(object instanceof Date) && !(object instanceof Calendar))
925 {
926 final String value = ObjectUtils.toString(object);
927 final String timePattern = field.getVarValue("timePattern");
928
929 if (StringUtils.isNotBlank(value))
930 {
931 try
932 {
933 if (StringUtils.isNotBlank(timePattern))
934 {
935 final java.text.DateFormat timeFormatter = new SimpleDateFormat(timePattern);
936 timeFormatter.parse(value);
937 }
938 else
939 {
940 DateFormat.getTimeInstance().parse(value);
941 }
942 }
943 catch (Exception exception)
944 {
945 errors.add(ValidatorMessages.getMessage(
946 action,
947 field,
948 context));
949 }
950 }
951 }
952 }
953
954 /**
955 * Checks if the field's value is equal to another field's value on the same form.
956 *
957 * @param context the faces context
958 * @param object the value of the field being validated.
959 * @param parameters Any field parameters from the validation.xml.
960 * @param errors The <code>Map</code> object to add errors to if any
961 * validation errors occur.
962 * @param action The <code>ValidatorAction</code> that is currently being
963 * performed.
964 * @param field The <code>Field</code> object associated with the current
965 * field being validated.
966 * @throws Exception
967 */
968 public static void validateEqual(
969 FacesContext context,
970 Object object,
971 Map parameters,
972 Collection errors,
973 ValidatorAction action,
974 Field field) throws Exception
975 {
976 final String value = ObjectUtils.toString(object);
977 if (StringUtils.isNotBlank(value))
978 {
979 final String equalFieldName = field.getVarValue("fieldName");
980 final EditableValueHolder equalField = (EditableValueHolder)findComponent(context, equalFieldName);
981 final Object equalFieldValue = equalField.getSubmittedValue() != null ? equalField.getSubmittedValue() : equalField.getValue();
982
983 if (equalFieldValue != null && !equalFieldValue.equals(value))
984 {
985 errors.add(ValidatorMessages.getMessage(
986 action,
987 field,
988 context));
989 }
990
991 }
992 }
993
994 /**
995 * @param context
996 * @param componentId
997 * @return component
998 * @throws ValidatorException
999 */
1000 public static UIComponent findComponent(final FacesContext context, final String componentId)
1001 throws ValidatorException
1002 {
1003 UIComponent component = null;
1004 final int index = componentId.indexOf(':');
1005 if (index != -1)
1006 {
1007 final String parentId = componentId.substring(0, index);
1008 UIComponent parent = context.getViewRoot().findComponent(parentId);
1009 if (parent == null)
1010 {
1011 throw new ValidatorException("No component with id: " + parentId + " could be found on view!");
1012 }
1013 final String restOfId = componentId.substring(index + 1, componentId.length());
1014 component = findComponent(context, parent, restOfId);
1015 }
1016 return component;
1017 }
1018
1019 private static final char COMPONENT_NAME_SEPARATOR = ':';
1020
1021 /**
1022 * @param context
1023 * @param parent
1024 * @param componentId
1025 * @return component
1026 */
1027 public static UIComponent findComponent(final FacesContext context, final UIComponent parent, String componentId)
1028 {
1029 UIComponent component = null;
1030 final int index = componentId.indexOf(COMPONENT_NAME_SEPARATOR);
1031 if (index != -1)
1032 {
1033 final String firstId = componentId.substring(0, index);
1034 component = findChildComponent(parent, firstId);
1035 componentId = componentId.substring(index + 1, componentId.length());
1036 }
1037 else if (StringUtils.isNotBlank(componentId))
1038 {
1039 component = findChildComponent(parent, componentId);
1040 }
1041 if (component != null && componentId.indexOf(COMPONENT_NAME_SEPARATOR) != -1)
1042 {
1043 component = findComponent(context, component, componentId);
1044 }
1045 return component;
1046 }
1047
1048 /**
1049 * @param component
1050 * @param id
1051 * @return child
1052 */
1053 public static UIComponent findChildComponent(final UIComponent component, final String id)
1054 {
1055 UIComponent child = null;
1056 if (component != null)
1057 {
1058 if (component.getId().equals(id))
1059 {
1060 child = component;
1061 }
1062 else
1063 {
1064 for (final Iterator iterator = component.getFacetsAndChildren(); iterator.hasNext();)
1065 {
1066 child = findChildComponent((UIComponent)iterator.next(), id);
1067 if (child != null)
1068 {
1069 break;
1070 }
1071 }
1072 }
1073 }
1074 return child;
1075 }
1076 }