package de.escalon.hypermedia;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Created by Dietrich on 11.03.2015.
*/
public class PropertyUtils {
private PropertyUtils() {
}
public static Object getPropertyValue(Object currentCallValue, PropertyDescriptor propertyDescriptor) {
Object propertyValue = null;
if (currentCallValue != null && propertyDescriptor.getReadMethod() != null) {
try {
propertyValue = propertyDescriptor.getReadMethod()
.invoke(currentCallValue);
} catch (Exception e) {
throw new RuntimeException("failed to read property from call value", e);
}
}
return propertyValue;
}
public static Map<String, PropertyDescriptor> getPropertyDescriptors(Object bean) {
return PropertyUtils.getPropertyDescriptors(bean.getClass());
}
public static Map<String, PropertyDescriptor> getPropertyDescriptors(Class<?> clazz) {
try {
PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(clazz)
.getPropertyDescriptors();
Map<String, PropertyDescriptor> ret = new LinkedHashMap<String, PropertyDescriptor>();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
ret.put(propertyDescriptor.getName(), propertyDescriptor);
}
return ret;
} catch (IntrospectionException e) {
throw new RuntimeException("failed to get property descriptors of class " + clazz.getSimpleName(), e);
}
}
public static Constructor findDefaultCtor(Constructor[] constructors) {
// TODO duplicate on HtmlResourceMessageConverter
Constructor constructor = null;
for (Constructor ctor : constructors) {
if (ctor.getParameterTypes().length == 0) {
constructor = ctor;
}
}
return constructor;
}
public static Constructor findJsonCreator(Constructor[] constructors, Class creatorAnnotation) {
// TODO duplicate on HtmlResourceMessageConverter
Constructor constructor = null;
for (Constructor ctor : constructors) {
if (AnnotationUtils.findAnnotation(ctor, creatorAnnotation) != null) {
constructor = ctor;
break;
}
}
return constructor;
}
// TODO move to PropertyUtil and remove current method for propertyDescriptors, cache search results
public static Object getPropertyOrFieldValue(Object currentCallValue, String propertyOrFieldName) {
if (currentCallValue == null) {
return null;
}
Object propertyValue = getBeanPropertyValue(currentCallValue, propertyOrFieldName);
if (propertyValue == null) {
propertyValue = getFieldValue(currentCallValue, propertyOrFieldName);
}
return propertyValue;
}
public static Object getFieldValue(Object currentCallValue, String fieldName) {
try {
Class<?> beanType = currentCallValue.getClass();
Object propertyValue = null;
Field[] fields = beanType.getFields();
for (Field field : fields) {
if (fieldName.equals(field.getName())) {
propertyValue = field.get(currentCallValue);
break;
}
}
return propertyValue;
} catch (Exception e) {
throw new RuntimeException("Failed to read field " + fieldName + " from " + currentCallValue.toString(), e);
}
}
public static Object getBeanPropertyValue(Object currentCallValue, String paramName) {
if (currentCallValue == null) {
return null;
}
try {
Object propertyValue = null;
BeanInfo info = Introspector.getBeanInfo(currentCallValue.getClass());
PropertyDescriptor[] pds = info.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
if (paramName.equals(pd.getName())) {
Method readMethod = pd.getReadMethod();
if (readMethod != null) {
propertyValue = readMethod.invoke(currentCallValue);
}
break;
}
}
return propertyValue;
} catch (Exception e) {
throw new RuntimeException("Failed to read property " + paramName + " from " + currentCallValue.toString
(), e);
}
}
}