interceptorcallchain.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 521 行
JAVA
521 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */package com.caucho.ejb.gen;import com.caucho.java.JavaWriter;import com.caucho.util.L10N;import com.caucho.webbeans.component.*;import com.caucho.webbeans.manager.*;import java.io.*;import java.lang.annotation.*;import java.lang.reflect.*;import java.util.*;import javax.annotation.security.*;import javax.ejb.*;import javax.interceptor.*;import javax.webbeans.*;/** * Represents the interception */public class InterceptorCallChain extends AbstractCallChain { private static final L10N L = new L10N(InterceptorCallChain.class); private View _view; private BusinessMethodGenerator _next; private String _uniqueName; private Method _implMethod; private ArrayList<Class> _defaultInterceptors = new ArrayList<Class>(); private ArrayList<Class> _classInterceptors = new ArrayList<Class>(); private ArrayList<Class> _methodInterceptors = new ArrayList<Class>(); private boolean _isExcludeDefaultInterceptors; private boolean _isExcludeClassInterceptors; private ArrayList<Class> _interceptors = new ArrayList<Class>(); // map from the interceptor class to the local variable for the interceptor private HashMap<Class,String> _interceptorVarMap = new HashMap<Class,String>(); // interceptors we're responsible for initializing private ArrayList<Class> _ownInterceptors = new ArrayList<Class>(); public InterceptorCallChain(BusinessMethodGenerator next, View view) { super(next); _next = next; _view = view; } /** * Returns true if the business method has any active XA annotation. */ public boolean isEnhanced() { return (_defaultInterceptors.size() > 0 || (! _isExcludeDefaultInterceptors && _view.getBean().getDefaultInterceptors().size() > 0) || _classInterceptors.size() > 0 || _methodInterceptors.size() > 0 || getAroundInvokeMethod() != null); } public ArrayList<Class> getInterceptors() { return _interceptors; } public Method getAroundInvokeMethod() { return _view.getAroundInvokeMethod(); } /** * Introspects the @Interceptors annotation on the method * and the class. */ public void introspect(Method apiMethod, Method implMethod) { if (implMethod == null) return; Class apiClass = apiMethod.getDeclaringClass(); Class implClass = implMethod.getDeclaringClass(); _implMethod = implMethod; Interceptors iAnn; iAnn = (Interceptors) apiClass.getAnnotation(Interceptors.class); if (iAnn != null) { for (Class iClass : iAnn.value()) _classInterceptors.add(iClass); } if (implClass != null) { iAnn = (Interceptors) implClass.getAnnotation(Interceptors.class); if (apiMethod != implMethod && iAnn != null) { for (Class iClass : iAnn.value()) _classInterceptors.add(iClass); } } iAnn = (Interceptors) apiMethod.getAnnotation(Interceptors.class); if (iAnn != null) { for (Class iClass : iAnn.value()) _methodInterceptors.add(iClass); } if (implMethod != null) { iAnn = (Interceptors) implMethod.getAnnotation(Interceptors.class); if (apiMethod != implMethod && iAnn != null) { for (Class iClass : iAnn.value()) _methodInterceptors.add(iClass); } } if (apiMethod.isAnnotationPresent(ExcludeClassInterceptors.class)) _isExcludeClassInterceptors = true; if (implMethod.isAnnotationPresent(ExcludeClassInterceptors.class)) _isExcludeClassInterceptors = true; if (apiMethod.isAnnotationPresent(ExcludeDefaultInterceptors.class)) _isExcludeDefaultInterceptors = true; if (implMethod.isAnnotationPresent(ExcludeDefaultInterceptors.class)) _isExcludeDefaultInterceptors = true; // webbeans annotations WebBeansContainer webBeans = WebBeansContainer.create(); ArrayList<Annotation> interceptorTypes = new ArrayList<Annotation>(); for (Annotation ann : implMethod.getAnnotations()) { Class annType = ann.annotationType(); if (annType.isAnnotationPresent(InterceptorBindingType.class)) interceptorTypes.add(ann); } if (interceptorTypes.size() > 0) { ArrayList<Class> interceptors = webBeans.findInterceptors(interceptorTypes); if (interceptors != null) _methodInterceptors.addAll(interceptors); } } @Override public void generatePrologue(JavaWriter out, HashMap map) throws IOException { if (! isEnhanced()) { _next.generatePrologue(out, map); return; } if (! _isExcludeDefaultInterceptors) _interceptors.addAll(_view.getBean().getDefaultInterceptors()); // ejb/0fb6 if (! _isExcludeClassInterceptors && _interceptors.size() == 0) _interceptors.addAll(_classInterceptors); _interceptors.addAll(_methodInterceptors); if (_interceptors.size() == 0 && getAroundInvokeMethod() == null) return; _uniqueName = "_v" + out.generateId(); out.println(); out.println("private static java.lang.reflect.Method " + _uniqueName + "_method;"); out.println("private static java.lang.reflect.Method " + _uniqueName + "_implMethod;"); boolean isAroundInvokePrologue = false; if (getAroundInvokeMethod() != null && map.get("ejb.around-invoke") == null) { isAroundInvokePrologue = true; map.put("ejb.around-invoke", "_caucho_aroundInvokeMethod"); out.println("private static java.lang.reflect.Method __caucho_aroundInvokeMethod;"); } out.println("private static java.lang.reflect.Method []" + _uniqueName + "_methodChain;"); out.println("private transient Object []" + _uniqueName + "_objectChain;"); Class cl = _implMethod.getDeclaringClass(); out.println(); out.println("static {"); out.pushDepth(); out.println("try {"); out.pushDepth(); out.print(_uniqueName + "_method = "); generateGetMethod(out, _implMethod.getDeclaringClass().getName(), _implMethod.getName(), _implMethod.getParameterTypes()); out.println(";"); out.println(_uniqueName + "_method.setAccessible(true);"); out.print(_uniqueName + "_implMethod = "); generateGetMethod(out, _next.getView().getBeanClassName(), "__caucho_" + _implMethod.getName(), _implMethod.getParameterTypes()); out.println(";"); out.println(_uniqueName + "_implMethod.setAccessible(true);"); if (isAroundInvokePrologue) { Method aroundInvoke = getAroundInvokeMethod(); out.print("__caucho_aroundInvokeMethod = "); generateGetMethod(out, aroundInvoke.getDeclaringClass().getName(), aroundInvoke.getName(), aroundInvoke.getParameterTypes()); out.println(";"); out.println("__caucho_aroundInvokeMethod.setAccessible(true);"); } generateMethodChain(out); out.popDepth(); out.println("} catch (Exception e) {"); out.println(" throw new RuntimeException(e);"); out.println("}"); out.popDepth(); out.println("}"); for (Class iClass : _interceptors) { String var = (String) map.get("interceptor-" + iClass.getName()); if (var == null) { var = "__caucho_i" + out.generateId(); out.println(); out.print("private static "); out.printClass(ComponentFactory.class); out.println(" " + var + "_f;"); out.print("private transient "); out.printClass(iClass); out.println(" " + var + ";"); map.put("interceptor-" + iClass.getName(), var); _ownInterceptors.add(iClass); } _interceptorVarMap.put(iClass, var); } _next.generatePrologue(out, map); } @Override public void generateConstructor(JavaWriter out, HashMap map) throws IOException { for (Class iClass : _ownInterceptors) { String var = _interceptorVarMap.get(iClass); out.println("if (" + var + "_f == null)"); out.println(" " + var + "_f = com.caucho.webbeans.manager.WebBeansContainer.create().createTransient(" + iClass.getName() + ".class);"); out.print(var + " = ("); out.printClass(iClass); out.println(")" + var + "_f.get();"); } _next.generateConstructor(out, map); } @Override public void generateCall(JavaWriter out) throws IOException { if (_interceptors.size() == 0 && getAroundInvokeMethod() == null) { _next.generateCall(out); return; } out.println("try {"); out.pushDepth(); out.print("if ("); generateThis(out); out.println("." + _uniqueName + "_objectChain == null) {"); out.pushDepth(); generateObjectChain(out); out.popDepth(); out.println("}"); if (! void.class.equals(_implMethod.getReturnType())) { out.printClass(_implMethod.getReturnType()); out.println(" result;"); } if (! void.class.equals(_implMethod.getReturnType())) { out.print("result = ("); printCastClass(out, _implMethod.getReturnType()); out.print(") "); } out.print("new com.caucho.ejb3.gen.InvocationContextImpl("); generateThis(out); out.print(", "); generateThis(out); out.print("." + _uniqueName + "_method, "); generateThis(out); out.print("." + _uniqueName + "_implMethod, "); generateThis(out); out.print("." + _uniqueName + "_methodChain, "); generateThis(out); out.print("." + _uniqueName + "_objectChain, "); out.print("new Object[] { "); for (int i = 0; i < _implMethod.getParameterTypes().length; i++) { out.print("a" + i + ", "); } out.println("}).proceed();"); _next.generatePreReturn(out); if (! void.class.equals(_implMethod.getReturnType())) { out.println("return result;"); } out.popDepth(); out.println("} catch (RuntimeException e) {"); out.println(" throw e;"); boolean isException = false; Class []exnList = _implMethod.getExceptionTypes(); for (Class cl : exnList) { if (RuntimeException.class.isAssignableFrom(cl)) continue; if (! isMostGeneralException(exnList, cl)) continue; if (cl.isAssignableFrom(Exception.class)) isException = true; out.println("} catch (" + cl.getName() + " e) {"); out.println(" throw e;"); } if (! isException) { out.println("} catch (Exception e) {"); out.println(" throw new RuntimeException(e);"); } out.println("}"); } protected void generateThis(JavaWriter out) throws IOException { _next.generateThis(out); } private boolean isMostGeneralException(Class []exnList, Class cl) { for (Class exn : exnList) { if (exn != cl && exn.isAssignableFrom(cl)) return false; } return true; } protected Method findInterceptorMethod(Class cl) { if (cl == null) return null; for (Method method : cl.getDeclaredMethods()) { if (method.isAnnotationPresent(AroundInvoke.class)) return method; } return findInterceptorMethod(cl.getSuperclass()); } protected void generateMethodChain(JavaWriter out) throws IOException { out.println(_uniqueName + "_methodChain = new java.lang.reflect.Method[] {"); out.pushDepth(); for (Class iClass : _interceptors) { Method method = findInterceptorMethod(iClass); if (method == null) throw new IllegalStateException(L.l("Can't find @AroundInvoke in '{0}'", iClass.getName())); generateGetMethod(out, method); out.println(", "); } if (getAroundInvokeMethod() != null) { out.println("__caucho_aroundInvokeMethod, "); } out.popDepth(); out.println("};"); } protected void generateObjectChain(JavaWriter out) throws IOException { generateThis(out); out.print("." + _uniqueName + "_objectChain = new Object[] { "); for (Class iClass : _interceptors) { generateThis(out); out.print("." + _interceptorVarMap.get(iClass) + ", "); } if (getAroundInvokeMethod() != null) { generateThis(out); out.print(", "); } out.println("};"); } protected void generateGetMethod(JavaWriter out, Method method) throws IOException { generateGetMethod(out, method.getDeclaringClass().getName(), method.getName(), method.getParameterTypes()); } protected void generateGetMethod(JavaWriter out, String className, String methodName, Class []paramTypes) throws IOException { out.print("com.caucho.ejb.util.EjbUtil.getMethod("); out.print(className + ".class"); out.print(", \"" + methodName + "\", new Class[] { "); for (Class type : paramTypes) { out.printClass(type); out.print(".class, "); } out.print("})"); } protected void printCastClass(JavaWriter out, Class type) throws IOException { if (! type.isPrimitive()) out.printClass(type); else if (boolean.class.equals(type)) out.print("Boolean"); else if (char.class.equals(type)) out.print("Character"); else if (byte.class.equals(type)) out.print("Byte"); else if (short.class.equals(type)) out.print("Short"); else if (int.class.equals(type)) out.print("Integer"); else if (long.class.equals(type)) out.print("Long"); else if (float.class.equals(type)) out.print("Float"); else if (double.class.equals(type)) out.print("Double"); else throw new IllegalStateException(type.getName()); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?