KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > interop > rmi > iiop > compiler > SkelCompiler


1 /**
2  *
3  * Copyright 2004-2005 The Apache Software Foundation
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 implied.
14  *
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package org.apache.geronimo.interop.rmi.iiop.compiler;
19
20 import java.lang.reflect.Method JavaDoc;
21 import java.lang.reflect.Modifier JavaDoc;
22 import java.io.File JavaDoc;
23 import java.util.*;
24
25 import org.apache.geronimo.interop.generator.*;
26 import org.apache.geronimo.interop.util.JavaClass;
27 import org.apache.geronimo.interop.util.ProcessUtil;
28 import org.apache.geronimo.interop.adapter.Adapter;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32
33 public class SkelCompiler extends Compiler JavaDoc {
34     private final Log log = LogFactory.getLog(SkelCompiler.class);
35
36     private ValueTypeContext vtc = new ValueTypeContext();
37
38     private static JParameter objInputVar = new JParameter(org.apache.geronimo.interop.rmi.iiop.ObjectInputStream.class, "input");
39     private static JParameter objOutputVar = new JParameter(org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream.class, "output");
40
41     private String JavaDoc inStreamName = "getInputStream";
42     private String JavaDoc outStreamName = "getOutputStream";
43
44     private HashMap packages = new HashMap();
45
46     public SkelCompiler(GenOptions go, ClassLoader JavaDoc cl) {
47         super(go, cl);
48     }
49
50     public void addMethodGetIds(JClass jc) {
51         //
52
// Method Template:
53
//
54
// public String[] getIds()
55
// {
56
// return _ids;
57
// }
58
//
59

60         JMethod jm = jc.newMethod(new JReturnType(String JavaDoc[].class),
61                                   "getIds",
62                                   (JParameter[]) null,
63                                   (Class JavaDoc[]) null);
64
65         jm.addStatement(new JCodeStatement("return _ids;"));
66     }
67
68     public void addMethodRegisterMethod(JClass jc) {
69         //
70
// Method Template:
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 JavaDoc.class, "name"),
81                                                    new JParameter(int.class, "id")},
82                                   (Class JavaDoc[]) null);
83
84         jm.addStatement(new JCodeStatement("_methods.put( name, new Integer(id) );"));
85     }
86
87     public void addMethodGetObjectRef(JClass jc, Class JavaDoc c) {
88         //
89
// Method Template:
90
//
91
// public ObjectRef getObjectRef()
92
// {
93
// ObjectRef or = new ObjectRef();
94
// or.$setID("RMI:mark.comps.Add:0000000000000000");
95
// or.$setObjectKey( "mark.comps.Add" );
96
// return or;
97
// }
98
//
99

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

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

178                     jcs = new JCodeStatement("input." + readMethod + "()");
179                 } else {
180                     vtVarName = vtc.getValueTypeVarName(jc, sparms[i]);
181                     if (vtVarName != null) {
182                         jcs = new JCodeStatement("(" + sparms[i].getTypeDecl() + ") input.readObject( " + vtVarName + " )");
183                     } else {
184                         jcs = new JCodeStatement("// Code Gen Error: Class '" + sparms[i].getTypeDecl() + " is not a valid value type.");
185                     }
186                 }
187
188                 declareStatementList.add(new JDeclareStatement(sparms[i], new JExpression(jcs)));
189
190                 invokeCall += " " + sparms[i].getName();
191                 if (i + 1 < sparms.length) {
192                     invokeCall += ",";
193                 }
194             }
195         }
196
197         invokeCall += " )";
198
199         if (jrc != null) {
200             invokeCall = jrc.getName() + " = " + invokeCall;
201         }
202
203         invokeCall = invokeCall + ";";
204
205         invokeStatement = new JCodeStatement(invokeCall);
206
207         JStatement writeResultStatement = null;
208         if (jrc != null) {
209             String JavaDoc writeMethod = getWriteMethod(jrc);
210             codeStmt = null;
211
212             if (writeMethod != null) {
213                 // Primitive Type
214
// Cast not needed since each method returns the primitive datatype.
215

216                 codeStmt = new JCodeStatement("output." + writeMethod + "( " + jrc.getName() + " );");
217             } else {
218                 vtVarName = vtc.getValueTypeVarName(jc, jrc);
219                 if (vtVarName != null) {
220                     codeStmt = new JCodeStatement("output.writeObject( " + vtVarName + ", " + jrc.getName() + " );");
221                 } else {
222                     codeStmt = new JCodeStatement("// Code Gen Error: Class '" + jrc.getTypeDecl() + " is not a valid value type.");
223                 }
224             }
225
226             writeResultStatement = codeStmt;
227         }
228
229         //
230
// The exception handling block:
231
//
232
// try
233
// {
234
// invoke method()
235
// }
236
// catch (java.lang.Exception $ex_1)
237
// {
238
// Listed here are the individual catches that the method can throw
239
// if ($ex_1 instanceof org.apache.geronimo.interop.CosNaming.NamingContextPackage.NotFound)
240
// {
241
// $output.writeException(type$4, $ex_1);
242
// return;
243
// }
244
// if ($ex_1 instanceof org.apache.geronimo.interop.CosNaming.NamingContextPackage.CannotProceed)
245
// {
246
// $output.writeException(type$5, $ex_1);
247
// return;
248
// }
249
// throw $ex_1;
250
// }
251

252         Class JavaDoc[] excepts = m.getExceptionTypes();
253         JVariable jvExcept = null;
254         JVariable jvTmp = null;
255
256         JCatchStatement catchStmt = null;
257
258         if (excepts != null && excepts.length > 0)
259         {
260             JTryCatchFinallyStatement tcfs = new JTryCatchFinallyStatement();
261             JTryStatement ts = tcfs.getTryStatement();
262
263             if (declareStatementList.size() > 0)
264             {
265                 for( int i=0; i<declareStatementList.size(); i++ )
266                 {
267                     ts.addStatement( (JStatement)declareStatementList.get(i) );
268                 }
269             }
270
271             ts.addStatement( invokeStatement );
272
273             jvExcept = new JVariable(java.lang.Exception JavaDoc.class, "ex");
274             catchStmt = tcfs.newCatch(jvExcept);
275
276             for( int i=0; excepts != null && i < excepts.length; i++ )
277             {
278                 jvTmp = new JVariable( excepts[i], "exvar" );
279                 vtVarName = vtc.getValueTypeVarName(jc, jvTmp);
280                 codeStmt = null;
281                 if (vtVarName != null) {
282                     codeStmt = new JCodeStatement("output.writeException( " + vtVarName + ", " + jvExcept.getName() + ");" );
283                 } else {
284                     codeStmt = new JCodeStatement("// Code Gen Error: Class '" + sparms[i].getTypeDecl() + " is not a valid value type.");
285                 }
286
287                 JIfStatement ifs = new JIfStatement( new JExpression(
288                         new JCodeStatement( jvExcept.getName() + " instanceof " + excepts[i].getName() ) ));
289                 ifs.addStatement( codeStmt );
290                 ifs.addStatement( new JCodeStatement( "return;" ));
291                 catchStmt.addStatement( ifs );
292             }
293
294             if (writeResultStatement != null)
295             {
296                 ts.addStatement( writeResultStatement );
297             }
298
299             jm.addStatement(tcfs);
300         }
301         else
302         {
303             if (declareStatementList.size() > 0)
304             {
305                 for( int i=0; i<declareStatementList.size(); i++ )
306                 {
307                     jm.addStatement( (JStatement)declareStatementList.get(i) );
308                 }
309             }
310
311             jm.addStatement( invokeStatement );
312
313             if (writeResultStatement != null)
314             {
315                 jm.addStatement( writeResultStatement );
316             }
317         }
318     }
319
320     protected boolean isVariableAValueType(JVariable jv) {
321         boolean rc = false;
322
323         if (jv != null) {
324             Class JavaDoc c = jv.getType();
325
326             rc = isClassAValueType(c);
327         }
328
329         return rc;
330     }
331
332     protected boolean isClassAValueType(Class JavaDoc c) {
333         boolean rc = false;
334
335         if (c != null) {
336             if (java.io.Serializable JavaDoc.class.isAssignableFrom(c)) {
337                 if (java.io.Externalizable JavaDoc.class.isAssignableFrom(c)) {
338                     // Ok - but use the writeExternal and readExternal methods for serialization
339
}
340
341                 if (!isClassARMIRemote(c)) {
342                     if (Modifier.isStatic(c.getModifiers()) &&
343                         c.getName().indexOf("$") != -1) {
344                         // TODO: How do we determine the inner-classes contained class?
345
// Parse the <containedclass>$<innerclass> ?
346

347                         //rc = isClassAValueType( c.getSuperclass() );
348
rc = true;
349                     }
350
351                     rc = true;
352                 } else {
353                     error("Class: " + c.getName() + " is not proper value type as it is an instance of java.rmi.Remote or subclass.");
354                 }
355             }
356         }
357
358         return rc;
359     }
360
361     protected boolean isClassARMIRemote(Class JavaDoc c) {
362         boolean rc = false;
363
364         if (c != null) {
365             rc = java.rmi.Remote JavaDoc.class.isAssignableFrom(c);
366         }
367
368         return rc;
369     }
370
371     public void generate() throws GenException {
372
373         GenOptions go = getGenOptions();
374         List interfaces = go.getInterfaces();
375         Iterator intf = null;
376
377         if (interfaces != null) {
378             intf = interfaces.iterator();
379         }
380
381         JavaGenerator jg = new JavaGenerator(genOptions);
382
383         if (go.isSimpleIdl()) {
384             inStreamName = "getSimpleInputStream";
385             outStreamName = "getSimpleOutputStream";
386         } else {
387             inStreamName = "getInputStream";
388             outStreamName = "getOutputStream";
389         }
390
391         String JavaDoc riClassName = "";
392         Class JavaDoc riClass = null;
393         String JavaDoc skelClassName = "";
394         String JavaDoc pkgName = "";
395         JPackage pkg = null;
396
397         while (intf != null && intf.hasNext() ) {
398             // Clear the value type cache.
399
vtc.clear();
400
401             riClassName = (String JavaDoc)intf.next();
402
403
404             try {
405                 riClass = getClassLoader().loadClass( riClassName );
406             } catch (Exception JavaDoc ex) {
407                 throw new GenException( "Generate Skels Failed:", ex );
408             }
409
410             if (!go.isSimpleIdl() && !isClassARMIRemote(riClass)) {
411                 error("Class '" + riClass.getName() + "' must be an instance of either java.rmi.Remote or of a subclass.");
412             }
413
414             pkgName = JavaClass.getNamePrefix(riClassName);
415             skelClassName = JavaClass.getNameSuffix(riClassName);
416             pkg = (JPackage) packages.get( pkgName );
417             if (pkg == null)
418             {
419                 pkg = new JPackage( pkgName );
420                 packages.put( pkgName, pkg );
421             }
422
423             JClass jc = pkg.newClass(skelClassName + "_Skeleton");
424
425             jc.addImport("org.apache.geronimo.interop.rmi.iiop", "RemoteInterface");
426             jc.addImport("org.apache.geronimo.interop.rmi.iiop", "ObjectRef");
427             jc.addImport("org.apache.geronimo.interop.rmi.iiop", "RemoteObject");
428
429             jc.setExtends("RemoteObject");
430             jc.addImplements("RemoteInterface");
431
432             JField idsField = jc.newField(String JavaDoc[].class, "_ids", new JExpression(new JCodeStatement("{ \"" + riClass.getName() + "\", \"RMI:" + riClass.getName() + ":0000000000000000\"}")), true);
433             idsField.setModifiers(Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL);
434
435             JField servantField = jc.newField(riClass, "_servant", new JExpression(new JCodeStatement("null")));
436             servantField.setModifiers(Modifier.PRIVATE);
437
438             JConstructor jcCon = jc.newConstructor((JParameter[]) null, (Class JavaDoc[]) null);
439             jcCon.addStatement(new JCodeStatement("super();"));
440
441             // Replaced with the method in the RemoteObject parent class
442
//addMethodRegisterMethod(jc);
443

444             addMethodGetIds(jc);
445
446             // Not used anymore
447
//addMethodGetSkeleton(jc);
448

449             addMethodGetObjectRef(jc, riClass);
450
451             JMethod jmInvoke = jc.newMethod(new JReturnType(void.class),
452                                             "invoke",
453                                             new JParameter[]{new JParameter(String JavaDoc.class, "methodName"),
454                                                              new JParameter(byte[].class, "objectKey"),
455                                                              new JParameter(Adapter.class, "adapter"),
456                                                              objInputVar,
457                                                              objOutputVar},
458                                             (Class JavaDoc[]) null);
459
460             jmInvoke.setModifier(Modifier.PUBLIC);
461
462             JLocalVariable jvM = jmInvoke.newLocalVariable(Integer JavaDoc.class, "m", new JExpression(new JCodeStatement("getMethodId(methodName); // (Integer)_methods.get(methodName)")));
463
464             JIfStatement jis = new JIfStatement(new JExpression(new JCodeStatement(jvM.getName() + " == null")));
465             jis.addStatement(new JCodeStatement("throw new org.omg.CORBA.BAD_OPERATION(methodName);"));
466             jmInvoke.addStatement(jis);
467
468             jmInvoke.addStatement(new JCodeStatement("_servant = (" + riClass.getName() + ")adapter.getServant(); //instance;"));
469
470             JIfStatement jis2 = new JIfStatement(new JExpression(new JCodeStatement(jvM.getName() + ".intValue() < 0")));
471             jis2.addStatement(new JCodeStatement("super.invoke( " + jvM.getName() + ".intValue(), objectKey, adapter, input, output );"));
472             jmInvoke.addStatement(jis2);
473
474             JTryCatchFinallyStatement tcfs = new JTryCatchFinallyStatement();
475             JTryStatement ts = tcfs.getTryStatement();
476
477             JSwitchStatement switchStmt = new JSwitchStatement(new JExpression(new JCodeStatement("m.intValue()")));
478             JCaseStatement caseStmt = null;
479             ts.addStatement(switchStmt);
480
481             Method JavaDoc m[] = getMethods( riClass, go.isSimpleIdl());
482             MethodOverload mo[] = null;
483             mo = getMethodOverloads( m );
484
485             for (int i = 0; mo != null && i < mo.length; i++)
486             {
487                 // Enter a new method id in the _methods hashtable.
488
jcCon.addStatement(new JCodeStatement("registerMethod( \"" + mo[i].iiop_name + "\", " + i + ");"));
489
490                 // Add a new case statement to the invoke swtich
491
caseStmt = switchStmt.newCase(new JExpression(new JCodeStatement("" + i)));
492                 caseStmt.addStatement(new JCodeStatement(mo[i].iiop_name + "(input,output);"));
493
494                 // Generate the method wrapper
495
addMethod(mo[i], jc, go);
496             }
497
498             JCatchStatement catchStmt = null;
499             JVariable jvExcept = null;
500
501             jvExcept = new JVariable(java.lang.Error JavaDoc.class, "erEx");
502             catchStmt = tcfs.newCatch(jvExcept);
503             catchStmt.addStatement(new JCodeStatement( "throw new org.apache.geronimo.interop.SystemException( " + jvExcept.getName() + " );" ) );
504
505             jvExcept = new JVariable(java.lang.RuntimeException JavaDoc.class, "rtEx");
506             catchStmt = tcfs.newCatch(jvExcept);
507             catchStmt.addStatement(new JCodeStatement( "throw " + jvExcept.getName() + ";" ) );
508
509             jvExcept = new JVariable(java.lang.Exception JavaDoc.class, "exEx");
510             catchStmt = tcfs.newCatch(jvExcept);
511             catchStmt.addStatement(new JCodeStatement( "throw new org.apache.geronimo.interop.SystemException( " + jvExcept.getName() + " );" ) );
512
513             jmInvoke.addStatement( tcfs );
514         }
515
516         Set pkgSet = packages.keySet();
517         Iterator pkgIt = pkgSet.iterator();
518         String JavaDoc skelPkg = "";
519
520         while (pkgIt.hasNext())
521         {
522             skelPkg = (String JavaDoc) pkgIt.next();
523             pkg = (JPackage)packages.get(skelPkg);
524             System.out.println("Generating Package: " + skelPkg);
525             jg.generate(pkg);
526         }
527     }
528
529     public void compile()
530             throws Exception JavaDoc {
531
532         Set pkg = packages.keySet();
533         Iterator pkgIt = pkg.iterator();
534         String JavaDoc skelPkg = "";
535
536         /*
537          * Each of the packages were generated under go.getGenSrcDir().
538          *
539          * Go through all the packages and run the compiler on *.java
540          */

