KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > core > dist > RemoteRef


1 /*
2   Copyright (C) 2001-2003 Lionel Seinturier, Renaud Pawlak.
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12   GNU Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

17
18 package org.objectweb.jac.core.dist;
19
20 import java.io.Serializable JavaDoc;
21 import java.lang.reflect.Constructor JavaDoc;
22 import java.util.Arrays JavaDoc;
23 import org.apache.log4j.Logger;
24 import org.objectweb.jac.core.Collaboration;
25 import org.objectweb.jac.core.JacPropLoader;
26 import org.objectweb.jac.core.ObjectRepository;
27 import org.objectweb.jac.core.SerializedJacObject;
28 import org.objectweb.jac.util.WrappedThrowableException;
29
30 /**
31  * <code>RemoteRef</code> stores the reference of a remote object.
32  * The way the remote object is accessed depends on
33  * the underlying communication protocol (eg CORBA or RMI).<p>
34  *
35  * Supporting a new communication protocol requires to subclass RemoteRef
36  * (eg RMIRemoteRef or CORBARemoteRef) and to implement the resolve and
37  * reresolve methods.<p>
38  *
39  * @see org.objectweb.jac.core.dist.RemoteRef#resolve(java.lang.String)
40  * @see org.objectweb.jac.core.dist.RemoteRef#reresolve()
41  * @see org.objectweb.jac.core.dist.rmi.RMIRemoteRef
42  *
43  * @author <a HREF="http://www-src.lip6.fr/homepages/Lionel.Seinturier/index-eng.html">Lionel Seinturier</a>
44  * @author <a HREF="http://cedric.cnam.fr/~pawlak/index-english.html">Renaud Pawlak</a>
45  */

