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