KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openejb > client > EJBObjectHandler


1 /**
2  * Redistribution and use of this software and associated documentation
3  * ("Software"), with or without modification, are permitted provided
4  * that the following conditions are met:
5  *
6  * 1. Redistributions of source code must retain copyright
7  * statements and notices. Redistributions must also contain a
8  * copy of this document.
9  *
10  * 2. Redistributions in binary form must reproduce the
11  * above copyright notice, this list of conditions and the
12  * following disclaimer in the documentation and/or other
13  * materials provided with the distribution.
14  *
15  * 3. The name "OpenEJB" must not be used to endorse or promote
16  * products derived from this Software without prior written
17  * permission of The OpenEJB Group. For written permission,
18  * please contact dev@openejb.org.
19  *
20  * 4. Products derived from this Software may not be called "OpenEJB"
21  * nor may "OpenEJB" appear in their names without prior written
22  * permission of The OpenEJB Group. OpenEJB is a registered
23  * trademark of The OpenEJB Group.
24  *
25  * 5. Due credit should be given to the OpenEJB Project
26  * (http://www.openejb.org/).
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32  * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39  * OF THE POSSIBILITY OF SUCH DAMAGE.
40  *
41  * Copyright 2001 (C) The OpenEJB Group. All Rights Reserved.
42  *
43  * $Id: EJBObjectHandler.java 1912 2005-06-16 22:29:56Z jlaskowski $
44  */

45 package org.openejb.client;
46
47 import java.lang.reflect.Method JavaDoc;
48 import java.rmi.RemoteException JavaDoc;
49
50 import javax.ejb.EJBObject JavaDoc;
51
52 import org.openejb.client.proxy.ProxyManager;
53
54 /**
55  *
56  * @author <a HREF="mailto:david.blevins@visi.com">David Blevins</a>
57  * @since 11/25/2001
58  */

