KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > easybeans > rpc > ClientRPCInvocationHandler


1 /**
2  * EasyBeans
3  * Copyright (C) 2006 Bull S.A.S.
4  * Contact: easybeans@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: ClientRPCInvocationHandler.java 1133 2006-10-04 14:30:41Z benoitf $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.easybeans.rpc;
27
28 import java.lang.reflect.Method JavaDoc;
29 import java.rmi.NoSuchObjectException JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.Hashtable JavaDoc;
32
33 import javax.ejb.EJBException JavaDoc;
34 import javax.ejb.EJBTransactionRequiredException JavaDoc;
35 import javax.ejb.NoSuchEJBException JavaDoc;
36 import javax.transaction.TransactionRequiredException JavaDoc;
37
38 import org.objectweb.easybeans.rpc.api.ClientRPC;
39 import org.objectweb.easybeans.rpc.api.EJBRequest;
40 import org.objectweb.easybeans.rpc.api.EJBResponse;
41 import org.objectweb.easybeans.rpc.api.RPCException;
42 import org.objectweb.easybeans.rpc.util.Hash;
43
44
45
46 /**
47  * This class sends an EJB request to the server and send back to the client the
48  * response.
49  * @author Florent Benoit
50  */

51 public class ClientRPCInvocationHandler extends AbsInvocationHandler {
52
53     /**
54      * Id for serializable class.
55      */

56     private static final long serialVersionUID = 1852625501781836250L;
57
58
59     /**
60      * Environment used by the client when lookup on proxy object has be done.
61      * This will be set by the Remote Factory.
62      */

63     private Hashtable JavaDoc<?, ?> rmiClientEnvironment = null;
64
65     /**
66      * Build a new Invocation handler.
67      * @param containerId the id of the container that will be called on the
68      * remote side.
69      * @param factoryName the name of the remote factory.
70      * @param useID true if all instance build with this ref are unique
71      * (stateful), false if it references the same object (stateless)
72      */

73     public ClientRPCInvocationHandler(final String JavaDoc containerId, final String JavaDoc factoryName, final boolean useID) {
74         super(containerId, factoryName, useID);
75     }
76
77     /**
78      * Processes a method invocation on a proxy instance and returns the result.
79      * This method will be invoked on an invocation handler when a method is
80      * invoked on a proxy instance that it is associated with.
81      * @param proxy the proxy instance that the method was invoked on
82      * @param method the <code>Method</code> instance corresponding to the
83      * interface method invoked on the proxy instance. The declaring
84      * class of the <code>Method</code> object will be the interface
85      * that the method was declared in, which may be a superinterface of
86      * the proxy interface that the proxy class inherits the method
87      * through.
88      * @param args an array of objects containing the values of the arguments
89      * passed in the method invocation on the proxy instance, or
90      * <code>null</code> if interface method takes no arguments.
91      * Arguments of primitive types are wrapped in instances of the
92      * appropriate primitive wrapper class, such as
93      * <code>java.lang.Integer</code> or <code>java.lang.Boolean</code>.
94      * @return the value to return from the method invocation on the proxy
95      * instance.
96      * @throws Exception the exception to throw from the method invocation on
97      * the proxy instance.
98      */

99     public Object JavaDoc invoke(final Object JavaDoc proxy, final Method JavaDoc method, final Object JavaDoc[] args) throws Exception JavaDoc {
100
101         // Bean removed, no methods are allowed
102
if (isRemoved()) {
103             handleThrowable(convertThrowable(new NoSuchEJBException JavaDoc("The bean has been removed")), false, method);
104         }
105
106         // Methods on the Object.class are not send on the remote side
107
if (method.getDeclaringClass().getName().equals("java.lang.Object")) {
108             return handleObjectMethods(method, args);
109         }
110
111         ClientRPC client = RPC.getClient(rmiClientEnvironment);
112
113         if (getHashedMethods() == null) {
114             setHashedMethods(new HashMap JavaDoc<Method JavaDoc, Long JavaDoc>());
115         }
116
117         Long JavaDoc hashLong = getHashedMethods().get(method);
118         if (hashLong == null) {
119             hashLong = Long.valueOf(Hash.hashMethod(method));
120             getHashedMethods().put(method, hashLong);
121         }
122
123         long hash = hashLong.longValue();
124
125         EJBRequest request = new JEJBRequest(method.getName(), hash, args, getContainerId(), getFactoryName(), getBeanId());
126
127         // send response
128
EJBResponse response;
129         try {
130             response = client.sendEJBRequest(request);
131         } catch (RuntimeException JavaDoc e) {
132             // Exception due to protocol
133
throw new EJBException JavaDoc("Error while sending a request", e);
134         }
135         // Sets the bean ID
136
setBeanId(response.getBeanId());
137
138         // bean removed ?
139
setRemoved(response.isRemoved());
140
141         // Handle exception
142
RPCException rpcException = response.getRPCException();
143         if (rpcException != null) {
144             handleThrowable(convertThrowable(rpcException.getCause()), rpcException.isApplicationException(), method);
145         }
146
147         return response.getValue();
148     }
149
150     /**
151      * Convert the received exception to the correct type for the remote case.
152      * @param throwable the exception to analyze.
153      * @return the converted exception or the original exception
154      */

155     private Throwable JavaDoc convertThrowable(final Throwable JavaDoc throwable) {
156         // see 14.3.9 chapter EJB3
157
if (isExtendingRmiRemote() && throwable instanceof NoSuchEJBException JavaDoc) {
158             NoSuchObjectException JavaDoc ne = new NoSuchObjectException JavaDoc(throwable.getMessage());
159             ne.detail = throwable;
160             return ne;
161         }
162
163         // see 14.4.2.2 chapter EJB3
164
if (throwable instanceof javax.ejb.TransactionRequiredLocalException JavaDoc) {
165             if (isExtendingRmiRemote()) {
166                 TransactionRequiredException JavaDoc tre = new TransactionRequiredException JavaDoc(throwable.getMessage());
167                 tre.detail = throwable;
168                 return tre;
169             }
170             // else
171
EJBTransactionRequiredException JavaDoc ejbTransRequiredException = new EJBTransactionRequiredException JavaDoc(throwable
172                     .getMessage());
173             ejbTransRequiredException.initCause(throwable);
174             return ejbTransRequiredException;
175         }
176         return throwable;
177     }
178
179     /**
180      * Set the RMI environment used by the client when the lookup has been done.
181      * @param rmiClientEnvironment the given environment.
182      */

183     public void setRMIEnv(final Hashtable JavaDoc<?, ?> rmiClientEnvironment) {
184         this.rmiClientEnvironment = rmiClientEnvironment;
185
186     }
187
188
189 }
190
Popular Tags