Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/struts/validator/FieldChecks.java


1   /*
2    * $Id: FieldChecks.java 54929 2004-10-16 16:38:42Z germuska $ 
3    *
4    * Copyright 2000-2004 The Apache Software Foundation.
5    * 
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    * 
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   * 
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.struts.validator;
20  
21  import java.io.Serializable;
22  import java.util.Date;
23  import java.util.Locale;
24  import java.util.StringTokenizer;
25  
26  import javax.servlet.http.HttpServletRequest;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.apache.commons.validator.Field;
31  import org.apache.commons.validator.GenericTypeValidator;
32  import org.apache.commons.validator.GenericValidator;
33  import org.apache.commons.validator.UrlValidator;
34  import org.apache.commons.validator.ValidatorAction;
35  import org.apache.commons.validator.util.ValidatorUtils;
36  import org.apache.struts.action.ActionMessages;
37  import org.apache.struts.util.RequestUtils;
38  
39  /**
40   * <p>
41   * This class contains the default validations that are used in the
42   * validator-rules.xml file.
43   * </p>
44   * <p>
45   * In general passing in a null or blank will return a null Object or a false
46   * boolean. However, nulls and blanks do not result in an error being added to the
47   * errors.
48   * </p>
49   *
50   * @since Struts 1.1
51   */
52  public class FieldChecks implements Serializable {
53  
54      /**
55       *  Commons Logging instance.
56       */
57      private static final Log log = LogFactory.getLog(FieldChecks.class);
58  
59      public static final String FIELD_TEST_NULL = "NULL";
60      public static final String FIELD_TEST_NOTNULL = "NOTNULL";
61      public static final String FIELD_TEST_EQUAL = "EQUAL";
62  
63      /**
64       * Checks if the field isn't null and length of the field is greater than zero not
65       * including whitespace.
66       *
67       * @param bean The bean validation is being performed on.
68       * @param va The <code>ValidatorAction</code> that is currently being performed.
69       * @param field The <code>Field</code> object associated with the current
70       * field being validated.
71       * @param errors The <code>ActionMessages</code> object to add errors to if
72       * any validation errors occur.
73       * @param request Current request object.
74       * @return true if meets stated requirements, false otherwise.
75       */
76      public static boolean validateRequired(Object bean,
77                                             ValidatorAction va, Field field,
78                                             ActionMessages errors,
79                                             HttpServletRequest request) {
80  
81          String value = null;
82          if (isString(bean)) {
83              value = (String) bean;
84          } else {
85              value = ValidatorUtils.getValueAsString(bean, field.getProperty());
86          }
87  
88          if (GenericValidator.isBlankOrNull(value)) {
89              errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
90              return false;
91          } else {
92              return true;
93          }
94  
95      }
96  
97      /**
98       * Checks if the field isn't null based on the values of other fields.
99       *
100      * @param bean The bean validation is being performed on.
101      * @param va The <code>ValidatorAction</code> that is currently being
102      * performed.
103      * @param field The <code>Field</code> object associated with the current
104      * field being validated.
105      * @param errors The <code>ActionMessages</code> object to add errors to if
106      * any validation errors occur.
107      * @param validator The <code>Validator</code> instance, used to access
108      * other field values.
109      * @param request Current request object.
110      * @return true if meets stated requirements, false otherwise.
111      */
112     public static boolean validateRequiredIf(Object bean,
113                                              ValidatorAction va, Field field,
114                                              ActionMessages errors,
115                                              org.apache.commons.validator.Validator validator,
116                                              HttpServletRequest request) {
117 
118         Object form = validator.getParameterValue(org.apache.commons.validator.Validator.BEAN_PARAM);
119         String value = null;
120         boolean required = false;
121 
122         if (isString(bean)) {
123             value = (String) bean;
124         } else {
125             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
126         }
127 
128         int i = 0;
129         String fieldJoin = "AND";
130         if (!GenericValidator.isBlankOrNull(field.getVarValue("fieldJoin"))) {
131             fieldJoin = field.getVarValue("fieldJoin");
132         }
133 
134         if (fieldJoin.equalsIgnoreCase("AND")) {
135             required = true;
136         }
137 
138         while (!GenericValidator.isBlankOrNull(field.getVarValue("field[" + i + "]"))) {
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             if (field.isIndexed() && dependIndexed.equalsIgnoreCase("true")) {
151                 String key = field.getKey();
152                 if ((key.indexOf("[") > -1) && (key.indexOf("]") > -1)) {
153                     String ind = key.substring(0, key.indexOf(".") + 1);
154                     dependProp = ind + dependProp;
155                 }
156             }
157 
158             dependVal = ValidatorUtils.getValueAsString(form, dependProp);
159             if (dependTest.equals(FIELD_TEST_NULL)) {
160                 if ((dependVal != null) && (dependVal.length() > 0)) {
161                     thisRequired = false;
162                 } else {
163                     thisRequired = true;
164                 }
165             }
166 
167             if (dependTest.equals(FIELD_TEST_NOTNULL)) {
168                 if ((dependVal != null) && (dependVal.length() > 0)) {
169                     thisRequired = true;
170                 } else {
171                     thisRequired = false;
172                 }
173             }
174 
175             if (dependTest.equals(FIELD_TEST_EQUAL)) {
176                 thisRequired = dependTestValue.equalsIgnoreCase(dependVal);
177             }
178 
179             if (fieldJoin.equalsIgnoreCase("AND")) {
180                 required = required && thisRequired;
181             } else {
182                 required = required || thisRequired;
183             }
184 
185             i++;
186         }
187 
188     if (required) {
189       if (GenericValidator.isBlankOrNull(value)) {
190         errors.add(
191           field.getKey(),
192           Resources.getActionMessage(request, va, field));
193 
194                 return false;
195 
196       } else {
197         return true;
198       }
199     }
200         return true;
201     }
202 
203     /**
204      * Checks if the field matches the regular expression in the field's mask attribute.
205      *
206      * @param bean The bean validation is being performed on.
207      * @param va The <code>ValidatorAction</code> that is currently being
208      * performed.
209      * @param field The <code>Field</code> object associated with the current
210      * field being validated.
211      * @param errors   The <code>ActionMessages</code> object to add errors to if
212      * any validation errors occur.
213      * @param request Current request object.
214      * @return true if field matches mask, false otherwise.
215      */
216     public static boolean validateMask(Object bean,
217                                        ValidatorAction va, Field field,
218                                        ActionMessages errors,
219                                        HttpServletRequest request) {
220 
221         String mask = field.getVarValue("mask");
222         String value = null;
223         if (isString(bean)) {
224             value = (String) bean;
225         } else {
226             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
227         }
228 
229         try {
230             if (!GenericValidator.isBlankOrNull(value)
231                 && !GenericValidator.matchRegexp(value, mask)) {
232 
233                 errors.add(
234                     field.getKey(),
235                     Resources.getActionMessage(request, va, field));
236 
237                 return false;
238             } else {
239                 return true;
240             }
241         } catch (Exception e) {
242             log.error(e.getMessage(), e);
243         }
244         return true;
245     }
246 
247 
248     /**
249      * Checks if the field can safely be converted to a byte primitive.
250      *
251      *@param bean The bean validation is being performed on.
252      *@param va The <code>ValidatorAction</code> that is currently being performed.
253      *@param field The <code>Field</code> object associated with the current
254      *field being validated.
255      *@param errors The <code>ActionMessages</code> object to add errors to if
256      *any validation errors occur.
257      *@param request Current request object.
258      *@return true if valid, false otherwise.
259      */
260     public static Object validateByte(Object bean,
261                                     ValidatorAction va, Field field,
262                                     ActionMessages errors,
263                                     HttpServletRequest request) {
264 
265         Object result = null;
266         String value = null;
267         if (isString(bean)) {
268             value = (String) bean;
269         } else {
270             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
271         }
272 
273         if (GenericValidator.isBlankOrNull(value)) {
274             return Boolean.TRUE;
275         }
276 
277         result = GenericTypeValidator.formatByte(value);
278 
279         if (result == null) {
280             errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
281         }
282 
283         return result == null ? Boolean.FALSE : result;
284     }
285 
286 
287     /**
288      * Checks if the field can safely be converted to a short primitive.
289      *
290      * @param bean The bean validation is being performed on.
291      * @param va The <code>ValidatorAction</code> that is currently being performed.
292      * @param field The <code>Field</code> object associated with the current
293      * field being validated.
294      * @param errors The <code>ActionMessages</code> object to add errors to if
295      * any validation errors occur.
296      * @param request Current request object.
297      * @return true if valid, false otherwise.
298      */
299     public static Object validateShort(Object bean,
300                                       ValidatorAction va, Field field,
301                                       ActionMessages errors,
302                                       HttpServletRequest request) {
303         Object result = null;
304         String value = null;
305         if (isString(bean)) {
306             value = (String) bean;
307         } else {
308             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
309         }
310 
311         if (GenericValidator.isBlankOrNull(value)) {
312             return Boolean.TRUE;
313         }
314 
315         result = GenericTypeValidator.formatShort(value);
316 
317         if (result == null) {
318             errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
319         }
320 
321         return result == null ? Boolean.FALSE : result;
322     }
323 
324 
325     /**
326      * Checks if the field can safely be converted to an int primitive.
327      *
328      * @param  bean     The bean validation is being performed on.
329      * @param  va       The <code>ValidatorAction</code> that is currently being performed.
330      * @param  field    The <code>Field</code> object associated with the current
331      *      field being validated.
332      * @param  errors   The <code>ActionMessages</code> object to add errors to if any
333      *      validation errors occur.
334      * @param  request  Current request object.
335      * @return true if valid, false otherwise.
336      */
337     public static Object validateInteger(Object bean,
338                                           ValidatorAction va, Field field,
339                                           ActionMessages errors,
340                                           HttpServletRequest request) {
341         Object result = null;
342         String value = null;
343         if (isString(bean)) {
344             value = (String) bean;
345         } else {
346             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
347         }
348 
349         if (GenericValidator.isBlankOrNull(value)) {
350             return Boolean.TRUE;
351         }
352 
353         result = GenericTypeValidator.formatInt(value);
354 
355         if (result == null) {
356             errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
357         }
358 
359         return result == null ? Boolean.FALSE : result;
360     }
361 
362 
363     /**
364      * Checks if the field can safely be converted to a long primitive.
365      *
366      * @param  bean     The bean validation is being performed on.
367      * @param  va       The <code>ValidatorAction</code> that is currently being performed.
368      * @param  field    The <code>Field</code> object associated with the current
369      *      field being validated.
370      * @param  errors   The <code>ActionMessages</code> object to add errors to if any
371      *      validation errors occur.
372      * @param  request  Current request object.
373      * @return true if valid, false otherwise.
374      */
375     public static Object validateLong(Object bean,
376                                     ValidatorAction va, Field field,
377                                     ActionMessages errors,
378                                     HttpServletRequest request) {
379         Object result = null;
380         String value = null;
381         if (isString(bean)) {
382             value = (String) bean;
383         } else {
384             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
385         }
386 
387         if (GenericValidator.isBlankOrNull(value)) {
388             return Boolean.TRUE;
389         }
390 
391         result = GenericTypeValidator.formatLong(value);
392 
393         if (result == null) {
394             errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
395         }
396 
397         return result == null ? Boolean.FALSE : result;
398     }
399 
400 
401     /**
402      * Checks if the field can safely be converted to a float primitive.
403      *
404      * @param  bean     The bean validation is being performed on.
405      * @param  va       The <code>ValidatorAction</code> that is currently being performed.
406      * @param  field    The <code>Field</code> object associated with the current
407      *      field being validated.
408      * @param  errors   The <code>ActionMessages</code> object to add errors to if any
409      *      validation errors occur.
410      * @param  request  Current request object.
411      * @return true if valid, false otherwise.
412      */
413     public static Object validateFloat(Object bean,
414                                       ValidatorAction va, Field field,
415                                       ActionMessages errors,
416                                       HttpServletRequest request) {
417         Object result = null;
418         String value = null;
419         if (isString(bean)) {
420             value = (String) bean;
421         } else {
422             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
423         }
424 
425         if (GenericValidator.isBlankOrNull(value)) {
426             return Boolean.TRUE;
427         }
428 
429         result = GenericTypeValidator.formatFloat(value);
430 
431         if (result == null) {
432             errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
433         }
434 
435         return result == null ? Boolean.FALSE : result;
436     }
437 
438 
439     /**
440      *  Checks if the field can safely be converted to a double primitive.
441      *
442      * @param  bean     The bean validation is being performed on.
443      * @param  va       The <code>ValidatorAction</code> that is currently being performed.
444      * @param  field    The <code>Field</code> object associated with the current
445      *      field being validated.
446      * @param  errors   The <code>ActionMessages</code> object to add errors to if any
447      *      validation errors occur.
448      * @param  request  Current request object.
449      * @return true if valid, false otherwise.
450      */
451     public static Object validateDouble(Object bean,
452                                         ValidatorAction va, Field field,
453                                         ActionMessages errors,
454                                         HttpServletRequest request) {
455         Object result = null;
456         String value = null;
457         if (isString(bean)) {
458             value = (String) bean;
459         } else {
460             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
461         }
462 
463         if (GenericValidator.isBlankOrNull(value)) {
464             return Boolean.TRUE;
465         }
466 
467         result = GenericTypeValidator.formatDouble(value);
468 
469         if (result == null) {
470             errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
471         }
472 
473         return result == null ? Boolean.FALSE : result;
474     }
475 
476 
477     /**
478      *  Checks if the field is a valid date. If the field has a datePattern variable,
479      *  that will be used to format <code>java.text.SimpleDateFormat</code>. If the
480      *  field has a datePatternStrict variable, that will be used to format <code>java.text.SimpleDateFormat</code>
481      *  and the length will be checked so '2/12/1999' will not pass validation with
482      *  the format 'MM/dd/yyyy' because the month isn't two digits. If no datePattern
483      *  variable is specified, then the field gets the DateFormat.SHORT format for
484      *  the locale. The setLenient method is set to <code>false</code> for all variations.
485      *
486      * @param  bean     The bean validation is being performed on.
487      * @param  va       The <code>ValidatorAction</code> that is currently being performed.
488      * @param  field    The <code>Field</code> object associated with the current
489      *      field being validated.
490      * @param  errors   The <code>ActionMessages</code> object to add errors to if any
491      *      validation errors occur.
492      * @param  request  Current request object.
493      * @return true if valid, false otherwise.
494      */
495     public static Object validateDate(Object bean,
496                                     ValidatorAction va, Field field,
497                                     ActionMessages errors,
498                                     HttpServletRequest request) {
499 
500         Object result = null;
501         String value = null;
502         if (isString(bean)) {
503             value = (String) bean;
504         } else {
505             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
506         }
507         String datePattern = field.getVarValue("datePattern");
508         String datePatternStrict = field.getVarValue("datePatternStrict");
509         Locale locale = RequestUtils.getUserLocale(request, null);
510 
511         if (GenericValidator.isBlankOrNull(value)) {
512             return Boolean.TRUE;
513         }
514 
515         try {
516             if (datePattern != null && datePattern.length() > 0) {
517                 result = GenericTypeValidator.formatDate(value, datePattern, false);
518             } else if (datePatternStrict != null && datePatternStrict.length() > 0) {
519                 result = GenericTypeValidator.formatDate(value, datePatternStrict, true);
520             } else {
521                 result = GenericTypeValidator.formatDate(value, locale);
522             }
523         } catch (Exception e) {
524             log.error(e.getMessage(), e);
525         }
526 
527         if (result == null) {
528             errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
529         }
530 
531         return result == null ? Boolean.FALSE : result;
532     }
533 
534     /**
535      * Checks if a fields value is within a range (min &amp; max specified in the
536      * vars attribute).
537      *
538      * @param  bean     The bean validation is being performed on.
539      * @param  va       The <code>ValidatorAction</code> that is currently being performed.
540      * @param  field    The <code>Field</code> object associated with the current
541      *      field being validated.
542      * @param  errors   The <code>ActionMessages</code> object to add errors to if any
543      *      validation errors occur.
544      * @param  request  Current request object.
545      * @return True if in range, false otherwise.
546      */
547     public static boolean validateIntRange(Object bean,
548                                            ValidatorAction va, Field field,
549                                            ActionMessages errors,
550                                            HttpServletRequest request) {
551 
552         String value = null;
553         if (isString(bean)) {
554             value = (String) bean;
555         } else {
556             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
557         }
558 
559         if (!GenericValidator.isBlankOrNull(value)) {
560             try {
561                 int intValue = Integer.parseInt(value);
562                 int min = Integer.parseInt(field.getVarValue("min"));
563                 int max = Integer.parseInt(field.getVarValue("max"));
564 
565                 if (!GenericValidator.isInRange(intValue, min, max)) {
566                     errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
567 
568                     return false;
569                 }
570             } catch (Exception e) {
571                 errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
572                 return false;
573             }
574         }
575 
576         return true;
577     }
578 
579     /**
580      *  Checks if a fields value is within a range (min &amp; max specified in the
581      *  vars attribute).
582      *
583      * @param  bean     The bean validation is being performed on.
584      * @param  va       The <code>ValidatorAction</code> that is currently being performed.
585      * @param  field    The <code>Field</code> object associated with the current
586      *      field being validated.
587      * @param  errors   The <code>ActionMessages</code> object to add errors to if any
588      *      validation errors occur.
589      * @param  request  Current request object.
590      * @return          True if in range, false otherwise.
591      */
592     public static boolean validateDoubleRange(Object bean,
593                                               ValidatorAction va, Field field,
594                                               ActionMessages errors,
595                                               HttpServletRequest request) {
596 
597         String value = null;
598         if (isString(bean)) {
599             value = (String) bean;
600         } else {
601             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
602         }
603 
604         if (!GenericValidator.isBlankOrNull(value)) {
605             try {
606                 double doubleValue = Double.parseDouble(value);
607                 double min = Double.parseDouble(field.getVarValue("min"));
608                 double max = Double.parseDouble(field.getVarValue("max"));
609 
610                 if (!GenericValidator.isInRange(doubleValue, min, max)) {
611                     errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
612 
613                     return false;
614                 }
615             } catch (Exception e) {
616                 errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
617                 return false;
618             }
619         }
620 
621         return true;
622     }
623 
624     /**
625      *  Checks if a fields value is within a range (min &amp; max specified in the
626      *  vars attribute).
627      *
628      * @param  bean     The bean validation is being performed on.
629      * @param  va       The <code>ValidatorAction</code> that is currently being performed.
630      * @param  field    The <code>Field</code> object associated with the current
631      *      field being validated.
632      * @param  errors   The <code>ActionMessages</code> object to add errors to if any
633      *      validation errors occur.
634      * @param  request  Current request object.
635      * @return True if in range, false otherwise.
636      */
637     public static boolean validateFloatRange(Object bean,
638                                              ValidatorAction va, Field field,
639                                              ActionMessages errors,
640                                              HttpServletRequest request) {
641 
642         String value = null;
643         if (isString(bean)) {
644             value = (String) bean;
645         } else {
646             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
647         }
648 
649         if (!GenericValidator.isBlankOrNull(value)) {
650             try {
651                 float floatValue = Float.parseFloat(value);
652                 float min = Float.parseFloat(field.getVarValue("min"));
653                 float max = Float.parseFloat(field.getVarValue("max"));
654 
655                 if (!GenericValidator.isInRange(floatValue, min, max)) {
656                     errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
657 
658                     return false;
659                 }
660             } catch (Exception e) {
661                 errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
662                 return false;
663             }
664         }
665 
666         return true;
667     }
668 
669 
670     /**
671      *  Checks if the field is a valid credit card number.
672      *
673      * @param  bean     The bean validation is being performed on.
674      * @param  va       The <code>ValidatorAction</code> that is currently being performed.
675      * @param  field    The <code>Field</code> object associated with the current
676      *      field being validated.
677      * @param  errors   The <code>ActionMessages</code> object to add errors to if any
678      *      validation errors occur.
679      * @param  request  Current request object.
680      * @return true if valid, false otherwise.
681      */
682     public static Object validateCreditCard(Object bean,
683                                           ValidatorAction va, Field field,
684                                           ActionMessages errors,
685                                           HttpServletRequest request) {
686 
687         Object result = null;
688         String value = null;
689         if (isString(bean)) {
690             value = (String) bean;
691         } else {
692             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
693         }
694 
695         if (GenericValidator.isBlankOrNull(value)) {
696             return Boolean.TRUE;
697         }
698 
699         result = GenericTypeValidator.formatCreditCard(value);
700 
701         if (result == null) {
702             errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
703         }
704 
705         return result == null ? Boolean.FALSE : result;
706 
707     }
708 
709 
710     /**
711      *  Checks if a field has a valid e-mail address.
712      *
713      * @param  bean     The bean validation is being performed on.
714      * @param  va       The <code>ValidatorAction</code> that is currently being performed.
715      * @param  field    The <code>Field</code> object associated with the current
716      *      field being validated.
717      * @param  errors   The <code>ActionMessages</code> object to add errors to if any
718      *      validation errors occur.
719      * @param  request  Current request object.
720      * @return True if valid, false otherwise.
721      */
722     public static boolean validateEmail(Object bean,
723                                         ValidatorAction va, Field field,
724                                         ActionMessages errors,
725                                         HttpServletRequest request) {
726 
727         String value = null;
728         if (isString(bean)) {
729             value = (String) bean;
730         } else {
731             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
732         }
733 
734         if (!GenericValidator.isBlankOrNull(value) && !GenericValidator.isEmail(value)) {
735             errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
736             return false;
737         } else {
738             return true;
739         }
740     }
741 
742 
743     /**
744      *  Checks if the field's length is less than or equal to the maximum value.
745      *  A <code>Null</code> will be considered an error.
746      *
747      * @param  bean     The bean validation is being performed on.
748      * @param  va       The <code>ValidatorAction</code> that is currently being performed.
749      * @param  field    The <code>Field</code> object associated with the current
750      *      field being validated.
751      * @param  errors   The <code>ActionMessages</code> object to add errors to if any
752      *      validation errors occur.
753      * @param  request  Current request object.
754      * @return True if stated conditions met.
755      */
756     public static boolean validateMaxLength(Object bean,
757                                             ValidatorAction va, Field field,
758                                             ActionMessages errors,
759                                             HttpServletRequest request) {
760 
761         String value = null;
762         if (isString(bean)) {
763             value = (String) bean;
764         } else {
765             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
766         }
767 
768         if (value != null) {
769             try {
770                 int max = Integer.parseInt(field.getVarValue("maxlength"));
771 
772                 if (!GenericValidator.maxLength(value, max)) {
773                     errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
774 
775                     return false;
776                 }
777             } catch (Exception e) {
778                 errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
779                 return false;
780             }
781         }
782 
783         return true;
784     }
785 
786 
787     /**
788      * Checks if the field's length is greater than or equal to the minimum value.
789      * A <code>Null</code> will be considered an error.
790      *
791      * @param  bean     The bean validation is being performed on.
792      * @param  va       The <code>ValidatorAction</code> that is currently being performed.
793      * @param  field    The <code>Field</code> object associated with the current
794      *      field being validated.
795      * @param  errors   The <code>ActionMessages</code> object to add errors to if any
796      *      validation errors occur.
797      * @param  request  Current request object.
798      * @return True if stated conditions met.
799      */
800     public static boolean validateMinLength(Object bean,
801                                             ValidatorAction va, Field field,
802                                             ActionMessages errors,
803                                             HttpServletRequest request) {
804 
805         String value = null;
806         if (isString(bean)) {
807             value = (String) bean;
808         } else {
809             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
810         }
811 
812         if (!GenericValidator.isBlankOrNull(value)) {
813             try {
814                 int min = Integer.parseInt(field.getVarValue("minlength"));
815 
816                 if (!GenericValidator.minLength(value, min)) {
817                     errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
818 
819                     return false;
820                 }
821             } catch (Exception e) {
822                 errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
823                 return false;
824             }
825         }
826 
827         return true;
828     }
829 
830     /**
831      * Checks if a field has a valid url. Four optional variables can be
832      * specified to configure url validation.
833      * <ul>
834      *    <li>Variable <code>allow2slashes</code> can be set to <code>true</code> or
835      *        <code>false</code> to control whether two slashes are allowed -
836      *        default is <code>false</code> (i.e. two slashes are NOT allowed).</li>
837      *    <li>Variable <code>nofragments</code> can be set to <code>true</code> or
838      *        <code>false</code> to control whether fragments are allowed -
839      *        default is <code>false</code> (i.e. fragments ARE allowed).</li>
840      *    <li>Variable <code>allowallschemes</code> can be set to <code>true</code> or
841      *        <code>false</code> to control if all schemes are allowed - default
842      *        is <code>false</code> (i.e. all schemes are NOT allowed).</li>
843      *    <li>Variable <code>schemes</code> can be set to a comma delimited list of
844      *        valid schemes. This value is ignored if <code>allowallschemes</code>
845      *        is set to <code>true</code>. Default schemes allowed are "http",
846      *        "https" and "ftp" if this variable is not specified.</li>
847      * </ul>
848      *
849      * @param  bean     The bean validation is being performed on.
850      * @param  va       The <code>ValidatorAction</code> that is currently being performed.
851      * @param  field    The <code>Field</code> object associated with the current
852      *      field being validated.
853      * @param  errors   The <code>ActionMessages</code> object to add errors to if any
854      *      validation errors occur.
855      * @param  request  Current request object.
856      * @return True if valid, false otherwise.
857      */
858     public static boolean validateUrl(Object bean,
859                                         ValidatorAction va, Field field,
860                                         ActionMessages errors,
861                                         HttpServletRequest request) {
862 
863         String value = null;
864         if (isString(bean)) {
865             value = (String) bean;
866         } else {
867             value = ValidatorUtils.getValueAsString(bean, field.getProperty());
868         }
869 
870         if (GenericValidator.isBlankOrNull(value)) {
871             return true;
872         }
873 
874         // Get the options and schemes Vars
875         boolean allowallschemes = "true".equalsIgnoreCase(field.getVarValue("allowallschemes"));
876         int options = allowallschemes ? UrlValidator.ALLOW_ALL_SCHEMES : 0;
877 
878         if ("true".equalsIgnoreCase(field.getVarValue("allow2slashes"))) {
879           options += UrlValidator.ALLOW_2_SLASHES;
880         }
881 
882         if ("true".equalsIgnoreCase(field.getVarValue("nofragments"))) {
883           options += UrlValidator.NO_FRAGMENTS;
884         }
885 
886         String schemesVar = allowallschemes ? null : field.getVarValue("schemes");
887 
888         // No options or schemes - use GenericValidator as default
889         if (options == 0 && schemesVar == null) {
890             if (GenericValidator.isUrl(value)) {
891                 return true;
892             } else {
893                 errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
894                 return false;
895             }
896         }
897 
898         // Parse comma delimited list of schemes into a String[]
899         String[] schemes = null;
900         if (schemesVar != null) {
901 
902           StringTokenizer st = new StringTokenizer(schemesVar, ",");
903           schemes = new String[st.countTokens()];
904 
905           int i = 0;
906           while (st.hasMoreTokens()) {
907               schemes[i++] = st.nextToken().trim();
908           }
909 
910         }
911 
912         // Create UrlValidator and validate with options/schemes
913         UrlValidator urlValidator = new UrlValidator(schemes, options);
914         if (urlValidator.isValid(value)) {
915             return true;
916         } else {
917             errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
918             return false;
919         }
920     }
921 
922     /**
923      *  Return <code>true</code> if the specified object is a String or a <code>null</code>
924      *  value.
925      *
926      * @param o Object to be tested
927      * @return The string value
928      */
929     protected static boolean isString(Object o) {
930         return (o == null) ? true : String.class.isInstance(o);
931     }
932 
933 }
934