io.smallrye.reactive.messaging.providers.helpers.ClassUtils Maven / Gradle / Ivy
package io.smallrye.reactive.messaging.providers.helpers;
import java.util.HashMap;
import java.util.Map;
/**
* Allows checking if a class can be assigned to a variable from another class.
*
* Code extracted from from Apache Commons Lang 3 - ClassUtils.java
*/
public class ClassUtils {
private ClassUtils() {
// Avoid direct instantiation.
}
/**
* Checks if one {@code cls} can be assigned to a variable of
* another {@code toClass}, like: {@code Cls c = ...; ToClass x = c;}
*
* @param cls the Class to check, may be {@code null}
* @param toClass the Class to try to assign into, returns {@code false} if null
* @return {@code true} if assignment possible
*/
public static boolean isAssignable(Class cls, Class toClass) {
if (toClass == null) {
return false;
}
// have to check for null, as isAssignableFrom doesn't
if (cls == null) {
return !toClass.isPrimitive();
}
if (cls.isPrimitive() && !toClass.isPrimitive()) {
cls = primitiveToWrapper(cls);
if (cls == null) {
return false;
}
}
if (toClass.isPrimitive() && !cls.isPrimitive()) {
cls = wrapperToPrimitive(cls);
if (cls == null) {
return false;
}
}
if (cls.equals(toClass)) {
return true;
}
if (cls.isPrimitive()) {
if (!toClass.isPrimitive()) {
return false;
}
if (Integer.TYPE.equals(cls)) {
return Long.TYPE.equals(toClass)
|| Float.TYPE.equals(toClass)
|| Double.TYPE.equals(toClass);
}
if (Long.TYPE.equals(cls)) {
return Float.TYPE.equals(toClass)
|| Double.TYPE.equals(toClass);
}
if (Boolean.TYPE.equals(cls)) {
return false;
}
if (Double.TYPE.equals(cls)) {
return false;
}
if (Float.TYPE.equals(cls)) {
return Double.TYPE.equals(toClass);
}
if (Character.TYPE.equals(cls)) {
return isInteger(toClass);
}
if (Short.TYPE.equals(cls)) {
return isInteger(toClass);
}
if (Byte.TYPE.equals(cls)) {
return Short.TYPE.equals(toClass)
|| Integer.TYPE.equals(toClass)
|| Long.TYPE.equals(toClass)
|| Float.TYPE.equals(toClass)
|| Double.TYPE.equals(toClass);
}
// should never get here
return false;
}
return toClass.isAssignableFrom(cls);
}
private static boolean isInteger(Class toClass) {
return Integer.TYPE.equals(toClass)
|| Long.TYPE.equals(toClass)
|| Float.TYPE.equals(toClass)
|| Double.TYPE.equals(toClass);
}
/**
*
* Converts the specified primitive Class object to its corresponding
* wrapper Class object.
*
*
*
* NOTE: From v2.2, this method handles {@code Void.TYPE},
* returning {@code Void.TYPE}.
*
*
* @param cls the class to convert, may be null
* @return the wrapper class for {@code cls} or {@code cls} if
* {@code cls} is not a primitive. {@code null} if null input.
* @since 2.1
*/
public static Class primitiveToWrapper(final Class cls) {
Class convertedClass = cls;
if (cls != null && cls.isPrimitive()) {
convertedClass = primitiveWrapperMap.get(cls);
}
return convertedClass;
}
/**
* Converts the specified wrapper class to its corresponding primitive
* class.
*
* @param cls the class
*/
private static Class wrapperToPrimitive(final Class cls) {
return wrapperPrimitiveMap.get(cls);
}
/**
* Maps primitive {@code Class}es to their corresponding wrapper {@code Class}.
*/
private static final Map, Class> primitiveWrapperMap = new HashMap<>();
static {
primitiveWrapperMap.put(Boolean.TYPE, Boolean.class);
primitiveWrapperMap.put(Byte.TYPE, Byte.class);
primitiveWrapperMap.put(Character.TYPE, Character.class);
primitiveWrapperMap.put(Short.TYPE, Short.class);
primitiveWrapperMap.put(Integer.TYPE, Integer.class);
primitiveWrapperMap.put(Long.TYPE, Long.class);
primitiveWrapperMap.put(Double.TYPE, Double.class);
primitiveWrapperMap.put(Float.TYPE, Float.class);
primitiveWrapperMap.put(Void.TYPE, Void.TYPE);
}
/**
* Maps wrapper {@code Class}es to their corresponding primitive types.
*/
private static final Map, Class> wrapperPrimitiveMap = new HashMap<>();
static {
for (final Map.Entry, Class> entry : primitiveWrapperMap.entrySet()) {
final Class primitiveClass = entry.getKey();
final Class wrapperClass = entry.getValue();
if (!primitiveClass.equals(wrapperClass)) {
wrapperPrimitiveMap.put(wrapperClass, primitiveClass);
}
}
}
}