aopalliance / php

PHP AOP Alliance
MIT License
9 stars 0 forks source link

Discussion about interface for method invocation #1

Open lisachenko opened 11 years ago

lisachenko commented 11 years ago

Invocation of the method is the main feature of AOP library, so we can start our first discussion about interface for MethodInvocation.

Here is the list of current realizations:

AOP-PHP Extension uses a single class AopTriggeredJoinpoint for storing information about invocation. There isn't a specific interface for MethodInvocation:

interface AopTriggeredJoinpoint // Simplified, not all methods described here
{

    /**
     * This will tell in wich condition your advice was launched
     *
     * @return integer
     */
    public function getKindOfAdvice();

    /**
     * getArguments will return the triggering method arguments as an indexed array.
     *
     * @return array
     */
    public function getArguments();

    /**
     * setArguments enables you to replace all the arguments the triggering method will receive
     *
     * @param array $newArgs New arguments
     */
    public function setArguments(array $newArgs);

    /**
     * getReturnedValue will give you the returned value of the triggering method.
     *
     * getReturnedValue will only be populated in advices of the kind "after".
     * In every other kind of advices, getReturnedValue will be null.
     *
     * @return mixed|null
     */
    public function getReturnedValue();

    /**
     * setReturnedValue enables you to define the resulting value of the triggering method.
     *
     * This function makes sense for advices of kind after, around, exception and final.
     *
     * @param mixed $newValue
     */
    public function setReturnedValue($newValue);

    /**
     * The process method allow you to explicitely launch the triggering method or property
     * operation (read / write).
     *
     * The process method will only be available for advices of kind around.
     *
     * @return mixed
     * @throws AopException
     */
    public function process();

    /**
     * getTriggeringObject returns the object of the triggered joinppoint
     *
     * @return object|null
     */
    public function getTriggeringObject();

    /**
     * getTriggeringClassName returns the object's class name of the triggered joinpoint
     *
     * @return string|null
     */
    public function getTriggeringClassName();

    /**
     * getTriggeringMethodName returns the name of the method of the triggered joinpoint
     *
     * @return string
     */
    public function getTriggeringMethodName();

}

Go! AOP library method invocation is based on aopalliance MethodInvocation:

interface Joinpoint
{

    /**
     * Proceeds to the next interceptor in the chain.
     *
     * <p>The implementation and the semantics of this method depends
     * on the actual joinpoint type (see the children interfaces).
     *
     * @return mixed see the children interfaces' proceed definition.
     */
    public function proceed();

    /**
     * Returns the object that holds the current joinpoint's static
     * part.
     *
     * <p>For instance, the target object for an invocation.
     *
     * @return object|null the object (can be null if the accessible object is
     * static).
     */
    public function getThis();

    /**
     * Returns the static part of this joinpoint.
     *
     * <p>The static part is an accessible object on which a chain of
     * interceptors are installed.
     * @return object
     */
     public function getStaticPart();
}

interface Invocation extends Joinpoint
{

    /**
     * Get the arguments as an array object.
     * It is possible to change element values within this array to change the arguments
     *
     * @return array the arguments of the invocation
     */
    public function getArguments();
}

interface MethodInvocation extends Invocation
{

    /**
     * Gets the method being called.
     *
     * <p>This method is a frienly implementation of the
     * {@link Joinpoint::getStaticPart()} method (same result).
     *
     * @return ReflectionMethod the method being called.
     */
    public function getMethod();

    /**
     * Invokes current method invocation with all interceptors
     *
     * @return mixed
     */
    public function __invoke();
}

CG library (JMSAopBundle) uses MethodInvocation class with following interface:

interface MethodInvocation
{        
    /**
     * Proceeds down the call-chain and eventually calls the original method.
     *
     * @return mixed
     */
    public function proceed();

    /**
     * Returns a string representation of the method.
     *
     * This is intended for debugging purposes only.
     *
     * @return string
     */
    public function __toString();
}

