KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > databinding > conversion > StringToNumberConverter


1 /*******************************************************************************
2  * Copyright (c) 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  ******************************************************************************/

11
12 package org.eclipse.core.databinding.conversion;
13
14 import java.math.BigDecimal JavaDoc;
15 import java.math.BigInteger JavaDoc;
16
17 import org.eclipse.core.internal.databinding.conversion.StringToNumberParser;
18 import org.eclipse.core.internal.databinding.conversion.StringToNumberParser.ParseResult;
19 import org.eclipse.core.internal.databinding.validation.NumberFormatConverter;
20
21 import com.ibm.icu.text.NumberFormat;
22
23 /**
24  * Converts a String to a Number using <code>NumberFormat.parse(...)</code>.
25  * This class is thread safe.
26  *
27  * @since 1.0
28  */

29 public class StringToNumberConverter extends NumberFormatConverter {
30     private Class JavaDoc toType;
31     /**
32      * NumberFormat instance to use for conversion. Access must be synchronized.
33      */

34     private NumberFormat numberFormat;
35
36     /**
37      * Minimum possible value for the type. Can be <code>null</code> as
38      * BigInteger doesn't have bounds.
39      */

40     private final Number JavaDoc min;
41     /**
42      * Maximum possible value for the type. Can be <code>null</code> as
43      * BigInteger doesn't have bounds.
44      */

45     private final Number JavaDoc max;
46
47     /**
48      * The boxed type of the toType;
49      */

50     private final Class JavaDoc boxedType;
51
52     private static final Integer JavaDoc MIN_INTEGER = new Integer JavaDoc(Integer.MIN_VALUE);
53     private static final Integer JavaDoc MAX_INTEGER = new Integer JavaDoc(Integer.MAX_VALUE);
54
55     private static final Double JavaDoc MIN_DOUBLE = new Double JavaDoc(-Double.MAX_VALUE);
56     private static final Double JavaDoc MAX_DOUBLE = new Double JavaDoc(Double.MAX_VALUE);
57
58     private static final Long JavaDoc MIN_LONG = new Long JavaDoc(Long.MIN_VALUE);
59     private static final Long JavaDoc MAX_LONG = new Long JavaDoc(Long.MIN_VALUE);
60
61     private static final Float JavaDoc MIN_FLOAT = new Float JavaDoc(-Float.MAX_VALUE);
62     private static final Float JavaDoc MAX_FLOAT = new Float JavaDoc(Float.MAX_VALUE);
63
64     /**
65      * @param numberFormat
66      * @param toType
67      * @param min
68      * minimum possible value for the type, can be <code>null</code>
69      * as BigInteger doesn't have bounds
70      * @param max
71      * maximum possible value for the type, can be <code>null</code>
72      * as BigInteger doesn't have bounds
73      * @param boxedType
74      * a convenience that allows for the checking against one type
75      * rather than boxed and unboxed types
76      */

77     private StringToNumberConverter(NumberFormat numberFormat, Class JavaDoc toType,
78             Number JavaDoc min, Number JavaDoc max, Class JavaDoc boxedType) {
79         super(String JavaDoc.class, toType, numberFormat);
80
81         this.toType = toType;
82         this.numberFormat = numberFormat;
83         this.min = min;
84         this.max = max;
85         this.boxedType = boxedType;
86     }
87
88     /**
89      * Converts the provided <code>fromObject</code> to the requested
90      * {@link #getToType() to type}.
91      *
92      * @see org.eclipse.core.databinding.conversion.IConverter#convert(java.lang.Object)
93      * @throws IllegalArgumentException
94      * if the value isn't in the format required by the NumberFormat
95      * or the value is out of range for the
96      * {@link #getToType() to type}.
97      * @throws IllegalArgumentException
98      * if conversion was not possible
99      */

100     public Object JavaDoc convert(Object JavaDoc fromObject) {
101         ParseResult result = StringToNumberParser.parse(fromObject,
102                 numberFormat, toType.isPrimitive());
103
104         if (result.getPosition() != null) {
105             // this shouldn't happen in the pipeline as validation should catch
106
// it but anyone can call convert so we should return a properly
107
// formatted message in an exception
108
throw new IllegalArgumentException JavaDoc(StringToNumberParser
109                     .createParseErrorMessage((String JavaDoc) fromObject, result
110                             .getPosition()));
111         } else if (result.getNumber() == null) {
112             // if an error didn't occur and the number is null then it's a boxed
113
// type and null should be returned
114
return null;
115         }
116
117         /*
118          * Technically the checks for ranges aren't needed here because the
119          * validator should have validated this already but we shouldn't assume
120          * this has occurred.
121          */

122         if (Integer JavaDoc.class.equals(boxedType)) {
123             if (StringToNumberParser.inIntegerRange(result.getNumber())) {
124                 return new Integer JavaDoc(result.getNumber().intValue());
125             }
126         } else if (Double JavaDoc.class.equals(boxedType)) {
127             if (StringToNumberParser.inDoubleRange(result.getNumber())) {
128                 return new Double JavaDoc(result.getNumber().doubleValue());
129             }
130         } else if (Long JavaDoc.class.equals(boxedType)) {
131             if (StringToNumberParser.inLongRange(result.getNumber())) {
132                 return new Long JavaDoc(result.getNumber().longValue());
133             }
134         } else if (Float JavaDoc.class.equals(boxedType)) {
135             if (StringToNumberParser.inFloatRange(result.getNumber())) {
136                 return new Float JavaDoc(result.getNumber().floatValue());
137             }
138         } else if (BigInteger JavaDoc.class.equals(boxedType)) {
139             return new BigDecimal JavaDoc(result.getNumber().doubleValue())
140                     .toBigInteger();
141         }
142
143         if (min != null && max != null) {
144             throw new IllegalArgumentException JavaDoc(StringToNumberParser
145                     .createOutOfRangeMessage(min, max, numberFormat));
146         }
147
148         /*
149          * Fail safe. I don't think this could even be thrown but throwing the
150          * exception is better than returning null and hiding the error.
151          */

152         throw new IllegalArgumentException JavaDoc(
153                 "Could not convert [" + fromObject + "] to type [" + toType + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
154
}
155
156     /**
157      * @param primitive
158      * <code>true</code> if the convert to type is an int
159      * @return to Integer converter for the default locale
160      */

161     public static StringToNumberConverter toInteger(boolean primitive) {
162         return toInteger(NumberFormat.getIntegerInstance(), primitive);
163     }
164
165     /**
166      * @param numberFormat
167      * @param primitive
168      * @return to Integer converter with the provided numberFormat
169      */

170     public static StringToNumberConverter toInteger(NumberFormat numberFormat,
171             boolean primitive) {
172         return new StringToNumberConverter(numberFormat,
173                 (primitive) ? Integer.TYPE : Integer JavaDoc.class, MIN_INTEGER,
174                 MAX_INTEGER, Integer JavaDoc.class);
175     }
176
177     /**
178      * @param primitive
179      * <code>true</code> if the convert to type is a double
180      * @return to Double converter for the default locale
181      */

182     public static StringToNumberConverter toDouble(boolean primitive) {
183         return toDouble(NumberFormat.getNumberInstance(), primitive);
184     }
185
186     /**
187      * @param numberFormat
188      * @param primitive
189      * @return to Double converter with the provided numberFormat
190      */

191     public static StringToNumberConverter toDouble(NumberFormat numberFormat,
192             boolean primitive) {
193         return new StringToNumberConverter(numberFormat,
194                 (primitive) ? Double.TYPE : Double JavaDoc.class, MIN_DOUBLE,
195                 MAX_DOUBLE, Double JavaDoc.class);
196     }
197
198     /**
199      * @param primitive
200      * <code>true</code> if the convert to type is a long
201      * @return to Long converter for the default locale
202      */

203     public static StringToNumberConverter toLong(boolean primitive) {
204         return toLong(NumberFormat.getIntegerInstance(), primitive);
205     }
206
207     /**
208      * @param numberFormat
209      * @param primitive
210      * @return to Long converter with the provided numberFormat
211      */

212     public static StringToNumberConverter toLong(NumberFormat numberFormat,
213             boolean primitive) {
214         return new StringToNumberConverter(numberFormat,
215                 (primitive) ? Long.TYPE : Long JavaDoc.class, MIN_LONG, MAX_LONG,
216                 Long JavaDoc.class);
217     }
218
219     /**
220      * @param primitive
221      * <code>true</code> if the convert to type is a float
222      * @return to Float converter for the default locale
223      */

224     public static StringToNumberConverter toFloat(boolean primitive) {
225         return toFloat(NumberFormat.getNumberInstance(), primitive);
226     }
227
228     /**
229      * @param numberFormat
230      * @param primitive
231      * @return to Float converter with the provided numberFormat
232      */

233     public static StringToNumberConverter toFloat(NumberFormat numberFormat,
234             boolean primitive) {
235         return new StringToNumberConverter(numberFormat,
236                 (primitive) ? Float.TYPE : Float JavaDoc.class, MIN_FLOAT, MAX_FLOAT,
237                 Float JavaDoc.class);
238     }
239
240     /**
241      * @return to BigInteger converter for the default locale
242      */

243     public static StringToNumberConverter toBigInteger() {
244         return toBigInteger(NumberFormat.getIntegerInstance());
245     }
246
247     /**
248      * @param numberFormat
249      * @return to BigInteger converter with the provided numberFormat
250      */

251     public static StringToNumberConverter toBigInteger(NumberFormat numberFormat) {
252         return new StringToNumberConverter(numberFormat, BigInteger JavaDoc.class,
253                 null, null, BigInteger JavaDoc.class);
254     }
255 }
256
Popular Tags