View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  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,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.trinidad.validator;
20  
21  import java.text.DateFormatSymbols;
22  
23  import java.util.Calendar;
24  import java.util.Date;
25  import java.util.HashMap;
26  import java.util.HashSet;
27  import java.util.List;
28  import java.util.Locale;
29  import java.util.Map;
30  import java.util.Set;
31  import java.util.TimeZone;
32  
33  import javax.el.ValueExpression;
34  
35  import javax.faces.application.FacesMessage;
36  import javax.faces.component.StateHolder;
37  import javax.faces.component.UIComponent;
38  import javax.faces.component.ValueHolder;
39  import javax.faces.context.FacesContext;
40  import javax.faces.convert.Converter;
41  import javax.faces.convert.DateTimeConverter;
42  import javax.faces.el.ValueBinding;
43  import javax.faces.validator.Validator;
44  import javax.faces.validator.ValidatorException;
45  
46  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
47  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFValidator;
48  import org.apache.myfaces.trinidad.bean.FacesBean;
49  import org.apache.myfaces.trinidad.bean.PropertyKey;
50  import org.apache.myfaces.trinidad.context.RequestContext;
51  import org.apache.myfaces.trinidad.logging.TrinidadLogger;
52  import org.apache.myfaces.trinidad.model.DateListProvider;
53  import org.apache.myfaces.trinidad.util.ComponentUtils;
54  import org.apache.myfaces.trinidad.util.MessageFactory;
55  
56  @JSFValidator(configExcluded=true)
57  public class DateRestrictionValidator implements Validator, StateHolder {
58  
59  
60    public static final String VALIDATOR_ID = "org.apache.myfaces.trinidad.DateRestriction";
61    
62    /**
63     * <p>The message identifier of the {@link javax.faces.application.FacesMessage}
64     * to be created if the valid days  value check fails.  The message format
65     * string for this message may optionally include <code>{0}</code>,
66     * <code>{1}</code> and <code>{3}</code> placeholders,
67     * which will be replaced by user input, component label and configured
68     * days value.</p>
69     */
70    public static final String DAY_MESSAGE_ID =
71        "org.apache.myfaces.trinidad.validator.DateRestrictionValidator.DAY";
72  
73    /**
74     * <p>The message identifier of the {@link javax.faces.application.FacesMessage}
75     * to be created if the valid month value check fails.  The message format
76     * string for this message may optionally include <code>{0}</code>,
77     * <code>{1}</code> and <code>{3}</code> placeholders,
78     * which will be replaced by user input, component label and configured
79     * month value.</p>
80     */
81    public static final String MONTH_MESSAGE_ID =
82        "org.apache.myfaces.trinidad.validator.DateRestrictionValidator.MONTH";
83  
84    /**
85     * <p>The message identifier of the {@link javax.faces.application.FacesMessage}
86     * to be created if the valid weekdays value check fails.  The message format
87     * string for this message may optionally include <code>{0}</code>,
88     * <code>{1}</code> and <code>{3}</code> placeholders,
89     * which will be replaced by user input, component label and configured
90     * weekdays value.</p>
91     */
92    public static final String WEEKDAY_MESSAGE_ID =
93        "org.apache.myfaces.trinidad.validator.DateRestrictionValidator.WEEKDAY";
94  
95    /**
96     * Construct a {@link Validator} with no preconfigured limits.
97     */
98    public DateRestrictionValidator()
99    {
100     super();
101     _initMaps();
102   }
103 
104   @JSFProperty
105   public final String[] getInvalidMonths()
106   {
107     return (String[]) _facesBean.getProperty(_INVALID_MONTHS);
108   }
109 
110   public final void setInvalidMonths(String[] invalidMonths)
111   {
112     _facesBean.setProperty(_INVALID_MONTHS, invalidMonths);
113   }
114   
115   @JSFProperty
116   public final String[] getInvalidDaysOfWeek()
117   {
118     return (String[]) _facesBean.getProperty(_INVALID_DAYS_OF_WEEK);  }
119 
120   public final void setInvalidDaysOfWeek(String[] invalidDaysOfWeek)
121   {
122     _facesBean.setProperty(_INVALID_DAYS_OF_WEEK, invalidDaysOfWeek);
123   }
124   
125   @JSFProperty
126   public final DateListProvider getInvalidDays()
127   {
128     return (DateListProvider)_facesBean.getProperty(_INVALID_DAYS);
129   }
130 
131   public final void setInvalidDays(DateListProvider invalidDays)
132   {
133     _facesBean.setProperty(_INVALID_DAYS, invalidDays);
134   }
135   
136   @JSFProperty
137   public final String getMessageDetailInvalidMonths()
138   {
139     Object messageDetailInvalidMonths = _facesBean.getProperty(_INVALID_MONTHS_MESSAGE_DETAIL_KEY);
140     return ComponentUtils.resolveString(messageDetailInvalidMonths);
141   }
142 
143   public final void setMessageDetailInvalidMonths(String invalidMonths)
144   {
145     _facesBean.setProperty(_INVALID_MONTHS_MESSAGE_DETAIL_KEY, invalidMonths);
146   }
147   
148   @JSFProperty
149   public final String getMessageDetailInvalidDaysOfWeek()
150   {
151     Object messageDetailInvalidDaysOfWeek = _facesBean.getProperty(_INVALID_DAYS_OF_WEEK_MESSAGE_DETAIL_KEY);
152     return ComponentUtils.resolveString(messageDetailInvalidDaysOfWeek);
153   }
154 
155   public final void setMessageDetailInvalidDaysOfWeek(String invalidDaysOfWeek)
156   {
157     _facesBean.setProperty(_INVALID_DAYS_OF_WEEK_MESSAGE_DETAIL_KEY, invalidDaysOfWeek);
158   }
159   
160   @JSFProperty
161   public final String getMessageDetailInvalidDays()
162   {
163     Object messageDetailInvalidDays = _facesBean.getProperty(_INVALID_DAYS_MESSAGE_DETAIL_KEY);
164     return ComponentUtils.resolveString(messageDetailInvalidDays);
165   }
166 
167   public final void setMessageDetailInvalidDays(String invalidDays)
168   {
169     _facesBean.setProperty(_INVALID_DAYS_MESSAGE_DETAIL_KEY, invalidDays);
170   }
171 
172   /**
173    * <p>Custom hint invalidDaysOfWeek message.</p>
174    * Overrides default hint message
175    * @param hintWeek Custom hint message.
176    */
177   public void setHintInvalidDaysOfWeek(String hintWeek)
178   {
179     _facesBean.setProperty(_HINT_WEEK_KEY, hintWeek);
180   }
181 
182   /**
183    * <p>Return custom hint invalidDaysOfWeek message.</p>
184    * @return Custom hint message.
185    * @see  #setHintInvalidDaysOfWeek(String)
186    */
187   @JSFProperty(tagExcluded=true)
188   public String getHintInvalidDaysOfWeek()
189   {
190     Object obj = _facesBean.getProperty(_HINT_WEEK_KEY);
191     return ComponentUtils.resolveString(obj);
192   }
193 
194   /**
195    * <p>Custom hint invalidMonths message.</p>
196    * Overrides default hint message
197    * @param hintMonth Custom hint message.
198    */
199   public void setHintInvalidMonths(String hintMonth)
200   {
201     _facesBean.setProperty(_HINT_MONTH_KEY, hintMonth);
202   }
203 
204   /**
205    * <p>Return custom hint invalidMonths message.</p>
206    * @return Custom hint message.
207    * @see  #setHintInvalidMonths(String)
208    */
209   @JSFProperty(tagExcluded=true)
210   public String getHintInvalidMonths()
211   {
212     Object obj = _facesBean.getProperty(_HINT_MONTH_KEY);
213     return ComponentUtils.resolveString(obj);
214   }
215 
216   /**
217    * @exception IllegalArgumentException if <code>value</code> is not of type
218    * {@link java.util.Date}
219    */
220   public void validate(
221     FacesContext context,
222     UIComponent  component,
223     Object       value) throws ValidatorException
224   {
225     if (isDisabled())
226       return;
227     
228     if ((context == null) || (component == null))
229     {
230       throw new NullPointerException(_LOG.getMessage(
231         "NULL_FACESCONTEXT_OR_UICOMPONENT"));
232     }
233 
234     if (value != null)
235     {
236       Calendar calendar = getCalendar();
237       Converter converter = _getConverter(context, component);
238       
239       // If we have a DateTimeConverter, use the converter timezone if configured
240       if (converter instanceof DateTimeConverter)
241       {
242         TimeZone tz = ((DateTimeConverter) converter).getTimeZone();
243         
244         if (tz != null) 
245         {
246           calendar.setTimeZone(tz);    
247         }
248       }
249 
250       calendar.setTime(getDateValue(value));
251       int dayOfTheWeekIndex = calendar.get(Calendar.DAY_OF_WEEK);
252       String weekday = _dayMap.get(dayOfTheWeekIndex);
253       
254       if (_getInvalidDaysOfWeek().contains(weekday))
255       {
256         throw new ValidatorException(_getWrongWeekDayMessage(context, component, converter, value, dayOfTheWeekIndex));
257       }
258       
259       int monthIndex = calendar.get(Calendar.MONTH);
260       String month = _monthMap.get(monthIndex);
261       if ( _getInvalidMonths().contains(month))
262       {
263         throw new ValidatorException(_getWrongMonthMessage(context, component, converter, value, monthIndex));
264       }
265       
266       DateListProvider dlp = getInvalidDays();
267         
268       if (dlp != null)
269       {
270         Calendar base = (Calendar)calendar.clone();
271           
272         // Reset the time part for range-start
273         calendar.set(Calendar.HOUR_OF_DAY, 0);
274         calendar.set(Calendar.MINUTE, 0);
275         calendar.set(Calendar.SECOND, 0);
276         calendar.set(Calendar.MILLISECOND, 0);
277         Date rangeStart = calendar.getTime();
278           
279         // Max out the time part for range-end
280         calendar.add(Calendar.DAY_OF_YEAR, 1);
281         calendar.add(Calendar.MILLISECOND, -1);
282         Date rangeEnd = calendar.getTime();
283           
284         // Get disabled/invalid dates between start and end range.
285         List<Date> dates = dlp.getDateList(context, base, rangeStart, rangeEnd);
286         
287         if(dates != null)
288         {
289           for (Date date : dates)
290           {
291             //range is only one submitted day...
292             if(!date.before(rangeStart) && !date.after(rangeEnd))
293             {
294               throw new ValidatorException(_getWrongDayMessage(context, component, value, date));
295             }
296           } //end-for
297         } //end if(dates!=null)
298       } // end  if (dlp != null)
299     } // end if (value != null)
300   }
301 
302   //  StateHolder Methods
303   public Object saveState(FacesContext context)
304   {
305     return _facesBean.saveState(context);
306   }
307 
308 
309   public void restoreState(FacesContext context, Object state)
310   {
311     _facesBean.restoreState(context, state);
312   }
313 
314   @JSFProperty(istransient=true, tagExcluded=true)
315   public boolean isTransient()
316   {
317     return (_transientValue);
318   }
319 
320 
321   public void setTransient(boolean transientValue)
322   {
323     _transientValue = transientValue;
324   }
325   //  End of StateHolder Methods
326 
327 
328   /**
329    * <p>Set the {@link ValueExpression} used to calculate the value for the
330    * specified attribute if any.</p>
331    *
332    * @param name Name of the attribute for which to set a {@link ValueExpression}
333    * @param expression The {@link ValueExpression} to set, or <code>null</code>
334    *  to remove any currently set {@link ValueExpression}
335    *
336    * @exception NullPointerException if <code>name</code>
337    *  is <code>null</code>
338    * @exception IllegalArgumentException if <code>name</code> is not a valid
339    *            attribute of this converter
340    */
341   public void setValueExpression(String name, ValueExpression expression)
342   {
343     ValidatorUtils.setValueExpression(_facesBean, name, expression) ;
344   }
345 
346 
347   /**
348    * <p>Return the {@link ValueExpression} used to calculate the value for the
349    * specified attribute name, if any.</p>
350    *
351    * @param name Name of the attribute or property for which to retrieve a
352    *  {@link ValueExpression}
353    *
354    * @exception NullPointerException if <code>name</code>
355    *  is <code>null</code>
356    * @exception IllegalArgumentException if <code>name</code> is not a valid
357    * attribute of this converter
358    */
359   public ValueExpression getValueExpression(String name)
360   {
361     return ValidatorUtils.getValueExpression(_facesBean, name);
362   }
363 
364 
365   /**
366    * <p>Set the {@link ValueBinding} used to calculate the value for the
367    * specified attribute if any.</p>
368    *
369    * @param name Name of the attribute for which to set a {@link ValueBinding}
370    * @param binding The {@link ValueBinding} to set, or <code>null</code>
371    *  to remove any currently set {@link ValueBinding}
372    *
373    * @exception NullPointerException if <code>name</code>
374    *  is <code>null</code>
375    * @exception IllegalArgumentException if <code>name</code> is not a valid
376    *            attribute of this validator
377    * @deprecated
378    */
379   public void setValueBinding(String name, ValueBinding binding)
380   {
381     ValidatorUtils.setValueBinding(_facesBean, name, binding) ;
382   }
383 
384   /**
385    * <p>Return the {@link ValueBinding} used to calculate the value for the
386    * specified attribute name, if any.</p>
387    *
388    * @param name Name of the attribute or property for which to retrieve a
389    *  {@link ValueBinding}
390    *
391    * @exception NullPointerException if <code>name</code>
392    *  is <code>null</code>
393    * @exception IllegalArgumentException if <code>name</code> is not a valid
394    * attribute of this validator
395    * @deprecated
396    */
397   public ValueBinding getValueBinding(String name)
398   {
399     return ValidatorUtils.getValueBinding(_facesBean, name);
400   }
401 
402   @Override
403   public boolean equals(Object o)
404   {
405     if ( o instanceof DateRestrictionValidator)
406     {
407       DateRestrictionValidator that = (DateRestrictionValidator)o;
408 
409       if ( _transientValue == that._transientValue &&
410            isDisabled() == that.isDisabled() &&
411            (ValidatorUtils.equals(getInvalidDays(), that.getInvalidDays())) &&
412            (ValidatorUtils.equals(getInvalidDaysOfWeek(), that.getInvalidDaysOfWeek())) &&
413            (ValidatorUtils.equals(getInvalidMonths(), that.getInvalidMonths())) &&
414            (ValidatorUtils.equals(getMessageDetailInvalidDays(),
415                                    that.getMessageDetailInvalidDays())) &&
416            (ValidatorUtils.equals(getMessageDetailInvalidDaysOfWeek(),
417                                    that.getMessageDetailInvalidDaysOfWeek())) &&
418            (ValidatorUtils.equals(getMessageDetailInvalidMonths(),
419                                    that.getMessageDetailInvalidMonths()))
420           )
421       {
422         return true;
423       }
424     }
425     return false;
426   }
427 
428   @Override
429   public int hashCode()
430   {
431     int result = 17;
432     Object days = getInvalidDays();
433     Object daysOfWeek = getInvalidDaysOfWeek();
434     Object month = getInvalidMonths();
435     Object msgDetDays = getMessageDetailInvalidDays();
436     Object msgDetDaysOfWeek = getMessageDetailInvalidDaysOfWeek();
437     Object msgDetMonth = getMessageDetailInvalidMonths();
438 
439     result = 37 * result + ( days == null ? 0 : days.hashCode());
440     result = 37 * result + ( daysOfWeek == null ? 0 : daysOfWeek.hashCode());
441     result = 37 * result + ( month == null ? 0 : month.hashCode());
442     result = 37 * result + ( _transientValue ? 0 : 1);
443     result = 37 * result + (isDisabled() ? 1 : 0);
444     result = 37 * result + ( msgDetDays == null ? 0: msgDetDays.hashCode());
445     result = 37 * result + ( msgDetDaysOfWeek == null ? 0: msgDetDaysOfWeek.hashCode());
446     result = 37 * result + ( msgDetMonth == null ? 0: msgDetMonth.hashCode());
447     return result;
448   }
449 
450   /**
451     * Return whether it is disabled.
452     * @return true if it's disabled and false if it's enabled. 
453     */ 
454   public void setDisabled(boolean isDisabled)
455   {
456     _facesBean.setProperty(_DISABLED_KEY, Boolean.valueOf(isDisabled));
457   }
458 
459   /**
460     * Return whether it is disabled.
461     * @return true if it's disabled and false if it's enabled. 
462     */  
463   public boolean isDisabled()
464   {
465     Boolean disabled = (Boolean) _facesBean.getProperty(_DISABLED_KEY);
466     
467     return (disabled != null) ? disabled.booleanValue() : false;
468   }  
469 
470   protected Calendar getCalendar()
471   {
472     TimeZone tz = null;
473     RequestContext rctx = RequestContext.getCurrentInstance();
474   
475     if (rctx != null)
476     {
477       tz = rctx.getTimeZone();
478     }
479     else
480     {
481       tz = TimeZone.getDefault();
482     }
483   
484     return Calendar.getInstance(tz);
485   }
486   
487   /**
488    * Parses the already converted value to a <code>java.util.Date</code>.
489    * @param value converted value
490    * @return fulltyped <code>java.util.Date</code>
491    * @throws IllegalArgumentException
492    */
493   protected static Date getDateValue(Object value) 
494     throws IllegalArgumentException
495   {
496     if (value instanceof Date)
497     {
498       return ( (Date)value );
499     }
500 
501     throw new IllegalArgumentException(_LOG.getMessage("VALUE_IS_NOT_DATE_TYPE"));
502   }  
503     
504   private Converter _getConverter(
505     FacesContext context,
506     UIComponent component)
507   {
508     Converter converter = null;
509     if (component instanceof ValueHolder)
510     {
511       converter = ((ValueHolder) component).getConverter();
512     }
513 
514     if (converter == null)
515     {
516       // Use the DateTimeConverter's CONVERTER_ID, not Date.class,
517       // because there is in fact not usually a converter registered
518       // at Date.class
519       converter = context.getApplication().createConverter(DateTimeConverter.CONVERTER_ID);
520     }
521 
522     assert(converter != null);
523 
524     return converter;
525   }
526 
527   /**
528    * Builds an error message indicating invalid week-day selection
529    * @param context FacesContext
530    * @param component inputDate instance
531    * @param converter date converter instance
532    * @param value user submitted value
533    * @param dayOfTheWeekIndex Week day index as returned by Calendar.DAY_OF_WEEK on the value
534    * @return FacesMessage
535    */
536   private FacesMessage _getWrongWeekDayMessage(
537     FacesContext  context,
538     UIComponent   component,
539     Converter     converter,
540     Object        value,
541     int           dayOfTheWeekIndex)
542   { 
543     RequestContext reqContext = RequestContext.getCurrentInstance();      
544     Locale locale = reqContext.getFormattingLocale();
545 
546     if (locale == null)
547     {
548       locale = context.getViewRoot().getLocale();
549     }
550       
551     Object cValue = _getConvertedValue(context, component, converter, value);
552     Object msg   = _getRawInvalidDaysOfWeekMessageDetail();
553     Object label = ValidatorUtils.getComponentLabel(component);
554     String[] weekdays = new DateFormatSymbols(locale).getWeekdays();
555 
556     // Fetch the localized week name 
557     Object[] params = {label, cValue, weekdays[dayOfTheWeekIndex]};
558 
559     return MessageFactory.getMessage(context, WEEKDAY_MESSAGE_ID, msg, params, component);
560   }
561   
562   private Object _getRawInvalidDaysOfWeekMessageDetail()
563   {
564     return _facesBean.getRawProperty(_INVALID_DAYS_OF_WEEK_MESSAGE_DETAIL_KEY);
565   }
566 
567   /**
568    * Builds an error message indicating invalid month selection
569    * @param context FacesContext
570    * @param component inputDate instance
571    * @param converter date converter instance
572    * @param value user submitted value
573    * @param monthIndex Month index as returned by Calendar.MONTH on the value
574    * @return FacesMessage
575    */
576   private FacesMessage _getWrongMonthMessage(
577     FacesContext  context,
578     UIComponent   component,
579     Converter     converter,
580     Object        value,
581     int           monthIndex)
582   { 
583     RequestContext reqContext = RequestContext.getCurrentInstance();  
584     Locale locale = reqContext.getFormattingLocale();
585 
586     if (locale == null)
587     {
588       locale = context.getViewRoot().getLocale();
589     }
590     
591     Object cValue = _getConvertedValue(context, component, converter, value);
592 
593     Object msg   = _getRawInvalidMonthMessageDetail();
594     Object label = ValidatorUtils.getComponentLabel(component);
595     
596     // Fetch the localized month name 
597     String[] months = new DateFormatSymbols(locale).getMonths();
598 
599     Object[] params = {label, cValue, months[monthIndex]};
600 
601     return MessageFactory.getMessage(context, MONTH_MESSAGE_ID, msg, params, component);
602   }
603   
604   private Object _getRawInvalidMonthMessageDetail()
605   {
606     return _facesBean.getRawProperty(_INVALID_MONTHS_MESSAGE_DETAIL_KEY);
607   }
608 
609   private FacesMessage _getWrongDayMessage(
610     FacesContext context,
611     UIComponent component,
612     Object value,
613     Object day)
614   { 
615     Converter converter = _getConverter(context, component);
616 
617     Object cValue = _getConvertedValue(context, component, converter, value);
618     Object cDay   = _getConvertedValue(context, component, converter, day);
619 
620     Object msg   = _getRawInvalidDaysMessageDetail();
621     Object label = ValidatorUtils.getComponentLabel(component);
622 
623     Object[] params = {label, cValue, cDay};
624 
625     return MessageFactory.getMessage(context, DAY_MESSAGE_ID, msg, params, component);
626   }
627   
628   private Object _getRawInvalidDaysMessageDetail()
629   {
630     return _facesBean.getRawProperty(_INVALID_DAYS_MESSAGE_DETAIL_KEY);
631   }
632 
633   private Object _getConvertedValue(
634     FacesContext context,
635     UIComponent  component,
636     Converter    converter,
637     Object       value)
638   {
639     return converter.getAsString(context, component, value);
640   }
641 
642   private final Set<String> _getInvalidMonths()
643   {
644     Set<String> monthSet = new HashSet<String>();
645     String[] month = getInvalidMonths();
646     if(month != null){
647       
648       for (int i = 0; i < month.length; i++)
649       {
650         monthSet.add(month[i].toLowerCase());
651       }
652     }
653       
654     return monthSet;
655   }
656 
657   private final Set<String> _getInvalidDaysOfWeek()
658   {
659     Set<String> daysOfWeekSet = new HashSet<String>();
660     String[] daysOfWeek = getInvalidDaysOfWeek();
661     if(daysOfWeek != null){
662       
663       for (int i = 0; i < daysOfWeek.length; i++)
664       {
665         daysOfWeekSet.add(daysOfWeek[i].toLowerCase());
666       }
667     }
668       
669     return daysOfWeekSet;
670   }
671 
672   private void _initMaps()
673   {
674     _dayMap = new HashMap<Integer, String>();
675     _dayMap.put(Calendar.SUNDAY, "sun");
676     _dayMap.put(Calendar.MONDAY, "mon");
677     _dayMap.put(Calendar.TUESDAY, "tue");
678     _dayMap.put(Calendar.WEDNESDAY, "wed");
679     _dayMap.put(Calendar.THURSDAY, "thu");
680     _dayMap.put(Calendar.FRIDAY, "fri");
681     _dayMap.put(Calendar.SATURDAY, "sat");
682     
683     _monthMap = new HashMap<Integer, String>();
684     _monthMap.put(Calendar.JANUARY, "jan");
685     _monthMap.put(Calendar.FEBRUARY, "feb");
686     _monthMap.put(Calendar.MARCH, "mar");
687     _monthMap.put(Calendar.APRIL, "apr");
688     _monthMap.put(Calendar.MAY, "may");
689     _monthMap.put(Calendar.JUNE, "jun");
690     _monthMap.put(Calendar.JULY, "jul");
691     _monthMap.put(Calendar.AUGUST, "aug");
692     _monthMap.put(Calendar.SEPTEMBER, "sep");
693     _monthMap.put(Calendar.OCTOBER, "oct");
694     _monthMap.put(Calendar.NOVEMBER, "nov");
695     _monthMap.put(Calendar.DECEMBER, "dec");
696   }
697   
698   private static final FacesBean.Type _TYPE = new FacesBean.Type();
699 
700   private static final PropertyKey _INVALID_MONTHS =
701     _TYPE.registerKey("invalidMonths", String[].class);
702 
703   private static final PropertyKey _INVALID_DAYS_OF_WEEK =
704     _TYPE.registerKey("invalidDaysOfWeek", String[].class);
705 
706   private static final PropertyKey _INVALID_DAYS =
707     _TYPE.registerKey("invalidDays", DateListProvider.class);
708 
709   private static final PropertyKey _INVALID_MONTHS_MESSAGE_DETAIL_KEY =
710     _TYPE.registerKey("messageDetailInvalidMonths", String.class);
711 
712   private static final PropertyKey _INVALID_DAYS_OF_WEEK_MESSAGE_DETAIL_KEY =
713     _TYPE.registerKey("messageDetailInvalidDaysOfWeek", String.class);
714 
715   private static final PropertyKey _INVALID_DAYS_MESSAGE_DETAIL_KEY =
716     _TYPE.registerKey("messageDetailInvalidDays", String.class);
717 
718   private static final PropertyKey  _HINT_WEEK_KEY =
719     _TYPE.registerKey("hintWeek", String.class);
720   
721   // Default is false
722   private static final PropertyKey _DISABLED_KEY =
723     _TYPE.registerKey("disabled", Boolean.class, Boolean.FALSE);
724 
725   private static final PropertyKey  _HINT_MONTH_KEY =
726     _TYPE.registerKey("hintMonth", String.class);
727 
728   private FacesBean _facesBean = ValidatorUtils.getFacesBean(_TYPE);
729 
730   private boolean _transientValue = false;
731   
732   private Map<Integer, String> _dayMap = null;
733   private Map<Integer, String> _monthMap = null;
734 
735   private static final TrinidadLogger _LOG =
736     TrinidadLogger.createTrinidadLogger(DateRestrictionValidator.class);
737 
738 }