All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bbottema.javareflection.valueconverter.converters.NumberConverters Maven / Gradle / Ivy

/*
 * Copyright (C) 2011 Benny Bottema ([email protected])
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.bbottema.javareflection.valueconverter.converters;

import lombok.experimental.UtilityClass;
import org.bbottema.javareflection.util.Function;
import org.bbottema.javareflection.util.Function.Functions;
import org.bbottema.javareflection.valueconverter.ValueFunction;
import org.bbottema.javareflection.valueconverter.ValueFunction.ValueFunctionImpl;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import static org.bbottema.javareflection.util.MiscUtil.newArrayList;

/**
 * Generates converters for all numbers to all other numbers, by virtue of Number's own interface that forces all subclasses to implement basic
 * conversions to common other Number classes.
 * 

* Attempts to convert a {@link Number} to the target datatype. *

* NOTE: precision may be lost when converting from a wide number to a narrower number (say float to integer). These * conversions are done by simply calling {@link Number#intValue()} and {@link Number#floatValue()} etc. *

* Conversions are as follows: *

    *
  1. String: value.toString()
  2. *
  3. Integer: value.intValue()
  4. *
  5. Boolean: value.intValue() > 0
  6. *
  7. Float: value.floatValue()
  8. *
  9. Double: value.doubleValue()
  10. *
  11. Long: value.longValue()
  12. *
  13. Byte: value.byteValue()
  14. *
  15. Short: value.shortValue()
  16. *
  17. Character: Character.forDigit(value, 10) ({@link Character#forDigit(int, int)})
  18. *
*/ @UtilityClass public class NumberConverters { private static final List> CONVERTABLE_NUMBER_FROM_CLASSES_JDK7 = newArrayList(Number.class, AtomicInteger.class, AtomicLong.class, BigDecimal.class, BigInteger.class, byte.class, Byte.class, double.class, Double.class, float.class, Float.class, int.class, Integer.class, long.class, Long.class, short.class, Short.class); private static final Map, Function> CONVERTERS_BY_TARGET_TYPE = new HashMap, Function>() {{ put(Number.class, new NumberDoubleFunction()); put(Integer.class, new NumberIntegerFunction()); put(int.class, new NumberIntegerFunction()); put(Boolean.class, new NumberBooleanFunction()); put(boolean.class, new NumberBooleanFunction()); put(Float.class, new NumberFloatFunction()); put(float.class, new NumberFloatFunction()); put(Double.class, new NumberDoubleFunction()); put(double.class, new NumberDoubleFunction()); put(Long.class, new NumberLongFunction()); put(long.class, new NumberLongFunction()); put(Byte.class, new NumberByteFunction()); put(byte.class, new NumberByteFunction()); put(Short.class, new NumberShortFunction()); put(short.class, new NumberShortFunction()); put(Character.class, new NumberCharacterFunction()); put(char.class, new NumberCharacterFunction()); put(String.class, Functions.simpleToString()); }}; public static final Collection> NUMBER_CONVERTERS = produceNumberConverters(); @SuppressWarnings("unchecked") private static Collection> produceNumberConverters() { ArrayList> valueFunctions = new ArrayList<>(); for (Class numberFromClass : CONVERTABLE_NUMBER_FROM_CLASSES_JDK7) { for (Map.Entry, Function> targetClassConverter : CONVERTERS_BY_TARGET_TYPE.entrySet()) { Class targetClass = targetClassConverter.getKey(); Function converter = (numberFromClass == targetClass || targetClass.isAssignableFrom(numberFromClass)) ? Functions.identity() : targetClassConverter.getValue(); valueFunctions.add(new ValueFunctionImpl(numberFromClass, targetClass, converter)); } } return valueFunctions; } public static class NumberIntegerFunction implements Function { public Integer apply(Number value) { return value.intValue(); } } public static class NumberBooleanFunction implements Function { public Boolean apply(Number value) { return value.intValue() > 0; } } public static class NumberFloatFunction implements Function { public Float apply(Number value) { return value.floatValue(); } } public static class NumberDoubleFunction implements Function { public Double apply(Number value) { return value.doubleValue(); } } public static class NumberLongFunction implements Function { public Long apply(Number value) { return value.longValue(); } } public static class NumberByteFunction implements Function { public Byte apply(Number value) { return value.byteValue(); } } public static class NumberShortFunction implements Function { public Short apply(Number value) { return value.shortValue(); } } public static class NumberCharacterFunction implements Function { public Character apply(Number value) { return Character.forDigit(value.intValue(), 10); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy