
org.numenta.nupic.util.BeanUtil Maven / Gradle / Ivy
/* ---------------------------------------------------------------------
* Numenta Platform for Intelligent Computing (NuPIC)
* Copyright (C) 2014, Numenta, Inc. Unless you have an agreement
* with Numenta, Inc., for a separate license for this software code, the
* following terms and conditions apply:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses.
*
* http://numenta.org/licenses/
* ---------------------------------------------------------------------
*/
package org.numenta.nupic.util;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
*Singleton helper for reading/writing beans properties
*@author Kirill Solovyev
*/
public class BeanUtil {
//TODO introduce proper log in future
//private static final Log LOG = LogFactory.getLog(BeanUtil.class);
private final Map, PropertyInfo[]> properties = new ConcurrentHashMap, PropertyInfo[]>();
private static final PropertyDescriptor[] EMPTY_PROPERTY_DESCRIPTOR = new PropertyDescriptor[0];
private static BeanUtil INSTANCE = new BeanUtil();
public static BeanUtil getInstance() {
return INSTANCE;
}
private BeanUtil() {
}
/**
* Write value to bean's property
* @param bean
* @param name
* @param value
* @return
*/
public boolean setSimpleProperty(Object bean, String name, Object value) {
PropertyInfo pi = getPropertyInfo(bean, name);
if (pi != null) {
setSimpleProperty(bean, pi, value);
return true;
} else {
return false;
}
}
public void setSimplePropertyRequired(Object bean, String name, Object value) {
setSimpleProperty(bean, getPropertyInfoRequired(bean, name), value);
}
/**
* Return bean's property value
* @param bean
* @param name
* @return
*/
public Object getSimpleProperty(Object bean, String name) {
return getSimpleProperty(bean, getPropertyInfo(bean, name));
}
private Object getSimpleProperty(Object bean, PropertyInfo info) {
if (info.getReadMethod() == null) {
throw new IllegalArgumentException("Property '" + info.name + "' of bean " + bean.getClass().getName() +
" does not have getter method");
}
return invokeMethod(info.getReadMethod(), bean);
}
private void setSimpleProperty(Object bean, PropertyInfo info, Object value) {
if (info.getWriteMethod() == null) {
throw new IllegalArgumentException("Property '" + info.name + "' of bean " + bean.getClass().getName() +
" does not have setter method");
}
invokeMethod(info.getWriteMethod(), bean, value);
}
private Object invokeMethod(Method m, Object instance, Object... args) {
if (instance == null) {
throw new IllegalArgumentException("Can not invole Method '" + m + "' on null instance");
}
try {
return m.invoke(instance, args);
} catch (IllegalArgumentException e) {
final String msg = "Cannot invoke " + m.getDeclaringClass().getName() + "." + m.getName() + " - " + e.getMessage();
//LOG.error(msg, e);
throw new IllegalArgumentException(msg, e);
} catch (IllegalAccessException e) {
final String msg = "Cannot invoke " + m.getDeclaringClass().getName() + "." + m.getName() + " - " + e.getMessage();
//LOG.error(msg, e);
throw new RuntimeException(msg, e);
} catch (InvocationTargetException e) {
Throwable te = e.getTargetException() == null ? e : e.getTargetException();
final String msg = "Error invoking " + m.getDeclaringClass().getName() + "." + m.getName() + " - " + te.getMessage();
//LOG.error(msg, e);
throw new RuntimeException(msg, te);
}
}
public PropertyInfo getPropertyInfo(Object bean, String name) {
if (bean == null) {
throw new IllegalArgumentException("Bean can not be null");
}
return getPropertyInfo(bean.getClass(), name);
}
public PropertyInfo getPropertyInfoRequired(Object bean, String name) {
PropertyInfo result = getPropertyInfo(bean, name);
if (result == null) {
throw new IllegalArgumentException(
"Bean " + bean.getClass().getName() + " does not have property '" + name + "'");
}
return result;
}
public PropertyInfo getPropertyInfo(Class> beanClass, String name) {
if (name == null) {
throw new IllegalArgumentException("Property name is required and can not be null");
}
PropertyInfo infos[] = getPropertiesInfoForBean(beanClass);
for (PropertyInfo info : infos) {
if (name.equals(info.getName())) {
return info;
}
}
return null;
}
public PropertyInfo[] getPropertiesInfoForBean(Class> beanClass) {
if (beanClass == null) {
throw new IllegalArgumentException("Bean class is required and can not be null");
}
PropertyInfo infos[] = properties.get(beanClass);
if (infos != null) {
return infos;
}
PropertyDescriptor descriptors[];
try {
descriptors = Introspector.getBeanInfo(beanClass).getPropertyDescriptors();
if (descriptors == null) {
descriptors = EMPTY_PROPERTY_DESCRIPTOR;
}
} catch (IntrospectionException e) {
descriptors = EMPTY_PROPERTY_DESCRIPTOR;
}
infos = new PropertyInfo[descriptors.length];
for (int i = 0; i < descriptors.length; i++) {
infos[i] = createPropertyInfo(beanClass, descriptors[i]);
}
properties.put(beanClass, infos);
return infos;
}
private PropertyInfo createPropertyInfo(Class> beanClass, PropertyDescriptor d) {
return new PropertyInfo(beanClass, d.getName(), d.getPropertyType(), d.getReadMethod(), d.getWriteMethod());
}
@SuppressWarnings("unused")
private PropertyInfo createPropertyInfo(Class> beanClass, String propertyName, Class> propertyType) {
return new PropertyInfo(beanClass, propertyName, propertyType, null, null);
}
public static class PropertyInfo {
private final Class> beanClass;
private final String name;
private final Class> type;
private final Method readMethod;
private final Method writeMethod;
PropertyInfo(Class> beanClass, String name, Class> type, Method readMethod, Method writeMethod) {
this.beanClass = beanClass;
this.name = name;
this.type = type;
this.readMethod = readMethod;
this.writeMethod = writeMethod;
}
public Class> getBeanClass() {
return beanClass;
}
public String getName() {
return name;
}
public Class> getType() {
return type;
}
public Method getReadMethod() {
return readMethod;
}
public Method getWriteMethod() {
return writeMethod;
}
public String toString() {
return "PropertyInfo{" +
"beanClass=" + beanClass +
", name='" + name + "'" +
", type=" + type +
", readMethod=" + readMethod +
", writeMethod=" + writeMethod +
"}";
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy