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
018package org.apache.commons.beanutils.locale.converters;
019
020import java.math.BigDecimal;
021import java.math.BigInteger;
022import java.text.DecimalFormat;
023import java.text.NumberFormat;
024import java.text.ParseException;
025import java.text.SimpleDateFormat;
026import java.util.Date;
027import java.util.Locale;
028
029import org.apache.commons.beanutils.ConversionException;
030import org.apache.commons.beanutils.locale.BaseLocaleConverter;
031import org.apache.commons.logging.Log;
032import org.apache.commons.logging.LogFactory;
033
034/**
035 * <p>Standard {@link org.apache.commons.beanutils.locale.LocaleConverter}
036 * implementation that converts an incoming
037 * locale-sensitive object into a <code>java.lang.String</code> object,
038 * optionally using a default value or throwing a
039 * {@link org.apache.commons.beanutils.ConversionException}
040 * if a conversion error occurs.</p>
041 *
042 */
043
044public class StringLocaleConverter extends BaseLocaleConverter {
045
046    /** All logging goes through this logger */
047    private final Log log = LogFactory.getLog(StringLocaleConverter.class);     //msz fix
048
049    /**
050     * Create a {@link org.apache.commons.beanutils.locale.LocaleConverter}
051     * that will throw a {@link org.apache.commons.beanutils.ConversionException}
052     * if a conversion error occurs. The locale is the default locale for
053     * this instance of the Java Virtual Machine and an unlocalized pattern is used
054     * for the convertion.
055     *
056     */
057    public StringLocaleConverter() {
058
059        this(false);
060    }
061
062    /**
063     * Create a {@link org.apache.commons.beanutils.locale.LocaleConverter}
064     * that will throw a {@link org.apache.commons.beanutils.ConversionException}
065     * if a conversion error occurs. The locale is the default locale for
066     * this instance of the Java Virtual Machine.
067     *
068     * @param locPattern    Indicate whether the pattern is localized or not
069     */
070    public StringLocaleConverter(final boolean locPattern) {
071
072        this(Locale.getDefault(), locPattern);
073    }
074
075    /**
076     * Create a {@link org.apache.commons.beanutils.locale.LocaleConverter}
077     * that will throw a {@link org.apache.commons.beanutils.ConversionException}
078     * if a conversion error occurs. An unlocalized pattern is used for the convertion.
079     *
080     * @param locale        The locale
081     */
082    public StringLocaleConverter(final Locale locale) {
083
084        this(locale, false);
085    }
086
087    /**
088     * Create a {@link org.apache.commons.beanutils.locale.LocaleConverter}
089     * that will throw a {@link org.apache.commons.beanutils.ConversionException}
090     * if a conversion error occurs.
091     *
092     * @param locale        The locale
093     * @param locPattern    Indicate whether the pattern is localized or not
094     */
095    public StringLocaleConverter(final Locale locale, final boolean locPattern) {
096
097        this(locale, (String) null, locPattern);
098    }
099
100    /**
101     * Create a {@link org.apache.commons.beanutils.locale.LocaleConverter}
102     * that will throw a {@link org.apache.commons.beanutils.ConversionException}
103     * if a conversion error occurs. An unlocalized pattern is used for the convertion.
104     *
105     * @param locale        The locale
106     * @param pattern       The convertion pattern
107     */
108    public StringLocaleConverter(final Locale locale, final String pattern) {
109
110        this(locale, pattern, false);
111    }
112
113    /**
114     * Create a {@link org.apache.commons.beanutils.locale.LocaleConverter}
115     * that will throw a {@link org.apache.commons.beanutils.ConversionException}
116     * if a conversion error occurs.
117     *
118     * @param locale        The locale
119     * @param pattern       The convertion pattern
120     * @param locPattern    Indicate whether the pattern is localized or not
121     */
122    public StringLocaleConverter(final Locale locale, final String pattern, final boolean locPattern) {
123
124        super(locale, pattern, locPattern);
125    }
126
127    /**
128     * Create a {@link org.apache.commons.beanutils.locale.LocaleConverter}
129     * that will return the specified default value
130     * if a conversion error occurs. The locale is the default locale for
131     * this instance of the Java Virtual Machine and an unlocalized pattern is used
132     * for the convertion.
133     *
134     * @param defaultValue  The default value to be returned
135     */
136    public StringLocaleConverter(final Object defaultValue) {
137
138        this(defaultValue, false);
139    }
140
141    /**
142     * Create a {@link org.apache.commons.beanutils.locale.LocaleConverter}
143     * that will return the specified default value
144     * if a conversion error occurs. The locale is the default locale for
145     * this instance of the Java Virtual Machine.
146     *
147     * @param defaultValue  The default value to be returned
148     * @param locPattern    Indicate whether the pattern is localized or not
149     */
150    public StringLocaleConverter(final Object defaultValue, final boolean locPattern) {
151
152        this(defaultValue, Locale.getDefault(), locPattern);
153    }
154
155    /**
156     * Create a {@link org.apache.commons.beanutils.locale.LocaleConverter}
157     * that will return the specified default value
158     * if a conversion error occurs. An unlocalized pattern is used for the convertion.
159     *
160     * @param defaultValue  The default value to be returned
161     * @param locale        The locale
162     */
163    public StringLocaleConverter(final Object defaultValue, final Locale locale) {
164
165        this(defaultValue, locale, false);
166    }
167
168    /**
169     * Create a {@link org.apache.commons.beanutils.locale.LocaleConverter}
170     * that will return the specified default value
171     * if a conversion error occurs.
172     *
173     * @param defaultValue  The default value to be returned
174     * @param locale        The locale
175     * @param locPattern    Indicate whether the pattern is localized or not
176     */
177    public StringLocaleConverter(final Object defaultValue, final Locale locale, final boolean locPattern) {
178
179        this(defaultValue, locale, null, locPattern);
180    }
181
182    /**
183     * Create a {@link org.apache.commons.beanutils.locale.LocaleConverter}
184     * that will return the specified default value
185     * if a conversion error occurs. An unlocalized pattern is used for the convertion.
186     *
187     * @param defaultValue  The default value to be returned
188     * @param locale        The locale
189     * @param pattern       The convertion pattern
190     */
191    public StringLocaleConverter(final Object defaultValue, final Locale locale, final String pattern) {
192
193        this(defaultValue, locale, pattern, false);
194    }
195
196    /**
197     * Create a {@link org.apache.commons.beanutils.locale.LocaleConverter}
198     * that will return the specified default value
199     * if a conversion error occurs.
200     *
201     * @param defaultValue  The default value to be returned
202     * @param locale        The locale
203     * @param pattern       The convertion pattern
204     * @param locPattern    Indicate whether the pattern is localized or not
205     */
206    public StringLocaleConverter(final Object defaultValue, final Locale locale, final String pattern, final boolean locPattern) {
207
208        super(defaultValue, locale, pattern, locPattern);
209    }
210
211    /**
212     * Make an instance of DecimalFormat.
213     *
214     * @param locale The locale
215     * @param pattern The pattern is used for the convertion
216     * @return The format for the locale and pattern
217     * @throws ConversionException if conversion cannot be performed
218     *  successfully
219     * @throws ParseException if an error occurs parsing a String to a Number
220     */
221    private DecimalFormat getDecimalFormat(final Locale locale, final String pattern) {
222
223        final DecimalFormat numberFormat = (DecimalFormat) NumberFormat.getInstance(locale);
224
225        // if some constructors default pattern to null, it makes only sense to handle null pattern gracefully
226        if (pattern != null) {
227            if (locPattern) {
228                numberFormat.applyLocalizedPattern(pattern);
229            } else {
230                numberFormat.applyPattern(pattern);
231            }
232        } else {
233            log.debug("No pattern provided, using default.");
234        }
235
236        return numberFormat;
237    }
238
239    /**
240     * Convert the specified locale-sensitive input object into an output object of the
241     * specified type.
242     *
243     * @param value The input object to be converted
244     * @param pattern The pattern is used for the convertion
245     * @return The converted value
246     * @throws org.apache.commons.beanutils.ConversionException if conversion
247     * cannot be performed successfully
248     * @throws ParseException if an error occurs
249     */
250    @Override
251    protected Object parse(final Object value, final String pattern) throws ParseException {
252
253        String result = null;
254
255        if (value instanceof Integer ||
256                value instanceof Long ||
257                value instanceof BigInteger ||
258                value instanceof Byte ||
259                value instanceof Short) {
260
261            result = getDecimalFormat(locale, pattern).format(((Number) value).longValue());
262        }
263        else if (value instanceof Double ||
264                value instanceof BigDecimal ||
265                value instanceof Float) {
266
267            result = getDecimalFormat(locale, pattern).format(((Number) value).doubleValue());
268        }
269        else if (value instanceof Date) { // java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp
270
271            final SimpleDateFormat dateFormat =
272                    new SimpleDateFormat(pattern, locale);
273
274            result = dateFormat.format(value);
275        }
276        else {
277            result = value.toString();
278        }
279
280        return result;
281    }
282}