All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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