001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.xbean.propertyeditor;
018
019 import java.text.DateFormat;
020 import java.text.ParseException;
021 import java.text.SimpleDateFormat;
022 import java.util.Date;
023 import java.util.Locale;
024 import java.util.List;
025 import java.util.ArrayList;
026
027 /**
028 * A property editor for Date typed properties.
029 *
030 * @version $Rev$ $Date$
031 */
032 public class DateEditor extends AbstractConverter {
033
034 private List<DateFormat> formats = new ArrayList<DateFormat>();
035
036 public DateEditor() {
037 super(Date.class);
038
039 formats.add(DateFormat.getInstance());
040 formats.add(DateFormat.getDateInstance());
041 formats.add(new SimpleDateFormat("yyyy-MM-dd")); // Atom (ISO 8601))) -- short version;
042 formats.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz")); // Atom (ISO 8601)));
043 }
044
045 /**
046 * Convert the text value of the property into a Date object instance.
047 *
048 * @return a Date object constructed from the property text value.
049 * @throws PropertyEditorException
050 * Unable to parse the string value into a Date.
051 */
052 protected Object toObjectImpl(String text) {
053 for (DateFormat format : formats) {
054 try {
055 return format.parse(text);
056 } catch (ParseException e) {
057 }
058 }
059
060 try {
061 return complexParse(text);
062 } catch (ParseException e) {
063 // any format errors show up as a ParseException, which we turn into
064 // a PropertyEditorException.
065 throw new PropertyEditorException(e);
066 }
067 }
068
069 private Object complexParse(String text) throws ParseException {
070 // find out whether the first token is a locale id and style in that
071 // order
072 // if there's locale, style is mandatory
073 Locale locale = Locale.getDefault();
074 int style = DateFormat.MEDIUM;
075 int firstSpaceIndex = text.indexOf(' ');
076 if (firstSpaceIndex != -1) {
077 String token = text.substring(0, firstSpaceIndex).intern();
078 if (token.startsWith("locale")) {
079 String localeStr = token.substring(token.indexOf('=') + 1);
080 int underscoreIndex = localeStr.indexOf('_');
081 if (underscoreIndex != -1) {
082 String language = localeStr.substring(0, underscoreIndex);
083 String country = localeStr.substring(underscoreIndex + 1);
084 locale = new Locale(language, country);
085 } else {
086 locale = new Locale(localeStr);
087 }
088 // locale is followed by mandatory style
089 int nextSpaceIndex = text.indexOf(' ', firstSpaceIndex + 1);
090 token = text.substring(firstSpaceIndex + 1, nextSpaceIndex);
091 String styleStr = token.substring(token.indexOf('=') + 1);
092 if (styleStr.equalsIgnoreCase("SHORT")) {
093 style = DateFormat.SHORT;
094 } else if (styleStr.equalsIgnoreCase("MEDIUM")) {
095 style = DateFormat.MEDIUM;
096 } else if (styleStr.equalsIgnoreCase("LONG")) {
097 style = DateFormat.LONG;
098 } else if (styleStr.equalsIgnoreCase("FULL")) {
099 style = DateFormat.FULL;
100 } else {
101 // unknown style name
102 // throw exception or assume default?
103 style = DateFormat.MEDIUM;
104 }
105 text = text.substring(nextSpaceIndex + 1);
106 }
107 }
108 DateFormat formats = DateFormat.getDateInstance(style, locale);
109 return formats.parse(text);
110 }
111
112 protected String toStringImpl(Object value) {
113 Date date = (Date) value;
114 String text = formats.get(0).format(date);
115 return text;
116 }
117 }