org.jdesigner.platform.web.converter.DateTimeConverter.java Source code

Java tutorial

Introduction

Here is the source code for org.jdesigner.platform.web.converter.DateTimeConverter.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jdesigner.platform.web.converter;

import java.util.Calendar;
import java.util.Date;

import org.apache.commons.beanutils.ConversionException;

import org.jdesigner.platform.data.DataUtils;
import org.jdesigner.platform.util.DateUtils;

/**
 * {@link org.apache.commons.beanutils.Converter} implementaion that handles
 * conversion to and from <b>date/time</b> objects.
 * <p>
 * This implementation handles conversion for the following <i>date/time</i>
 * types.
 * <ul>
 * <li><code>java.util.Date</code></li>
 * <li><code>java.util.Calendar</code></li>
 * <li><code>java.sql.Date</code></li>
 * <li><code>java.sql.Time</code></li>
 * <li><code>java.sql.Timestamp</code></li>
 * </ul>
 * 
 * <h3>String Conversions (to and from)</h3>
 * This class provides a number of ways in which date/time conversions to/from
 * Strings can be achieved:
 * <ul>
 * <li>Using the SHORT date format for the default Locale, configure using:</li>
 * <ul>
 * <li><code>setUseLocaleFormat(true)</code></li>
 * </ul>
 * <li>Using the SHORT date format for a specified Locale, configure using:</li>
 * <ul>
 * <li><code>setLocale(Locale)</code></li>
 * </ul>
 * <li>Using the specified date pattern(s) for the default Locale, configure
 * using:</li>
 * <ul>
 * <li>Either <code>setPattern(String)</code> or
 * <code>setPatterns(String[])</code></li>
 * </ul>
 * <li>Using the specified date pattern(s) for a specified Locale, configure
 * using:</li>
 * <ul>
 * <li><code>setPattern(String)</code> or
 * <code>setPatterns(String[]) and...</code></li>
 * <li><code>setLocale(Locale)</code></li>
 * </ul>
 * <li>If none of the above are configured the <code>toDate(String)</code>
 * method is used to convert from String to Date and the Dates's
 * <code>toString()</code> method used to convert from Date to String.</li>
 * </ul>
 * 
 * <p>
 * The <b>Time Zone</b> to use with the date format can be specified using the
 * <code>setTimeZone()</code> method.
 * 
 * @version $Revision: 1.1 $ $Date: 2010/04/08 05:41:59 $
 * @since 1.8.0
 */
public abstract class DateTimeConverter extends AbstractConverter {

    // ----------------------------------------------------------- Constructors

    /**
     * Construct a Date/Time <i>Converter</i> that throws a
     * <code>ConversionException</code> if an error occurs.
     */
    public DateTimeConverter() {
        super();
    }

    /**
     * Construct a Date/Time <i>Converter</i> that returns a default value if an
     * error occurs.
     * 
     * @param defaultValue
     *            The default value to be returned if the value to be converted
     *            is missing or an error occurs converting the value.
     */
    public DateTimeConverter(Object defaultValue) {
        super(defaultValue);
    }

    /**
     * Convert an input Date/Calendar object into a String.
     * <p>
     * <b>N.B.</b>If the converter has been configured to with one or more
     * patterns (using <code>setPatterns()</code>), then the first pattern will
     * be used to format the date into a String. Otherwise the default
     * <code>DateFormat</code> for the default locale (and <i>style</i> if
     * configured) will be used.
     * 
     * @param value
     *            The input value to be converted
     * @return the converted String value.
     * @throws Throwable
     *             if an error occurs converting to a String
     */
    protected String convertToString(Object value) throws Throwable {
        Date date = null;
        if (value instanceof Date) {
            return DateUtils.dateToISO((Date) value);
        } else if (value instanceof Calendar) {

        } else if (value instanceof Calendar) {
            date = ((Calendar) value).getTime();
        } else if (value instanceof Long) {
            date = new Date(((Long) value).longValue());
        }

        if (date != null)
            return date.toString();
        String result = value.toString();
        return result;
    }

    /**
     * Convert the input object into a Date object of the specified type.
     * <p>
     * This method handles conversions between the following types:
     * <ul>
     * <li><code>java.util.Date</code></li>
     * <li><code>java.util.Calendar</code></li>
     * <li><code>java.sql.Date</code></li>
     * <li><code>java.sql.Time</code></li>
     * <li><code>java.sql.Timestamp</code></li>
     * </ul>
     * 
     * It also handles conversion from a <code>String</code> to any of the above
     * types.
     * <p>
     * 
     * For <code>String</code> conversion, if the converter has been configured
     * with one or more patterns (using <code>setPatterns()</code>), then the
     * conversion is attempted with each of the specified patterns. Otherwise
     * the default <code>DateFormat</code> for the default locale (and
     * <i>style</i> if configured) will be used.
     * 
     * @param targetType
     *            Data type to which this value should be converted.
     * @param value
     *            The input value to be converted.
     * @return The converted value.
     * @throws Exception
     *             if conversion cannot be performed successfully
     */
    protected Object convertToType(Class targetType, Object value) throws Exception {

        // Class sourceType = value.getClass();

        // Handle java.sql.Timestamp
        if (value instanceof java.sql.Timestamp) {

            // ---------------------- JDK 1.3 Fix ----------------------
            // N.B. Prior to JDK 1.4 the Timestamp's getTime() method
            // didn't include the milliseconds. The following code
            // ensures it works consistently accross JDK versions
            java.sql.Timestamp timestamp = (java.sql.Timestamp) value;
            long timeInMillis = ((timestamp.getTime() / 1000) * 1000);
            timeInMillis += timestamp.getNanos() / 1000000;
            // ---------------------- JDK 1.3 Fix ----------------------
            return toDate(targetType, timeInMillis);
        }

        // Handle Date (includes java.sql.Date & java.sql.Time)
        if (value instanceof Date) {
            Date date = (Date) value;
            return toDate(targetType, date.getTime());
        }

        // Handle Calendar
        if (value instanceof Calendar) {
            Calendar calendar = (Calendar) value;
            return toDate(targetType, calendar.getTime().getTime());
        }

        // Handle Long
        if (value instanceof Long) {
            Long longObj = (Long) value;
            return toDate(targetType, longObj.longValue());
        }

        // Convert all other types to String & handle
        String stringValue = value.toString().trim();
        if (stringValue.length() == 0) {
            return handleMissing(targetType);
        }

        // Default String conversion
        return toDate(targetType, stringValue);

    }

