/* * Copyright (c) 2002-2015, JIDE Software Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ package jidefx.utils.converter; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.text.ParseException; import java.util.Locale; /** * {@link ObjectConverter} abstract implementation for Number. The fromString method is not implemented. * * @param <T> the data type of this converter. */ abstract public class AbstractNumberConverter<T extends Number> extends DefaultObjectConverter<T> { /** * A converter context to tell the NumberConverter to use fixed 2 digit fraction. */ public static final ConverterContext CONTEXT_FIXED_1_DIGIT_FRACTION = new ConverterContext("Fixed1DigitFraction"); //NON-NLS /** * A converter context to tell the NumberConverter to use fixed 2 digit fraction. */ public static final ConverterContext CONTEXT_FIXED_2_DIGIT_FRACTION = new ConverterContext("Fixed2DigitFraction"); //NON-NLS /** * A converter context to tell the NumberConverter to use fixed 2 digit fraction. */ public static final ConverterContext CONTEXT_FIXED_4_DIGIT_FRACTION = new ConverterContext("Fixed4DigitFraction"); //NON-NLS /** * A property for the converter context. You can set a {@link NumberFormat} to it and the converter will use it to * do the conversion. */ public static final String PROPERTY_NUMBER_FORMAT = "NumberFormat"; //NON-NLS private final Locale _locale; private final String _pattern; private final NumberFormat _numberFormat; public AbstractNumberConverter() { this(Locale.getDefault()); } public AbstractNumberConverter(Locale locale) { this(locale, null); } public AbstractNumberConverter(String pattern) { this(Locale.getDefault(), pattern); } public AbstractNumberConverter(Locale locale, String pattern) { this(locale, pattern, null); } public AbstractNumberConverter(NumberFormat numberFormat) { this(null, null, numberFormat); } AbstractNumberConverter(Locale locale, String pattern, NumberFormat numberFormat) { _locale = locale; _pattern = pattern; _numberFormat = numberFormat; } /** * Returns a {@code NumberFormat} instance to use for formatting and parsing in this {@link * AbstractNumberConverter}. * * @return a NumberFormat. */ protected NumberFormat getNumberFormat() { Locale locale = _locale == null ? Locale.getDefault() : _locale; if (_numberFormat != null) { return _numberFormat; } else if (_pattern != null) { DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale); return new DecimalFormat(_pattern, symbols); } else { return NumberFormat.getNumberInstance(locale); } } /** * Converts the String to a Number. It will use the NumberFormat defined as {@link #PROPERTY_NUMBER_FORMAT} if any. * If not there, it will use {@link #getNumberFormat()} to get the NumberFormat to do the conversion. * * @param string the string to be converted. * @param context the context * @return the Number converted from the String. */ public Number numberFromString(String string, ConverterContext context) { if (string == null) { return null; } string = string.trim(); if (string.length() == 0) { return null; } Object format = context != null ? context.getProperties().get(PROPERTY_NUMBER_FORMAT) : null; if (format instanceof NumberFormat) { try { return ((NumberFormat) format).parse(string); } catch (Exception e) { // ignore here. we will use the default way to convert it below } } NumberFormat parser = getNumberFormat(); try { return parser.parse(string); } catch (ParseException e) { return null; } } @Override public String toString(T number, ConverterContext context) { // If the specified value is null, return a zero-length String if (number == null) { return ""; } if (Double.isNaN(number.doubleValue())) { return ""; } Object format = context != null ? context.getProperties().get(PROPERTY_NUMBER_FORMAT) : null; if (format instanceof NumberFormat) { try { return ((NumberFormat) format).format(number); } catch (Exception e) { // ignore here. we will use the default way to convert it below } } NumberFormat formatter = getNumberFormat(); try { // Perform the requested formatting return formatter.format(number); } catch (Exception e) { return number.toString(); } } }