View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.util;
8   
9   import java.math.BigDecimal;
10  import java.math.BigInteger;
11  
12  /**
13   * <code>NumberUtils</code> contains useful methods for manipulating numbers.
14   */
15  // @ThreadSafe
16  public class NumberUtils extends org.apache.commons.lang.math.NumberUtils
17  {
18      public static final int INTEGER_ERROR = -999999999;
19      public static final long LONG_ERROR = -999999999;
20      public static final float FLOAT_ERROR = -999999999;
21      public static final double DOUBLE_ERROR = -999999999;
22  
23      public static long toLong(Object obj)
24      {
25          if (obj == null)
26          {
27              throw new IllegalArgumentException("Unable to convert null object to long");
28          }
29          else if (obj instanceof String)
30          {
31              return toLong((String) obj);
32          }
33          else if (obj instanceof Number)
34          {
35              return ((Number) obj).longValue();
36          }
37          else
38          {
39              throw new IllegalArgumentException("Unable to convert object of type: "
40                                                 + obj.getClass().getName() + " to long.");
41          }
42      }
43  
44      public static int toInt(Object obj)
45      {
46          if (obj == null)
47          {
48              throw new IllegalArgumentException("Unable to convert null object to int");
49          }
50          else if (obj instanceof String)
51          {
52              return toInt((String) obj);
53          }
54          else if (obj instanceof Number)
55          {
56              return ((Number) obj).intValue();
57          }
58          else
59          {
60              throw new IllegalArgumentException("Unable to convert object of type: "
61                                                 + obj.getClass().getName() + " to int.");
62          }
63      }
64  
65      public static float toFloat(Object obj)
66      {
67          if (obj == null)
68          {
69              throw new IllegalArgumentException("Unable to convert null object to float");
70          }
71          else if (obj instanceof String)
72          {
73              return toFloat((String) obj);
74          }
75          else if (obj instanceof Number)
76          {
77              return ((Number) obj).floatValue();
78          }
79          else
80          {
81              throw new IllegalArgumentException("Unable to convert object of type: "
82                                                 + obj.getClass().getName() + " to float.");
83          }
84      }
85  
86      public static double toDouble(Object obj)
87      {
88          if (obj == null)
89          {
90              throw new IllegalArgumentException("Unable to convert null object to double");
91          }
92          else if (obj instanceof String)
93          {
94              return toDouble((String) obj);
95          }
96          else if (obj instanceof Number)
97          {
98              return ((Number) obj).doubleValue();
99          }
100         else
101         {
102             throw new IllegalArgumentException("Unable to convert object of type: "
103                                                + obj.getClass().getName() + " to double.");
104         }
105     }
106 
107     public static int toInt(String str)
108     {
109         return toInt(str, INTEGER_ERROR);
110     }
111 
112     public static long toLong(String str)
113     {
114         return toLong(str, LONG_ERROR);
115     }
116 
117     public static float toFloat(String str)
118     {
119         return toFloat(str, FLOAT_ERROR);
120     }
121 
122     public static double toDouble(String str)
123     {
124         return toDouble(str, DOUBLE_ERROR);
125     }
126 
127     /*
128      * The following methods are from org.springframework.util.NumberUtils
129      */
130 
131     @SuppressWarnings("unchecked")
132     public static <T extends Number> T parseNumber(String text, Class<T> targetClass)
133     {
134         text = text.trim();
135 
136         if (targetClass.equals(Byte.class))
137         {
138             return (T) Byte.valueOf(text);
139         }
140         else if (targetClass.equals(Short.class))
141         {
142             return (T) Short.valueOf(text);
143         }
144         else if (targetClass.equals(Integer.class))
145         {
146             return (T) Integer.valueOf(text);
147         }
148         else if (targetClass.equals(Long.class))
149         {
150             return (T) Long.valueOf(text);
151         }
152         else if (targetClass.equals(BigInteger.class))
153         {
154             return (T) new BigInteger(text);
155         }
156         else if (targetClass.equals(Float.class))
157         {
158             return (T) Float.valueOf(text);
159         }
160         else if (targetClass.equals(Double.class))
161         {
162             return (T) Double.valueOf(text);
163         }
164         else if (targetClass.equals(BigDecimal.class) || targetClass.equals(Number.class))
165         {
166             return (T) new BigDecimal(text);
167         }
168         else
169         {
170             throw new IllegalArgumentException("Cannot convert String [" + text + "] to target class ["
171                                                + targetClass.getName() + "]");
172         }
173     }
174 
175     @SuppressWarnings("unchecked")
176     public static <T extends Number> T convertNumberToTargetClass(Number number, Class<T> targetClass)
177         throws IllegalArgumentException
178     {
179 
180         if (targetClass.isInstance(number))
181         {
182             return (T) number;
183         }
184         else if (targetClass.equals(Byte.class))
185         {
186             long value = number.longValue();
187             if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE)
188             {
189                 raiseOverflowException(number, targetClass);
190             }
191             return (T) new Byte(number.byteValue());
192         }
193         else if (targetClass.equals(Short.class))
194         {
195             long value = number.longValue();
196             if (value < Short.MIN_VALUE || value > Short.MAX_VALUE)
197             {
198                 raiseOverflowException(number, targetClass);
199             }
200             return (T) new Short(number.shortValue());
201         }
202         else if (targetClass.equals(Integer.class))
203         {
204             long value = number.longValue();
205             if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE)
206             {
207                 raiseOverflowException(number, targetClass);
208             }
209             return (T) new Integer(number.intValue());
210         }
211         else if (targetClass.equals(Long.class))
212         {
213             return (T) new Long(number.longValue());
214         }
215         else if (targetClass.equals(BigInteger.class))
216         {
217             if (number instanceof BigDecimal)
218             {
219                 // do not lose precision - use BigDecimal's own conversion
220                 return (T) ((BigDecimal) number).toBigInteger();
221             }
222             else
223             {
224                 // original value is not a Big* number - use standard long conversion
225                 return (T) BigInteger.valueOf(number.longValue());
226             }
227         }
228         else if (targetClass.equals(Float.class))
229         {
230             return (T) new Float(number.floatValue());
231         }
232         else if (targetClass.equals(Double.class))
233         {
234             return (T) new Double(number.doubleValue());
235         }
236         else if (targetClass.equals(BigDecimal.class))
237         {
238             // always use BigDecimal(String) here to avoid unpredictability of
239             // BigDecimal(double)
240             // (see BigDecimal javadoc for details)
241             return (T) new BigDecimal(number.toString());
242         }
243         else
244         {
245             throw new IllegalArgumentException("Could not convert number [" + number + "] of type ["
246                                                + number.getClass().getName() + "] to unknown target class ["
247                                                + targetClass.getName() + "]");
248         }
249     }
250 
251     /**
252      * Raise an overflow exception for the given number and target class.
253      * 
254      * @param number the number we tried to convert
255      * @param targetClass the target class we tried to convert to
256      */
257     private static void raiseOverflowException(Number number, Class targetClass)
258     {
259         throw new IllegalArgumentException("Could not convert number [" + number + "] of type ["
260                                            + number.getClass().getName() + "] to target class ["
261                                            + targetClass.getName() + "]: overflow");
262     }
263 
264 }