KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > fractal > rmi > stub > Stub


1 /***
2  * Fractal RMI: a binder for remote method calls between Fractal components.
3  * Copyright (C) 2003 France Telecom R&D
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Contact: Eric.Bruneton@rd.francetelecom.com
20  *
21  * Author: Eric Bruneton
22  *
23  * with some code fragments copied from Jonathan:
24  * org.objectweb.jeremie.libs.stub_factories.std.RefImpl
25  * (authors: B. Dumant, K. Milsted)
26  */

27
28 package org.objectweb.fractal.rmi.stub;
29
30 import org.objectweb.fractal.api.Component;
31 import org.objectweb.fractal.api.Interface;
32 import org.objectweb.fractal.api.Type;
33
34 import org.objectweb.fractal.rmi.RemoteException;
35
36 import org.objectweb.jonathan.apis.binding.Identifier;
37 import org.objectweb.jonathan.apis.binding.Reference;
38 import org.objectweb.jonathan.apis.kernel.JonathanException;
39 import org.objectweb.jonathan.apis.presentation.MarshalException;
40 import org.objectweb.jonathan.apis.presentation.Marshaller;
41 import org.objectweb.jonathan.apis.presentation.MarshallerFactory;
42 import org.objectweb.jonathan.apis.presentation.UnMarshaller;
43 import org.objectweb.jonathan.apis.protocols.ReplyInterface;
44 import org.objectweb.jonathan.apis.protocols.ServerException;
45 import org.objectweb.jonathan.apis.protocols.SessionIdentifier;
46 import org.objectweb.jonathan.apis.protocols.Session_High;
47
48 /**
49  * Super class of the stub classes generated by the {@link RmiStubFactory}.
50  * A stub gives access to an interface of a Fractal component.
51  * More precisely, it gives access to the "functional" interface provided by
52  * a server interface, and also gives access to the {@link Interface} interface
53  * implemented by this server interface. The
54  * "functional" interface is implemented by a sub class of this class, while
55  * the {@link Interface} interface is implemented
56  * by this class once and for all.
57  */

