KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gcc > rmi > iiop > compiler > SkelCompiler


1 /*
2  * Copyright 2004 The Apache Software Foundation or its licensors, as
3  * applicable.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14  * implied.
15  *
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */

19
20 package gcc.rmi.iiop.compiler;
21
22 import gcc.generator.*;
23
24 import java.lang.reflect.Method;
25 import java.lang.reflect.Modifier;
26
27 import java.util.HashMap;
28 import java.util.Date;
29 import java.io.File;
30
31 public class SkelCompiler
32         extends Compiler
33 {
34     protected ValueTypeContext _vtc = new ValueTypeContext();
35     protected static JParameter _objInputVar = new JParameter( gcc.rmi.iiop.ObjectInputStream.class, "input");
36     protected static JParameter _objOutputVar = new JParameter( gcc.rmi.iiop.ObjectOutputStream.class, "output");
37
38     public SkelCompiler(Class remoteInterface)
39     {
40         super( remoteInterface );
41     }
42
43     public SkelCompiler( Class remoteInterface, GenOptions go )
44     {
45         super( remoteInterface, go );
46     }
47
48     //
49
// Methods
50
//
51

52     public void addMethodGetIds( JClass jc )
53     {
54         /*
55         public String[] getIds()
56         {
57             return _ids;
58         }
59         */

60
61         JMethod jm = jc.newMethod( new JReturnType(String.class, true),
62                                    "getIds",
63                                    (JParameter[])null,
64                                    (Class[])null );
65
66         jm.addStatement( new JCodeStatement("return _ids;") );
67     }
68
69     public void addMethodRegisterMethod( JClass jc )
70     {
71         /*
72         public void registerMethod( String name, int id )
73         {
74             _methodMap.put( name, new Integer(id) );
75         }
76         */

77
78         JMethod jm = jc.newMethod( new JReturnType(void.class),
79                                    "registerMethod",
80                                    new JParameter[] { new JParameter( String.class, "name" ),
81                                                       new JParameter( int.class, "id" ) },
82                                     (Class[]) null );
83
84         jm.addStatement( new JCodeStatement("_methods.put( name, new Integer(id) );") );
85     }
86
87     public void addMethodGetObjectRef( JClass jc, Class c )
88     {
89         /*
90         public ObjectRef $getObjectRef()
91         {
92             ObjectRef or = new ObjectRef();
93             or.$setID("RMI:mark.comps.Add:0000000000000000");
94             or.$setObjectKey( "mark.comps.Add" );
95             return or;
96         }
97         */

98
99         JMethod jm = jc.newMethod( new JReturnType("ObjectRef"),
100                                    "$getObjectRef",
101                                    (JParameter[])null,
102                                     (Class[]) null );
103
104         JLocalVariable jvor = jm.newLocalVariable( gcc.rmi.iiop.ObjectRef.class, "or", new JExpression( new JCodeStatement( "new ObjectRef()" ) ) );
105         jm.addStatement( new JCodeStatement( jvor.getName() + ".$setID(\"RMI:" + c.getName() + ":0000000000000000\");" ) );
106         jm.addStatement( new JCodeStatement( jvor.getName() + ".$setObjectKey(\"" + c.getName() + "\");" ) );
107         jm.addStatement( new JCodeStatement( "return " + jvor.getName() + ";" ) );
108     }
109
110     public void addMethodGetSkeleton( JClass jc )
111     {
112         /*
113         public RemoteInterface $getSkeleton()
114         {
115             return this;
116         }
117         */

118
119         JMethod jm = jc.newMethod( new JReturnType("RemoteInterface"),
120                                    "$getSkeleton",
121                                    (JParameter[])null,
122                                    (Class[]) null );
123
124         jm.addStatement( new JCodeStatement("return this;") );
125     }
126
127     protected boolean throwsAnRMIRemoteException( Method m )
128     {
129         boolean rc = false;
130
131         Class c[] = m.getExceptionTypes ();
132         int i;
133
134         for( i=0; i<c.length && !rc; i++ )
135         {
136             rc = java.rmi.RemoteException.class.isAssignableFrom(c[i]);
137         }
138
139         return rc;
140     }
141
142     public void addMethod( Method m, JClass jc )
143     {
144         String invokeCall;
145         String name = m.getName();
146         JParameter[] sparms = getMethodParms(m);
147         JParameter[] iparms = new JParameter[] { _objInputVar, _objOutputVar };
148
149         if (!isSimpleIDL() && !throwsAnRMIRemoteException(m))
150         {
151             error( "Method " + m.getName() + " does not throw java.rmi.RemoteException or subclass, unable to generate its skeleton method." );
152         }
153
154         JMethod jm = jc.newMethod( new JReturnType(void.class), name, iparms, null );
155
156         JVariable jrc = null;
157         String rc = m.getReturnType().getName();
158         if ( rc != null && rc.length() > 0 && (!rc.equals("void")) )
159         {
160             jrc = jm.newLocalVariable( m.getReturnType(), "rc" );
161         }
162
163         JTryCatchFinallyStatement tcfs = new JTryCatchFinallyStatement();
164         JTryStatement ts = tcfs.getTryStatement();
165
166         invokeCall = "_servant." + name + "(";
167
168         if (sparms != null && sparms.length > 0)
169         {
170             int i;
171             for( i=0; i<sparms.length; i++ )
172             {
173                 String readMethod = getReadMethod(sparms[i]);
174                 JCodeStatement jcs = null;
175
176                 if (readMethod != null)
177                 {
178                     // Primitive Type
179
// Cast not needed since each method returns the primitive datatype.
180

181                     jcs = new JCodeStatement( "input." + readMethod + "()" );
182                 }
183                 else
184                 {
185                     String vtVarName = _vtc.getValueTypeVarName( jc, sparms[i] );
186                     if (vtVarName != null)
187                     {
188                         jcs = new JCodeStatement( "(" + sparms[i].getTypeDecl() + ") input.readObject( " + vtVarName + " )" );
189                     }
190                     else
191                     {
192                         jcs = new JCodeStatement( "// Code Gen Error: Class '" + sparms[i].getTypeDecl() + " is not a valid value type." );
193                     }
194                 }
195
196                 ts.addStatement( new JDeclareStatement( sparms[i], new JExpression( jcs ) ) );
197
198                 invokeCall += " " + sparms[i].getName();
199                 if (i + 1 < sparms.length)
200                 {
201                     invokeCall += ",";
202                 }
203             }
204         }
205
206         invokeCall += " )";
207
208         if (jrc != null)
209         {
210             invokeCall = jrc.getName() + " = " + invokeCall;
211         }
212
213         invokeCall = invokeCall + ";";
214
215         ts.addStatement( new JCodeStatement(invokeCall) );
216
217         JVariable jv = new JVariable( java.lang.Exception.class, "ex" );
218         JCatchStatement cs = tcfs.newCatch( jv );
219         cs.addStatement( new JCodeStatement( jv.getName() + ".printStackTrace();" ) );
220
221         jv = new JVariable( java.lang.Error.class, "er" );
222         cs = tcfs.newCatch( jv );
223         cs.addStatement( new JCodeStatement( jv.getName() + ".printStackTrace();" ) );
224
225         jm.addStatement( tcfs );
226
227         if (jrc != null)
228         {
229             String writeMethod = getWriteMethod(jrc);
230             JCodeStatement jcs = null;
231
232             if (writeMethod != null)
233             {
234                 // Primitive Type
235
// Cast not needed since each method returns the primitive datatype.
236

237                 jcs = new JCodeStatement( "output." + writeMethod + "( " + jrc.getName() + " );" );
238             }
239             else
240             {
241                 String vtVarName = _vtc.getValueTypeVarName( jc, jrc );
242                 if (vtVarName != null)
243                 {
244                     jcs = new JCodeStatement( "output.writeObject( " + vtVarName + ", " + jrc.getName() +" );" );
245                 }
246                 else
247                 {
248                     jcs = new JCodeStatement( "// Code Gen Error: Class '" + jrc.getTypeDecl() + " is not a valid value type." );
249                 }
250             }
251
252             ts.addStatement( jcs );
253         }
254     }
255
256     protected boolean isVariableAValueType( JVariable jv )
257     {
258         boolean rc = false;
259
260         if (jv != null)
261         {
262             Class c = jv.getType();
263
264             rc = isClassAValueType( c );
265         }
266
267         return rc;
268     }
269
270     protected boolean isClassAValueType( Class c )
271     {
272         boolean rc = false;
273
274         if (c != null)
275         {
276             if (java.io.Serializable.class.isAssignableFrom(c))
277             {
278                 if (java.io.Externalizable.class.isAssignableFrom(c))
279                 {
280                     // Ok - but use the writeExternal and readExternal methods for serialization
281
}
282
283                 if (! isClassARMIRemote(c))
284                 {
285                     if ( Modifier.isStatic(c.getModifiers()) &&
286                          c.getName().indexOf("$") != -1 )
287                     {
288                         // TODO: How do we determine the inner-classes contained class?
289
// Parse the <containedclass>$<innerclass> ?
290

291                         //rc = isClassAValueType( c.getSuperclass() );
292
rc = true;
293                     }
294
295                     rc = true;
296                 }
297                 else
298                 {
299                     error( "Class: " + c.getName() + " is not proper value type as it is an instance of java.rmi.Remote or subclass." );
300                 }
301             }
302         }
303
304         return rc;
305     }
306
307     protected boolean isClassARMIRemote( Class c )
308     {
309         boolean rc = false;
310
311         if (c != null)
312         {
313             rc = java.rmi.Remote.class.isAssignableFrom( c );
314         }
315
316         return rc;
317     }
318
319     protected void error( String msg )
320     {
321         System.out.println( "Error: " + msg );
322     }
323
324     protected void error( String msg, Throwable t )
325     {
326         error( msg );
327         t.printStackTrace();
328     }
329
330     public void generate()
331         throws Exception
332     {
333         _vtc.clear();
334
335         if (!isSimpleIDL() && !isClassARMIRemote( _riClass ))
336         {
337             error( "Class '" + _riClass.getName() + "' must be an instance of either java.rmi.Remote or of a subclass." );
338         }
339
340         ClassLoader cl = _riClass.getClassLoader();
341         if (cl == null)
342         {
343             cl = ClassLoader.getSystemClassLoader();
344         }
345
346         String fullGenDir = _genOptions.getGenDir();
347
348         JavaGenerator jg = new JavaGenerator( _genOptions );
349
350         String className = _riClass.getName();
351
352         JPackage p = new JPackage( "" );
353         if (_riClass.getPackage() != null)
354         {
355             p = new JPackage( _riClass.getPackage().getName() );
356             className = className.substring ( className.lastIndexOf( ".") + 1 );
357         }
358
359         JClass jc = p.newClass( className + "_Skeleton" );
360
361         /*
362         jw.comment( "" );
363         jw.comment( "CORBA RMI-IIOP Skeleton Generator" );
364         jw.comment( " Interface: " + c.getName() );
365         jw.comment( " Date: " + (new Date(System.currentTimeMillis())).toString() );
366         jw.comment( "" );
367         */

368
369         jc.addImport( "gcc.rmi.iiop", "ObjectInputStream" );
370         jc.addImport( "gcc.rmi.iiop", "ObjectOutputStream" );
371         jc.addImport( "gcc.rmi.iiop", "RemoteInterface" );
372         jc.addImport( "gcc.rmi.iiop", "RemoteInterface" );
373         jc.addImport( "gcc.rmi.iiop", "ObjectRef" );
374         jc.addImport( "gcc.rmi.iiop", "RemoteObject" );
375         jc.addImport( "gcc.rmi.iiop.server", "Adapter" );
376         jc.addImport( "java.util", "HashMap" );
377
378         jc.setExtends( "RemoteObject" );
379         jc.addImplements( "RemoteInterface" );
380
381         JField idsField = jc.newField( String[].class, "_ids", new JExpression( new JCodeStatement( "{ \"" + _riClass.getName() + "\", \"RMI:" + _riClass.getName() + ":0000000000000000\"}" ) ), true );
382         JField methodsField = jc.newField( java.util.HashMap.class, "_methods", new JExpression( new JCodeStatement( "new HashMap(10)" ) ) );
383         JField servantField = jc.newField( _riClass, "_servant", new JExpression( new JCodeStatement( "null" ) ) );
384
385         JConstructor jcCon = jc.newConstructor( (JParameter[]) null, (Class[]) null );
386         jcCon.addStatement( new JCodeStatement( "super();" ) );
387
388         addMethodRegisterMethod( jc );
389         addMethodGetIds( jc );
390         addMethodGetSkeleton( jc );
391         addMethodGetObjectRef( jc, _riClass );
392
393         JMethod jmInvoke = jc.newMethod( new JReturnType(void.class),
394                                    "$invoke",
395                                    new JParameter[] { new JParameter( String.class, "methodName" ),
396                                                       new JParameter( byte[].class, "objectKey" ),
397                                                       new JParameter( Object.class, "instance" ),
398                                                       _objInputVar,
399                                                       _objOutputVar },
400                                     (Class[]) null );
401
402         jmInvoke.setModifier( Modifier.PUBLIC, true );
403
404         JLocalVariable jvM = jmInvoke.newLocalVariable( Integer.class, "m", new JExpression( new JCodeStatement( "(Integer)_methods.get(methodName)" ) ) );
405
406         jmInvoke.addStatement( new JCodeStatement( "if (m == null)" ) );
407         jmInvoke.addStatement( new JCodeStatement( "{" ) );
408         jmInvoke.addStatement( new JCodeStatement( " throw new org.omg.CORBA.BAD_OPERATION(methodName);" ) );
409         jmInvoke.addStatement( new JCodeStatement( "}" ) );
410         jmInvoke.addStatement( new JCodeStatement( "" ) );
411         jmInvoke.addStatement( new JCodeStatement( "_servant = (" + _riClass.getName() + ")instance;" ) );
412         jmInvoke.addStatement( new JCodeStatement( "" ) );
413         jmInvoke.addStatement( new JCodeStatement( "if (m.intValue() < 0)" ) );
414         jmInvoke.addStatement( new JCodeStatement( "{" ) );
415         jmInvoke.addStatement( new JCodeStatement( " super.invoke( m.intValue(), objectKey, instance, input, output );" ) );
416         jmInvoke.addStatement( new JCodeStatement( "}" ) );
417         jmInvoke.addStatement( new JCodeStatement( "" ) );
418
419         JSwitchStatement ss = new JSwitchStatement(new JExpression(new JCodeStatement("m.intValue()")));
420         JCaseStatement cs = null;
421         jmInvoke.addStatement( ss );
422
423         Method m[] = null;
424
425         if (isSimpleIDL())
426         {
427             m = _riClass.getMethods();
428         }
429         else
430         {
431             m = _riClass.getDeclaredMethods();
432         }
433
434         if (m != null && m.length > 0)
435         {
436             int i;
437             for (i=0; i<m.length; i++)
438             {
439                 // Enter a new method id in the _methods hashtable.
440
jcCon.addStatement( new JCodeStatement( "registerMethod( \"" + m[i].getName() + "\", " + i + ");" ) );
441
442                 // Add a new case statement to the invoke swtich
443
cs = ss.newCase( new JExpression( new JCodeStatement("" + i) ) );
444                 cs.addStatement( new JCodeStatement( m[i].getName() + "(input,output);" ) );
445
446                 // Generate the method wrapper
447
addMethod( m[i], jc );
448             }
449         }
450
451         jg.generate( p );
452     }
453
454     public void compile()
455         throws Exception
456     {
457     }
458
459     public Class getSkelClass()
460     {
461         Class c = null;
462
463         try
464         {
465             //generate();
466
compile();
467         }
468         catch( Exception ex )
469         {
470             ex.printStackTrace();
471         }
472
473         return c;
474     }
475
476     public static void main( String args[] )
477         throws Exception
478     {
479         boolean generate = false;
480         boolean compile = false;
481         boolean simpleIDL = false;
482         String ri = "";
483         GenOptions go = new GenOptions();
484
485         go.setGenDir( "./src" );
486         go.setOverwrite( false );
487         go.setVerbose( false );
488
489         for( int i=0; i<args.length; i++ )
490         {
491             if (args[i].equals( "-g" ))
492             {
493                 generate = true;
494             }
495             else if (args[i].equals( "-c" ))
496             {
497                 compile = true;
498             }
499             else if (args[i].equals( "-d" ) && ((i+1) < args.length))
500             {
501                 go.setGenDir( args[++i] );
502             }
503             else if (args[i].equals( "-v" ))
504             {
505                 go.setVerbose( true );
506             }
507             else if (args[i].equals( "-o" ))
508             {
509                 go.setOverwrite( true );
510             }
511             else if (args[i].equals( "-s" ))
512             {
513                 simpleIDL = true;
514             }
515             else if (args[i].startsWith("-"))
516             {
517                 System.out.println( "Warning: Ignoring unrecognized options: '" + args[i] + "'" );
518             }
519             else
520             {
521                 ri = args[i];
522             }
523         }
524
525         Class riClass = Class.forName( ri );
526
527         SkelCompiler sg = new SkelCompiler(riClass,go);
528
529         sg.setSimpleIDL( simpleIDL );
530
531         if (generate)
532         {
533             if (go.isVerbose())
534             {
535                 System.out.println("Generating: " + ri );
536             }
537
538             sg.generate();
539         }
540
541         if (compile)
542         {
543             if (go.isVerbose())
544             {
545                 System.out.println("Compiling: " + ri );
546             }
547
548             sg.compile();
549         }
550
551         //sg.setSimpleIDL( true );
552
//sg.generate( "gcc.rmi.iiop.NameServiceOperations");
553
}
554 }
555
556
Popular Tags