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

org.apache.dubbo.common.utils.CompatibleTypeUtils Maven / Gradle / Ivy

There is a newer version: 3.3.0-beta.3
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.dubbo.common.utils;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class CompatibleTypeUtils {

    private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /**
     * the text to parse such as "2007-12-03T10:15:30"
     */
    private static final int ISO_LOCAL_DATE_TIME_MIN_LEN = 19;

    private CompatibleTypeUtils() {
    }

    /**
     * Compatible type convert. Null value is allowed to pass in. If no conversion is needed, then the original value
     * will be returned.
     * 

* Supported compatible type conversions include (primary types and corresponding wrappers are not listed): *

    *
  • String -> char, enum, Date *
  • byte, short, int, long -> byte, short, int, long *
  • float, double -> float, double *
*/ @SuppressWarnings({"unchecked", "rawtypes"}) public static Object compatibleTypeConvert(Object value, Class type) { if (value == null || type == null || type.isAssignableFrom(value.getClass())) { return value; } if (value instanceof String) { String string = (String) value; if (char.class.equals(type) || Character.class.equals(type)) { if (string.length() != 1) { throw new IllegalArgumentException(String.format("CAN NOT convert String(%s) to char!" + " when convert String to char, the String MUST only 1 char.", string)); } return string.charAt(0); } if (type.isEnum()) { return Enum.valueOf((Class) type, string); } if (type == BigInteger.class) { return new BigInteger(string); } if (type == BigDecimal.class) { return new BigDecimal(string); } if (type == Short.class || type == short.class) { return new Short(string); } if (type == Integer.class || type == int.class) { return new Integer(string); } if (type == Long.class || type == long.class) { return new Long(string); } if (type == Double.class || type == double.class) { return new Double(string); } if (type == Float.class || type == float.class) { return new Float(string); } if (type == Byte.class || type == byte.class) { return new Byte(string); } if (type == Boolean.class || type == boolean.class) { return Boolean.valueOf(string); } if (type == Date.class || type == java.sql.Date.class || type == java.sql.Timestamp.class || type == java.sql.Time.class) { try { Date date = new SimpleDateFormat(DATE_FORMAT).parse(string); if (type == java.sql.Date.class) { return new java.sql.Date(date.getTime()); } if (type == java.sql.Timestamp.class) { return new java.sql.Timestamp(date.getTime()); } if (type == java.sql.Time.class) { return new java.sql.Time(date.getTime()); } return date; } catch (ParseException e) { throw new IllegalStateException("Failed to parse date " + value + " by format " + DATE_FORMAT + ", cause: " + e.getMessage(), e); } } if (type == java.time.LocalDateTime.class) { if (StringUtils.isEmpty(string)) { return null; } return LocalDateTime.parse(string); } if (type == java.time.LocalDate.class) { if (StringUtils.isEmpty(string)) { return null; } return LocalDate.parse(string); } if (type == java.time.LocalTime.class) { if (StringUtils.isEmpty(string)) { return null; } if (string.length() >= ISO_LOCAL_DATE_TIME_MIN_LEN) { return LocalDateTime.parse(string).toLocalTime(); } else { return LocalTime.parse(string); } } if (type == Class.class) { try { return ReflectUtils.name2class(string); } catch (ClassNotFoundException e) { throw new RuntimeException(e.getMessage(), e); } } if (char[].class.equals(type)) { // Process string to char array for generic invoke // See // - https://github.com/apache/dubbo/issues/2003 int len = string.length(); char[] chars = new char[len]; string.getChars(0, len, chars, 0); return chars; } } if (value instanceof Number) { Number number = (Number) value; if (type == byte.class || type == Byte.class) { return number.byteValue(); } if (type == short.class || type == Short.class) { return number.shortValue(); } if (type == int.class || type == Integer.class) { return number.intValue(); } if (type == long.class || type == Long.class) { return number.longValue(); } if (type == float.class || type == Float.class) { return number.floatValue(); } if (type == double.class || type == Double.class) { return number.doubleValue(); } if (type == BigInteger.class) { return BigInteger.valueOf(number.longValue()); } if (type == BigDecimal.class) { return new BigDecimal(number.toString()); } if (type == Date.class) { return new Date(number.longValue()); } if (type == boolean.class || type == Boolean.class) { return 0 != number.intValue(); } } if (value instanceof Collection) { Collection collection = (Collection) value; if (type.isArray()) { int length = collection.size(); Object array = Array.newInstance(type.getComponentType(), length); int i = 0; for (Object item : collection) { Array.set(array, i++, item); } return array; } if (!type.isInterface()) { try { Collection result = (Collection) type.newInstance(); result.addAll(collection); return result; } catch (Throwable ignored) { } } if (type == List.class) { return new ArrayList(collection); } if (type == Set.class) { return new HashSet(collection); } } if (value.getClass().isArray() && Collection.class.isAssignableFrom(type)) { int length = Array.getLength(value); Collection collection; if (!type.isInterface()) { try { collection = (Collection) type.newInstance(); } catch (Throwable e) { collection = new ArrayList(length); } } else if (type == Set.class) { collection = new HashSet(Math.max((int) (length/.75f) + 1, 16)); } else { collection = new ArrayList(length); } for (int i = 0; i < length; i++) { collection.add(Array.get(value, i)); } return collection; } return value; } }