/**
* This software is provided as IS by Antilia-Soft SL.
* Copyright 2006-2007.
*/
//package com.antilia.common.util;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
public class ReflectionUtils {
public static final String NESTED_PROPERTY_SEPARATOR = ".";
public static Field getPropertyField(Class> beanClass,String property) throws NoSuchFieldException {
if (beanClass == null)
throw new IllegalArgumentException("beanClass cannot be null");
Field field = null;
try {
field = beanClass.getDeclaredField(property);
} catch (NoSuchFieldException e) {
if (beanClass.getSuperclass() == null)
throw e;
// look for the field in the superClass
field = getPropertyField(beanClass.getSuperclass(),property);
}
return field;
}
public static Field getField(Class> beanClass,String propertyPath) throws NoSuchFieldException {
if (beanClass == null)
throw new IllegalArgumentException("beanClass cannot be null");
if (propertyPath.indexOf("[") != -1)
propertyPath = propertyPath.substring(0,propertyPath.indexOf("["));
// if the property path is simple then look for it directly on the class.
if (propertyPath.indexOf(NESTED_PROPERTY_SEPARATOR) == -1) {
// look if the field is declared in this class.
return getPropertyField(beanClass,propertyPath);
} else {
// if the property is a compound one then split it and look for the first field.
// and recursively locate fields of fields.
String propertyName = propertyPath.substring(0,propertyPath.indexOf(NESTED_PROPERTY_SEPARATOR));
Field field = getField(beanClass,propertyName);
// try to locate sub-properties
return getField(getTargetType(field),propertyPath.substring(propertyPath.indexOf(NESTED_PROPERTY_SEPARATOR)+1));
}
}
public static Class> getTargetType(Field field) {
// Generic type, case when we have a Collection of ?
if (field.getGenericType() instanceof ParameterizedType) {
ParameterizedType type = (ParameterizedType)field.getGenericType();
if (type.getActualTypeArguments().length == 1 && type.getActualTypeArguments()[0] instanceof Class)
return (Class>)type.getActualTypeArguments()[0];
}
return field.getType();
}
public static Class> getPropertyClass(Class> beanClass,String propertyPath) {
try {
Field field = getField(beanClass, propertyPath);
return(getTargetType(field));
} catch (NoSuchFieldException e) {
throw new IllegalArgumentException(propertyPath+" is not a property of "+beanClass.getName());
}
}
public static boolean isFieldDeclared(Class> beanClass,String propertyPath) {
try {
return getField(beanClass, propertyPath) != null;
} catch(NoSuchFieldException e) {
return false;
}
}
public static Object getPropertyValue(Object bean,String propertyPath) throws NoSuchFieldException {
if (bean == null)
throw new IllegalArgumentException("bean cannot be null");
Field field = ReflectionUtils.getField(bean.getClass(), propertyPath);
field.setAccessible(true);
try {
return(field.get(bean));
} catch (IllegalAccessException e) {
return(null);
}
}
}