/*
 * This file is part of Nuts Framework.
 * Copyright(C) 2009-2012 Nuts Develop Team.
 *
 * Nuts Framework is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License any later version.
 * 
 * Nuts Framework 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 Nuts Framework. If not, see <http://www.gnu.org/licenses/>.
 */
package nuts.core.beans;


/**
 * utility class for bean property
 */
public class PropertyUtils {
	/**
	 * getBeanHandler
	 * @param <T>
	 * @param type bean type
	 * @return BeanHandler
	 */
	public static <T> BeanHandler<T> getBeanHandler(Class<T> type) {
		return BeanHandlerFactory.getInstance().getBeanHandler(type);
	}

	protected static void assertBeanAndName(Object bean, String name) {
		if (bean == null) {
			throw new IllegalArgumentException("argument bean is null.");
		}
		if (name == null) {
			throw new IllegalArgumentException("argument name is null.");
		}
	}
	
	/**
	 * <p>
	 * Return the value of the property of the specified name,
	 * for the specified bean, with no type conversions.
	 * </p>
	 * 
	 * @param bean Bean whose property is to be extracted
	 * @param name the property to be extracted
	 * @return the property value
	 * 
	 * @exception IllegalArgumentException if <code>bean</code> or
	 *                <code>name</code> is null
	 *                throws an exception
	 */
	@SuppressWarnings("unchecked")
	public static Object getProperty(Object bean, String name) {
		assertBeanAndName(bean, name);
		
		BeanHandler bh = BeanHandlerFactory.getInstance().getBeanHandler(bean.getClass());

		return bh.getBeanValue(bean, name);
	}

	/**
	 * <p>
	 * set the value of the property of the specified name.
	 * for the specified bean, with no type conversions.
	 * </p>
	 * 
	 * @param bean Bean whose property is to be set
	 * @param name the property name 
	 * @param value the property value to be set
	 * 
	 * @exception IllegalArgumentException if <code>bean</code> or
	 *                <code>name</code> is null
	 *                throws an exception
	 */
	@SuppressWarnings("unchecked")
	public static void setProperty(Object bean, String name, Object value) {
		assertBeanAndName(bean, name);
		
		BeanHandler bh = BeanHandlerFactory.getInstance().getBeanHandler(bean.getClass());

		bh.setBeanValue(bean, name, value);
	}

	/**
	 * <p>
	 * Return the value of the property of the specified name,
	 * for the specified bean, with no type conversions.
	 * </p>
	 * 
	 * @param bean Bean whose property is to be extracted
	 * @param name the property to be extracted
	 * @return the property value
	 * 
	 * @exception IllegalArgumentException if <code>bean</code> or
	 *                <code>name</code> is null
	 *                throws an exception
	 */
	@SuppressWarnings("unchecked")
	public static Object getSimpleProperty(Object bean, String name) {
		assertBeanAndName(bean, name);
		
		BeanHandler bh = BeanHandlerFactory.getInstance().getBeanHandler(bean.getClass());

		return bh.getPropertyValue(bean, name);
	}

	/**
	 * <p>
	 * set the value of the property of the specified name.
	 * for the specified bean, with no type conversions.
	 * </p>
	 * 
	 * @param bean Bean whose property is to be set
	 * @param name the property name 
	 * @param value the property value to be set
	 * 
	 * @exception IllegalArgumentException if <code>bean</code> or
	 *                <code>name</code> is null
	 *                throws an exception
	 */
	@SuppressWarnings("unchecked")
	public static void setSimpleProperty(Object bean, String name, Object value) {
		assertBeanAndName(bean, name);
		
		BeanHandler bh = BeanHandlerFactory.getInstance().getBeanHandler(bean.getClass());

		bh.setPropertyValue(bean, name, value);
	}
}
