View Javadoc

1   /*******************************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   *******************************************************************************/
19  package org.apache.commons.convert;
20  
21  import java.math.BigDecimal;
22  import java.math.BigInteger;
23  import java.text.DecimalFormat;
24  import java.text.NumberFormat;
25  import java.text.ParseException;
26  import java.util.Locale;
27  import java.util.TimeZone;
28  
29  /** Number Converter classes. */
30  public class NumberConverters implements ConverterLoader {
31  
32      protected static final Class<?>[] classArray = {BigDecimal.class, BigInteger.class, Byte.class, Double.class, Integer.class, Float.class, Long.class, Short.class};
33  
34      protected static Number fromString(String str, NumberFormat nf) throws ConversionException {
35          try {
36              return nf.parse(str);
37          } catch (ParseException e) {
38              throw new ConversionException(e);
39          }
40      }
41  
42      protected static <S, T> void registerConverter(Converter<S, T> converter) {
43          if (converter.getSourceClass() != converter.getTargetClass()) {
44              Converters.registerConverter(converter);
45          }
46      }
47  
48      @SuppressWarnings("unchecked")
49      public void loadConverters() {
50          Converters.loadContainedConverters(NumberConverters.class);
51          for (Class<?> sourceClass : classArray) {
52              registerConverter(new GenericNumberToBigDecimal(sourceClass));
53              registerConverter(new GenericNumberToBigInteger(sourceClass));
54              registerConverter(new GenericNumberToByte(sourceClass));
55              registerConverter(new GenericNumberToDouble(sourceClass));
56              registerConverter(new GenericNumberToInteger(sourceClass));
57              registerConverter(new GenericNumberToFloat(sourceClass));
58              registerConverter(new GenericNumberToLong(sourceClass));
59              registerConverter(new GenericNumberToShort(sourceClass));
60              registerConverter(new GenericSingletonToList(sourceClass));
61              registerConverter(new GenericSingletonToSet(sourceClass));
62          }
63      }
64  
65      /**
66       * An abstract <code>Number</code> to <code>String</code> converter class
67       * that implements some of the <code>LocalizedConverter</code> methods. 
68       */
69      public static abstract class AbstractNumberToStringConverter<N extends Number> extends AbstractLocalizedConverter<N, String> {
70          public AbstractNumberToStringConverter(Class<N> sourceClass) {
71              super(sourceClass, String.class);
72          }
73  
74          public String convert(N obj) throws ConversionException {
75              return obj.toString();
76          }
77  
78          public String convert(N obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException {
79              if (formatString == null) {
80                  return format(obj, NumberFormat.getNumberInstance(locale));
81              } else {
82                  return format(obj, new DecimalFormat(formatString));
83              }
84          }
85  
86          protected abstract String format(N obj, NumberFormat nf) throws ConversionException;
87      }
88  
89      /**
90       * An abstract <code>String</code> to <code>Number</code> converter class
91       * that implements some of the <code>LocalizedConverter</code> methods. 
92       */
93      public static abstract class AbstractStringToNumberConverter<N extends Number> extends AbstractLocalizedConverter<String, N> {
94          public AbstractStringToNumberConverter(Class<N> targetClass) {
95              super(String.class, targetClass);
96          }
97  
98          protected abstract N convert(Number number) throws ConversionException;
99  
100         public N convert(String obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException {
101             if (formatString == null) {
102                 return convert(fromString(obj, NumberFormat.getNumberInstance(locale)));
103             } else {
104                 return convert(fromString(obj, new DecimalFormat(formatString)));
105             }
106         }
107     }
108 
109     /**
110      * An object that converts a <code>BigDecimal</code> to a
111      * <code>String</code>.
112      */
113     public static class BigDecimalToString extends AbstractNumberToStringConverter<BigDecimal> {
114         public BigDecimalToString() {
115             super(BigDecimal.class);
116         }
117 
118         protected String format(BigDecimal obj, NumberFormat nf) throws ConversionException {
119             return nf.format(obj.doubleValue());
120         }
121     }
122 
123     /**
124      * An object that converts a <code>BigInteger</code> to a
125      * <code>String</code>.
126      */
127     public static class BigIntegerToString extends AbstractNumberToStringConverter<BigInteger> {
128         public BigIntegerToString() {
129             super(BigInteger.class);
130         }
131 
132         protected String format(BigInteger obj, NumberFormat nf) throws ConversionException {
133             return nf.format(obj.doubleValue());
134         }
135     }
136 
137     /**
138      * An object that converts a <code>Byte</code> to a
139      * <code>String</code>.
140      */
141     public static class ByteToString extends AbstractNumberToStringConverter<Byte> {
142         public ByteToString() {
143             super(Byte.class);
144         }
145 
146         protected String format(Byte obj, NumberFormat nf) throws ConversionException {
147             return nf.format(obj.floatValue());
148         }
149     }
150 
151     /**
152      * An object that converts a <code>Double</code> to a
153      * <code>String</code>.
154      */
155     public static class DoubleToString extends AbstractNumberToStringConverter<Double> {
156         public DoubleToString() {
157             super(Double.class);
158         }
159 
160         protected String format(Double obj, NumberFormat nf) throws ConversionException {
161             return nf.format(obj.doubleValue());
162         }
163     }
164 
165     /**
166      * An object that converts a <code>Float</code> to a
167      * <code>String</code>.
168      */
169     public static class FloatToString extends AbstractNumberToStringConverter<Float> {
170         public FloatToString() {
171             super(Float.class);
172         }
173 
174         protected String format(Float obj, NumberFormat nf) throws ConversionException {
175             return nf.format(obj.floatValue());
176         }
177     }
178 
179     /**
180      * An object that converts a <code>Number</code> to a
181      * <code>BigDecimal</code>.
182      */
183     public static class GenericNumberToBigDecimal<N extends Number> extends AbstractConverter<N, BigDecimal> {
184         public GenericNumberToBigDecimal(Class<N> sourceClass) {
185             super(sourceClass, BigDecimal.class);
186         }
187 
188         public BigDecimal convert(N obj) throws ConversionException {
189             return new BigDecimal(obj.doubleValue());
190         }
191     }
192 
193     /**
194      * An object that converts a <code>Number</code> to a
195      * <code>BigInteger</code>.
196      */
197     public static class GenericNumberToBigInteger<N extends Number> extends AbstractConverter<N, BigInteger> {
198         public GenericNumberToBigInteger(Class<N> sourceClass) {
199             super(sourceClass, BigInteger.class);
200         }
201 
202         public BigInteger convert(N obj) throws ConversionException {
203             return BigInteger.valueOf(obj.longValue());
204         }
205     }
206 
207     /**
208      * An object that converts a <code>Number</code> to a
209      * <code>Byte</code>.
210      */
211     public static class GenericNumberToByte<N extends Number> extends AbstractConverter<N, Byte> {
212         public GenericNumberToByte(Class<N> sourceClass) {
213             super(sourceClass, Byte.class);
214         }
215 
216         public Byte convert(N obj) throws ConversionException {
217             return Byte.valueOf(obj.byteValue());
218         }
219     }
220 
221     /**
222      * An object that converts a <code>Number</code> to a
223      * <code>Double</code>.
224      */
225     public static class GenericNumberToDouble<N extends Number> extends AbstractConverter<N, Double> {
226         public GenericNumberToDouble(Class<N> sourceClass) {
227             super(sourceClass, Double.class);
228         }
229 
230         public Double convert(N obj) throws ConversionException {
231             return obj.doubleValue();
232         }
233     }
234 
235     /**
236      * An object that converts a <code>Number</code> to a
237      * <code>Float</code>.
238      */
239     public static class GenericNumberToFloat<N extends Number> extends AbstractConverter<N, Float> {
240         public GenericNumberToFloat(Class<N> sourceClass) {
241             super(sourceClass, Float.class);
242         }
243 
244         public Float convert(N obj) throws ConversionException {
245             return obj.floatValue();
246         }
247     }
248 
249     /**
250      * An object that converts a <code>Number</code> to an
251      * <code>Integer</code>.
252      */
253     public static class GenericNumberToInteger<N extends Number> extends AbstractConverter<N, Integer> {
254         public GenericNumberToInteger(Class<N> sourceClass) {
255             super(sourceClass, Integer.class);
256         }
257 
258         public Integer convert(N obj) throws ConversionException {
259             return obj.intValue();
260         }
261     }
262 
263     /**
264      * An object that converts a <code>Number</code> to a
265      * <code>Long</code>.
266      */
267     public static class GenericNumberToLong<N extends Number> extends AbstractConverter<N, Long> {
268         public GenericNumberToLong(Class<N> sourceClass) {
269             super(sourceClass, Long.class);
270         }
271 
272         public Long convert(N obj) throws ConversionException {
273             return obj.longValue();
274         }
275     }
276 
277     /**
278      * An object that converts a <code>Number</code> to a
279      * <code>Short</code>.
280      */
281     public static class GenericNumberToShort<N extends Number> extends AbstractConverter<N, Short> {
282         public GenericNumberToShort(Class<N> sourceClass) {
283             super(sourceClass, Short.class);
284         }
285 
286         public Short convert(N obj) throws ConversionException {
287             return obj.shortValue();
288         }
289     }
290 
291     /**
292      * An object that converts an <code>Integer</code> to a
293      * <code>String</code>.
294      */
295     public static class IntegerToString extends AbstractNumberToStringConverter<Integer> {
296         public IntegerToString() {
297             super(Integer.class);
298         }
299 
300         protected String format(Integer obj, NumberFormat nf) throws ConversionException {
301             return nf.format(obj.intValue());
302         }
303     }
304 
305     /**
306      * An object that converts a <code>Long</code> to a
307      * <code>BigDecimal</code>.
308      */
309     public static class LongToBigDecimal extends AbstractConverter<Long, BigDecimal> {
310         public LongToBigDecimal() {
311             super(Long.class, BigDecimal.class);
312         }
313 
314         public BigDecimal convert(Long obj) throws ConversionException {
315             return BigDecimal.valueOf(obj.longValue());
316         }
317     }
318 
319     /**
320      * An object that converts a <code>Long</code> to a
321      * <code>String</code>.
322      */
323     public static class LongToString extends AbstractNumberToStringConverter<Long> {
324         public LongToString() {
325             super(Long.class);
326         }
327 
328         protected String format(Long obj, NumberFormat nf) throws ConversionException {
329             return nf.format(obj.longValue());
330         }
331     }
332 
333     /**
334      * An object that converts a <code>Short</code> to a
335      * <code>String</code>.
336      */
337     public static class ShortToString extends AbstractNumberToStringConverter<Short> {
338         public ShortToString() {
339             super(Short.class);
340         }
341 
342         protected String format(Short obj, NumberFormat nf) throws ConversionException {
343             return nf.format(obj.floatValue());
344         }
345     }
346 
347     /**
348      * An object that converts a <code>String</code> to a
349      * <code>BigDecimal</code>.
350      */
351     public static class StringToBigDecimal extends AbstractStringToNumberConverter<BigDecimal> {
352         public StringToBigDecimal() {
353             super(BigDecimal.class);
354         }
355 
356         protected BigDecimal convert(Number number) throws ConversionException {
357             return BigDecimal.valueOf(number.doubleValue());
358         }
359 
360         public BigDecimal convert(String obj) throws ConversionException {
361             return BigDecimal.valueOf(Double.valueOf(obj));
362         }
363     }
364 
365     /**
366      * An object that converts a <code>String</code> to a
367      * <code>BigInteger</code>.
368      */
369     public static class StringToBigInteger extends AbstractStringToNumberConverter<BigInteger> {
370         public StringToBigInteger() {
371             super(BigInteger.class);
372         }
373 
374         protected BigInteger convert(Number number) throws ConversionException {
375             return BigInteger.valueOf(number.longValue());
376         }
377 
378         public BigInteger convert(String obj) throws ConversionException {
379             return new BigInteger(obj);
380         }
381     }
382 
383     /**
384      * An object that converts a <code>String</code> to a
385      * <code>Byte</code>.
386      */
387     public static class StringToByte extends AbstractConverter<String, Byte> {
388         public StringToByte() {
389             super(String.class, Byte.class);
390         }
391 
392         public Byte convert(String obj) throws ConversionException {
393             return Byte.valueOf(obj);
394         }
395     }
396 
397     /**
398      * An object that converts a <code>String</code> to a
399      * <code>Double</code>.
400      */
401     public static class StringToDouble extends AbstractStringToNumberConverter<Double> {
402         public StringToDouble() {
403             super(Double.class);
404         }
405 
406         protected Double convert(Number number) throws ConversionException {
407             return number.doubleValue();
408         }
409 
410         public Double convert(String obj) throws ConversionException {
411             return Double.valueOf(obj);
412         }
413     }
414 
415     /**
416      * An object that converts a <code>String</code> to a
417      * <code>Float</code>.
418      */
419     public static class StringToFloat extends AbstractStringToNumberConverter<Float> {
420         public StringToFloat() {
421             super(Float.class);
422         }
423 
424         protected Float convert(Number number) throws ConversionException {
425             return number.floatValue();
426         }
427 
428         public Float convert(String obj) throws ConversionException {
429             return Float.valueOf(obj);
430         }
431     }
432 
433     /**
434      * An object that converts a <code>String</code> to an
435      * <code>Integer</code>.
436      */
437     public static class StringToInteger extends AbstractStringToNumberConverter<Integer> {
438         public StringToInteger() {
439             super(Integer.class);
440         }
441 
442         protected Integer convert(Number number) throws ConversionException {
443             return number.intValue();
444         }
445 
446         public Integer convert(String obj) throws ConversionException {
447             return Integer.valueOf(obj);
448         }
449     }
450 
451     /**
452      * An object that converts a <code>String</code> to a
453      * <code>Long</code>.
454      */
455     public static class StringToLong extends AbstractStringToNumberConverter<Long> {
456         public StringToLong() {
457             super(Long.class);
458         }
459 
460         protected Long convert(Number number) throws ConversionException {
461             return number.longValue();
462         }
463 
464         public Long convert(String obj) throws ConversionException {
465             return Long.valueOf(obj);
466         }
467     }
468 
469     /**
470      * An object that converts a <code>String</code> to a
471      * <code>Short</code>.
472      */
473     public static class StringToShort extends AbstractConverter<String, Short> {
474         public StringToShort() {
475             super(String.class, Short.class);
476         }
477 
478         public Short convert(String obj) throws ConversionException {
479             return Short.valueOf(obj);
480         }
481     }
482 }