All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ru.frostman.web.aop.MethodInvocation Maven / Gradle / Ivy

/******************************************************************************
 * WebJavin - Java Web Framework.                                             *
 *                                                                            *
 * Copyright (c) 2011 - Sergey "Frosman" Lukjanov, [email protected]             *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License");            *
 * you may not use this file except in compliance with the License.           *
 * You may obtain a copy of the License at                                    *
 *                                                                            *
 * http://www.apache.org/licenses/LICENSE-2.0                                 *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 ******************************************************************************/

package ru.frostman.web.aop;

import com.google.common.collect.Lists;
import ru.frostman.web.aop.thr.AopException;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.NoSuchElementException;

/**
 * @author slukjanov aka Frostman
 */
public class MethodInvocation {
    private String className;
    private Class targetClass;

    private Object thisObject;

    private String methodName;
    private Class[] argTypes;

    private Method method;
    private Method targetMethod;

    private Object[] args;

    private LinkedList interceptors = Lists.newLinkedList();

    public MethodInvocation(String className, Object thisObject, String methodName, Class[] argTypes,
                            Object[] args, MethodInterceptor... interceptors) {
        this.className = className;
        this.thisObject = thisObject;
        this.methodName = methodName;
        this.argTypes = argTypes;
        this.args = args;

        for (MethodInterceptor interceptor : interceptors) {
            this.interceptors.addLast(interceptor);
        }
    }

    /**
     * Proceeds to the next interceptor in the chain
     *
     * @return result of invoking next method interceptor or target method
     */
    public Object proceed() {
        MethodInterceptor interceptor;
        try {
            interceptor = interceptors.removeFirst();
        } catch (NoSuchElementException ex) {
            try {
                return getTargetMethod().invoke(getThis(), getArgs());
            } catch (Exception e) {
                throw new AopException("Exception while invoking target method: "
                        + getClassName() + "#" + getMethodName(), e);
            }
        }

        return interceptor.invoke(this);
    }

    private String getClassName() {
        return className;
    }

    public Class getTargetClass() {
        if (targetClass == null) {
            if (thisObject != null) {
                targetClass = thisObject.getClass();
            } else {
                try {
                    targetClass = Thread.currentThread().getContextClassLoader().loadClass(className);
                } catch (ClassNotFoundException e) {
                    throw new AopException("Exception while loading target class: " + className, e);
                }
            }
        }

        return targetClass;
    }

    public Object getThis() {
        return thisObject;
    }

    private String getMethodName() {
        return methodName;
    }

    public Class[] getArgTypes() {
        return argTypes;
    }

    public Method getMethod() {
        if (method == null) {
            method = getMethodByName(getMethodName());
        }

        return method;
    }

    private Method getTargetMethod() {
        if (targetMethod == null) {
            targetMethod = getMethodByName("$javin$" + getMethodName());
        }

        return targetMethod;
    }


    private Method getMethodByName(String methodName) {
        try {
            //todo cache such methods to improve performance
            Method method = getTargetClass().getDeclaredMethod(methodName, getArgTypes());
            method.setAccessible(true);

            return method;
        } catch (NoSuchMethodException e) {
            throw new AopException("Method not found: " + getMethodName() + " " + Arrays.toString(getArgTypes()), e);
        }
    }

    public Object[] getArgs() {
        return args;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy