001: /*
002: * Copyright (C) 2003, 2004 Joe Walnes.
003: * Copyright (C) 2006, 2007, 2008 XStream Committers.
004: * All rights reserved.
005: *
006: * The software in this package is published under the terms of the BSD
007: * style license a copy of which has been included with this distribution in
008: * the LICENSE.txt file.
009: *
010: * Created on 26. September 2003 by Joe Walnes
011: */
012: package com.thoughtworks.xstream.converters.basic;
013:
014: import com.thoughtworks.xstream.converters.ConversionException;
015:
016: import java.text.ParseException;
017: import java.text.SimpleDateFormat;
018: import java.util.Date;
019: import com.thoughtworks.xstream.core.util.ThreadSafeSimpleDateFormat;
020:
021: /**
022: * Converts a java.util.Date to a String as a date format,
023: * retaining precision down to milliseconds.
024: *
025: * @author Joe Walnes
026: * @author Jörg Schaible
027: */
028: public class DateConverter extends AbstractSingleValueConverter {
029:
030: private final ThreadSafeSimpleDateFormat defaultFormat;
031: private final ThreadSafeSimpleDateFormat[] acceptableFormats;
032:
033: /**
034: * Construct a DateConverter with standard formats and lenient set off.
035: */
036: public DateConverter() {
037: this (false);
038: }
039:
040: /**
041: * Construct a DateConverter with standard formats.
042: *
043: * @param lenient the lenient setting of {@link SimpleDateFormat#setLenient(boolean)}
044: * @since 1.3
045: */
046: public DateConverter(boolean lenient) {
047: this ("yyyy-MM-dd HH:mm:ss.S z", new String[] {
048: "yyyy-MM-dd HH:mm:ss.S a", "yyyy-MM-dd HH:mm:ssz",
049: "yyyy-MM-dd HH:mm:ss z", // JDK 1.3 needs both versions
050: "yyyy-MM-dd HH:mm:ssa" }, // backwards compatibility
051: lenient);
052: }
053:
054: /**
055: * Construct a DateConverter with lenient set off.
056: *
057: * @param defaultFormat the default format
058: * @param acceptableFormats fallback formats
059: */
060: public DateConverter(String defaultFormat,
061: String[] acceptableFormats) {
062: this (defaultFormat, acceptableFormats, false);
063: }
064:
065: /**
066: * Construct a DateConverter.
067: *
068: * @param defaultFormat the default format
069: * @param acceptableFormats fallback formats
070: * @param lenient the lenient setting of {@link SimpleDateFormat#setLenient(boolean)}
071: * @since 1.3
072: */
073: public DateConverter(String defaultFormat,
074: String[] acceptableFormats, boolean lenient) {
075: this .defaultFormat = new ThreadSafeSimpleDateFormat(
076: defaultFormat, 4, 20, lenient);
077: this .acceptableFormats = new ThreadSafeSimpleDateFormat[acceptableFormats.length];
078: for (int i = 0; i < acceptableFormats.length; i++) {
079: this .acceptableFormats[i] = new ThreadSafeSimpleDateFormat(
080: acceptableFormats[i], 1, 20, lenient);
081: }
082: }
083:
084: public boolean canConvert(Class type) {
085: return type.equals(Date.class);
086: }
087:
088: public Object fromString(String str) {
089: try {
090: return defaultFormat.parse(str);
091: } catch (ParseException e) {
092: for (int i = 0; i < acceptableFormats.length; i++) {
093: try {
094: return acceptableFormats[i].parse(str);
095: } catch (ParseException e2) {
096: // no worries, let's try the next format.
097: }
098: }
099: // no dateFormats left to try
100: throw new ConversionException("Cannot parse date " + str);
101: }
102: }
103:
104: public String toString(Object obj) {
105: return defaultFormat.format((Date) obj);
106: }
107:
108: }
|