src/share/classes/sun/rmi/rmic/iiop/StubGenerator.java

Mon, 26 Mar 2012 14:01:40 +0100

author
coffeys
date
Mon, 26 Mar 2012 14:01:40 +0100
changeset 370
5222b7d658d4
parent 158
91006f157c46
child 402
27d87f0031bf
permissions
-rw-r--r--

7143851: Improve IIOP stub and tie generation in RMIC
7149048: Changes to corba rmic stubGenerator class are not used during jdk build process
Reviewed-by: mschoene, robm

     1 /*
     2  * Copyright (c) 1998, 2012, 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  */
    26 /*
    27  * Licensed Materials - Property of IBM
    28  * RMI-IIOP v1.0
    29  * Copyright IBM Corp. 1998 1999  All Rights Reserved
    30  *
    31  */
    33 package sun.rmi.rmic.iiop;
    35 import java.io.File;
    36 import java.io.IOException;
    37 import java.util.Vector;
    38 import java.util.Hashtable;
    39 import java.util.Enumeration;
    40 import sun.tools.java.Identifier;
    41 import sun.tools.java.ClassNotFound;
    42 import sun.tools.java.ClassDefinition;
    43 import sun.tools.java.ClassDeclaration;
    44 import sun.tools.java.CompilerError;
    45 import sun.rmi.rmic.IndentingWriter;
    46 import java.util.HashSet;
    47 import java.util.Arrays;
    48 import com.sun.corba.se.impl.util.Utility;
    49 import com.sun.corba.se.impl.util.PackagePrefixChecker;
    50 import sun.rmi.rmic.Main;
    52 /**
    53  * An IIOP stub/tie generator for rmic.
    54  *
    55  * @author      Bryan Atsatt
    56  * @author      Anil Vijendran
    57  * @author      M. Mortazavi
    58  */
    60 public class StubGenerator extends sun.rmi.rmic.iiop.Generator {
    62     private static final String DEFAULT_STUB_CLASS = "javax.rmi.CORBA.Stub";
    63     private static final String DEFAULT_TIE_CLASS = "org.omg.CORBA_2_3.portable.ObjectImpl";
    64     private static final String DEFAULT_POA_TIE_CLASS = "org.omg.PortableServer.Servant";
    66     protected boolean reverseIDs = false;
    67     protected boolean localStubs = true;
    68     protected boolean standardPackage = false;
    69     protected boolean useHash = true;
    70     protected String stubBaseClass = DEFAULT_STUB_CLASS;
    71     protected String tieBaseClass = DEFAULT_TIE_CLASS;
    72     protected HashSet namesInUse = new HashSet();
    73     protected Hashtable classesInUse = new Hashtable();
    74     protected Hashtable imports = new Hashtable();
    75     protected int importCount = 0;
    76     protected String currentPackage = null;
    77     protected String currentClass = null;
    78     protected boolean castArray = false;
    79     protected Hashtable transactionalObjects = new Hashtable() ;
    80     protected boolean POATie = false ;
    82     /**
    83      * Default constructor for Main to use.
    84      */
    85     public StubGenerator() {
    86     }
    88     /**
    89      * Overridden in order to set the standardPackage flag.
    90      */
    91     public void generate(
    92             sun.rmi.rmic.BatchEnvironment env,
    93             ClassDefinition cdef, File destDir) {
    94         ((sun.rmi.rmic.iiop.BatchEnvironment)env).
    95                 setStandardPackage(standardPackage);
    96         super.generate(env, cdef, destDir);
    97     }
    99     /**
   100      * Return true if a new instance should be created for each
   101      * class on the command line. Subclasses which return true
   102      * should override newInstance() to return an appropriately
   103      * constructed instance.
   104      */
   105     protected boolean requireNewInstance() {
   106         return false;
   107     }
   109     /**
   110      * Return true if non-conforming types should be parsed.
   111      * @param stack The context stack.
   112      */
   113     protected boolean parseNonConforming(ContextStack stack) {
   115         // We let the environment setting decide so that
   116         // another generator (e.g. IDLGenerator) can change
   117         // it and we will just go with the flow...
   119         return stack.getEnv().getParseNonConforming();
   120     }
   122     /**
   123      * Create and return a top-level type.
   124      * @param cdef The top-level class definition.
   125      * @param stack The context stack.
   126      * @return The compound type or null if is non-conforming.
   127      */
   128     protected CompoundType getTopType(ClassDefinition cdef, ContextStack stack) {
   130         CompoundType result = null;
   132         // Do we have an interface?
   134         if (cdef.isInterface()) {
   136             // Yes, so first try Abstract...
   138             result = AbstractType.forAbstract(cdef,stack,true);
   140             if (result == null) {
   142                 // Then try Remote...
   144                 result = RemoteType.forRemote(cdef,stack,false);
   145             }
   146         } else {
   148             // Not an interface, so try Implementation...
   150             result = ImplementationType.forImplementation(cdef,stack,false);
   151         }
   153         return result;
   154     }
   156     /**
   157      * Examine and consume command line arguments.
   158      * @param argv The command line arguments. Ignore null
   159      * and unknown arguments. Set each consumed argument to null.
   160      * @param error Report any errors using the main.error() methods.
   161      * @return true if no errors, false otherwise.
   162      */
   163     public boolean parseArgs(String argv[], Main main) {
   164         Object marker = new Object() ;
   166         // Reset any cached options...
   168         reverseIDs = false;
   169         localStubs = true;
   170         useHash = true;
   171         stubBaseClass = DEFAULT_STUB_CLASS;
   172         //       tieBaseClass = DEFAULT_TIE_CLASS;
   173         transactionalObjects = new Hashtable() ;
   175         // Parse options...
   177         boolean result = super.parseArgs(argv,main);
   178         if (result) {
   179             for (int i = 0; i < argv.length; i++) {
   180                 if (argv[i] != null) {
   181                     String arg = argv[i].toLowerCase();
   182                     if (arg.equals("-iiop")) {
   183                         argv[i] = null;
   184                     } else if (arg.equals("-xreverseids")) {
   185                         reverseIDs = true;
   186                         argv[i] = null;
   187                     } else if (arg.equals("-nolocalstubs")) {
   188                         localStubs = false;
   189                         argv[i] = null;
   190                     } else if (arg.equals("-xnohash")) {
   191                         useHash = false;
   192                         argv[i] = null;
   193                     } else if (argv[i].equals("-standardPackage")) {
   194                         standardPackage = true;
   195                         argv[i] = null;
   196                     } else if (arg.equals("-xstubbase")) {
   197                         argv[i] = null;
   198                         if (++i < argv.length && argv[i] != null && !argv[i].startsWith("-")) {
   199                             stubBaseClass = argv[i];
   200                             argv[i] = null;
   201                         } else {
   202                             main.error("rmic.option.requires.argument", "-Xstubbase");
   203                             result = false;
   204                         }
   205                     } else if (arg.equals("-xtiebase")) {
   206                         argv[i] = null;
   207                         if (++i < argv.length && argv[i] != null && !argv[i].startsWith("-")) {
   208                             tieBaseClass = argv[i];
   209                             argv[i] = null;
   210                         } else {
   211                             main.error("rmic.option.requires.argument", "-Xtiebase");
   212                             result = false;
   213                         }
   214                     } else if (arg.equals("-transactional" )) {
   215                         // Scan for the next non-flag argument.
   216                         // Assume that it is a class name and add it
   217                         // to the list of transactional classes.
   218                         for ( int ctr=i+1; ctr<argv.length; ctr++ ) {
   219                             if (argv[ctr].charAt(1) != '-') {
   220                                 transactionalObjects.put( argv[ctr], marker ) ;
   221                                 break ;
   222                             }
   223                         }
   224                         argv[i] = null;
   225                     } else if (arg.equals( "-poa" )) {
   226                         POATie = true ;
   227                         argv[i] = null;
   228                     }
   229                 }
   230             }
   231         }
   232         if(POATie){
   233             tieBaseClass = DEFAULT_POA_TIE_CLASS;
   234         } else {
   235             tieBaseClass = DEFAULT_TIE_CLASS;
   236         }
   237         return result;
   238     }
   240     /**
   241      * Return an array containing all the file names and types that need to be
   242      * generated for the given top-level type.  The file names must NOT have an
   243      * extension (e.g. ".java").
   244      * @param topType The type returned by getTopType().
   245      * @param alreadyChecked A set of Types which have already been checked.
   246      *  Intended to be passed to topType.collectMatching(filter,alreadyChecked).
   247      */
   248     protected OutputType[] getOutputTypesFor(CompoundType topType,
   249                                              HashSet alreadyChecked) {
   251         // We want to generate stubs for all remote and implementation types,
   252         // so collect them up.
   253         //
   254         // We use the form of collectMatching which allows us to pass in a set of
   255         // types which have previously been checked. By doing so, we ensure that if
   256         // the command line contains Hello and HelloImpl, we will only generate
   257         // output for Hello once...
   259         int filter = TYPE_REMOTE | TYPE_IMPLEMENTATION;
   260         Type[] genTypes = topType.collectMatching(filter,alreadyChecked);
   261         int count = genTypes.length;
   262         Vector list = new Vector(count+5);
   263         BatchEnvironment theEnv = topType.getEnv();
   265         // Now walk all types...
   267         for (int i = 0; i < genTypes.length; i++) {
   269             Type type = genTypes[i];
   270             String typeName = type.getName();
   271             boolean createStub = true;
   273             // Is it an implementation type?
   275             if (type instanceof ImplementationType) {
   277                 // Yes, so add a tie for it...
   279                 list.addElement(new OutputType(Utility.tieNameForCompiler(typeName), type));
   281                 // Does it have more than 1 remote interface?  If so, we
   282                 // want to create a stub for it...
   284                 int remoteInterfaceCount = 0;
   285                 InterfaceType[] interfaces = ((CompoundType)type).getInterfaces();
   286                 for (int j = 0; j < interfaces.length; j++) {
   287                     if (interfaces[j].isType(TYPE_REMOTE) &&
   288                         !interfaces[j].isType(TYPE_ABSTRACT)) {
   289                         remoteInterfaceCount++;
   290                     }
   291                 }
   293                 if (remoteInterfaceCount <= 1) {
   295                     // No, so do not create a stub for this type...
   297                     createStub = false;
   298                 }
   299             }
   301             // Is it an abstract interface type?
   303             if (type instanceof AbstractType) {
   305                 // Do not create a stub for this type...
   307                 createStub = false;  // d11141
   308             }
   310             if (createStub) {
   312                 // Add a stub for the type...
   314                 list.addElement(new OutputType(Utility.stubNameForCompiler(typeName), type));
   315             }
   316         }
   318         // Copy list into array..
   320         OutputType[] outputTypes = new OutputType[list.size()];
   321         list.copyInto(outputTypes);
   322         return outputTypes;
   323     }
   325     /**
   326      * Return the file name extension for the given file name (e.g. ".java").
   327      * All files generated with the ".java" extension will be compiled. To
   328      * change this behavior for ".java" files, override the compileJavaSourceFile
   329      * method to return false.
   330      * @param outputType One of the items returned by getOutputTypesFor(...)
   331      */
   332     protected String getFileNameExtensionFor(OutputType outputType) {
   333         return SOURCE_FILE_EXTENSION;
   334     }
   336     /**
   337      * Write the output for the given OutputFileName into the output stream.
   338      * @param name One of the items returned by getOutputTypesFor(...)
   339      * @param alreadyChecked A set of Types which have already been checked.
   340      *  Intended to be passed to Type.collectMatching(filter,alreadyChecked).
   341      * @param writer The output stream.
   342      */
   343     protected void writeOutputFor(      OutputType outputType,
   344                                         HashSet alreadyChecked,
   345                                         IndentingWriter writer) throws IOException {
   347         String fileName = outputType.getName();
   348         CompoundType theType = (CompoundType) outputType.getType();
   350         // Are we doing a Stub or Tie?
   352         if (fileName.endsWith(Utility.RMI_STUB_SUFFIX)) {
   354             // Stub.
   356             writeStub(outputType,writer);
   358         } else {
   360             // Tie
   362             writeTie(outputType,writer);
   363         }
   364     }
   366     /**
   367      * Write a stub for the specified type.
   368      */
   369     protected void writeStub(OutputType outputType,
   370                              IndentingWriter p) throws IOException {
   372         CompoundType theType = (CompoundType) outputType.getType();
   373         RemoteType[] remoteInterfaces = getDirectRemoteInterfaces(theType);
   375         // Write comment.
   377         p.pln("// Stub class generated by rmic, do not edit.");
   378         p.pln("// Contents subject to change without notice.");
   379         p.pln();
   381         // Set our standard classes...
   383         setStandardClassesInUse(theType,true);
   385         // Add classes for this type...
   387         addClassesInUse(theType,remoteInterfaces);
   389         // Write package and import statements...
   391         writePackageAndImports(p);
   393         // Declare the stub class; implement all remote interfaces.
   395         p.p("public class " + currentClass);
   396         p.p(" extends " + getName(stubBaseClass));
   397         p.p(" implements ");
   398         if (remoteInterfaces.length > 0) {
   399             for(int i = 0; i < remoteInterfaces.length; i++) {
   400                 if (i > 0) {
   401                     p.pln(",");
   402                 }
   403                 String objName = testUtil(getName(remoteInterfaces[i]), theType);
   404                 p.p(objName);
   405             }
   406         }
   408         // Add java.rmi.Remote if this type does not implement it.
   409         // This allows stubs for Abstract interfaces to be treated
   410         // uniformly...
   412         if (!implementsRemote(theType)) {
   413             p.pln(",");
   414             p.p(getName("java.rmi.Remote"));
   415         }
   417         p.plnI(" {");
   418         p.pln();
   420         // Write the ids...
   422         writeIds( p, theType, false );
   423         p.pln();
   425         // Write the _ids() method...
   427         p.plnI("public String[] _ids() { ");
   428         p.pln("return (String[]) _type_ids.clone();");
   429         p.pOln("}");
   431         // Get all the methods and write each stub method...
   433         CompoundType.Method[] remoteMethods = theType.getMethods();
   434         int methodCount = remoteMethods.length;
   435         if (methodCount > 0) {
   436             boolean writeHeader = true;
   437             for(int i = 0; i < methodCount; i++) {
   438                 if (!remoteMethods[i].isConstructor()) {
   439                     if (writeHeader) {
   440                         writeHeader = false;
   441                     }
   442                     p.pln();
   443                     writeStubMethod(p, remoteMethods[i], theType);
   444                 }
   445             }
   446         }
   448         // Write the cast array hack...
   450         writeCastArray(p);
   452         p.pOln("}");            // end stub class
   453     }
   455     void addClassInUse(String qualifiedName) {
   456         String unqualifiedName = qualifiedName;
   457         String packageName = null;
   458         int index = qualifiedName.lastIndexOf('.');
   459         if (index > 0) {
   460             unqualifiedName = qualifiedName.substring(index+1);
   461             packageName = qualifiedName.substring(0,index);
   462         }
   463         addClassInUse(unqualifiedName,qualifiedName,packageName);
   464     }
   466     void addClassInUse(Type type) {
   467         if (!type.isPrimitive()) {
   468             Identifier id = type.getIdentifier();
   469             String name = IDLNames.replace(id.getName().toString(),". ",".");
   470             String packageName = type.getPackageName();
   471             String qualifiedName;
   472             if (packageName != null) {
   473                 qualifiedName = packageName+"."+name;
   474             } else {
   475                 qualifiedName = name;
   476             }
   477             addClassInUse(name,qualifiedName,packageName);
   478         }
   479     }
   481     void addClassInUse(Type[] types) {
   482         for (int i = 0; i < types.length; i++) {
   483             addClassInUse(types[i]);
   484         }
   485     }
   487     void addStubInUse(Type type) {
   488         if (type.getIdentifier() != idCorbaObject &&
   489             type.isType(TYPE_CORBA_OBJECT)) {
   490             String stubName = getStubNameFor(type,false);
   491             String packageName = type.getPackageName();
   492             String fullName;
   493             if (packageName == null) {
   494                 fullName = stubName;
   495             } else {
   496                 fullName = packageName + "." + stubName;
   497             }
   498             addClassInUse(stubName,fullName,packageName);
   499         }
   500         if (type.isType(TYPE_REMOTE) ||
   501             type.isType(TYPE_JAVA_RMI_REMOTE)) {
   502             addClassInUse("javax.rmi.PortableRemoteObject");
   503         }
   504     }
   506     String getStubNameFor(Type type, boolean qualified) {
   507         String stubName;
   508         String className;
   509         if (qualified) {
   510             className = type.getQualifiedName();
   511         } else {
   512             className = type.getName();
   513         }
   514         if (((CompoundType)type).isCORBAObject()) {
   515             stubName = Utility.idlStubName(className);
   516         } else {
   517             stubName = Utility.stubNameForCompiler(className);
   518         }
   519         return stubName;
   520     }
   522     void addStubInUse(Type[] types) {
   523         for (int i = 0; i < types.length; i++) {
   524             addStubInUse(types[i]);
   525         }
   526     }
   528     private static final String NO_IMPORT = new String();
   530     void addClassInUse(String unqualifiedName, String qualifiedName, String packageName) {
   532         // Have we already got an entry for this qualifiedName?
   534         String currentName = (String)classesInUse.get(qualifiedName);
   536         if (currentName == null) {
   538             // No, never seen it before. Grab any existing import
   539             // name and then decide what to do...
   541             String importName = (String) imports.get(unqualifiedName);
   542             String nameToUse = null;
   544             if (packageName == null) {
   546                 // Default package, so doesn't matter which name to use...
   548                 nameToUse = unqualifiedName;
   550             } else if (packageName.equals("java.lang")) {
   552                 // java.lang.*, so use unqualified name...
   554                 nameToUse = unqualifiedName;
   556                 // unless you want to be able to import things from the right place :--)
   558                 if(nameToUse.endsWith("_Stub")) nameToUse = Util.packagePrefix()+qualifiedName;
   560             } else if (currentPackage != null && packageName.equals(currentPackage)) {
   562                 // Class in currentPackage, so use unqualified name...
   564                 nameToUse = unqualifiedName;
   566                 // Do we already have a previous import under this
   567                 // unqualified name?
   569                 if (importName != null) {
   571                     // Yes, so we use qualifiedName...
   573                     nameToUse = qualifiedName;
   575                 }
   577             } else if (importName != null) {
   579                 // It is in some package for which we normally
   580                 // would import, but we have a previous import
   581                 // under this unqualified name. We must use
   582                 // the qualified name...
   584                 nameToUse = qualifiedName;
   586                 /*
   587                   // Is the currentPackage the default package?
   589                   if (currentPackage == null) {
   591                   // Yes, so undo the import so that all
   592                   // uses for this name will be qualified...
   594                   String old = (String)imports.remove(unqualifiedName);
   595                   classesInUse.put(old,old);
   596                   importCount--;
   598                   // Note that this name is in use but should
   599                   // not be imported...
   601                   imports.put(nameToUse,NO_IMPORT);
   602                   }
   603                 */
   604             } else if (qualifiedName.equals("org.omg.CORBA.Object")) {
   606                 // Always qualify this quy to avoid confusion...
   608                 nameToUse = qualifiedName;
   610             } else {
   612                 // Default to using unqualified name, and add
   613                 // this guy to the imports...
   615                 // Check for nested class in which case we use
   616                 // the fully qualified name instead of imports
   617                 if (unqualifiedName.indexOf('.') != -1) {
   618                     nameToUse = qualifiedName;
   619                 } else {
   620                     nameToUse = unqualifiedName;
   621                     imports.put(unqualifiedName,qualifiedName);
   622                     importCount++;
   623                 }
   624             }
   626             // Now add the name...
   628             classesInUse.put(qualifiedName,nameToUse);
   629         }
   630     }
   632     String getName(Type type) {
   633         if (type.isPrimitive()) {
   634             return type.getName() + type.getArrayBrackets();
   635         }
   636         Identifier id = type.getIdentifier();
   637         String name = IDLNames.replace(id.toString(),". ",".");
   638         return getName(name) + type.getArrayBrackets();
   639     }
   641     // Added for Bug 4818753
   642     String getExceptionName(Type type) {
   643         Identifier id = type.getIdentifier();
   644         return IDLNames.replace(id.toString(),". ",".");
   645     }
   647     String getName(String qualifiedName) {
   648         return (String)classesInUse.get(qualifiedName);
   649     }
   651     String getName(Identifier id) {
   652         return getName(id.toString());
   653     }
   655     String getStubName(Type type) {
   656         String stubName = getStubNameFor(type,true);
   657         return getName(stubName);
   658     }
   660     void setStandardClassesInUse(CompoundType type,
   661                                  boolean stub) throws IOException {
   663         // Reset our state...
   665         currentPackage = type.getPackageName();
   666         imports.clear();
   667         classesInUse.clear();
   668         namesInUse.clear();
   669         importCount = 0;
   670         castArray = false;
   672         // Add the top-level type...
   674         addClassInUse(type);
   676         // Set current class name...
   678         if (stub) {
   679             currentClass = Utility.stubNameForCompiler(type.getName());
   680         } else {
   681             currentClass = Utility.tieNameForCompiler(type.getName());
   682         }
   684         // Add current class...
   686         if (currentPackage == null) {
   687             addClassInUse(currentClass,currentClass,currentPackage);
   688         } else {
   689             addClassInUse(currentClass,(currentPackage+"."+currentClass),currentPackage);
   690         }
   692         // Add standard classes...
   694         addClassInUse("javax.rmi.CORBA.Util");
   695         addClassInUse(idRemote.toString());
   696         addClassInUse(idRemoteException.toString());
   697         addClassInUse(idOutputStream.toString());
   698         addClassInUse(idInputStream.toString());
   699         addClassInUse(idSystemException.toString());
   700         addClassInUse(idJavaIoSerializable.toString());
   701         addClassInUse(idCorbaORB.toString());
   702         addClassInUse(idReplyHandler.toString());
   704         // Add stub/tie specific imports...
   706         if (stub) {
   707             addClassInUse(stubBaseClass);
   708             addClassInUse("java.rmi.UnexpectedException");
   709             addClassInUse(idRemarshalException.toString());
   710             addClassInUse(idApplicationException.toString());
   711             if (localStubs) {
   712                 addClassInUse("org.omg.CORBA.portable.ServantObject");
   713             }
   714         } else {
   715             addClassInUse(type);
   716             addClassInUse(tieBaseClass);
   717             addClassInUse(idTieInterface.toString());
   718             addClassInUse(idBadMethodException.toString());
   719             addClassInUse(idPortableUnknownException.toString());
   720             addClassInUse(idJavaLangThrowable.toString());
   721         }
   722     }
   724     void addClassesInUse(CompoundType type, RemoteType[] interfaces) {
   726         // Walk all methods and add types in use...
   728         CompoundType.Method[] methods = type.getMethods();
   729         for (int i = 0; i < methods.length; i++) {
   730             addClassInUse(methods[i].getReturnType());
   731             addStubInUse(methods[i].getReturnType());
   732             addClassInUse(methods[i].getArguments());
   733             addStubInUse(methods[i].getArguments());
   734             addClassInUse(methods[i].getExceptions());
   735             // bug 4473859: Also include narrower subtypes for use
   736             addClassInUse(methods[i].getImplExceptions());
   737         }
   739         // If this is a stub, add all interfaces...
   741         if (interfaces != null) {
   742             addClassInUse(interfaces);
   743         }
   744     }
   746     void writePackageAndImports(IndentingWriter p) throws IOException {
   748         // Write package declaration...
   750         if (currentPackage != null) {
   751             p.pln("package " +
   752                      Util.correctPackageName(
   753                           currentPackage, false, standardPackage)
   754                    + ";");
   755             p.pln();
   756         }
   758         // Get imports into an array and sort them...
   760         String[] names = new String[importCount];
   761         int index = 0;
   762         for (Enumeration e = imports.elements() ; e.hasMoreElements() ;) {
   763             String it = (String) e.nextElement();
   764             if (it != NO_IMPORT) {
   765                 names[index++] = it;
   766             }
   767         }
   769         Arrays.sort(names,new StringComparator());
   771         // Now dump them out...
   773         for (int i = 0; i < importCount; i++) {
   774             if(
   775                Util.isOffendingPackage(names[i])
   776                && names[i].endsWith("_Stub")
   777                && String.valueOf(names[i].charAt(names[i].lastIndexOf(".")+1)).equals("_")
   778                ){
   779                 p.pln("import " + PackagePrefixChecker.packagePrefix()+names[i]+";");
   780             } else{
   781                 p.pln("import " + names[i] + ";");
   782             }
   783         }
   784         p.pln();
   786         // Include offending packages . . .
   787         if ( currentPackage!=null && Util.isOffendingPackage(currentPackage) ){
   788             p.pln("import " + currentPackage +".*  ;");
   789         }
   790         p.pln();
   792     }
   794     boolean implementsRemote(CompoundType theType) {
   795         boolean result = theType.isType(TYPE_REMOTE) && !theType.isType(TYPE_ABSTRACT);
   797         // If theType is not remote, look at all the interfaces
   798         // until we find one that is...
   800         if (!result) {
   801             InterfaceType[] interfaces = theType.getInterfaces();
   802             for (int i = 0; i < interfaces.length; i++) {
   803                 result = implementsRemote(interfaces[i]);
   804                 if (result) {
   805                     break;
   806                 }
   807             }
   808         }
   810         return result;
   811     }
   813     void writeStubMethod (  IndentingWriter p,
   814                             CompoundType.Method method,
   815                             CompoundType theType) throws IOException {
   817         // Wtite the method declaration and opening brace...
   819         String methodName = method.getName();
   820         String methodIDLName = method.getIDLName();
   822         Type paramTypes[] = method.getArguments();
   823         String paramNames[] = method.getArgumentNames();
   824         Type returnType = method.getReturnType();
   825         ValueType[] exceptions = getStubExceptions(method,false);
   827         addNamesInUse(method);
   828         addNameInUse("_type_ids");
   830         String objName = testUtil(getName(returnType), returnType);
   831         p.p("public " + objName + " " + methodName + "(");
   832         for(int i = 0; i < paramTypes.length; i++) {
   833             if (i > 0)
   834                 p.p(", ");
   835             p.p(getName(paramTypes[i]) + " " + paramNames[i]);
   836         }
   838         p.p(")");
   839         if (exceptions.length > 0) {
   840             p.p(" throws ");
   841             for(int i = 0; i < exceptions.length; i++) {
   842                 if (i > 0) {
   843                     p.p(", ");
   844                 }
   845                 // Added for Bug 4818753
   846                 p.p(getExceptionName(exceptions[i]));
   847             }
   848         }
   850         p.plnI(" {");
   852         // Now create the method body...
   854         if (localStubs) {
   855             writeLocalStubMethodBody(p,method,theType);
   856         } else {
   857             writeNonLocalStubMethodBody(p,method,theType);
   858         }
   860         // Close out the method...
   862         p.pOln("}");
   863     }
   866     void writeLocalStubMethodBody (IndentingWriter p,
   867                                    CompoundType.Method method,
   868                                    CompoundType theType) throws IOException {
   870         String objName;
   871         String paramNames[] = method.getArgumentNames();
   872         Type returnType = method.getReturnType();
   873         ValueType[] exceptions = getStubExceptions(method,false);
   874         String methodName = method.getName();
   875         String methodIDLName = method.getIDLName();
   877         p.plnI("if (!Util.isLocal(this)) {");
   878         writeNonLocalStubMethodBody(p,method,theType);
   879         p.pOlnI("} else {");
   880         String so = getVariableName("so");
   882         p.pln("ServantObject "+so+" = _servant_preinvoke(\""+methodIDLName+"\","+getName(theType)+".class);");
   883         p.plnI("if ("+so+" == null) {");
   884         if (!returnType.isType(TYPE_VOID)) {
   885             p.p("return ");
   886         }
   887         p.p(methodName+"(");
   888         for (int i = 0; i < paramNames.length; i++) {
   889             if (i > 0)
   890                 p.p(", ");
   891             p.p(paramNames[i]);
   892         }
   893         p.pln(");");
   894         if (returnType.isType(TYPE_VOID)) {
   895             p.pln( "return ;" ) ;
   896         }
   898         p.pOln("}");
   899         p.plnI("try {");
   901         // Generate code to copy required arguments, and
   902         // get back the names by which all arguments are known...
   904         String[] argNames = writeCopyArguments(method,p);
   906         // Now write the method...
   908         boolean copyReturn = mustCopy(returnType);
   909         String resultName = null;
   910         if (!returnType.isType(TYPE_VOID)) {
   911             if (copyReturn) {
   912                 resultName = getVariableName("result");
   913                 objName = testUtil(getName(returnType), returnType);
   914                 p.p(objName+" "+resultName + " = ");
   915             } else {
   916                 p.p("return ");
   917             }
   918         }
   919         objName = testUtil(getName(theType), theType);
   920         p.p("(("+objName+")"+so+".servant)."+methodName+"(");
   922         for (int i = 0; i < argNames.length; i++) {
   923             if (i > 0)
   924                 p.p(", ");
   925             p.p(argNames[i]);
   926         }
   928         if (copyReturn) {
   929             p.pln(");");
   930             objName = testUtil(getName(returnType), returnType);
   931             p.pln("return ("+objName+")Util.copyObject("+resultName+",_orb());");
   932         } else {
   933             p.pln(");");
   934         }
   936         String e1 = getVariableName("ex");
   937         String e2 = getVariableName("exCopy");
   938         p.pOlnI("} catch (Throwable "+e1+") {");
   940         p.pln("Throwable "+e2+" = (Throwable)Util.copyObject("+e1+",_orb());");
   941         for(int i = 0; i < exceptions.length; i++) {
   942             if (exceptions[i].getIdentifier() != idRemoteException &&
   943                 exceptions[i].isType(TYPE_VALUE)) {
   944                 // Added for Bug 4818753
   945                 p.plnI("if ("+e2+" instanceof "+getExceptionName(exceptions[i])+") {");
   946                 p.pln("throw ("+getExceptionName(exceptions[i])+")"+e2+";");
   947                 p.pOln("}");
   948             }
   949         }
   951         p.pln("throw Util.wrapException("+e2+");");
   952         p.pOlnI("} finally {");
   953         p.pln("_servant_postinvoke("+so+");");
   954         p.pOln("}");
   955         p.pOln("}");
   956     }
   959     void writeNonLocalStubMethodBody (  IndentingWriter p,
   960                                         CompoundType.Method method,
   961                                         CompoundType theType) throws IOException {
   963         String methodName = method.getName();
   964         String methodIDLName = method.getIDLName();
   966         Type paramTypes[] = method.getArguments();
   967         String paramNames[] = method.getArgumentNames();
   968         Type returnType = method.getReturnType();
   969         ValueType[] exceptions = getStubExceptions(method,true);
   971         String in = getVariableName("in");
   972         String out = getVariableName("out");
   973         String ex = getVariableName("ex");
   975         // Decide if we need to use the new streams for
   976         // any of the read calls...
   978         boolean needNewReadStreamClass = false;
   979         for (int i = 0; i < exceptions.length; i++) {
   980             if (exceptions[i].getIdentifier() != idRemoteException &&
   981                 exceptions[i].isType(TYPE_VALUE) &&
   982                 needNewReadStreamClass(exceptions[i])) {
   983                 needNewReadStreamClass = true;
   984                 break;
   985             }
   986         }
   987         if (!needNewReadStreamClass) {
   988             for (int i = 0; i < paramTypes.length; i++) {
   989                 if (needNewReadStreamClass(paramTypes[i])) {
   990                     needNewReadStreamClass = true;
   991                     break;
   992                 }
   993             }
   994         }
   995         if (!needNewReadStreamClass) {
   996             needNewReadStreamClass = needNewReadStreamClass(returnType);
   997         }
   999         // Decide if we need to use the new streams for
  1000         // any of the write calls...
  1002         boolean needNewWriteStreamClass = false;
  1003         for (int i = 0; i < paramTypes.length; i++) {
  1004             if (needNewWriteStreamClass(paramTypes[i])) {
  1005                 needNewWriteStreamClass = true;
  1006                 break;
  1010         // Now write the method, inserting casts where needed...
  1012         p.plnI("try {");
  1013         if (needNewReadStreamClass) {
  1014             p.pln(idExtInputStream + " "+in+" = null;");
  1015         } else {
  1016             p.pln(idInputStream + " "+in+" = null;");
  1018         p.plnI("try {");
  1020         String argStream = "null";
  1022         if (needNewWriteStreamClass) {
  1023             p.plnI(idExtOutputStream + " "+out+" = ");
  1024             p.pln("(" + idExtOutputStream + ")");
  1025             p.pln("_request(\"" + methodIDLName + "\", true);");
  1026             p.pO();
  1027         } else {
  1028             p.pln("OutputStream "+out+" = _request(\"" + methodIDLName + "\", true);");
  1031         if (paramTypes.length > 0) {
  1032             writeMarshalArguments(p, out, paramTypes, paramNames);
  1033             p.pln();
  1035         argStream = out;
  1037         if (returnType.isType(TYPE_VOID)) {
  1038             p.pln("_invoke(" + argStream + ");" );
  1039         } else {
  1040             if (needNewReadStreamClass) {
  1041                 p.plnI(in+" = (" + idExtInputStream + ")_invoke(" + argStream + ");");
  1042                 p.pO();
  1043             } else {
  1044                 p.pln(in+" = _invoke(" + argStream + ");");
  1046             p.p("return ");
  1047             writeUnmarshalArgument(p, in, returnType, null);
  1048             p.pln();
  1051         // Handle ApplicationException...
  1053         p.pOlnI("} catch ("+getName(idApplicationException)+" "+ex+") {");
  1054         if (needNewReadStreamClass) {
  1055             p.pln(in + " = (" + idExtInputStream + ") "+ex+".getInputStream();");
  1056         } else {
  1057             p.pln(in + " = "+ex+".getInputStream();");
  1060         boolean idRead = false;
  1061         boolean idAllocated = false;
  1062         for(int i = 0; i < exceptions.length; i++) {
  1063             if (exceptions[i].getIdentifier() != idRemoteException) {
  1065                 // Is this our special-case IDLEntity exception?
  1067                 if (exceptions[i].isIDLEntityException() && !exceptions[i].isCORBAUserException()) {
  1069                     // Yes.
  1071                     if (!idAllocated && !idRead) {
  1072                         p.pln("String $_id = "+ex+".getId();");
  1073                         idAllocated = true;
  1076                     String helperName = IDLNames.replace(exceptions[i].getQualifiedIDLName(false),"::",".");
  1077                     helperName += "Helper";
  1078                     p.plnI("if ($_id.equals("+helperName+".id())) {");
  1079                     p.pln("throw "+helperName+".read("+in+");");
  1081                 } else {
  1083                     // No.
  1085                     if (!idAllocated && !idRead) {
  1086         p.pln("String $_id = "+in+".read_string();");
  1087                         idAllocated = true;
  1088                         idRead = true;
  1089                     } else if (idAllocated && !idRead) {
  1090                         p.pln("$_id = "+in+".read_string();");
  1091                         idRead = true;
  1093                     p.plnI("if ($_id.equals(\""+getExceptionRepositoryID(exceptions[i])+"\")) {");
  1094                     // Added for Bug 4818753
  1095                     p.pln("throw ("+getExceptionName(exceptions[i])+") "+in+".read_value(" + getExceptionName(exceptions[i]) + ".class);");
  1097                 p.pOln("}");
  1100         if (!idAllocated && !idRead) {
  1101             p.pln("String $_id = "+in+".read_string();");
  1102             idAllocated = true;
  1103             idRead = true;
  1104         } else if (idAllocated && !idRead) {
  1105             p.pln("$_id = "+in+".read_string();");
  1106             idRead = true;
  1108         p.pln("throw new UnexpectedException($_id);");
  1110         // Handle RemarshalException...
  1112         p.pOlnI("} catch ("+getName(idRemarshalException)+" "+ex+") {");
  1113         if (!returnType.isType(TYPE_VOID)) {
  1114             p.p("return ");
  1116         p.p(methodName + "(");
  1117         for(int i = 0; i < paramTypes.length; i++) {
  1118             if (i > 0) {
  1119                 p.p(",");
  1121             p.p(paramNames[i]);
  1123         p.pln(");");
  1125         // Ensure that we release the reply...
  1127         p.pOlnI("} finally {");
  1128         p.pln("_releaseReply("+in+");");
  1130         p.pOln("}");
  1132         // Handle SystemException...
  1134         p.pOlnI("} catch (SystemException "+ex+") {");
  1135         p.pln("throw Util.mapSystemException("+ex+");");
  1136         p.pOln("}");
  1138         // returnResult(p,returnType);
  1141     void allocateResult (IndentingWriter p,
  1142                          Type returnType) throws IOException {
  1143         if (!returnType.isType(TYPE_VOID)) {
  1144             String objName = testUtil(getName(returnType), returnType);
  1145             p.p(objName + " result = ");
  1149     int getTypeCode(Type type) {
  1151         int typeCode = type.getTypeCode();
  1153         // Handle late-breaking special case for
  1154         // abstract IDL entities...
  1156         if ((type instanceof CompoundType) &&
  1157             ((CompoundType)type).isAbstractBase()) {
  1158             typeCode = TYPE_ABSTRACT;
  1161         return typeCode;
  1165     /**
  1166      * Write a snippet of Java code to marshal a value named "name" of
  1167      * type "type" to the java.io.ObjectOutput stream named "stream".
  1168      */
  1169     void writeMarshalArgument(IndentingWriter p,
  1170                               String streamName,
  1171                               Type type, String name) throws IOException {
  1173         int typeCode = getTypeCode(type);
  1175         switch (typeCode) {
  1176         case TYPE_BOOLEAN:
  1177             p.p(streamName + ".write_boolean(" + name + ");");
  1178             break;
  1179         case TYPE_BYTE:
  1180             p.p(streamName + ".write_octet(" + name + ");");
  1181             break;
  1182         case TYPE_CHAR:
  1183             p.p(streamName + ".write_wchar(" + name + ");");
  1184             break;
  1185         case TYPE_SHORT:
  1186             p.p(streamName + ".write_short(" + name + ");");
  1187             break;
  1188         case TYPE_INT:
  1189             p.p(streamName + ".write_long(" + name + ");");
  1190             break;
  1191         case TYPE_LONG:
  1192             p.p(streamName + ".write_longlong(" + name + ");");
  1193             break;
  1194         case TYPE_FLOAT:
  1195             p.p(streamName + ".write_float(" + name + ");");
  1196             break;
  1197         case TYPE_DOUBLE:
  1198             p.p(streamName + ".write_double(" + name + ");");
  1199             break;
  1200         case TYPE_STRING:
  1201             p.p(streamName + ".write_value(" + name + "," + getName(type) + ".class);");
  1202             break;
  1203         case TYPE_ANY:
  1204             p.p("Util.writeAny("+ streamName + "," + name + ");");
  1205             break;
  1206         case TYPE_CORBA_OBJECT:
  1207             p.p(streamName + ".write_Object(" + name + ");");
  1208             break;
  1209         case TYPE_REMOTE:
  1210             p.p("Util.writeRemoteObject("+ streamName + "," + name + ");");
  1211             break;
  1212         case TYPE_ABSTRACT:
  1213             p.p("Util.writeAbstractObject("+ streamName + "," + name + ");");
  1214             break;
  1215         case TYPE_NC_INTERFACE:
  1216             p.p(streamName + ".write_value((Serializable)" + name + "," + getName(type) + ".class);");
  1217             break;
  1218         case TYPE_VALUE:
  1219             p.p(streamName + ".write_value(" + name + "," + getName(type) + ".class);");
  1220             break;
  1221         case TYPE_IMPLEMENTATION:
  1222             p.p(streamName + ".write_value((Serializable)" + name + "," + getName(type) + ".class);");
  1223             break;
  1224         case TYPE_NC_CLASS:
  1225             p.p(streamName + ".write_value((Serializable)" + name + "," + getName(type) + ".class);");
  1226             break;
  1227         case TYPE_ARRAY:
  1228             castArray = true;
  1229             p.p(streamName + ".write_value(cast_array(" + name + ")," + getName(type) + ".class);");
  1230             break;
  1231         case TYPE_JAVA_RMI_REMOTE:
  1232             p.p("Util.writeRemoteObject("+ streamName + "," + name + ");");
  1233             break;
  1234         default:
  1235             throw new Error("unexpected type code: " + typeCode);
  1239     /**
  1240      * Write a snippet of Java code to unmarshal a value of type "type"
  1241      * from the java.io.ObjectInput stream named "stream" into a variable
  1242      * named "name" (if "name" is null, the value in unmarshalled and
  1243      * discarded).
  1244      */
  1245     void writeUnmarshalArgument(IndentingWriter p,
  1246                                 String streamName,
  1247                                 Type type,
  1248                                 String name) throws IOException {
  1250         int typeCode = getTypeCode(type);
  1252         if (name != null) {
  1253             p.p(name + " = ");
  1256         switch (typeCode) {
  1257         case TYPE_BOOLEAN:
  1258             p.p(streamName + ".read_boolean();");
  1259             break;
  1260         case TYPE_BYTE:
  1261             p.p(streamName + ".read_octet();");
  1262             break;
  1263         case TYPE_CHAR:
  1264             p.p(streamName + ".read_wchar();");
  1265             break;
  1266         case TYPE_SHORT:
  1267             p.p(streamName + ".read_short();");
  1268             break;
  1269         case TYPE_INT:
  1270             p.p(streamName + ".read_long();");
  1271             break;
  1272         case TYPE_LONG:
  1273             p.p(streamName + ".read_longlong();");
  1274             break;
  1275         case TYPE_FLOAT:
  1276             p.p(streamName + ".read_float();");
  1277             break;
  1278         case TYPE_DOUBLE:
  1279             p.p(streamName + ".read_double();");
  1280             break;
  1281         case TYPE_STRING:
  1282             p.p("(String) " + streamName + ".read_value(" + getName(type) + ".class);");
  1283             break;
  1284         case TYPE_ANY:
  1285             if (type.getIdentifier() != idJavaLangObject) {
  1286                 p.p("(" + getName(type) + ") ");
  1288             p.p("Util.readAny(" + streamName + ");");
  1289             break;
  1290         case TYPE_CORBA_OBJECT:
  1291             if (type.getIdentifier() == idCorbaObject) {
  1292                 p.p("(" + getName(type) + ") " + streamName + ".read_Object();");
  1293             } else {
  1294                 p.p("(" + getName(type) + ") " + streamName + ".read_Object(" + getStubName(type) + ".class);");
  1296             break;
  1297         case TYPE_REMOTE:
  1298             String objName = testUtil(getName(type), type);
  1299             p.p("(" + objName + ") " +
  1300                 "PortableRemoteObject.narrow(" + streamName + ".read_Object(), " + objName + ".class);");
  1301             break;
  1302         case TYPE_ABSTRACT:
  1303             p.p("(" + getName(type) + ") " + streamName + ".read_abstract_interface();");
  1304             break;
  1305         case TYPE_NC_INTERFACE:
  1306             p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);");
  1307             break;
  1308         case TYPE_VALUE:
  1309             p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);");
  1310             break;
  1311         case TYPE_IMPLEMENTATION:
  1312             p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);");
  1313             break;
  1314         case TYPE_NC_CLASS:
  1315             p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);");
  1316             break;
  1317         case TYPE_ARRAY:
  1318             p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);");
  1319             break;
  1320         case TYPE_JAVA_RMI_REMOTE:
  1321             p.p("(" + getName(type) + ") " +
  1322                 "PortableRemoteObject.narrow(" + streamName + ".read_Object(), " + getName(type) + ".class);");
  1323             //      p.p("(" + getName(type) + ") " + streamName + ".read_Object(" + getStubName(type) + ".class);");
  1324             break;
  1325         default:
  1326             throw new Error("unexpected type code: " + typeCode);
  1330     /**
  1331      * Get a list of all the RepositoryIDs for interfaces
  1332      * implemented directly or indirectly by theType. In the
  1333      * case of an  ImplementationType which implements 2 or
  1334      * more remote interfaces, this list will begin with the
  1335      * Identifier for the implementation (see section 5.9 in
  1336      * the Java -> IDL mapping). Ensures that the most derived
  1337      * type is first in the list because the IOR is generated
  1338      * using that entry in the _ids array.
  1339      */
  1340     String[] getAllRemoteRepIDs (CompoundType theType) {
  1342         String[] result;
  1344         // Collect up all the (inherited) remote interfaces
  1345         // (ignores all the 'special' interfaces: Remote,
  1346         // Serializable, Externalizable)...
  1348         Type[] types = collectAllRemoteInterfaces(theType);
  1350         int length = types.length;
  1351         boolean haveImpl = theType instanceof ImplementationType;
  1352         InterfaceType[] interfaces = theType.getInterfaces();
  1353         int remoteCount = countRemote(interfaces,false);
  1354         int offset = 0;
  1356         // Do we have an implementation type that implements
  1357         // more than one remote interface?
  1359         if (haveImpl && remoteCount > 1) {
  1361             // Yes, so we need to insert it at the beginning...
  1363             result = new String[length + 1];
  1364             result[0] = getRepositoryID(theType);
  1365             offset = 1;
  1367         } else {
  1369             // No.
  1371             result = new String[length];
  1373             // Here we need to ensure that the most derived
  1374             // interface ends up being first in the list. If
  1375             // there is only one, we're done.
  1377             if (length > 1) {
  1379                 // First, decide what the most derived type is...
  1381                 String mostDerived = null;
  1383                 if (haveImpl) {
  1385                     // If we get here, we know that there is only one
  1386                     // direct remote interface, so just find it...
  1388                     for (int i = 0; i < interfaces.length; i++) {
  1389                         if (interfaces[i].isType(TYPE_REMOTE)) {
  1390                             mostDerived = interfaces[i].getRepositoryID();
  1391                             break;
  1394                 } else {
  1396                     // If we get here we know that theType is a RemoteType
  1397                     // so just use its id...
  1399                     mostDerived = theType.getRepositoryID();
  1402                 // Now search types list and make sure mostDerived is
  1403                 // at index zero...
  1405                 for (int i = 0; i < length; i++) {
  1406                     if (types[i].getRepositoryID() == mostDerived) {
  1408                         // Found it. Swap it if we need to...
  1410                         if (i > 0) {
  1411                             Type temp = types[0];
  1412                             types[0] = types[i];
  1413                             types[i] = temp;
  1416                         break;
  1422         // Now copy contents of the types array...
  1424         for (int i = 0; i < types.length; i++) {
  1425             result[offset++] = getRepositoryID(types[i]);
  1428         // If we're supposed to, reverse the array. This
  1429         // is only done when the -testReverseIDs flag is
  1430         // passed, and that should ONLY be done for test
  1431         // cases. This is an undocumented feature.
  1433         if (reverseIDs) {
  1434             int start = 0;
  1435             int end = result.length -1;
  1436             while (start < end) {
  1437                 String temp = result[start];
  1438                 result[start++] = result[end];
  1439                 result[end--] = temp;
  1443         return result;
  1446     /**
  1447      * Collect all the inherited remote interfaces.
  1448      */
  1449     Type[] collectAllRemoteInterfaces (CompoundType theType) {
  1450         Vector list = new Vector();
  1452         // Collect up all the Remote interfaces, and get an instance
  1453         // for java.rmi.Remote...
  1455         addRemoteInterfaces(list,theType);
  1457         // Create and return our results...
  1459         Type[] result = new Type[list.size()];
  1460         list.copyInto(result);
  1462         return result;
  1465     /**
  1466      * Add all the inherited remote interfaces to list.
  1467      */
  1468     void addRemoteInterfaces(Vector list, CompoundType theType) {
  1470         if (theType != null) {
  1471             if (theType.isInterface() && !list.contains(theType)) {
  1472                 list.addElement(theType);
  1475             InterfaceType[] interfaces = theType.getInterfaces();
  1476             for (int i = 0; i < interfaces.length; i++) {
  1478                 if (interfaces[i].isType(TYPE_REMOTE)) {
  1479                     addRemoteInterfaces(list,interfaces[i]);
  1483             addRemoteInterfaces(list,theType.getSuperclass());
  1487     /**
  1488      * Get a list of all the remote interfaces which this stub
  1489      * should declare.
  1490      */
  1491     RemoteType[] getDirectRemoteInterfaces (CompoundType theType) {
  1493         RemoteType[] result;
  1494         InterfaceType[] interfaces = theType.getInterfaces();
  1496         // First, get a list of all the interfaces...
  1498         InterfaceType[] list;
  1500         // Because we can be passed either an ImplementationType
  1501         // (which has interfaces) or a RemoteType (which is an
  1502         // interface and may have interfaces) we must handle each
  1503         // separately...
  1505         // Do we have an implementation type?
  1507         if (theType instanceof ImplementationType) {
  1509             // Yes, so list is exactly what this type
  1510             // implements and is correct already.
  1512             list = interfaces;
  1514         } else {
  1516             // No, so list is just theType...
  1518             list = new InterfaceType[1];
  1519             list[0] = (InterfaceType) theType;
  1522         // Ok, now count up the remote interfaces, allocate
  1523         // our result and fill it in...
  1525         int remoteCount = countRemote(list,false);
  1527         if (remoteCount == 0) {
  1528             throw new CompilerError("iiop.StubGenerator: No remote interfaces!");
  1531         result = new RemoteType[remoteCount];
  1532         int offset = 0;
  1533         for (int i = 0; i < list.length; i++) {
  1534             if (list[i].isType(TYPE_REMOTE)) {
  1535                 result[offset++] = (RemoteType)list[i];
  1539         return result;
  1542     int countRemote (Type[] list, boolean includeAbstract) {
  1543         int remoteCount = 0;
  1544         for (int i = 0; i < list.length; i++) {
  1545             if (list[i].isType(TYPE_REMOTE) &&
  1546                 (includeAbstract || !list[i].isType(TYPE_ABSTRACT))) {
  1547                 remoteCount++;
  1551         return remoteCount;
  1554     void writeCastArray(IndentingWriter p) throws IOException {
  1555         if (castArray) {
  1556             p.pln();
  1557             p.pln("// This method is required as a work-around for");
  1558             p.pln("// a bug in the JDK 1.1.6 verifier.");
  1559             p.pln();
  1560             p.plnI("private "+getName(idJavaIoSerializable)+" cast_array(Object obj) {");
  1561             p.pln("return ("+getName(idJavaIoSerializable)+")obj;");
  1562             p.pOln("}");
  1565     void writeIds(IndentingWriter p, CompoundType theType, boolean isTie
  1566                   ) throws IOException {
  1567         p.plnI("private static final String[] _type_ids = {");
  1569         String[] ids = getAllRemoteRepIDs(theType);
  1571         if (ids.length >0 ) {
  1572             for(int i = 0; i < ids.length; i++) {
  1573                 if (i > 0)
  1574                     p.pln(", ");
  1575                 p.p("\"" + ids[i] + "\"");
  1577         } else {
  1578            // Must be an implementation which only implements Remote...
  1579            p.pln("\"\"");
  1581         String qname = theType.getQualifiedName() ;
  1582         boolean isTransactional = isTie && transactionalObjects.containsKey( qname ) ;
  1583         // Add TransactionalObject if needed.
  1584         if (isTransactional) {
  1585             // Have already written an id.
  1586             p.pln( ", " ) ;
  1587             p.pln( "\"IDL:omg.org/CosTransactions/TransactionalObject:1.0\"" ) ;
  1588         } else if (ids.length > 0) {
  1589             p.pln();
  1591         p.pOln("};");
  1595     /**
  1596      * Write the Tie for the remote class to a stream.
  1597      */
  1598     protected void writeTie(OutputType outputType,
  1599                             IndentingWriter p) throws IOException
  1601         CompoundType theType = (CompoundType) outputType.getType();
  1602         RemoteType[] remoteInterfaces = null;
  1604         // Write comment...
  1605         p.pln("// Tie class generated by rmic, do not edit.");
  1606         p.pln("// Contents subject to change without notice.");
  1607         p.pln();
  1609         // Set our standard classes...
  1610         setStandardClassesInUse(theType,false);
  1612         // Add classes for this type...
  1613         addClassesInUse(theType,remoteInterfaces);
  1615         // Write package and import statements...
  1616         writePackageAndImports(p);
  1618         // Declare the tie class.
  1619         p.p("public class " + currentClass + " extends " +
  1620             getName(tieBaseClass) + " implements Tie");
  1622         // Add java.rmi.Remote if this type does not implement it.
  1623         // This allows stubs for Abstract interfaces to be treated
  1624         // uniformly...
  1625         if (!implementsRemote(theType)) {
  1626             p.pln(",");
  1627             p.p(getName("java.rmi.Remote"));
  1630         p.plnI(" {");
  1632         // Write data members...
  1633         p.pln();
  1634         p.pln("private " + getName(theType) + " target = null;");
  1635         p.pln();
  1637         // Write the ids...
  1638         writeIds( p, theType, true ) ;
  1640         // Write setTarget method...
  1641         p.pln();
  1642         p.plnI("public void setTarget(Remote target) {");
  1643         p.pln("this.target = (" + getName(theType) + ") target;");
  1644         p.pOln("}");
  1646         // Write getTarget method...
  1647         p.pln();
  1648         p.plnI("public Remote getTarget() {");
  1649         p.pln("return target;");
  1650         p.pOln("}");
  1652         // Write thisObject method...
  1653         p.pln();
  1654         write_tie_thisObject_method(p,idCorbaObject);
  1656         // Write deactivate method...
  1657         p.pln();
  1658         write_tie_deactivate_method(p);
  1660         // Write get orb method...
  1661         p.pln();
  1662         p.plnI("public ORB orb() {");
  1663         p.pln("return _orb();");
  1664         p.pOln("}");
  1666         // Write set orb method...
  1667         p.pln();
  1668         write_tie_orb_method(p);
  1670         // Write the _ids() method...
  1671         p.pln();
  1672         write_tie__ids_method(p);
  1674         // Get all the methods...
  1675         CompoundType.Method[] remoteMethods = theType.getMethods();
  1677         // Register all the argument names used, plus our
  1678         // data member names...
  1680         addNamesInUse(remoteMethods);
  1681         addNameInUse("target");
  1682         addNameInUse("_type_ids");
  1684         // Write the _invoke method...
  1685         p.pln();
  1687         String in = getVariableName("in");
  1688         String _in = getVariableName("_in");
  1689         String ex = getVariableName("ex");
  1690         String method = getVariableName("method");
  1691         String reply = getVariableName("reply");
  1693         p.plnI("public OutputStream  _invoke(String "+method+", InputStream "+_in+", " +
  1694                "ResponseHandler "+reply+") throws SystemException {");
  1696         if (remoteMethods.length > 0) {
  1697             p.plnI("try {");
  1698             p.plnI(idExtInputStream + " "+in+" = ");
  1699             p.pln("(" + idExtInputStream + ") "+_in+";");
  1700             p.pO();
  1702             // See if we should use a hash table style
  1703             // comparison...
  1705             StaticStringsHash hash = getStringsHash(remoteMethods);
  1707             if (hash != null) {
  1708                 p.plnI("switch ("+method+"."+hash.method+") {");
  1709                 for (int i = 0; i < hash.buckets.length; i++) {
  1710                     p.plnI("case "+hash.keys[i]+": ");
  1711                     for (int j = 0; j < hash.buckets[i].length; j++) {
  1712                         CompoundType.Method current = remoteMethods[hash.buckets[i][j]];
  1713                         if (j > 0) {
  1714                             p.pO("} else ");
  1716                         p.plnI("if ("+method+".equals(\""+ current.getIDLName() +"\")) {");
  1717                         writeTieMethod(p, theType,current);
  1719                     p.pOln("}");
  1720                     p.pO();
  1722             } else {
  1723                 for(int i = 0; i < remoteMethods.length; i++) {
  1724                 CompoundType.Method current = remoteMethods[i];
  1725                 if (i > 0) {
  1726                     p.pO("} else ");
  1729                 p.plnI("if ("+method+".equals(\""+ current.getIDLName() +"\")) {");
  1730                 writeTieMethod(p, theType, current);
  1734             if (hash != null) {
  1735                 p.pI();
  1736                 //        p.plnI("default:");
  1737             } else {
  1738                 //   p.pOlnI("} else {");
  1740             //              p.pln("throw new "+getName(idBadMethodException)+"();");
  1742             if (hash != null) {
  1743                 p.pO();
  1745             p.pOln("}");
  1746             p.pln("throw new "+getName(idBadMethodException)+"();");
  1748             p.pOlnI("} catch ("+getName(idSystemException)+" "+ex+") {");
  1749             p.pln("throw "+ex+";");
  1751             p.pOlnI("} catch ("+getName(idJavaLangThrowable)+" "+ex+") {");
  1752             p.pln("throw new " + getName(idPortableUnknownException) + "("+ex+");");
  1753             p.pOln("}");
  1754         } else {
  1755             // No methods...
  1757             p.pln("throw new " + getName(idBadMethodException) + "();");
  1760         p.pOln("}");            // end invoke
  1762         // Write the cast array hack...
  1764         writeCastArray(p);
  1766         // End tie class...
  1767         p.pOln("}");
  1769     public void catchWrongPolicy(IndentingWriter p) throws IOException {
  1770         p.pln("");
  1772     public void catchServantNotActive(IndentingWriter p) throws IOException {
  1773         p.pln("");
  1775     public void catchObjectNotActive(IndentingWriter p) throws IOException {
  1776         p.pln("");
  1779     public void write_tie_thisObject_method(IndentingWriter p,
  1780                                             Identifier idCorbaObject)
  1781         throws IOException
  1783         if(POATie){
  1784             p.plnI("public " + idCorbaObject + " thisObject() {");
  1785             /*
  1786             p.pln("org.omg.CORBA.Object objref = null;");
  1787             p.pln("try{");
  1788             p.pln("objref = _poa().servant_to_reference(this);");
  1789             p.pln("}catch (org.omg.PortableServer.POAPackage.WrongPolicy exception){");
  1790             catchWrongPolicy(p);
  1791             p.pln("}catch (org.omg.PortableServer.POAPackage.ServantNotActive exception){");
  1792             catchServantNotActive(p);
  1793             p.pln("}");
  1794             p.pln("return objref;");
  1795             */
  1796             p.pln("return _this_object();");
  1797             p.pOln("}");
  1798         } else {
  1799             p.plnI("public " + idCorbaObject + " thisObject() {");
  1800             p.pln("return this;");
  1801             p.pOln("}");
  1805     public void write_tie_deactivate_method(IndentingWriter p)
  1806         throws IOException
  1808         if(POATie){
  1809             p.plnI("public void deactivate() {");
  1810             p.pln("try{");
  1811             p.pln("_poa().deactivate_object(_poa().servant_to_id(this));");
  1812             p.pln("}catch (org.omg.PortableServer.POAPackage.WrongPolicy exception){");
  1813             catchWrongPolicy(p);
  1814             p.pln("}catch (org.omg.PortableServer.POAPackage.ObjectNotActive exception){");
  1815             catchObjectNotActive(p);
  1816             p.pln("}catch (org.omg.PortableServer.POAPackage.ServantNotActive exception){");
  1817             catchServantNotActive(p);
  1818             p.pln("}");
  1819             p.pOln("}");
  1820         } else {
  1821             p.plnI("public void deactivate() {");
  1822             p.pln("_orb().disconnect(this);");
  1823             p.pln("_set_delegate(null);");
  1824             p.pln("target = null;");
  1825             p.pOln("}");
  1829     public void write_tie_orb_method(IndentingWriter p)
  1830         throws IOException
  1832         if(POATie){
  1833         p.plnI("public void orb(ORB orb) {");
  1834         /*
  1835         p.pln("try{");
  1836         p.pln("orb.connect(_poa().servant_to_reference(this));");
  1837         p.pln("}catch (org.omg.PortableServer.POAPackage.WrongPolicy exception){");
  1838         catchWrongPolicy(p);
  1839         p.pln("}catch (org.omg.PortableServer.POAPackage.ServantNotActive exception){");
  1840         catchServantNotActive(p);
  1841         p.pln("}");
  1842         */
  1843         p.pln("try {");
  1844         p.pln("    ((org.omg.CORBA_2_3.ORB)orb).set_delegate(this);");
  1845         p.pln("}");
  1846         p.pln("catch(ClassCastException e) {");
  1847         p.pln("    throw new org.omg.CORBA.BAD_PARAM");
  1848         p.pln("        (\"POA Servant requires an instance of org.omg.CORBA_2_3.ORB\");");
  1849         p.pln("}");
  1850         p.pOln("}");
  1851         } else {
  1852         p.plnI("public void orb(ORB orb) {");
  1853         p.pln("orb.connect(this);");
  1854         p.pOln("}");
  1858     public void write_tie__ids_method(IndentingWriter p)
  1859         throws IOException
  1861         if(POATie){
  1862         p.plnI("public String[] _all_interfaces(org.omg.PortableServer.POA poa, byte[] objectId){");
  1863         p.pln("return (String[]) _type_ids.clone();");
  1864         p.pOln("}");
  1865         } else {
  1866         p.plnI("public String[] _ids() { ");
  1867         p.pln("return (String[]) _type_ids.clone();");
  1868         p.pOln("}");
  1873     StaticStringsHash getStringsHash (CompoundType.Method[] methods) {
  1874         if (useHash && methods.length > 1) {
  1875             String[] methodNames = new String[methods.length];
  1876             for (int i = 0; i < methodNames.length; i++) {
  1877                 methodNames[i] = methods[i].getIDLName();
  1879             return new StaticStringsHash(methodNames);
  1881         return null;
  1884     static boolean needNewReadStreamClass(Type type) {
  1885         if (type.isType(TYPE_ABSTRACT)) {
  1886             return true;
  1888         // Handle late-breaking special case for
  1889         // abstract IDL entities...
  1890         if ((type instanceof CompoundType) &&
  1891             ((CompoundType)type).isAbstractBase()) {
  1892             return true;
  1894         return needNewWriteStreamClass(type);
  1897     static boolean needNewWriteStreamClass(Type type) {
  1898         switch (type.getTypeCode()) {
  1899         case TYPE_VOID:
  1900         case TYPE_BOOLEAN:
  1901         case TYPE_BYTE:
  1902         case TYPE_CHAR:
  1903         case TYPE_SHORT:
  1904         case TYPE_INT:
  1905         case TYPE_LONG:
  1906         case TYPE_FLOAT:
  1907         case TYPE_DOUBLE:           return false;
  1909         case TYPE_STRING:           return true;
  1910         case TYPE_ANY:              return false;
  1911         case TYPE_CORBA_OBJECT:     return false;
  1912         case TYPE_REMOTE:           return false;
  1913         case TYPE_ABSTRACT:         return false;
  1914         case TYPE_NC_INTERFACE:     return true;
  1915         case TYPE_VALUE:            return true;
  1916         case TYPE_IMPLEMENTATION:   return true;
  1917         case TYPE_NC_CLASS:         return true;
  1918         case TYPE_ARRAY:            return true;
  1919         case TYPE_JAVA_RMI_REMOTE:  return false;
  1921         default: throw new Error("unexpected type code: " + type.getTypeCode());
  1925     /*
  1926      * Decide which arguments need to be copied and write
  1927      * the copy code. Returns an array of argument names to
  1928      * use to refer to either the copy or the original.
  1929      */
  1930     String[] writeCopyArguments(CompoundType.Method method,
  1931                                 IndentingWriter p) throws IOException {
  1933         Type[] args = method.getArguments();
  1934         String[] origNames = method.getArgumentNames();
  1936         // Copy the current parameter names to a result array...
  1938         String[] result = new String[origNames.length];
  1939         for (int i = 0; i < result.length; i++) {
  1940             result[i] = origNames[i];
  1943         // Decide which arguments must be copied, if any. If
  1944         // any of the arguments are types for which a 'real' copy
  1945         // will be done, rather than just an autoConnect, set
  1946         // realCopy = true. Note that abstract types may only
  1947         // need autoConnect, but we cannot know that at compile
  1948         // time...
  1950         boolean realCopy = false;
  1951         boolean[] copyArg = new boolean[args.length];
  1952         int copyCount = 0;
  1953         int firstCopiedArg = 0; // Only used in single copy case.  It is only the first arg that
  1954                                 // needs copying IF copyCount == 1.
  1956         for (int i = 0; i < args.length; i++) {
  1957             if (mustCopy(args[i])) {
  1958                 copyArg[i] = true;
  1959                 copyCount++;
  1960                 firstCopiedArg = i;
  1961                 if (args[i].getTypeCode() != TYPE_REMOTE &&
  1962                     args[i].getTypeCode() != TYPE_IMPLEMENTATION) {
  1963                     realCopy = true;
  1965             } else {
  1966                 copyArg[i] = false;
  1970         // Do we have any types which must be copied?
  1971         if (copyCount > 0) {
  1972             // Yes. Are we only doing the copy to ensure
  1973             // that autoConnect occurs?
  1974             if (realCopy) {
  1975                 // Nope. We need to go back thru the list and
  1976                 // mark any strings so that they will be copied
  1977                 // to preserve any shared references...
  1978                 for (int i = 0; i < args.length; i++) {
  1979                     if (args[i].getTypeCode() == TYPE_STRING) {
  1980                         copyArg[i] = true;
  1981                         copyCount++;
  1986             // We're ready to generate code. Do we have more than
  1987             // one to copy?
  1988             if (copyCount > 1) {
  1989                 // Generate a call to copyObjects...
  1990                 String arrayName = getVariableName("copies");
  1991                 p.p("Object[] " + arrayName + " = Util.copyObjects(new Object[]{");
  1992                 boolean first = true;
  1993                 for (int i = 0; i < args.length; i++) {
  1994                     if (copyArg[i]) {
  1995                         if (!first) {
  1996                             p.p(",");
  1998                         first = false;
  1999                         p.p(origNames[i]);
  2002                 p.pln("},_orb());");
  2004                 // For each of the types which was copied, create
  2005                 // a local temporary for it, updating the result
  2006                 // array with the new local parameter name...
  2007                 int copyIndex = 0 ;
  2008                 for (int i = 0; i < args.length; i++) {
  2009                     if (copyArg[i]) {
  2010                         result[i] = getVariableName(result[i]+"Copy");
  2011                         p.pln( getName(args[i]) + " " + result[i] + " = (" + getName(args[i]) + ") " +
  2012                                arrayName + "[" + copyIndex++ +"];");
  2015             } else {
  2016                 // Generate a call to copyObject, updating the result
  2017                 // with the new local parameter name...
  2018                 result[firstCopiedArg] = getVariableName(result[firstCopiedArg]+"Copy");
  2019                 p.pln( getName(args[firstCopiedArg]) + " " + result[firstCopiedArg] + " = (" +
  2020                        getName(args[firstCopiedArg]) + ") Util.copyObject(" +
  2021                        origNames[firstCopiedArg] + ",_orb());");
  2025         return result;
  2028     static final String SINGLE_SLASH = "\\";
  2029     static final String DOUBLE_SLASH = SINGLE_SLASH + SINGLE_SLASH;
  2031     String getRepositoryID(Type type) {
  2032         return IDLNames.replace(type.getRepositoryID(), SINGLE_SLASH, DOUBLE_SLASH);
  2035     String getExceptionRepositoryID(Type type) {
  2036         ClassType theType = (ClassType) type;
  2037         return IDLNames.getIDLRepositoryID(theType.getQualifiedIDLExceptionName(false));
  2040     String getVariableName(String proposed) {
  2041         while (namesInUse.contains(proposed)) {
  2042             proposed = "$" + proposed;
  2045         return proposed;
  2048     void addNamesInUse(CompoundType.Method[] methods) {
  2049         for (int i = 0; i < methods.length; i++) {
  2050             addNamesInUse(methods[i]);
  2054     void addNamesInUse(CompoundType.Method method) {
  2055         String paramNames[] = method.getArgumentNames();
  2056         for (int i = 0; i < paramNames.length; i++) {
  2057             addNameInUse(paramNames[i]);
  2061     void addNameInUse(String name) {
  2062         namesInUse.add(name);
  2065     static boolean mustCopy(Type type) {
  2066         switch (type.getTypeCode()) {
  2067         case TYPE_VOID:
  2068         case TYPE_BOOLEAN:
  2069         case TYPE_BYTE:
  2070         case TYPE_CHAR:
  2071         case TYPE_SHORT:
  2072         case TYPE_INT:
  2073         case TYPE_LONG:
  2074         case TYPE_FLOAT:
  2075         case TYPE_DOUBLE:
  2076         case TYPE_STRING:           return false;
  2078         case TYPE_ANY:              return true;
  2080         case TYPE_CORBA_OBJECT:     return false;
  2082         case TYPE_REMOTE:
  2083         case TYPE_ABSTRACT:
  2084         case TYPE_NC_INTERFACE:
  2085         case TYPE_VALUE:
  2086         case TYPE_IMPLEMENTATION:
  2087         case TYPE_NC_CLASS:
  2088         case TYPE_ARRAY:
  2089         case TYPE_JAVA_RMI_REMOTE:  return true;
  2091         default: throw new Error("unexpected type code: " + type.getTypeCode());
  2095     ValueType[] getStubExceptions (CompoundType.Method method, boolean sort) {
  2097         ValueType[] list = method.getFilteredStubExceptions(method.getExceptions());
  2099         // Sort the list so that all org.omg.CORBA.UserException
  2100         // subtypes are at the beginning of the list.  This ensures
  2101         // that the stub will not call read_string() before calling
  2102         // XXHelper.read().
  2104         if (sort) {
  2105             Arrays.sort(list,new UserExceptionComparator());
  2108         return list;
  2111     ValueType[] getTieExceptions (CompoundType.Method method) {
  2112         return method.getUniqueCatchList(method.getImplExceptions());
  2115     void writeTieMethod(IndentingWriter p, CompoundType type,
  2116                         CompoundType.Method method) throws IOException {
  2117         String methodName = method.getName();
  2118         Type paramTypes[] = method.getArguments();
  2119         String paramNames[] = method.getArgumentNames();
  2120         Type returnType = method.getReturnType();
  2121         ValueType[] exceptions = getTieExceptions(method);
  2122         String in = getVariableName("in");
  2123         String ex = getVariableName("ex");
  2124         String out = getVariableName("out");
  2125         String reply = getVariableName("reply");
  2127         for (int i = 0; i < paramTypes.length; i++) {
  2128             p.p(getName(paramTypes[i])+" "+paramNames[i]+" = ");
  2129             writeUnmarshalArgument(p, in, paramTypes[i], null);
  2130             p.pln();
  2133         boolean handleExceptions = exceptions != null;
  2134         boolean doReturn = !returnType.isType(TYPE_VOID);
  2136         if (handleExceptions && doReturn) {
  2137             String objName = testUtil(getName(returnType), returnType);
  2138             p.pln(objName+" result;");
  2141         if (handleExceptions)
  2142             p.plnI("try {");
  2144         if (doReturn) {
  2145             if (handleExceptions) {
  2146                 p.p("result = ");
  2147             } else {
  2148                 p.p(getName(returnType)+" result = ");
  2152         p.p("target."+methodName+"(");
  2153         for(int i = 0; i < paramNames.length; i++) {
  2154             if (i > 0)
  2155                 p.p(", ");
  2156             p.p(paramNames[i]);
  2158         p.pln(");");
  2160         if (handleExceptions) {
  2161             for(int i = 0; i < exceptions.length; i++) {
  2162                 p.pOlnI("} catch ("+getName(exceptions[i])+" "+ex+") {");
  2164                 // Is this our IDLEntity Exception special case?
  2166                 if (exceptions[i].isIDLEntityException() && !exceptions[i].isCORBAUserException()) {
  2168                                 // Yes...
  2170                     String helperName = IDLNames.replace(exceptions[i].getQualifiedIDLName(false),"::",".");
  2171                     helperName += "Helper";
  2172                     p.pln(idOutputStream+" "+out +" = "+reply+".createExceptionReply();");
  2173                     p.pln(helperName+".write("+out+","+ex+");");
  2175                 } else {
  2177                                 // No...
  2179                     p.pln("String id = \"" + getExceptionRepositoryID(exceptions[i]) + "\";");
  2180                 p.plnI(idExtOutputStream + " "+out+" = ");
  2181                 p.pln("(" + idExtOutputStream + ") "+reply+".createExceptionReply();");
  2182                 p.pOln(out+".write_string(id);");
  2183                     p.pln(out+".write_value("+ex+"," + getName(exceptions[i]) + ".class);");
  2186                 p.pln("return "+out+";");
  2188             p.pOln("}");
  2191         if (needNewWriteStreamClass(returnType)) {
  2192             p.plnI(idExtOutputStream + " "+out+" = ");
  2193             p.pln("(" + idExtOutputStream + ") "+reply+".createReply();");
  2194             p.pO();
  2195         } else {
  2196             p.pln("OutputStream "+out+" = "+reply+".createReply();");
  2199         if (doReturn) {
  2200             writeMarshalArgument(p, out, returnType, "result");
  2201             p.pln();
  2204         p.pln("return "+out+";");
  2208     /**
  2209      * Write Java statements to marshal a series of values in order as
  2210      * named in the "names" array, with types as specified in the "types"
  2211      * array", to the java.io.ObjectOutput stream named "stream".
  2212      */
  2213     void writeMarshalArguments(IndentingWriter p,
  2214                                String streamName,
  2215                                Type[] types, String[] names)
  2216         throws IOException
  2218         if (types.length != names.length) {
  2219             throw new Error("paramter type and name arrays different sizes");
  2222         for (int i = 0; i < types.length; i++) {
  2223             writeMarshalArgument(p, streamName, types[i], names[i]);
  2224             if (i != types.length -1) {
  2225                 p.pln();
  2230     /**
  2231      * Added for IASRI 4987274. Remote classes named "Util" were
  2232      * getting confused with javax.rmi.CORBA.Util and the
  2233      * unqualifiedName "Util".
  2234      */
  2235     String testUtil(String objectName, Type ttype) {
  2236         if (objectName.equals("Util")) {
  2237                 String correctedName = (String)ttype.getPackageName() + "." + objectName;
  2238                 return correctedName;
  2239         } else {
  2240                 return objectName;
  2245 class StringComparator implements java.util.Comparator {
  2246     public int compare(Object o1, Object o2) {
  2247         String s1 = (String)o1;
  2248         String s2 = (String)o2;
  2249         return s1.compareTo(s2);
  2254 class UserExceptionComparator implements java.util.Comparator {
  2255     public int compare(Object o1, Object o2) {
  2256         ValueType v1 = (ValueType)o1;
  2257         ValueType v2 = (ValueType)o2;
  2258         int result = 0;
  2259         if (isUserException(v1)) {
  2260             if (!isUserException(v2)) {
  2261                 result = -1;
  2263         } else if (isUserException(v2)) {
  2264             if (!isUserException(v1)) {
  2265                 result = 1;
  2268         return result;
  2271     final boolean isUserException(ValueType it) {
  2272         return it.isIDLEntityException() && !it.isCORBAUserException();

mercurial