Coverage report

  %line %branch
org.apache.commons.validator.routines.AbstractCalendarValidator
99% 
97% 

 1  
 /*
 2  
  * $Id: AbstractCalendarValidator.java 386637 2006-03-17 13:22:26Z niallp $
 3  
  * $Revision: 386637 $
 4  
  * $Date: 2006-03-17 13:22:26 +0000 (Fri, 17 Mar 2006) $
 5  
  *
 6  
  * ====================================================================
 7  
  * Copyright 2006 The Apache Software Foundation
 8  
  *
 9  
  * Licensed under the Apache License, Version 2.0 (the "License");
 10  
  * you may not use this file except in compliance with the License.
 11  
  * You may obtain a copy of the License at
 12  
  *
 13  
  *     http://www.apache.org/licenses/LICENSE-2.0
 14  
  *
 15  
  * Unless required by applicable law or agreed to in writing, software
 16  
  * distributed under the License is distributed on an "AS IS" BASIS,
 17  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 18  
  * See the License for the specific language governing permissions and
 19  
  * limitations under the License.
 20  
  */
 21  
 package org.apache.commons.validator.routines;
 22  
 
 23  
 import java.text.DateFormatSymbols;
 24  
 import java.text.Format;
 25  
 import java.text.DateFormat;
 26  
 import java.text.SimpleDateFormat;
 27  
 import java.util.Calendar;
 28  
 import java.util.Locale;
 29  
 import java.util.TimeZone;
 30  
 
 31  
 /**
 32  
  * <p>Abstract class for Date/Time/Calendar validation.</p>
 33  
  * 
 34  
  * <p>This is a <i>base</i> class for building Date / Time
 35  
  *    Validators using format parsing.</p>
 36  
  *    
 37  
  * @version $Revision: 386637 $ $Date: 2006-03-17 13:22:26 +0000 (Fri, 17 Mar 2006) $
 38  
  * @since Validator 1.3.0
 39  
  */
 40  
 public abstract class AbstractCalendarValidator extends AbstractFormatValidator {
 41  
 
 42  27
     private int dateStyle = -1;
 43  
 
 44  27
     private int timeStyle = -1;
 45  
 
 46  
     /**
 47  
      * Construct an instance with the specified <i>strict</i>, 
 48  
      * <i>time</i> and <i>date</i> style parameters.
 49  
      * 
 50  
      * @param strict <code>true</code> if strict 
 51  
      *        <code>Format</code> parsing should be used.
 52  
      * @param dateStyle the date style to use for Locale validation.
 53  
      * @param timeStyle the time style to use for Locale validation.
 54  
      */
 55  
     public AbstractCalendarValidator(boolean strict, int dateStyle, class="keyword">int timeStyle) {
 56  27
         super(strict);
 57  27
         this.dateStyle = dateStyle;
 58  27
         this.timeStyle = timeStyle;
 59  27
     }
 60  
 
 61  
     /**
 62  
      * <p>Validate using the specified <code>Locale</code>. 
 63  
      * 
 64  
      * @param value The value validation is being performed on.
 65  
      * @param pattern The pattern used to format the value.
 66  
      * @param locale The locale to use for the Format, defaults to the default
 67  
      * @return <code>true</code> if the value is valid.
 68  
      */
 69  
     public boolean isValid(String value, String pattern, Locale locale) {
 70  134
         Object parsedValue = parse(value, pattern, locale, (TimeZone)null);
 71  134
         return (parsedValue == null ? false : true);
 72  
     }
 73  
 
 74  
     /**
 75  
      * <p>Format an object into a <code>String</code> using
 76  
      * the default Locale.</p>
 77  
      *
 78  
      * @param value The value validation is being performed on.
 79  
      * @param timeZone The Time Zone used to format the date,
 80  
      *  system default if null (unless value is a <code>Calendar</code>.
 81  
      * @return The value formatted as a <code>String</code>.
 82  
      */
 83  
     public String format(Object value, TimeZone timeZone) {
 84  1
         return format(value, (String)null, (Locale)class="keyword">null, timeZone);
 85  
     }
 86  
 
 87  
     /**
 88  
      * <p>Format an object into a <code>String</code> using
 89  
      * the specified pattern.</p>
 90  
      *
 91  
      * @param value The value validation is being performed on.
 92  
      * @param pattern The pattern used to format the value.
 93  
      * @param timeZone The Time Zone used to format the date,
 94  
      *  system default if null (unless value is a <code>Calendar</code>.
 95  
      * @return The value formatted as a <code>String</code>.
 96  
      */
 97  
     public String format(Object value, String pattern, TimeZone timeZone) {
 98  2
         return format(value, pattern, (Locale)null, timeZone);
 99  
     }
 100  
 
 101  
     /**
 102  
      * <p>Format an object into a <code>String</code> using
 103  
      * the specified Locale.</p>
 104  
      *
 105  
      * @param value The value validation is being performed on.
 106  
      * @param locale The locale to use for the Format.
 107  
      * @param timeZone The Time Zone used to format the date,
 108  
      *  system default if null (unless value is a <code>Calendar</code>.
 109  
      * @return The value formatted as a <code>String</code>.
 110  
      */
 111  
     public String format(Object value, Locale locale, TimeZone timeZone) {
 112  1
         return format(value, (String)null, locale, timeZone);
 113  
     }
 114  
 
 115  
     /**
 116  
      * <p>Format an object using the specified pattern and/or 
 117  
      *    <code>Locale</code>. 
 118  
      *
 119  
      * @param value The value validation is being performed on.
 120  
      * @param pattern The pattern used to format the value.
 121  
      * @param locale The locale to use for the Format.
 122  
      * @return The value formatted as a <code>String</code>.
 123  
      */
 124  
     public String format(Object value, String pattern, Locale locale) {
 125  11
         return format(value, pattern, locale, (TimeZone)null);
 126  
     }
 127  
 
 128  
     /**
 129  
      * <p>Format an object using the specified pattern and/or 
 130  
      *    <code>Locale</code>. 
 131  
      *
 132  
      * @param value The value validation is being performed on.
 133  
      * @param pattern The pattern used to format the value.
 134  
      * @param locale The locale to use for the Format.
 135  
      * @param timeZone The Time Zone used to format the date,
 136  
      *  system default if null (unless value is a <code>Calendar</code>.
 137  
      * @return The value formatted as a <code>String</code>.
 138  
      */
 139  
     public String format(Object value, String pattern, Locale locale, TimeZone timeZone) {
 140  16
         DateFormat formatter = (DateFormat)getFormat(pattern, locale);
 141  16
         if (timeZone != null) {
 142  5
             formatter.setTimeZone(timeZone);
 143  11
         } else if (value instanceof Calendar) {
 144  8
             formatter.setTimeZone(((Calendar)value).getTimeZone());
 145  
         }
 146  16
         return format(value, formatter);
 147  
     }
 148  
 
 149  
     /**
 150  
      * <p>Format a value with the specified <code>DateFormat</code>.</p>
 151  
      * 
 152  
      * @param value The value to be formatted.
 153  
      * @param formatter The Format to use.
 154  
      * @return The formatted value.
 155  
      */
 156  
     protected String format(Object value, Format formatter) {
 157  16
         if (value == null) {
 158  1
             return null;
 159  15
         } else if (value instanceof Calendar) {
 160  13
             value = ((Calendar)value).getTime(); 
 161  
         }
 162  15
         return formatter.format(value);
 163  
     }
 164  
 
 165  
     /**
 166  
      * <p>Checks if the value is valid against a specified pattern.</p>
 167  
      *
 168  
      * @param value The value validation is being performed on.
 169  
      * @param pattern The pattern used to validate the value against, or the
 170  
      *        default for the <code>Locale</code> if <code>null</code>.
 171  
      * @param locale The locale to use for the date format, system default if null.
 172  
      * @param timeZone The Time Zone used to parse the date, system default if null.
 173  
      * @return The parsed value if valid or <code>null</code> if invalid.
 174  
      */
 175  
     protected Object parse(String value, String pattern, Locale locale, TimeZone timeZone) {
 176  
 
 177  282
         value = (value == null ? class="keyword">null : value.trim());
 178  282
         if (value == null || value.length() == 0) {
 179  0
             return null;
 180  
         }
 181  282
         DateFormat formatter = (DateFormat)getFormat(pattern, locale);
 182  282
         if (timeZone != null) {
 183  12
             formatter.setTimeZone(timeZone);
 184  
         }
 185  282
         return parse(value, formatter);
 186  
 
 187  
     }
 188  
 
 189  
     /**
 190  
      * <p>Process the parsed value, performing any further validation 
 191  
      *    and type conversion required.</p>
 192  
      * 
 193  
      * @param value The parsed object created.
 194  
      * @param formatter The Format used to parse the value with.
 195  
      * @return The parsed value converted to the appropriate type
 196  
      *         if valid or <code>null</code> if invalid.
 197  
      */
 198  
     protected abstract Object processParsedValue(Object value, Format formatter);
 199  
 
 200  
     /**
 201  
      * <p>Returns a <code>DateFormat</code> for the specified <i>pattern</i>
 202  
      *    and/or <code>Locale</code>.</p>
 203  
      * 
 204  
      * @param pattern The pattern used to validate the value against or
 205  
      *        <code>null</code> to use the default for the <code>Locale</code>.
 206  
      * @param locale The locale to use for the currency format, system default if null.
 207  
      * @return The <code>DateFormat</code> to created.
 208  
      */
 209  
     protected Format getFormat(String pattern, Locale locale) {
 210  298
         DateFormat formatter = null;
 211  298
         boolean usePattern = (pattern != null && pattern.length() > 0);
 212  298
         if (!usePattern) {
 213  145
             formatter = (DateFormat)getFormat(locale);
 214  153
         } else if (locale == null) {
 215  139
             formatter = new SimpleDateFormat(pattern);
 216  
         } else {
 217  14
             DateFormatSymbols symbols = new DateFormatSymbols(locale);
 218  14
             formatter = new SimpleDateFormat(pattern, symbols);
 219  
         }
 220  298
         formatter.setLenient(false);
 221  298
         return formatter;
 222  
     }
 223  
 
 224  
     /**
 225  
      * <p>Returns a <code>DateFormat</code> for the specified Locale.</p>
 226  
      * 
 227  
      * @param locale The locale a <code>DateFormat</code> is required for,
 228  
      *        system default if null.
 229  
      * @return The <code>DateFormat</code> to created.
 230  
      */
 231  
     protected Format getFormat(Locale locale) {
 232  
 
 233  145
         DateFormat formatter = null; 
 234  145
         if (dateStyle >= 0 && timeStyle >= 0) {
 235  2
             if (locale == null) {
 236  1
                 formatter = DateFormat.getDateTimeInstance(dateStyle, timeStyle);
 237  
             } else {
 238  1
                 formatter = DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale);
 239  
             }
 240  143
         } else if (timeStyle >= 0) {
 241  41
             if (locale == null) {
 242  3
                 formatter = DateFormat.getTimeInstance(timeStyle);
 243  
             } else {
 244  38
                 formatter = DateFormat.getTimeInstance(timeStyle, locale);
 245  
             }
 246  
         } else {
 247  102
             int useDateStyle = dateStyle >= 0 ? dateStyle : DateFormat.SHORT;
 248  102
             if (locale == null) {
 249  13
                 formatter = DateFormat.getDateInstance(useDateStyle);
 250  
             } else {
 251  89
                 formatter = DateFormat.getDateInstance(useDateStyle, locale);
 252  
             }
 253  
         }
 254  145
         formatter.setLenient(false);
 255  145
         return formatter;
 256  
 
 257  
     }
 258  
 
 259  
     /**
 260  
      * <p>Compares a calendar value to another, indicating whether it is
 261  
      *    equal, less then or more than at a specified level.</p>
 262  
      * 
 263  
      * @param value The Calendar value.
 264  
      * @param compare The <code>Calendar</code> to check the value against.
 265  
      * @param field The field <i>level</i> to compare to - e.g. specifying
 266  
      *        <code>Calendar.MONTH</code> will compare the year and month
 267  
      *        portions of the calendar. 
 268  
      * @return Zero if the first value is equal to the second, -1
 269  
      *         if it is less than the second or +1 if it is greater than the second.  
 270  
      */
 271  
     protected int compare(Calendar value, Calendar compare, class="keyword">int field) {
 272  
 
 273  44
         int result = 0;
 274  
 
 275  
         // Compare Year
 276  44
         result = calculateCompareResult(value, compare, Calendar.YEAR);
 277  44
         if (result != 0 || field == Calendar.YEAR) {
 278  6
             return result;
 279  
         }
 280  
 
 281  
         // Compare Week of Year
 282  38
         if (field == Calendar.WEEK_OF_YEAR) {
 283  10
             return calculateCompareResult(value, compare, Calendar.WEEK_OF_YEAR);
 284  
         }
 285  
 
 286  
         // Compare Day of the Year
 287  28
         if (field == Calendar.DAY_OF_YEAR) {
 288  1
             return calculateCompareResult(value, compare, Calendar.DAY_OF_YEAR);
 289  
         }
 290  
 
 291  
         // Compare Month
 292  27
         result = calculateCompareResult(value, compare, Calendar.MONTH);
 293  27
         if (result != 0 || field == Calendar.MONTH) {
 294  10
             return result;
 295  
         }
 296  
 
 297  
         // Compare Week of Month
 298  17
         if (field == Calendar.WEEK_OF_MONTH) {
 299  1
             return calculateCompareResult(value, compare, Calendar.WEEK_OF_MONTH);
 300  
         }
 301  
 
 302  
         // Compare Date
 303  16
         result = calculateCompareResult(value, compare, Calendar.DATE);
 304  16
         if (result != 0 || (field == Calendar.DATE || 
 305  
                           field == Calendar.DAY_OF_MONTH ||
 306  
                           field == Calendar.DAY_OF_WEEK ||
 307  
                           field == Calendar.DAY_OF_WEEK_IN_MONTH)) {
 308  10
             return result;
 309  
         }
 310  
 
 311  
         // Compare Time fields
 312  6
         return compareTime(value, compare, field);
 313  
 
 314  
     }
 315  
 
 316  
     /**
 317  
      * <p>Compares a calendar time value to another, indicating whether it is
 318  
      *    equal, less then or more than at a specified level.</p>
 319  
      * 
 320  
      * @param value The Calendar value.
 321  
      * @param compare The <code>Calendar</code> to check the value against.
 322  
      * @param field The field <i>level</i> to compare to - e.g. specifying
 323  
      *        <code>Calendar.MINUTE</code> will compare the hours and minutes
 324  
      *        portions of the calendar. 
 325  
      * @return Zero if the first value is equal to the second, -1
 326  
      *         if it is less than the second or +1 if it is greater than the second.  
 327  
      */
 328  
     protected int compareTime(Calendar value, Calendar compare, class="keyword">int field) {
 329  
 
 330  24
         int result = 0;
 331  
 
 332  
         // Compare Hour
 333  24
         result = calculateCompareResult(value, compare, Calendar.HOUR_OF_DAY);
 334  24
         if (result != 0 || (field == Calendar.HOUR || field == Calendar.HOUR_OF_DAY)) {
 335  7
             return result;
 336  
         }
 337  
 
 338  
         // Compare Minute
 339  17
         result = calculateCompareResult(value, compare, Calendar.MINUTE);
 340  17
         if (result != 0 || field == Calendar.MINUTE) {
 341  7
             return result;
 342  
         }
 343  
 
 344  
         // Compare Second
 345  10
         result = calculateCompareResult(value, compare, Calendar.SECOND);
 346  10
         if (result != 0 || field == Calendar.SECOND) {
 347  6
             return result;
 348  
         }
 349  
 
 350  
         // Compare Milliseconds
 351  4
         if (field == Calendar.MILLISECOND) {
 352  3
             return calculateCompareResult(value, compare, Calendar.MILLISECOND);
 353  
         }
 354  
 
 355  1
         throw new IllegalArgumentException("Invalid field: " + field);
 356  
 
 357  
     }
 358  
 
 359  
     /**
 360  
      * <p>Compares a calendar's quarter value to another, indicating whether it is
 361  
      *    equal, less then or more than the specified quarter.</p>
 362  
      * 
 363  
      * @param value The Calendar value.
 364  
      * @param compare The <code>Calendar</code> to check the value against.
 365  
      * @param monthOfFirstQuarter The  month that the first quarter starts.
 366  
      * @return Zero if the first quarter is equal to the second, -1
 367  
      *         if it is less than the second or +1 if it is greater than the second.  
 368  
      */
 369  
     protected int compareQuarters(Calendar value, Calendar compare, class="keyword">int monthOfFirstQuarter) {
 370  25
         int valueQuarter   = calculateQuarter(value, monthOfFirstQuarter);
 371  25
         int compareQuarter = calculateQuarter(compare, monthOfFirstQuarter);
 372  25
         if (valueQuarter < compareQuarter) {
 373  6
             return -1;
 374  19
         } else if (valueQuarter > compareQuarter) {
 375  9
             return 1;
 376  
         } else {
 377  10
             return 0;
 378  
         }
 379  
     }
 380  
 
 381  
     /**
 382  
      * <p>Calculate the quarter for the specified Calendar.</p>
 383  
      * 
 384  
      * @param calendar The Calendar value.
 385  
      * @param monthOfFirstQuarter The  month that the first quarter starts.
 386  
      * @return The calculated quarter.
 387  
      */
 388  
     private int calculateQuarter(Calendar calendar, class="keyword">int monthOfFirstQuarter) {
 389  
         // Add Year
 390  50
         int year = calendar.get(Calendar.YEAR);
 391  
 
 392  50
         int month = (calendar.get(Calendar.MONTH) + 1);
 393  50
         int relativeMonth = (month >= monthOfFirstQuarter)
 394  
                           ? (month - monthOfFirstQuarter)
 395  
                           : (month + (12 - monthOfFirstQuarter));
 396  50
         int quarter = ((relativeMonth / 3) + 1);
 397  
         // adjust the year if the quarter doesn't start in January
 398  50
         if (month < monthOfFirstQuarter) {
 399  1
             --year;
 400  
         }
 401  50
         return (year * 10) + quarter;
 402  
     }
 403  
 
 404  
     /**
 405  
      * <p>Compares the field from two calendars indicating whether the field for the
 406  
      *    first calendar is equal to, less than or greater than the field from the
 407  
      *    second calendar.
 408  
      *    
 409  
      * @param value The Calendar value.
 410  
      * @param compare The <code>Calendar</code> to check the value against.
 411  
      * @param field The field to compare for the calendars.
 412  
      * @return Zero if the first calendar's field is equal to the seconds, -1
 413  
      *         if it is less than the seconds or +1 if it is greater than the seconds.  
 414  
      */
 415  
     private int calculateCompareResult(Calendar value, Calendar compare, class="keyword">int field) {
 416  153
         int difference = value.get(field) - compare.get(field);
 417  153
         if (dclass="keyword">ifference < 0) {
 418  13
             return -1;
 419  140
         } else if (dclass="keyword">ifference > 0) {
 420  17
             return 1;
 421  
         } else {
 422  123
             return 0;
 423  
         }
 424  
     }
 425  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.