View Javadoc

1   /**
2    * Copyright 2009 Timothy Johnston Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
3    * file except in compliance with the License. You may obtain a copy of the License at
4    * 
5    * http://www.apache.org/licenses/LICENSE-2.0
6    * 
7    * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8    * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9    * specific language governing permissions and limitations under the License.
10   */
11  package com.timjohnstondev.unitconverter.logic;
12  
13  import java.math.BigDecimal;
14  import java.math.MathContext;
15  import java.math.RoundingMode;
16  import java.text.DecimalFormat;
17  import java.util.ResourceBundle;
18  
19  /**
20   * Utility class that contains all of the logic for performing mathematical calculations for the conversions.
21   */
22  public final class CalculationLogic
23  {
24    private static ResourceBundle resources = ResourceBundle.getBundle("com.timjohnstondev.unitconverter.view.View");
25  
26    private CalculationLogic()
27    {}
28  
29    /**
30     * Returns the formula or formatted numeric conversion factor.
31     * 
32     * @param conversion the conversion factor or formula
33     * @return the formula or formatted numeric conversion factor
34     */
35    public static String getConversionFactor(final String conversion)
36    {
37      String text = conversion;
38      if (conversion.indexOf(FormulaParser.VARIABLE) < 0)
39      {
40        text = formatNumber(new BigDecimal(conversion));
41      }
42      return text;
43    }
44  
45    /**
46     * Updates the result field if the input field has valid data and a conversion factor is selected.
47     * 
48     * @param input input
49     * @param conversionFactor conversionFactor
50     * @param molecularWeightCorrection the correction factor to adjust for molecular weight in mole to mass and mass to
51     *          mole conversions
52     * @return result
53     */
54    public static String getResult(final String input, final String conversionFactor,
55        final BigDecimal molecularWeightCorrection)
56    {
57      BigDecimal resultNumber = BigDecimal.ZERO;
58      String result = null;
59  
60      if (conversionFactor != null && verifyInput(input))
61      {
62        if (conversionFactor.indexOf(FormulaParser.VARIABLE) >= 0)
63        {
64          resultNumber = FormulaParser.parse(input, conversionFactor);
65        }
66        else
67        {
68          resultNumber = new BigDecimal(input).multiply(new BigDecimal(conversionFactor));
69        }
70        resultNumber = resultNumber.multiply(molecularWeightCorrection);
71        result = formatNumber(resultNumber);
72      }
73      return result;
74    }
75  
76    private static boolean verifyInput(final String input)
77    {
78      boolean matches = false;
79      final String[] patterns = {resources.getString("InputFilter.inputPatternSNDecimal"),
80              resources.getString("InputFilter.inputPatternSNFraction"),
81              resources.getString("InputFilter.inputPatternSNInteger"),
82              resources.getString("InputFilter.inputPatternDecimal"),
83              resources.getString("InputFilter.inputPatternFraction"),
84              resources.getString("InputFilter.inputPatternInteger")};
85  
86      for (String pattern : patterns)
87      {
88        if (input.matches(pattern))
89        {
90          matches = true;
91          break;
92        }
93      }
94      return matches;
95    }
96  
97    private static String formatNumber(final BigDecimal number)
98    {
99      final int numberLengthLimit = Integer.parseInt(resources.getString("CalculationPanel.numberLengthLimit"));
100     DecimalFormat formatter = new DecimalFormat(resources.getString("CalculationPanel.nonScientificNotationFormat"));
101     if (number.toPlainString().length() > numberLengthLimit)
102     {
103       if (number.doubleValue() < .1 || number.doubleValue() > Math.pow(10, numberLengthLimit))
104       {
105         formatter = new DecimalFormat(resources.getString("CalculationPanel.scientificNotationFormat"));
106       }
107     }
108     final MathContext mathContext = new MathContext(numberLengthLimit, RoundingMode.HALF_UP);
109     final BigDecimal tempFactor = number.round(mathContext);
110     return formatter.format(tempFactor);
111   }
112 
113 }