package org.seasar.framework.aop.impl;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;

import net.sf.cglib.proxy.MethodProxy;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * @author higa
 *
 */
public class MethodInvocationImpl implements MethodInvocation {

	private Object target_;
	private Method method_;
	private Object[] arguments_;
	private MethodProxy methodProxy_;
	private MethodInterceptor[] interceptors_;
	private Class targetClass_;
	private int interceptorsIndex_ = 0;

	public MethodInvocationImpl(
		Object target,
		Method method,
		Object[] arguments,
		MethodProxy methodProxy,
		MethodInterceptor[] interceptors,
		Class targetClass) {

		target_ = target;
		method_ = method;
		arguments_ = arguments;
		methodProxy_ = methodProxy;
		interceptors_ = interceptors;
		targetClass_ = targetClass;
	}

	/**
	 * @see org.aopalliance.intercept.MethodInvocation#getMethod()
	 */
	public Method getMethod() {
		return method_;
	}

	/**
	 * @see org.aopalliance.intercept.Invocation#getArguments()
	 */
	public Object[] getArguments() {
		return arguments_;
	}

	/**
	 * @see org.aopalliance.intercept.Joinpoint#proceed()
	 */
	public Object proceed() throws Throwable {
		while (interceptorsIndex_ < interceptors_.length) {
			return interceptors_[interceptorsIndex_++].invoke(this);
		}
		return methodProxy_.invokeSuper(target_, arguments_);
	}

	/**
	 * @see org.aopalliance.intercept.Joinpoint#getThis()
	 */
	public Object getThis() {
		return target_;
	}

	/**
	 * @see org.aopalliance.intercept.Joinpoint#getStaticPart()
	 */
	public AccessibleObject getStaticPart() {
		return method_;
	}
	
	public Class getTargetClass() {
		return targetClass_;
	}

}
