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 }