package org.arefgard.container.aop;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;


public class ClassGenerator{
	public static Object generate(String className) throws ClassNotFoundException {
		try {
			Class clazz = Class.forName(className);
			return clazz.newInstance();
		}catch(Exception e) {
			throw new ClassNotFoundException("", e);
		}
	}
	
	public static Object generate(String className, String[] typelist, Object[] objlist) throws ClassNotFoundException {
		try {
			
			int typesize = typelist.length;
			int objsize = objlist.length;
			
			// 小さい方をサイズとして使用
			int length = 0;
			if(typesize > objsize) {
				length = objsize;
			}else {
				length = typesize;
			}
			Class clazz = Class.forName(className);
			ClassStructure structure = ClassStructure.parse(clazz);
			ConstructorStructure construct = structure.getConstructor(objlist);
			if(construct != null) {
				// 値設定用のコンストラクタが用意されている場合
				return construct.getConstructor().newInstance(objlist);
			}else {
				// setter/getterで値を設定する場合
				Object obj = clazz.newInstance();
				for(int i = 0; i < length; i++) {
					MethodStructure method = structure.getSetter(typelist[i], objlist[i].getClass());
					method.getMethod().invoke(obj, objlist[i]);
				}
				return obj;
			}
		}catch(Exception e) {
			throw new ClassNotFoundException("", e);
		}
	}
	
	public static Object generate(String className, Map<String, Object> property) throws ClassNotFoundException{
		try {
			Class clazz = Class.forName(className);
			ClassStructure structure = ClassStructure.parse(clazz);
			
			Object result = clazz.newInstance();
			
			// プロパティをインジェクションする
			if(property != null || property.size() != 0) {
				Set<String> keys = property.keySet();
				for(Iterator<String> itr = keys.iterator();itr.hasNext();) {
					String key = itr.next();
					Object value = property.get(key);
					structure.getSetter(key, value.getClass()).getMethod().invoke(result, new Object[] {value});
				}
			}
			return result;
		}catch(Exception e) {
			throw new ClassNotFoundException("", e);
		}
	}
}
