001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License version 2
011: * as published by the Free Software Foundation.
012: *
013: * Resin Open Source is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
016: * of NON-INFRINGEMENT. See the GNU General Public License for more
017: * details.
018: *
019: * You should have received a copy of the GNU General Public License
020: * along with Resin Open Source; if not, write to the
021: *
022: * Free Software Foundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package javax.faces.convert;
030:
031: import java.util.*;
032: import java.text.*;
033:
034: import javax.faces.application.*;
035: import javax.faces.context.*;
036: import javax.faces.component.*;
037:
038: public class DateTimeConverter implements Converter, StateHolder {
039: public static final String CONVERTER_ID = "javax.faces.DateTime";
040: public static final String DATE_ID = "javax.faces.converter.DateTimeConverter.DATE";
041: public static final String DATETIME_ID = "javax.faces.converter.DateTimeConverter.DATETIME";
042: public static final String STRING_ID = "javax.faces.converter.STRING";
043: public static final String TIME_ID = "javax.faces.converter.DateTimeConverter.TIME";
044:
045: private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
046:
047: private String _dateStyle = "default";
048: private String _timeStyle = "default";
049: private Locale _locale;
050:
051: private String _pattern;
052: private TimeZone _timeZone = GMT;
053: private String _type = "date";
054:
055: private boolean _isTransient;
056:
057: private DateFormat _format;
058:
059: public String getDateStyle() {
060: return _dateStyle;
061: }
062:
063: public void setDateStyle(String value) {
064: _dateStyle = value;
065: _format = null;
066: }
067:
068: public String getTimeStyle() {
069: return _timeStyle;
070: }
071:
072: public void setTimeStyle(String value) {
073: _timeStyle = value;
074: _format = null;
075: }
076:
077: public Locale getLocale() {
078: if (_locale != null)
079: return _locale;
080:
081: FacesContext context = FacesContext.getCurrentInstance();
082:
083: return context.getViewRoot().getLocale();
084: }
085:
086: public void setLocale(Locale locale) {
087: _locale = locale;
088: _format = null;
089: }
090:
091: public String getPattern() {
092: return _pattern;
093: }
094:
095: public void setPattern(String value) {
096: _pattern = value;
097: _format = null;
098: }
099:
100: public String getType() {
101: return _type;
102: }
103:
104: public void setType(String value) {
105: _type = value;
106: _format = null;
107: }
108:
109: public TimeZone getTimeZone() {
110: return _timeZone;
111: }
112:
113: public void setTimeZone(TimeZone value) {
114: _timeZone = value;
115: _format = null;
116: }
117:
118: public void setTransient(boolean value) {
119: _isTransient = value;
120: }
121:
122: public boolean isTransient() {
123: return _isTransient;
124: }
125:
126: public void restoreState(FacesContext context, Object state) {
127: Object[] values = (Object[]) state;
128: _dateStyle = (String) values[0];
129: _timeStyle = (String) values[1];
130: _locale = (Locale) values[2];
131: _pattern = (String) values[3];
132: _timeZone = (TimeZone) values[4];
133: _type = (String) values[5];
134: }
135:
136: public Object saveState(FacesContext context) {
137: Object[] state = new Object[6];
138: state[0] = _dateStyle;
139: state[1] = _timeStyle;
140: state[2] = _locale;
141: state[3] = _pattern;
142: state[4] = _timeZone;
143: state[5] = _type;
144: return state;
145: }
146:
147: public Object getAsObject(FacesContext context,
148: UIComponent component, String value)
149: throws ConverterException {
150: if (context == null || component == null)
151: throw new NullPointerException();
152:
153: if (value == null)
154: return null;
155:
156: value = value.trim();
157:
158: if (value.length() == 0)
159: return null;
160:
161: DateFormat format = getFormat(context);
162:
163: try {
164: synchronized (format) {
165: return format.parse(value);
166: }
167: } catch (ParseException e) {
168: String summary;
169: String detail;
170:
171: if ("date".equals(_type)) {
172: summary = Util
173: .l10n(
174: context,
175: DATE_ID,
176: "{2}: \"{0}\" could not be understood as a date.",
177: value, getExample(context), Util
178: .getLabel(context, component));
179:
180: detail = Util
181: .l10n(
182: context,
183: DATE_ID + "_detail",
184: "{2}: \"{0}\" could not be understood as a percentage. Example: {1}.",
185: value, getExample(context), Util
186: .getLabel(context, component));
187: } else if ("time".equals(_type)) {
188: summary = Util
189: .l10n(
190: context,
191: TIME_ID,
192: "{2}: \"{0}\" could not be understood as a time.",
193: value, getExample(context), Util
194: .getLabel(context, component));
195:
196: detail = Util
197: .l10n(
198: context,
199: TIME_ID + "_detail",
200: "{2}: \"{0}\" could not be understood as a time. Example: {1}.",
201: value, getExample(context), Util
202: .getLabel(context, component));
203: } else {
204: summary = Util
205: .l10n(
206: context,
207: DATETIME_ID,
208: "{2}: \"{0}\" could not be understood as a date and time.",
209: value, getExample(context), Util
210: .getLabel(context, component));
211:
212: detail = Util
213: .l10n(
214: context,
215: DATETIME_ID + "_detail",
216: "{2}: \"{0}\" could not be understood as a date and time. Example: {1}.",
217: value, getExample(context), Util
218: .getLabel(context, component));
219: }
220:
221: FacesMessage msg = new FacesMessage(summary, detail);
222:
223: throw new ConverterException(msg, e);
224: }
225: }
226:
227: public String getAsString(FacesContext context,
228: UIComponent component, Object value)
229: throws ConverterException {
230: if (context == null || component == null)
231: throw new NullPointerException();
232:
233: if (value == null)
234: return "";
235: else if (value instanceof Date) {
236: DateFormat format = getFormat(context);
237:
238: synchronized (format) {
239: return format.format((Date) value);
240: }
241: } else
242: return String.valueOf(value);
243: }
244:
245: private DateFormat getFormat(FacesContext context) {
246: synchronized (this ) {
247: if (_locale == null) {
248: Locale locale = context.getViewRoot().getLocale();
249:
250: return createFormat(locale);
251: } else if (_format == null) {
252: _format = createFormat(_locale);
253: }
254:
255: return _format;
256: }
257: }
258:
259: private DateFormat createFormat(Locale locale) {
260: DateFormat format;
261:
262: int dateStyle = DateFormat.DEFAULT;
263: int timeStyle = DateFormat.DEFAULT;
264:
265: if ("short".equals(_dateStyle)) {
266: dateStyle = DateFormat.SHORT;
267: } else if ("medium".equals(_dateStyle)) {
268: dateStyle = DateFormat.MEDIUM;
269: } else if ("long".equals(_dateStyle)) {
270: dateStyle = DateFormat.LONG;
271: } else if ("full".equals(_dateStyle)) {
272: dateStyle = DateFormat.FULL;
273: } else if ("default".equals(_dateStyle)) {
274: dateStyle = DateFormat.DEFAULT;
275: } else if (_dateStyle != null)
276: throw new ConverterException("'" + _dateStyle
277: + "' is an unknown dateStyle");
278:
279: if ("short".equals(_timeStyle)) {
280: timeStyle = DateFormat.SHORT;
281: } else if ("medium".equals(_timeStyle)) {
282: timeStyle = DateFormat.MEDIUM;
283: } else if ("long".equals(_timeStyle)) {
284: timeStyle = DateFormat.LONG;
285: } else if ("full".equals(_timeStyle)) {
286: timeStyle = DateFormat.FULL;
287: } else if ("default".equals(_timeStyle)) {
288: timeStyle = DateFormat.DEFAULT;
289: } else if (_timeStyle != null)
290: throw new ConverterException("'" + _timeStyle
291: + "' is an unknown timeStyle");
292:
293: if (_type == null || "date".equals(_type)) {
294: if (locale != null)
295: format = DateFormat.getDateInstance(dateStyle, locale);
296: else
297: format = DateFormat.getDateInstance(dateStyle);
298: } else if ("time".equals(_type)) {
299: if (locale != null)
300: format = DateFormat.getTimeInstance(timeStyle, locale);
301: else
302: format = DateFormat.getTimeInstance(timeStyle);
303: } else if ("both".equals(_type)) {
304: if (locale != null)
305: format = DateFormat.getDateTimeInstance(dateStyle,
306: timeStyle, locale);
307: else
308: format = DateFormat.getDateTimeInstance(dateStyle,
309: timeStyle);
310: } else
311: throw new ConverterException("'" + _type
312: + "' is an unknown type");
313:
314: try {
315: if (_pattern != null && format instanceof SimpleDateFormat)
316: ((SimpleDateFormat) format).applyPattern(_pattern);
317: } catch (Exception e) {
318: throw new ConverterException(e);
319: }
320:
321: if (_timeZone != null)
322: format.setTimeZone(_timeZone);
323:
324: return format;
325: }
326:
327: private String getExample(FacesContext context) {
328: DateFormat format = getFormat(context);
329:
330: synchronized (format) {
331: Date date = new Date(894621091000L);
332:
333: return format.format(date);
334: }
335: }
336:
337: public String toString() {
338: return "DateTimeConverter[]";
339: }
340: }
|