    /**
     * Convert a long value to the specified Date type for this
     * <i>Converter</i>.
     * <p>
     * 
     * This method handles conversion to the following types:
     * <ul>
     * <li><code>java.util.Date</code></li>
     * <li><code>java.util.Calendar</code></li>
     * <li><code>java.sql.Date</code></li>
     * <li><code>java.sql.Time</code></li>
     * <li><code>java.sql.Timestamp</code></li>
     * </ul>
     * 
     * @param type
     *            The Date type to convert to
     * @param value
     *            The long value to convert.
     * @return The converted date value.
     */
    private Object toDate(Class type, long value) {

        // java.util.Date
        if (type.equals(Date.class)) {
            return new Date(value);
        }

        // java.sql.Date
        if (type.equals(java.sql.Date.class)) {
            return new java.sql.Date(value);
        }

        // java.sql.Time
        if (type.equals(java.sql.Time.class)) {
            return new java.sql.Time(value);
        }

        // java.sql.Timestamp
        if (type.equals(java.sql.Timestamp.class)) {
            return new java.sql.Timestamp(value);
        }

        String msg = toString(getClass()) + " cannot handle conversion to '" + toString(type) + "'";
        if (log().isWarnEnabled()) {
            log().warn("    " + msg);
        }
        throw new ConversionException(msg);
    }

    /**
     * Default String to Date conversion.
     * <p>
     * This method handles conversion from a String to the following types:
     * <ul>
     * <li><code>java.sql.Date</code></li>
     * <li><code>java.sql.Time</code></li>
     * <li><code>java.sql.Timestamp</code></li>
     * </ul>
     * <p>
     * <strong>N.B.</strong> No default String conversion mechanism is provided
     * for <code>java.util.Date</code> and <code>java.util.Calendar</code> type.
     * 
     * @param type
     *            The Number type to convert to
     * @param value
     *            The String value to convert.
     * @return The converted Number value.
     */
    private Object toDate(Class type, String value) {

        // java.util.Date
        if (type.equals(java.util.Date.class)) {
            try {
                return DateUtils.stringToDate(DataUtils.getDatePattern(), value);
            } catch (Exception e) {
                String msg = "String must be in Date format [" + DataUtils.getDatePattern()
                        + "] to create a java.util.Date";
                log().error(msg);
                throw new ConversionException(msg);
            }
        }

        // java.sql.Date
        if (type.equals(java.sql.Date.class)) {
            try {
                return DateUtils.stringToDate(DataUtils.getDatePattern(), value);
            } catch (Exception e) {
                String msg = "String must be in JDBC format [" + DataUtils.getDatePattern()
                        + "] to create a java.sql.Date";
                log().error(msg);
                throw new ConversionException(msg);
            }
        }

        // java.sql.Time
        if (type.equals(java.sql.Time.class)) {
            try {
                return DateUtils.stringToTime(DataUtils.getTimePattern(), value);
            } catch (Exception e) {
                String msg = ("String must be in JDBC format [" + DataUtils.getTimePattern()
                        + "] to create a java.sql.Time");
                log().error(msg);
                throw new ConversionException(msg);
            }
        }

        // java.sql.Timestamp
        if (type.equals(java.sql.Timestamp.class)) {
            try {
                return DateUtils.stringToTimestamp(DataUtils.getDateTimePattern(), value);
            } catch (Exception e) {
                String msg = ("String must be in JDBC format [" + DataUtils.getDateTimePattern() + "] "
                        + "to create a java.sql.Timestamp");
                log().error(msg);
                throw new ConversionException(msg);
            }
        }

        String msg = toString(getClass()) + " does not support default String to '" + toString(type)
                + "' conversion.";
        if (log().isWarnEnabled()) {
            log().warn("    " + msg);
            log().warn("    (N.B. Re-configure Converter or use alternative implementation)");
        }
        throw new ConversionException(msg);
    }

    /**
     * Provide a String representation of this date/time converter.
     * 
     * @return A String representation of this date/time converter
     */
    public String toString() {
        StringBuffer buffer = new StringBuffer();
        buffer.append(toString(getClass()));
        buffer.append("[UseDefault=");
        buffer.append(isUseDefault());
        buffer.append(']');
        return buffer.toString();
    }

}