KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > corba > se > impl > presentation > rmi > DynamicMethodMarshallerImpl


1 /*
2  * @(#)DynamicMethodMarshallerImpl.java 1.12 04/06/21
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.corba.se.impl.presentation.rmi ;
9
10 import java.io.Serializable JavaDoc ;
11 import java.io.Externalizable JavaDoc ;
12
13 import javax.rmi.PortableRemoteObject JavaDoc ;
14 import javax.rmi.CORBA.Util JavaDoc ;
15
16 import org.omg.CORBA.portable.IDLEntity JavaDoc ;
17
18 import org.omg.CORBA_2_3.portable.InputStream JavaDoc ;
19 import org.omg.CORBA_2_3.portable.OutputStream JavaDoc ;
20 import org.omg.CORBA.portable.ApplicationException JavaDoc ;
21
22 import java.lang.reflect.Method JavaDoc ;
23
24 import java.rmi.RemoteException JavaDoc ;
25
26 import com.sun.corba.se.spi.orb.ORB ;
27
28 import com.sun.corba.se.spi.presentation.rmi.DynamicMethodMarshaller ;
29
30 public class DynamicMethodMarshallerImpl implements DynamicMethodMarshaller
31 {
32     Method JavaDoc method ;
33     ExceptionHandler ehandler ;
34     boolean hasArguments = true ;
35     boolean hasVoidResult = true ;
36     boolean needsArgumentCopy ; // true if copyObjects call needs for args
37
boolean needsResultCopy ; // true if copyObject call needs for result
38
ReaderWriter[] argRWs = null ;
39     ReaderWriter resultRW = null ;
40
41     private static boolean isAnyClass( Class JavaDoc cls )
42     {
43     return cls.equals( Object JavaDoc.class ) || cls.equals( Serializable JavaDoc.class ) ||
44         cls.equals( Externalizable JavaDoc.class ) ;
45     }
46
47     // Assume that cls is not Remote, !isAnyClass(cls), and
48
// !org.omg.CORBA.Object.class.isAssignableFrom( cls ).
49
// Then return whether cls is an RMI-IIOP abstract interface.
50
private static boolean isAbstractInterface( Class JavaDoc cls )
51     {
52     // Either cls is an interface that extends IDLEntity, or else
53
// cls does not extend java.rmi.Remote and all of its methods
54
// throw RemoteException.
55
if (IDLEntity JavaDoc.class.isAssignableFrom( cls ))
56         return cls.isInterface() ;
57     else
58         return cls.isInterface() && allMethodsThrowRemoteException( cls ) ;
59     }
60
61     private static boolean allMethodsThrowRemoteException( Class JavaDoc cls )
62     {
63     Method JavaDoc[] methods = cls.getMethods() ;
64
65     // Check that all methods (other than those declared in java.lang.Object)
66
// throw an exception that is a subclass of RemoteException.
67
for (int ctr=0; ctr<methods.length; ctr++) {
68         Method JavaDoc method = methods[ctr] ;
69         if (method.getDeclaringClass() != Object JavaDoc.class)
70         if (!throwsRemote( method ))
71             return false ;
72     }
73
74     return true ;
75     }
76
77     private static boolean throwsRemote( Method JavaDoc method )
78     {
79     Class JavaDoc[] exceptionTypes = method.getExceptionTypes() ;
80
81     // Check that some exceptionType is a subclass of RemoteException
82
for (int ctr=0; ctr<exceptionTypes.length; ctr++) {
83         Class JavaDoc exceptionType = exceptionTypes[ctr] ;
84         if (java.rmi.RemoteException JavaDoc.class.isAssignableFrom( exceptionType ))
85         return true ;
86     }
87
88     return false ;
89     }
90
91     public interface ReaderWriter
92     {
93     Object JavaDoc read( InputStream JavaDoc is ) ;
94     
95     void write( OutputStream JavaDoc os, Object JavaDoc value ) ;
96     }
97
98     abstract static class ReaderWriterBase implements ReaderWriter
99     {
100     String JavaDoc name ;
101
102     public ReaderWriterBase( String JavaDoc name )
103     {
104         this.name = name ;
105     }
106
107     public String JavaDoc toString()
108     {
109         return "ReaderWriter[" + name + "]" ;
110     }
111     }
112
113     private static ReaderWriter booleanRW = new ReaderWriterBase( "boolean" )
114     {
115     public Object JavaDoc read( InputStream JavaDoc is )
116     {
117         boolean value = is.read_boolean() ;
118         return new Boolean JavaDoc( value ) ;
119     }
120
121     public void write( OutputStream JavaDoc os, Object JavaDoc value )
122     {
123         Boolean JavaDoc val = (Boolean JavaDoc)value ;
124         os.write_boolean( val.booleanValue() ) ;
125     }
126     } ;
127
128     private static ReaderWriter byteRW = new ReaderWriterBase( "byte" )
129     {
130     public Object JavaDoc read( InputStream JavaDoc is )
131     {
132         byte value = is.read_octet() ;
133         return new Byte JavaDoc( value ) ;
134     }
135
136     public void write( OutputStream JavaDoc os, Object JavaDoc value )
137     {
138         Byte JavaDoc val = (Byte JavaDoc)value ;
139         os.write_octet( val.byteValue() ) ;
140     }
141     } ;
142
143     private static ReaderWriter charRW = new ReaderWriterBase( "char" )
144     {
145     public Object JavaDoc read( InputStream JavaDoc is )
146     {
147         char value = is.read_wchar() ;
148         return new Character JavaDoc( value ) ;
149     }
150     
151     public void write( OutputStream JavaDoc os, Object JavaDoc value )
152     {
153         Character JavaDoc val = (Character JavaDoc)value ;
154         os.write_wchar( val.charValue() ) ;
155     }
156     } ;
157     
158     private static ReaderWriter shortRW = new ReaderWriterBase( "short" )
159     {
160     public Object JavaDoc read( InputStream JavaDoc is )
161     {
162         short value = is.read_short() ;
163         return new Short JavaDoc( value ) ;
164     }
165     
166     public void write( OutputStream JavaDoc os, Object JavaDoc value )
167     {
168         Short JavaDoc val = (Short JavaDoc)value ;
169         os.write_short( val.shortValue() ) ;
170     }
171     } ;
172     
173     private static ReaderWriter intRW = new ReaderWriterBase( "int" )
174     {
175     public Object JavaDoc read( InputStream JavaDoc is )
176     {
177         int value = is.read_long() ;
178         return new Integer JavaDoc( value ) ;
179     }
180     
181     public void write( OutputStream JavaDoc os, Object JavaDoc value )
182     {
183         Integer JavaDoc val = (Integer JavaDoc)value ;
184         os.write_long( val.intValue() ) ;
185     }
186     } ;
187     
188     private static ReaderWriter longRW = new ReaderWriterBase( "long" )
189     {
190     public Object JavaDoc read( InputStream JavaDoc is )
191     {
192         long value = is.read_longlong() ;
193         return new Long JavaDoc( value ) ;
194     }
195     
196     public void write( OutputStream JavaDoc os, Object JavaDoc value )
197     {
198         Long JavaDoc val = (Long JavaDoc)value ;
199         os.write_longlong( val.longValue() ) ;
200     }
201     } ;
202     
203     private static ReaderWriter floatRW = new ReaderWriterBase( "float" )
204     {
205     public Object JavaDoc read( InputStream JavaDoc is )
206     {
207         float value = is.read_float() ;
208         return new Float JavaDoc( value ) ;
209     }
210     
211     public void write( OutputStream JavaDoc os, Object JavaDoc value )
212     {
213         Float JavaDoc val = (Float JavaDoc)value ;
214         os.write_float( val.floatValue() ) ;
215     }
216     } ;
217     
218     private static ReaderWriter doubleRW = new ReaderWriterBase( "double" )
219     {
220     public Object JavaDoc read( InputStream JavaDoc is )
221     {
222         double value = is.read_double() ;
223         return new Double JavaDoc( value ) ;
224     }
225     
226     public void write( OutputStream JavaDoc os, Object JavaDoc value )
227     {
228         Double JavaDoc val = (Double JavaDoc)value ;
229         os.write_double( val.doubleValue() ) ;
230     }
231     } ;
232     
233     private static ReaderWriter corbaObjectRW = new ReaderWriterBase(
234     "org.omg.CORBA.Object" )
235     {
236     public Object JavaDoc read( InputStream JavaDoc is )
237     {
238         return is.read_Object() ;
239     }
240     
241     public void write( OutputStream JavaDoc os, Object JavaDoc value )
242     {
243         os.write_Object( (org.omg.CORBA.Object JavaDoc)value ) ;
244     }
245     } ;
246     
247     private static ReaderWriter anyRW = new ReaderWriterBase( "any" )
248     {
249     public Object JavaDoc read( InputStream JavaDoc is )
250     {
251         return Util.readAny(is) ;
252     }
253
254     public void write( OutputStream JavaDoc os, Object JavaDoc value )
255     {
256         Util.writeAny( os, value ) ;
257     }
258     } ;
259
260     private static ReaderWriter abstractInterfaceRW = new ReaderWriterBase(
261     "abstract_interface" )
262     {
263     public Object JavaDoc read( InputStream JavaDoc is )
264     {
265         return is.read_abstract_interface() ;
266     }
267
268     public void write( OutputStream JavaDoc os, Object JavaDoc value )
269     {
270         Util.writeAbstractObject( os, value ) ;
271     }
272     } ;
273
274  
275     public static ReaderWriter makeReaderWriter( final Class JavaDoc cls )
276     {
277     if (cls.equals( boolean.class ))
278         return booleanRW ;
279     else if (cls.equals( byte.class ))
280         return byteRW ;
281     else if (cls.equals( char.class ))
282         return charRW ;
283     else if (cls.equals( short.class ))
284         return shortRW ;
285     else if (cls.equals( int.class ))
286         return intRW ;
287     else if (cls.equals( long.class ))
288         return longRW ;
289     else if (cls.equals( float.class ))
290         return floatRW ;
291     else if (cls.equals( double.class ))
292         return doubleRW ;
293     else if (java.rmi.Remote JavaDoc.class.isAssignableFrom( cls ))
294         return new ReaderWriterBase( "remote(" + cls.getName() + ")" )
295         {
296         public Object JavaDoc read( InputStream JavaDoc is )
297         {
298             return PortableRemoteObject.narrow( is.read_Object(),
299             cls ) ;
300         }
301
302         public void write( OutputStream JavaDoc os, Object JavaDoc value )
303         {
304             Util.writeRemoteObject( os, value ) ;
305         }
306         } ;
307     else if (cls.equals(org.omg.CORBA.Object JavaDoc.class))
308         return corbaObjectRW ;
309     else if (org.omg.CORBA.Object JavaDoc.class.isAssignableFrom( cls ))
310         return new ReaderWriterBase( "org.omg.CORBA.Object(" +
311         cls.getName() + ")" )
312         {
313         public Object JavaDoc read( InputStream JavaDoc is )
314         {
315             return is.read_Object(cls) ;
316         }
317         
318         public void write( OutputStream JavaDoc os, Object JavaDoc value )
319         {
320             os.write_Object( (org.omg.CORBA.Object JavaDoc)value ) ;
321         }
322         } ;
323     else if (isAnyClass(cls))
324         return anyRW ;
325     else if (isAbstractInterface(cls))
326         return abstractInterfaceRW ;
327
328     // For anything else, just read it as a value type.
329
return new ReaderWriterBase( "value(" + cls.getName() + ")" )
330     {
331         public Object JavaDoc read( InputStream JavaDoc is )
332         {
333         return is.read_value(cls) ;
334         }
335
336         public void write( OutputStream JavaDoc os, Object JavaDoc value )
337         {
338         os.write_value( (Serializable JavaDoc)value, cls ) ;
339         }
340     } ;
341     }
342
343     public DynamicMethodMarshallerImpl( Method JavaDoc method )
344     {
345     this.method = method ;
346     ehandler = new ExceptionHandlerImpl( method.getExceptionTypes() ) ;
347     needsArgumentCopy = false ;
348         
349     Class JavaDoc[] argTypes = method.getParameterTypes() ;
350     hasArguments = argTypes.length > 0 ;
351     if (hasArguments) {
352         argRWs = new ReaderWriter[ argTypes.length ] ;
353         for (int ctr=0; ctr<argTypes.length; ctr++ ) {
354         // This could be further optimized to avoid
355
// copying if argTypes contains at most one
356
// immutable object type.
357
if (!argTypes[ctr].isPrimitive())
358             needsArgumentCopy = true ;
359         argRWs[ctr] = makeReaderWriter( argTypes[ctr] ) ;
360         }
361     }
362
363     Class JavaDoc resultType = method.getReturnType() ;
364     needsResultCopy = false ;
365     hasVoidResult = resultType.equals( void.class ) ;
366     if (!hasVoidResult) {
367         needsResultCopy = !resultType.isPrimitive() ;
368         resultRW = makeReaderWriter( resultType ) ;
369     }
370     }
371
372     public Method JavaDoc getMethod()
373     {
374     return method ;
375     }
376
377     public Object JavaDoc[] copyArguments( Object JavaDoc[] args,
378     ORB orb ) throws RemoteException JavaDoc
379     {
380     if (needsArgumentCopy)
381         return Util.copyObjects( args, orb ) ;
382     else
383         return args ;
384     }
385
386     public Object JavaDoc[] readArguments( InputStream JavaDoc is )
387     {
388     Object JavaDoc[] result = null ;
389
390     if (hasArguments) {
391         result = new Object JavaDoc[ argRWs.length ] ;
392         for (int ctr=0; ctr<argRWs.length; ctr++ )
393         result[ctr] = argRWs[ctr].read( is ) ;
394     }
395
396     return result ;
397     }
398
399     public void writeArguments( OutputStream JavaDoc os, Object JavaDoc[] args )
400     {
401     if (hasArguments) {
402         if (args.length != argRWs.length)
403         throw new IllegalArgumentException JavaDoc( "Expected " + argRWs.length +
404             " arguments, but got " + args.length + " arguments." ) ;
405
406         for (int ctr=0; ctr<argRWs.length; ctr++ )
407         argRWs[ctr].write( os, args[ctr] ) ;
408     }
409     }
410
411     public Object JavaDoc copyResult( Object JavaDoc result, ORB orb ) throws RemoteException JavaDoc
412     {
413     if (needsResultCopy)
414         return Util.copyObject( result, orb ) ;
415     else
416         return result ;
417     }
418
419     public Object JavaDoc readResult( InputStream JavaDoc is )
420     {
421     if (hasVoidResult)
422         return null ;
423     else
424         return resultRW.read( is ) ;
425     }
426
427     public void writeResult( OutputStream JavaDoc os, Object JavaDoc result )
428     {
429     if (!hasVoidResult)
430         resultRW.write( os, result ) ;
431     }
432
433     public boolean isDeclaredException( Throwable JavaDoc thr )
434     {
435     return ehandler.isDeclaredException( thr.getClass() ) ;
436     }
437
438     public void writeException( OutputStream JavaDoc os, Exception JavaDoc ex )
439     {
440     ehandler.writeException( os, ex ) ;
441     }
442
443     public Exception JavaDoc readException( ApplicationException JavaDoc ae )
444     {
445     return ehandler.readException( ae ) ;
446     }
447 }
448
Popular Tags