KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > ejb > containers > EJBObjectInvocationHandler


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.ejb.containers;
24
25 import java.lang.reflect.InvocationHandler JavaDoc;
26 import java.lang.reflect.InvocationTargetException JavaDoc;
27 import java.lang.reflect.Proxy JavaDoc;
28 import java.lang.reflect.Method JavaDoc;
29
30 import java.util.Iterator JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.logging.Logger JavaDoc;
34 import java.util.logging.Level JavaDoc;
35
36 import java.rmi.RemoteException JavaDoc;
37
38 import javax.ejb.EJBException JavaDoc;
39 import javax.ejb.EJBObject JavaDoc;
40 import com.sun.ejb.Invocation;
41 import com.sun.ejb.InvocationInfo;
42 import com.sun.ejb.Container;
43 import com.sun.ejb.containers.util.MethodMap;
44 import com.sun.enterprise.EJBObjectToTie;
45 import com.sun.enterprise.util.LocalStringManagerImpl;
46 import com.sun.enterprise.util.Utility;
47 import com.sun.logging.LogDomains;
48
49 /**
50  * Handler for EJBObject invocations through EJBObject proxy.
51  *
52  *
53  * @author Kenneth Saks
54  */

55
56 public final class EJBObjectInvocationHandler
57     extends EJBObjectImpl implements InvocationHandler JavaDoc {
58
59     private static Logger JavaDoc logger = LogDomains.getLogger(LogDomains.EJB_LOGGER);
60
61     private static LocalStringManagerImpl localStrings =
62         new LocalStringManagerImpl(EJBObjectInvocationHandler.class);
63
64     // Cache reference to invocation info populated during container
65
// initialization. This avoids the overhead of building the method
66
// info each time a proxy is created.
67
private MethodMap invocationInfoMap_;
68
69     private Class JavaDoc remoteIntf_;
70
71     /**
72      * Constructor used for Remote Home view.
73      */

74     public EJBObjectInvocationHandler(MethodMap invocationInfoMap,
75                                       Class JavaDoc remoteIntf)
76         throws Exception JavaDoc {
77
78         invocationInfoMap_ = invocationInfoMap;
79
80         remoteIntf_ = remoteIntf;
81         setIsRemoteHomeView(true);
82
83         // NOTE : Container is not set on super-class until after
84
// constructor is called.
85
}
86
87     /**
88      * Constructor used for Remote Business view.
89      */

90     public EJBObjectInvocationHandler(MethodMap invocationInfoMap)
91         throws Exception JavaDoc {
92
93         invocationInfoMap_ = invocationInfoMap;
94
95         setIsRemoteHomeView(false);
96
97         // NOTE : Container is not set on super-class until after
98
// constructor is called.
99
}
100
101     /**
102      * This entry point is only used for the Remote Home view.
103      */

104     public Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args)
105         throws Throwable JavaDoc {
106
107         return invoke(remoteIntf_, method, args);
108     }
109
110     Object JavaDoc invoke(Class JavaDoc clientInterface, Method JavaDoc method, Object JavaDoc[] args)
111         throws Throwable JavaDoc {
112
113         ClassLoader JavaDoc originalClassLoader = null;
114
115         // NOTE : be careful with "args" parameter. It is null
116
// if method signature has 0 arguments.
117
try {
118             container.onEnteringContainer();
119
120             // In some cases(e.g. if the Home/Remote interfaces appear in
121
// a parent of the application's classloader),
122
// ServantLocator.preinvoke() will not be called by the
123
// ORB, and therefore BaseContainer.externalPreInvoke will not have
124
// been called for this invocation. In those cases we need to set
125
// the context classloader to the application's classloader before
126
// proceeding. Otherwise, the context classloader could still
127
// reflect the caller's class loader.
128

129             if( Thread.currentThread().getContextClassLoader() !=
130                 getContainer().getClassLoader() ) {
131                 originalClassLoader = Utility.setContextClassLoader
132                     (getContainer().getClassLoader());
133             }
134             
135             Class JavaDoc methodClass = method.getDeclaringClass();
136             if( methodClass == java.lang.Object JavaDoc.class ) {
137                 return InvocationHandlerUtil.invokeJavaObjectMethod
138                     (this, method, args);
139             }
140             
141             // Use optimized version of get that takes param count as an
142
// argument.
143
InvocationInfo invInfo = (InvocationInfo)
144                 invocationInfoMap_.get(method,
145                                        ((args != null) ? args.length : 0) );
146             
147             if( invInfo == null ) {
148                 throw new RemoteException JavaDoc("Unknown Remote interface method :"
149                                           + method);
150             }
151             
152             if( (methodClass == javax.ejb.EJBObject JavaDoc.class) ||
153                 invInfo.ejbIntfOverride ) {
154                 return invokeEJBObjectMethod(method.getName(), args);
155             } else if( invInfo.targetMethod1 == null ) {
156                 Object JavaDoc [] params = new Object JavaDoc[]
157                     { invInfo.ejbName, "Remote", invInfo.method.toString() };
158                 String JavaDoc errorMsg = localStrings.getLocalString
159                     ("ejb.bean_class_method_not_found", "", params);
160               
161                 logger.log(Level.SEVERE, "ejb.bean_class_method_not_found",
162                        params);
163                 throw new RemoteException JavaDoc(errorMsg);
164             }
165             
166             // Process application-specific method.
167

168             Object JavaDoc returnValue = null;
169             
170             Invocation inv = new Invocation();
171             
172             inv.isLocal = false;
173             inv.isHome = false;
174             inv.isBusinessInterface = !isRemoteHomeView();
175             inv.ejbObject = this;
176             inv.method = method;
177
178             inv.clientInterface = clientInterface;
179
180             // Set cached invocation params. This will save additional lookups
181
// in BaseContainer.
182
inv.transactionAttribute = invInfo.txAttr;
183             inv.securityPermissions = invInfo.securityPermissions;
184             inv.invocationInfo = invInfo;
185             inv.beanMethod = invInfo.targetMethod1;
186             inv.methodParams = args;
187             
188             try {
189                 container.preInvoke(inv);
190                 returnValue = container.intercept(inv);
191             } catch(InvocationTargetException JavaDoc ite) {
192                 inv.exception = ite.getCause();
193                 inv.exceptionFromBeanMethod = inv.exception;
194             } catch(Throwable JavaDoc t) {
195                 inv.exception = t;
196             } finally {
197                 container.postInvoke(inv);
198             }
199             
200             if (inv.exception != null) {
201                 InvocationHandlerUtil.throwRemoteException
202                     (inv.exception, method.getExceptionTypes());
203             }
204             
205             return returnValue;
206         } finally {
207             
208             if( originalClassLoader != null ) {
209                 Utility.setContextClassLoader(originalClassLoader);
210             }
211
212             container.onLeavingContainer();
213         }
214     }
215
216
217     private Object JavaDoc invokeEJBObjectMethod(String JavaDoc methodName, Object JavaDoc[] args)
218         throws Exception JavaDoc
219     {
220         // Return value is null if target method returns void.
221
Object JavaDoc returnValue = null;
222
223
224         // NOTE : Might be worth optimizing this method check if it
225
// turns out to be a bottleneck. I don't think these methods
226
// are called with the frequency that this would be an issue,
227
// but it's worth considering.
228

229         if( methodName.equals("getEJBHome") ) {
230
231             returnValue = super.getEJBHome();
232
233         } else if( methodName.equals("getHandle") ) {
234
235             returnValue = super.getHandle();
236
237         } else if( methodName.equals("getPrimaryKey") ) {
238
239             returnValue = super.getPrimaryKey();
240
241         } else if( methodName.equals("isIdentical") ) {
242
243             // boolean isIdentical(EJBObject)
244
// Convert the param into an EJBObject.
245
EJBObject JavaDoc other = (EJBObject JavaDoc) args[0];
246
247             returnValue = new Boolean JavaDoc(super.isIdentical(other));
248
249         } else if( methodName.equals("remove") ) {
250
251             super.remove();
252
253         } else {
254
255             throw new RemoteException JavaDoc("unknown EJBObject method = "
256                                       + methodName);
257         }
258
259         return returnValue;
260     }
261
262 }
263
Popular Tags