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

com.jfinal.aop.Invocation Maven / Gradle / Ivy

/**
 * Copyright (c) 2011-2021, James Zhan 詹波 ([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 com.jfinal.aop;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.jfinal.proxy.Callback;
import com.jfinal.proxy.ProxyMethod;
import com.jfinal.proxy.ProxyMethodCache;
import com.jfinal.core.Action;
import com.jfinal.core.Controller;

/**
 * Invocation is used to invoke the interceptors and the target method
 */
@SuppressWarnings("unchecked")
public class Invocation {
	
	private static final Object[] NULL_ARGS = new Object[0];	// Prevent new Object[0] by jvm for args of method invoking
	
	private Action action;
	private Object target;
	private Method method;
	private Object[] args;
	private Callback callback;
	private Interceptor[] inters;
	private Object returnValue;
	
	private int index = 0;
	
	public Invocation(Object target, Long proxyMethodKey, Callback callback, Object... args) {
		this.action = null;
		this.target = target;
		
		ProxyMethod proxyMethod = ProxyMethodCache.get(proxyMethodKey);
		this.method = proxyMethod.getMethod();
		this.inters = proxyMethod.getInterceptors();
		
		this.callback = callback;
		this.args = args;
	}
	
	public Invocation(Object target, Long proxyMethodKey, Callback callback) {
		this(target, proxyMethodKey, callback, NULL_ARGS);
	}
	
	/**
	 * 用于扩展 ProxyFactory
	 */
	public Invocation(Object target, Method method, Interceptor[] inters, Callback callback, Object[] args) {
		this.action = null;
		this.target = target;
		
		this.method = method;
		this.inters = inters;
		
		this.callback = callback;
		this.args = args;
	}
	
	// InvocationWrapper need this constructor
	protected Invocation() {
		this.action = null;
	}
	
	public Invocation(Action action, Controller controller) {
		this.action = action;
		this.inters = action.getInterceptors();
		this.target = controller;
		
		// this.args = NULL_ARGS;
		this.args = action.getParameterGetter().get(action, controller);
	}
	
	public void invoke() {
		if (index < inters.length) {
			inters[index++].intercept(this);
		}
		else if (index++ == inters.length) {	// index++ ensure invoke action only one time
			try {
				// Invoke the action
				if (action != null) {
					returnValue = action.getMethod().invoke(target, args);
				}
				// Invoke the callback
				else {
					returnValue = callback.call(args);
				}
			}
			catch (InvocationTargetException e) {
				Throwable t = e.getTargetException();
				if (t == null) {t = e;}
				throw t instanceof RuntimeException ? (RuntimeException)t : new RuntimeException(t);
			}
			catch (RuntimeException e) {
				throw e;
			}
			catch (Throwable t) {
				throw new RuntimeException(t);
			}
		}
	}
	
	public Object getArg(int index) {
		if (index >= args.length)
			throw new ArrayIndexOutOfBoundsException();
		return args[index];
	}
	
	public void setArg(int index, Object value) {
		if (index >= args.length)
			throw new ArrayIndexOutOfBoundsException();
		args[index] = value;
	}
	
	public Object[] getArgs() {
		return args;
	}
	
	/**
	 * Get the target object which be intercepted
	 * 
	 * Example:
	 * OrderService os = getTarget();
	 * 
*/ public T getTarget() { return (T)target; } /** * Return the method of this action. *

* You can getMethod.getAnnotations() to get annotation on action method to do more things */ public Method getMethod() { if (action != null) return action.getMethod(); return method; } /** * Return the method name of this action's method. */ public String getMethodName() { if (action != null) return action.getMethodName(); return method.getName(); } /** * Get the return value of the target method */ public T getReturnValue() { return (T)returnValue; } /** * Set the return value of the target method */ public void setReturnValue(Object returnValue) { this.returnValue = returnValue; } // --------- /** * Return the controller of this action. */ public Controller getController() { if (action == null) throw new RuntimeException("This method can only be used for action interception"); return (Controller)target; } /** * Return the action key. * actionKey = controllerPath + methodName */ public String getActionKey() { if (action == null) throw new RuntimeException("This method can only be used for action interception"); return action.getActionKey(); } /** * Return the controller path. */ public String getControllerPath() { if (action == null) throw new RuntimeException("This method can only be used for action interception"); return action.getControllerPath(); } /** * 该方法已改名为 getControllerPath() */ @Deprecated public String getControllerKey() { return getControllerPath(); } /** * Return view path of this controller. */ public String getViewPath() { if (action == null) throw new RuntimeException("This method can only be used for action interception"); return action.getViewPath(); } /** * return true if it is action invocation. */ public boolean isActionInvocation() { return action != null; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy