package org.arefgard.container.aop;

import java.lang.reflect.Method;
import java.util.List;

public class MethodInvocation {
	
	private Object obj;
	
	public MethodInvocation(Object obj) {
		this.obj = obj;
	}
	
	public void setProperty(String property, Object value) throws Exception {
		Class clazz = this.obj.getClass();

		StringBuffer methodName = new StringBuffer("set");
		methodName.append(property.substring(0, 1).toUpperCase());
		methodName.append(property.substring(1));
		Method method = null;
		try {
			method = clazz.getDeclaredMethod(methodName.toString(), new Class[] {value.getClass()});
		}catch(NoSuchMethodException e) {
			// プリミティブとして扱ってみる
			if(value instanceof java.lang.Integer) {
				method = clazz.getDeclaredMethod(methodName.toString(), new Class[] {Integer.TYPE});
			}else if(value instanceof java.lang.Boolean) {
				method = clazz.getDeclaredMethod(methodName.toString(), new Class[] {Boolean.TYPE});
			}else if(value instanceof java.lang.Byte) {
				method = clazz.getDeclaredMethod(methodName.toString(), new Class[] {Byte.TYPE});
			}else if(value instanceof java.lang.Character) {
				method = clazz.getDeclaredMethod(methodName.toString(), new Class[] {Character.TYPE});
			}else if(value instanceof java.lang.Double) {
				method = clazz.getDeclaredMethod(methodName.toString(), new Class[] {Double.TYPE});
			}else if(value instanceof java.lang.Float) {
				method = clazz.getDeclaredMethod(methodName.toString(), new Class[] {Float.TYPE});
			}else if(value instanceof java.lang.Long) {
				method = clazz.getDeclaredMethod(methodName.toString(), new Class[] {Long.TYPE});
			}else if(value instanceof java.lang.Short) {
				method = clazz.getDeclaredMethod(methodName.toString(), new Class[] {Short.TYPE});
			}
		}
		method.invoke(obj, new Object[] { value });
	}
	
	public Object getProperty(String property) throws Exception {
		Class clazz = this.obj.getClass();
		
		StringBuffer methodName = new StringBuffer("get");
		methodName.append(property.substring(0, 1).toUpperCase());
		methodName.append(property.substring(1));
		
		Method method = clazz.getDeclaredMethod(methodName.toString());
		return method.invoke(obj);
	}
	
	public Object execute(String methodName, List<Object> parameter) throws Exception {
		Class clazz = this.obj.getClass();
		Method method = null;
		if(parameter == null) {
			method = clazz.getDeclaredMethod(methodName, (Class[])null);
			return method.invoke(obj, (Object[])null);
		}else {
			Object[] objList = parameter.toArray();
			Class[] classList = new Class[objList.length];
			for(int i = 0; i < objList.length; i++) {
				classList[i] = objList[i].getClass();
			}
			method = clazz.getDeclaredMethod(methodName, classList);
			return method.invoke(obj, objList);
		}
	}
}