FLOW3 Typo hasn't specific interface for MethodInvocation and uses general JoinPoint interface:

interface JoinPointInterface {

    /**
     * Returns the reference to the proxy class instance
     *
     * @return \TYPO3\FLOW3\Object\Proxy\ProxyInterface
     */
    public function getProxy();

    /**
     * Returns the class name of the target class this join point refers to
     *
     * @return string The class name
     */
    public function getClassName();

    /**
     * Returns the method name of the method this join point refers to
     *
     * @return string The method name
     */
    public function getMethodName();

    /**
     * Returns an array of arguments which have been passed to the target method
     *
     * @return array Array of arguments
     */
    public function getMethodArguments();

    /**
     * Returns the value of the specified method argument
     *
     * @param  string $argumentName Name of the argument
     * @return mixed Value of the argument
     */
    public function getMethodArgument($argumentName);

    /**
     * Returns TRUE if the argument with the specified name exists in the
     * method call this joinpoint refers to.
     *
     * @param string $argumentName Name of the argument to check
     * @return boolean TRUE if the argument exists
     */
    public function isMethodArgument($argumentName);

    /**
     * Sets the value of the specified method argument
     *
     * @param string $argumentName Name of the argument
     * @param mixed $argumentValue Value of the argument
     * @return void
     */
    public function setMethodArgument($argumentName, $argumentValue);

    /**
     * Returns the advice chain related to this join point
     *
     * @return \TYPO3\FLOW3\Aop\Advice\AdviceChain The advice chain
     */
    public function getAdviceChain();

    /**
     * If an exception was thrown by the target method
     * Only makes sense for After Throwing advices.
     *
     * @return boolean
     */
    public function hasException();

    /**
     * Returns the exception which has been thrown in the target method.
     * If no exception has been thrown, NULL is returned.
     * Only makes sense for After Throwing advices.
     *
     * @return \Exception The exception thrown or NULL
     */
    public function getException();

    /**
     * Returns the result of the method invocation. The result is only
     * available for AfterReturning advices.
     *
     * @return mixed Result of the method invocation
     */
    public function getResult();

}

Ray.Aop is based on AOP Alliance MethodInvocation interface (there are minor differences with Go).

interface MethodInvocation extends Invocation
{

    /**
     * Gets the method being called.
     *
     * <p>This method is a friendly implementation of the {@link
     * Joinpoint#getStaticPart()} method (same result).
     *
     * @return \ReflectionMethod method being called.
     */
    public function getMethod();
}

Ding framework hasn't specific interface and uses MethodInvocation class

Interface for it:

interface MethodInvocation
{

    /**
     * Returns information about the original invocation to the (aspected)
     * method. Will return itself as the original invocation if none was set
     * at construction time.
     *
     * @see MethodInvocation::$_originalInvocation
     *
     * @return MethodInvocation
     */
    public function getOriginalInvocation();

    /**
     * Call this one *from* your aspect, in order to proceed with the
     * execution. If you pass any arguments to this method, they will override
     * the original arguments when proceeding to the call.
     *
     * @return void
     */
    public function proceed();

    /**
     * If the target method throws an exception, you can get it here.
     *
     * @return Exception
     */
    public function getException();

    /**
     * Changes (updates) the exception for the execution of the aspected method.
     *
     * @param Exception $value
     *
     * @return void
     */
    public function setException(\Exception $exception);

    /**
     * Returns class name for the executed method.
     *
     * @return string
     */
    public function getClass();

    /**
     * Returns name for the executed method.
     *
     * @return string
     */
    public function getMethod();

    /**
     * Returns the target object for this method
     *
     * @return object
     */
    public function getObject();

    /**
     * Returns arguments for the executed method.
     *
     * @return array
     */
    public function getArguments();
}

Seasar is based on Java AOP Alliance, so interface looks like described one for Go! and Ray.Aop.

lisachenko commented 11 years ago

@geraldcroes @kdambekalns @robertlemke @schmittjoh @koriym Ping

lisachenko commented 11 years ago

@vicb ping