package org.seasar.framework.container.assembler;

import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;

import org.seasar.framework.aop.Aspect;
import org.seasar.framework.aop.proxy.AopProxy;
import org.seasar.framework.container.AspectDef;
import org.seasar.framework.container.ComponentDef;
import org.seasar.framework.container.ContainerConstants;
import org.seasar.framework.util.ClassUtil;
import org.seasar.framework.util.ConstructorUtil;

/**
 * @author higa
 *  
 */
public abstract class AbstractConstructorAssembler extends AbstractAssembler
		implements ConstructorAssembler {

	public AbstractConstructorAssembler(ComponentDef componentDef) {
		super(componentDef);
	}

	protected final AopProxy createAopProxy() {
		ComponentDef cd = getComponentDef();
		Map parameters = new HashMap();
		parameters.put(ContainerConstants.COMPONENT_DEF_NAME, cd);
		return new AopProxy(cd.getComponentClass(), getAspects(), parameters);
	}

	protected Object assembleDefault() {
		if (getComponentDef().getAspectDefSize() > 0) {
			AopProxy aopProxy = createAopProxy();
			return aopProxy.create();
		} else {
			Class clazz = getComponentDef().getComponentClass();
			Constructor constructor = ClassUtil.getConstructor(clazz, null);
			return ConstructorUtil.newInstance(constructor, null);
		}
	}

	private Aspect[] getAspects() {
		int size = getComponentDef().getAspectDefSize();
		Aspect[] aspects = new Aspect[size];
		for (int i = 0; i < size; ++i) {
			AspectDef aspectDef = getComponentDef().getAspectDef(i);
			aspects[i] = aspectDef.getAspect();
		}
		return aspects;
	}
}