Coverage Report - javax.faces.convert.DateTimeConverter
 
Classes in this File Line Coverage Branch Coverage Complexity
DateTimeConverter
31%
38/122
17%
10/58
3.292
 
 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 javax.faces.convert;
 20  
 
 21  
 import java.text.DateFormat;
 22  
 import java.text.ParseException;
 23  
 import java.text.SimpleDateFormat;
 24  
 import java.util.Date;
 25  
 import java.util.Locale;
 26  
 import java.util.TimeZone;
 27  
 
 28  
 import javax.faces.component.PartialStateHolder;
 29  
 import javax.faces.component.UIComponent;
 30  
 import javax.faces.context.FacesContext;
 31  
 
 32  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFConverter;
 33  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperty;
 34  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
 35  
 
 36  
 /**
 37  
  * This tag associates a date time converter with the nearest parent UIComponent.
 38  
  * 
 39  
  * Unless otherwise specified, all attributes accept static values or EL expressions.
 40  
  * 
 41  
  * see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a>
 42  
  */
 43  
 @JSFConverter(
 44  
     name="f:convertDateTime",
 45  
     bodyContent="empty",
 46  
     tagClass="org.apache.myfaces.taglib.core.ConvertDateTimeTag")
 47  
 @JSFJspProperty(
 48  
     name="binding", 
 49  
     returnType = "javax.faces.convert.DateTimeConverter",
 50  
     longDesc = "A ValueExpression that evaluates to a DateTimeConverter.")
 51  
 public class DateTimeConverter
 52  
         implements Converter, PartialStateHolder
 53  
 {
 54  
 
 55  
     // API field
 56  
     public static final String CONVERTER_ID = "javax.faces.DateTime";
 57  
     public static final String DATE_ID = "javax.faces.converter.DateTimeConverter.DATE";
 58  
     public static final String DATETIME_ID = "javax.faces.converter.DateTimeConverter.DATETIME";
 59  
     public static final String STRING_ID = "javax.faces.converter.STRING";
 60  
     public static final String TIME_ID = "javax.faces.converter.DateTimeConverter.TIME";
 61  
 
 62  
     // internal constants
 63  
     private static final String TYPE_DATE = "date";
 64  
     private static final String TYPE_TIME = "time";
 65  
     private static final String TYPE_BOTH = "both";
 66  
     private static final String STYLE_DEFAULT = "default";
 67  
     private static final String STYLE_MEDIUM = "medium";
 68  
     private static final String STYLE_SHORT = "short";
 69  
     private static final String STYLE_LONG = "long";
 70  
     private static final String STYLE_FULL = "full";
 71  2
     private static final TimeZone TIMEZONE_DEFAULT = TimeZone.getTimeZone("GMT");
 72  
 
 73  
     private String _dateStyle;
 74  
     private Locale _locale;
 75  
     private String _pattern;
 76  
     private String _timeStyle;
 77  
     private TimeZone _timeZone;
 78  
     private String _type;
 79  
     private boolean _transient;
 80  
 
 81  
     // CONSTRUCTORS
 82  
     public DateTimeConverter()
 83  2
     {
 84  2
     }
 85  
 
 86  
     // METHODS
 87  
     public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value)
 88  
     {
 89  4
         if (facesContext == null)
 90  
         {
 91  0
             throw new NullPointerException("facesContext");
 92  
         }
 93  4
         if (uiComponent == null)
 94  
         {
 95  0
             throw new NullPointerException("uiComponent");
 96  
         }
 97  
 
 98  4
         if (value != null)
 99  
         {
 100  4
             value = value.trim();
 101  4
             if (value.length() > 0)
 102  
             {
 103  4
                 DateFormat format = getDateFormat();
 104  4
                 TimeZone tz = getTimeZone();
 105  4
                 if( tz != null )
 106  
                 {
 107  4
                     format.setTimeZone(tz);
 108  
                 }
 109  
                 try
 110  
                 {
 111  4
                     return format.parse(value);
 112  
                 }
 113  2
                 catch (ParseException e)
 114  
                 {
 115  2
                     String type = getType();
 116  2
                     Object[] args = new Object[]{value,
 117  
                             format.format(new Date()),_MessageUtils.getLabel(facesContext, uiComponent)};
 118  
                     
 119  2
                     if(type.equals(TYPE_DATE))
 120  
                     {
 121  2
                         throw new ConverterException(_MessageUtils.getErrorMessage(facesContext, DATE_ID, args));
 122  
                     }
 123  0
                     else if (type.equals(TYPE_TIME))
 124  
                     {
 125  0
                         throw new ConverterException(_MessageUtils.getErrorMessage(facesContext, TIME_ID, args));
 126  
                     }
 127  0
                     else if (type.equals(TYPE_BOTH))
 128  
                     {
 129  0
                         throw new ConverterException(_MessageUtils.getErrorMessage(facesContext, DATETIME_ID, args));
 130  
                     }
 131  
                     else
 132  
                     {
 133  0
                         throw new ConverterException("invalid type '" + _type + "'");
 134  
                     }
 135  
                 }
 136  
             }
 137  
         }
 138  0
         return null;
 139  
     }
 140  
 
 141  
     public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value)
 142  
     {
 143  0
         if (facesContext == null)
 144  
         {
 145  0
             throw new NullPointerException("facesContext");
 146  
         }
 147  0
         if (uiComponent == null)
 148  
         {
 149  0
             throw new NullPointerException("uiComponent");
 150  
         }
 151  
 
 152  0
         if (value == null)
 153  
         {
 154  0
             return "";
 155  
         }
 156  0
         if (value instanceof String)
 157  
         {
 158  0
             return (String)value;
 159  
         }
 160  
 
 161  0
         DateFormat format = getDateFormat();
 162  0
         TimeZone tz = getTimeZone(); 
 163  0
         if (tz != null)
 164  
         {
 165  0
             format.setTimeZone(tz);
 166  
         }
 167  
         try
 168  
         {
 169  0
             return format.format(value);
 170  
         }
 171  0
         catch (Exception e)
 172  
         {
 173  0
             throw new ConverterException(_MessageUtils.getErrorMessage(facesContext, STRING_ID,
 174  
                     new Object[]{value,_MessageUtils.getLabel(facesContext, uiComponent)}),e);
 175  
         }
 176  
     }
 177  
 
 178  
     private DateFormat getDateFormat()
 179  
     {
 180  4
         String type = getType();
 181  
         DateFormat format;
 182  4
         if (_pattern != null)
 183  
         {
 184  
             try 
 185  
             {
 186  4
                 format = new SimpleDateFormat(_pattern, getLocale());
 187  
             } 
 188  0
                 catch (IllegalArgumentException iae)
 189  
             {
 190  0
                 throw new ConverterException("Invalid pattern", iae);    
 191  4
             }
 192  
         }
 193  0
         else if (type.equals(TYPE_DATE))
 194  
         {
 195  0
             format = DateFormat.getDateInstance(calcStyle(getDateStyle()), getLocale());
 196  
         }
 197  0
         else if (type.equals(TYPE_TIME))
 198  
         {
 199  0
             format = DateFormat.getTimeInstance(calcStyle(getTimeStyle()), getLocale());
 200  
         }
 201  0
         else if (type.equals(TYPE_BOTH))
 202  
         {
 203  0
             format = DateFormat.getDateTimeInstance(calcStyle(getDateStyle()),
 204  
                                                     calcStyle(getTimeStyle()),
 205  
                                                     getLocale());
 206  
         }
 207  
         else
 208  
         {
 209  0
             throw new ConverterException("invalid type '" + _type + "'");
 210  
         }
 211  
         
 212  
         // format cannot be lenient (JSR-127)
 213  4
         format.setLenient(false);
 214  4
         return format;
 215  
     }
 216  
 
 217  
     private int calcStyle(String name)
 218  
     {
 219  0
         if (name.equals(STYLE_DEFAULT))
 220  
         {
 221  0
             return DateFormat.DEFAULT;
 222  
         }
 223  0
         if (name.equals(STYLE_MEDIUM))
 224  
         {
 225  0
             return DateFormat.MEDIUM;
 226  
         }
 227  0
         if (name.equals(STYLE_SHORT))
 228  
         {
 229  0
             return DateFormat.SHORT;
 230  
         }
 231  0
         if (name.equals(STYLE_LONG))
 232  
         {
 233  0
             return DateFormat.LONG;
 234  
         }
 235  0
         if (name.equals(STYLE_FULL))
 236  
         {
 237  0
             return DateFormat.FULL;
 238  
         }
 239  
 
 240  0
         throw new ConverterException("invalid style '" + name + "'");
 241  
     }
 242  
 
 243  
     // STATE SAVE/RESTORE
 244  
     public void restoreState(FacesContext facesContext, Object state)
 245  
     {
 246  0
         if (state != null)
 247  
         {
 248  0
             Object[] values = (Object[])state;
 249  0
             _dateStyle = (String)values[0];
 250  0
             _locale = (Locale)values[1];
 251  0
             _pattern = (String)values[2];
 252  0
             _timeStyle = (String)values[3];
 253  0
             _timeZone = (TimeZone)values[4];
 254  0
             _type = (String)values[5];
 255  
         }
 256  0
     }
 257  
 
 258  
     public Object saveState(FacesContext facesContext)
 259  
     {
 260  0
         if (!initialStateMarked())
 261  
         {
 262  0
             Object[] values = new Object[6];
 263  0
             values[0] = _dateStyle;
 264  0
             values[1] = _locale;
 265  0
             values[2] = _pattern;
 266  0
             values[3] = _timeStyle;
 267  0
             values[4] = _timeZone;
 268  0
             values[5] = _type;
 269  0
             return values;
 270  
         }
 271  0
         return null;
 272  
     }
 273  
 
 274  
     // GETTER & SETTER
 275  
     
 276  
     /**
 277  
      * The style of the date.  Values include: default, short, medium, 
 278  
      * long, and full.
 279  
      * 
 280  
      */
 281  
     @JSFProperty
 282  
     public String getDateStyle()
 283  
     {
 284  0
         return _dateStyle != null ? _dateStyle : STYLE_DEFAULT;
 285  
     }
 286  
 
 287  
     public void setDateStyle(String dateStyle)
 288  
     {
 289  
         //TODO: validate timeStyle
 290  0
         _dateStyle = dateStyle;
 291  0
         clearInitialState();
 292  0
     }
 293  
 
 294  
     /**
 295  
      * The name of the locale to be used, instead of the default.
 296  
      * 
 297  
      */
 298  
     @JSFProperty
 299  
     public Locale getLocale()
 300  
     {
 301  4
         if (_locale != null)
 302  
         {
 303  0
             return _locale;
 304  
         }
 305  4
         FacesContext context = FacesContext.getCurrentInstance();
 306  4
         return context.getViewRoot().getLocale();
 307  
     }
 308  
 
 309  
     public void setLocale(Locale locale)
 310  
     {
 311  0
         _locale = locale;
 312  0
         clearInitialState();
 313  0
     }
 314  
 
 315  
     /**
 316  
      * A custom Date formatting pattern, in the format used by java.text.SimpleDateFormat.
 317  
      * 
 318  
      */
 319  
     @JSFProperty
 320  
     public String getPattern()
 321  
     {
 322  0
         return _pattern;
 323  
     }
 324  
 
 325  
     public void setPattern(String pattern)
 326  
     {
 327  2
         _pattern = pattern;
 328  2
         clearInitialState();
 329  2
     }
 330  
 
 331  
     /**
 332  
      * The style of the time.  Values include:  default, short, medium, long, 
 333  
      * and full.
 334  
      * 
 335  
      */
 336  
     @JSFProperty
 337  
     public String getTimeStyle()
 338  
     {
 339  0
         return _timeStyle != null ? _timeStyle : STYLE_DEFAULT;
 340  
     }
 341  
 
 342  
     public void setTimeStyle(String timeStyle)
 343  
     {
 344  
         //TODO: validate timeStyle
 345  0
         _timeStyle = timeStyle;
 346  0
         clearInitialState();
 347  0
     }
 348  
 
 349  
     /**
 350  
      * The time zone to use instead of GMT (the default timezone). When
 351  
      * this value is a value-binding to a TimeZone instance, that
 352  
      * timezone is used. Otherwise this value is treated as a String
 353  
      * containing a timezone id, ie as the ID parameter of method
 354  
      * java.util.TimeZone.getTimeZone(String).
 355  
      * 
 356  
      */
 357  
     @JSFProperty
 358  
     public TimeZone getTimeZone()
 359  
     {
 360  4
         return _timeZone != null ? _timeZone : TIMEZONE_DEFAULT;
 361  
     }
 362  
 
 363  
     public void setTimeZone(TimeZone timeZone)
 364  
     {
 365  2
         _timeZone = timeZone;
 366  2
         clearInitialState();
 367  2
     }
 368  
 
 369  
     public boolean isTransient()
 370  
     {
 371  0
         return _transient;
 372  
     }
 373  
 
 374  
     public void setTransient(boolean aTransient)
 375  
     {
 376  0
         _transient = aTransient;
 377  0
     }
 378  
 
 379  
     /**
 380  
      * Specifies whether the date, time, or both should be 
 381  
      * parsed/formatted.  Values include:  date, time, and both.
 382  
      * Default based on setting of timeStyle and dateStyle.
 383  
      * 
 384  
      */
 385  
     @JSFProperty
 386  
     public String getType()
 387  
     {
 388  6
         return _type != null ? _type : TYPE_DATE;
 389  
     }
 390  
 
 391  
     public void setType(String type)
 392  
     {
 393  
         //TODO: validate type
 394  0
         _type = type;
 395  0
         clearInitialState();
 396  0
     }
 397  
     
 398  2
     private boolean _initialStateMarked = false;
 399  
 
 400  
     public void clearInitialState()
 401  
     {
 402  4
         _initialStateMarked = false;
 403  4
     }
 404  
 
 405  
     public boolean initialStateMarked()
 406  
     {
 407  0
         return _initialStateMarked;
 408  
     }
 409  
 
 410  
     public void markInitialState()
 411  
     {
 412  0
         _initialStateMarked = true;
 413  0
     }
 414  
 }