KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > util > NumberUtils


1 /*
2  * Copyright 2002-2006 the original author or authors.
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 org.springframework.util;
18
19 import java.math.BigDecimal JavaDoc;
20 import java.math.BigInteger JavaDoc;
21 import java.text.NumberFormat JavaDoc;
22 import java.text.ParseException JavaDoc;
23
24 /**
25  * Miscellaneous utility methods for number conversion and parsing.
26  * Mainly for internal use within the framework; consider Jakarta's
27  * Commons Lang for a more comprehensive suite of string utilities.
28  *
29  * @author Juergen Hoeller
30  * @author Rob Harrop
31  * @since 1.1.2
32  */

33 public abstract class NumberUtils {
34
35     /**
36      * Convert the given number into an instance of the given target class.
37      * @param number the number to convert
38      * @param targetClass the target class to convert to
39      * @return the converted number
40      * @throws IllegalArgumentException if the target class is not supported
41      * (i.e. not a standard Number subclass as included in the JDK)
42      * @see java.lang.Byte
43      * @see java.lang.Short
44      * @see java.lang.Integer
45      * @see java.lang.Long
46      * @see java.math.BigInteger
47      * @see java.lang.Float
48      * @see java.lang.Double
49      * @see java.math.BigDecimal
50      */

51     public static Number JavaDoc convertNumberToTargetClass(Number JavaDoc number, Class JavaDoc targetClass)
52             throws IllegalArgumentException JavaDoc {
53
54         Assert.notNull(number, "Number must not be null");
55         Assert.notNull(targetClass, "Target class must not be null");
56
57         if (targetClass.isInstance(number)) {
58             return number;
59         }
60         else if (targetClass.equals(Byte JavaDoc.class)) {
61             long value = number.longValue();
62             if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
63                 raiseOverflowException(number, targetClass);
64             }
65             return new Byte JavaDoc(number.byteValue());
66         }
67         else if (targetClass.equals(Short JavaDoc.class)) {
68             long value = number.longValue();
69             if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
70                 raiseOverflowException(number, targetClass);
71             }
72             return new Short JavaDoc(number.shortValue());
73         }
74         else if (targetClass.equals(Integer JavaDoc.class)) {
75             long value = number.longValue();
76             if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
77                 raiseOverflowException(number, targetClass);
78             }
79             return new Integer JavaDoc(number.intValue());
80         }
81         else if (targetClass.equals(Long JavaDoc.class)) {
82             return new Long JavaDoc(number.longValue());
83         }
84         else if (targetClass.equals(Float JavaDoc.class)) {
85             return new Float JavaDoc(number.floatValue());
86         }
87         else if (targetClass.equals(Double JavaDoc.class)) {
88             return new Double JavaDoc(number.doubleValue());
89         }
90         else if (targetClass.equals(BigInteger JavaDoc.class)) {
91             return BigInteger.valueOf(number.longValue());
92         }
93         else if (targetClass.equals(BigDecimal JavaDoc.class)) {
94             // using BigDecimal(String) here, to avoid unpredictability of BigDecimal(double)
95
// (see BigDecimal javadoc for details)
96
return new BigDecimal JavaDoc(number.toString());
97         }
98         else {
99             throw new IllegalArgumentException JavaDoc("Could not convert number [" + number + "] of type [" +
100                     number.getClass().getName() + "] to unknown target class [" + targetClass.getName() + "]");
101         }
102     }
103
104     /**
105      * Raise an overflow exception for the given number and target class.
106      * @param number the number we tried to convert
107      * @param targetClass the target class we tried to convert to
108      */

109     private static void raiseOverflowException(Number JavaDoc number, Class JavaDoc targetClass) {
110         throw new IllegalArgumentException JavaDoc("Could not convert number [" + number + "] of type [" +
111                 number.getClass().getName() + "] to target class [" + targetClass.getName() + "]: overflow");
112     }
113
114     /**
115      * Parse the given text into a number instance of the given target class,
116      * using the corresponding default <code>decode</code> methods. Trims the
117      * input <code>String</code> before attempting to parse the number. Supports
118      * numbers in hex format (with leading 0x) and in octal format (with leading 0).
119      * @param text the text to convert
120      * @param targetClass the target class to parse into
121      * @return the parsed number
122      * @throws IllegalArgumentException if the target class is not supported
123      * (i.e. not a standard Number subclass as included in the JDK)
124      * @see java.lang.Byte#decode
125      * @see java.lang.Short#decode
126      * @see java.lang.Integer#decode
127      * @see java.lang.Long#decode
128      * @see #decodeBigInteger(String)
129      * @see java.lang.Float#valueOf
130      * @see java.lang.Double#valueOf
131      * @see java.math.BigDecimal#BigDecimal(String)
132      */

