View Javadoc
1   /*
2   Copyright (c) 2018 James Ahlborn
3   
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7   
8       http://www.apache.org/licenses/LICENSE-2.0
9   
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15  */
16  
17  package com.healthmarketscience.jackcess.expr;
18  
19  import java.math.BigDecimal;
20  import java.text.DecimalFormatSymbols;
21  import java.util.Locale;
22  
23  import com.healthmarketscience.jackcess.impl.expr.FormatUtil;
24  import com.healthmarketscience.jackcess.impl.expr.NumberFormatter;
25  
26  /**
27   * A NumericConfig encapsulates number formatting options for expression
28   * evaluation.  The default {@link #US_NUMERIC_CONFIG} instance provides US
29   * specific locale configuration.  Databases which have been built for other
30   * locales can utilize custom implementations of NumericConfig in order to
31   * evaluate expressions correctly.
32   *
33   * @author James Ahlborn
34   */
35  public class NumericConfig
36  {
37    public static final NumericConfigonfig.html#NumericConfig">NumericConfig US_NUMERIC_CONFIG = new NumericConfig(
38        2, true, false, true, 3, Locale.US);
39  
40    public enum Type {
41      CURRENCY, FIXED, STANDARD, PERCENT, SCIENTIFIC, EURO;
42    }
43  
44    private final int _numDecDigits;
45    private final boolean _incLeadingDigit;
46    private final boolean _useNegParens;
47    private final boolean _useNegCurrencyParens;
48    private final int _numGroupDigits;
49    private final DecimalFormatSymbols _symbols;
50    private final NumberFormatter _numFmt;
51    private final String _currencyFormat;
52    private final String _fixedFormat;
53    private final String _standardFormat;
54    private final String _percentFormat;
55    private final String _scientificFormat;
56    private final String _euroFormat;
57  
58    public NumericConfig(int numDecDigits, boolean incLeadingDigit,
59                         boolean useNegParens, boolean useNegCurrencyParens,
60                         int numGroupDigits, Locale locale) {
61      _numDecDigits = numDecDigits;
62      _incLeadingDigit = incLeadingDigit;
63      _useNegParens = useNegParens;
64      _useNegCurrencyParens = useNegCurrencyParens;
65      _numGroupDigits = numGroupDigits;
66      _symbols = DecimalFormatSymbols.getInstance(locale);
67      _numFmt = new NumberFormatter(_symbols);
68  
69      _currencyFormat = FormatUtil.createNumberFormatPattern(
70          FormatUtil.NumPatternType.CURRENCY, _numDecDigits, _incLeadingDigit,
71          _useNegCurrencyParens, _numGroupDigits);
72      _fixedFormat = FormatUtil.createNumberFormatPattern(
73          FormatUtil.NumPatternType.GENERAL, _numDecDigits, true,
74          _useNegParens, 0);
75      _standardFormat = FormatUtil.createNumberFormatPattern(
76          FormatUtil.NumPatternType.GENERAL, _numDecDigits, _incLeadingDigit,
77          _useNegParens, _numGroupDigits);
78      _percentFormat = FormatUtil.createNumberFormatPattern(
79          FormatUtil.NumPatternType.PERCENT, _numDecDigits, _incLeadingDigit,
80          _useNegParens, 0);
81      _scientificFormat = FormatUtil.createNumberFormatPattern(
82          FormatUtil.NumPatternType.SCIENTIFIC, _numDecDigits, true,
83          false, 0);
84      _euroFormat = FormatUtil.createNumberFormatPattern(
85          FormatUtil.NumPatternType.EURO, _numDecDigits, _incLeadingDigit,
86          _useNegCurrencyParens, _numGroupDigits);
87    }
88  
89    public int getNumDecimalDigits() {
90      return _numDecDigits;
91    }
92  
93    public boolean includeLeadingDigit() {
94      return _incLeadingDigit;
95    }
96  
97    public boolean useParensForNegatives() {
98      return _useNegParens;
99    }
100 
101   public boolean useParensForCurrencyNegatives() {
102     return _useNegCurrencyParens;
103   }
104 
105   public int getNumGroupingDigits() {
106     return _numGroupDigits;
107   }
108 
109   public String getNumberFormat(Type type) {
110     switch(type) {
111     case CURRENCY:
112       return _currencyFormat;
113     case FIXED:
114       return _fixedFormat;
115     case STANDARD:
116       return _standardFormat;
117     case PERCENT:
118       return _percentFormat;
119     case SCIENTIFIC:
120       return _scientificFormat;
121     case EURO:
122       return _euroFormat;
123     default:
124       throw new IllegalArgumentException("unknown number type " + type);
125     }
126   }
127 
128   public DecimalFormatSymbols getDecimalFormatSymbols() {
129     return _symbols;
130   }
131 
132   /**
133    * @return the given float formatted according to the current locale config
134    */
135   public String format(float f) {
136     return _numFmt.format(f);
137   }
138 
139   /**
140    * @return the given double formatted according to the current locale config
141    */
142   public String format(double d) {
143     return _numFmt.format(d);
144   }
145 
146   /**
147    * @return the given BigDecimal formatted according to the current locale config
148    */
149   public String format(BigDecimal bd) {
150     return _numFmt.format(bd);
151   }
152 }