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

Sat, 07 Nov 2020 10:30:02 +0800

author
aoqi
date
Sat, 07 Nov 2020 10:30:02 +0800
changeset 2030
6a4286d4ceb1
parent 1410
9c913ea7e4a1
permissions
-rw-r--r--

Added tag mips-jdk8u275-b01 for changeset 146eabb0a016

     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             //
   450             // private transient boolean _instantiated = false;
   451             //
   452             // private static Void checkPermission() {
   453             // SecurityManager sm = System.getSecurityManager();
   454             // if (sm != null) {
   455             //     sm.checkPermission(new SerializablePermission(
   456             // "enableSubclassImplementation")); // testing
   457             // }
   458             // return null;
   459             // }
   460             //
   461             // private _XXXXX_Stub(Void ignore) {
   462             // }
   463             //
   464             // public _XXXXX_Stub() {
   465             // this(checkPermission());
   466             // _instantiated = true;
   467             // }
   468             //
   469             // private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
   470             //    checkPermission();
   471             //    s.defaultReadObject();
   472             //    _instantiated = true;
   473             // }
   474             //
   475             // where XXXXX is the name of the remote interface
   477                 p.pln();
   478                 p.plnI("private transient boolean _instantiated = false;");
   479                 p.pln();
   480                 p.pO();
   481                 p.plnI("private static Void checkPermission() {");
   482                 p.plnI("SecurityManager sm = System.getSecurityManager();");
   483                 p.pln("if (sm != null) {");
   484                 p.pI();
   485                 p.plnI("sm.checkPermission(new SerializablePermission(");
   486                 p.plnI("\"enableSubclassImplementation\"));");
   487                 p.pO();
   488                 p.pO();
   489                 p.pOln("}");
   490                 p.pln("return null;");
   491                 p.pO();
   492                 p.pOln("}");
   493                 p.pln();
   494                 p.pO();
   496                 p.pI();
   497                 p.plnI("private " + currentClass + "(Void ignore) {  }");
   498                 p.pln();
   499                 p.pO();
   501                 p.plnI("public " + currentClass + "() {");
   502                 p.pln("this(checkPermission());");
   503                 p.pln("_instantiated = true;");
   504                 p.pOln("}");
   505                 p.pln();
   506                 p.plnI("private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {");
   507                 p.plnI("checkPermission();");
   508                 p.pO();
   509                 p.pln("s.defaultReadObject();");
   510                 p.pln("_instantiated = true;");
   511                 p.pOln("}");
   512                 p.pln();
   513                 //p.pO();
   514         }
   516        if (!emitPermissionCheck) {
   517             p.pI();
   518        }
   520         // Write the _ids() method...
   522         p.plnI("public String[] _ids() { ");
   523         p.pln("return (String[]) _type_ids.clone();");
   524         p.pOln("}");
   526         // Get all the methods and write each stub method...
   528         CompoundType.Method[] remoteMethods = theType.getMethods();
   529         int methodCount = remoteMethods.length;
   530         if (methodCount > 0) {
   531             boolean writeHeader = true;
   532             for(int i = 0; i < methodCount; i++) {
   533                 if (!remoteMethods[i].isConstructor()) {
   534                     if (writeHeader) {
   535                         writeHeader = false;
   536                     }
   537                     p.pln();
   538                     writeStubMethod(p, remoteMethods[i], theType);
   539                 }
   540             }
   541         }
   543         // Write the cast array hack...
   545         writeCastArray(p);
   547         p.pOln("}");            // end stub class
   548     }
   550     void addClassInUse(String qualifiedName) {
   551         String unqualifiedName = qualifiedName;
   552         String packageName = null;
   553         int index = qualifiedName.lastIndexOf('.');
   554         if (index > 0) {
   555             unqualifiedName = qualifiedName.substring(index+1);
   556             packageName = qualifiedName.substring(0,index);
   557         }
   558         addClassInUse(unqualifiedName,qualifiedName,packageName);
   559     }
   561     void addClassInUse(Type type) {
   562         if (!type.isPrimitive()) {
   563             Identifier id = type.getIdentifier();
   564             String name = IDLNames.replace(id.getName().toString(),". ",".");
   565             String packageName = type.getPackageName();
   566             String qualifiedName;
   567             if (packageName != null) {
   568                 qualifiedName = packageName+"."+name;
   569             } else {
   570                 qualifiedName = name;
   571             }
   572             addClassInUse(name,qualifiedName,packageName);
   573         }
   574     }
   576     void addClassInUse(Type[] types) {
   577         for (int i = 0; i < types.length; i++) {
   578             addClassInUse(types[i]);
   579         }
   580     }
   582     void addStubInUse(Type type) {
   583         if (type.getIdentifier() != idCorbaObject &&
   584             type.isType(TYPE_CORBA_OBJECT)) {
   585             String stubName = getStubNameFor(type,false);
   586             String packageName = type.getPackageName();
   587             String fullName;
   588             if (packageName == null) {
   589                 fullName = stubName;
   590             } else {
   591                 fullName = packageName + "." + stubName;
   592             }
   593             addClassInUse(stubName,fullName,packageName);
   594         }
   595         if (type.isType(TYPE_REMOTE) ||
   596             type.isType(TYPE_JAVA_RMI_REMOTE)) {
   597             addClassInUse("javax.rmi.PortableRemoteObject");
   598         }
   599     }
   601     String getStubNameFor(Type type, boolean qualified) {
   602         String stubName;
   603         String className;
   604         if (qualified) {
   605             className = type.getQualifiedName();
   606         } else {
   607             className = type.getName();
   608         }
   609         if (((CompoundType)type).isCORBAObject()) {
   610             stubName = Utility.idlStubName(className);
   611         } else {
   612             stubName = Utility.stubNameForCompiler(className);
   613         }
   614         return stubName;
   615     }
   617     void addStubInUse(Type[] types) {
   618         for (int i = 0; i < types.length; i++) {
   619             addStubInUse(types[i]);
   620         }
   621     }
   623     private static final String NO_IMPORT = new String();
   625     void addClassInUse(String unqualifiedName, String qualifiedName, String packageName) {
   627         // Have we already got an entry for this qualifiedName?
   629         String currentName = (String)classesInUse.get(qualifiedName);
   631         if (currentName == null) {
   633             // No, never seen it before. Grab any existing import
   634             // name and then decide what to do...
   636             String importName = (String) imports.get(unqualifiedName);
   637             String nameToUse = null;
   639             if (packageName == null) {
   641                 // Default package, so doesn't matter which name to use...
   643                 nameToUse = unqualifiedName;
   645             } else if (packageName.equals("java.lang")) {
   647                 // java.lang.*, so use unqualified name...
   649                 nameToUse = unqualifiedName;
   651                 // unless you want to be able to import things from the right place :--)
   653                 if(nameToUse.endsWith("_Stub")) nameToUse = Util.packagePrefix()+qualifiedName;
   655             } else if (currentPackage != null && packageName.equals(currentPackage)) {
   657                 // Class in currentPackage, so use unqualified name...
   659                 nameToUse = unqualifiedName;
   661                 // Do we already have a previous import under this
   662                 // unqualified name?
   664                 if (importName != null) {
   666                     // Yes, so we use qualifiedName...
   668                     nameToUse = qualifiedName;
   670                 }
   672             } else if (importName != null) {
   674                 // It is in some package for which we normally
   675                 // would import, but we have a previous import
   676                 // under this unqualified name. We must use
   677                 // the qualified name...
   679                 nameToUse = qualifiedName;
   681                 /*
   682                   // Is the currentPackage the default package?
   684                   if (currentPackage == null) {
   686                   // Yes, so undo the import so that all
   687                   // uses for this name will be qualified...
   689                   String old = (String)imports.remove(unqualifiedName);
   690                   classesInUse.put(old,old);
   691                   importCount--;
   693                   // Note that this name is in use but should
   694                   // not be imported...
   696                   imports.put(nameToUse,NO_IMPORT);
   697                   }
   698                 */
   699             } else if (qualifiedName.equals("org.omg.CORBA.Object")) {
   701                 // Always qualify this quy to avoid confusion...
   703                 nameToUse = qualifiedName;
   705             } else {
   707                 // Default to using unqualified name, and add
   708                 // this guy to the imports...
   710                 // Check for nested class in which case we use
   711                 // the fully qualified name instead of imports
   712                 if (unqualifiedName.indexOf('.') != -1) {
   713                     nameToUse = qualifiedName;
   714                 } else {
   715                     nameToUse = unqualifiedName;
   716                     imports.put(unqualifiedName,qualifiedName);
   717                     importCount++;
   718                 }
   719             }
   721             // Now add the name...
   723             classesInUse.put(qualifiedName,nameToUse);
   724         }
   725     }
   727     String getName(Type type) {
   728         if (type.isPrimitive()) {
   729             return type.getName() + type.getArrayBrackets();
   730         }
   731         Identifier id = type.getIdentifier();
   732         String name = IDLNames.replace(id.toString(),". ",".");
   733         return getName(name) + type.getArrayBrackets();
   734     }
   736     // Added for Bug 4818753
   737     String getExceptionName(Type type) {
   738         Identifier id = type.getIdentifier();
   739         return IDLNames.replace(id.toString(),". ",".");
   740     }
   742     String getName(String qualifiedName) {
   743         return (String)classesInUse.get(qualifiedName);
   744     }
   746     String getName(Identifier id) {
   747         return getName(id.toString());
   748     }
   750     String getStubName(Type type) {
   751         String stubName = getStubNameFor(type,true);
   752         return getName(stubName);
   753     }
   755     void setStandardClassesInUse(CompoundType type,
   756                                  boolean stub) throws IOException {
   758         // Reset our state...
   760         currentPackage = type.getPackageName();
   761         imports.clear();
   762         classesInUse.clear();
   763         namesInUse.clear();
   764         importCount = 0;
   765         castArray = false;
   767         // Add the top-level type...
   769         addClassInUse(type);
   771         // Set current class name...
   773         if (stub) {
   774             currentClass = Utility.stubNameForCompiler(type.getName());
   775         } else {
   776             currentClass = Utility.tieNameForCompiler(type.getName());
   777         }
   779         // Add current class...
   781         if (currentPackage == null) {
   782             addClassInUse(currentClass,currentClass,currentPackage);
   783         } else {
   784             addClassInUse(currentClass,(currentPackage+"."+currentClass),currentPackage);
   785         }
   787         // Add standard classes...
   789         addClassInUse("javax.rmi.CORBA.Util");
   790         addClassInUse(idRemote.toString());
   791         addClassInUse(idRemoteException.toString());
   792         addClassInUse(idOutputStream.toString());
   793         addClassInUse(idInputStream.toString());
   794         addClassInUse(idSystemException.toString());
   795         addClassInUse(idJavaIoSerializable.toString());
   796         addClassInUse(idCorbaORB.toString());
   797         addClassInUse(idReplyHandler.toString());
   799         // Add stub/tie specific imports...
   801         if (stub) {
   802             addClassInUse(stubBaseClass);
   803             addClassInUse("java.rmi.UnexpectedException");
   804             addClassInUse(idRemarshalException.toString());
   805             addClassInUse(idApplicationException.toString());
   806             if (localStubs) {
   807                 addClassInUse("org.omg.CORBA.portable.ServantObject");
   808             }
   809         } else {
   810             addClassInUse(type);
   811             addClassInUse(tieBaseClass);
   812             addClassInUse(idTieInterface.toString());
   813             addClassInUse(idBadMethodException.toString());
   814             addClassInUse(idPortableUnknownException.toString());
   815             addClassInUse(idJavaLangThrowable.toString());
   816         }
   817     }
   819     void addClassesInUse(CompoundType type, RemoteType[] interfaces) {
   821         // Walk all methods and add types in use...
   823         CompoundType.Method[] methods = type.getMethods();
   824         for (int i = 0; i < methods.length; i++) {
   825             addClassInUse(methods[i].getReturnType());
   826             addStubInUse(methods[i].getReturnType());
   827             addClassInUse(methods[i].getArguments());
   828             addStubInUse(methods[i].getArguments());
   829             addClassInUse(methods[i].getExceptions());
   830             // bug 4473859: Also include narrower subtypes for use
   831             addClassInUse(methods[i].getImplExceptions());
   832         }
   834         // If this is a stub, add all interfaces...
   836         if (interfaces != null) {
   837             addClassInUse(interfaces);
   838         }
   839     }
   841     void writePackageAndImports(IndentingWriter p) throws IOException {
   843         // Write package declaration...
   845         if (currentPackage != null) {
   846             p.pln("package " +
   847                      Util.correctPackageName(
   848                           currentPackage, false, standardPackage)
   849                    + ";");
   850             p.pln();
   851         }
   853         // Get imports into an array and sort them...
   855         String[] names = new String[importCount];
   856         int index = 0;
   857         for (Enumeration e = imports.elements() ; e.hasMoreElements() ;) {
   858             String it = (String) e.nextElement();
   859             if (it != NO_IMPORT) {
   860                 names[index++] = it;
   861             }
   862         }
   864         Arrays.sort(names,new StringComparator());
   866         // Now dump them out...
   868         for (int i = 0; i < importCount; i++) {
   869             if(
   870                Util.isOffendingPackage(names[i])
   871                && names[i].endsWith("_Stub")
   872                && String.valueOf(names[i].charAt(names[i].lastIndexOf(".")+1)).equals("_")
   873                ){
   874                 p.pln("import " + PackagePrefixChecker.packagePrefix()+names[i]+";");
   875             } else{
   876                 p.pln("import " + names[i] + ";");
   877             }
   878         }
   879         p.pln();
   881         // Include offending packages . . .
   882         if ( currentPackage!=null && Util.isOffendingPackage(currentPackage) ){
   883             p.pln("import " + currentPackage +".*  ;");
   884         }
   885         p.pln();
   887     }
   889     boolean implementsRemote(CompoundType theType) {
   890         boolean result = theType.isType(TYPE_REMOTE) && !theType.isType(TYPE_ABSTRACT);
   892         // If theType is not remote, look at all the interfaces
   893         // until we find one that is...
   895         if (!result) {
   896             InterfaceType[] interfaces = theType.getInterfaces();
   897             for (int i = 0; i < interfaces.length; i++) {
   898                 result = implementsRemote(interfaces[i]);
   899                 if (result) {
   900                     break;
   901                 }
   902             }
   903         }
   905         return result;
   906     }
   908     void writeStubMethod (  IndentingWriter p,
   909                             CompoundType.Method method,
   910                             CompoundType theType) throws IOException {
   912         // Wtite the method declaration and opening brace...
   913         String methodName = method.getName();
   914         String methodIDLName = method.getIDLName();
   916         Type paramTypes[] = method.getArguments();
   917         String paramNames[] = method.getArgumentNames();
   918         Type returnType = method.getReturnType();
   919         ValueType[] exceptions = getStubExceptions(method,false);
   920         boolean hasIOException = false;
   922         addNamesInUse(method);
   923         addNameInUse("_type_ids");
   925         String objName = testUtil(getName(returnType), returnType);
   926         p.p("public " + objName + " " + methodName + "(");
   927         for(int i = 0; i < paramTypes.length; i++) {
   928             if (i > 0)
   929                 p.p(", ");
   930             p.p(getName(paramTypes[i]) + " " + paramNames[i]);
   931         }
   933         p.p(")");
   934         if (exceptions.length > 0) {
   935             p.p(" throws ");
   936             for(int i = 0; i < exceptions.length; i++) {
   937                 if (i > 0) {
   938                     p.p(", ");
   939                 }
   940                 // Added for Bug 4818753
   941                 p.p(getExceptionName(exceptions[i]));
   942             }
   943         }
   945         p.plnI(" {");
   947         // Now create the method body...
   948         if (emitPermissionCheck) {
   949             p.pln("if ((System.getSecurityManager() != null) && (!_instantiated)) {");
   950             p.plnI("    throw new java.io.IOError(new java.io.IOException(\"InvalidObject \"));");
   951             p.pOln("}");
   952             p.pln();
   953         }
   956         if (localStubs) {
   957             writeLocalStubMethodBody(p,method,theType);
   958         } else {
   959             writeNonLocalStubMethodBody(p,method,theType);
   960         }
   962         // Close out the method...
   964         p.pOln("}");
   965     }
   968     void writeLocalStubMethodBody (IndentingWriter p,
   969                                    CompoundType.Method method,
   970                                    CompoundType theType) throws IOException {
   972         String objName;
   973         String paramNames[] = method.getArgumentNames();
   974         Type returnType = method.getReturnType();
   975         ValueType[] exceptions = getStubExceptions(method,false);
   976         String methodName = method.getName();
   977         String methodIDLName = method.getIDLName();
   979         p.plnI("if (!Util.isLocal(this)) {");
   980         writeNonLocalStubMethodBody(p,method,theType);
   981         p.pOlnI("} else {");
   982         String so = getVariableName("so");
   984         p.pln("ServantObject "+so+" = _servant_preinvoke(\""+methodIDLName+"\","+getName(theType)+".class);");
   985         p.plnI("if ("+so+" == null) {");
   986         if (!returnType.isType(TYPE_VOID)) {
   987             p.p("return ");
   988         }
   989         p.p(methodName+"(");
   990         for (int i = 0; i < paramNames.length; i++) {
   991             if (i > 0)
   992                 p.p(", ");
   993             p.p(paramNames[i]);
   994         }
   995         p.pln(");");
   996         if (returnType.isType(TYPE_VOID)) {
   997             p.pln( "return ;" ) ;
   998         }
  1000         p.pOln("}");
  1001         p.plnI("try {");
  1003         // Generate code to copy required arguments, and
  1004         // get back the names by which all arguments are known...
  1006         String[] argNames = writeCopyArguments(method,p);
  1008         // Now write the method...
  1010         boolean copyReturn = mustCopy(returnType);
  1011         String resultName = null;
  1012         if (!returnType.isType(TYPE_VOID)) {
  1013             if (copyReturn) {
  1014                 resultName = getVariableName("result");
  1015                 objName = testUtil(getName(returnType), returnType);
  1016                 p.p(objName+" "+resultName + " = ");
  1017             } else {
  1018                 p.p("return ");
  1021         objName = testUtil(getName(theType), theType);
  1022         p.p("(("+objName+")"+so+".servant)."+methodName+"(");
  1024         for (int i = 0; i < argNames.length; i++) {
  1025             if (i > 0)
  1026                 p.p(", ");
  1027             p.p(argNames[i]);
  1030         if (copyReturn) {
  1031             p.pln(");");
  1032             objName = testUtil(getName(returnType), returnType);
  1033             p.pln("return ("+objName+")Util.copyObject("+resultName+",_orb());");
  1034         } else {
  1035             p.pln(");");
  1038         String e1 = getVariableName("ex");
  1039         String e2 = getVariableName("exCopy");
  1040         p.pOlnI("} catch (Throwable "+e1+") {");
  1042         p.pln("Throwable "+e2+" = (Throwable)Util.copyObject("+e1+",_orb());");
  1043         for(int i = 0; i < exceptions.length; i++) {
  1044             if (exceptions[i].getIdentifier() != idRemoteException &&
  1045                 exceptions[i].isType(TYPE_VALUE)) {
  1046                 // Added for Bug 4818753
  1047                 p.plnI("if ("+e2+" instanceof "+getExceptionName(exceptions[i])+") {");
  1048                 p.pln("throw ("+getExceptionName(exceptions[i])+")"+e2+";");
  1049                 p.pOln("}");
  1053         p.pln("throw Util.wrapException("+e2+");");
  1054         p.pOlnI("} finally {");
  1055         p.pln("_servant_postinvoke("+so+");");
  1056         p.pOln("}");
  1057         p.pOln("}");
  1061     void writeNonLocalStubMethodBody (  IndentingWriter p,
  1062                                         CompoundType.Method method,
  1063                                         CompoundType theType) throws IOException {
  1065         String methodName = method.getName();
  1066         String methodIDLName = method.getIDLName();
  1068         Type paramTypes[] = method.getArguments();
  1069         String paramNames[] = method.getArgumentNames();
  1070         Type returnType = method.getReturnType();
  1071         ValueType[] exceptions = getStubExceptions(method,true);
  1073         String in = getVariableName("in");
  1074         String out = getVariableName("out");
  1075         String ex = getVariableName("ex");
  1077         // Decide if we need to use the new streams for
  1078         // any of the read calls...
  1080         boolean needNewReadStreamClass = false;
  1081         for (int i = 0; i < exceptions.length; i++) {
  1082             if (exceptions[i].getIdentifier() != idRemoteException &&
  1083                 exceptions[i].isType(TYPE_VALUE) &&
  1084                 needNewReadStreamClass(exceptions[i])) {
  1085                 needNewReadStreamClass = true;
  1086                 break;
  1089         if (!needNewReadStreamClass) {
  1090             for (int i = 0; i < paramTypes.length; i++) {
  1091                 if (needNewReadStreamClass(paramTypes[i])) {
  1092                     needNewReadStreamClass = true;
  1093                     break;
  1097         if (!needNewReadStreamClass) {
  1098             needNewReadStreamClass = needNewReadStreamClass(returnType);
  1101         // Decide if we need to use the new streams for
  1102         // any of the write calls...
  1104         boolean needNewWriteStreamClass = false;
  1105         for (int i = 0; i < paramTypes.length; i++) {
  1106             if (needNewWriteStreamClass(paramTypes[i])) {
  1107                 needNewWriteStreamClass = true;
  1108                 break;
  1112         // Now write the method, inserting casts where needed...
  1114         p.plnI("try {");
  1115         if (needNewReadStreamClass) {
  1116             p.pln(idExtInputStream + " "+in+" = null;");
  1117         } else {
  1118             p.pln(idInputStream + " "+in+" = null;");
  1120         p.plnI("try {");
  1122         String argStream = "null";
  1124         if (needNewWriteStreamClass) {
  1125             p.plnI(idExtOutputStream + " "+out+" = ");
  1126             p.pln("(" + idExtOutputStream + ")");
  1127             p.pln("_request(\"" + methodIDLName + "\", true);");
  1128             p.pO();
  1129         } else {
  1130             p.pln("OutputStream "+out+" = _request(\"" + methodIDLName + "\", true);");
  1133         if (paramTypes.length > 0) {
  1134             writeMarshalArguments(p, out, paramTypes, paramNames);
  1135             p.pln();
  1137         argStream = out;
  1139         if (returnType.isType(TYPE_VOID)) {
  1140             p.pln("_invoke(" + argStream + ");" );
  1141         } else {
  1142             if (needNewReadStreamClass) {
  1143                 p.plnI(in+" = (" + idExtInputStream + ")_invoke(" + argStream + ");");
  1144                 p.pO();
  1145             } else {
  1146                 p.pln(in+" = _invoke(" + argStream + ");");
  1148             p.p("return ");
  1149             writeUnmarshalArgument(p, in, returnType, null);
  1150             p.pln();
  1153         // Handle ApplicationException...
  1155         p.pOlnI("} catch ("+getName(idApplicationException)+" "+ex+") {");
  1156         if (needNewReadStreamClass) {
  1157             p.pln(in + " = (" + idExtInputStream + ") "+ex+".getInputStream();");
  1158         } else {
  1159             p.pln(in + " = "+ex+".getInputStream();");
  1162         boolean idRead = false;
  1163         boolean idAllocated = false;
  1164         for(int i = 0; i < exceptions.length; i++) {
  1165             if (exceptions[i].getIdentifier() != idRemoteException) {
  1167                 // Is this our special-case IDLEntity exception?
  1169                 if (exceptions[i].isIDLEntityException() && !exceptions[i].isCORBAUserException()) {
  1171                     // Yes.
  1173                     if (!idAllocated && !idRead) {
  1174                         p.pln("String $_id = "+ex+".getId();");
  1175                         idAllocated = true;
  1178                     String helperName = IDLNames.replace(exceptions[i].getQualifiedIDLName(false),"::",".");
  1179                     helperName += "Helper";
  1180                     p.plnI("if ($_id.equals("+helperName+".id())) {");
  1181                     p.pln("throw "+helperName+".read("+in+");");
  1183                 } else {
  1185                     // No.
  1187                     if (!idAllocated && !idRead) {
  1188         p.pln("String $_id = "+in+".read_string();");
  1189                         idAllocated = true;
  1190                         idRead = true;
  1191                     } else if (idAllocated && !idRead) {
  1192                         p.pln("$_id = "+in+".read_string();");
  1193                         idRead = true;
  1195                     p.plnI("if ($_id.equals(\""+getExceptionRepositoryID(exceptions[i])+"\")) {");
  1196                     // Added for Bug 4818753
  1197                     p.pln("throw ("+getExceptionName(exceptions[i])+") "+in+".read_value(" + getExceptionName(exceptions[i]) + ".class);");
  1199                 p.pOln("}");
  1202         if (!idAllocated && !idRead) {
  1203             p.pln("String $_id = "+in+".read_string();");
  1204             idAllocated = true;
  1205             idRead = true;
  1206         } else if (idAllocated && !idRead) {
  1207             p.pln("$_id = "+in+".read_string();");
  1208             idRead = true;
  1210         p.pln("throw new UnexpectedException($_id);");
  1212         // Handle RemarshalException...
  1214         p.pOlnI("} catch ("+getName(idRemarshalException)+" "+ex+") {");
  1215         if (!returnType.isType(TYPE_VOID)) {
  1216             p.p("return ");
  1218         p.p(methodName + "(");
  1219         for(int i = 0; i < paramTypes.length; i++) {
  1220             if (i > 0) {
  1221                 p.p(",");
  1223             p.p(paramNames[i]);
  1225         p.pln(");");
  1227         // Ensure that we release the reply...
  1229         p.pOlnI("} finally {");
  1230         p.pln("_releaseReply("+in+");");
  1232         p.pOln("}");
  1234         // Handle SystemException...
  1236         p.pOlnI("} catch (SystemException "+ex+") {");
  1237         p.pln("throw Util.mapSystemException("+ex+");");
  1238         p.pOln("}");
  1240         // returnResult(p,returnType);
  1243     void allocateResult (IndentingWriter p,
  1244                          Type returnType) throws IOException {
  1245         if (!returnType.isType(TYPE_VOID)) {
  1246             String objName = testUtil(getName(returnType), returnType);
  1247             p.p(objName + " result = ");
  1251     int getTypeCode(Type type) {
  1253         int typeCode = type.getTypeCode();
  1255         // Handle late-breaking special case for
  1256         // abstract IDL entities...
  1258         if ((type instanceof CompoundType) &&
  1259             ((CompoundType)type).isAbstractBase()) {
  1260             typeCode = TYPE_ABSTRACT;
  1263         return typeCode;
  1267     /**
  1268      * Write a snippet of Java code to marshal a value named "name" of
  1269      * type "type" to the java.io.ObjectOutput stream named "stream".
  1270      */
  1271     void writeMarshalArgument(IndentingWriter p,
  1272                               String streamName,
  1273                               Type type, String name) throws IOException {
  1275         int typeCode = getTypeCode(type);
  1277         switch (typeCode) {
  1278         case TYPE_BOOLEAN:
  1279             p.p(streamName + ".write_boolean(" + name + ");");
  1280             break;
  1281         case TYPE_BYTE:
  1282             p.p(streamName + ".write_octet(" + name + ");");
  1283             break;
  1284         case TYPE_CHAR:
  1285             p.p(streamName + ".write_wchar(" + name + ");");
  1286             break;
  1287         case TYPE_SHORT:
  1288             p.p(streamName + ".write_short(" + name + ");");
  1289             break;
  1290         case TYPE_INT:
  1291             p.p(streamName + ".write_long(" + name + ");");
  1292             break;
  1293         case TYPE_LONG:
  1294             p.p(streamName + ".write_longlong(" + name + ");");
  1295             break;
  1296         case TYPE_FLOAT:
  1297             p.p(streamName + ".write_float(" + name + ");");
  1298             break;
  1299         case TYPE_DOUBLE:
  1300             p.p(streamName + ".write_double(" + name + ");");
  1301             break;
  1302         case TYPE_STRING:
  1303             p.p(streamName + ".write_value(" + name + "," + getName(type) + ".class);");
  1304             break;
  1305         case TYPE_ANY:
  1306             p.p("Util.writeAny("+ streamName + "," + name + ");");
  1307             break;
  1308         case TYPE_CORBA_OBJECT:
  1309             p.p(streamName + ".write_Object(" + name + ");");
  1310             break;
  1311         case TYPE_REMOTE:
  1312             p.p("Util.writeRemoteObject("+ streamName + "," + name + ");");
  1313             break;
  1314         case TYPE_ABSTRACT:
  1315             p.p("Util.writeAbstractObject("+ streamName + "," + name + ");");
  1316             break;
  1317         case TYPE_NC_INTERFACE:
  1318             p.p(streamName + ".write_value((Serializable)" + name + "," + getName(type) + ".class);");
  1319             break;
  1320         case TYPE_VALUE:
  1321             p.p(streamName + ".write_value(" + name + "," + getName(type) + ".class);");
  1322             break;
  1323         case TYPE_IMPLEMENTATION:
  1324             p.p(streamName + ".write_value((Serializable)" + name + "," + getName(type) + ".class);");
  1325             break;
  1326         case TYPE_NC_CLASS:
  1327             p.p(streamName + ".write_value((Serializable)" + name + "," + getName(type) + ".class);");
  1328             break;
  1329         case TYPE_ARRAY:
  1330             castArray = true;
  1331             p.p(streamName + ".write_value(cast_array(" + name + ")," + getName(type) + ".class);");
  1332             break;
  1333         case TYPE_JAVA_RMI_REMOTE:
  1334             p.p("Util.writeRemoteObject("+ streamName + "," + name + ");");
  1335             break;
  1336         default:
  1337             throw new Error("unexpected type code: " + typeCode);
  1341     /**
  1342      * Write a snippet of Java code to unmarshal a value of type "type"
  1343      * from the java.io.ObjectInput stream named "stream" into a variable
  1344      * named "name" (if "name" is null, the value in unmarshalled and
  1345      * discarded).
  1346      */
  1347     void writeUnmarshalArgument(IndentingWriter p,
  1348                                 String streamName,
  1349                                 Type type,
  1350                                 String name) throws IOException {
  1352         int typeCode = getTypeCode(type);
  1354         if (name != null) {
  1355             p.p(name + " = ");
  1358         switch (typeCode) {
  1359         case TYPE_BOOLEAN:
  1360             p.p(streamName + ".read_boolean();");
  1361             break;
  1362         case TYPE_BYTE:
  1363             p.p(streamName + ".read_octet();");
  1364             break;
  1365         case TYPE_CHAR:
  1366             p.p(streamName + ".read_wchar();");
  1367             break;
  1368         case TYPE_SHORT:
  1369             p.p(streamName + ".read_short();");
  1370             break;
  1371         case TYPE_INT:
  1372             p.p(streamName + ".read_long();");
  1373             break;
  1374         case TYPE_LONG:
  1375             p.p(streamName + ".read_longlong();");
  1376             break;
  1377         case TYPE_FLOAT:
  1378             p.p(streamName + ".read_float();");
  1379             break;
  1380         case TYPE_DOUBLE:
  1381             p.p(streamName + ".read_double();");
  1382             break;
  1383         case TYPE_STRING:
  1384             p.p("(String) " + streamName + ".read_value(" + getName(type) + ".class);");
  1385             break;
  1386         case TYPE_ANY:
  1387             if (type.getIdentifier() != idJavaLangObject) {
  1388                 p.p("(" + getName(type) + ") ");
  1390             p.p("Util.readAny(" + streamName + ");");
  1391             break;
  1392         case TYPE_CORBA_OBJECT:
  1393             if (type.getIdentifier() == idCorbaObject) {
  1394                 p.p("(" + getName(type) + ") " + streamName + ".read_Object();");
  1395             } else {
  1396                 p.p("(" + getName(type) + ") " + streamName + ".read_Object(" + getStubName(type) + ".class);");
  1398             break;
  1399         case TYPE_REMOTE:
  1400             String objName = testUtil(getName(type), type);
  1401             p.p("(" + objName + ") " +
  1402                 "PortableRemoteObject.narrow(" + streamName + ".read_Object(), " + objName + ".class);");
  1403             break;
  1404         case TYPE_ABSTRACT:
  1405             p.p("(" + getName(type) + ") " + streamName + ".read_abstract_interface();");
  1406             break;
  1407         case TYPE_NC_INTERFACE:
  1408             p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);");
  1409             break;
  1410         case TYPE_VALUE:
  1411             p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);");
  1412             break;
  1413         case TYPE_IMPLEMENTATION:
  1414             p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);");
  1415             break;
  1416         case TYPE_NC_CLASS:
  1417             p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);");
  1418             break;
  1419         case TYPE_ARRAY:
  1420             p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);");
  1421             break;
  1422         case TYPE_JAVA_RMI_REMOTE:
  1423             p.p("(" + getName(type) + ") " +
  1424                 "PortableRemoteObject.narrow(" + streamName + ".read_Object(), " + getName(type) + ".class);");
  1425             //      p.p("(" + getName(type) + ") " + streamName + ".read_Object(" + getStubName(type) + ".class);");
  1426             break;
  1427         default:
  1428             throw new Error("unexpected type code: " + typeCode);
  1432     /**
  1433      * Get a list of all the RepositoryIDs for interfaces
  1434      * implemented directly or indirectly by theType. In the
  1435      * case of an  ImplementationType which implements 2 or
  1436      * more remote interfaces, this list will begin with the
  1437      * Identifier for the implementation (see section 5.9 in
  1438      * the Java -> IDL mapping). Ensures that the most derived
  1439      * type is first in the list because the IOR is generated
  1440      * using that entry in the _ids array.
  1441      */
  1442     String[] getAllRemoteRepIDs (CompoundType theType) {
  1444         String[] result;
  1446         // Collect up all the (inherited) remote interfaces
  1447         // (ignores all the 'special' interfaces: Remote,
  1448         // Serializable, Externalizable)...
  1450         Type[] types = collectAllRemoteInterfaces(theType);
  1452         int length = types.length;
  1453         boolean haveImpl = theType instanceof ImplementationType;
  1454         InterfaceType[] interfaces = theType.getInterfaces();
  1455         int remoteCount = countRemote(interfaces,false);
  1456         int offset = 0;
  1458         // Do we have an implementation type that implements
  1459         // more than one remote interface?
  1461         if (haveImpl && remoteCount > 1) {
  1463             // Yes, so we need to insert it at the beginning...
  1465             result = new String[length + 1];
  1466             result[0] = getRepositoryID(theType);
  1467             offset = 1;
  1469         } else {
  1471             // No.
  1473             result = new String[length];
  1475             // Here we need to ensure that the most derived
  1476             // interface ends up being first in the list. If
  1477             // there is only one, we're done.
  1479             if (length > 1) {
  1481                 // First, decide what the most derived type is...
  1483                 String mostDerived = null;
  1485                 if (haveImpl) {
  1487                     // If we get here, we know that there is only one
  1488                     // direct remote interface, so just find it...
  1490                     for (int i = 0; i < interfaces.length; i++) {
  1491                         if (interfaces[i].isType(TYPE_REMOTE)) {
  1492                             mostDerived = interfaces[i].getRepositoryID();
  1493                             break;
  1496                 } else {
  1498                     // If we get here we know that theType is a RemoteType
  1499                     // so just use its id...
  1501                     mostDerived = theType.getRepositoryID();
  1504                 // Now search types list and make sure mostDerived is
  1505                 // at index zero...
  1507                 for (int i = 0; i < length; i++) {
  1508                     if (types[i].getRepositoryID() == mostDerived) {
  1510                         // Found it. Swap it if we need to...
  1512                         if (i > 0) {
  1513                             Type temp = types[0];
  1514                             types[0] = types[i];
  1515                             types[i] = temp;
  1518                         break;
  1524         // Now copy contents of the types array...
  1526         for (int i = 0; i < types.length; i++) {
  1527             result[offset++] = getRepositoryID(types[i]);
  1530         // If we're supposed to, reverse the array. This
  1531         // is only done when the -testReverseIDs flag is
  1532         // passed, and that should ONLY be done for test
  1533         // cases. This is an undocumented feature.
  1535         if (reverseIDs) {
  1536             int start = 0;
  1537             int end = result.length -1;
  1538             while (start < end) {
  1539                 String temp = result[start];
  1540                 result[start++] = result[end];
  1541                 result[end--] = temp;
  1545         return result;
  1548     /**
  1549      * Collect all the inherited remote interfaces.
  1550      */
  1551     Type[] collectAllRemoteInterfaces (CompoundType theType) {
  1552         Vector list = new Vector();
  1554         // Collect up all the Remote interfaces, and get an instance
  1555         // for java.rmi.Remote...
  1557         addRemoteInterfaces(list,theType);
  1559         // Create and return our results...
  1561         Type[] result = new Type[list.size()];
  1562         list.copyInto(result);
  1564         return result;
  1567     /**
  1568      * Add all the inherited remote interfaces to list.
  1569      */
  1570     void addRemoteInterfaces(Vector list, CompoundType theType) {
  1572         if (theType != null) {
  1573             if (theType.isInterface() && !list.contains(theType)) {
  1574                 list.addElement(theType);
  1577             InterfaceType[] interfaces = theType.getInterfaces();
  1578             for (int i = 0; i < interfaces.length; i++) {
  1580                 if (interfaces[i].isType(TYPE_REMOTE)) {
  1581                     addRemoteInterfaces(list,interfaces[i]);
  1585             addRemoteInterfaces(list,theType.getSuperclass());
  1589     /**
  1590      * Get a list of all the remote interfaces which this stub
  1591      * should declare.
  1592      */
  1593     RemoteType[] getDirectRemoteInterfaces (CompoundType theType) {
  1595         RemoteType[] result;
  1596         InterfaceType[] interfaces = theType.getInterfaces();
  1598         // First, get a list of all the interfaces...
  1600         InterfaceType[] list;
  1602         // Because we can be passed either an ImplementationType
  1603         // (which has interfaces) or a RemoteType (which is an
  1604         // interface and may have interfaces) we must handle each
  1605         // separately...
  1607         // Do we have an implementation type?
  1609         if (theType instanceof ImplementationType) {
  1611             // Yes, so list is exactly what this type
  1612             // implements and is correct already.
  1614             list = interfaces;
  1616         } else {
  1618             // No, so list is just theType...
  1620             list = new InterfaceType[1];
  1621             list[0] = (InterfaceType) theType;
  1624         // Ok, now count up the remote interfaces, allocate
  1625         // our result and fill it in...
  1627         int remoteCount = countRemote(list,false);
  1629         if (remoteCount == 0) {
  1630             throw new CompilerError("iiop.StubGenerator: No remote interfaces!");
  1633         result = new RemoteType[remoteCount];
  1634         int offset = 0;
  1635         for (int i = 0; i < list.length; i++) {
  1636             if (list[i].isType(TYPE_REMOTE)) {
  1637                 result[offset++] = (RemoteType)list[i];
  1641         return result;
  1644     int countRemote (Type[] list, boolean includeAbstract) {
  1645         int remoteCount = 0;
  1646         for (int i = 0; i < list.length; i++) {
  1647             if (list[i].isType(TYPE_REMOTE) &&
  1648                 (includeAbstract || !list[i].isType(TYPE_ABSTRACT))) {
  1649                 remoteCount++;
  1653         return remoteCount;
  1656     void writeCastArray(IndentingWriter p) throws IOException {
  1657         if (castArray) {
  1658             p.pln();
  1659             p.pln("// This method is required as a work-around for");
  1660             p.pln("// a bug in the JDK 1.1.6 verifier.");
  1661             p.pln();
  1662             p.plnI("private "+getName(idJavaIoSerializable)+" cast_array(Object obj) {");
  1663             p.pln("return ("+getName(idJavaIoSerializable)+")obj;");
  1664             p.pOln("}");
  1667     void writeIds(IndentingWriter p, CompoundType theType, boolean isTie
  1668                   ) throws IOException {
  1669         p.plnI("private static final String[] _type_ids = {");
  1671         String[] ids = getAllRemoteRepIDs(theType);
  1673         if (ids.length >0 ) {
  1674             for(int i = 0; i < ids.length; i++) {
  1675                 if (i > 0)
  1676                     p.pln(", ");
  1677                 p.p("\"" + ids[i] + "\"");
  1679         } else {
  1680            // Must be an implementation which only implements Remote...
  1681            p.pln("\"\"");
  1683         String qname = theType.getQualifiedName() ;
  1684         boolean isTransactional = isTie && transactionalObjects.containsKey( qname ) ;
  1685         // Add TransactionalObject if needed.
  1686         if (isTransactional) {
  1687             // Have already written an id.
  1688             p.pln( ", " ) ;
  1689             p.pln( "\"IDL:omg.org/CosTransactions/TransactionalObject:1.0\"" ) ;
  1690         } else if (ids.length > 0) {
  1691             p.pln();
  1693         p.pOln("};");
  1697     /**
  1698      * Write the Tie for the remote class to a stream.
  1699      */
  1700     protected void writeTie(OutputType outputType,
  1701                             IndentingWriter p) throws IOException
  1703         CompoundType theType = (CompoundType) outputType.getType();
  1704         RemoteType[] remoteInterfaces = null;
  1706         // Write comment...
  1707         p.pln("// Tie class generated by rmic, do not edit.");
  1708         p.pln("// Contents subject to change without notice.");
  1709         p.pln();
  1711         // Set our standard classes...
  1712         setStandardClassesInUse(theType,false);
  1714         // Add classes for this type...
  1715         addClassesInUse(theType,remoteInterfaces);
  1717         // Write package and import statements...
  1718         writePackageAndImports(p);
  1720         // Declare the tie class.
  1721         p.p("public class " + currentClass + " extends " +
  1722             getName(tieBaseClass) + " implements Tie");
  1724         // Add java.rmi.Remote if this type does not implement it.
  1725         // This allows stubs for Abstract interfaces to be treated
  1726         // uniformly...
  1727         if (!implementsRemote(theType)) {
  1728             p.pln(",");
  1729             p.p(getName("java.rmi.Remote"));
  1732         p.plnI(" {");
  1734         // Write data members...
  1735         p.pln();
  1736         p.pln("volatile private " + getName(theType) + " target = null;");
  1737         p.pln();
  1739         // Write the ids...
  1740         writeIds( p, theType, true ) ;
  1742         // Write setTarget method...
  1743         p.pln();
  1744         p.plnI("public void setTarget(Remote target) {");
  1745         p.pln("this.target = (" + getName(theType) + ") target;");
  1746         p.pOln("}");
  1748         // Write getTarget method...
  1749         p.pln();
  1750         p.plnI("public Remote getTarget() {");
  1751         p.pln("return target;");
  1752         p.pOln("}");
  1754         // Write thisObject method...
  1755         p.pln();
  1756         write_tie_thisObject_method(p,idCorbaObject);
  1758         // Write deactivate method...
  1759         p.pln();
  1760         write_tie_deactivate_method(p);
  1762         // Write get orb method...
  1763         p.pln();
  1764         p.plnI("public ORB orb() {");
  1765         p.pln("return _orb();");
  1766         p.pOln("}");
  1768         // Write set orb method...
  1769         p.pln();
  1770         write_tie_orb_method(p);
  1772         // Write the _ids() method...
  1773         p.pln();
  1774         write_tie__ids_method(p);
  1776         // Get all the methods...
  1777         CompoundType.Method[] remoteMethods = theType.getMethods();
  1779         // Register all the argument names used, plus our
  1780         // data member names...
  1782         addNamesInUse(remoteMethods);
  1783         addNameInUse("target");
  1784         addNameInUse("_type_ids");
  1786         // Write the _invoke method...
  1787         p.pln();
  1789         String in = getVariableName("in");
  1790         String _in = getVariableName("_in");
  1791         String ex = getVariableName("ex");
  1792         String method = getVariableName("method");
  1793         String reply = getVariableName("reply");
  1795         p.plnI("public OutputStream  _invoke(String "+method+", InputStream "+_in+", " +
  1796                "ResponseHandler "+reply+") throws SystemException {");
  1798         if (remoteMethods.length > 0) {
  1799             p.plnI("try {");
  1800             p.pln(getName(theType) + " target = this.target;");
  1801             p.plnI("if (target == null) {");
  1802             p.pln("throw new java.io.IOException();");
  1803             p.pOln("}");
  1804             p.plnI(idExtInputStream + " "+in+" = ");
  1805             p.pln("(" + idExtInputStream + ") "+_in+";");
  1806             p.pO();
  1808             // See if we should use a hash table style
  1809             // comparison...
  1811             StaticStringsHash hash = getStringsHash(remoteMethods);
  1813             if (hash != null) {
  1814                 p.plnI("switch ("+method+"."+hash.method+") {");
  1815                 for (int i = 0; i < hash.buckets.length; i++) {
  1816                     p.plnI("case "+hash.keys[i]+": ");
  1817                     for (int j = 0; j < hash.buckets[i].length; j++) {
  1818                         CompoundType.Method current = remoteMethods[hash.buckets[i][j]];
  1819                         if (j > 0) {
  1820                             p.pO("} else ");
  1822                         p.plnI("if ("+method+".equals(\""+ current.getIDLName() +"\")) {");
  1823                         writeTieMethod(p, theType,current);
  1825                     p.pOln("}");
  1826                     p.pO();
  1828             } else {
  1829                 for(int i = 0; i < remoteMethods.length; i++) {
  1830                 CompoundType.Method current = remoteMethods[i];
  1831                 if (i > 0) {
  1832                     p.pO("} else ");
  1835                 p.plnI("if ("+method+".equals(\""+ current.getIDLName() +"\")) {");
  1836                 writeTieMethod(p, theType, current);
  1840             if (hash != null) {
  1841                 p.pI();
  1842                 //        p.plnI("default:");
  1843             } else {
  1844                 //   p.pOlnI("} else {");
  1846             //              p.pln("throw new "+getName(idBadMethodException)+"();");
  1848             if (hash != null) {
  1849                 p.pO();
  1851             p.pOln("}");
  1852             p.pln("throw new "+getName(idBadMethodException)+"();");
  1854             p.pOlnI("} catch ("+getName(idSystemException)+" "+ex+") {");
  1855             p.pln("throw "+ex+";");
  1857             p.pOlnI("} catch ("+getName(idJavaLangThrowable)+" "+ex+") {");
  1858             p.pln("throw new " + getName(idPortableUnknownException) + "("+ex+");");
  1859             p.pOln("}");
  1860         } else {
  1861             // No methods...
  1863             p.pln("throw new " + getName(idBadMethodException) + "();");
  1866         p.pOln("}");            // end invoke
  1868         // Write the cast array hack...
  1870         writeCastArray(p);
  1872         // End tie class...
  1873         p.pOln("}");
  1875     public void catchWrongPolicy(IndentingWriter p) throws IOException {
  1876         p.pln("");
  1878     public void catchServantNotActive(IndentingWriter p) throws IOException {
  1879         p.pln("");
  1881     public void catchObjectNotActive(IndentingWriter p) throws IOException {
  1882         p.pln("");
  1885     public void write_tie_thisObject_method(IndentingWriter p,
  1886                                             Identifier idCorbaObject)
  1887         throws IOException
  1889         if(POATie){
  1890             p.plnI("public " + idCorbaObject + " thisObject() {");
  1891             /*
  1892             p.pln("org.omg.CORBA.Object objref = null;");
  1893             p.pln("try{");
  1894             p.pln("objref = _poa().servant_to_reference(this);");
  1895             p.pln("}catch (org.omg.PortableServer.POAPackage.WrongPolicy exception){");
  1896             catchWrongPolicy(p);
  1897             p.pln("}catch (org.omg.PortableServer.POAPackage.ServantNotActive exception){");
  1898             catchServantNotActive(p);
  1899             p.pln("}");
  1900             p.pln("return objref;");
  1901             */
  1902             p.pln("return _this_object();");
  1903             p.pOln("}");
  1904         } else {
  1905             p.plnI("public " + idCorbaObject + " thisObject() {");
  1906             p.pln("return this;");
  1907             p.pOln("}");
  1911     public void write_tie_deactivate_method(IndentingWriter p)
  1912         throws IOException
  1914         if(POATie){
  1915             p.plnI("public void deactivate() {");
  1916             p.pln("try{");
  1917             p.pln("_poa().deactivate_object(_poa().servant_to_id(this));");
  1918             p.pln("}catch (org.omg.PortableServer.POAPackage.WrongPolicy exception){");
  1919             catchWrongPolicy(p);
  1920             p.pln("}catch (org.omg.PortableServer.POAPackage.ObjectNotActive exception){");
  1921             catchObjectNotActive(p);
  1922             p.pln("}catch (org.omg.PortableServer.POAPackage.ServantNotActive exception){");
  1923             catchServantNotActive(p);
  1924             p.pln("}");
  1925             p.pOln("}");
  1926         } else {
  1927             p.plnI("public void deactivate() {");
  1928             p.pln("_orb().disconnect(this);");
  1929             p.pln("_set_delegate(null);");
  1930             p.pln("target = null;");
  1931             p.pOln("}");
  1935     public void write_tie_orb_method(IndentingWriter p)
  1936         throws IOException
  1938         if(POATie){
  1939         p.plnI("public void orb(ORB orb) {");
  1940         /*
  1941         p.pln("try{");
  1942         p.pln("orb.connect(_poa().servant_to_reference(this));");
  1943         p.pln("}catch (org.omg.PortableServer.POAPackage.WrongPolicy exception){");
  1944         catchWrongPolicy(p);
  1945         p.pln("}catch (org.omg.PortableServer.POAPackage.ServantNotActive exception){");
  1946         catchServantNotActive(p);
  1947         p.pln("}");
  1948         */
  1949         p.pln("try {");
  1950         p.pln("    ((org.omg.CORBA_2_3.ORB)orb).set_delegate(this);");
  1951         p.pln("}");
  1952         p.pln("catch(ClassCastException e) {");
  1953         p.pln("    throw new org.omg.CORBA.BAD_PARAM");
  1954         p.pln("        (\"POA Servant requires an instance of org.omg.CORBA_2_3.ORB\");");
  1955         p.pln("}");
  1956         p.pOln("}");
  1957         } else {
  1958         p.plnI("public void orb(ORB orb) {");
  1959         p.pln("orb.connect(this);");
  1960         p.pOln("}");
  1964     public void write_tie__ids_method(IndentingWriter p)
  1965         throws IOException
  1967         if(POATie){
  1968         p.plnI("public String[] _all_interfaces(org.omg.PortableServer.POA poa, byte[] objectId){");
  1969         p.pln("return (String[]) _type_ids.clone();");
  1970         p.pOln("}");
  1971         } else {
  1972         p.plnI("public String[] _ids() { ");
  1973         p.pln("return (String[]) _type_ids.clone();");
  1974         p.pOln("}");
  1979     StaticStringsHash getStringsHash (CompoundType.Method[] methods) {
  1980         if (useHash && methods.length > 1) {
  1981             String[] methodNames = new String[methods.length];
  1982             for (int i = 0; i < methodNames.length; i++) {
  1983                 methodNames[i] = methods[i].getIDLName();
  1985             return new StaticStringsHash(methodNames);
  1987         return null;
  1990     static boolean needNewReadStreamClass(Type type) {
  1991         if (type.isType(TYPE_ABSTRACT)) {
  1992             return true;
  1994         // Handle late-breaking special case for
  1995         // abstract IDL entities...
  1996         if ((type instanceof CompoundType) &&
  1997             ((CompoundType)type).isAbstractBase()) {
  1998             return true;
  2000         return needNewWriteStreamClass(type);
  2003     static boolean needNewWriteStreamClass(Type type) {
  2004         switch (type.getTypeCode()) {
  2005         case TYPE_VOID:
  2006         case TYPE_BOOLEAN:
  2007         case TYPE_BYTE:
  2008         case TYPE_CHAR:
  2009         case TYPE_SHORT:
  2010         case TYPE_INT:
  2011         case TYPE_LONG:
  2012         case TYPE_FLOAT:
  2013         case TYPE_DOUBLE:           return false;
  2015         case TYPE_STRING:           return true;
  2016         case TYPE_ANY:              return false;
  2017         case TYPE_CORBA_OBJECT:     return false;
  2018         case TYPE_REMOTE:           return false;
  2019         case TYPE_ABSTRACT:         return false;
  2020         case TYPE_NC_INTERFACE:     return true;
  2021         case TYPE_VALUE:            return true;
  2022         case TYPE_IMPLEMENTATION:   return true;
  2023         case TYPE_NC_CLASS:         return true;
  2024         case TYPE_ARRAY:            return true;
  2025         case TYPE_JAVA_RMI_REMOTE:  return false;
  2027         default: throw new Error("unexpected type code: " + type.getTypeCode());
  2031     /*
  2032      * Decide which arguments need to be copied and write
  2033      * the copy code. Returns an array of argument names to
  2034      * use to refer to either the copy or the original.
  2035      */
  2036     String[] writeCopyArguments(CompoundType.Method method,
  2037                                 IndentingWriter p) throws IOException {
  2039         Type[] args = method.getArguments();
  2040         String[] origNames = method.getArgumentNames();
  2042         // Copy the current parameter names to a result array...
  2044         String[] result = new String[origNames.length];
  2045         for (int i = 0; i < result.length; i++) {
  2046             result[i] = origNames[i];
  2049         // Decide which arguments must be copied, if any. If
  2050         // any of the arguments are types for which a 'real' copy
  2051         // will be done, rather than just an autoConnect, set
  2052         // realCopy = true. Note that abstract types may only
  2053         // need autoConnect, but we cannot know that at compile
  2054         // time...
  2056         boolean realCopy = false;
  2057         boolean[] copyArg = new boolean[args.length];
  2058         int copyCount = 0;
  2059         int firstCopiedArg = 0; // Only used in single copy case.  It is only the first arg that
  2060                                 // needs copying IF copyCount == 1.
  2062         for (int i = 0; i < args.length; i++) {
  2063             if (mustCopy(args[i])) {
  2064                 copyArg[i] = true;
  2065                 copyCount++;
  2066                 firstCopiedArg = i;
  2067                 if (args[i].getTypeCode() != TYPE_REMOTE &&
  2068                     args[i].getTypeCode() != TYPE_IMPLEMENTATION) {
  2069                     realCopy = true;
  2071             } else {
  2072                 copyArg[i] = false;
  2076         // Do we have any types which must be copied?
  2077         if (copyCount > 0) {
  2078             // Yes. Are we only doing the copy to ensure
  2079             // that autoConnect occurs?
  2080             if (realCopy) {
  2081                 // Nope. We need to go back thru the list and
  2082                 // mark any strings so that they will be copied
  2083                 // to preserve any shared references...
  2084                 for (int i = 0; i < args.length; i++) {
  2085                     if (args[i].getTypeCode() == TYPE_STRING) {
  2086                         copyArg[i] = true;
  2087                         copyCount++;
  2092             // We're ready to generate code. Do we have more than
  2093             // one to copy?
  2094             if (copyCount > 1) {
  2095                 // Generate a call to copyObjects...
  2096                 String arrayName = getVariableName("copies");
  2097                 p.p("Object[] " + arrayName + " = Util.copyObjects(new Object[]{");
  2098                 boolean first = true;
  2099                 for (int i = 0; i < args.length; i++) {
  2100                     if (copyArg[i]) {
  2101                         if (!first) {
  2102                             p.p(",");
  2104                         first = false;
  2105                         p.p(origNames[i]);
  2108                 p.pln("},_orb());");
  2110                 // For each of the types which was copied, create
  2111                 // a local temporary for it, updating the result
  2112                 // array with the new local parameter name...
  2113                 int copyIndex = 0 ;
  2114                 for (int i = 0; i < args.length; i++) {
  2115                     if (copyArg[i]) {
  2116                         result[i] = getVariableName(result[i]+"Copy");
  2117                         p.pln( getName(args[i]) + " " + result[i] + " = (" + getName(args[i]) + ") " +
  2118                                arrayName + "[" + copyIndex++ +"];");
  2121             } else {
  2122                 // Generate a call to copyObject, updating the result
  2123                 // with the new local parameter name...
  2124                 result[firstCopiedArg] = getVariableName(result[firstCopiedArg]+"Copy");
  2125                 p.pln( getName(args[firstCopiedArg]) + " " + result[firstCopiedArg] + " = (" +
  2126                        getName(args[firstCopiedArg]) + ") Util.copyObject(" +
  2127                        origNames[firstCopiedArg] + ",_orb());");
  2131         return result;
  2134     static final String SINGLE_SLASH = "\\";
  2135     static final String DOUBLE_SLASH = SINGLE_SLASH + SINGLE_SLASH;
  2137     String getRepositoryID(Type type) {
  2138         return IDLNames.replace(type.getRepositoryID(), SINGLE_SLASH, DOUBLE_SLASH);
  2141     String getExceptionRepositoryID(Type type) {
  2142         ClassType theType = (ClassType) type;
  2143         return IDLNames.getIDLRepositoryID(theType.getQualifiedIDLExceptionName(false));
  2146     String getVariableName(String proposed) {
  2147         while (namesInUse.contains(proposed)) {
  2148             proposed = "$" + proposed;
  2151         return proposed;
  2154     void addNamesInUse(CompoundType.Method[] methods) {
  2155         for (int i = 0; i < methods.length; i++) {
  2156             addNamesInUse(methods[i]);
  2160     void addNamesInUse(CompoundType.Method method) {
  2161         String paramNames[] = method.getArgumentNames();
  2162         for (int i = 0; i < paramNames.length; i++) {
  2163             addNameInUse(paramNames[i]);
  2167     void addNameInUse(String name) {
  2168         namesInUse.add(name);
  2171     static boolean mustCopy(Type type) {
  2172         switch (type.getTypeCode()) {
  2173         case TYPE_VOID:
  2174         case TYPE_BOOLEAN:
  2175         case TYPE_BYTE:
  2176         case TYPE_CHAR:
  2177         case TYPE_SHORT:
  2178         case TYPE_INT:
  2179         case TYPE_LONG:
  2180         case TYPE_FLOAT:
  2181         case TYPE_DOUBLE:
  2182         case TYPE_STRING:           return false;
  2184         case TYPE_ANY:              return true;
  2186         case TYPE_CORBA_OBJECT:     return false;
  2188         case TYPE_REMOTE:
  2189         case TYPE_ABSTRACT:
  2190         case TYPE_NC_INTERFACE:
  2191         case TYPE_VALUE:
  2192         case TYPE_IMPLEMENTATION:
  2193         case TYPE_NC_CLASS:
  2194         case TYPE_ARRAY:
  2195         case TYPE_JAVA_RMI_REMOTE:  return true;
  2197         default: throw new Error("unexpected type code: " + type.getTypeCode());
  2201     ValueType[] getStubExceptions (CompoundType.Method method, boolean sort) {
  2203         ValueType[] list = method.getFilteredStubExceptions(method.getExceptions());
  2205         // Sort the list so that all org.omg.CORBA.UserException
  2206         // subtypes are at the beginning of the list.  This ensures
  2207         // that the stub will not call read_string() before calling
  2208         // XXHelper.read().
  2210         if (sort) {
  2211             Arrays.sort(list,new UserExceptionComparator());
  2214         return list;
  2217     ValueType[] getTieExceptions (CompoundType.Method method) {
  2218         return method.getUniqueCatchList(method.getImplExceptions());
  2221     void writeTieMethod(IndentingWriter p, CompoundType type,
  2222                         CompoundType.Method method) throws IOException {
  2223         String methodName = method.getName();
  2224         Type paramTypes[] = method.getArguments();
  2225         String paramNames[] = method.getArgumentNames();
  2226         Type returnType = method.getReturnType();
  2227         ValueType[] exceptions = getTieExceptions(method);
  2228         String in = getVariableName("in");
  2229         String ex = getVariableName("ex");
  2230         String out = getVariableName("out");
  2231         String reply = getVariableName("reply");
  2233         for (int i = 0; i < paramTypes.length; i++) {
  2234             p.p(getName(paramTypes[i])+" "+paramNames[i]+" = ");
  2235             writeUnmarshalArgument(p, in, paramTypes[i], null);
  2236             p.pln();
  2239         boolean handleExceptions = exceptions != null;
  2240         boolean doReturn = !returnType.isType(TYPE_VOID);
  2242         if (handleExceptions && doReturn) {
  2243             String objName = testUtil(getName(returnType), returnType);
  2244             p.pln(objName+" result;");
  2247         if (handleExceptions)
  2248             p.plnI("try {");
  2250         if (doReturn) {
  2251             if (handleExceptions) {
  2252                 p.p("result = ");
  2253             } else {
  2254                 p.p(getName(returnType)+" result = ");
  2258         p.p("target."+methodName+"(");
  2259         for(int i = 0; i < paramNames.length; i++) {
  2260             if (i > 0)
  2261                 p.p(", ");
  2262             p.p(paramNames[i]);
  2264         p.pln(");");
  2266         if (handleExceptions) {
  2267             for(int i = 0; i < exceptions.length; i++) {
  2268                 p.pOlnI("} catch ("+getName(exceptions[i])+" "+ex+") {");
  2270                 // Is this our IDLEntity Exception special case?
  2272                 if (exceptions[i].isIDLEntityException() && !exceptions[i].isCORBAUserException()) {
  2274                                 // Yes...
  2276                     String helperName = IDLNames.replace(exceptions[i].getQualifiedIDLName(false),"::",".");
  2277                     helperName += "Helper";
  2278                     p.pln(idOutputStream+" "+out +" = "+reply+".createExceptionReply();");
  2279                     p.pln(helperName+".write("+out+","+ex+");");
  2281                 } else {
  2283                                 // No...
  2285                     p.pln("String id = \"" + getExceptionRepositoryID(exceptions[i]) + "\";");
  2286                 p.plnI(idExtOutputStream + " "+out+" = ");
  2287                 p.pln("(" + idExtOutputStream + ") "+reply+".createExceptionReply();");
  2288                 p.pOln(out+".write_string(id);");
  2289                     p.pln(out+".write_value("+ex+"," + getName(exceptions[i]) + ".class);");
  2292                 p.pln("return "+out+";");
  2294             p.pOln("}");
  2297         if (needNewWriteStreamClass(returnType)) {
  2298             p.plnI(idExtOutputStream + " "+out+" = ");
  2299             p.pln("(" + idExtOutputStream + ") "+reply+".createReply();");
  2300             p.pO();
  2301         } else {
  2302             p.pln("OutputStream "+out+" = "+reply+".createReply();");
  2305         if (doReturn) {
  2306             writeMarshalArgument(p, out, returnType, "result");
  2307             p.pln();
  2310         p.pln("return "+out+";");
  2314     /**
  2315      * Write Java statements to marshal a series of values in order as
  2316      * named in the "names" array, with types as specified in the "types"
  2317      * array", to the java.io.ObjectOutput stream named "stream".
  2318      */
  2319     void writeMarshalArguments(IndentingWriter p,
  2320                                String streamName,
  2321                                Type[] types, String[] names)
  2322         throws IOException
  2324         if (types.length != names.length) {
  2325             throw new Error("paramter type and name arrays different sizes");
  2328         for (int i = 0; i < types.length; i++) {
  2329             writeMarshalArgument(p, streamName, types[i], names[i]);
  2330             if (i != types.length -1) {
  2331                 p.pln();
  2336     /**
  2337      * Added for IASRI 4987274. Remote classes named "Util" were
  2338      * getting confused with javax.rmi.CORBA.Util and the
  2339      * unqualifiedName "Util".
  2340      */
  2341     String testUtil(String objectName, Type ttype) {
  2342         if (objectName.equals("Util")) {
  2343                 String correctedName = (String)ttype.getPackageName() + "." + objectName;
  2344                 return correctedName;
  2345         } else {
  2346                 return objectName;
  2351 class StringComparator implements java.util.Comparator {
  2352     public int compare(Object o1, Object o2) {
  2353         String s1 = (String)o1;
  2354         String s2 = (String)o2;
  2355         return s1.compareTo(s2);
  2360 class UserExceptionComparator implements java.util.Comparator {
  2361     public int compare(Object o1, Object o2) {
  2362         ValueType v1 = (ValueType)o1;
  2363         ValueType v2 = (ValueType)o2;
  2364         int result = 0;
  2365         if (isUserException(v1)) {
  2366             if (!isUserException(v2)) {
  2367                 result = -1;
  2369         } else if (isUserException(v2)) {
  2370             if (!isUserException(v1)) {
  2371                 result = 1;
  2374         return result;
  2377     final boolean isUserException(ValueType it) {
  2378         return it.isIDLEntityException() && !it.isCORBAUserException();

mercurial