541
542         GenOptions go = getGenOptions();
543         String JavaDoc classpath = adjustPath(go.getClasspath());
544         String JavaDoc srcpath = adjustPath(go.getGenSrcDir());
545
546         String JavaDoc filesToCompile = "";
547         String JavaDoc javacCmd = "";
548
549         while (pkgIt.hasNext())
550         {
551             skelPkg = (String JavaDoc) pkgIt.next();
552             skelPkg = skelPkg.replace( '.', File.separatorChar );
553             filesToCompile = adjustPath(go.getGenSrcDir() + File.separator + skelPkg + File.separator + "*.java");
554
555             System.out.println("Compiling Package: " + filesToCompile);
556
557             javacCmd = "javac -d " + go.getGenClassDir() +
558                             ( go.isCompileDebug() ? " -g" : "" ) +
559                             " -classpath " + classpath + " " +
560                             " -sourcepath " + srcpath + " " + filesToCompile;
561
562             System.out.println( "Lauching: " + javacCmd );
563
564             ProcessUtil pu = ProcessUtil.getInstance();
565             pu.setEcho(System.out);
566             pu.run(javacCmd, (String JavaDoc[]) null, "./" );
567         }
568     }
569
570     public Class JavaDoc getSkelClass() {
571         Class JavaDoc c = null;
572
573         try {
574             //generate();
575
compile();
576         } catch (Exception JavaDoc ex) {
577             ex.printStackTrace();
578         }
579
580         return c;
581     }
582
583     public static void main(String JavaDoc args[]) throws Exception JavaDoc {
584         GenOptions go = null;
585
586         try
587         {
588             go = new GenOptions( "./skels", args );
589         }
590         catch( GenWarning gw )
591         {
592             gw.printStackTrace();
593         }
594
595         ClassLoader JavaDoc cl = ClassLoader.getSystemClassLoader();
596         SkelCompiler sg = new SkelCompiler( go, cl );
597
598         if (go.isGenerate()) {
599             sg.generate();
600         }
601
602         if (go.isCompile()) {
603             sg.compile();
604         }
605     }
606 }
607
Popular Tags