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.DecimalFormat;
024 import java.text.NumberFormat;
025 import java.text.ParseException;
026 import java.util.Locale;
027 import java.util.TimeZone;
028
029 /** Number Converter classes. */
030 public class NumberConverters implements ConverterLoader {
031
032 protected static final Class<?>[] classArray = {BigDecimal.class, BigInteger.class, Byte.class, Double.class, Integer.class, Float.class, Long.class, Short.class};
033
034 protected static Number fromString(String str, NumberFormat nf) throws ConversionException {
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 /**
066 * An abstract <code>Number</code> to <code>String</code> converter class
067 * that implements some of the <code>LocalizedConverter</code> methods.
068 */
069 public static abstract class AbstractNumberToStringConverter<N extends Number> extends AbstractLocalizedConverter<N, String> {
070 public AbstractNumberToStringConverter(Class<N> sourceClass) {
071 super(sourceClass, String.class);
072 }
073
074 public String convert(N obj) throws ConversionException {
075 return obj.toString();
076 }
077
078 public String convert(N obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException {
079 if (formatString == null) {
080 return format(obj, NumberFormat.getNumberInstance(locale));
081 } else {
082 return format(obj, new DecimalFormat(formatString));
083 }
084 }
085
086 protected abstract String format(N obj, NumberFormat nf) throws ConversionException;
087 }
088
089 /**
090 * An abstract <code>String</code> to <code>Number</code> converter class
091 * that implements some of the <code>LocalizedConverter</code> methods.
092 */
093 public static abstract class AbstractStringToNumberConverter<N extends Number> extends AbstractLocalizedConverter<String, N> {
094 public AbstractStringToNumberConverter(Class<N> targetClass) {
095 super(String.class, targetClass);
096 }
097
098 protected abstract N convert(Number number) throws ConversionException;
099
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 }