133     public static Number JavaDoc parseNumber(String JavaDoc text, Class JavaDoc targetClass) {
134         Assert.notNull(text, "Text must not be null");
135         Assert.notNull(targetClass, "Target class must not be null");
136
137         String JavaDoc trimmed = text.trim();
138
139         if (targetClass.equals(Byte JavaDoc.class)) {
140             return Byte.decode(trimmed);
141         }
142         else if (targetClass.equals(Short JavaDoc.class)) {
143             return Short.decode(trimmed);
144         }
145         else if (targetClass.equals(Integer JavaDoc.class)) {
146             return Integer.decode(trimmed);
147         }
148         else if (targetClass.equals(Long JavaDoc.class)) {
149             return Long.decode(trimmed);
150         }
151         else if (targetClass.equals(BigInteger JavaDoc.class)) {
152             return decodeBigInteger(trimmed);
153         }
154         else if (targetClass.equals(Float JavaDoc.class)) {
155             return Float.valueOf(trimmed);
156         }
157         else if (targetClass.equals(Double JavaDoc.class)) {
158             return Double.valueOf(trimmed);
159         }
160         else if (targetClass.equals(BigDecimal JavaDoc.class) || targetClass.equals(Number JavaDoc.class)) {
161             return new BigDecimal JavaDoc(trimmed);
162         }
163         else {
164             throw new IllegalArgumentException JavaDoc(
165                     "Cannot convert String [" + text + "] to target class [" + targetClass.getName() + "]");
166         }
167     }
168
169     /**
170      * Parse the given text into a number instance of the given target class,
171      * using the given NumberFormat. Trims the input <code>String</code>
172      * before attempting to parse the number.
173      * @param text the text to convert
174      * @param targetClass the target class to parse into
175      * @param numberFormat the NumberFormat to use for parsing (if <code>null</code>,
176      * this method falls back to <code>parseNumber(String, Class)</code>)
177      * @return the parsed number
178      * @throws IllegalArgumentException if the target class is not supported
179      * (i.e. not a standard Number subclass as included in the JDK)
180      * @see java.text.NumberFormat#parse
181      * @see #convertNumberToTargetClass
182      * @see #parseNumber(String, Class)
183      */

184     public static Number JavaDoc parseNumber(String JavaDoc text, Class JavaDoc targetClass, NumberFormat JavaDoc numberFormat) {
185         if (numberFormat != null) {
186             Assert.notNull(text, "Text must not be null");
187             Assert.notNull(targetClass, "Target class must not be null");
188             try {
189                 Number JavaDoc number = numberFormat.parse(text.trim());
190                 return convertNumberToTargetClass(number, targetClass);
191             }
192             catch (ParseException JavaDoc ex) {
193                 throw new IllegalArgumentException JavaDoc(ex.getMessage());
194             }
195         }
196         else {
197             return parseNumber(text, targetClass);
198         }
199     }
200
201     /**
202      * Decode a {@link java.math.BigInteger} from a {@link String} value.
203      * Supports decimal, hex and octal notation.
204      * @see BigInteger#BigInteger(String, int)
205      */

206     private static BigInteger JavaDoc decodeBigInteger(String JavaDoc value) {
207         int radix = 10;
208         int index = 0;
209         boolean negative = false;
210
211         // Handle minus sign, if present.
212
if (value.startsWith("-")) {
213             negative = true;
214             index++;
215         }
216
217         // Handle radix specifier, if present.
218
if (value.startsWith("0x", index) || value.startsWith("0X", index)) {
219             index += 2;
220             radix = 16;
221         }
222         else if (value.startsWith("#", index)) {
223             index++;
224             radix = 16;
225         }
226         else if (value.startsWith("0", index) && value.length() > 1 + index) {
227             index++;
228             radix = 8;
229         }
230
231         BigInteger JavaDoc result = new BigInteger JavaDoc(value.substring(index), radix);
232         return (negative ? result.negate() : result);
233     }
234
235 }
236
Popular Tags