001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free SoftwareFoundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Rodrigo Westrupp
028: */
029:
030: package com.caucho.ejb.cfg;
031:
032: import com.caucho.bytecode.*;
033: import com.caucho.log.Log;
034: import com.caucho.util.L10N;
035: import com.caucho.vfs.PersistentDependency;
036:
037: import java.lang.reflect.Method;
038: import java.security.AccessController;
039: import java.security.PrivilegedActionException;
040: import java.security.PrivilegedExceptionAction;
041: import java.util.ArrayList;
042: import java.util.logging.Logger;
043: import javax.annotation.PostConstruct;
044: import javax.interceptor.AroundInvoke;
045: import javax.interceptor.InvocationContext;
046:
047: /**
048: * Configuration for an interceptor.
049: */
050: public class Interceptor {
051: private static Logger log = Log.open(Interceptor.class);
052: private static final L10N L = new L10N(Interceptor.class);
053:
054: private String _interceptorClass;
055: private String _aroundInvokeMethodName;
056:
057: private AroundInvokeConfig _aroundInvokeConfig;
058:
059: private PreDestroyConfig _preDestroyConfig;
060: private PostConstructConfig _postConstructConfig;
061:
062: private PrePassivateConfig _prePassivateConfig;
063: private PostActivateConfig _postActivateConfig;
064:
065: private String _postConstructMethodName;
066:
067: private ClassLoader _loader;
068: protected JClassLoader _jClassLoader;
069:
070: private JClass _interceptorJClass;
071:
072: ArrayList<PersistentDependency> _dependList = new ArrayList<PersistentDependency>();
073:
074: public Interceptor() {
075: _loader = Thread.currentThread().getContextClassLoader();
076:
077: _jClassLoader = JClassLoaderWrapper.create(_loader);
078: }
079:
080: public JClass getInterceptorJClass() {
081: return _interceptorJClass;
082: }
083:
084: public String getInterceptorClass() {
085: return _interceptorClass;
086: }
087:
088: public void setInterceptorClass(String interceptorClass) {
089: _interceptorClass = interceptorClass;
090: }
091:
092: public void init() {
093: // ejb/0fb5
094: if (_aroundInvokeConfig != null)
095: _aroundInvokeMethodName = _aroundInvokeConfig
096: .getMethodName();
097:
098: // ejb/0fbi
099: if (_postConstructConfig != null)
100: _postConstructMethodName = _postConstructConfig
101: .getLifecycleCallbackMethod();
102:
103: if (_aroundInvokeMethodName == null
104: || _postConstructMethodName == null) {
105: // XXX: EnhancerManager getJavaClassLoader()
106: // ClassLoader parentLoader = Thread.currentThread().getContextClassLoader();
107: // JClassLoader jClassLoader = EnhancerManager.create(parentLoader).getJavaClassLoader();
108:
109: _interceptorJClass = _jClassLoader
110: .forName(_interceptorClass);
111:
112: JClass cl = _interceptorJClass;
113:
114: do {
115: for (JMethod method : _interceptorJClass
116: .getDeclaredMethods()) {
117: if (method.isAnnotationPresent(AroundInvoke.class)) {
118: // XXX: throw exception for invalid final or static.
119:
120: if (_aroundInvokeMethodName == null)
121: _aroundInvokeMethodName = method.getName();
122: else if (cl == _interceptorJClass) {
123: // XXX: throw exception for invalid duplicated @AroundInvoke methods.
124: }
125: }
126:
127: if (method.isAnnotationPresent(PostConstruct.class)) {
128: // XXX: throw exception for invalid final or static.
129:
130: if (_postConstructMethodName == null)
131: _postConstructMethodName = method.getName();
132: else if (cl == _interceptorJClass) {
133: // XXX: throw exception for invalid duplicated @PostConstruct methods.
134: } else {
135: // XXX: needs to call superclass lifecycle callback methods.
136: }
137: }
138: }
139: } while ((cl = cl.getSuperClass()) != null);
140: }
141: }
142:
143: public static void makeAccessible(final Method method) {
144: try {
145: AccessController
146: .doPrivileged(new PrivilegedExceptionAction() {
147: public Object run() {
148: method.setAccessible(true);
149: return null;
150: }
151: });
152: } catch (PrivilegedActionException e) {
153: throw new RuntimeException(e.getException());
154: }
155: }
156:
157: public Method getAroundInvokeMethod() {
158: return getAroundInvokeMethod(_interceptorJClass.getJavaClass(),
159: _aroundInvokeMethodName);
160: }
161:
162: public static Method getAroundInvokeMethod(Class cl,
163: String methodName) {
164: // ejb/0fbm
165: for (Method method : cl.getDeclaredMethods()) {
166: if (method.getName().equals(methodName)) {
167: Class paramTypes[] = method.getParameterTypes();
168:
169: if (paramTypes.length != 1)
170: continue;
171:
172: if (!paramTypes[0].equals(InvocationContext.class))
173: continue;
174:
175: method.setAccessible(true);
176:
177: return method;
178: }
179: }
180:
181: return null;
182: }
183:
184: public String getAroundInvokeMethodName() {
185: return _aroundInvokeMethodName;
186: }
187:
188: public String getPostConstructMethodName() {
189: return _postConstructMethodName;
190: }
191:
192: public PostActivateConfig getPostActivate() {
193: return _postActivateConfig;
194: }
195:
196: public PostConstructConfig getPostConstruct() {
197: return _postConstructConfig;
198: }
199:
200: public PreDestroyConfig getPreDestroy() {
201: return _preDestroyConfig;
202: }
203:
204: public PrePassivateConfig getPrePassivate() {
205: return _prePassivateConfig;
206: }
207:
208: public void setAroundInvoke(AroundInvokeConfig aroundInvoke) {
209: _aroundInvokeConfig = aroundInvoke;
210: }
211:
212: public void setPostActivate(PostActivateConfig postActivate) {
213: _postActivateConfig = postActivate;
214: }
215:
216: public void setPostConstruct(PostConstructConfig postConstruct) {
217: _postConstructConfig = postConstruct;
218: }
219:
220: public void setPreDestroy(PreDestroyConfig preDestroy) {
221: _preDestroyConfig = preDestroy;
222: }
223:
224: public void setPrePassivate(PrePassivateConfig prePassivate) {
225: _prePassivateConfig = prePassivate;
226: }
227:
228: public String toString() {
229: return "Interceptor[" + _interceptorClass + "]";
230: }
231: }
|