/*
 *
 * The Seasar Software License, Version 1.1
 *
 * Copyright (c) 2003-2004 The Seasar Project. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * 1. Redistributions of source code must retain the above
 *    copyrightnotice, this list of conditions and the following
 *    disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above
 *    copyright notice, this list of conditions and the following
 *    disclaimer in the documentation and/or other materials provided
 *    with the distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgement:
 *    "This product includes software developed by the
 *    Seasar Project (http://www.seasar.org/)."
 *    Alternately, this acknowledgement may appear in the software
 *    itself, if and wherever such third-party acknowledgements
 *    normally appear.
 *
 * 4. Neither the names "The Seasar Project" nor　the name of its
 *    contributors ay be used to endour or promote products derived
 *    from this software without specific prior written permission of
 *    the Seasar Project.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIESOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE SEASER　PROJECT
 * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL,SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.seasar.groovy;

import groovy.lang.Closure;

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

/**
 * Groovyのクロージャを呼びだすMethodInterceptor。
 * MethodInvocationはClosureAroundAdviceのコンストラクターに渡されたClosureへと
 * 引数としてそのまま渡される。
 * <p>
 * Closureの戻り値はそのままMethodInterceptorの戻り値として扱われるので、
 * なんらかの値を返さなくてはならない場合は、Closure内で値を返すこと。
 * <p>
 * サンプル:
 * <pre>
 * closure  = {invocation|
 *   invocation.getArgs()[1][0]    // => 1
 *   invocation.getArgs()[1][1]    // => 2
 *   result = invocation.proceed() // => 3
 *   return result + 1            // => 4
 * }
 * pointcut = new PointcutImpl(Calc)
 * aspect   = new AspectImpl(new ClosureAroundAdvice(closure), pointcut);
 * proxy    = new AopProxy(Calc, new Aspect[]{ aspect })
 * calc     = proxy.create()
 * println calc.plus(1, 2)
 * </pre>
 * 
 * @since 0.2
 * @author takai
 */
public class ClosureAroundAdvice implements MethodInterceptor {

    private Closure _closure;

    /**
     * コンストラクター。
     * コンストラクターに渡されたクロージャがJoinPointを処理する。
     * 
     * @param closure JoinPointが渡されるクロージャ。
     */
    public ClosureAroundAdvice(Closure closure) {
        _closure = closure;
    }

    /**
     * @param invocation ジョインポイント。
     * @return クロージャの戻り値。
     */
    public Object invoke(MethodInvocation invocation) throws Throwable {
        return _closure.call(invocation);
    }

}
