Coverage Report - org.apache.tapestry.valid.DateValidator
 
Classes in this File Line Coverage Branch Coverage Complexity
DateValidator
0%
0/79
0%
0/28
1.923
 
 1  
 // Copyright 2004, 2005 The Apache Software Foundation
 2  
 //
 3  
 // Licensed under the Apache License, Version 2.0 (the "License");
 4  
 // you may not use this file except in compliance with the License.
 5  
 // You may obtain a copy of the License at
 6  
 //
 7  
 //     http://www.apache.org/licenses/LICENSE-2.0
 8  
 //
 9  
 // Unless required by applicable law or agreed to in writing, software
 10  
 // distributed under the License is distributed on an "AS IS" BASIS,
 11  
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  
 // See the License for the specific language governing permissions and
 13  
 // limitations under the License.
 14  
 
 15  
 package org.apache.tapestry.valid;
 16  
 
 17  
 import java.text.DateFormat;
 18  
 import java.text.ParseException;
 19  
 import java.text.SimpleDateFormat;
 20  
 import java.util.Calendar;
 21  
 import java.util.Date;
 22  
 import java.util.GregorianCalendar;
 23  
 import java.util.HashMap;
 24  
 import java.util.Map;
 25  
 
 26  
 import org.apache.tapestry.IMarkupWriter;
 27  
 import org.apache.tapestry.IRequestCycle;
 28  
 import org.apache.tapestry.form.IFormComponent;
 29  
 
 30  
 /**
 31  
  * Provides input validation for strings treated as dates. In addition, allows a minimum and maximum
 32  
  * date to be set.
 33  
  * 
 34  
  * @author Howard Lewis Ship
 35  
  * @since 1.0.8
 36  
  */
 37  
 
 38  
 public class DateValidator extends BaseValidator
 39  
 {
 40  
     public static final String DEFAULT_DISPLAY_FORMAT = "MM/DD/YYYY";
 41  
     
 42  0
     public static final DateFormat DEFAULT_DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy");
 43  
     
 44  
     private DateFormat _format;
 45  
 
 46  
     private String _displayFormat;
 47  
 
 48  
     private Date _minimum;
 49  
 
 50  
     private Date _maximum;
 51  
 
 52  
     private Calendar _calendar;
 53  
 
 54  0
     private String _scriptPath = "/org/apache/tapestry/valid/DateValidator.script";
 55  
 
 56  
     private String _dateTooEarlyMessage;
 57  
 
 58  
     private String _dateTooLateMessage;
 59  
 
 60  
     private String _invalidDateFormatMessage;
 61  
 
 62  
     public DateValidator()
 63  0
     {
 64  
 
 65  0
     }
 66  
 
 67  
     /**
 68  
      * Initializes the DateValidator with properties defined by the initializer.
 69  
      * 
 70  
      * @since 4.0
 71  
      */
 72  
 
 73  
     public DateValidator(String initializer)
 74  
     {
 75  0
         super(initializer);
 76  0
     }
 77  
 
 78  
     public void setFormat(DateFormat value)
 79  
     {
 80  0
         _format = value;
 81  0
     }
 82  
 
 83  
     public DateFormat getFormat()
 84  
     {
 85  0
         return _format;
 86  
     }
 87  
 
 88  
     /**
 89  
      * @return the {@link DateFormat}the validator will use, returning the default if no other date
 90  
      *         format is specified via {@link #setFormat(DateFormat)}
 91  
      * @since 3.0
 92  
      */
 93  
     public DateFormat getEffectiveFormat()
 94  
     {
 95  0
         if (_format == null)
 96  0
             return DEFAULT_DATE_FORMAT;
 97  
 
 98  0
         return _format;
 99  
     }
 100  
 
 101  
     public String getDisplayFormat()
 102  
     {
 103  0
         return _displayFormat;
 104  
     }
 105  
 
 106  
     public void setDisplayFormat(String value)
 107  
     {
 108  0
         _displayFormat = value;
 109  0
     }
 110  
 
 111  
     /**
 112  
      * @return the display format message the validator will use, returning the default if no other
 113  
      *         display format message is specified. The default is the
 114  
      *         {@link SimpleDateFormat#toPattern()}for {@link SimpleDateFormat}s, or "MM/DD/YYYY"
 115  
      *         for unknown {@link DateFormat}subclasses.
 116  
      * @since 3.0
 117  
      */
 118  
     public String getEffectiveDisplayFormat()
 119  
     {
 120  0
         if (_displayFormat == null)
 121  
         {
 122  0
             DateFormat format = getEffectiveFormat();
 123  0
             if (format instanceof SimpleDateFormat)
 124  0
                 return ((SimpleDateFormat) format).toPattern();
 125  
 
 126  0
             return DEFAULT_DISPLAY_FORMAT;
 127  
         }
 128  
 
 129  0
         return _displayFormat;
 130  
     }
 131  
 
 132  
     public String toString(IFormComponent file, Object value)
 133  
     {
 134  0
         if (value == null)
 135  0
             return null;
 136  
 
 137  0
         Date date = (Date) value;
 138  
 
 139  0
         DateFormat format = getEffectiveFormat();
 140  
 
 141  
         // DateFormat is not threadsafe, so guard access to it.
 142  
 
 143  0
         synchronized (format)
 144  
         {
 145  0
             return format.format(date);
 146  0
         }
 147  
     }
 148  
 
 149  
     public Object toObject(IFormComponent field, String value) throws ValidatorException
 150  
     {
 151  0
         if (checkRequired(field, value))
 152  0
             return null;
 153  
 
 154  0
         DateFormat format = getEffectiveFormat();
 155  
 
 156  
         Date result;
 157  
 
 158  
         try
 159  
         {
 160  
             // DateFormat is not threadsafe, so guard access
 161  
             // to it.
 162  
 
 163  0
             synchronized (format)
 164  
             {
 165  0
                 result = format.parse(value);
 166  0
             }
 167  
 
 168  0
             if (_calendar == null)
 169  0
                 _calendar = new GregorianCalendar();
 170  
 
 171  0
             _calendar.setTime(result);
 172  
 
 173  
             // SimpleDateFormat allows two-digit dates to be
 174  
             // entered, i.e., 12/24/66 is Dec 24 0066 ... that's
 175  
             // probably not what is really wanted, so treat
 176  
             // it as an invalid date.
 177  
 
 178  0
             if (_calendar.get(Calendar.YEAR) < 1000)
 179  0
                 result = null;
 180  
 
 181  
         }
 182  0
         catch (ParseException ex)
 183  
         {
 184  
             // ParseException does not include a useful error message
 185  
             // about what's wrong.
 186  0
             result = null;
 187  0
         }
 188  
 
 189  0
         if (result == null)
 190  0
             throw new ValidatorException(buildInvalidDateFormatMessage(field),
 191  
                     ValidationConstraint.DATE_FORMAT);
 192  
 
 193  
         // OK, check that the date is in range.
 194  
 
 195  0
         if (_minimum != null && _minimum.compareTo(result) > 0)
 196  0
             throw new ValidatorException(buildDateTooEarlyMessage(field, format.format(_minimum)),
 197  
                     ValidationConstraint.TOO_SMALL);
 198  
 
 199  0
         if (_maximum != null && _maximum.compareTo(result) < 0)
 200  0
             throw new ValidatorException(buildDateTooLateMessage(field, format.format(_maximum)),
 201  
                     ValidationConstraint.TOO_LARGE);
 202  
 
 203  0
         return result;
 204  
 
 205  
     }
 206  
 
 207  
     public Date getMaximum()
 208  
     {
 209  0
         return _maximum;
 210  
     }
 211  
 
 212  
     public void setMaximum(Date maximum)
 213  
     {
 214  0
         _maximum = maximum;
 215  0
     }
 216  
 
 217  
     public Date getMinimum()
 218  
     {
 219  0
         return _minimum;
 220  
     }
 221  
 
 222  
     public void setMinimum(Date minimum)
 223  
     {
 224  0
         _minimum = minimum;
 225  0
     }
 226  
 
 227  
     /**
 228  
      * @since 2.2
 229  
      */
 230  
 
 231  
     public void renderValidatorContribution(IFormComponent field, IMarkupWriter writer,
 232  
             IRequestCycle cycle)
 233  
     {
 234  0
         if (!(isClientScriptingEnabled() && isRequired()))
 235  0
             return;
 236  
         
 237  0
         Map symbols = new HashMap();
 238  
         
 239  0
         symbols.put("requiredMessage", buildRequiredMessage(field));
 240  
         
 241  0
         processValidatorScript(_scriptPath, cycle, field, symbols);
 242  0
     }
 243  
     
 244  
     /**
 245  
      * @since 2.2
 246  
      */
 247  
 
 248  
     public String getScriptPath()
 249  
     {
 250  0
         return _scriptPath;
 251  
     }
 252  
 
 253  
     /**
 254  
      * Allows a developer to use the existing validation logic with a different client-side script.
 255  
      * This is often sufficient to allow application-specific error presentation (perhaps by using
 256  
      * DHTML to update the content of a &lt;span&gt; tag, or to use a more sophisticated pop-up
 257  
      * window than <code>window.alert()</code>).
 258  
      * 
 259  
      * @since 2.2
 260  
      */
 261  
 
 262  
     public void setScriptPath(String scriptPath)
 263  
     {
 264  0
         _scriptPath = scriptPath;
 265  0
     }
 266  
 
 267  
     /** @since 3.0 */
 268  
 
 269  
     public String getDateTooEarlyMessage()
 270  
     {
 271  0
         return _dateTooEarlyMessage;
 272  
     }
 273  
 
 274  
     /** @since 3.0 */
 275  
 
 276  
     public String getDateTooLateMessage()
 277  
     {
 278  0
         return _dateTooLateMessage;
 279  
     }
 280  
 
 281  
     /** @since 3.0 */
 282  
 
 283  
     public String getInvalidDateFormatMessage()
 284  
     {
 285  0
         return _invalidDateFormatMessage;
 286  
     }
 287  
 
 288  
     /** @since 3.0 */
 289  
 
 290  
     protected String buildInvalidDateFormatMessage(IFormComponent field)
 291  
     {
 292  0
         String pattern = getPattern(_invalidDateFormatMessage, "invalid-date-format", field
 293  
                 .getPage().getLocale());
 294  
 
 295  0
         return formatString(pattern, field.getDisplayName(), getEffectiveDisplayFormat());
 296  
     }
 297  
 
 298  
     /** @since 3.0 * */
 299  
 
 300  
     protected String buildDateTooEarlyMessage(IFormComponent field, String earliestDate)
 301  
     {
 302  0
         String pattern = getPattern(_dateTooEarlyMessage, "date-too-early", field.getPage()
 303  
                 .getLocale());
 304  
 
 305  0
         return formatString(pattern, field.getDisplayName(), earliestDate);
 306  
     }
 307  
 
 308  
     /** @since 3.0 */
 309  
 
 310  
     protected String buildDateTooLateMessage(IFormComponent field, String latestDate)
 311  
     {
 312  0
         String pattern = getPattern(_dateTooLateMessage, "date-too-late", field.getPage()
 313  
                 .getLocale());
 314  
 
 315  0
         return formatString(pattern, field.getDisplayName(), latestDate);
 316  
     }
 317  
 
 318  
     /**
 319  
      * Overrides the bundle key <code>date-too-early</code>. Parameter {0} is the display name of
 320  
      * the field. Parameter {1} is the earliest allowed date.
 321  
      * 
 322  
      * @since 3.0
 323  
      */
 324  
 
 325  
     public void setDateTooEarlyMessage(String string)
 326  
     {
 327  0
         _dateTooEarlyMessage = string;
 328  0
     }
 329  
 
 330  
     /**
 331  
      * Overrides the bundle key <code>date-too-late</code>. Parameter {0} is the display name of
 332  
      * the field. Parameter {1} is the latest allowed date.
 333  
      * 
 334  
      * @since 3.0
 335  
      */
 336  
 
 337  
     public void setDateTooLateMessage(String string)
 338  
     {
 339  0
         _dateTooLateMessage = string;
 340  0
     }
 341  
 
 342  
     /**
 343  
      * Overrides the bundle key <code>invalid-date-format</code>. Parameter {0} is the display
 344  
      * name of the field. Parameter {1} is the allowed format.
 345  
      * 
 346  
      * @since 3.0
 347  
      */
 348  
 
 349  
     public void setInvalidDateFormatMessage(String string)
 350  
     {
 351  0
         _invalidDateFormatMessage = string;
 352  0
     }
 353  
 
 354  
 }