001 /*******************************************************************************
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *******************************************************************************/
019 package org.apache.commons.convert;
020
021 import java.math.BigDecimal;
022 import java.math.BigInteger;
023 import java.text.NumberFormat;
024 import java.text.ParseException;
025 import java.util.Locale;
026 import java.util.TimeZone;
027
028 /** Number Converter classes. */
029 public class NumberConverters implements ConverterLoader {
030
031 protected static final Class<?>[] classArray = {BigDecimal.class, BigInteger.class, Byte.class, Double.class, Integer.class, Float.class, Long.class, Short.class};
032
033 protected static Number fromString(String str, Locale locale) throws ConversionException {
034 NumberFormat nf = NumberFormat.getNumberInstance(locale);
035 try {
036 return nf.parse(str);
037 } catch (ParseException e) {
038 throw new ConversionException(e);
039 }
040 }
041
042 protected static <S, T> void registerConverter(Converter<S, T> converter) {
043 if (converter.getSourceClass() != converter.getTargetClass()) {
044 Converters.registerConverter(converter);
045 }
046 }
047
048 @SuppressWarnings("unchecked")
049 public void loadConverters() {
050 Converters.loadContainedConverters(NumberConverters.class);
051 for (Class<?> sourceClass : classArray) {
052 registerConverter(new GenericNumberToBigDecimal(sourceClass));
053 registerConverter(new GenericNumberToBigInteger(sourceClass));
054 registerConverter(new GenericNumberToByte(sourceClass));
055 registerConverter(new GenericNumberToDouble(sourceClass));
056 registerConverter(new GenericNumberToInteger(sourceClass));
057 registerConverter(new GenericNumberToFloat(sourceClass));
058 registerConverter(new GenericNumberToLong(sourceClass));
059 registerConverter(new GenericNumberToShort(sourceClass));
060 registerConverter(new GenericSingletonToList(sourceClass));
061 registerConverter(new GenericSingletonToSet(sourceClass));
062 }
063 }
064
065 public static abstract class AbstractNumberConverter<S, T> extends AbstractLocalizedConverter<S, T> {
066 protected AbstractNumberConverter(Class<S> sourceClass, Class<T> targetClass) {
067 super(sourceClass, targetClass);
068 }
069
070 public T convert(S obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException {
071 return convert(obj, locale, null);
072 }
073 }
074
075 /**
076 * An abstract <code>Number</code> to <code>String</code> converter class
077 * that implements some of the <code>LocalizedConverter</code> methods.
078 */
079 public static abstract class AbstractNumberToStringConverter<N extends Number> extends AbstractNumberConverter<N, String> {
080 public AbstractNumberToStringConverter(Class<N> sourceClass) {
081 super(sourceClass, String.class);
082 }
083
084 public String convert(N obj) throws ConversionException {
085 return obj.toString();
086 }
087
088 public String convert(N obj, Locale locale, TimeZone timeZone) throws ConversionException {
089 return format(obj, NumberFormat.getNumberInstance(locale));
090 }
091
092 protected abstract String format(N obj, NumberFormat nf) throws ConversionException;
093 }
094
095 /**
096 * An abstract <code>String</code> to <code>Number</code> converter class
097 * that implements some of the <code>LocalizedConverter</code> methods.
098 */
099 public static abstract class AbstractStringToNumberConverter<N extends Number> extends AbstractNumberConverter<String, N> {
100 public AbstractStringToNumberConverter(Class<N> targetClass) {
101 super(String.class, targetClass);
102 }
103
104 protected abstract N convert(Number number) throws ConversionException;
105
106 public N convert(String obj, Locale locale, TimeZone timeZone) throws ConversionException {
107 return convert(fromString(obj, locale));
108 }
109 }
110
111 /**
112 * An object that converts a <code>BigDecimal</code> to a
113 * <code>String</code>.
114 */
115 public static class BigDecimalToString extends AbstractNumberToStringConverter<BigDecimal> {
116 public BigDecimalToString() {
117 super(BigDecimal.class);
118 }
119
120 protected String format(BigDecimal obj, NumberFormat nf) throws ConversionException {
121 return nf.format(obj.doubleValue());
122 }
123 }
124
125 /**
126 * An object that converts a <code>BigInteger</code> to a
127 * <code>String</code>.
128 */
129 public static class BigIntegerToString extends AbstractNumberToStringConverter<BigInteger> {
130 public BigIntegerToString() {
131 super(BigInteger.class);
132 }
133
134 protected String format(BigInteger obj, NumberFormat nf) throws ConversionException {
135 return nf.format(obj.doubleValue());
136 }
137 }
138
139 /**
140 * An object that converts a <code>Byte</code> to a
141 * <code>String</code>.
142 */
143 public static class ByteToString extends AbstractNumberToStringConverter<Byte> {
144 public ByteToString() {
145 super(Byte.class);
146 }
147
148 protected String format(Byte obj, NumberFormat nf) throws ConversionException {
149 return nf.format(obj.floatValue());
150 }
151 }
152
153 /**
154 * An object that converts a <code>Double</code> to a
155 * <code>String</code>.
156 */
157 public static class DoubleToString extends AbstractNumberToStringConverter<Double> {
158 public DoubleToString() {
159 super(Double.class);
160 }
161
162 protected String format(Double obj, NumberFormat nf) throws ConversionException {
163 return nf.format(obj.doubleValue());
164 }
165 }
166
167 /**
168 * An object that converts a <code>Float</code> to a
169 * <code>String</code>.
170 */
171 public static class FloatToString extends AbstractNumberToStringConverter<Float> {
172 public FloatToString() {
173 super(Float.class);
174 }
175
176 protected String format(Float obj, NumberFormat nf) throws ConversionException {
177 return nf.format(obj.floatValue());
178 }
179 }
180
181 /**
182 * An object that converts a <code>Number</code> to a
183 * <code>BigDecimal</code>.
184 */
185 public static class GenericNumberToBigDecimal<N extends Number> extends AbstractConverter<N, BigDecimal> {
186 public GenericNumberToBigDecimal(Class<N> sourceClass) {
187 super(sourceClass, BigDecimal.class);
188 }
189
190 public BigDecimal convert(N obj) throws ConversionException {
191 return new BigDecimal(obj.doubleValue());
192 }
193 }
194
195 /**
196 * An object that converts a <code>Number</code> to a
197 * <code>BigInteger</code>.
198 */
199 public static class GenericNumberToBigInteger<N extends Number> extends AbstractConverter<N, BigInteger> {
200 public GenericNumberToBigInteger(Class<N> sourceClass) {
201 super(sourceClass, BigInteger.class);
202 }
203
204 public BigInteger convert(N obj) throws ConversionException {
205 return BigInteger.valueOf(obj.longValue());
206 }
207 }
208
209 /**
210 * An object that converts a <code>Number</code> to a
211 * <code>Byte</code>.
212 */
213 public static class GenericNumberToByte<N extends Number> extends AbstractConverter<N, Byte> {
214 public GenericNumberToByte(Class<N> sourceClass) {
215 super(sourceClass, Byte.class);
216 }
217
218 public Byte convert(N obj) throws ConversionException {
219 return Byte.valueOf(obj.byteValue());
220 }
221 }
222
223 /**
224 * An object that converts a <code>Number</code> to a
225 * <code>Double</code>.
226 */
227 public static class GenericNumberToDouble<N extends Number> extends AbstractConverter<N, Double> {
228 public GenericNumberToDouble(Class<N> sourceClass) {
229 super(sourceClass, Double.class);
230 }
231
232 public Double convert(N obj) throws ConversionException {
233 return obj.doubleValue();
234 }
235 }
236
237 /**
238 * An object that converts a <code>Number</code> to a
239 * <code>Float</code>.
240 */
241 public static class GenericNumberToFloat<N extends Number> extends AbstractConverter<N, Float> {
242 public GenericNumberToFloat(Class<N> sourceClass) {
243 super(sourceClass, Float.class);
244 }
245
246 public Float convert(N obj) throws ConversionException {
247 return obj.floatValue();
248 }
249 }
250
251 /**
252 * An object that converts a <code>Number</code> to an
253 * <code>Integer</code>.
254 */
255 public static class GenericNumberToInteger<N extends Number> extends AbstractConverter<N, Integer> {
256 public GenericNumberToInteger(Class<N> sourceClass) {
257 super(sourceClass, Integer.class);
258 }
259
260 public Integer convert(N obj) throws ConversionException {
261 return obj.intValue();
262 }
263 }
264
265 /**
266 * An object that converts a <code>Number</code> to a
267 * <code>Long</code>.
268 */
269 public static class GenericNumberToLong<N extends Number> extends AbstractConverter<N, Long> {
270 public GenericNumberToLong(Class<N> sourceClass) {
271 super(sourceClass, Long.class);
272 }
273
274 public Long convert(N obj) throws ConversionException {
275 return obj.longValue();
276 }
277 }
278
279 /**
280 * An object that converts a <code>Number</code> to a
281 * <code>Short</code>.
282 */
283 public static class GenericNumberToShort<N extends Number> extends AbstractConverter<N, Short> {
284 public GenericNumberToShort(Class<N> sourceClass) {
285 super(sourceClass, Short.class);
286 }
287
288 public Short convert(N obj) throws ConversionException {
289 return obj.shortValue();
290 }
291 }
292
293 /**
294 * An object that converts an <code>Integer</code> to a
295 * <code>String</code>.
296 */
297 public static class IntegerToString extends AbstractNumberToStringConverter<Integer> {
298 public IntegerToString() {
299 super(Integer.class);
300 }
301
302 protected String format(Integer obj, NumberFormat nf) throws ConversionException {
303 return nf.format(obj.intValue());
304 }
305 }
306
307 /**
308 * An object that converts a <code>Long</code> to a
309 * <code>BigDecimal</code>.
310 */
311 public static class LongToBigDecimal extends AbstractConverter<Long, BigDecimal> {
312 public LongToBigDecimal() {
313 super(Long.class, BigDecimal.class);
314 }
315
316 public BigDecimal convert(Long obj) throws ConversionException {
317 return BigDecimal.valueOf(obj.longValue());
318 }
319 }
320
321 /**
322 * An object that converts a <code>Long</code> to a
323 * <code>String</code>.
324 */
325 public static class LongToString extends AbstractNumberToStringConverter<Long> {
326 public LongToString() {
327 super(Long.class);
328 }
329
330 protected String format(Long obj, NumberFormat nf) throws ConversionException {
331 return nf.format(obj.longValue());
332 }
333 }
334
335 /**
336 * An object that converts a <code>Short</code> to a
337 * <code>String</code>.
338 */
339 public static class ShortToString extends AbstractNumberToStringConverter<Short> {
340 public ShortToString() {
341 super(Short.class);
342 }
343
344 protected String format(Short obj, NumberFormat nf) throws ConversionException {
345 return nf.format(obj.floatValue());
346 }
347 }
348
349 /**
350 * An object that converts a <code>String</code> to a
351 * <code>BigDecimal</code>.
352 */
353 public static class StringToBigDecimal extends AbstractStringToNumberConverter<BigDecimal> {
354 public StringToBigDecimal() {
355 super(BigDecimal.class);
356 }
357
358 protected BigDecimal convert(Number number) throws ConversionException {
359 return BigDecimal.valueOf(number.doubleValue());
360 }
361
362 public BigDecimal convert(String obj) throws ConversionException {
363 return BigDecimal.valueOf(Double.valueOf(obj));
364 }
365 }
366
367 /**
368 * An object that converts a <code>String</code> to a
369 * <code>BigInteger</code>.
370 */
371 public static class StringToBigInteger extends AbstractStringToNumberConverter<BigInteger> {
372 public StringToBigInteger() {
373 super(BigInteger.class);
374 }
375
376 protected BigInteger convert(Number number) throws ConversionException {
377 return BigInteger.valueOf(number.longValue());
378 }
379
380 public BigInteger convert(String obj) throws ConversionException {
381 return new BigInteger(obj);
382 }
383 }
384
385 /**
386 * An object that converts a <code>String</code> to a
387 * <code>Byte</code>.
388 */
389 public static class StringToByte extends AbstractConverter<String, Byte> {
390 public StringToByte() {
391 super(String.class, Byte.class);
392 }
393
394 public Byte convert(String obj) throws ConversionException {
395 return Byte.valueOf(obj);
396 }
397 }
398
399 /**
400 * An object that converts a <code>String</code> to a
401 * <code>Double</code>.
402 */
403 public static class StringToDouble extends AbstractStringToNumberConverter<Double> {
404 public StringToDouble() {
405 super(Double.class);
406 }
407
408 protected Double convert(Number number) throws ConversionException {
409 return number.doubleValue();
410 }
411
412 public Double convert(String obj) throws ConversionException {
413 return Double.valueOf(obj);
414 }
415 }
416
417 /**
418 * An object that converts a <code>String</code> to a
419 * <code>Float</code>.
420 */
421 public static class StringToFloat extends AbstractStringToNumberConverter<Float> {
422 public StringToFloat() {
423 super(Float.class);
424 }
425
426 protected Float convert(Number number) throws ConversionException {
427 return number.floatValue();
428 }
429
430 public Float convert(String obj) throws ConversionException {
431 return Float.valueOf(obj);
432 }
433 }
434
435 /**
436 * An object that converts a <code>String</code> to an
437 * <code>Integer</code>.
438 */
439 public static class StringToInteger extends AbstractStringToNumberConverter<Integer> {
440 public StringToInteger() {
441 super(Integer.class);
442 }
443
444 protected Integer convert(Number number) throws ConversionException {
445 return number.intValue();
446 }
447
448 public Integer convert(String obj) throws ConversionException {
449 return Integer.valueOf(obj);
450 }
451 }
452
453 /**
454 * An object that converts a <code>String</code> to a
455 * <code>Long</code>.
456 */
457 public static class StringToLong extends AbstractStringToNumberConverter<Long> {
458 public StringToLong() {
459 super(Long.class);
460 }
461
462 protected Long convert(Number number) throws ConversionException {
463 return number.longValue();
464 }
465
466 public Long convert(String obj) throws ConversionException {
467 return Long.valueOf(obj);
468 }
469 }
470
471 /**
472 * An object that converts a <code>String</code> to a
473 * <code>Short</code>.
474 */
475 public static class StringToShort extends AbstractConverter<String, Short> {
476 public StringToShort() {
477 super(String.class, Short.class);
478 }
479
480 public Short convert(String obj) throws ConversionException {
481 return Short.valueOf(obj);
482 }
483 }
484 }