46 public class RemoteRef implements Serializable JavaDoc {
47     static Logger logger = Logger.getLogger("dist");
48     static Logger loggerSerial = Logger.getLogger("serialization");
49
50     /** The reference of the container that handles the remote object. */
51     protected RemoteContainer remCont;
52    
53     /** The index (see org.objectweb.jac.core.JacObject) of the remote object. */
54     protected int remIndex;
55
56     /** The name of the remote object that is of will be associated to
57        the remote ref. */

58     protected String JavaDoc name = null;
59
60     /** Property key for the remote reference class. */
61     //protected static final String remRefClassProp = "Jac.remoteRefClass";
62

63     /** Default remote reference class. */
64     //protected static final String remRefDefaultClassName = "org.objectweb.jac.core.dist.rmi.RMIRemoteRef";
65

66     /**
67      * This class method returns a new RemoteRef object.<p>
68      *
69      * Property org.objectweb.jac.dist.remoteRefClass defines the class of the actual
70      * RemoteRef returned (e.g. CORBARemoteRef). If the property is not
71      * defined or if the class does not exist, RMIRemoteRef is the
72      * default.<p>
73      *
74      * @param name the name to give to the remote ref (should be equal
75      * to the pointed object name)
76      * @return a new RemoteRef object
77      */

78     public static RemoteRef create(String JavaDoc name) {
79       
80         RemoteRef remoteRef = null;
81         String JavaDoc remoteRefClassName = JacPropLoader.remoteRefClassName;
82
83         try {
84             Class JavaDoc remoteRefClass = Class.forName(remoteRefClassName);
85             remoteRef = (RemoteRef) remoteRefClass.newInstance();
86         } catch (Exception JavaDoc e) {
87             logger.error("create "+name,e);
88         }
89       
90         remoteRef.setName(name);
91
92         return remoteRef;
93     }
94
95     /**
96      * This class method returns a remote reference
97      * for an existing remote JAC object.<p>
98      *
99      * Property org.objectweb.jac.dist.remoteRefClass defines the class of the actual
100      * RemoteRef returned (e.g. CORBARemoteRef). If the property is not
101      * defined or if the class does not exist, RMIRemoteRef is the
102      * default.<p>
103      *
104      * @param name the remote object name (can be null if not needed)
105      * @param remCont the remote container where the JAC object is
106      * instantiated
107      * @param remIndex the index of the JAC object in the remote
108      * container
109      * @return the remote reference of the JAC object
110      */

111     public static RemoteRef create(String JavaDoc name,
112                                    RemoteContainer remCont,
113                                    int remIndex)
114     {
115         logger.debug("creating remote ref " + name + ", " +
116                      remCont + ", " + remIndex);
117
118         RemoteRef remoteRef = null;
119         String JavaDoc remoteRefClassName = JacPropLoader.remoteRefClassName;
120         /*
121           String remoteRefClassName = null;
122
123           if (JacObject.props != null) {
124           remoteRefClassName = JacObject.props.getProperty(remRefClassProp);
125           }
126       
127           if ( remoteRefClassName == null ) {
128           remoteRefClassName = "org.objectweb.jac.core.dist.rmi.RMIRemoteRef";
129           }
130         */

131         try {
132             Class JavaDoc remoteRefClass = Class.forName(remoteRefClassName);
133          
134             Constructor JavaDoc c =
135                 remoteRefClass.getConstructor(
136                     new Class JavaDoc[] { RemoteContainer.class, int.class }
137                 );
138             remoteRef =
139                 (RemoteRef)c.newInstance(
140                     new Object JavaDoc[] { remCont, new Integer JavaDoc(remIndex) });
141         } catch(Exception JavaDoc e) {
142             logger.error("create "+name+","+remCont+","+remIndex,e);
143         }
144       
145         remoteRef.setName(name);
146         logger.debug("returning remote ref " + remoteRef);
147       
148         return remoteRef;
149     }
150
151     /**
152     * Create a remote reference from a local JAC object (in order, for
153     * example, to transmit it to a remote container).<p>
154     *
155     * @param name the name to be given to the remote reference
156     * @param localObject the object to create the reference from
157     * @return the new remote reference */

158
159     public static RemoteRef create(String JavaDoc name, Object JavaDoc localObject) {
160         logger.debug("creating remote ref "+name+" for "+localObject);
161         return RemoteRef.create(
162             name, RemoteContainer.resolve(Distd.getLocalContainerName()),
163             ObjectRepository.getMemoryObjectIndex(localObject));
164     }
165    
166     /**
167     * This is a full constructor for RemoteRef.<p>
168     *
169     * @param remCont the ref of the container that handles the remote
170     * object.
171     * @param remIndex the index of the remote object */

172     
173     public RemoteRef(RemoteContainer remCont, int remIndex) {
174         this.remCont = remCont;
175         this.remIndex = remIndex;
176     }
177    
178    
179     /**
180     * This is a more friendly constructor for RemoteRef.<p>
181     *
182     * @param remCont the name of the container that handles the remote
183     * object.
184     * @param remIndex the index of the remote object. */

185    
186     public RemoteRef(String JavaDoc remCont, int remIndex) {
187         this.remCont = resolve(remCont);
188         this.remIndex = remIndex;
189     }
190
191
192     /**
193     * Empty default constructor for RemoteRef needed by the compiler whenever
194     * RemoteRef is subclasses (eg RMIRemoteRef or CORBARemoteRef).<p>
195     *
196     * This constructor should never be called in other cases (this is why it is
197     * protected).<p>
198     */

199    
200     protected RemoteRef() {}
201    
202    
203     /**
204     * The getter method for the remCont field.<p>
205     *
206     * It returns a the container that handles the remote object. If
207     * the remote container is local, then the object pointed by the
208     * remote reference is also local.<p>
209     *
210     * @return the remCont field value */

211     
212     public RemoteContainer getRemCont() { return remCont; }
213
214
215     /**
216     * The setter method for the name.<p>
217     *
218     * @param name the new name */

219
220     public void setName(String JavaDoc name) {
221         this.name = name;
222     }
223    
224     /**
225     * The getter method for the name.
226     *
227     * @return the reference name */

228    
229     public String JavaDoc getName() {
230         return name;
231     }
232
233     /**
234     * The getter method for the <code>remIndex</code> field.<p>
235     *
236     * <code>remIndex</code> is the index (see org.objectweb.jac.core.JacObject) of
237     * the remote object.
238     *
239     * @return the remIndex field value */

240     
241     public int getRemIndex() { return remIndex; }
242    
243     /**
244     * This method resolves a container from a container name.<p>
245     *
246     * Its implementation is protocol dependent (eg RMI or CORBA).
247     * Most concrete implementations of this method (see RMIRemoteRef)
248     * simply delegate the resolution to a resolve() class method defined
249     * in a container class (see RMIRemoteContainer).<p>
250     *
251     * @param contName the name of the container
252     * @return the container
253     *
254     * @see org.objectweb.jac.core.dist.rmi.RMIRemoteRef#resolve(String)
255     */

256     public RemoteContainer resolve(String JavaDoc contName) { return null; }
257
258     /**
259     * This method re-gets the reference of a remote container.<p>
260     *
261     * Its implementation is protocol dependent (eg RMI or CORBA).
262     * Some communication protocols (eg CORBA) do not linearalize
263     * remote references in a standard way. Thus a remote reference
264     * may need to be adapted whenever it is transmitted.<p>
265     *
266     * This method is called when a remote reference
267     * is recieved by a <code>RemoteContainer</code>.<p>
268     *
269     * @return the container reference
270     *
271     * @see org.objectweb.jac.core.dist.rmi.RMIRemoteRef#reresolve()
272     */

273     public RemoteContainer reresolve() { return null; }
274    
275
276     /** Following constants are property keys used by remoteNew(). */
277    
278     final protected static String JavaDoc toAdaptProp = "org.objectweb.jac.toAdapt";
279
280
281     /**
282     * Remotely instantiate a class.<p>
283     *
284     * Make the current <code>RemoteRef</code> instance reference the
285     * created object.<p>
286     *
287     * @param host the host machine
288     * @param clName the class to instantiate */

289    
290     public void remoteNew(String JavaDoc host, String JavaDoc clName) {
291         remoteNewWithCopy(host, clName, null, null, null);
292     }
293    
294     /**
295     * Remotely instantiate a class.<p>
296     *
297     * Make the current <code>RemoteRef</code> instance reference the
298     * created object.<p>
299     *
300     * @param host the host machine
301     * @param clName the class to instantiate
302     * @param args initialization arguments for the instantiation */

303    
304     public void remoteNew(String JavaDoc host, String JavaDoc clName, Object JavaDoc[] args) {
305         remoteNewWithCopy(host, clName, args, null, null);
306     }
307    
308     /**
309     * Remotely instantiate a class.<p>
310     *
311     * Make the current <code>RemoteRef</code> instance reference the
312     * created object and copy the state of the given object into the
313     * remote object.<p>
314     *
315     * All the fields of the object are copied.<p>
316     *
317     * @param host the host machine
318     * @param clName the class to instantiate
319     * @param src the source object containing the data to copy */

320    
321     public void remoteNewWithCopy(String JavaDoc host, String JavaDoc clName, Object JavaDoc src) {
322         remoteNewWithCopy(host, clName, null, src, null);
323     }
324    
325     /**
326     * Remotely instantiate a class.<p>
327     *
328     * Make the current <code>RemoteRef</code> instance reference the
329     * created object and copy the state of the given object into the
330     * remote object.<p>
331     *
332     * All the fields of the object are copied.<p>
333     *
334     * @param host the host machine
335     * @param clName the class to instantiate
336     * @param args initialization arguments for the instantiation
337     * @param src the source object containing the data to copy */

338    
339     public void remoteNewWithCopy(String JavaDoc host,
340                                   String JavaDoc clName,
341                                   Object JavaDoc[] args,
342                                   Object JavaDoc src) {
343         remoteNewWithCopy(host, clName, args, src, null);
344     }
345
346
347     /**
348     * Remotely instantiate a class.<p>
349     *
350     * Make the current <code>RemoteRef</code> instance reference the
351     * created object and copy the state of the given object into the
352     * remote object.<p>
353     *
354     * Only specified fields are copied.<p>
355     *
356     * @param host the host machine
357     * @param clName the class to instantiate
358     * @param src the source object containing the data to copy
359     * @param fieldsName the fields name to copy */

360    
361     public void remoteNewWithCopy(String JavaDoc host,
362                                   String JavaDoc clName,
363                                   Object JavaDoc src,
364                                   String JavaDoc[] fieldsName) {
365         remoteNewWithCopy(host, clName, null, src, fieldsName);
366     }
367    
368    
369     /**
370     * Remotely instantiate a class.
371     *
372     * Make the current <code>RemoteRef</code> instance reference the
373     * created object and copy the state of the given object into the
374     * remote object.<p>
375     *
376     * Only specified fields are copied.<p>
377     *
378     * @param host the host machine
379     * @param clName the class to instantiate
380     * @param args initialization arguments for the instantiation
381     * @param src the source object containing the data to copy
382     * @param fieldsName the fields name to copy */

383    
384     public void remoteNewWithCopy(String JavaDoc host,
385                                   String JavaDoc clName,
386                                   Object JavaDoc[] args,
387                                   Object JavaDoc src,
388                                   String JavaDoc[] fieldsName)
389     {
390         /**
391          * Resolving the host consists in getting the concrete remote reference
392          * (e.g. RMIRemoteRef or CORBARemoteRef) associated to the remote
393          * container where the remote instantiation is to be performed.
394          */

395       
396         remCont = resolve(host);
397
398         /** Prepare the fields name and value */
399       
400         Object JavaDoc[] fieldsValue = null;
401       
402         if (src!=null) {
403             if ( fieldsName == null ) {
404                 Object JavaDoc[] state = ObjectState.getState(src);
405                 fieldsName = (String JavaDoc[])state[0];
406                 fieldsValue = (Object JavaDoc[])state[1];
407             }
408             else {
409                 Object JavaDoc[] state = ObjectState.getState(src,fieldsName );
410                 fieldsName = (String JavaDoc[])state[0];
411                 fieldsValue = (Object JavaDoc[])state[1];
412             }
413         }
414
415         if (fieldsName!=null)
416             loggerSerial.debug(
417                 "serializing fields "+Arrays.asList(fieldsName)+
418                 " values = "+Arrays.asList(fieldsValue));
419
420         byte[] sfieldsValue = SerializedJacObject.serialize(fieldsValue);
421         if (sfieldsValue!=null)
422             Distd.outputCount += sfieldsValue.length;
423
424       /** Remotely create an instance of className */
425
426         remIndex =
427             remCont.instantiates(
428                 name, clName, args, fieldsName,
429                 sfieldsValue,
430                 SerializedJacObject.serialize(Collaboration.get())
431             );
432
433     }
434
435     /**
436      * Copy the state of a given object into the remote object
437      * referenced by the current reference.<p>
438      *
439      * All the fields of the object are copied.<p>
440      *
441      * @param src the source object containing the data to copy
442      */

443     public void remoteCopy(Object JavaDoc src) {
444
445         Object JavaDoc[] state = ObjectState.getState(src);
446         byte[] sstate = SerializedJacObject.serialize( (Object JavaDoc[]) state[1] );
447
448         if ( sstate != null ) Distd.outputCount += sstate.length;
449
450         /** Perform the remote copy */
451         remCont.copy(
452             name, remIndex,
453             (String JavaDoc[]) state[0],
454             sstate,
455             SerializedJacObject.serialize(Collaboration.get())
456         );
457     }
458    
459    
460     /**
461      * Copy the state of a given object into the remote object
462      * referenced by the current reference.<p>
463      *
464      * Only specified fields are copied.<p>
465      *
466      * @param src the source object containing the data to copy
467      * @param fieldsName the fields name to copy
468      */

469     public void remoteCopy(Object JavaDoc src, String JavaDoc[] fieldsName) {
470
471         Object JavaDoc[] state = ObjectState.getState(src,fieldsName );
472         byte[] sstate = SerializedJacObject.serialize( (Object JavaDoc[]) state[1] );
473
474         if ( sstate != null ) Distd.outputCount += sstate.length;
475
476         /** Perform the remote copy */
477
478         remCont.copy(
479             name,
480             remIndex,
481             (String JavaDoc[]) state[0],
482             sstate,
483             SerializedJacObject.serialize(Collaboration.get())
484         );
485     }
486    
487     /**
488      * Forward a call to the referenced object.<p>
489      *
490      * @param methodName the called method name
491      * @param methodArgs the called method arguments
492      * @return the result
493      */

494     public Object JavaDoc invoke(String JavaDoc methodName, Object JavaDoc[] methodArgs) {
495         return invoke(methodName,methodArgs,null);
496     }
497    
498     /**
499      * Forward a call to the referenced object.<p>
500      *
501      * @param methodName the called method name
502      * @param methodArgs the called method arguments
503      * @return the result
504      */

505     public Object JavaDoc invoke(String JavaDoc methodName, Object JavaDoc[] methodArgs,
506                          Boolean JavaDoc[] refs)
507     {
508         logger.debug("invoking "+methodName+" on "+this);
509
510         byte[] ret = null;
511         byte[] args = SerializedJacObject.serializeArgs(methodArgs,refs);
512
513         if (args != null)
514             Distd.outputCount += args.length;
515
516         // System.out.println("Collab = "+Collaboration.get());
517
try {
518             ret = remCont.invoke(
519                 remIndex,
520                 methodName,
521                 args,
522                 SerializedJacObject.serialize(Collaboration.get())
523             );
524         } catch (Exception JavaDoc e) {
525             if (e instanceof WrappedThrowableException) {
526                 throw (RuntimeException JavaDoc) e;
527             }
528             logger.error("Failed to remotely invoke "+methodName+": "+e);
529         }
530
531         if ( ret != null ) Distd.inputCount += ret.length;
532
533         return SerializedJacObject.deserialize( ret );
534     }
535
536     /**
537      * Forward a role method call to the referenced object.<p>
538      *
539      * @param methodName the called role method name
540      * @param methodArgs the called role method arguments
541      * @return the result
542      */

543     public Object JavaDoc invokeRoleMethod(String JavaDoc methodName,Object JavaDoc[] methodArgs) {
544
545         logger.debug("invoking role method "+methodName+" on "+
546                      this+"-"+remCont);
547
548         byte[] ret = null;
549         byte[] args = SerializedJacObject.serialize(methodArgs);
550
551         if (args != null) Distd.outputCount += args.length;
552       
553         try {
554             ret = remCont.invokeRoleMethod(
555                 remIndex,
556                 methodName,
557                 args,
558                 SerializedJacObject.serialize(Collaboration.get())
559             );
560         } catch ( Exception JavaDoc e ) {
561             if ( e instanceof WrappedThrowableException ) {
562                 throw (RuntimeException JavaDoc) e;
563             }
564             logger.error("Failed to remotely invoke "+methodName+": "+e);
565         }
566
567         if ( ret != null ) Distd.inputCount += ret.length;
568
569         return SerializedJacObject.deserialize(ret);
570     }
571
572     /**
573      * Create a textual representation of the remote reference.
574      *
575      * @return the textual representation of the current reference
576      */

577     public String JavaDoc toString() {
578         return ( "#" + getRemCont().getName() + "/" +
579                  name + "[" + getRemIndex() + "]#" );
580     }
581
582     /**
583      * Test the equality of 2 remote references.
584      *
585      * @param o the remote reference to check
586      * @return true if equals the current one
587      */

588     public boolean equals(Object JavaDoc o) {
589         if ( ! (o instanceof RemoteRef) ) return false;
590         RemoteRef r = (RemoteRef) o;
591         return ( r.getRemIndex() == remIndex )
592             && ( r.getRemCont().equals (remCont) );
593     }
594    
595 }
596
Popular Tags