
io.lettuce.core.internal.LettuceClassUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lettuce-core Show documentation
Show all versions of lettuce-core Show documentation
Advanced and thread-safe Java Redis client for synchronous, asynchronous, and
reactive usage. Supports Cluster, Sentinel, Pipelining, Auto-Reconnect, Codecs
and much more.
The newest version!
package io.lettuce.core.internal;
import java.util.IdentityHashMap;
import java.util.Map;
/**
* Miscellaneous class utility methods. Mainly for internal use within the framework.
*
* @author Mark Paluch
* @since 4.2
*/
public class LettuceClassUtils {
/** The CGLIB class separator character "$$" */
public static final String CGLIB_CLASS_SEPARATOR = "$$";
/**
* Map with primitive wrapper type as key and corresponding primitive type as value, for example: Integer.class ->
* int.class.
*/
private static final Map, Class>> primitiveWrapperTypeMap = new IdentityHashMap, Class>>(9);
/**
* Map with primitive type as key and corresponding wrapper type as value, for example: int.class -> Integer.class.
*/
private static final Map, Class>> primitiveTypeToWrapperMap = new IdentityHashMap, Class>>(9);
static {
primitiveWrapperTypeMap.put(Boolean.class, boolean.class);
primitiveWrapperTypeMap.put(Byte.class, byte.class);
primitiveWrapperTypeMap.put(Character.class, char.class);
primitiveWrapperTypeMap.put(Double.class, double.class);
primitiveWrapperTypeMap.put(Float.class, float.class);
primitiveWrapperTypeMap.put(Integer.class, int.class);
primitiveWrapperTypeMap.put(Long.class, long.class);
primitiveWrapperTypeMap.put(Short.class, short.class);
primitiveWrapperTypeMap.put(Void.class, void.class);
}
/**
* Determine whether the {@link Class} identified by the supplied name is present and can be loaded. Will return
* {@code false} if either the class or one of its dependencies is not present or cannot be loaded.
*
* @param className the name of the class to check
* @return whether the specified class is present
*/
public static boolean isPresent(String className) {
try {
forName(className);
return true;
} catch (Throwable ex) {
// Class or one of its dependencies is not present...
return false;
}
}
/**
* Loads a class using the {@link #getDefaultClassLoader()}.
*
* @param className
* @return
*/
public static Class> findClass(String className) {
try {
return forName(className, getDefaultClassLoader());
} catch (ClassNotFoundException e) {
return null;
}
}
/**
* Loads a class using the {@link #getDefaultClassLoader()}.
*
* @param className
* @return
* @throws ClassNotFoundException
*/
public static Class> forName(String className) throws ClassNotFoundException {
return forName(className, getDefaultClassLoader());
}
private static Class> forName(String className, ClassLoader classLoader) throws ClassNotFoundException {
try {
return classLoader.loadClass(className);
} catch (ClassNotFoundException ex) {
int lastDotIndex = className.lastIndexOf('.');
if (lastDotIndex != -1) {
String innerClassName = className.substring(0, lastDotIndex) + '$' + className.substring(lastDotIndex + 1);
try {
return classLoader.loadClass(innerClassName);
} catch (ClassNotFoundException ex2) {
// swallow - let original exception get through
}
}
throw ex;
}
}
/**
* Return the default ClassLoader to use: typically the thread context ClassLoader, if available; the ClassLoader that
* loaded the ClassUtils class will be used as fallback.
*
* @return the default ClassLoader (never null
)
* @see java.lang.Thread#getContextClassLoader()
*/
private static ClassLoader getDefaultClassLoader() {
ClassLoader cl = null;
try {
cl = Thread.currentThread().getContextClassLoader();
} catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back to system class loader...
}
if (cl == null) {
// No thread context class loader -> use class loader of this class.
cl = LettuceClassUtils.class.getClassLoader();
}
return cl;
}
/**
* Check if the right-hand side type may be assigned to the left-hand side type, assuming setting by reflection. Considers
* primitive wrapper classes as assignable to the corresponding primitive types.
*
* @param lhsType the target type
* @param rhsType the value type that should be assigned to the target type
* @return if the target type is assignable from the value type
*/
public static boolean isAssignable(Class> lhsType, Class> rhsType) {
LettuceAssert.notNull(lhsType, "Left-hand side type must not be null");
LettuceAssert.notNull(rhsType, "Right-hand side type must not be null");
if (lhsType.isAssignableFrom(rhsType)) {
return true;
}
if (lhsType.isPrimitive()) {
Class> resolvedPrimitive = primitiveWrapperTypeMap.get(rhsType);
if (lhsType == resolvedPrimitive) {
return true;
}
} else {
Class> resolvedWrapper = primitiveTypeToWrapperMap.get(rhsType);
if (resolvedWrapper != null && lhsType.isAssignableFrom(resolvedWrapper)) {
return true;
}
}
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy