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

org.zodiac.fastorm.rdb.codec.NumberValueCodec Maven / Gradle / Ivy

The newest version!
package org.zodiac.fastorm.rdb.codec;

import org.zodiac.commons.util.time.DateFormatter;
import org.zodiac.fastorm.core.ValueCodec;
import org.zodiac.fastorm.rdb.executor.NullValue;
import org.zodiac.sdk.toolkit.util.lang.ObjUtil;

import java.lang.reflect.Constructor;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.function.Function;

public class NumberValueCodec implements ValueCodec {

    private final Function converter;

    public NumberValueCodec(Function converter) {
        this.converter = converter;
    }

    public NumberValueCodec(Class javaType) {
        if (javaType == int.class || javaType == Integer.class) {
            converter = Number::intValue;
        } else if (javaType == double.class || javaType == Double.class) {
            converter = Number::doubleValue;
        } else if (javaType == float.class || javaType == Float.class) {
            converter = Number::floatValue;
        } else if (javaType == long.class || javaType == Long.class) {
            converter = Number::longValue;
        } else if (javaType == byte.class || javaType == Byte.class) {
            converter = Number::byteValue;
        } else if (javaType == short.class || javaType == Short.class) {
            converter = Number::shortValue;
        } else if (javaType == boolean.class || javaType == Boolean.class) {
            converter = num -> num.byteValue() != 0;
        } else if (javaType == BigDecimal.class) {
            converter = num -> {
                if (num instanceof BigDecimal) {
                    return (BigDecimal) num;
                } else {
                    return new BigDecimal(num.toString());
                }
            };
        } else if (javaType == BigInteger.class) {
            converter = num -> {
                if (num instanceof BigInteger) {
                    return (BigInteger) num;
                } else if (num instanceof BigDecimal) {
                    return ((BigDecimal) num).toBigInteger();
                } else {
                    return new BigInteger(num.toString());
                }
            };
        } else if (Date.class.isAssignableFrom(javaType)) {
            try {
                Constructor constructor = javaType.getConstructor();
                converter = num -> {
                    try {
                        Date date = (Date) constructor.newInstance();
                        date.setTime(num.longValue());
                        return date;
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                };
            } catch (NoSuchMethodException | SecurityException e) {
                throw new RuntimeException(e);
            }
        } else {
            converter = num -> num;
        }
    }

    @Override
    public Object encode(Object value) {
        //if (StringUtils.isNullOrEmpty(value)) {
        if (ObjUtil.isEmpty(value)) {
            return null;
        }
        return tryCastNumber(value);
    }

    @Override
    public Object decode(Object data) {
        return tryCastNumber(data);
    }

    private Object tryCastNumber(Object value) {
        if (null == value) {
            return null;
        }

        if (value instanceof NullValue) {
            return value;
        }

        if (value instanceof Date) {
            value = ((Date) value).getTime();
        } else if (value instanceof LocalDateTime) {
            value = ((LocalDateTime) value).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        } else if (value instanceof ZonedDateTime) {
            value = ((ZonedDateTime) value).toInstant().toEpochMilli();
        } else if (value instanceof String) {
            if (org.apache.commons.lang3.StringUtils.isNumeric(String.valueOf(value))) {
                value = new BigDecimal(String.valueOf(value));
            } else {
                /*Attempt to convert the date in character format.*/
                Date date = DateFormatter.fromString(String.valueOf(value));
                if (null != date) {
                    value = date.getTime();
                }else {
                    value = new BigDecimal(String.valueOf(value));
                }
            }
        }

        if (value instanceof Number) {
            return converter.apply(((Number) value));
        }

        if (Boolean.TRUE.equals(value)) {
            return converter.apply(1);
        }
        if (Boolean.FALSE.equals(value)) {
            return converter.apply(0);
        }
        throw new IllegalArgumentException(String.format("The value [%s] cannot be converted to a number.", value));
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy