1 18 package org.apache.geronimo.interop.rmi.iiop.compiler; 19 20 import java.lang.reflect.Method ; 21 import java.lang.reflect.Modifier ; 22 import java.io.File ; 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 { 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 inStreamName = "getInputStream"; 42 private String outStreamName = "getOutputStream"; 43 44 private HashMap packages = new HashMap(); 45 46 public SkelCompiler(GenOptions go, ClassLoader cl) { 47 super(go, cl); 48 } 49 50 public void addMethodGetIds(JClass jc) { 51 60 JMethod jm = jc.newMethod(new JReturnType(String [].class), 61 "getIds", 62 (JParameter[]) null, 63 (Class []) null); 64 65 jm.addStatement(new JCodeStatement("return _ids;")); 66 } 67 68 public void addMethodRegisterMethod(JClass jc) { 69 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 100 JMethod jm = jc.newMethod(new JReturnType(org.apache.geronimo.interop.rmi.iiop.ObjectRef.class), 101 "getObjectRef", 102 (JParameter[]) null, 103 (Class []) 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 121 JMethod jm = jc.newMethod(new JReturnType(org.apache.geronimo.interop.rmi.iiop.RemoteInterface.class), 122 "$getSkeleton", 123 (JParameter[]) null, 124 (Class []) null); 125 126 jm.addStatement(new JCodeStatement("return this;")); 127 } 128 129 protected boolean throwsAnRMIRemoteException(Method m) { 130 boolean rc = false; 131 132 Class c[] = m.getExceptionTypes(); 133 int i; 134 135 for (i = 0; i < c.length && !rc; i++) { 136 rc = java.rmi.RemoteException .class.isAssignableFrom(c[i]); 137 } 138 139 return rc; 140 } 141 142 public void addMethod(MethodOverload mo, JClass jc, GenOptions go) { 143 String invokeCall; 144 Method m = mo.method; 145 String name = m.getName(); 146 JParameter[] sparms = getMethodParms(m); 147 JParameter[] iparms = new JParameter[]{objInputVar, objOutputVar}; 148 String 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 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 readMethod = getReadMethod(sparms[i]); 172 JCodeStatement jcs = null; 173 174 if (readMethod != null) { 175 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 writeMethod = getWriteMethod(jrc); 210 codeStmt = null; 211 212 if (writeMethod != null) { 213 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 252 Class [] 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 .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 c = jv.getType(); 325 326 rc = isClassAValueType(c); 327 } 328 329 return rc; 330 } 331 332 protected boolean isClassAValueType(Class c) { 333 boolean rc = false; 334 335 if (c != null) { 336 if (java.io.Serializable .class.isAssignableFrom(c)) { 337 if (java.io.Externalizable .class.isAssignableFrom(c)) { 338 } 340 341 if (!isClassARMIRemote(c)) { 342 if (Modifier.isStatic(c.getModifiers()) && 343 c.getName().indexOf("$") != -1) { 344 347 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 c) { 362 boolean rc = false; 363 364 if (c != null) { 365 rc = java.rmi.Remote .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 riClassName = ""; 392 Class riClass = null; 393 String skelClassName = ""; 394 String pkgName = ""; 395 JPackage pkg = null; 396 397 while (intf != null && intf.hasNext() ) { 398 vtc.clear(); 400 401 riClassName = (String )intf.next(); 402 403 404 try { 405 riClass = getClassLoader().loadClass( riClassName ); 406 } catch (Exception 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 [].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 []) null); 439 jcCon.addStatement(new JCodeStatement("super();")); 440 441 444 addMethodGetIds(jc); 445 446 449 addMethodGetObjectRef(jc, riClass); 450 451 JMethod jmInvoke = jc.newMethod(new JReturnType(void.class), 452 "invoke", 453 new JParameter[]{new JParameter(String .class, "methodName"), 454 new JParameter(byte[].class, "objectKey"), 455 new JParameter(Adapter.class, "adapter"), 456 objInputVar, 457 objOutputVar}, 458 (Class []) null); 459 460 jmInvoke.setModifier(Modifier.PUBLIC); 461 462 JLocalVariable jvM = jmInvoke.newLocalVariable(Integer .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 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 jcCon.addStatement(new JCodeStatement("registerMethod( \"" + mo[i].iiop_name + "\", " + i + ");")); 489 490 caseStmt = switchStmt.newCase(new JExpression(new JCodeStatement("" + i))); 492 caseStmt.addStatement(new JCodeStatement(mo[i].iiop_name + "(input,output);")); 493 494 addMethod(mo[i], jc, go); 496 } 497 498 JCatchStatement catchStmt = null; 499 JVariable jvExcept = null; 500 501 jvExcept = new JVariable(java.lang.Error .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 .class, "rtEx"); 506 catchStmt = tcfs.newCatch(jvExcept); 507 catchStmt.addStatement(new JCodeStatement( "throw " + jvExcept.getName() + ";" ) ); 508 509 jvExcept = new JVariable(java.lang.Exception .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 skelPkg = ""; 519 520 while (pkgIt.hasNext()) 521 { 522 skelPkg = (String ) 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 { 531 532 Set pkg = packages.keySet(); 533 Iterator pkgIt = pkg.iterator(); 534 String skelPkg = ""; 535 536 541 542 GenOptions go = getGenOptions(); 543 String classpath = adjustPath(go.getClasspath()); 544 String srcpath = adjustPath(go.getGenSrcDir()); 545 546 String filesToCompile = ""; 547 String javacCmd = ""; 548 549 while (pkgIt.hasNext()) 550 { 551 skelPkg = (String ) 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 []) null, "./" ); 567 } 568 } 569 570 public Class getSkelClass() { 571 Class c = null; 572 573 try { 574 compile(); 576 } catch (Exception ex) { 577 ex.printStackTrace(); 578 } 579 580 return c; 581 } 582 583 public static void main(String args[]) throws Exception { 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 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 |