/*
 * 作成日： 2004/09/13
 */
package org.seasar.tapestry.util;

import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * The data transmission between Bean and Bean is supported. 
 * @author maruo_syunsuke
 */
public class BeanCopy {
	private static final Log LOG = LogFactory.getLog(BeanCopy.class);
	/**
	 * 
	 * @param dest
	 * @param src
	 */
	public void beanCopy(Object dest, Object src) {
		Class clazz = dest.getClass();
		Method[] srcMethods = src.getClass().getDeclaredMethods();
		for (int i = 0; i < srcMethods.length; i++) {
			Method getterMethod = srcMethods[i];
			String getterName = getterMethod.getName() ;
			if( getterName.startsWith("get") == false )continue ;
			String setterName = "s"+getterName.substring(1);
			Method setterMethod = null ;
			try {
				setterMethod = clazz.getMethod(setterName, 
							new Class[] {getterMethod.getReturnType() });
				setterMethod.invoke(dest,
						new Object[] {getterMethod.invoke(src,new Object[0])});
			} catch (NoSuchMethodException e) {
				LOG.trace("setterに対応するgetterが無かった : "+ setterName);
				continue ;
			}catch(Exception e) {
				LOG.trace("error",e);
			}
		}
	}

	/**
	 * @param dest
	 * @param src
	 * @param between
	 */
	public void beanCopy(Object dest, Object src, Class between) {
		Class clazz = dest.getClass();
		Method[] srcMethods = src.getClass().getDeclaredMethods();
		for (int i = 0; i < srcMethods.length; i++) {
			Method getterMethod = srcMethods[i];
			String getterName = getterMethod.getName() ;
			if( getterName.startsWith("get") == false )continue ;

			Method setterMethod = null ;
			String setterName = null ;
			try {
				setterName = (String) between.getField(
						getterName.substring(3,4).toLowerCase()
						+getterName.substring(4)
					).get(between);
				setterName = "set"+setterName.substring(0,1).toUpperCase()
											+setterName.substring(1);
			} catch (IllegalArgumentException e) {
				throw new RuntimeException(e);
			} catch (SecurityException e) {
				throw new RuntimeException(e);
			} catch (IllegalAccessException e) {
				LOG.trace("アノテレートクラスに対応する値にアクセスできなかった : "+ getterName);
				setterName = "s"+getterName.substring(1);
			} catch (NoSuchFieldException e) {
				LOG.trace("アノテレートクラスに対応する値が無かった : "+ getterName);
				setterName = "s"+getterName.substring(1);
			}

			try {
				setterMethod = clazz.getMethod(setterName, 
						new Class[] {getterMethod.getReturnType() });
				setterMethod.invoke(dest,
						new Object[] {getterMethod.invoke(src,new Object[0])});
			} catch (Exception e) {
				LOG.trace("セット失敗",e);
			}
		}
	}
}
