001: /*
002: * Copyright 2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package javax.faces.convert;
017:
018: import javax.faces.component.UIComponent;
019: import javax.faces.component.StateHolder;
020: import javax.faces.context.FacesContext;
021: import java.text.DateFormat;
022: import java.text.ParseException;
023: import java.text.SimpleDateFormat;
024: import java.util.Date;
025: import java.util.Locale;
026: import java.util.TimeZone;
027:
028: /**
029: * see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a>
030: *
031: * @author Thomas Spiegl (latest modification by $Author: pmcmahan $)
032: * @version $Revision: 529409 $ $Date: 2007-04-16 23:38:37 +0200 (Mo, 16 Apr 2007) $
033: */
034: public class DateTimeConverter implements Converter, StateHolder {
035:
036: // API field
037: public static final String CONVERTER_ID = "javax.faces.DateTime";
038: public static final String DATE_ID = "javax.faces.converter.DateTimeConverter.DATE";
039: public static final String DATETIME_ID = "javax.faces.converter.DateTimeConverter.DATETIME";
040: public static final String STRING_ID = "javax.faces.converter.STRING";
041: public static final String TIME_ID = "javax.faces.converter.DateTimeConverter.TIME";
042:
043: // internal constants
044: private static final String TYPE_DATE = "date";
045: private static final String TYPE_TIME = "time";
046: private static final String TYPE_BOTH = "both";
047: private static final String STYLE_DEFAULT = "default";
048: private static final String STYLE_MEDIUM = "medium";
049: private static final String STYLE_SHORT = "short";
050: private static final String STYLE_LONG = "long";
051: private static final String STYLE_FULL = "full";
052: private static final TimeZone TIMEZONE_DEFAULT = TimeZone
053: .getTimeZone("GMT");
054:
055: private String _dateStyle;
056: private Locale _locale;
057: private String _pattern;
058: private String _timeStyle;
059: private TimeZone _timeZone;
060: private String _type;
061: private boolean _transient;
062:
063: // CONSTRUCTORS
064: public DateTimeConverter() {
065: }
066:
067: // METHODS
068: public Object getAsObject(FacesContext facesContext,
069: UIComponent uiComponent, String value) {
070: if (facesContext == null)
071: throw new NullPointerException("facesContext");
072: if (uiComponent == null)
073: throw new NullPointerException("uiComponent");
074:
075: if (value != null) {
076: value = value.trim();
077: if (value.length() > 0) {
078: DateFormat format = getDateFormat();
079: TimeZone tz = getTimeZone();
080: if (tz != null)
081: format.setTimeZone(tz);
082: try {
083: return format.parse(value);
084: } catch (ParseException e) {
085: try {
086: String type = getType();
087: Object[] args = new Object[] {
088: value,
089: format.parse(new Date().toString()),
090: _MessageUtils.getLabel(facesContext,
091: uiComponent) };
092:
093: if (type.equals(TYPE_DATE))
094: throw new ConverterException(_MessageUtils
095: .getErrorMessage(facesContext,
096: DATE_ID, args));
097: else if (type.equals(TYPE_TIME))
098: throw new ConverterException(_MessageUtils
099: .getErrorMessage(facesContext,
100: TIME_ID, args));
101: else if (type.equals(TYPE_BOTH))
102: throw new ConverterException(_MessageUtils
103: .getErrorMessage(facesContext,
104: DATETIME_ID, args));
105: else
106: throw new ConverterException(
107: "invalid type '" + _type + "'");
108: } catch (ParseException exception) {
109: throw new ConverterException(exception);
110: }
111: }
112: }
113: }
114: return null;
115: }
116:
117: public String getAsString(FacesContext facesContext,
118: UIComponent uiComponent, Object value) {
119: if (facesContext == null)
120: throw new NullPointerException("facesContext");
121: if (uiComponent == null)
122: throw new NullPointerException("uiComponent");
123:
124: if (value == null) {
125: return "";
126: }
127: if (value instanceof String) {
128: return (String) value;
129: }
130:
131: DateFormat format = getDateFormat();
132: TimeZone tz = getTimeZone();
133: if (tz != null) {
134: format.setTimeZone(tz);
135: }
136: try {
137: return format.format(value);
138: } catch (Exception e) {
139: throw new ConverterException(_MessageUtils.getErrorMessage(
140: facesContext, STRING_ID, new Object[] {
141: value,
142: _MessageUtils.getLabel(facesContext,
143: uiComponent) }), e);
144: }
145: }
146:
147: private DateFormat getDateFormat() {
148: String type = getType();
149: DateFormat format;
150: if (_pattern != null) {
151: try {
152: format = new SimpleDateFormat(_pattern, getLocale());
153: } catch (IllegalArgumentException iae) {
154: throw new ConverterException("Invalid pattern", iae);
155: }
156: } else if (type.equals(TYPE_DATE)) {
157: format = DateFormat.getDateInstance(
158: calcStyle(getDateStyle()), getLocale());
159: } else if (type.equals(TYPE_TIME)) {
160: format = DateFormat.getTimeInstance(
161: calcStyle(getTimeStyle()), getLocale());
162: } else if (type.equals(TYPE_BOTH)) {
163: format = DateFormat.getDateTimeInstance(
164: calcStyle(getDateStyle()),
165: calcStyle(getTimeStyle()), getLocale());
166: } else {
167: throw new ConverterException("invalid type '" + _type + "'");
168: }
169:
170: // format cannot be lenient (JSR-127)
171: format.setLenient(false);
172: return format;
173: }
174:
175: private int calcStyle(String name) {
176: if (name.equals(STYLE_DEFAULT)) {
177: return DateFormat.DEFAULT;
178: }
179: if (name.equals(STYLE_MEDIUM)) {
180: return DateFormat.MEDIUM;
181: }
182: if (name.equals(STYLE_SHORT)) {
183: return DateFormat.SHORT;
184: }
185: if (name.equals(STYLE_LONG)) {
186: return DateFormat.LONG;
187: }
188: if (name.equals(STYLE_FULL)) {
189: return DateFormat.FULL;
190: }
191:
192: throw new ConverterException("invalid style '" + name + "'");
193: }
194:
195: // STATE SAVE/RESTORE
196: public void restoreState(FacesContext facesContext, Object state) {
197: Object[] values = (Object[]) state;
198: _dateStyle = (String) values[0];
199: _locale = (Locale) values[1];
200: _pattern = (String) values[2];
201: _timeStyle = (String) values[3];
202: _timeZone = (TimeZone) values[4];
203: _type = (String) values[5];
204: }
205:
206: public Object saveState(FacesContext facesContext) {
207: Object[] values = new Object[6];
208: values[0] = _dateStyle;
209: values[1] = _locale;
210: values[2] = _pattern;
211: values[3] = _timeStyle;
212: values[4] = _timeZone;
213: values[5] = _type;
214: return values;
215: }
216:
217: // GETTER & SETTER
218: public String getDateStyle() {
219: return _dateStyle != null ? _dateStyle : STYLE_DEFAULT;
220: }
221:
222: public void setDateStyle(String dateStyle) {
223: //TODO: validate timeStyle
224: _dateStyle = dateStyle;
225: }
226:
227: public Locale getLocale() {
228: if (_locale != null)
229: return _locale;
230: FacesContext context = FacesContext.getCurrentInstance();
231: return context.getViewRoot().getLocale();
232: }
233:
234: public void setLocale(Locale locale) {
235: _locale = locale;
236: }
237:
238: public String getPattern() {
239: return _pattern;
240: }
241:
242: public void setPattern(String pattern) {
243: _pattern = pattern;
244: }
245:
246: public String getTimeStyle() {
247: return _timeStyle != null ? _timeStyle : STYLE_DEFAULT;
248: }
249:
250: public void setTimeStyle(String timeStyle) {
251: //TODO: validate timeStyle
252: _timeStyle = timeStyle;
253: }
254:
255: public TimeZone getTimeZone() {
256: return _timeZone != null ? _timeZone : TIMEZONE_DEFAULT;
257: }
258:
259: public void setTimeZone(TimeZone timeZone) {
260: _timeZone = timeZone;
261: }
262:
263: public boolean isTransient() {
264: return _transient;
265: }
266:
267: public void setTransient(boolean aTransient) {
268: _transient = aTransient;
269: }
270:
271: public String getType() {
272: return _type != null ? _type : TYPE_DATE;
273: }
274:
275: public void setType(String type) {
276: //TODO: validate type
277: _type = type;
278: }
279: }
|