![JAR search and dependency download from the Maven repository](/logo.png)
org.codehaus.jackson.map.util.ClassUtil Maven / Gradle / Ivy
Go to download
Data Mapper package is a high-performance data binding package
built on Jackson JSON processor
package org.codehaus.jackson.map.util;
import java.lang.reflect.*;
import java.util.*;
public final class ClassUtil
{
private ClassUtil() { }
/*
//////////////////////////////////////////////////////////
// Methods that deal with inheritance
//////////////////////////////////////////////////////////
*/
/**
* Method that will find all sub-classes and implemented interfaces
* of a given class or interface. Classes are listed in order of
* precedence, starting with the immediate super-class, followed by
* interfaces class directly declares to implemented, and then recursively
* followed by parent of super-class and so forth.
* Note that Object.class
is not included in the list
* regardless of whether endBefore
argument is defined
*
* @param endBefore Super-type to NOT include in results, if any; when
* encountered, will be ignored (and no super types are checked).
*/
public static List> findSuperTypes(Class> cls, Class> endBefore)
{
/* We don't expect to get huge collections, thus overhead of a
* Set seems unnecessary.
*/
ArrayList> result = new ArrayList>();
_addSuperTypes(cls, endBefore, result, false);
return result;
}
private static void _addSuperTypes(Class> cls, Class> endBefore, ArrayList> result, boolean addClassItself)
{
if (cls == endBefore || cls == null || cls == Object.class) {
return;
}
if (addClassItself) {
if (result.contains(cls)) { // already added, no need to check supers
return;
}
result.add(cls);
}
for (Class> intCls : cls.getInterfaces()) {
_addSuperTypes(intCls, endBefore, result, true);
}
_addSuperTypes(cls.getSuperclass(), endBefore, result, true);
}
/*
//////////////////////////////////////////////////////////
// Class type detection methods
//////////////////////////////////////////////////////////
*/
/**
* @return Null if class might be a bean; type String (that identifies
* why it's not a bean) if not
*/
public static String canBeABeanType(Class> type)
{
// First: language constructs that ain't beans:
if (type.isAnnotation()) {
return "annotation";
}
if (type.isArray()) {
return "array";
}
if (type.isEnum()) {
return "enum";
}
if (type.isPrimitive()) {
return "primitive";
}
// Anything else? Seems valid, then
return null;
}
public static String isLocalType(Class> type)
{
// one more: method locals, anonymous, are not good:
if (type.getEnclosingMethod() != null) {
return "local/anonymous";
}
/* But how about non-static inner classes? Can't construct
* easily (theoretically, we could try to check if parent
* happens to be enclosing... but that gets convoluted)
*/
if (type.getEnclosingClass() != null) {
if (!Modifier.isStatic(type.getModifiers())) {
return "non-static member class";
}
}
return null;
}
/**
* Helper method used to weed out dynamic Proxy types; types that do
* not expose concrete method API that we could use to figure out
* automatic Bean (property) based serialization.
*/
public static boolean isProxyType(Class> type)
{
// Then: well-known proxy (etc) classes
if (Proxy.isProxyClass(type)) {
return true;
}
String name = type.getName();
// Hibernate uses proxies heavily as well:
if (name.startsWith("net.sf.cglib.proxy.")
|| name.startsWith("org.hibernate.proxy.")) {
return true;
}
// Not one of known proxies, nope:
return false;
}
/**
* Helper method that checks if given class is a concrete one;
* that is, not an interface or abstract class.
*/
public static boolean isConcrete(Class> type)
{
int mod = type.getModifiers();
return (mod & (Modifier.INTERFACE | Modifier.ABSTRACT)) == 0;
}
/*
//////////////////////////////////////////////////////////
// Method type detection methods
//////////////////////////////////////////////////////////
*/
public static boolean hasGetterSignature(Method m)
{
// First: static methods can't be getters
if (Modifier.isStatic(m.getModifiers())) {
return false;
}
// Must take no args
Class>[] pts = m.getParameterTypes();
if (pts != null && pts.length != 0) {
return false;
}
// Can't be a void method
if (Void.TYPE == m.getReturnType()) {
return false;
}
// Otherwise looks ok:
return true;
}
/*
//////////////////////////////////////////////////////////
// Exception handling
//////////////////////////////////////////////////////////
*/
/**
* Method that can be used to find the "root cause", innermost
* of chained (wrapped) exceptions.
*/
public static Throwable getRootCause(Throwable t)
{
while (t.getCause() != null) {
t = t.getCause();
}
return t;
}
public static void throwAsIAE(Throwable t)
{
throwAsIAE(t, t.getMessage());
}
public static void throwAsIAE(Throwable t, String msg)
{
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
if (t instanceof Error) {
throw (Error) t;
}
throw new IllegalArgumentException(msg, t);
}
public static void unwrapAndThrowAsIAE(Throwable t)
{
throwAsIAE(getRootCause(t));
}
public static void unwrapAndThrowAsIAE(Throwable t, String msg)
{
throwAsIAE(getRootCause(t), msg);
}
/*
//////////////////////////////////////////////////////////
// Instantiation
//////////////////////////////////////////////////////////
*/
/**
* Method that can be called to try to create an instantiate of
* specified type. Instantiation is done using default no-argument
* constructor.
*
* @param canFixAccess Whether it is possible to try to change access
* rights of the default constructor (in case it is not publicly
* accessible) or not.
*
* @throws IllegalArgumentException If instantiation fails for any reason;
* except for cases where constructor throws an unchecked exception
* (which will be passed as is)
*/
public static Object createInstance(Class> cls, boolean canFixAccess)
throws IllegalArgumentException
{
Constructor> ctor = null;
try {
ctor = cls.getDeclaredConstructor();
} catch (Exception e) {
ClassUtil.unwrapAndThrowAsIAE(e, "Failed to find default constructor of class "+cls.getName()+", problem: "+e.getMessage());
}
if (ctor == null) {
throw new IllegalArgumentException("Class "+cls.getName()+" has no default (no arg) constructor");
}
if (canFixAccess) {
checkAndFixAccess(ctor);
} else {
// Has to be public...
if (!Modifier.isPublic(ctor.getModifiers())) {
throw new IllegalArgumentException("Default constructor for "+cls.getName()+" is not accessible (non-public?): not allowed to try modify access via Reflection: can not instantiate type");
}
}
try {
return ctor.newInstance();
} catch (Exception e) {
ClassUtil.unwrapAndThrowAsIAE(e, "Failed to instantiate class "+cls.getName()+", problem: "+e.getMessage());
return null;
}
}
/*
//////////////////////////////////////////////////////////
// Access checking/handling methods
//////////////////////////////////////////////////////////
*/
/**
* Method called to check if we can use the passed method or constructor
* (wrt access restriction -- public methods can be called, others
* usually not); and if not, if there is a work-around for
* the problem.
*/
public static void checkAndFixAccess(Member member)
{
// We know all members are also accessible objects...
AccessibleObject ao = (AccessibleObject) member;
/* 14-Jan-2009, tatu: It seems safe and potentially beneficial to
* always to make it accessible (latter because it will force
* skipping checks we have no use for...), so let's always call it.
*/
//if (!ao.isAccessible()) {
try {
ao.setAccessible(true);
} catch (SecurityException se) {
/* 17-Apr-2009, tatu: Related to [JACKSON-101]: this can fail on
* platforms like EJB and Google App Engine); so let's
* only fail if we really needed it...
*/
if (!ao.isAccessible()) {
Class> declClass = member.getDeclaringClass();
throw new IllegalArgumentException("Can not access "+member+" (from class "+declClass.getName()+"; failed to set access: "+se.getMessage());
}
}
//}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy