
com.lambdaworks.redis.internal.LettuceClassUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lettuce Show documentation
Show all versions of lettuce 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!
/*
* Copyright 2011-2016 the original author or authors.
*
* 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 com.lambdaworks.redis.internal;
import java.util.IdentityHashMap;
import java.util.Map;
import org.springframework.util.TypeUtils;
import com.lambdaworks.redis.JavaRuntime;
/**
* 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 = JavaRuntime.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
* @see TypeUtils#isAssignable
*/
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