59 public abstract class EJBObjectHandler extends EJBInvocationHandler {
60                      
61
62     protected static final Method JavaDoc GETEJBHOME = getMethod(EJBObject JavaDoc.class, "getEJBHome", null);
63     protected static final Method JavaDoc GETHANDLE = getMethod(EJBObject JavaDoc.class, "getHandle", null);
64     protected static final Method JavaDoc GETPRIMARYKEY = getMethod(EJBObject JavaDoc.class, "getPrimaryKey", null);
65     protected static final Method JavaDoc ISIDENTICAL = getMethod(EJBObject JavaDoc.class, "isIdentical", new Class JavaDoc []{EJBObject JavaDoc.class});
66     protected static final Method JavaDoc REMOVE = getMethod(EJBObject JavaDoc.class, "remove", null);
67     
68     protected static final Method JavaDoc GETHANDLER = getMethod(EJBObjectProxy.class, "getEJBObjectHandler", null);
69     
70     /*
71     * The registryId is a logical identifier that is used as a key when placing EntityEJBObjectHandler into
72     * the BaseEjbProxyHanlder's liveHandleRegistry. EntityEJBObjectHandlers that represent the same
73     * bean identity (keyed by the registry id) will be stored together so that they can be removed together
74     * when the EJBInvocationHandler.invalidateAllHandlers is invoked. The EntityEJBObjectHandler uses a
75     * compound key composed of the entity bean's primary key, deployment id, and
76     * container id. This uniquely identifies the bean identity that is proxied by this handler allowing it
77     * to be removed with other handlers bound to the same registry id.
78     */

79     public Object JavaDoc registryId;
80
81
82     EJBHomeProxy ejbHome = null;
83
84     // new Class []{javax.ejb.EntityContext.class}
85

86     public EJBObjectHandler(){
87     }
88     
89     public EJBObjectHandler(EJBMetaDataImpl ejb, ServerMetaData server, ClientMetaData client){
90         super(ejb, server, client);
91     }
92     
93     public EJBObjectHandler(EJBMetaDataImpl ejb, ServerMetaData server, ClientMetaData client, Object JavaDoc primaryKey){
94         super(ejb, server, client, primaryKey);
95     }
96     
97     protected void setEJBHomeProxy(EJBHomeProxy ejbHome){
98         this.ejbHome = ejbHome;
99     }
100
101     public static EJBObjectHandler createEJBObjectHandler(EJBMetaDataImpl ejb, ServerMetaData server, ClientMetaData client, Object JavaDoc primaryKey){
102         
103         switch (ejb.type) {
104             case EJBMetaDataImpl.BMP_ENTITY:
105             case EJBMetaDataImpl.CMP_ENTITY:
106                 
107                 return new EntityEJBObjectHandler(ejb, server, client, primaryKey);
108             
109             case EJBMetaDataImpl.STATEFUL:
110                 
111                 return new StatefulEJBObjectHandler(ejb, server, client, primaryKey);
112             
113             case EJBMetaDataImpl.STATELESS:
114                 
115                 return new StatelessEJBObjectHandler(ejb, server, client, primaryKey);
116         }
117         return null;
118     }
119     /**
120     * The Registry id is a logical identifier that is used as a key when placing EjbObjectProxyHanlders into
121     * the BaseEjbProxyHanlder's liveHandleRegistry. EjbObjectProxyHanlders that represent the same
122     * bean identity (keyed by the registry id) will be stored together so that they can be removed together
123     * when the EJBInvocationHandler.invalidateAllHandlers is invoked.
124     *
125     * This method is implemented by the subclasses to return an id that logically identifies
126     * bean identity for a specific deployment id and container. For example, the EntityEJBObjectHandler
127     * overrides this method to return a compound key composed of the bean's primary key, deployment id, and
128     * container id. This uniquely identifies the bean identity that is proxied by this handler. Another example
129     * is the StatefulEjbObjectHanlder which overrides this method to return the stateful bean's hidden primary key,
130     * which is a java.rmi.dgc.VMID.
131     */

132     public abstract Object JavaDoc getRegistryId();
133
134     public EJBObjectProxy createEJBObjectProxy(){
135         
136         EJBObjectProxy ejbObject = null;
137         
138         try{
139             
140             Class JavaDoc[] interfaces = new Class JavaDoc[]{ EJBObjectProxy.class, ejb.remoteClass };
141             ejbObject = (EJBObjectProxy) ProxyManager.newProxyInstance(interfaces, this);
142         
143         } catch (IllegalAccessException JavaDoc e){
144             //TODO:1: Better exception handling.
145
e.printStackTrace();
146         }
147         return ejbObject;
148     }
149
150
151     // The EJBObject stub is synchronized to prevent multiple client threads from accessing the
152
// stub concurrently. This is required by session beans (6.5.6 Serializing session bean methods) but
153
// not required by entity beans. Implementing synchronization on the stub prohibits multiple threads from currently
154
// invoking methods on the same stub, but doesn't prohibit a client from having multiple references to the same
155
// entity identity. Synchronizing the stub is a simple and elegant solution to a difficult problem.
156
//
157
public synchronized Object JavaDoc _invoke(Object JavaDoc p, Method JavaDoc m, Object JavaDoc[] a) throws Throwable JavaDoc{
158
159         Object JavaDoc retValue = null;
160         /*
161          * This section is to be replaced by a more appropriate solution.
162          * This code is very temporary.
163          */

164         
165         try{
166    
167             String JavaDoc methodName = m.getName();
168             if (m.getDeclaringClass() == Object JavaDoc.class ) {
169                 if ( m.equals( TOSTRING ) ){
170                     return "proxy="+this;
171                 } else if ( m.equals( EQUALS ) ) {
172                     //TODO
173
return Boolean.FALSE;
174                     // Maybe turn this into Externalizable
175
} else if ( m.equals( HASHCODE ) ) {
176                     return new Integer JavaDoc( this.hashCode() );
177                 } else {
178                     throw new UnsupportedOperationException JavaDoc("Unkown method: "+m);
179                 }
180             } else if (m.getDeclaringClass() == EJBObjectProxy.class ) {
181                 if ( m.equals( GETHANDLER ) ){
182                     return this;
183                 } else if (methodName.equals("writeReplace")) {
184                     return new EJBObjectProxyHandle(this);
185                 } else if (methodName.equals("readResolve")) {
186                     //TODO
187
// Maybe turn this into Externalizable
188
} else {
189                     throw new UnsupportedOperationException JavaDoc("Unkown method: "+m);
190                 }
191             } else if ( m.getDeclaringClass() == javax.ejb.EJBObject JavaDoc.class) {
192                 if( m.equals( GETHANDLE )) retValue = getHandle(m,a,p);
193                 else if(m.equals(GETPRIMARYKEY)) retValue = getPrimaryKey(m,a,p);
194                 else if(m.equals(ISIDENTICAL)) retValue = isIdentical(m,a,p);
195                 else if(m.equals(GETEJBHOME)) retValue = getEJBHome(m,a,p);
196                 else if(m.equals(REMOVE)) retValue = remove(m,a,p);
197                 else throw new UnsupportedOperationException JavaDoc("Unkown method: "+m);
198             } else if ( m.getDeclaringClass() == ejb.remoteClass ) {
199                 retValue = businessMethod(m,a,p);
200             } else {
201                 throw new UnsupportedOperationException JavaDoc("Unkown method: "+m);
202             }
203             
204         
205         /*
206          * The ire is thrown by the container system and propagated by
207          * the server to the stub.
208          */

209         }catch ( org.openejb.InvalidateReferenceException ire ) {
210             invalidateAllHandlers(getRegistryId());
211             return ire.getRootCause();
212         /*
213          * Application exceptions must be reported dirctly to the client. They
214          * do not impact the viability of the proxy.
215          */

216         } catch ( org.openejb.ApplicationException ae ) {
217             throw ae.getRootCause();
218         /*
219          * A system exception would be highly unusual and would indicate a sever
220          * problem with the container system.
221          */

222         } catch ( org.openejb.SystemException se ) {
223             invalidateReference();
224             throw new RemoteException JavaDoc("Container has suffered a SystemException",se.getRootCause());
225         } catch ( org.openejb.OpenEJBException oe ) {
226             throw new RemoteException JavaDoc("Unknown Container Exception",oe.getRootCause());
227         }
228         return retValue;
229     }
230     
231
232     protected Object JavaDoc getEJBHome(Method JavaDoc method, Object JavaDoc[] args, Object JavaDoc proxy) throws Throwable JavaDoc{
233         if ( ejbHome == null ) {
234             ejbHome = EJBHomeHandler.createEJBHomeHandler(ejb, server, client).createEJBHomeProxy();
235         }
236         return ejbHome;
237     }
238     
239     protected Object JavaDoc getHandle(Method JavaDoc method, Object JavaDoc[] args, Object JavaDoc proxy) throws Throwable JavaDoc{
240         return new EJBObjectHandle((EJBObjectProxy)proxy);
241     }
242     
243     
244     protected abstract Object JavaDoc getPrimaryKey(Method JavaDoc method, Object JavaDoc[] args, Object JavaDoc proxy) throws Throwable JavaDoc;
245     
246     protected abstract Object JavaDoc isIdentical(Method JavaDoc method, Object JavaDoc[] args, Object JavaDoc proxy) throws Throwable JavaDoc;
247
248     protected abstract Object JavaDoc remove(Method JavaDoc method, Object JavaDoc[] args, Object JavaDoc proxy) throws Throwable JavaDoc;
249     
250     protected Object JavaDoc businessMethod(Method JavaDoc method, Object JavaDoc[] args, Object JavaDoc proxy) throws Throwable JavaDoc{
251 // checkAuthorization(method);
252
// return container.invoke(deploymentID, method, args, primaryKey, getThreadSpecificSecurityIdentity());
253

254         EJBRequest req = new EJBRequest( EJB_OBJECT_BUSINESS_METHOD );
255         
256         req.setMethodParameters( args );
257         req.setMethodInstance( method );
258         req.setClientIdentity( client.getClientIdentity() );
259         req.setDeploymentCode( ejb.deploymentCode );
260         req.setDeploymentId( ejb.deploymentID );
261         req.setPrimaryKey( primaryKey );
262         
263         EJBResponse res = request( req );
264   
265 // if (method.getName().equals("test36_returnEJBHome2")) {
266
// System.out.println("\n\n----------------------------------------------------------");
267
// System.out.println(method.getName());
268
// Object obj = res.getResult();
269
// System.out.println("obj="+(obj==null));
270
// System.out.println("obj="+(obj.getClass()));
271
// System.out.println("obj="+(obj.getClass().getDeclaringClass()));
272
// Class[] ifs = obj.getClass().getInterfaces();
273
// for (int i=0; i < ifs.length; i++){
274
// System.out.println("ifs["+i+"] "+ifs[i]);
275
// }
276
// }
277
switch (res.getResponseCode()) {
278         case EJB_ERROR:
279 // System.out.println("ERROR "+res.getResult());
280
throw (Throwable JavaDoc)res.getResult();
281         case EJB_SYS_EXCEPTION:
282 // System.out.println("SYS EXEPTION "+res.getResult());
283
throw (Throwable JavaDoc)res.getResult();
284         case EJB_APP_EXCEPTION:
285 // System.out.println("APP EXEPTION "+res.getResult());
286
throw (Throwable JavaDoc)res.getResult();
287         case EJB_OK:
288             return res.getResult();
289         default:
290             throw new RemoteException JavaDoc("Received invalid response code from server: "+res.getResponseCode());
291         }
292     }
293 }
294
Popular Tags