    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
    018    package org.apache.commons.beanutils.locale;
    019
    020    import org.apache.commons.beanutils.ConversionException;
    021    import org.apache.commons.logging.Log;
    022    import org.apache.commons.logging.LogFactory;
    023
    024    import java.text.ParseException;
    025    import java.util.Locale;
    026
    027
    028    /**
    029     * <p>The base class for all standart type locale-sensitive converters.
    030     * It has {@link LocaleConverter} and {@link org.apache.commons.beanutils.Converter} implementations,
    031     * that convert an incoming locale-sensitive Object into an object of correspond type,
    032     * optionally using a default value or throwing a {@link ConversionException}
    033     * if a conversion error occurs.</p>
    034     *
    035     * @author Yauheny Mikulski
    036     */
    037
    038    public abstract class BaseLocaleConverter implements LocaleConverter {
    039
    040        // ----------------------------------------------------- Instance Variables
    041
    042        /** All logging goes through this logger */
    043        private Log log = LogFactory.getLog(BaseLocaleConverter.class);
    044
    045        /** The default value specified to our Constructor, if any. */
    046        private Object defaultValue = null;
    047
    048        /** Should we return the default value on conversion errors? */
    049        protected boolean useDefault = false;
    050
    051        /** The locale specified to our Constructor, by default - system locale. */
    052        protected Locale locale = Locale.getDefault();
    053
    054        /** The default pattern specified to our Constructor, if any. */
    055        protected String pattern = null;
    056
    057        /** The flag indicating whether the given pattern string is localized or not. */
    058        protected boolean locPattern = false;
    059
    060        // ----------------------------------------------------------- Constructors
    061
    062        /**
    063         * Create a {@link LocaleConverter} that will throw a {@link ConversionException}
    064         * if a conversion error occurs.
    065         * An unlocalized pattern is used for the convertion.
    066         *
    067         * @param locale        The locale
    068         * @param pattern       The convertion pattern
    069         */
    070        protected BaseLocaleConverter(Locale locale, String pattern) {
    071
    072            this(null, locale, pattern, false, false);
    073        }
    074
    075        /**
    076         * Create a {@link LocaleConverter} that will throw a {@link ConversionException}
    077         * if a conversion error occurs.
    078         *
    079         * @param locale        The locale
    080         * @param pattern       The convertion pattern
    081         * @param locPattern    Indicate whether the pattern is localized or not
    082         */
    083        protected BaseLocaleConverter(Locale locale, String pattern, boolean locPattern) {
    084
    085            this(null, locale, pattern, false, locPattern);
    086        }
    087
    088        /**
    089         * Create a {@link LocaleConverter} that will return the specified default value
    090         * if a conversion error occurs.
    091         * An unlocalized pattern is used for the convertion.
    092         *
    093         * @param defaultValue  The default value to be returned
    094         * @param locale        The locale
    095         * @param pattern       The convertion pattern
    096         */
    097        protected BaseLocaleConverter(Object defaultValue, Locale locale, String pattern) {
    098
    099            this(defaultValue, locale, pattern, false);
    100        }
    101
    102        /**
    103         * Create a {@link LocaleConverter} that will return the specified default value
    104         * if a conversion error occurs.
    105         *
    106         * @param defaultValue  The default value to be returned
    107         * @param locale        The locale
    108         * @param pattern       The convertion pattern
    109         * @param locPattern    Indicate whether the pattern is localized or not
    110         */
    111        protected BaseLocaleConverter(Object defaultValue, Locale locale, String pattern, boolean locPattern) {
    112
    113            this(defaultValue, locale, pattern, true, locPattern);
    114        }
    115
    116        /**
    117         * Create a {@link LocaleConverter} that will return the specified default value
    118         * or throw a {@link ConversionException} if a conversion error occurs.
    119         *
    120         * @param defaultValue  The default value to be returned
    121         * @param locale        The locale
    122         * @param pattern       The convertion pattern
    123         * @param useDefault    Indicate whether the default value is used or not
    124         * @param locPattern    Indicate whether the pattern is localized or not
    125         */
    126        private BaseLocaleConverter(Object defaultValue, Locale locale,
    127                                    String pattern, boolean useDefault, boolean locPattern) {
    128
    129            if (useDefault) {
    130                this.defaultValue = defaultValue;
    131                this.useDefault = true;
    132            }
    133
    134            if (locale != null) {
    135                this.locale = locale;
    136            }
    137
    138            this.pattern = pattern;
    139            this.locPattern = locPattern;
    140        }
    141
    142        // --------------------------------------------------------- Methods
    143
    144        /**
    145         * Convert the specified locale-sensitive input object into an output object of the
    146         * specified type.
    147         *
    148         * @param value The input object to be converted
    149         * @param pattern The pattern is used for the convertion
    150         * @return The converted value
    151         *
    152         * @exception ParseException if conversion cannot be performed
    153         *  successfully
    154         */
    155
    156        abstract protected Object parse(Object value, String pattern) throws ParseException;
    157
    158
    159        /**
    160         * Convert the specified locale-sensitive input object into an output object.
    161         * The default pattern is used for the convertion.
    162         *
    163         * @param value The input object to be converted
    164         * @return The converted value
    165         *
    166         * @exception ConversionException if conversion cannot be performed
    167         *  successfully
    168         */
    169        public Object convert(Object value) {
    170            return convert(value, null);
    171        }
    172
    173        /**
    174         * Convert the specified locale-sensitive input object into an output object.
    175         *
    176         * @param value The input object to be converted
    177         * @param pattern The pattern is used for the convertion
    178         * @return The converted value
    179         *
    180         * @exception ConversionException if conversion cannot be performed
    181         *  successfully
    182         */
    183        public Object convert(Object value, String pattern) {
    184            return convert(null, value, pattern);
    185        }
    186
    187        /**
    188         * Convert the specified locale-sensitive input object into an output object of the
    189         * specified type. The default pattern is used for the convertion.
    190         *
    191         * @param type Data type to which this value should be converted
    192         * @param value The input object to be converted
    193         * @return The converted value
    194         *
    195         * @exception ConversionException if conversion cannot be performed
    196         *  successfully
    197         */
    198        public Object convert(Class type, Object value) {
    199            return convert(type, value, null);
    200        }
    201
    202        /**
    203         * Convert the specified locale-sensitive input object into an output object of the
    204         * specified type.
    205         *
    206         * @param type Data is type to which this value should be converted
    207         * @param value is the input object to be converted
    208         * @param pattern is the pattern is used for the conversion; if null is
    209         * passed then the default pattern associated with the converter object
    210         * will be used.
    211         * @return The converted value
    212         *
    213         * @exception ConversionException if conversion cannot be performed
    214         *  successfully
    215         */
    216        public Object convert(Class type, Object value, String pattern) {
    217            if (value == null) {
    218                if (useDefault) {
    219                    return (defaultValue);
    220                } else {
    221                    // symmetric beanutils function allows null
    222                    // so do not: throw new ConversionException("No value specified");
    223                    log.debug("Null value specified for conversion, returing null");
    224                    return null;
    225                }
    226            }
    227
    228            try {
    229                if (pattern != null) {
    230                    return parse(value, pattern);
    231                } else {
    232                    return parse(value, this.pattern);
    233                }
    234            } catch (Exception e) {
    235                if (useDefault) {
    236                    return (defaultValue);
    237                } else {
    238                    if (e instanceof ConversionException) {
    239                        throw (ConversionException)e;
    240                    }
    241                    throw new ConversionException(e);
    242                }
    243            }
    244        }
    245    }