package org.milyn.javabean.decoders; import org.milyn.config.Configurable; import org.milyn.cdr.SmooksConfigurationException; import java.text.*; import java.util.*; /** * LocaleAwareDateDecoder is a decoder 'helper' that can be subclassed * by Date decoders to enable them to use locale specific date formats. * <pre> * Usage: * <resource-config selector="decoder:DecoderName"> * <resource>org.milyn.javabean.decoders.DateDecoder</resource> * <param name="format">EEE MMM dd HH:mm:ss z yyyy</param> * </resource-config> * Optional parameters: * <param name="locale-language">sv</param> * <param name="locale-country">SE</param> * <param name="verify-locale">false</param> * </pre> * * @author <a href="mailto:daniel.bevenius@gmail.com">daniel.bevenius@gmail.com</a> */ public abstract class LocaleAwareDateDecoder implements Configurable { /** * Date format configuration key. */ public static final String FORMAT = "format"; /** * Default date format string */ public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss"; /** * ISO Language Code. Lower case two-letter code defined by ISO-639 */ public static final String LOCALE_LANGUAGE_CODE = "locale-language"; /** * ISO Country Code. Upper case two-letter code defined by ISO-3166 */ public static final String LOCALE_COUNTRY_CODE = "locale-country"; /** * True or false(default). * Whether or not a check should be performed to verify that * the specified locale is installed. This operation can take some * time and should be turned off in a production evironment */ public static final String VERIFY_LOCALE = "verify-locale"; private boolean verifyLocale; protected String format; /* * Need to initialize a default decoder as not calls can be make * directly to decode without calling setConfigurtion. */ protected SimpleDateFormat decoder = new SimpleDateFormat( DEFAULT_DATE_FORMAT ); public void setConfiguration(Properties resourceConfig) throws SmooksConfigurationException { format = resourceConfig.getProperty(FORMAT, DEFAULT_DATE_FORMAT); if (format == null) { throw new SmooksConfigurationException("Decoder must specify a 'format' parameter."); } final String languageCode = resourceConfig.getProperty(LOCALE_LANGUAGE_CODE); final String countryCode = resourceConfig.getProperty(LOCALE_COUNTRY_CODE); verifyLocale = Boolean.parseBoolean(resourceConfig.getProperty(VERIFY_LOCALE, "false")); decoder = new SimpleDateFormat(format.trim(), getLocale( languageCode, countryCode )); } /** * Returns a Locale matching the passed in languageCode, and countryCode * * @param languageCode lowercase two-letter ISO-639 code. * @param countryCode uppercase two-letter ISO-3166 code. * @return Locale matching the passed in languageCode and optionally the * countryCode. If languageCode is null the default Locale * will be returned. * @throws SmooksConfigurationException * if the Locale is not installed on the system */ protected Locale getLocale(final String languageCode, final String countryCode ) { Locale locale = null; if ( languageCode == null ) locale = Locale.getDefault(); else if ( countryCode == null ) locale = new Locale( languageCode.trim() ); else locale = new Locale( languageCode.trim(), countryCode.trim() ); if ( verifyLocale ) if ( !isLocalInstalled( locale ) ) throw new SmooksConfigurationException( "Locale " + locale + " is not available on this system."); return locale; } protected boolean isLocalInstalled(final Locale locale ) { return Arrays.asList( Locale.getAvailableLocales() ).contains( locale ); } }