001/*
002 * Copyright 2002-2017 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.format.number;
018
019import java.text.DecimalFormat;
020import java.text.NumberFormat;
021import java.util.Locale;
022
023import org.springframework.lang.Nullable;
024
025/**
026 * A general-purpose number formatter using NumberFormat's number style.
027 *
028 * <p>Delegates to {@link java.text.NumberFormat#getInstance(Locale)}.
029 * Configures BigDecimal parsing so there is no loss in precision.
030 * Allows configuration over the decimal number pattern.
031 * The {@link #parse(String, Locale)} routine always returns a BigDecimal.
032 *
033 * @author Keith Donald
034 * @author Juergen Hoeller
035 * @since 4.2
036 * @see #setPattern
037 * @see #setLenient
038 */
039public class NumberStyleFormatter extends AbstractNumberFormatter {
040
041        @Nullable
042        private String pattern;
043
044
045        /**
046         * Create a new NumberStyleFormatter without a pattern.
047         */
048        public NumberStyleFormatter() {
049        }
050
051        /**
052         * Create a new NumberStyleFormatter with the specified pattern.
053         * @param pattern the format pattern
054         * @see #setPattern
055         */
056        public NumberStyleFormatter(String pattern) {
057                this.pattern = pattern;
058        }
059
060
061        /**
062         * Specify the pattern to use to format number values.
063         * If not specified, the default DecimalFormat pattern is used.
064         * @see java.text.DecimalFormat#applyPattern(String)
065         */
066        public void setPattern(String pattern) {
067                this.pattern = pattern;
068        }
069
070
071        @Override
072        public NumberFormat getNumberFormat(Locale locale) {
073                NumberFormat format = NumberFormat.getInstance(locale);
074                if (!(format instanceof DecimalFormat)) {
075                        if (this.pattern != null) {
076                                throw new IllegalStateException("Cannot support pattern for non-DecimalFormat: " + format);
077                        }
078                        return format;
079                }
080                DecimalFormat decimalFormat = (DecimalFormat) format;
081                decimalFormat.setParseBigDecimal(true);
082                if (this.pattern != null) {
083                        decimalFormat.applyPattern(this.pattern);
084                }
085                return decimalFormat;
086        }
087
088}