FileDocCategorySizeDatePackage
SynchronizedDateFormat.javaAPI DocApache James 2.3.15584Fri Jan 12 12:56:36 GMT 2007org.apache.mailet.dates

SynchronizedDateFormat.java

/****************************************************************
 * 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.apache.mailet.dates;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;


/**
 * This class is designed to be a synchronized wrapper for a
 * <code>java.text.DateFormat</code> subclass.  In general,
 * these subclasses (most notably the <code>java.text.SimpleDateFormat</code>
 * classes are not thread safe, so we need to synchronize on the
 * internal DateFormat for all delegated calls.
 *
 */
public class SynchronizedDateFormat implements SimplifiedDateFormat {
    private final DateFormat internalDateFormat;

    /**
     * Public constructor that mimics that of SimpleDateFormat.  See
     * java.text.SimpleDateFormat for more details.
     *
     * @param pattern the pattern that defines this DateFormat
     * @param locale the locale
     */
    public SynchronizedDateFormat(String pattern, Locale locale) {
        internalDateFormat = new SimpleDateFormat(pattern, locale);
    }

    /**
     * <p>Wrapper method to allow child classes to synchronize a preexisting
     * DateFormat.</p>
     *
     * <p>TODO: Investigate replacing this with a factory method.</p>
     *
     * @param the DateFormat to synchronize
     */
    protected SynchronizedDateFormat(DateFormat theDateFormat) {
        internalDateFormat = theDateFormat;
    }

    /**
     * SimpleDateFormat will handle most of this for us, but we
     * want to ensure thread safety, so we wrap the call in a
     * synchronized block.
     *
     * @return java.lang.String
     * @param d Date
     */
    public String format(Date d) {
        synchronized (internalDateFormat) {
           return internalDateFormat.format(d);
        }
    }

    /**
     * Parses text from the beginning of the given string to produce a date.
     * The method may not use the entire text of the given string.
     * <p>
     * This method is designed to be thread safe, so we wrap our delegated
     * parse method in an appropriate synchronized block.
     *
     * @param source A <code>String</code> whose beginning should be parsed.
     * @return A <code>Date</code> parsed from the string.
     * @throws ParseException if the beginning of the specified string
     *         cannot be parsed.
     */
    public Date parse(String source) throws ParseException {
        synchronized (internalDateFormat) {
            return internalDateFormat.parse(source);
        }
    }

    /**
     * Sets the time zone of this SynchronizedDateFormat object.
     * @param zone the given new time zone.
     */
    public void setTimeZone(TimeZone zone) {
        synchronized(internalDateFormat) {
            internalDateFormat.setTimeZone(zone);
        }
    }

    /**
     * Gets the time zone.
     * @return the time zone associated with this SynchronizedDateFormat.
     */
    public TimeZone getTimeZone() {
        synchronized(internalDateFormat) {
            return internalDateFormat.getTimeZone();
        }
    }

    /**
     * Specify whether or not date/time parsing is to be lenient.  With
     * lenient parsing, the parser may use heuristics to interpret inputs that
     * do not precisely match this object's format.  With strict parsing,
     * inputs must match this object's format.
     * @param lenient when true, parsing is lenient
     * @see java.util.Calendar#setLenient
     */
    public void setLenient(boolean lenient)
    {
        synchronized(internalDateFormat) {
            internalDateFormat.setLenient(lenient);
        }
    }

    /**
     * Tell whether date/time parsing is to be lenient.
     * @return whether this SynchronizedDateFormat is lenient.
     */
    public boolean isLenient()
    {
        synchronized(internalDateFormat) {
            return internalDateFormat.isLenient();
        }
    }

    /**
     * Overrides hashCode
     */
    public int hashCode() {
        synchronized(internalDateFormat) {
            return internalDateFormat.hashCode();
        }
    }

    /**
     * Overrides equals
     */
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        synchronized(internalDateFormat) {
            return internalDateFormat.equals(obj);
        }
    }

}