StubGenerator.java revision 608:7e06bf1dcb09
1/* 2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26/* 27 * Licensed Materials - Property of IBM 28 * RMI-IIOP v1.0 29 * Copyright IBM Corp. 1998 1999 All Rights Reserved 30 * 31 */ 32 33package sun.rmi.rmic.iiop; 34 35import java.io.File; 36import java.io.IOException; 37import java.io.SerializablePermission; 38import java.security.AccessController; 39import java.security.PrivilegedAction; 40import java.util.Vector; 41import java.util.Hashtable; 42import java.util.Enumeration; 43import sun.tools.java.Identifier; 44import sun.tools.java.ClassNotFound; 45import sun.tools.java.ClassDefinition; 46import sun.tools.java.ClassDeclaration; 47import sun.tools.java.CompilerError; 48import sun.rmi.rmic.IndentingWriter; 49import java.util.HashSet; 50import java.util.Arrays; 51import com.sun.corba.se.impl.util.Utility; 52import com.sun.corba.se.impl.util.PackagePrefixChecker; 53import sun.rmi.rmic.Main; 54 55 56/** 57 * An IIOP stub/tie generator for rmic. 58 * 59 * @author Bryan Atsatt 60 * @author Anil Vijendran 61 * @author M. Mortazavi 62 */ 63 64public class StubGenerator extends sun.rmi.rmic.iiop.Generator { 65 66 private static final String DEFAULT_STUB_CLASS = "javax.rmi.CORBA.Stub"; 67 private static final String DEFAULT_TIE_CLASS = "org.omg.CORBA_2_3.portable.ObjectImpl"; 68 private static final String DEFAULT_POA_TIE_CLASS = "org.omg.PortableServer.Servant"; 69 70 protected boolean reverseIDs = false; 71 protected boolean localStubs = true; 72 protected boolean standardPackage = false; 73 protected boolean useHash = true; 74 protected String stubBaseClass = DEFAULT_STUB_CLASS; 75 protected String tieBaseClass = DEFAULT_TIE_CLASS; 76 protected HashSet namesInUse = new HashSet(); 77 protected Hashtable classesInUse = new Hashtable(); 78 protected Hashtable imports = new Hashtable(); 79 protected int importCount = 0; 80 protected String currentPackage = null; 81 protected String currentClass = null; 82 protected boolean castArray = false; 83 protected Hashtable transactionalObjects = new Hashtable() ; 84 protected boolean POATie = false ; 85 protected boolean emitPermissionCheck = false; 86 87 /** 88 * Default constructor for Main to use. 89 */ 90 public StubGenerator() { 91 } 92 93 /** 94 * Overridden in order to set the standardPackage flag. 95 */ 96 public void generate( 97 sun.rmi.rmic.BatchEnvironment env, 98 ClassDefinition cdef, File destDir) { 99 ((sun.rmi.rmic.iiop.BatchEnvironment)env). 100 setStandardPackage(standardPackage); 101 super.generate(env, cdef, destDir); 102 } 103 104 /** 105 * Return true if a new instance should be created for each 106 * class on the command line. Subclasses which return true 107 * should override newInstance() to return an appropriately 108 * constructed instance. 109 */ 110 protected boolean requireNewInstance() { 111 return false; 112 } 113 114 /** 115 * Return true if non-conforming types should be parsed. 116 * @param stack The context stack. 117 */ 118 protected boolean parseNonConforming(ContextStack stack) { 119 120 // We let the environment setting decide so that 121 // another generator (e.g. IDLGenerator) can change 122 // it and we will just go with the flow... 123 124 return stack.getEnv().getParseNonConforming(); 125 } 126 127 /** 128 * Create and return a top-level type. 129 * @param cdef The top-level class definition. 130 * @param stack The context stack. 131 * @return The compound type or null if is non-conforming. 132 */ 133 protected CompoundType getTopType(ClassDefinition cdef, ContextStack stack) { 134 135 CompoundType result = null; 136 137 // Do we have an interface? 138 139 if (cdef.isInterface()) { 140 141 // Yes, so first try Abstract... 142 143 result = AbstractType.forAbstract(cdef,stack,true); 144 145 if (result == null) { 146 147 // Then try Remote... 148 149 result = RemoteType.forRemote(cdef,stack,false); 150 } 151 } else { 152 153 // Not an interface, so try Implementation... 154 155 result = ImplementationType.forImplementation(cdef,stack,false); 156 } 157 158 return result; 159 } 160 161 /** 162 * Examine and consume command line arguments. 163 * @param argv The command line arguments. Ignore null 164 * and unknown arguments. Set each consumed argument to null. 165 * @param error Report any errors using the main.error() methods. 166 * @return true if no errors, false otherwise. 167 */ 168 public boolean parseArgs(String argv[], Main main) { 169 Object marker = new Object() ; 170 171 // Reset any cached options... 172 173 reverseIDs = false; 174 localStubs = true; 175 useHash = true; 176 stubBaseClass = DEFAULT_STUB_CLASS; 177 // tieBaseClass = DEFAULT_TIE_CLASS; 178 transactionalObjects = new Hashtable() ; 179 180 // Parse options... 181 182 boolean result = super.parseArgs(argv,main); 183 if (result) { 184 for (int i = 0; i < argv.length; i++) { 185 if (argv[i] != null) { 186 String arg = argv[i].toLowerCase(); 187 if (arg.equals("-iiop")) { 188 argv[i] = null; 189 } else if (arg.equals("-xreverseids")) { 190 reverseIDs = true; 191 argv[i] = null; 192 } else if (arg.equals("-nolocalstubs")) { 193 localStubs = false; 194 argv[i] = null; 195 } else if (arg.equals("-xnohash")) { 196 useHash = false; 197 argv[i] = null; 198 } else if (argv[i].equals("-standardPackage")) { 199 standardPackage = true; 200 argv[i] = null; 201 } else if (argv[i].equals("-emitPermissionCheck")) { 202 emitPermissionCheck = true; 203 argv[i] = null; 204 } else if (arg.equals("-xstubbase")) { 205 argv[i] = null; 206 if (++i < argv.length && argv[i] != null && !argv[i].startsWith("-")) { 207 stubBaseClass = argv[i]; 208 argv[i] = null; 209 } else { 210 main.error("rmic.option.requires.argument", "-Xstubbase"); 211 result = false; 212 } 213 } else if (arg.equals("-xtiebase")) { 214 argv[i] = null; 215 if (++i < argv.length && argv[i] != null && !argv[i].startsWith("-")) { 216 tieBaseClass = argv[i]; 217 argv[i] = null; 218 } else { 219 main.error("rmic.option.requires.argument", "-Xtiebase"); 220 result = false; 221 } 222 } else if (arg.equals("-transactional" )) { 223 // Scan for the next non-flag argument. 224 // Assume that it is a class name and add it 225 // to the list of transactional classes. 226 for ( int ctr=i+1; ctr<argv.length; ctr++ ) { 227 if (argv[ctr].charAt(1) != '-') { 228 transactionalObjects.put( argv[ctr], marker ) ; 229 break ; 230 } 231 } 232 argv[i] = null; 233 } else if (arg.equals( "-poa" )) { 234 POATie = true ; 235 argv[i] = null; 236 } 237 } 238 } 239 } 240 if(POATie){ 241 tieBaseClass = DEFAULT_POA_TIE_CLASS; 242 } else { 243 tieBaseClass = DEFAULT_TIE_CLASS; 244 } 245 return result; 246 } 247 248 /** 249 * Return an array containing all the file names and types that need to be 250 * generated for the given top-level type. The file names must NOT have an 251 * extension (e.g. ".java"). 252 * @param topType The type returned by getTopType(). 253 * @param alreadyChecked A set of Types which have already been checked. 254 * Intended to be passed to topType.collectMatching(filter,alreadyChecked). 255 */ 256 protected OutputType[] getOutputTypesFor(CompoundType topType, 257 HashSet alreadyChecked) { 258 259 // We want to generate stubs for all remote and implementation types, 260 // so collect them up. 261 // 262 // We use the form of collectMatching which allows us to pass in a set of 263 // types which have previously been checked. By doing so, we ensure that if 264 // the command line contains Hello and HelloImpl, we will only generate 265 // output for Hello once... 266 267 int filter = TYPE_REMOTE | TYPE_IMPLEMENTATION; 268 Type[] genTypes = topType.collectMatching(filter,alreadyChecked); 269 int count = genTypes.length; 270 Vector list = new Vector(count+5); 271 BatchEnvironment theEnv = topType.getEnv(); 272 273 // Now walk all types... 274 275 for (int i = 0; i < genTypes.length; i++) { 276 277 Type type = genTypes[i]; 278 String typeName = type.getName(); 279 boolean createStub = true; 280 281 // Is it an implementation type? 282 283 if (type instanceof ImplementationType) { 284 285 // Yes, so add a tie for it... 286 287 list.addElement(new OutputType(Utility.tieNameForCompiler(typeName), type)); 288 289 // Does it have more than 1 remote interface? If so, we 290 // want to create a stub for it... 291 292 int remoteInterfaceCount = 0; 293 InterfaceType[] interfaces = ((CompoundType)type).getInterfaces(); 294 for (int j = 0; j < interfaces.length; j++) { 295 if (interfaces[j].isType(TYPE_REMOTE) && 296 !interfaces[j].isType(TYPE_ABSTRACT)) { 297 remoteInterfaceCount++; 298 } 299 } 300 301 if (remoteInterfaceCount <= 1) { 302 303 // No, so do not create a stub for this type... 304 305 createStub = false; 306 } 307 } 308 309 // Is it an abstract interface type? 310 311 if (type instanceof AbstractType) { 312 313 // Do not create a stub for this type... 314 315 createStub = false; // d11141 316 } 317 318 if (createStub) { 319 320 // Add a stub for the type... 321 322 list.addElement(new OutputType(Utility.stubNameForCompiler(typeName), type)); 323 } 324 } 325 326 // Copy list into array.. 327 328 OutputType[] outputTypes = new OutputType[list.size()]; 329 list.copyInto(outputTypes); 330 return outputTypes; 331 } 332 333 /** 334 * Return the file name extension for the given file name (e.g. ".java"). 335 * All files generated with the ".java" extension will be compiled. To 336 * change this behavior for ".java" files, override the compileJavaSourceFile 337 * method to return false. 338 * @param outputType One of the items returned by getOutputTypesFor(...) 339 */ 340 protected String getFileNameExtensionFor(OutputType outputType) { 341 return SOURCE_FILE_EXTENSION; 342 } 343 344 /** 345 * Write the output for the given OutputFileName into the output stream. 346 * @param name One of the items returned by getOutputTypesFor(...) 347 * @param alreadyChecked A set of Types which have already been checked. 348 * Intended to be passed to Type.collectMatching(filter,alreadyChecked). 349 * @param writer The output stream. 350 */ 351 protected void writeOutputFor( OutputType outputType, 352 HashSet alreadyChecked, 353 IndentingWriter writer) throws IOException { 354 355 String fileName = outputType.getName(); 356 CompoundType theType = (CompoundType) outputType.getType(); 357 358 // Are we doing a Stub or Tie? 359 360 if (fileName.endsWith(Utility.RMI_STUB_SUFFIX)) { 361 362 // Stub. 363 364 writeStub(outputType,writer); 365 366 } else { 367 368 // Tie 369 370 writeTie(outputType,writer); 371 } 372 } 373 374 /** 375 * Write a stub for the specified type. 376 */ 377 protected void writeStub(OutputType outputType, 378 IndentingWriter p) throws IOException { 379 380 CompoundType theType = (CompoundType) outputType.getType(); 381 RemoteType[] remoteInterfaces = getDirectRemoteInterfaces(theType); 382 383 // Write comment. 384 385 p.pln("// Stub class generated by rmic, do not edit."); 386 p.pln("// Contents subject to change without notice."); 387 p.pln(); 388 389 // Set our standard classes... 390 391 setStandardClassesInUse(theType,true); 392 393 // Add classes for this type... 394 395 addClassesInUse(theType,remoteInterfaces); 396 397 // Write package and import statements... 398 399 writePackageAndImports(p); 400 401// generate 402// import java.security.AccessController; 403// import java.security.PrivilegedAction; 404// import java.io.SerializablePermission; 405 if (emitPermissionCheck) { 406 p.pln("import java.security.AccessController;"); 407 p.pln("import java.security.PrivilegedAction;"); 408 p.pln("import java.io.SerializablePermission;"); 409 p.pln(); 410 p.pln(); 411 } 412 413 // Declare the stub class; implement all remote interfaces. 414 415 p.p("public class " + currentClass); 416 417 p.p(" extends " + getName(stubBaseClass)); 418 p.p(" implements "); 419 if (remoteInterfaces.length > 0) { 420 for(int i = 0; i < remoteInterfaces.length; i++) { 421 if (i > 0) { 422 p.pln(","); 423 } 424 String objName = testUtil(getName(remoteInterfaces[i]), theType); 425 p.p(objName); 426 } 427 } 428 429 // Add java.rmi.Remote if this type does not implement it. 430 // This allows stubs for Abstract interfaces to be treated 431 // uniformly... 432 433 if (!implementsRemote(theType)) { 434 p.pln(","); 435 p.p(getName("java.rmi.Remote")); 436 } 437 438 p.plnI(" {"); 439 p.pln(); 440 441 // Write the ids... 442 443 writeIds( p, theType, false ); 444 p.pln(); 445 446 if (emitPermissionCheck) { 447 448 // produce the following generated code for example 449 // private static Void checkPermission() { 450 // SecurityManager sm = System.getSecurityManager(); 451 // if (sm != null) { 452 // sm.checkPermission(new SerializablePermission( 453 // "enableSubclassImplementation")); // testing 454 // } 455 // return null; 456 // } 457 // 458 // private _XXXXX_Stub(Void ignore) { 459 // } 460 // 461 // public _XXXXX_Stub() { 462 // this(checkPermission()); 463 // } 464 // 465 // where XXXXX is the name of the remote interface 466 467 p.pln(); 468 p.plnI("private static Void checkPermission() {"); 469 p.plnI("SecurityManager sm = System.getSecurityManager();"); 470 p.pln("if (sm != null) {"); 471 p.pI(); 472 p.plnI("sm.checkPermission(new SerializablePermission("); 473 p.plnI("\"enableSubclassImplementation\"));"); 474 p.pO(); 475 p.pO(); 476 p.pOln("}"); 477 p.pln("return null;"); 478 p.pO(); 479 p.pOln("}"); 480 p.pln(); 481 p.pO(); 482 483 p.pI(); 484 p.pln("private " + currentClass + "(Void ignore) { }"); 485 p.pln(); 486 487 p.plnI("public " + currentClass + "() { "); 488 p.pln("this(checkPermission());"); 489 p.pOln("}"); 490 p.pln(); 491 } 492 493 if (!emitPermissionCheck) { 494 p.pI(); 495 } 496 497 // Write the _ids() method... 498 499 p.plnI("public String[] _ids() { "); 500 p.pln("return (String[]) _type_ids.clone();"); 501 p.pOln("}"); 502 503 // Get all the methods and write each stub method... 504 505 CompoundType.Method[] remoteMethods = theType.getMethods(); 506 int methodCount = remoteMethods.length; 507 if (methodCount > 0) { 508 boolean writeHeader = true; 509 for(int i = 0; i < methodCount; i++) { 510 if (!remoteMethods[i].isConstructor()) { 511 if (writeHeader) { 512 writeHeader = false; 513 } 514 p.pln(); 515 writeStubMethod(p, remoteMethods[i], theType); 516 } 517 } 518 } 519 520 // Write the cast array hack... 521 522 writeCastArray(p); 523 524 p.pOln("}"); // end stub class 525 } 526 527 void addClassInUse(String qualifiedName) { 528 String unqualifiedName = qualifiedName; 529 String packageName = null; 530 int index = qualifiedName.lastIndexOf('.'); 531 if (index > 0) { 532 unqualifiedName = qualifiedName.substring(index+1); 533 packageName = qualifiedName.substring(0,index); 534 } 535 addClassInUse(unqualifiedName,qualifiedName,packageName); 536 } 537 538 void addClassInUse(Type type) { 539 if (!type.isPrimitive()) { 540 Identifier id = type.getIdentifier(); 541 String name = IDLNames.replace(id.getName().toString(),". ","."); 542 String packageName = type.getPackageName(); 543 String qualifiedName; 544 if (packageName != null) { 545 qualifiedName = packageName+"."+name; 546 } else { 547 qualifiedName = name; 548 } 549 addClassInUse(name,qualifiedName,packageName); 550 } 551 } 552 553 void addClassInUse(Type[] types) { 554 for (int i = 0; i < types.length; i++) { 555 addClassInUse(types[i]); 556 } 557 } 558 559 void addStubInUse(Type type) { 560 if (type.getIdentifier() != idCorbaObject && 561 type.isType(TYPE_CORBA_OBJECT)) { 562 String stubName = getStubNameFor(type,false); 563 String packageName = type.getPackageName(); 564 String fullName; 565 if (packageName == null) { 566 fullName = stubName; 567 } else { 568 fullName = packageName + "." + stubName; 569 } 570 addClassInUse(stubName,fullName,packageName); 571 } 572 if (type.isType(TYPE_REMOTE) || 573 type.isType(TYPE_JAVA_RMI_REMOTE)) { 574 addClassInUse("javax.rmi.PortableRemoteObject"); 575 } 576 } 577 578 String getStubNameFor(Type type, boolean qualified) { 579 String stubName; 580 String className; 581 if (qualified) { 582 className = type.getQualifiedName(); 583 } else { 584 className = type.getName(); 585 } 586 if (((CompoundType)type).isCORBAObject()) { 587 stubName = Utility.idlStubName(className); 588 } else { 589 stubName = Utility.stubNameForCompiler(className); 590 } 591 return stubName; 592 } 593 594 void addStubInUse(Type[] types) { 595 for (int i = 0; i < types.length; i++) { 596 addStubInUse(types[i]); 597 } 598 } 599 600 private static final String NO_IMPORT = new String(); 601 602 void addClassInUse(String unqualifiedName, String qualifiedName, String packageName) { 603 604 // Have we already got an entry for this qualifiedName? 605 606 String currentName = (String)classesInUse.get(qualifiedName); 607 608 if (currentName == null) { 609 610 // No, never seen it before. Grab any existing import 611 // name and then decide what to do... 612 613 String importName = (String) imports.get(unqualifiedName); 614 String nameToUse = null; 615 616 if (packageName == null) { 617 618 // Default package, so doesn't matter which name to use... 619 620 nameToUse = unqualifiedName; 621 622 } else if (packageName.equals("java.lang")) { 623 624 // java.lang.*, so use unqualified name... 625 626 nameToUse = unqualifiedName; 627 628 // unless you want to be able to import things from the right place :--) 629 630 if(nameToUse.endsWith("_Stub")) nameToUse = Util.packagePrefix()+qualifiedName; 631 632 } else if (currentPackage != null && packageName.equals(currentPackage)) { 633 634 // Class in currentPackage, so use unqualified name... 635 636 nameToUse = unqualifiedName; 637 638 // Do we already have a previous import under this 639 // unqualified name? 640 641 if (importName != null) { 642 643 // Yes, so we use qualifiedName... 644 645 nameToUse = qualifiedName; 646 647 } 648 649 } else if (importName != null) { 650 651 // It is in some package for which we normally 652 // would import, but we have a previous import 653 // under this unqualified name. We must use 654 // the qualified name... 655 656 nameToUse = qualifiedName; 657 658 /* 659 // Is the currentPackage the default package? 660 661 if (currentPackage == null) { 662 663 // Yes, so undo the import so that all 664 // uses for this name will be qualified... 665 666 String old = (String)imports.remove(unqualifiedName); 667 classesInUse.put(old,old); 668 importCount--; 669 670 // Note that this name is in use but should 671 // not be imported... 672 673 imports.put(nameToUse,NO_IMPORT); 674 } 675 */ 676 } else if (qualifiedName.equals("org.omg.CORBA.Object")) { 677 678 // Always qualify this quy to avoid confusion... 679 680 nameToUse = qualifiedName; 681 682 } else { 683 684 // Default to using unqualified name, and add 685 // this guy to the imports... 686 687 // Check for nested class in which case we use 688 // the fully qualified name instead of imports 689 if (unqualifiedName.indexOf('.') != -1) { 690 nameToUse = qualifiedName; 691 } else { 692 nameToUse = unqualifiedName; 693 imports.put(unqualifiedName,qualifiedName); 694 importCount++; 695 } 696 } 697 698 // Now add the name... 699 700 classesInUse.put(qualifiedName,nameToUse); 701 } 702 } 703 704 String getName(Type type) { 705 if (type.isPrimitive()) { 706 return type.getName() + type.getArrayBrackets(); 707 } 708 Identifier id = type.getIdentifier(); 709 String name = IDLNames.replace(id.toString(),". ","."); 710 return getName(name) + type.getArrayBrackets(); 711 } 712 713 // Added for Bug 4818753 714 String getExceptionName(Type type) { 715 Identifier id = type.getIdentifier(); 716 return IDLNames.replace(id.toString(),". ","."); 717 } 718 719 String getName(String qualifiedName) { 720 return (String)classesInUse.get(qualifiedName); 721 } 722 723 String getName(Identifier id) { 724 return getName(id.toString()); 725 } 726 727 String getStubName(Type type) { 728 String stubName = getStubNameFor(type,true); 729 return getName(stubName); 730 } 731 732 void setStandardClassesInUse(CompoundType type, 733 boolean stub) throws IOException { 734 735 // Reset our state... 736 737 currentPackage = type.getPackageName(); 738 imports.clear(); 739 classesInUse.clear(); 740 namesInUse.clear(); 741 importCount = 0; 742 castArray = false; 743 744 // Add the top-level type... 745 746 addClassInUse(type); 747 748 // Set current class name... 749 750 if (stub) { 751 currentClass = Utility.stubNameForCompiler(type.getName()); 752 } else { 753 currentClass = Utility.tieNameForCompiler(type.getName()); 754 } 755 756 // Add current class... 757 758 if (currentPackage == null) { 759 addClassInUse(currentClass,currentClass,currentPackage); 760 } else { 761 addClassInUse(currentClass,(currentPackage+"."+currentClass),currentPackage); 762 } 763 764 // Add standard classes... 765 766 addClassInUse("javax.rmi.CORBA.Util"); 767 addClassInUse(idRemote.toString()); 768 addClassInUse(idRemoteException.toString()); 769 addClassInUse(idOutputStream.toString()); 770 addClassInUse(idInputStream.toString()); 771 addClassInUse(idSystemException.toString()); 772 addClassInUse(idJavaIoSerializable.toString()); 773 addClassInUse(idCorbaORB.toString()); 774 addClassInUse(idReplyHandler.toString()); 775 776 // Add stub/tie specific imports... 777 778 if (stub) { 779 addClassInUse(stubBaseClass); 780 addClassInUse("java.rmi.UnexpectedException"); 781 addClassInUse(idRemarshalException.toString()); 782 addClassInUse(idApplicationException.toString()); 783 if (localStubs) { 784 addClassInUse("org.omg.CORBA.portable.ServantObject"); 785 } 786 } else { 787 addClassInUse(type); 788 addClassInUse(tieBaseClass); 789 addClassInUse(idTieInterface.toString()); 790 addClassInUse(idBadMethodException.toString()); 791 addClassInUse(idPortableUnknownException.toString()); 792 addClassInUse(idJavaLangThrowable.toString()); 793 } 794 } 795 796 void addClassesInUse(CompoundType type, RemoteType[] interfaces) { 797 798 // Walk all methods and add types in use... 799 800 CompoundType.Method[] methods = type.getMethods(); 801 for (int i = 0; i < methods.length; i++) { 802 addClassInUse(methods[i].getReturnType()); 803 addStubInUse(methods[i].getReturnType()); 804 addClassInUse(methods[i].getArguments()); 805 addStubInUse(methods[i].getArguments()); 806 addClassInUse(methods[i].getExceptions()); 807 // bug 4473859: Also include narrower subtypes for use 808 addClassInUse(methods[i].getImplExceptions()); 809 } 810 811 // If this is a stub, add all interfaces... 812 813 if (interfaces != null) { 814 addClassInUse(interfaces); 815 } 816 } 817 818 void writePackageAndImports(IndentingWriter p) throws IOException { 819 820 // Write package declaration... 821 822 if (currentPackage != null) { 823 p.pln("package " + 824 Util.correctPackageName( 825 currentPackage, false, standardPackage) 826 + ";"); 827 p.pln(); 828 } 829 830 // Get imports into an array and sort them... 831 832 String[] names = new String[importCount]; 833 int index = 0; 834 for (Enumeration e = imports.elements() ; e.hasMoreElements() ;) { 835 String it = (String) e.nextElement(); 836 if (it != NO_IMPORT) { 837 names[index++] = it; 838 } 839 } 840 841 Arrays.sort(names,new StringComparator()); 842 843 // Now dump them out... 844 845 for (int i = 0; i < importCount; i++) { 846 if( 847 Util.isOffendingPackage(names[i]) 848 && names[i].endsWith("_Stub") 849 && String.valueOf(names[i].charAt(names[i].lastIndexOf(".")+1)).equals("_") 850 ){ 851 p.pln("import " + PackagePrefixChecker.packagePrefix()+names[i]+";"); 852 } else{ 853 p.pln("import " + names[i] + ";"); 854 } 855 } 856 p.pln(); 857 858 // Include offending packages . . . 859 if ( currentPackage!=null && Util.isOffendingPackage(currentPackage) ){ 860 p.pln("import " + currentPackage +".* ;"); 861 } 862 p.pln(); 863 864 } 865 866 boolean implementsRemote(CompoundType theType) { 867 boolean result = theType.isType(TYPE_REMOTE) && !theType.isType(TYPE_ABSTRACT); 868 869 // If theType is not remote, look at all the interfaces 870 // until we find one that is... 871 872 if (!result) { 873 InterfaceType[] interfaces = theType.getInterfaces(); 874 for (int i = 0; i < interfaces.length; i++) { 875 result = implementsRemote(interfaces[i]); 876 if (result) { 877 break; 878 } 879 } 880 } 881 882 return result; 883 } 884 885 void writeStubMethod ( IndentingWriter p, 886 CompoundType.Method method, 887 CompoundType theType) throws IOException { 888 889 // Wtite the method declaration and opening brace... 890 String methodName = method.getName(); 891 String methodIDLName = method.getIDLName(); 892 893 Type paramTypes[] = method.getArguments(); 894 String paramNames[] = method.getArgumentNames(); 895 Type returnType = method.getReturnType(); 896 ValueType[] exceptions = getStubExceptions(method,false); 897 898 addNamesInUse(method); 899 addNameInUse("_type_ids"); 900 901 String objName = testUtil(getName(returnType), returnType); 902 p.p("public " + objName + " " + methodName + "("); 903 for(int i = 0; i < paramTypes.length; i++) { 904 if (i > 0) 905 p.p(", "); 906 p.p(getName(paramTypes[i]) + " " + paramNames[i]); 907 } 908 909 p.p(")"); 910 if (exceptions.length > 0) { 911 p.p(" throws "); 912 for(int i = 0; i < exceptions.length; i++) { 913 if (i > 0) { 914 p.p(", "); 915 } 916 // Added for Bug 4818753 917 p.p(getExceptionName(exceptions[i])); 918 } 919 } 920 921 p.plnI(" {"); 922 923 // Now create the method body... 924 925 if (localStubs) { 926 writeLocalStubMethodBody(p,method,theType); 927 } else { 928 writeNonLocalStubMethodBody(p,method,theType); 929 } 930 931 // Close out the method... 932 933 p.pOln("}"); 934 } 935 936 937 void writeLocalStubMethodBody (IndentingWriter p, 938 CompoundType.Method method, 939 CompoundType theType) throws IOException { 940 941 String objName; 942 String paramNames[] = method.getArgumentNames(); 943 Type returnType = method.getReturnType(); 944 ValueType[] exceptions = getStubExceptions(method,false); 945 String methodName = method.getName(); 946 String methodIDLName = method.getIDLName(); 947 948 p.plnI("if (!Util.isLocal(this)) {"); 949 writeNonLocalStubMethodBody(p,method,theType); 950 p.pOlnI("} else {"); 951 String so = getVariableName("so"); 952 953 p.pln("ServantObject "+so+" = _servant_preinvoke(\""+methodIDLName+"\","+getName(theType)+".class);"); 954 p.plnI("if ("+so+" == null) {"); 955 if (!returnType.isType(TYPE_VOID)) { 956 p.p("return "); 957 } 958 p.p(methodName+"("); 959 for (int i = 0; i < paramNames.length; i++) { 960 if (i > 0) 961 p.p(", "); 962 p.p(paramNames[i]); 963 } 964 p.pln(");"); 965 if (returnType.isType(TYPE_VOID)) { 966 p.pln( "return ;" ) ; 967 } 968 969 p.pOln("}"); 970 p.plnI("try {"); 971 972 // Generate code to copy required arguments, and 973 // get back the names by which all arguments are known... 974 975 String[] argNames = writeCopyArguments(method,p); 976 977 // Now write the method... 978 979 boolean copyReturn = mustCopy(returnType); 980 String resultName = null; 981 if (!returnType.isType(TYPE_VOID)) { 982 if (copyReturn) { 983 resultName = getVariableName("result"); 984 objName = testUtil(getName(returnType), returnType); 985 p.p(objName+" "+resultName + " = "); 986 } else { 987 p.p("return "); 988 } 989 } 990 objName = testUtil(getName(theType), theType); 991 p.p("(("+objName+")"+so+".servant)."+methodName+"("); 992 993 for (int i = 0; i < argNames.length; i++) { 994 if (i > 0) 995 p.p(", "); 996 p.p(argNames[i]); 997 } 998 999 if (copyReturn) { 1000 p.pln(");"); 1001 objName = testUtil(getName(returnType), returnType); 1002 p.pln("return ("+objName+")Util.copyObject("+resultName+",_orb());"); 1003 } else { 1004 p.pln(");"); 1005 } 1006 1007 String e1 = getVariableName("ex"); 1008 String e2 = getVariableName("exCopy"); 1009 p.pOlnI("} catch (Throwable "+e1+") {"); 1010 1011 p.pln("Throwable "+e2+" = (Throwable)Util.copyObject("+e1+",_orb());"); 1012 for(int i = 0; i < exceptions.length; i++) { 1013 if (exceptions[i].getIdentifier() != idRemoteException && 1014 exceptions[i].isType(TYPE_VALUE)) { 1015 // Added for Bug 4818753 1016 p.plnI("if ("+e2+" instanceof "+getExceptionName(exceptions[i])+") {"); 1017 p.pln("throw ("+getExceptionName(exceptions[i])+")"+e2+";"); 1018 p.pOln("}"); 1019 } 1020 } 1021 1022 p.pln("throw Util.wrapException("+e2+");"); 1023 p.pOlnI("} finally {"); 1024 p.pln("_servant_postinvoke("+so+");"); 1025 p.pOln("}"); 1026 p.pOln("}"); 1027 } 1028 1029 1030 void writeNonLocalStubMethodBody ( IndentingWriter p, 1031 CompoundType.Method method, 1032 CompoundType theType) throws IOException { 1033 1034 String methodName = method.getName(); 1035 String methodIDLName = method.getIDLName(); 1036 1037 Type paramTypes[] = method.getArguments(); 1038 String paramNames[] = method.getArgumentNames(); 1039 Type returnType = method.getReturnType(); 1040 ValueType[] exceptions = getStubExceptions(method,true); 1041 1042 String in = getVariableName("in"); 1043 String out = getVariableName("out"); 1044 String ex = getVariableName("ex"); 1045 1046 // Decide if we need to use the new streams for 1047 // any of the read calls... 1048 1049 boolean needNewReadStreamClass = false; 1050 for (int i = 0; i < exceptions.length; i++) { 1051 if (exceptions[i].getIdentifier() != idRemoteException && 1052 exceptions[i].isType(TYPE_VALUE) && 1053 needNewReadStreamClass(exceptions[i])) { 1054 needNewReadStreamClass = true; 1055 break; 1056 } 1057 } 1058 if (!needNewReadStreamClass) { 1059 for (int i = 0; i < paramTypes.length; i++) { 1060 if (needNewReadStreamClass(paramTypes[i])) { 1061 needNewReadStreamClass = true; 1062 break; 1063 } 1064 } 1065 } 1066 if (!needNewReadStreamClass) { 1067 needNewReadStreamClass = needNewReadStreamClass(returnType); 1068 } 1069 1070 // Decide if we need to use the new streams for 1071 // any of the write calls... 1072 1073 boolean needNewWriteStreamClass = false; 1074 for (int i = 0; i < paramTypes.length; i++) { 1075 if (needNewWriteStreamClass(paramTypes[i])) { 1076 needNewWriteStreamClass = true; 1077 break; 1078 } 1079 } 1080 1081 // Now write the method, inserting casts where needed... 1082 1083 p.plnI("try {"); 1084 if (needNewReadStreamClass) { 1085 p.pln(idExtInputStream + " "+in+" = null;"); 1086 } else { 1087 p.pln(idInputStream + " "+in+" = null;"); 1088 } 1089 p.plnI("try {"); 1090 1091 String argStream = "null"; 1092 1093 if (needNewWriteStreamClass) { 1094 p.plnI(idExtOutputStream + " "+out+" = "); 1095 p.pln("(" + idExtOutputStream + ")"); 1096 p.pln("_request(\"" + methodIDLName + "\", true);"); 1097 p.pO(); 1098 } else { 1099 p.pln("OutputStream "+out+" = _request(\"" + methodIDLName + "\", true);"); 1100 } 1101 1102 if (paramTypes.length > 0) { 1103 writeMarshalArguments(p, out, paramTypes, paramNames); 1104 p.pln(); 1105 } 1106 argStream = out; 1107 1108 if (returnType.isType(TYPE_VOID)) { 1109 p.pln("_invoke(" + argStream + ");" ); 1110 } else { 1111 if (needNewReadStreamClass) { 1112 p.plnI(in+" = (" + idExtInputStream + ")_invoke(" + argStream + ");"); 1113 p.pO(); 1114 } else { 1115 p.pln(in+" = _invoke(" + argStream + ");"); 1116 } 1117 p.p("return "); 1118 writeUnmarshalArgument(p, in, returnType, null); 1119 p.pln(); 1120 } 1121 1122 // Handle ApplicationException... 1123 1124 p.pOlnI("} catch ("+getName(idApplicationException)+" "+ex+") {"); 1125 if (needNewReadStreamClass) { 1126 p.pln(in + " = (" + idExtInputStream + ") "+ex+".getInputStream();"); 1127 } else { 1128 p.pln(in + " = "+ex+".getInputStream();"); 1129 } 1130 1131 boolean idRead = false; 1132 boolean idAllocated = false; 1133 for(int i = 0; i < exceptions.length; i++) { 1134 if (exceptions[i].getIdentifier() != idRemoteException) { 1135 1136 // Is this our special-case IDLEntity exception? 1137 1138 if (exceptions[i].isIDLEntityException() && !exceptions[i].isCORBAUserException()) { 1139 1140 // Yes. 1141 1142 if (!idAllocated && !idRead) { 1143 p.pln("String $_id = "+ex+".getId();"); 1144 idAllocated = true; 1145 } 1146 1147 String helperName = IDLNames.replace(exceptions[i].getQualifiedIDLName(false),"::","."); 1148 helperName += "Helper"; 1149 p.plnI("if ($_id.equals("+helperName+".id())) {"); 1150 p.pln("throw "+helperName+".read("+in+");"); 1151 1152 } else { 1153 1154 // No. 1155 1156 if (!idAllocated && !idRead) { 1157 p.pln("String $_id = "+in+".read_string();"); 1158 idAllocated = true; 1159 idRead = true; 1160 } else if (idAllocated && !idRead) { 1161 p.pln("$_id = "+in+".read_string();"); 1162 idRead = true; 1163 } 1164 p.plnI("if ($_id.equals(\""+getExceptionRepositoryID(exceptions[i])+"\")) {"); 1165 // Added for Bug 4818753 1166 p.pln("throw ("+getExceptionName(exceptions[i])+") "+in+".read_value(" + getExceptionName(exceptions[i]) + ".class);"); 1167 } 1168 p.pOln("}"); 1169 } 1170 } 1171 if (!idAllocated && !idRead) { 1172 p.pln("String $_id = "+in+".read_string();"); 1173 idAllocated = true; 1174 idRead = true; 1175 } else if (idAllocated && !idRead) { 1176 p.pln("$_id = "+in+".read_string();"); 1177 idRead = true; 1178 } 1179 p.pln("throw new UnexpectedException($_id);"); 1180 1181 // Handle RemarshalException... 1182 1183 p.pOlnI("} catch ("+getName(idRemarshalException)+" "+ex+") {"); 1184 if (!returnType.isType(TYPE_VOID)) { 1185 p.p("return "); 1186 } 1187 p.p(methodName + "("); 1188 for(int i = 0; i < paramTypes.length; i++) { 1189 if (i > 0) { 1190 p.p(","); 1191 } 1192 p.p(paramNames[i]); 1193 } 1194 p.pln(");"); 1195 1196 // Ensure that we release the reply... 1197 1198 p.pOlnI("} finally {"); 1199 p.pln("_releaseReply("+in+");"); 1200 1201 p.pOln("}"); 1202 1203 // Handle SystemException... 1204 1205 p.pOlnI("} catch (SystemException "+ex+") {"); 1206 p.pln("throw Util.mapSystemException("+ex+");"); 1207 p.pOln("}"); 1208 1209 // returnResult(p,returnType); 1210 } 1211 1212 void allocateResult (IndentingWriter p, 1213 Type returnType) throws IOException { 1214 if (!returnType.isType(TYPE_VOID)) { 1215 String objName = testUtil(getName(returnType), returnType); 1216 p.p(objName + " result = "); 1217 } 1218 } 1219 1220 int getTypeCode(Type type) { 1221 1222 int typeCode = type.getTypeCode(); 1223 1224 // Handle late-breaking special case for 1225 // abstract IDL entities... 1226 1227 if ((type instanceof CompoundType) && 1228 ((CompoundType)type).isAbstractBase()) { 1229 typeCode = TYPE_ABSTRACT; 1230 } 1231 1232 return typeCode; 1233 } 1234 1235 1236 /** 1237 * Write a snippet of Java code to marshal a value named "name" of 1238 * type "type" to the java.io.ObjectOutput stream named "stream". 1239 */ 1240 void writeMarshalArgument(IndentingWriter p, 1241 String streamName, 1242 Type type, String name) throws IOException { 1243 1244 int typeCode = getTypeCode(type); 1245 1246 switch (typeCode) { 1247 case TYPE_BOOLEAN: 1248 p.p(streamName + ".write_boolean(" + name + ");"); 1249 break; 1250 case TYPE_BYTE: 1251 p.p(streamName + ".write_octet(" + name + ");"); 1252 break; 1253 case TYPE_CHAR: 1254 p.p(streamName + ".write_wchar(" + name + ");"); 1255 break; 1256 case TYPE_SHORT: 1257 p.p(streamName + ".write_short(" + name + ");"); 1258 break; 1259 case TYPE_INT: 1260 p.p(streamName + ".write_long(" + name + ");"); 1261 break; 1262 case TYPE_LONG: 1263 p.p(streamName + ".write_longlong(" + name + ");"); 1264 break; 1265 case TYPE_FLOAT: 1266 p.p(streamName + ".write_float(" + name + ");"); 1267 break; 1268 case TYPE_DOUBLE: 1269 p.p(streamName + ".write_double(" + name + ");"); 1270 break; 1271 case TYPE_STRING: 1272 p.p(streamName + ".write_value(" + name + "," + getName(type) + ".class);"); 1273 break; 1274 case TYPE_ANY: 1275 p.p("Util.writeAny("+ streamName + "," + name + ");"); 1276 break; 1277 case TYPE_CORBA_OBJECT: 1278 p.p(streamName + ".write_Object(" + name + ");"); 1279 break; 1280 case TYPE_REMOTE: 1281 p.p("Util.writeRemoteObject("+ streamName + "," + name + ");"); 1282 break; 1283 case TYPE_ABSTRACT: 1284 p.p("Util.writeAbstractObject("+ streamName + "," + name + ");"); 1285 break; 1286 case TYPE_NC_INTERFACE: 1287 p.p(streamName + ".write_value((Serializable)" + name + "," + getName(type) + ".class);"); 1288 break; 1289 case TYPE_VALUE: 1290 p.p(streamName + ".write_value(" + name + "," + getName(type) + ".class);"); 1291 break; 1292 case TYPE_IMPLEMENTATION: 1293 p.p(streamName + ".write_value((Serializable)" + name + "," + getName(type) + ".class);"); 1294 break; 1295 case TYPE_NC_CLASS: 1296 p.p(streamName + ".write_value((Serializable)" + name + "," + getName(type) + ".class);"); 1297 break; 1298 case TYPE_ARRAY: 1299 castArray = true; 1300 p.p(streamName + ".write_value(cast_array(" + name + ")," + getName(type) + ".class);"); 1301 break; 1302 case TYPE_JAVA_RMI_REMOTE: 1303 p.p("Util.writeRemoteObject("+ streamName + "," + name + ");"); 1304 break; 1305 default: 1306 throw new Error("unexpected type code: " + typeCode); 1307 } 1308 } 1309 1310 /** 1311 * Write a snippet of Java code to unmarshal a value of type "type" 1312 * from the java.io.ObjectInput stream named "stream" into a variable 1313 * named "name" (if "name" is null, the value in unmarshalled and 1314 * discarded). 1315 */ 1316 void writeUnmarshalArgument(IndentingWriter p, 1317 String streamName, 1318 Type type, 1319 String name) throws IOException { 1320 1321 int typeCode = getTypeCode(type); 1322 1323 if (name != null) { 1324 p.p(name + " = "); 1325 } 1326 1327 switch (typeCode) { 1328 case TYPE_BOOLEAN: 1329 p.p(streamName + ".read_boolean();"); 1330 break; 1331 case TYPE_BYTE: 1332 p.p(streamName + ".read_octet();"); 1333 break; 1334 case TYPE_CHAR: 1335 p.p(streamName + ".read_wchar();"); 1336 break; 1337 case TYPE_SHORT: 1338 p.p(streamName + ".read_short();"); 1339 break; 1340 case TYPE_INT: 1341 p.p(streamName + ".read_long();"); 1342 break; 1343 case TYPE_LONG: 1344 p.p(streamName + ".read_longlong();"); 1345 break; 1346 case TYPE_FLOAT: 1347 p.p(streamName + ".read_float();"); 1348 break; 1349 case TYPE_DOUBLE: 1350 p.p(streamName + ".read_double();"); 1351 break; 1352 case TYPE_STRING: 1353 p.p("(String) " + streamName + ".read_value(" + getName(type) + ".class);"); 1354 break; 1355 case TYPE_ANY: 1356 if (type.getIdentifier() != idJavaLangObject) { 1357 p.p("(" + getName(type) + ") "); 1358 } 1359 p.p("Util.readAny(" + streamName + ");"); 1360 break; 1361 case TYPE_CORBA_OBJECT: 1362 if (type.getIdentifier() == idCorbaObject) { 1363 p.p("(" + getName(type) + ") " + streamName + ".read_Object();"); 1364 } else { 1365 p.p("(" + getName(type) + ") " + streamName + ".read_Object(" + getStubName(type) + ".class);"); 1366 } 1367 break; 1368 case TYPE_REMOTE: 1369 String objName = testUtil(getName(type), type); 1370 p.p("(" + objName + ") " + 1371 "PortableRemoteObject.narrow(" + streamName + ".read_Object(), " + objName + ".class);"); 1372 break; 1373 case TYPE_ABSTRACT: 1374 p.p("(" + getName(type) + ") " + streamName + ".read_abstract_interface();"); 1375 break; 1376 case TYPE_NC_INTERFACE: 1377 p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);"); 1378 break; 1379 case TYPE_VALUE: 1380 p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);"); 1381 break; 1382 case TYPE_IMPLEMENTATION: 1383 p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);"); 1384 break; 1385 case TYPE_NC_CLASS: 1386 p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);"); 1387 break; 1388 case TYPE_ARRAY: 1389 p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);"); 1390 break; 1391 case TYPE_JAVA_RMI_REMOTE: 1392 p.p("(" + getName(type) + ") " + 1393 "PortableRemoteObject.narrow(" + streamName + ".read_Object(), " + getName(type) + ".class);"); 1394 // p.p("(" + getName(type) + ") " + streamName + ".read_Object(" + getStubName(type) + ".class);"); 1395 break; 1396 default: 1397 throw new Error("unexpected type code: " + typeCode); 1398 } 1399 } 1400 1401 /** 1402 * Get a list of all the RepositoryIDs for interfaces 1403 * implemented directly or indirectly by theType. In the 1404 * case of an ImplementationType which implements 2 or 1405 * more remote interfaces, this list will begin with the 1406 * Identifier for the implementation (see section 5.9 in 1407 * the Java -> IDL mapping). Ensures that the most derived 1408 * type is first in the list because the IOR is generated 1409 * using that entry in the _ids array. 1410 */ 1411 String[] getAllRemoteRepIDs (CompoundType theType) { 1412 1413 String[] result; 1414 1415 // Collect up all the (inherited) remote interfaces 1416 // (ignores all the 'special' interfaces: Remote, 1417 // Serializable, Externalizable)... 1418 1419 Type[] types = collectAllRemoteInterfaces(theType); 1420 1421 int length = types.length; 1422 boolean haveImpl = theType instanceof ImplementationType; 1423 InterfaceType[] interfaces = theType.getInterfaces(); 1424 int remoteCount = countRemote(interfaces,false); 1425 int offset = 0; 1426 1427 // Do we have an implementation type that implements 1428 // more than one remote interface? 1429 1430 if (haveImpl && remoteCount > 1) { 1431 1432 // Yes, so we need to insert it at the beginning... 1433 1434 result = new String[length + 1]; 1435 result[0] = getRepositoryID(theType); 1436 offset = 1; 1437 1438 } else { 1439 1440 // No. 1441 1442 result = new String[length]; 1443 1444 // Here we need to ensure that the most derived 1445 // interface ends up being first in the list. If 1446 // there is only one, we're done. 1447 1448 if (length > 1) { 1449 1450 // First, decide what the most derived type is... 1451 1452 String mostDerived = null; 1453 1454 if (haveImpl) { 1455 1456 // If we get here, we know that there is only one 1457 // direct remote interface, so just find it... 1458 1459 for (int i = 0; i < interfaces.length; i++) { 1460 if (interfaces[i].isType(TYPE_REMOTE)) { 1461 mostDerived = interfaces[i].getRepositoryID(); 1462 break; 1463 } 1464 } 1465 } else { 1466 1467 // If we get here we know that theType is a RemoteType 1468 // so just use its id... 1469 1470 mostDerived = theType.getRepositoryID(); 1471 } 1472 1473 // Now search types list and make sure mostDerived is 1474 // at index zero... 1475 1476 for (int i = 0; i < length; i++) { 1477 if (types[i].getRepositoryID() == mostDerived) { 1478 1479 // Found it. Swap it if we need to... 1480 1481 if (i > 0) { 1482 Type temp = types[0]; 1483 types[0] = types[i]; 1484 types[i] = temp; 1485 } 1486 1487 break; 1488 } 1489 } 1490 } 1491 } 1492 1493 // Now copy contents of the types array... 1494 1495 for (int i = 0; i < types.length; i++) { 1496 result[offset++] = getRepositoryID(types[i]); 1497 } 1498 1499 // If we're supposed to, reverse the array. This 1500 // is only done when the -testReverseIDs flag is 1501 // passed, and that should ONLY be done for test 1502 // cases. This is an undocumented feature. 1503 1504 if (reverseIDs) { 1505 int start = 0; 1506 int end = result.length -1; 1507 while (start < end) { 1508 String temp = result[start]; 1509 result[start++] = result[end]; 1510 result[end--] = temp; 1511 } 1512 } 1513 1514 return result; 1515 } 1516 1517 /** 1518 * Collect all the inherited remote interfaces. 1519 */ 1520 Type[] collectAllRemoteInterfaces (CompoundType theType) { 1521 Vector list = new Vector(); 1522 1523 // Collect up all the Remote interfaces, and get an instance 1524 // for java.rmi.Remote... 1525 1526 addRemoteInterfaces(list,theType); 1527 1528 // Create and return our results... 1529 1530 Type[] result = new Type[list.size()]; 1531 list.copyInto(result); 1532 1533 return result; 1534 } 1535 1536 /** 1537 * Add all the inherited remote interfaces to list. 1538 */ 1539 void addRemoteInterfaces(Vector list, CompoundType theType) { 1540 1541 if (theType != null) { 1542 if (theType.isInterface() && !list.contains(theType)) { 1543 list.addElement(theType); 1544 } 1545 1546 InterfaceType[] interfaces = theType.getInterfaces(); 1547 for (int i = 0; i < interfaces.length; i++) { 1548 1549 if (interfaces[i].isType(TYPE_REMOTE)) { 1550 addRemoteInterfaces(list,interfaces[i]); 1551 } 1552 } 1553 1554 addRemoteInterfaces(list,theType.getSuperclass()); 1555 } 1556 } 1557 1558 /** 1559 * Get a list of all the remote interfaces which this stub 1560 * should declare. 1561 */ 1562 RemoteType[] getDirectRemoteInterfaces (CompoundType theType) { 1563 1564 RemoteType[] result; 1565 InterfaceType[] interfaces = theType.getInterfaces(); 1566 1567 // First, get a list of all the interfaces... 1568 1569 InterfaceType[] list; 1570 1571 // Because we can be passed either an ImplementationType 1572 // (which has interfaces) or a RemoteType (which is an 1573 // interface and may have interfaces) we must handle each 1574 // separately... 1575 1576 // Do we have an implementation type? 1577 1578 if (theType instanceof ImplementationType) { 1579 1580 // Yes, so list is exactly what this type 1581 // implements and is correct already. 1582 1583 list = interfaces; 1584 1585 } else { 1586 1587 // No, so list is just theType... 1588 1589 list = new InterfaceType[1]; 1590 list[0] = (InterfaceType) theType; 1591 } 1592 1593 // Ok, now count up the remote interfaces, allocate 1594 // our result and fill it in... 1595 1596 int remoteCount = countRemote(list,false); 1597 1598 if (remoteCount == 0) { 1599 throw new CompilerError("iiop.StubGenerator: No remote interfaces!"); 1600 } 1601 1602 result = new RemoteType[remoteCount]; 1603 int offset = 0; 1604 for (int i = 0; i < list.length; i++) { 1605 if (list[i].isType(TYPE_REMOTE)) { 1606 result[offset++] = (RemoteType)list[i]; 1607 } 1608 } 1609 1610 return result; 1611 } 1612 1613 int countRemote (Type[] list, boolean includeAbstract) { 1614 int remoteCount = 0; 1615 for (int i = 0; i < list.length; i++) { 1616 if (list[i].isType(TYPE_REMOTE) && 1617 (includeAbstract || !list[i].isType(TYPE_ABSTRACT))) { 1618 remoteCount++; 1619 } 1620 } 1621 1622 return remoteCount; 1623 } 1624 1625 void writeCastArray(IndentingWriter p) throws IOException { 1626 if (castArray) { 1627 p.pln(); 1628 p.pln("// This method is required as a work-around for"); 1629 p.pln("// a bug in the JDK 1.1.6 verifier."); 1630 p.pln(); 1631 p.plnI("private "+getName(idJavaIoSerializable)+" cast_array(Object obj) {"); 1632 p.pln("return ("+getName(idJavaIoSerializable)+")obj;"); 1633 p.pOln("}"); 1634 } 1635 } 1636 void writeIds(IndentingWriter p, CompoundType theType, boolean isTie 1637 ) throws IOException { 1638 p.plnI("private static final String[] _type_ids = {"); 1639 1640 String[] ids = getAllRemoteRepIDs(theType); 1641 1642 if (ids.length >0 ) { 1643 for(int i = 0; i < ids.length; i++) { 1644 if (i > 0) 1645 p.pln(", "); 1646 p.p("\"" + ids[i] + "\""); 1647 } 1648 } else { 1649 // Must be an implementation which only implements Remote... 1650 p.pln("\"\""); 1651 } 1652 String qname = theType.getQualifiedName() ; 1653 boolean isTransactional = isTie && transactionalObjects.containsKey( qname ) ; 1654 // Add TransactionalObject if needed. 1655 if (isTransactional) { 1656 // Have already written an id. 1657 p.pln( ", " ) ; 1658 p.pln( "\"IDL:omg.org/CosTransactions/TransactionalObject:1.0\"" ) ; 1659 } else if (ids.length > 0) { 1660 p.pln(); 1661 } 1662 p.pOln("};"); 1663 } 1664 1665 1666 /** 1667 * Write the Tie for the remote class to a stream. 1668 */ 1669 protected void writeTie(OutputType outputType, 1670 IndentingWriter p) throws IOException 1671 { 1672 CompoundType theType = (CompoundType) outputType.getType(); 1673 RemoteType[] remoteInterfaces = null; 1674 1675 // Write comment... 1676 p.pln("// Tie class generated by rmic, do not edit."); 1677 p.pln("// Contents subject to change without notice."); 1678 p.pln(); 1679 1680 // Set our standard classes... 1681 setStandardClassesInUse(theType,false); 1682 1683 // Add classes for this type... 1684 addClassesInUse(theType,remoteInterfaces); 1685 1686 // Write package and import statements... 1687 writePackageAndImports(p); 1688 1689 // Declare the tie class. 1690 p.p("public class " + currentClass + " extends " + 1691 getName(tieBaseClass) + " implements Tie"); 1692 1693 // Add java.rmi.Remote if this type does not implement it. 1694 // This allows stubs for Abstract interfaces to be treated 1695 // uniformly... 1696 if (!implementsRemote(theType)) { 1697 p.pln(","); 1698 p.p(getName("java.rmi.Remote")); 1699 } 1700 1701 p.plnI(" {"); 1702 1703 // Write data members... 1704 p.pln(); 1705 p.pln("volatile private " + getName(theType) + " target = null;"); 1706 p.pln(); 1707 1708 // Write the ids... 1709 writeIds( p, theType, true ) ; 1710 1711 // Write setTarget method... 1712 p.pln(); 1713 p.plnI("public void setTarget(Remote target) {"); 1714 p.pln("this.target = (" + getName(theType) + ") target;"); 1715 p.pOln("}"); 1716 1717 // Write getTarget method... 1718 p.pln(); 1719 p.plnI("public Remote getTarget() {"); 1720 p.pln("return target;"); 1721 p.pOln("}"); 1722 1723 // Write thisObject method... 1724 p.pln(); 1725 write_tie_thisObject_method(p,idCorbaObject); 1726 1727 // Write deactivate method... 1728 p.pln(); 1729 write_tie_deactivate_method(p); 1730 1731 // Write get orb method... 1732 p.pln(); 1733 p.plnI("public ORB orb() {"); 1734 p.pln("return _orb();"); 1735 p.pOln("}"); 1736 1737 // Write set orb method... 1738 p.pln(); 1739 write_tie_orb_method(p); 1740 1741 // Write the _ids() method... 1742 p.pln(); 1743 write_tie__ids_method(p); 1744 1745 // Get all the methods... 1746 CompoundType.Method[] remoteMethods = theType.getMethods(); 1747 1748 // Register all the argument names used, plus our 1749 // data member names... 1750 1751 addNamesInUse(remoteMethods); 1752 addNameInUse("target"); 1753 addNameInUse("_type_ids"); 1754 1755 // Write the _invoke method... 1756 p.pln(); 1757 1758 String in = getVariableName("in"); 1759 String _in = getVariableName("_in"); 1760 String ex = getVariableName("ex"); 1761 String method = getVariableName("method"); 1762 String reply = getVariableName("reply"); 1763 1764 p.plnI("public OutputStream _invoke(String "+method+", InputStream "+_in+", " + 1765 "ResponseHandler "+reply+") throws SystemException {"); 1766 1767 if (remoteMethods.length > 0) { 1768 p.plnI("try {"); 1769 p.pln(getName(theType) + " target = this.target;"); 1770 p.plnI("if (target == null) {"); 1771 p.pln("throw new java.io.IOException();"); 1772 p.pOln("}"); 1773 p.plnI(idExtInputStream + " "+in+" = "); 1774 p.pln("(" + idExtInputStream + ") "+_in+";"); 1775 p.pO(); 1776 1777 // See if we should use a hash table style 1778 // comparison... 1779 1780 StaticStringsHash hash = getStringsHash(remoteMethods); 1781 1782 if (hash != null) { 1783 p.plnI("switch ("+method+"."+hash.method+") {"); 1784 for (int i = 0; i < hash.buckets.length; i++) { 1785 p.plnI("case "+hash.keys[i]+": "); 1786 for (int j = 0; j < hash.buckets[i].length; j++) { 1787 CompoundType.Method current = remoteMethods[hash.buckets[i][j]]; 1788 if (j > 0) { 1789 p.pO("} else "); 1790 } 1791 p.plnI("if ("+method+".equals(\""+ current.getIDLName() +"\")) {"); 1792 writeTieMethod(p, theType,current); 1793 } 1794 p.pOln("}"); 1795 p.pO(); 1796 } 1797 } else { 1798 for(int i = 0; i < remoteMethods.length; i++) { 1799 CompoundType.Method current = remoteMethods[i]; 1800 if (i > 0) { 1801 p.pO("} else "); 1802 } 1803 1804 p.plnI("if ("+method+".equals(\""+ current.getIDLName() +"\")) {"); 1805 writeTieMethod(p, theType, current); 1806 } 1807 } 1808 1809 if (hash != null) { 1810 p.pI(); 1811 // p.plnI("default:"); 1812 } else { 1813 // p.pOlnI("} else {"); 1814 } 1815 // p.pln("throw new "+getName(idBadMethodException)+"();"); 1816 1817 if (hash != null) { 1818 p.pO(); 1819 } 1820 p.pOln("}"); 1821 p.pln("throw new "+getName(idBadMethodException)+"();"); 1822 1823 p.pOlnI("} catch ("+getName(idSystemException)+" "+ex+") {"); 1824 p.pln("throw "+ex+";"); 1825 1826 p.pOlnI("} catch ("+getName(idJavaLangThrowable)+" "+ex+") {"); 1827 p.pln("throw new " + getName(idPortableUnknownException) + "("+ex+");"); 1828 p.pOln("}"); 1829 } else { 1830 // No methods... 1831 1832 p.pln("throw new " + getName(idBadMethodException) + "();"); 1833 } 1834 1835 p.pOln("}"); // end invoke 1836 1837 // Write the cast array hack... 1838 1839 writeCastArray(p); 1840 1841 // End tie class... 1842 p.pOln("}"); 1843 } 1844 public void catchWrongPolicy(IndentingWriter p) throws IOException { 1845 p.pln(""); 1846 } 1847 public void catchServantNotActive(IndentingWriter p) throws IOException { 1848 p.pln(""); 1849 } 1850 public void catchObjectNotActive(IndentingWriter p) throws IOException { 1851 p.pln(""); 1852 } 1853 1854 public void write_tie_thisObject_method(IndentingWriter p, 1855 Identifier idCorbaObject) 1856 throws IOException 1857 { 1858 if(POATie){ 1859 p.plnI("public " + idCorbaObject + " thisObject() {"); 1860 /* 1861 p.pln("org.omg.CORBA.Object objref = null;"); 1862 p.pln("try{"); 1863 p.pln("objref = _poa().servant_to_reference(this);"); 1864 p.pln("}catch (org.omg.PortableServer.POAPackage.WrongPolicy exception){"); 1865 catchWrongPolicy(p); 1866 p.pln("}catch (org.omg.PortableServer.POAPackage.ServantNotActive exception){"); 1867 catchServantNotActive(p); 1868 p.pln("}"); 1869 p.pln("return objref;"); 1870 */ 1871 p.pln("return _this_object();"); 1872 p.pOln("}"); 1873 } else { 1874 p.plnI("public " + idCorbaObject + " thisObject() {"); 1875 p.pln("return this;"); 1876 p.pOln("}"); 1877 } 1878 } 1879 1880 public void write_tie_deactivate_method(IndentingWriter p) 1881 throws IOException 1882 { 1883 if(POATie){ 1884 p.plnI("public void deactivate() {"); 1885 p.pln("try{"); 1886 p.pln("_poa().deactivate_object(_poa().servant_to_id(this));"); 1887 p.pln("}catch (org.omg.PortableServer.POAPackage.WrongPolicy exception){"); 1888 catchWrongPolicy(p); 1889 p.pln("}catch (org.omg.PortableServer.POAPackage.ObjectNotActive exception){"); 1890 catchObjectNotActive(p); 1891 p.pln("}catch (org.omg.PortableServer.POAPackage.ServantNotActive exception){"); 1892 catchServantNotActive(p); 1893 p.pln("}"); 1894 p.pOln("}"); 1895 } else { 1896 p.plnI("public void deactivate() {"); 1897 p.pln("_orb().disconnect(this);"); 1898 p.pln("_set_delegate(null);"); 1899 p.pln("target = null;"); 1900 p.pOln("}"); 1901 } 1902 } 1903 1904 public void write_tie_orb_method(IndentingWriter p) 1905 throws IOException 1906 { 1907 if(POATie){ 1908 p.plnI("public void orb(ORB orb) {"); 1909 /* 1910 p.pln("try{"); 1911 p.pln("orb.connect(_poa().servant_to_reference(this));"); 1912 p.pln("}catch (org.omg.PortableServer.POAPackage.WrongPolicy exception){"); 1913 catchWrongPolicy(p); 1914 p.pln("}catch (org.omg.PortableServer.POAPackage.ServantNotActive exception){"); 1915 catchServantNotActive(p); 1916 p.pln("}"); 1917 */ 1918 p.pln("try {"); 1919 p.pln(" ((org.omg.CORBA_2_3.ORB)orb).set_delegate(this);"); 1920 p.pln("}"); 1921 p.pln("catch(ClassCastException e) {"); 1922 p.pln(" throw new org.omg.CORBA.BAD_PARAM"); 1923 p.pln(" (\"POA Servant requires an instance of org.omg.CORBA_2_3.ORB\");"); 1924 p.pln("}"); 1925 p.pOln("}"); 1926 } else { 1927 p.plnI("public void orb(ORB orb) {"); 1928 p.pln("orb.connect(this);"); 1929 p.pOln("}"); 1930 } 1931 } 1932 1933 public void write_tie__ids_method(IndentingWriter p) 1934 throws IOException 1935 { 1936 if(POATie){ 1937 p.plnI("public String[] _all_interfaces(org.omg.PortableServer.POA poa, byte[] objectId){"); 1938 p.pln("return (String[]) _type_ids.clone();"); 1939 p.pOln("}"); 1940 } else { 1941 p.plnI("public String[] _ids() { "); 1942 p.pln("return (String[]) _type_ids.clone();"); 1943 p.pOln("}"); 1944 } 1945 } 1946 1947 1948 StaticStringsHash getStringsHash (CompoundType.Method[] methods) { 1949 if (useHash && methods.length > 1) { 1950 String[] methodNames = new String[methods.length]; 1951 for (int i = 0; i < methodNames.length; i++) { 1952 methodNames[i] = methods[i].getIDLName(); 1953 } 1954 return new StaticStringsHash(methodNames); 1955 } 1956 return null; 1957 } 1958 1959 static boolean needNewReadStreamClass(Type type) { 1960 if (type.isType(TYPE_ABSTRACT)) { 1961 return true; 1962 } 1963 // Handle late-breaking special case for 1964 // abstract IDL entities... 1965 if ((type instanceof CompoundType) && 1966 ((CompoundType)type).isAbstractBase()) { 1967 return true; 1968 } 1969 return needNewWriteStreamClass(type); 1970 } 1971 1972 static boolean needNewWriteStreamClass(Type type) { 1973 switch (type.getTypeCode()) { 1974 case TYPE_VOID: 1975 case TYPE_BOOLEAN: 1976 case TYPE_BYTE: 1977 case TYPE_CHAR: 1978 case TYPE_SHORT: 1979 case TYPE_INT: 1980 case TYPE_LONG: 1981 case TYPE_FLOAT: 1982 case TYPE_DOUBLE: return false; 1983 1984 case TYPE_STRING: return true; 1985 case TYPE_ANY: return false; 1986 case TYPE_CORBA_OBJECT: return false; 1987 case TYPE_REMOTE: return false; 1988 case TYPE_ABSTRACT: return false; 1989 case TYPE_NC_INTERFACE: return true; 1990 case TYPE_VALUE: return true; 1991 case TYPE_IMPLEMENTATION: return true; 1992 case TYPE_NC_CLASS: return true; 1993 case TYPE_ARRAY: return true; 1994 case TYPE_JAVA_RMI_REMOTE: return false; 1995 1996 default: throw new Error("unexpected type code: " + type.getTypeCode()); 1997 } 1998 } 1999 2000 /* 2001 * Decide which arguments need to be copied and write 2002 * the copy code. Returns an array of argument names to 2003 * use to refer to either the copy or the original. 2004 */ 2005 String[] writeCopyArguments(CompoundType.Method method, 2006 IndentingWriter p) throws IOException { 2007 2008 Type[] args = method.getArguments(); 2009 String[] origNames = method.getArgumentNames(); 2010 2011 // Copy the current parameter names to a result array... 2012 2013 String[] result = new String[origNames.length]; 2014 for (int i = 0; i < result.length; i++) { 2015 result[i] = origNames[i]; 2016 } 2017 2018 // Decide which arguments must be copied, if any. If 2019 // any of the arguments are types for which a 'real' copy 2020 // will be done, rather than just an autoConnect, set 2021 // realCopy = true. Note that abstract types may only 2022 // need autoConnect, but we cannot know that at compile 2023 // time... 2024 2025 boolean realCopy = false; 2026 boolean[] copyArg = new boolean[args.length]; 2027 int copyCount = 0; 2028 int firstCopiedArg = 0; // Only used in single copy case. It is only the first arg that 2029 // needs copying IF copyCount == 1. 2030 2031 for (int i = 0; i < args.length; i++) { 2032 if (mustCopy(args[i])) { 2033 copyArg[i] = true; 2034 copyCount++; 2035 firstCopiedArg = i; 2036 if (args[i].getTypeCode() != TYPE_REMOTE && 2037 args[i].getTypeCode() != TYPE_IMPLEMENTATION) { 2038 realCopy = true; 2039 } 2040 } else { 2041 copyArg[i] = false; 2042 } 2043 } 2044 2045 // Do we have any types which must be copied? 2046 if (copyCount > 0) { 2047 // Yes. Are we only doing the copy to ensure 2048 // that autoConnect occurs? 2049 if (realCopy) { 2050 // Nope. We need to go back thru the list and 2051 // mark any strings so that they will be copied 2052 // to preserve any shared references... 2053 for (int i = 0; i < args.length; i++) { 2054 if (args[i].getTypeCode() == TYPE_STRING) { 2055 copyArg[i] = true; 2056 copyCount++; 2057 } 2058 } 2059 } 2060 2061 // We're ready to generate code. Do we have more than 2062 // one to copy? 2063 if (copyCount > 1) { 2064 // Generate a call to copyObjects... 2065 String arrayName = getVariableName("copies"); 2066 p.p("Object[] " + arrayName + " = Util.copyObjects(new Object[]{"); 2067 boolean first = true; 2068 for (int i = 0; i < args.length; i++) { 2069 if (copyArg[i]) { 2070 if (!first) { 2071 p.p(","); 2072 } 2073 first = false; 2074 p.p(origNames[i]); 2075 } 2076 } 2077 p.pln("},_orb());"); 2078 2079 // For each of the types which was copied, create 2080 // a local temporary for it, updating the result 2081 // array with the new local parameter name... 2082 int copyIndex = 0 ; 2083 for (int i = 0; i < args.length; i++) { 2084 if (copyArg[i]) { 2085 result[i] = getVariableName(result[i]+"Copy"); 2086 p.pln( getName(args[i]) + " " + result[i] + " = (" + getName(args[i]) + ") " + 2087 arrayName + "[" + copyIndex++ +"];"); 2088 } 2089 } 2090 } else { 2091 // Generate a call to copyObject, updating the result 2092 // with the new local parameter name... 2093 result[firstCopiedArg] = getVariableName(result[firstCopiedArg]+"Copy"); 2094 p.pln( getName(args[firstCopiedArg]) + " " + result[firstCopiedArg] + " = (" + 2095 getName(args[firstCopiedArg]) + ") Util.copyObject(" + 2096 origNames[firstCopiedArg] + ",_orb());"); 2097 } 2098 } 2099 2100 return result; 2101 } 2102 2103 static final String SINGLE_SLASH = "\\"; 2104 static final String DOUBLE_SLASH = SINGLE_SLASH + SINGLE_SLASH; 2105 2106 String getRepositoryID(Type type) { 2107 return IDLNames.replace(type.getRepositoryID(), SINGLE_SLASH, DOUBLE_SLASH); 2108 } 2109 2110 String getExceptionRepositoryID(Type type) { 2111 ClassType theType = (ClassType) type; 2112 return IDLNames.getIDLRepositoryID(theType.getQualifiedIDLExceptionName(false)); 2113 } 2114 2115 String getVariableName(String proposed) { 2116 while (namesInUse.contains(proposed)) { 2117 proposed = "$" + proposed; 2118 } 2119 2120 return proposed; 2121 } 2122 2123 void addNamesInUse(CompoundType.Method[] methods) { 2124 for (int i = 0; i < methods.length; i++) { 2125 addNamesInUse(methods[i]); 2126 } 2127 } 2128 2129 void addNamesInUse(CompoundType.Method method) { 2130 String paramNames[] = method.getArgumentNames(); 2131 for (int i = 0; i < paramNames.length; i++) { 2132 addNameInUse(paramNames[i]); 2133 } 2134 } 2135 2136 void addNameInUse(String name) { 2137 namesInUse.add(name); 2138 } 2139 2140 static boolean mustCopy(Type type) { 2141 switch (type.getTypeCode()) { 2142 case TYPE_VOID: 2143 case TYPE_BOOLEAN: 2144 case TYPE_BYTE: 2145 case TYPE_CHAR: 2146 case TYPE_SHORT: 2147 case TYPE_INT: 2148 case TYPE_LONG: 2149 case TYPE_FLOAT: 2150 case TYPE_DOUBLE: 2151 case TYPE_STRING: return false; 2152 2153 case TYPE_ANY: return true; 2154 2155 case TYPE_CORBA_OBJECT: return false; 2156 2157 case TYPE_REMOTE: 2158 case TYPE_ABSTRACT: 2159 case TYPE_NC_INTERFACE: 2160 case TYPE_VALUE: 2161 case TYPE_IMPLEMENTATION: 2162 case TYPE_NC_CLASS: 2163 case TYPE_ARRAY: 2164 case TYPE_JAVA_RMI_REMOTE: return true; 2165 2166 default: throw new Error("unexpected type code: " + type.getTypeCode()); 2167 } 2168 } 2169 2170 ValueType[] getStubExceptions (CompoundType.Method method, boolean sort) { 2171 2172 ValueType[] list = method.getFilteredStubExceptions(method.getExceptions()); 2173 2174 // Sort the list so that all org.omg.CORBA.UserException 2175 // subtypes are at the beginning of the list. This ensures 2176 // that the stub will not call read_string() before calling 2177 // XXHelper.read(). 2178 2179 if (sort) { 2180 Arrays.sort(list,new UserExceptionComparator()); 2181 } 2182 2183 return list; 2184 } 2185 2186 ValueType[] getTieExceptions (CompoundType.Method method) { 2187 return method.getUniqueCatchList(method.getImplExceptions()); 2188 } 2189 2190 void writeTieMethod(IndentingWriter p, CompoundType type, 2191 CompoundType.Method method) throws IOException { 2192 String methodName = method.getName(); 2193 Type paramTypes[] = method.getArguments(); 2194 String paramNames[] = method.getArgumentNames(); 2195 Type returnType = method.getReturnType(); 2196 ValueType[] exceptions = getTieExceptions(method); 2197 String in = getVariableName("in"); 2198 String ex = getVariableName("ex"); 2199 String out = getVariableName("out"); 2200 String reply = getVariableName("reply"); 2201 2202 for (int i = 0; i < paramTypes.length; i++) { 2203 p.p(getName(paramTypes[i])+" "+paramNames[i]+" = "); 2204 writeUnmarshalArgument(p, in, paramTypes[i], null); 2205 p.pln(); 2206 } 2207 2208 boolean handleExceptions = exceptions != null; 2209 boolean doReturn = !returnType.isType(TYPE_VOID); 2210 2211 if (handleExceptions && doReturn) { 2212 String objName = testUtil(getName(returnType), returnType); 2213 p.pln(objName+" result;"); 2214 } 2215 2216 if (handleExceptions) 2217 p.plnI("try {"); 2218 2219 if (doReturn) { 2220 if (handleExceptions) { 2221 p.p("result = "); 2222 } else { 2223 p.p(getName(returnType)+" result = "); 2224 } 2225 } 2226 2227 p.p("target."+methodName+"("); 2228 for(int i = 0; i < paramNames.length; i++) { 2229 if (i > 0) 2230 p.p(", "); 2231 p.p(paramNames[i]); 2232 } 2233 p.pln(");"); 2234 2235 if (handleExceptions) { 2236 for(int i = 0; i < exceptions.length; i++) { 2237 p.pOlnI("} catch ("+getName(exceptions[i])+" "+ex+") {"); 2238 2239 // Is this our IDLEntity Exception special case? 2240 2241 if (exceptions[i].isIDLEntityException() && !exceptions[i].isCORBAUserException()) { 2242 2243 // Yes... 2244 2245 String helperName = IDLNames.replace(exceptions[i].getQualifiedIDLName(false),"::","."); 2246 helperName += "Helper"; 2247 p.pln(idOutputStream+" "+out +" = "+reply+".createExceptionReply();"); 2248 p.pln(helperName+".write("+out+","+ex+");"); 2249 2250 } else { 2251 2252 // No... 2253 2254 p.pln("String id = \"" + getExceptionRepositoryID(exceptions[i]) + "\";"); 2255 p.plnI(idExtOutputStream + " "+out+" = "); 2256 p.pln("(" + idExtOutputStream + ") "+reply+".createExceptionReply();"); 2257 p.pOln(out+".write_string(id);"); 2258 p.pln(out+".write_value("+ex+"," + getName(exceptions[i]) + ".class);"); 2259 } 2260 2261 p.pln("return "+out+";"); 2262 } 2263 p.pOln("}"); 2264 } 2265 2266 if (needNewWriteStreamClass(returnType)) { 2267 p.plnI(idExtOutputStream + " "+out+" = "); 2268 p.pln("(" + idExtOutputStream + ") "+reply+".createReply();"); 2269 p.pO(); 2270 } else { 2271 p.pln("OutputStream "+out+" = "+reply+".createReply();"); 2272 } 2273 2274 if (doReturn) { 2275 writeMarshalArgument(p, out, returnType, "result"); 2276 p.pln(); 2277 } 2278 2279 p.pln("return "+out+";"); 2280 } 2281 2282 2283 /** 2284 * Write Java statements to marshal a series of values in order as 2285 * named in the "names" array, with types as specified in the "types" 2286 * array", to the java.io.ObjectOutput stream named "stream". 2287 */ 2288 void writeMarshalArguments(IndentingWriter p, 2289 String streamName, 2290 Type[] types, String[] names) 2291 throws IOException 2292 { 2293 if (types.length != names.length) { 2294 throw new Error("paramter type and name arrays different sizes"); 2295 } 2296 2297 for (int i = 0; i < types.length; i++) { 2298 writeMarshalArgument(p, streamName, types[i], names[i]); 2299 if (i != types.length -1) { 2300 p.pln(); 2301 } 2302 } 2303 } 2304 2305 /** 2306 * Added for IASRI 4987274. Remote classes named "Util" were 2307 * getting confused with javax.rmi.CORBA.Util and the 2308 * unqualifiedName "Util". 2309 */ 2310 String testUtil(String objectName, Type ttype) { 2311 if (objectName.equals("Util")) { 2312 String correctedName = (String)ttype.getPackageName() + "." + objectName; 2313 return correctedName; 2314 } else { 2315 return objectName; 2316 } 2317 } 2318} 2319 2320class StringComparator implements java.util.Comparator { 2321 public int compare(Object o1, Object o2) { 2322 String s1 = (String)o1; 2323 String s2 = (String)o2; 2324 return s1.compareTo(s2); 2325 } 2326} 2327 2328 2329class UserExceptionComparator implements java.util.Comparator { 2330 public int compare(Object o1, Object o2) { 2331 ValueType v1 = (ValueType)o1; 2332 ValueType v2 = (ValueType)o2; 2333 int result = 0; 2334 if (isUserException(v1)) { 2335 if (!isUserException(v2)) { 2336 result = -1; 2337 } 2338 } else if (isUserException(v2)) { 2339 if (!isUserException(v1)) { 2340 result = 1; 2341 } 2342 } 2343 return result; 2344 } 2345 2346 final boolean isUserException(ValueType it) { 2347 return it.isIDLEntityException() && !it.isCORBAUserException(); 2348 } 2349} 2350