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

Wed, 27 Apr 2016 01:21:28 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:21:28 +0800
changeset 0
7ef37b2cdcad
child 748
6845b95cba6b
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/corba/
changeset: 765:f46df0af2ca8
tag: jdk8u25-b17

     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  */
    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.io.SerializablePermission;
    38 import java.security.AccessController;
    39 import java.security.PrivilegedAction;
    40 import java.util.Vector;
    41 import java.util.Hashtable;
    42 import java.util.Enumeration;
    43 import sun.tools.java.Identifier;
    44 import sun.tools.java.ClassNotFound;
    45 import sun.tools.java.ClassDefinition;
    46 import sun.tools.java.ClassDeclaration;
    47 import sun.tools.java.CompilerError;
    48 import sun.rmi.rmic.IndentingWriter;
    49 import java.util.HashSet;
    50 import java.util.Arrays;
    51 import com.sun.corba.se.impl.util.Utility;
    52 import com.sun.corba.se.impl.util.PackagePrefixChecker;
    53 import sun.rmi.rmic.Main;
    56 /**
    57  * An IIOP stub/tie generator for rmic.
    58  *
    59  * @author      Bryan Atsatt
    60  * @author      Anil Vijendran
    61  * @author      M. Mortazavi
    62  */
    64 public class StubGenerator extends sun.rmi.rmic.iiop.Generator {
    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";
    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;
    87     /**
    88      * Default constructor for Main to use.
    89      */
    90     public StubGenerator() {
    91     }
    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     }
   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     }
   114     /**
   115      * Return true if non-conforming types should be parsed.
   116      * @param stack The context stack.
   117      */
   118     protected boolean parseNonConforming(ContextStack stack) {
   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...
   124         return stack.getEnv().getParseNonConforming();
   125     }
   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) {
   135         CompoundType result = null;
   137         // Do we have an interface?
   139         if (cdef.isInterface()) {
   141             // Yes, so first try Abstract...
   143             result = AbstractType.forAbstract(cdef,stack,true);
   145             if (result == null) {
   147                 // Then try Remote...
   149                 result = RemoteType.forRemote(cdef,stack,false);
   150             }
   151         } else {
   153             // Not an interface, so try Implementation...
   155             result = ImplementationType.forImplementation(cdef,stack,false);
   156         }
   158         return result;
   159     }
   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() ;
   171         // Reset any cached options...
   173         reverseIDs = false;
   174         localStubs = true;
   175         useHash = true;
   176         stubBaseClass = DEFAULT_STUB_CLASS;
   177         //       tieBaseClass = DEFAULT_TIE_CLASS;
   178         transactionalObjects = new Hashtable() ;
   180         // Parse options...
   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     }
   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) {
   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...
   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();
   273         // Now walk all types...
   275         for (int i = 0; i < genTypes.length; i++) {
   277             Type type = genTypes[i];
   278             String typeName = type.getName();
   279             boolean createStub = true;
   281             // Is it an implementation type?
   283             if (type instanceof ImplementationType) {
   285                 // Yes, so add a tie for it...
   287                 list.addElement(new OutputType(Utility.tieNameForCompiler(typeName), type));
   289                 // Does it have more than 1 remote interface?  If so, we
   290                 // want to create a stub for it...
   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                 }
   301                 if (remoteInterfaceCount <= 1) {
   303                     // No, so do not create a stub for this type...
   305                     createStub = false;
   306                 }
   307             }
   309             // Is it an abstract interface type?
   311             if (type instanceof AbstractType) {
   313                 // Do not create a stub for this type...
   315                 createStub = false;  // d11141
   316             }
   318             if (createStub) {
   320                 // Add a stub for the type...
   322                 list.addElement(new OutputType(Utility.stubNameForCompiler(typeName), type));
   323             }
   324         }
   326         // Copy list into array..
   328         OutputType[] outputTypes = new OutputType[list.size()];
   329         list.copyInto(outputTypes);
   330         return outputTypes;
   331     }
   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     }
   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 {
   355         String fileName = outputType.getName();
   356         CompoundType theType = (CompoundType) outputType.getType();
   358         // Are we doing a Stub or Tie?
   360         if (fileName.endsWith(Utility.RMI_STUB_SUFFIX)) {
   362             // Stub.
   364             writeStub(outputType,writer);
   366         } else {
   368             // Tie
   370             writeTie(outputType,writer);
   371         }
   372     }
   374     /**
   375      * Write a stub for the specified type.
   376      */
   377     protected void writeStub(OutputType outputType,
   378                              IndentingWriter p) throws IOException {
   380         CompoundType theType = (CompoundType) outputType.getType();
   381         RemoteType[] remoteInterfaces = getDirectRemoteInterfaces(theType);
   383         // Write comment.
   385         p.pln("// Stub class generated by rmic, do not edit.");
   386         p.pln("// Contents subject to change without notice.");
   387         p.pln();
   389         // Set our standard classes...
   391         setStandardClassesInUse(theType,true);
   393         // Add classes for this type...
   395         addClassesInUse(theType,remoteInterfaces);
   397         // Write package and import statements...
   399         writePackageAndImports(p);
   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         }
   413         // Declare the stub class; implement all remote interfaces.
   415         p.p("public class " + currentClass);
   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         }
   429         // Add java.rmi.Remote if this type does not implement it.
   430         // This allows stubs for Abstract interfaces to be treated
   431         // uniformly...
   433         if (!implementsRemote(theType)) {
   434             p.pln(",");
   435             p.p(getName("java.rmi.Remote"));
   436         }
   438         p.plnI(" {");
   439         p.pln();
   441         // Write the ids...
   443         writeIds( p, theType, false );
   444         p.pln();
   446         if (emitPermissionCheck) {
   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
   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();
   483                 p.pI();
   484                 p.pln("private " + currentClass + "(Void ignore) {  }");
   485                 p.pln();
   487                 p.plnI("public " + currentClass + "() { ");
   488                 p.pln("this(checkPermission());");
   489                 p.pOln("}");
   490                 p.pln();
   491         }
   493        if (!emitPermissionCheck) {
   494             p.pI();
   495        }
   497         // Write the _ids() method...
   499         p.plnI("public String[] _ids() { ");
   500         p.pln("return (String[]) _type_ids.clone();");
   501         p.pOln("}");
   503         // Get all the methods and write each stub method...
   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         }
   520         // Write the cast array hack...
   522         writeCastArray(p);
   524         p.pOln("}");            // end stub class
   525     }
   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     }
   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     }
   553     void addClassInUse(Type[] types) {
   554         for (int i = 0; i < types.length; i++) {
   555             addClassInUse(types[i]);
   556         }
   557     }
   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     }
   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     }
   594     void addStubInUse(Type[] types) {
   595         for (int i = 0; i < types.length; i++) {
   596             addStubInUse(types[i]);
   597         }
   598     }
   600     private static final String NO_IMPORT = new String();
   602     void addClassInUse(String unqualifiedName, String qualifiedName, String packageName) {
   604         // Have we already got an entry for this qualifiedName?
   606         String currentName = (String)classesInUse.get(qualifiedName);
   608         if (currentName == null) {
   610             // No, never seen it before. Grab any existing import
   611             // name and then decide what to do...
   613             String importName = (String) imports.get(unqualifiedName);
   614             String nameToUse = null;
   616             if (packageName == null) {
   618                 // Default package, so doesn't matter which name to use...
   620                 nameToUse = unqualifiedName;
   622             } else if (packageName.equals("java.lang")) {
   624                 // java.lang.*, so use unqualified name...
   626                 nameToUse = unqualifiedName;
   628                 // unless you want to be able to import things from the right place :--)
   630                 if(nameToUse.endsWith("_Stub")) nameToUse = Util.packagePrefix()+qualifiedName;
   632             } else if (currentPackage != null && packageName.equals(currentPackage)) {
   634                 // Class in currentPackage, so use unqualified name...
   636                 nameToUse = unqualifiedName;
   638                 // Do we already have a previous import under this
   639                 // unqualified name?
   641                 if (importName != null) {
   643                     // Yes, so we use qualifiedName...
   645                     nameToUse = qualifiedName;
   647                 }
   649             } else if (importName != null) {
   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...
   656                 nameToUse = qualifiedName;
   658                 /*
   659                   // Is the currentPackage the default package?
   661                   if (currentPackage == null) {
   663                   // Yes, so undo the import so that all
   664                   // uses for this name will be qualified...
   666                   String old = (String)imports.remove(unqualifiedName);
   667                   classesInUse.put(old,old);
   668                   importCount--;
   670                   // Note that this name is in use but should
   671                   // not be imported...
   673                   imports.put(nameToUse,NO_IMPORT);
   674                   }
   675                 */
   676             } else if (qualifiedName.equals("org.omg.CORBA.Object")) {
   678                 // Always qualify this quy to avoid confusion...
   680                 nameToUse = qualifiedName;
   682             } else {
   684                 // Default to using unqualified name, and add
   685                 // this guy to the imports...
   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             }
   698             // Now add the name...
   700             classesInUse.put(qualifiedName,nameToUse);
   701         }
   702     }
   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     }
   713     // Added for Bug 4818753
   714     String getExceptionName(Type type) {
   715         Identifier id = type.getIdentifier();
   716         return IDLNames.replace(id.toString(),". ",".");
   717     }
   719     String getName(String qualifiedName) {
   720         return (String)classesInUse.get(qualifiedName);
   721     }
   723     String getName(Identifier id) {
   724         return getName(id.toString());
   725     }
   727     String getStubName(Type type) {
   728         String stubName = getStubNameFor(type,true);
   729         return getName(stubName);
   730     }
   732     void setStandardClassesInUse(CompoundType type,
   733                                  boolean stub) throws IOException {
   735         // Reset our state...
   737         currentPackage = type.getPackageName();
   738         imports.clear();
   739         classesInUse.clear();
   740         namesInUse.clear();
   741         importCount = 0;
   742         castArray = false;
   744         // Add the top-level type...
   746         addClassInUse(type);
   748         // Set current class name...
   750         if (stub) {
   751             currentClass = Utility.stubNameForCompiler(type.getName());
   752         } else {
   753             currentClass = Utility.tieNameForCompiler(type.getName());
   754         }
   756         // Add current class...
   758         if (currentPackage == null) {
   759             addClassInUse(currentClass,currentClass,currentPackage);
   760         } else {
   761             addClassInUse(currentClass,(currentPackage+"."+currentClass),currentPackage);
   762         }
   764         // Add standard classes...
   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());
   776         // Add stub/tie specific imports...
   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     }
   796     void addClassesInUse(CompoundType type, RemoteType[] interfaces) {
   798         // Walk all methods and add types in use...
   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         }
   811         // If this is a stub, add all interfaces...
   813         if (interfaces != null) {
   814             addClassInUse(interfaces);
   815         }
   816     }
   818     void writePackageAndImports(IndentingWriter p) throws IOException {
   820         // Write package declaration...
   822         if (currentPackage != null) {
   823             p.pln("package " +
   824                      Util.correctPackageName(
   825                           currentPackage, false, standardPackage)
   826                    + ";");
   827             p.pln();
   828         }
   830         // Get imports into an array and sort them...
   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         }
   841         Arrays.sort(names,new StringComparator());
   843         // Now dump them out...
   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();
   858         // Include offending packages . . .
   859         if ( currentPackage!=null && Util.isOffendingPackage(currentPackage) ){
   860             p.pln("import " + currentPackage +".*  ;");
   861         }
   862         p.pln();
   864     }
   866     boolean implementsRemote(CompoundType theType) {
   867         boolean result = theType.isType(TYPE_REMOTE) && !theType.isType(TYPE_ABSTRACT);
   869         // If theType is not remote, look at all the interfaces
   870         // until we find one that is...
   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         }
   882         return result;
   883     }
   885     void writeStubMethod (  IndentingWriter p,
   886                             CompoundType.Method method,
   887                             CompoundType theType) throws IOException {
   889         // Wtite the method declaration and opening brace...
   890         String methodName = method.getName();
   891         String methodIDLName = method.getIDLName();
   893         Type paramTypes[] = method.getArguments();
   894         String paramNames[] = method.getArgumentNames();
   895         Type returnType = method.getReturnType();
   896         ValueType[] exceptions = getStubExceptions(method,false);
   898         addNamesInUse(method);
   899         addNameInUse("_type_ids");
   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         }
   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         }
   921         p.plnI(" {");
   923         // Now create the method body...
   925         if (localStubs) {
   926             writeLocalStubMethodBody(p,method,theType);
   927         } else {
   928             writeNonLocalStubMethodBody(p,method,theType);
   929         }
   931         // Close out the method...
   933         p.pOln("}");
   934     }
   937     void writeLocalStubMethodBody (IndentingWriter p,
   938                                    CompoundType.Method method,
   939                                    CompoundType theType) throws IOException {
   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();
   948         p.plnI("if (!Util.isLocal(this)) {");
   949         writeNonLocalStubMethodBody(p,method,theType);
   950         p.pOlnI("} else {");
   951         String so = getVariableName("so");
   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         }
   969         p.pOln("}");
   970         p.plnI("try {");
   972         // Generate code to copy required arguments, and
   973         // get back the names by which all arguments are known...
   975         String[] argNames = writeCopyArguments(method,p);
   977         // Now write the method...
   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+"(");
   993         for (int i = 0; i < argNames.length; i++) {
   994             if (i > 0)
   995                 p.p(", ");
   996             p.p(argNames[i]);
   997         }
   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(");");
  1007         String e1 = getVariableName("ex");
  1008         String e2 = getVariableName("exCopy");
  1009         p.pOlnI("} catch (Throwable "+e1+") {");
  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("}");
  1022         p.pln("throw Util.wrapException("+e2+");");
  1023         p.pOlnI("} finally {");
  1024         p.pln("_servant_postinvoke("+so+");");
  1025         p.pOln("}");
  1026         p.pOln("}");
  1030     void writeNonLocalStubMethodBody (  IndentingWriter p,
  1031                                         CompoundType.Method method,
  1032                                         CompoundType theType) throws IOException {
  1034         String methodName = method.getName();
  1035         String methodIDLName = method.getIDLName();
  1037         Type paramTypes[] = method.getArguments();
  1038         String paramNames[] = method.getArgumentNames();
  1039         Type returnType = method.getReturnType();
  1040         ValueType[] exceptions = getStubExceptions(method,true);
  1042         String in = getVariableName("in");
  1043         String out = getVariableName("out");
  1044         String ex = getVariableName("ex");
  1046         // Decide if we need to use the new streams for
  1047         // any of the read calls...
  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;
  1058         if (!needNewReadStreamClass) {
  1059             for (int i = 0; i < paramTypes.length; i++) {
  1060                 if (needNewReadStreamClass(paramTypes[i])) {
  1061                     needNewReadStreamClass = true;
  1062                     break;
  1066         if (!needNewReadStreamClass) {
  1067             needNewReadStreamClass = needNewReadStreamClass(returnType);
  1070         // Decide if we need to use the new streams for
  1071         // any of the write calls...
  1073         boolean needNewWriteStreamClass = false;
  1074         for (int i = 0; i < paramTypes.length; i++) {
  1075             if (needNewWriteStreamClass(paramTypes[i])) {
  1076                 needNewWriteStreamClass = true;
  1077                 break;
  1081         // Now write the method, inserting casts where needed...
  1083         p.plnI("try {");
  1084         if (needNewReadStreamClass) {
  1085             p.pln(idExtInputStream + " "+in+" = null;");
  1086         } else {
  1087             p.pln(idInputStream + " "+in+" = null;");
  1089         p.plnI("try {");
  1091         String argStream = "null";
  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);");
  1102         if (paramTypes.length > 0) {
  1103             writeMarshalArguments(p, out, paramTypes, paramNames);
  1104             p.pln();
  1106         argStream = out;
  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 + ");");
  1117             p.p("return ");
  1118             writeUnmarshalArgument(p, in, returnType, null);
  1119             p.pln();
  1122         // Handle ApplicationException...
  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();");
  1131         boolean idRead = false;
  1132         boolean idAllocated = false;
  1133         for(int i = 0; i < exceptions.length; i++) {
  1134             if (exceptions[i].getIdentifier() != idRemoteException) {
  1136                 // Is this our special-case IDLEntity exception?
  1138                 if (exceptions[i].isIDLEntityException() && !exceptions[i].isCORBAUserException()) {
  1140                     // Yes.
  1142                     if (!idAllocated && !idRead) {
  1143                         p.pln("String $_id = "+ex+".getId();");
  1144                         idAllocated = true;
  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+");");
  1152                 } else {
  1154                     // No.
  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;
  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);");
  1168                 p.pOln("}");
  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;
  1179         p.pln("throw new UnexpectedException($_id);");
  1181         // Handle RemarshalException...
  1183         p.pOlnI("} catch ("+getName(idRemarshalException)+" "+ex+") {");
  1184         if (!returnType.isType(TYPE_VOID)) {
  1185             p.p("return ");
  1187         p.p(methodName + "(");
  1188         for(int i = 0; i < paramTypes.length; i++) {
  1189             if (i > 0) {
  1190                 p.p(",");
  1192             p.p(paramNames[i]);
  1194         p.pln(");");
  1196         // Ensure that we release the reply...
  1198         p.pOlnI("} finally {");
  1199         p.pln("_releaseReply("+in+");");
  1201         p.pOln("}");
  1203         // Handle SystemException...
  1205         p.pOlnI("} catch (SystemException "+ex+") {");
  1206         p.pln("throw Util.mapSystemException("+ex+");");
  1207         p.pOln("}");
  1209         // returnResult(p,returnType);
  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 = ");
  1220     int getTypeCode(Type type) {
  1222         int typeCode = type.getTypeCode();
  1224         // Handle late-breaking special case for
  1225         // abstract IDL entities...
  1227         if ((type instanceof CompoundType) &&
  1228             ((CompoundType)type).isAbstractBase()) {
  1229             typeCode = TYPE_ABSTRACT;
  1232         return typeCode;
  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 {
  1244         int typeCode = getTypeCode(type);
  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);
  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 {
  1321         int typeCode = getTypeCode(type);
  1323         if (name != null) {
  1324             p.p(name + " = ");
  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) + ") ");
  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);");
  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);
  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) {
  1413         String[] result;
  1415         // Collect up all the (inherited) remote interfaces
  1416         // (ignores all the 'special' interfaces: Remote,
  1417         // Serializable, Externalizable)...
  1419         Type[] types = collectAllRemoteInterfaces(theType);
  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;
  1427         // Do we have an implementation type that implements
  1428         // more than one remote interface?
  1430         if (haveImpl && remoteCount > 1) {
  1432             // Yes, so we need to insert it at the beginning...
  1434             result = new String[length + 1];
  1435             result[0] = getRepositoryID(theType);
  1436             offset = 1;
  1438         } else {
  1440             // No.
  1442             result = new String[length];
  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.
  1448             if (length > 1) {
  1450                 // First, decide what the most derived type is...
  1452                 String mostDerived = null;
  1454                 if (haveImpl) {
  1456                     // If we get here, we know that there is only one
  1457                     // direct remote interface, so just find it...
  1459                     for (int i = 0; i < interfaces.length; i++) {
  1460                         if (interfaces[i].isType(TYPE_REMOTE)) {
  1461                             mostDerived = interfaces[i].getRepositoryID();
  1462                             break;
  1465                 } else {
  1467                     // If we get here we know that theType is a RemoteType
  1468                     // so just use its id...
  1470                     mostDerived = theType.getRepositoryID();
  1473                 // Now search types list and make sure mostDerived is
  1474                 // at index zero...
  1476                 for (int i = 0; i < length; i++) {
  1477                     if (types[i].getRepositoryID() == mostDerived) {
  1479                         // Found it. Swap it if we need to...
  1481                         if (i > 0) {
  1482                             Type temp = types[0];
  1483                             types[0] = types[i];
  1484                             types[i] = temp;
  1487                         break;
  1493         // Now copy contents of the types array...
  1495         for (int i = 0; i < types.length; i++) {
  1496             result[offset++] = getRepositoryID(types[i]);
  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.
  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;
  1514         return result;
  1517     /**
  1518      * Collect all the inherited remote interfaces.
  1519      */
  1520     Type[] collectAllRemoteInterfaces (CompoundType theType) {
  1521         Vector list = new Vector();
  1523         // Collect up all the Remote interfaces, and get an instance
  1524         // for java.rmi.Remote...
  1526         addRemoteInterfaces(list,theType);
  1528         // Create and return our results...
  1530         Type[] result = new Type[list.size()];
  1531         list.copyInto(result);
  1533         return result;
  1536     /**
  1537      * Add all the inherited remote interfaces to list.
  1538      */
  1539     void addRemoteInterfaces(Vector list, CompoundType theType) {
  1541         if (theType != null) {
  1542             if (theType.isInterface() && !list.contains(theType)) {
  1543                 list.addElement(theType);
  1546             InterfaceType[] interfaces = theType.getInterfaces();
  1547             for (int i = 0; i < interfaces.length; i++) {
  1549                 if (interfaces[i].isType(TYPE_REMOTE)) {
  1550                     addRemoteInterfaces(list,interfaces[i]);
  1554             addRemoteInterfaces(list,theType.getSuperclass());
  1558     /**
  1559      * Get a list of all the remote interfaces which this stub
  1560      * should declare.
  1561      */
  1562     RemoteType[] getDirectRemoteInterfaces (CompoundType theType) {
  1564         RemoteType[] result;
  1565         InterfaceType[] interfaces = theType.getInterfaces();
  1567         // First, get a list of all the interfaces...
  1569         InterfaceType[] list;
  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...
  1576         // Do we have an implementation type?
  1578         if (theType instanceof ImplementationType) {
  1580             // Yes, so list is exactly what this type
  1581             // implements and is correct already.
  1583             list = interfaces;
  1585         } else {
  1587             // No, so list is just theType...
  1589             list = new InterfaceType[1];
  1590             list[0] = (InterfaceType) theType;
  1593         // Ok, now count up the remote interfaces, allocate
  1594         // our result and fill it in...
  1596         int remoteCount = countRemote(list,false);
  1598         if (remoteCount == 0) {
  1599             throw new CompilerError("iiop.StubGenerator: No remote interfaces!");
  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];
  1610         return result;
  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++;
  1622         return remoteCount;
  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("}");
  1636     void writeIds(IndentingWriter p, CompoundType theType, boolean isTie
  1637                   ) throws IOException {
  1638         p.plnI("private static final String[] _type_ids = {");
  1640         String[] ids = getAllRemoteRepIDs(theType);
  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] + "\"");
  1648         } else {
  1649            // Must be an implementation which only implements Remote...
  1650            p.pln("\"\"");
  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();
  1662         p.pOln("};");
  1666     /**
  1667      * Write the Tie for the remote class to a stream.
  1668      */
  1669     protected void writeTie(OutputType outputType,
  1670                             IndentingWriter p) throws IOException
  1672         CompoundType theType = (CompoundType) outputType.getType();
  1673         RemoteType[] remoteInterfaces = null;
  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();
  1680         // Set our standard classes...
  1681         setStandardClassesInUse(theType,false);
  1683         // Add classes for this type...
  1684         addClassesInUse(theType,remoteInterfaces);
  1686         // Write package and import statements...
  1687         writePackageAndImports(p);
  1689         // Declare the tie class.
  1690         p.p("public class " + currentClass + " extends " +
  1691             getName(tieBaseClass) + " implements Tie");
  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"));
  1701         p.plnI(" {");
  1703         // Write data members...
  1704         p.pln();
  1705         p.pln("volatile private " + getName(theType) + " target = null;");
  1706         p.pln();
  1708         // Write the ids...
  1709         writeIds( p, theType, true ) ;
  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("}");
  1717         // Write getTarget method...
  1718         p.pln();
  1719         p.plnI("public Remote getTarget() {");
  1720         p.pln("return target;");
  1721         p.pOln("}");
  1723         // Write thisObject method...
  1724         p.pln();
  1725         write_tie_thisObject_method(p,idCorbaObject);
  1727         // Write deactivate method...
  1728         p.pln();
  1729         write_tie_deactivate_method(p);
  1731         // Write get orb method...
  1732         p.pln();
  1733         p.plnI("public ORB orb() {");
  1734         p.pln("return _orb();");
  1735         p.pOln("}");
  1737         // Write set orb method...
  1738         p.pln();
  1739         write_tie_orb_method(p);
  1741         // Write the _ids() method...
  1742         p.pln();
  1743         write_tie__ids_method(p);
  1745         // Get all the methods...
  1746         CompoundType.Method[] remoteMethods = theType.getMethods();
  1748         // Register all the argument names used, plus our
  1749         // data member names...
  1751         addNamesInUse(remoteMethods);
  1752         addNameInUse("target");
  1753         addNameInUse("_type_ids");
  1755         // Write the _invoke method...
  1756         p.pln();
  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");
  1764         p.plnI("public OutputStream  _invoke(String "+method+", InputStream "+_in+", " +
  1765                "ResponseHandler "+reply+") throws SystemException {");
  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();
  1777             // See if we should use a hash table style
  1778             // comparison...
  1780             StaticStringsHash hash = getStringsHash(remoteMethods);
  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 ");
  1791                         p.plnI("if ("+method+".equals(\""+ current.getIDLName() +"\")) {");
  1792                         writeTieMethod(p, theType,current);
  1794                     p.pOln("}");
  1795                     p.pO();
  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 ");
  1804                 p.plnI("if ("+method+".equals(\""+ current.getIDLName() +"\")) {");
  1805                 writeTieMethod(p, theType, current);
  1809             if (hash != null) {
  1810                 p.pI();
  1811                 //        p.plnI("default:");
  1812             } else {
  1813                 //   p.pOlnI("} else {");
  1815             //              p.pln("throw new "+getName(idBadMethodException)+"();");
  1817             if (hash != null) {
  1818                 p.pO();
  1820             p.pOln("}");
  1821             p.pln("throw new "+getName(idBadMethodException)+"();");
  1823             p.pOlnI("} catch ("+getName(idSystemException)+" "+ex+") {");
  1824             p.pln("throw "+ex+";");
  1826             p.pOlnI("} catch ("+getName(idJavaLangThrowable)+" "+ex+") {");
  1827             p.pln("throw new " + getName(idPortableUnknownException) + "("+ex+");");
  1828             p.pOln("}");
  1829         } else {
  1830             // No methods...
  1832             p.pln("throw new " + getName(idBadMethodException) + "();");
  1835         p.pOln("}");            // end invoke
  1837         // Write the cast array hack...
  1839         writeCastArray(p);
  1841         // End tie class...
  1842         p.pOln("}");
  1844     public void catchWrongPolicy(IndentingWriter p) throws IOException {
  1845         p.pln("");
  1847     public void catchServantNotActive(IndentingWriter p) throws IOException {
  1848         p.pln("");
  1850     public void catchObjectNotActive(IndentingWriter p) throws IOException {
  1851         p.pln("");
  1854     public void write_tie_thisObject_method(IndentingWriter p,
  1855                                             Identifier idCorbaObject)
  1856         throws IOException
  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("}");
  1880     public void write_tie_deactivate_method(IndentingWriter p)
  1881         throws IOException
  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("}");
  1904     public void write_tie_orb_method(IndentingWriter p)
  1905         throws IOException
  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("}");
  1933     public void write_tie__ids_method(IndentingWriter p)
  1934         throws IOException
  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("}");
  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();
  1954             return new StaticStringsHash(methodNames);
  1956         return null;
  1959     static boolean needNewReadStreamClass(Type type) {
  1960         if (type.isType(TYPE_ABSTRACT)) {
  1961             return true;
  1963         // Handle late-breaking special case for
  1964         // abstract IDL entities...
  1965         if ((type instanceof CompoundType) &&
  1966             ((CompoundType)type).isAbstractBase()) {
  1967             return true;
  1969         return needNewWriteStreamClass(type);
  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;
  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;
  1996         default: throw new Error("unexpected type code: " + type.getTypeCode());
  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 {
  2008         Type[] args = method.getArguments();
  2009         String[] origNames = method.getArgumentNames();
  2011         // Copy the current parameter names to a result array...
  2013         String[] result = new String[origNames.length];
  2014         for (int i = 0; i < result.length; i++) {
  2015             result[i] = origNames[i];
  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...
  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.
  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;
  2040             } else {
  2041                 copyArg[i] = false;
  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++;
  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(",");
  2073                         first = false;
  2074                         p.p(origNames[i]);
  2077                 p.pln("},_orb());");
  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++ +"];");
  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());");
  2100         return result;
  2103     static final String SINGLE_SLASH = "\\";
  2104     static final String DOUBLE_SLASH = SINGLE_SLASH + SINGLE_SLASH;
  2106     String getRepositoryID(Type type) {
  2107         return IDLNames.replace(type.getRepositoryID(), SINGLE_SLASH, DOUBLE_SLASH);
  2110     String getExceptionRepositoryID(Type type) {
  2111         ClassType theType = (ClassType) type;
  2112         return IDLNames.getIDLRepositoryID(theType.getQualifiedIDLExceptionName(false));
  2115     String getVariableName(String proposed) {
  2116         while (namesInUse.contains(proposed)) {
  2117             proposed = "$" + proposed;
  2120         return proposed;
  2123     void addNamesInUse(CompoundType.Method[] methods) {
  2124         for (int i = 0; i < methods.length; i++) {
  2125             addNamesInUse(methods[i]);
  2129     void addNamesInUse(CompoundType.Method method) {
  2130         String paramNames[] = method.getArgumentNames();
  2131         for (int i = 0; i < paramNames.length; i++) {
  2132             addNameInUse(paramNames[i]);
  2136     void addNameInUse(String name) {
  2137         namesInUse.add(name);
  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;
  2153         case TYPE_ANY:              return true;
  2155         case TYPE_CORBA_OBJECT:     return false;
  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;
  2166         default: throw new Error("unexpected type code: " + type.getTypeCode());
  2170     ValueType[] getStubExceptions (CompoundType.Method method, boolean sort) {
  2172         ValueType[] list = method.getFilteredStubExceptions(method.getExceptions());
  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().
  2179         if (sort) {
  2180             Arrays.sort(list,new UserExceptionComparator());
  2183         return list;
  2186     ValueType[] getTieExceptions (CompoundType.Method method) {
  2187         return method.getUniqueCatchList(method.getImplExceptions());
  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");
  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();
  2208         boolean handleExceptions = exceptions != null;
  2209         boolean doReturn = !returnType.isType(TYPE_VOID);
  2211         if (handleExceptions && doReturn) {
  2212             String objName = testUtil(getName(returnType), returnType);
  2213             p.pln(objName+" result;");
  2216         if (handleExceptions)
  2217             p.plnI("try {");
  2219         if (doReturn) {
  2220             if (handleExceptions) {
  2221                 p.p("result = ");
  2222             } else {
  2223                 p.p(getName(returnType)+" result = ");
  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]);
  2233         p.pln(");");
  2235         if (handleExceptions) {
  2236             for(int i = 0; i < exceptions.length; i++) {
  2237                 p.pOlnI("} catch ("+getName(exceptions[i])+" "+ex+") {");
  2239                 // Is this our IDLEntity Exception special case?
  2241                 if (exceptions[i].isIDLEntityException() && !exceptions[i].isCORBAUserException()) {
  2243                                 // Yes...
  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+");");
  2250                 } else {
  2252                                 // No...
  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);");
  2261                 p.pln("return "+out+";");
  2263             p.pOln("}");
  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();");
  2274         if (doReturn) {
  2275             writeMarshalArgument(p, out, returnType, "result");
  2276             p.pln();
  2279         p.pln("return "+out+";");
  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
  2293         if (types.length != names.length) {
  2294             throw new Error("paramter type and name arrays different sizes");
  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();
  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;
  2320 class 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);
  2329 class 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;
  2338         } else if (isUserException(v2)) {
  2339             if (!isUserException(v1)) {
  2340                 result = 1;
  2343         return result;
  2346     final boolean isUserException(ValueType it) {
  2347         return it.isIDLEntityException() && !it.isCORBAUserException();

mercurial