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.SimpleDateFormat;
23 import java.util.Locale;
24 import java.util.TimeZone;
25
26 import javax.faces.component.StateHolder;
27 import javax.faces.component.UIComponent;
28 import javax.faces.context.FacesContext;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public class DateTimeConverter implements Converter, StateHolder {
45
46 public static final String CONVERTER_ID = "javax.faces.DateTime";
47
48
49 private static final String CONVERSION_MESSAGE_ID = "javax.faces.convert.DateTimeConverter.CONVERSION";
50
51 private static final TimeZone TIMEZONE_DEFAULT = TimeZone.getTimeZone("GMT");
52
53 private String _dateStyle;
54 private Locale _locale;
55 private String _pattern;
56 private String _timeStyle;
57 private TimeZone _timeZone;
58 private String _type;
59 private boolean _transient;
60
61 public Object getAsObject(FacesContext context, UIComponent component, String value) throws ConverterException {
62 if (context == null) {
63 throw new NullPointerException("facesContext");
64 }
65 if (component == null) {
66 throw new NullPointerException("uiComponent");
67 }
68
69 if (value == null) {
70 return null;
71 }
72
73 String trimmedValue = value.trim();
74 if (trimmedValue.length() == 0) {
75 return null;
76 }
77
78 try {
79 return prepareDateFormat().parse(trimmedValue);
80 } catch (Exception e) {
81 throw new ConverterException(
82 _MessageUtils.getErrorMessage(context, CONVERSION_MESSAGE_ID,
83 new Object[] {value, component.getId()}), e);
84 }
85 }
86
87 public String getAsString(FacesContext context, UIComponent component, Object value) throws ConverterException {
88 if (context == null) {
89 throw new NullPointerException("facesContext");
90 }
91 if (component == null) {
92 throw new NullPointerException("uiComponent");
93 }
94
95 if (value == null) {
96 return "";
97 }
98 if (value instanceof String) {
99 return (String) value;
100 }
101
102 try {
103 return prepareDateFormat().format(value);
104 } catch (Exception e) {
105 throw new ConverterException(e);
106 }
107 }
108
109 private DateFormat prepareDateFormat() {
110 DateFormat format = getDateFormat();
111
112 format.setLenient(false);
113
114 TimeZone tz = getTimeZone();
115 if (tz != null) {
116 format.setTimeZone(tz);
117 }
118
119 return format;
120 }
121
122 private DateFormat getDateFormat() {
123 if(_pattern != null) {
124 try {
125 return new SimpleDateFormat(_pattern, getLocale());
126 } catch (IllegalArgumentException iae) {
127 throw new ConverterException("Invalid pattern", iae);
128 }
129 }
130
131 return Type.getType(getType()).getFormatter(calcDateStyle(), calcTimeStyle(), getLocale());
132 }
133
134 private int calcDateStyle() {
135 return Style.getStyleFormat(getDateStyle());
136 }
137
138 private int calcTimeStyle() {
139 return Style.getStyleFormat(getTimeStyle());
140 }
141
142
143 public void restoreState(FacesContext facesContext, Object state) {
144 Object[] values = (Object[]) state;
145 _dateStyle = (String) values[0];
146 _locale = (Locale) values[1];
147 _pattern = (String) values[2];
148 _timeStyle = (String) values[3];
149 _timeZone = (TimeZone) values[4];
150 _type = (String) values[5];
151 }
152
153 public Object saveState(FacesContext facesContext) {
154 Object[] values = new Object[6];
155 values[0] = _dateStyle;
156 values[1] = _locale;
157 values[2] = _pattern;
158 values[3] = _timeStyle;
159 values[4] = _timeZone;
160 values[5] = _type;
161 return values;
162 }
163
164
165
166
167
168
169
170
171
172 public String getDateStyle() {
173 return _dateStyle != null ? _dateStyle : Style.DEFAULT.getName();
174 }
175
176 public void setDateStyle(String dateStyle) {
177
178 _dateStyle = dateStyle;
179 }
180
181
182
183
184
185
186 public Locale getLocale() {
187 if (_locale != null)
188 return _locale;
189 FacesContext context = FacesContext.getCurrentInstance();
190 return context.getViewRoot().getLocale();
191 }
192
193 public void setLocale(Locale locale) {
194 _locale = locale;
195 }
196
197
198
199
200
201
202 public String getPattern() {
203 return _pattern;
204 }
205
206 public void setPattern(String pattern) {
207 _pattern = pattern;
208 }
209
210
211
212
213
214
215
216 public String getTimeStyle() {
217 return _timeStyle != null ? _timeStyle : Style.DEFAULT.getName();
218 }
219
220 public void setTimeStyle(String timeStyle) {
221
222 _timeStyle = timeStyle;
223 }
224
225
226
227
228
229
230
231
232
233
234 public TimeZone getTimeZone() {
235 return _timeZone != null ? _timeZone : TIMEZONE_DEFAULT;
236 }
237
238 public void setTimeZone(TimeZone timeZone) {
239 _timeZone = timeZone;
240 }
241
242 public boolean isTransient() {
243 return _transient;
244 }
245
246 public void setTransient(boolean aTransient) {
247 _transient = aTransient;
248 }
249
250
251
252
253
254
255
256
257 public String getType() {
258 return _type != null ? _type : Type.DATE.getName();
259 }
260
261 public void setType(String type) {
262
263 _type = type;
264 }
265
266 private static class Style {
267
268 private static final Style DEFAULT = new Style("default", DateFormat.DEFAULT);
269 private static final Style MEDIUM = new Style("medium", DateFormat.MEDIUM);
270 private static final Style SHORT = new Style("short", DateFormat.SHORT);
271 private static final Style LONG = new Style("long", DateFormat.LONG);
272 private static final Style FULL = new Style("full", DateFormat.FULL);
273
274 private static final Style[] values = new Style[] {DEFAULT, MEDIUM, SHORT, LONG, FULL};
275
276 public static Style getStyle(String name) {
277 for(int i = 0;i < values.length;i++) {
278 if(values[i]._name.equals(name)) {
279 return values[i];
280 }
281 }
282
283 throw new ConverterException("invalid style '" + name + "'");
284 }
285
286 private static int getStyleFormat(String name) {
287 return getStyle(name).getFormat();
288 }
289
290 private String _name;
291 private int _format;
292
293 private Style(String name, int format) {
294 this._name = name;
295 this._format = format;
296 }
297
298 public String getName() {
299 return _name;
300 }
301
302 public int getFormat() {
303 return _format;
304 }
305 }
306
307 private abstract static class Type {
308
309 private static final Type DATE = new Type("date") {
310 public DateFormat getFormatter(int dateStyle, int timeStyle, Locale locale) {
311 return DateFormat.getDateInstance(dateStyle, locale);
312 }
313 };
314 private static final Type TIME = new Type("time") {
315 public DateFormat getFormatter(int dateStyle, int timeStyle, Locale locale) {
316 return DateFormat.getTimeInstance(timeStyle, locale);
317 }
318 };
319 private static final Type BOTH = new Type("both") {
320 public DateFormat getFormatter(int dateStyle, int timeStyle, Locale locale) {
321 return DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale);
322 }
323 };
324
325 private static final Type[] values = new Type[] {DATE, TIME, BOTH};
326
327 public static Type getType(String name) {
328 for(int i = 0;i < values.length;i++) {
329 if(values[i]._name.equals(name)) {
330 return values[i];
331 }
332 }
333
334 throw new ConverterException("invalid type '" + name + "'");
335 }
336
337 private String _name;
338
339 private Type(String name) {
340 this._name = name;
341 }
342
343 public String getName() {
344 return _name;
345 }
346
347 public abstract DateFormat getFormatter(int dateStyle, int timeStyle, Locale locale);
348 }
349 }