View Javadoc

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