58
59 public class Stub implements Reference, Interface {
60
61   /**
62    * The identifier of the remote object to which this stub gives access.
63    */

64
65   protected Identifier id;
66
67   /**
68    * The marshaller factory to be used to create new invocation messages.
69    */

70
71   protected MarshallerFactory marshallerFactory;
72
73   /**
74    * The identifier of the session that gives access to the remote object.
75    */

76
77   protected SessionIdentifier sessionId;
78
79   /**
80    * The session that gives access to the remote object. This session is used to
81    * send the invocation messages down the protocol stack.
82    */

83
84   protected Session_High session;
85
86   /**
87    * Constructs a new {@link Stub}.
88    */

89
90   public Stub () {
91   }
92
93   // --------------------------------------------------------------------------
94
// Implementation of the Reference interface
95
// --------------------------------------------------------------------------
96

97   /**
98    * Returns the set of identifiers associated with this reference.
99    *
100    * @return the set of identifiers associated with this reference.
101    * @see #setIdentifiers
102    */

103
104   public Identifier[] getIdentifiers () {
105     return new Identifier[] { id };
106   }
107
108   /**
109    * Sets the set of identifiers associated with this reference.
110    *
111    * @param ids the set of identifiers to be associated with this reference.
112    * @see #getIdentifiers
113    */

114
115   public void setIdentifiers (Identifier[] ids) {
116     this.id = ids[0];
117   }
118
119   // --------------------------------------------------------------------------
120
// Implementation of the Interface interface
121
// --------------------------------------------------------------------------
122

123   public Component getFcItfOwner () {
124     try {
125       Marshaller marshaller = request();
126       ReplyInterface reply = prepareInvocation(marshaller);
127       marshaller.writeInt(-1);
128       invoke(marshaller);
129       UnMarshaller unmarshaller = reply.listen();
130       Component result = (Component)unmarshaller.readValue();
131       unmarshaller.close();
132       return result;
133     } catch (Exception JavaDoc e) {
134       e = handleException(e);
135       if (e instanceof RuntimeException JavaDoc) {
136         throw (RuntimeException JavaDoc)e;
137       } else {
138         throw new RemoteException("server side exception", e);
139       }
140     }
141   }
142
143   public String JavaDoc getFcItfName () {
144     try {
145       Marshaller marshaller = request();
146       ReplyInterface reply = prepareInvocation(marshaller);
147       marshaller.writeInt(-2);
148       invoke(marshaller);
149       UnMarshaller unmarshaller = reply.listen();
150       String JavaDoc result = (String JavaDoc)unmarshaller.readValue();
151       unmarshaller.close();
152       return result;
153     } catch (Exception JavaDoc e) {
154       e = handleException(e);
155       if (e instanceof RuntimeException JavaDoc) {
156         throw (RuntimeException JavaDoc)e;
157       } else {
158         throw new RemoteException("server side exception", e);
159       }
160     }
161   }
162
163   public Type getFcItfType () {
164     try {
165       Marshaller marshaller = request();
166       ReplyInterface reply = prepareInvocation(marshaller);
167       marshaller.writeInt(-3);
168       invoke(marshaller);
169       UnMarshaller unmarshaller = reply.listen();
170       Type result = (Type)unmarshaller.readValue();
171       unmarshaller.close();
172       return result;
173     } catch (Exception JavaDoc e) {
174       e = handleException(e);
175       if (e instanceof RuntimeException JavaDoc) {
176         throw (RuntimeException JavaDoc)e;
177       } else {
178         throw new RemoteException("server side exception", e);
179       }
180     }
181   }
182
183   public boolean isFcInternalItf () {
184     try {
185       Marshaller marshaller = request();
186       ReplyInterface reply = prepareInvocation(marshaller);
187       marshaller.writeInt(-4);
188       invoke(marshaller);
189       UnMarshaller unmarshaller = reply.listen();
190       boolean result = unmarshaller.readBoolean();
191       unmarshaller.close();
192       return result;
193     } catch (Exception JavaDoc e) {
194       e = handleException(e);
195       if (e instanceof RuntimeException JavaDoc) {
196         throw (RuntimeException JavaDoc)e;
197       } else {
198         throw new RemoteException("server side exception", e);
199       }
200     }
201   }
202
203   // --------------------------------------------------------------------------
204
// Utility methods
205
// --------------------------------------------------------------------------
206

207   /**
208    * Obtains a marshaller for marshalling invocation data.
209    *
210    * @return a marshaller for marshalling invocation data.
211    * @throws MarshalException if something goes wrong.
212    */

213
214   protected Marshaller request () throws MarshalException {
215     if (marshallerFactory == null) {
216       throw new MarshalException("null marshaller factory");
217     }
218     return marshallerFactory.newMarshaller();
219   }
220
221   /**
222    * Prepares the marshaller prior to marshalling invocation data. This
223    * preparation is protocol-specific and typically consists of adding headers
224    * to the marshaller. In line with Java method invocation semantics, a reply
225    * is expected after the remote invocation is executed; a reply interface
226    * is thus returned in order to listen for the reply.
227    *
228    * @param marshaller a marshaller to be used for the invocation data.
229    * @return a reply interface for listening for the reply.
230    * @throws MarshalException if something goes wrong.
231    */

232
233   protected ReplyInterface prepareInvocation (final Marshaller marshaller)
234     throws MarshalException
235   {
236     try {
237       synchronized(this) {
238         if (session == null) {
239           session = sessionId.bind(null);
240         }
241       }
242       return session.prepareInvocation(marshaller);
243     } catch (Exception JavaDoc e) {
244       throw new MarshalException("exception preparing marshaller: " + e);
245     }
246   }
247
248   /**
249    * Sends the marshaller with the invocation data down the protocol stack.
250    *
251    * @param marshaller a marshaller with the invocation data.
252    * @throws MarshalException if something goes wrong.
253    */

254
255   protected void invoke (final Marshaller marshaller) throws MarshalException {
256     try {
257       synchronized(this) {
258         if (session == null) {
259           throw new MarshalException("null session");
260         }
261       }
262       session.send(marshaller);
263     } catch (Exception JavaDoc e) {
264       throw new MarshalException("exception at invocation: " + e);
265     }
266   }
267
268   /**
269    * Handles an exception that happen in this stub.
270    *
271    * @param e an exception.
272    * @return the exception encapsulated in the given exception (if it is a
273    * {@link ServerException}, i.e., an exception that was
274    * thrown by the remote object and sent back in a reply message), or a
275    * new {@link RemoteException} encaspulating the given
276    * exception in the other cases (case of an exception that was thrown
277    * locally by the stub itself).
278    */

279
280   protected Exception JavaDoc handleException (final Exception JavaDoc e) {
281     if (e instanceof ServerException) {
282       try {
283         UnMarshaller unmarshaller = ((ServerException)e).unmarshaller;
284         Exception JavaDoc f = (Exception JavaDoc)unmarshaller.readValue();
285         unmarshaller.close();
286         return f;
287       } catch (JonathanException je) {
288         return new RemoteException(
289           "error during exception unmarshalling by stub", je);
290       }
291     } else {
292       return new RemoteException(
293         "error during marshalling/unmarshalling by stub", e);
294     }
295   }
296
297   protected Object JavaDoc replaceClassName (Object JavaDoc o) throws ClassNotFoundException JavaDoc {
298     if (o instanceof String JavaDoc) {
299       return Class.forName((String JavaDoc)o);
300     } else if (o instanceof Object JavaDoc[]) {
301       Object JavaDoc[] desc = (Object JavaDoc[])o;
302       if (desc.length == 2 && desc[1] instanceof String JavaDoc) {
303         return new Object JavaDoc[] { desc[0], Class.forName((String JavaDoc)desc[1]) };
304       }
305     }
306     return o;
307   }
308   
309   protected Object JavaDoc replaceClassValue (Object JavaDoc o) {
310     if (o instanceof Class JavaDoc) {
311       return ((Class JavaDoc)o).getName();
312     } else if (o instanceof Object JavaDoc[]) {
313       Object JavaDoc[] desc = (Object JavaDoc[])o;
314       if (desc.length == 2 && desc[1] instanceof Class JavaDoc) {
315         return new Object JavaDoc[] { desc[0], ((Class JavaDoc)desc[1]).getName() };
316       }
317     }
318     return o;
319   }
320
321   // --------------------------------------------------------------------------
322
// Overriden methods
323
// --------------------------------------------------------------------------
324

325   /**
326    * Tests if the given object is equal to this stub.
327    *
328    * @param o the object to be compared to this stub.
329    * @return <tt>true</tt> if the given object is a stub whose {@link #id id} is
330    * equal to the {@link #id id} of this stub, <tt>false</tt> otherwise.
331    */

332
333   public boolean equals (final Object JavaDoc o) {
334     if (o instanceof Stub) {
335       return id.equals(((Stub)o).id);
336     }
337     return false;
338   }
339
340   /**
341    * Returns the hashcode of this stub.
342    *
343    * @return the hashcode of the {@link #id id} of this stub.
344    */

345
346   public int hashCode () {
347     return id.hashCode();
348   }
349
350   /**
351    * Finalizes this object. This method closes the {@link #session session}
352    * associated to this stub if it is not <tt>null</tt>.
353    */

354
355   protected void finalize () {
356     if (session != null) {
357       session.close();
358       session = null;
359     }
360   }
361 }
362
Popular Tags