1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/sun/rmi/rmic/iiop/StubGenerator.java Wed Apr 27 01:21:28 2016 +0800 1.3 @@ -0,0 +1,2349 @@ 1.4 +/* 1.5 + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +/* 1.30 + * Licensed Materials - Property of IBM 1.31 + * RMI-IIOP v1.0 1.32 + * Copyright IBM Corp. 1998 1999 All Rights Reserved 1.33 + * 1.34 + */ 1.35 + 1.36 +package sun.rmi.rmic.iiop; 1.37 + 1.38 +import java.io.File; 1.39 +import java.io.IOException; 1.40 +import java.io.SerializablePermission; 1.41 +import java.security.AccessController; 1.42 +import java.security.PrivilegedAction; 1.43 +import java.util.Vector; 1.44 +import java.util.Hashtable; 1.45 +import java.util.Enumeration; 1.46 +import sun.tools.java.Identifier; 1.47 +import sun.tools.java.ClassNotFound; 1.48 +import sun.tools.java.ClassDefinition; 1.49 +import sun.tools.java.ClassDeclaration; 1.50 +import sun.tools.java.CompilerError; 1.51 +import sun.rmi.rmic.IndentingWriter; 1.52 +import java.util.HashSet; 1.53 +import java.util.Arrays; 1.54 +import com.sun.corba.se.impl.util.Utility; 1.55 +import com.sun.corba.se.impl.util.PackagePrefixChecker; 1.56 +import sun.rmi.rmic.Main; 1.57 + 1.58 + 1.59 +/** 1.60 + * An IIOP stub/tie generator for rmic. 1.61 + * 1.62 + * @author Bryan Atsatt 1.63 + * @author Anil Vijendran 1.64 + * @author M. Mortazavi 1.65 + */ 1.66 + 1.67 +public class StubGenerator extends sun.rmi.rmic.iiop.Generator { 1.68 + 1.69 + private static final String DEFAULT_STUB_CLASS = "javax.rmi.CORBA.Stub"; 1.70 + private static final String DEFAULT_TIE_CLASS = "org.omg.CORBA_2_3.portable.ObjectImpl"; 1.71 + private static final String DEFAULT_POA_TIE_CLASS = "org.omg.PortableServer.Servant"; 1.72 + 1.73 + protected boolean reverseIDs = false; 1.74 + protected boolean localStubs = true; 1.75 + protected boolean standardPackage = false; 1.76 + protected boolean useHash = true; 1.77 + protected String stubBaseClass = DEFAULT_STUB_CLASS; 1.78 + protected String tieBaseClass = DEFAULT_TIE_CLASS; 1.79 + protected HashSet namesInUse = new HashSet(); 1.80 + protected Hashtable classesInUse = new Hashtable(); 1.81 + protected Hashtable imports = new Hashtable(); 1.82 + protected int importCount = 0; 1.83 + protected String currentPackage = null; 1.84 + protected String currentClass = null; 1.85 + protected boolean castArray = false; 1.86 + protected Hashtable transactionalObjects = new Hashtable() ; 1.87 + protected boolean POATie = false ; 1.88 + protected boolean emitPermissionCheck = false; 1.89 + 1.90 + /** 1.91 + * Default constructor for Main to use. 1.92 + */ 1.93 + public StubGenerator() { 1.94 + } 1.95 + 1.96 + /** 1.97 + * Overridden in order to set the standardPackage flag. 1.98 + */ 1.99 + public void generate( 1.100 + sun.rmi.rmic.BatchEnvironment env, 1.101 + ClassDefinition cdef, File destDir) { 1.102 + ((sun.rmi.rmic.iiop.BatchEnvironment)env). 1.103 + setStandardPackage(standardPackage); 1.104 + super.generate(env, cdef, destDir); 1.105 + } 1.106 + 1.107 + /** 1.108 + * Return true if a new instance should be created for each 1.109 + * class on the command line. Subclasses which return true 1.110 + * should override newInstance() to return an appropriately 1.111 + * constructed instance. 1.112 + */ 1.113 + protected boolean requireNewInstance() { 1.114 + return false; 1.115 + } 1.116 + 1.117 + /** 1.118 + * Return true if non-conforming types should be parsed. 1.119 + * @param stack The context stack. 1.120 + */ 1.121 + protected boolean parseNonConforming(ContextStack stack) { 1.122 + 1.123 + // We let the environment setting decide so that 1.124 + // another generator (e.g. IDLGenerator) can change 1.125 + // it and we will just go with the flow... 1.126 + 1.127 + return stack.getEnv().getParseNonConforming(); 1.128 + } 1.129 + 1.130 + /** 1.131 + * Create and return a top-level type. 1.132 + * @param cdef The top-level class definition. 1.133 + * @param stack The context stack. 1.134 + * @return The compound type or null if is non-conforming. 1.135 + */ 1.136 + protected CompoundType getTopType(ClassDefinition cdef, ContextStack stack) { 1.137 + 1.138 + CompoundType result = null; 1.139 + 1.140 + // Do we have an interface? 1.141 + 1.142 + if (cdef.isInterface()) { 1.143 + 1.144 + // Yes, so first try Abstract... 1.145 + 1.146 + result = AbstractType.forAbstract(cdef,stack,true); 1.147 + 1.148 + if (result == null) { 1.149 + 1.150 + // Then try Remote... 1.151 + 1.152 + result = RemoteType.forRemote(cdef,stack,false); 1.153 + } 1.154 + } else { 1.155 + 1.156 + // Not an interface, so try Implementation... 1.157 + 1.158 + result = ImplementationType.forImplementation(cdef,stack,false); 1.159 + } 1.160 + 1.161 + return result; 1.162 + } 1.163 + 1.164 + /** 1.165 + * Examine and consume command line arguments. 1.166 + * @param argv The command line arguments. Ignore null 1.167 + * and unknown arguments. Set each consumed argument to null. 1.168 + * @param error Report any errors using the main.error() methods. 1.169 + * @return true if no errors, false otherwise. 1.170 + */ 1.171 + public boolean parseArgs(String argv[], Main main) { 1.172 + Object marker = new Object() ; 1.173 + 1.174 + // Reset any cached options... 1.175 + 1.176 + reverseIDs = false; 1.177 + localStubs = true; 1.178 + useHash = true; 1.179 + stubBaseClass = DEFAULT_STUB_CLASS; 1.180 + // tieBaseClass = DEFAULT_TIE_CLASS; 1.181 + transactionalObjects = new Hashtable() ; 1.182 + 1.183 + // Parse options... 1.184 + 1.185 + boolean result = super.parseArgs(argv,main); 1.186 + if (result) { 1.187 + for (int i = 0; i < argv.length; i++) { 1.188 + if (argv[i] != null) { 1.189 + String arg = argv[i].toLowerCase(); 1.190 + if (arg.equals("-iiop")) { 1.191 + argv[i] = null; 1.192 + } else if (arg.equals("-xreverseids")) { 1.193 + reverseIDs = true; 1.194 + argv[i] = null; 1.195 + } else if (arg.equals("-nolocalstubs")) { 1.196 + localStubs = false; 1.197 + argv[i] = null; 1.198 + } else if (arg.equals("-xnohash")) { 1.199 + useHash = false; 1.200 + argv[i] = null; 1.201 + } else if (argv[i].equals("-standardPackage")) { 1.202 + standardPackage = true; 1.203 + argv[i] = null; 1.204 + } else if (argv[i].equals("-emitPermissionCheck")) { 1.205 + emitPermissionCheck = true; 1.206 + argv[i] = null; 1.207 + } else if (arg.equals("-xstubbase")) { 1.208 + argv[i] = null; 1.209 + if (++i < argv.length && argv[i] != null && !argv[i].startsWith("-")) { 1.210 + stubBaseClass = argv[i]; 1.211 + argv[i] = null; 1.212 + } else { 1.213 + main.error("rmic.option.requires.argument", "-Xstubbase"); 1.214 + result = false; 1.215 + } 1.216 + } else if (arg.equals("-xtiebase")) { 1.217 + argv[i] = null; 1.218 + if (++i < argv.length && argv[i] != null && !argv[i].startsWith("-")) { 1.219 + tieBaseClass = argv[i]; 1.220 + argv[i] = null; 1.221 + } else { 1.222 + main.error("rmic.option.requires.argument", "-Xtiebase"); 1.223 + result = false; 1.224 + } 1.225 + } else if (arg.equals("-transactional" )) { 1.226 + // Scan for the next non-flag argument. 1.227 + // Assume that it is a class name and add it 1.228 + // to the list of transactional classes. 1.229 + for ( int ctr=i+1; ctr<argv.length; ctr++ ) { 1.230 + if (argv[ctr].charAt(1) != '-') { 1.231 + transactionalObjects.put( argv[ctr], marker ) ; 1.232 + break ; 1.233 + } 1.234 + } 1.235 + argv[i] = null; 1.236 + } else if (arg.equals( "-poa" )) { 1.237 + POATie = true ; 1.238 + argv[i] = null; 1.239 + } 1.240 + } 1.241 + } 1.242 + } 1.243 + if(POATie){ 1.244 + tieBaseClass = DEFAULT_POA_TIE_CLASS; 1.245 + } else { 1.246 + tieBaseClass = DEFAULT_TIE_CLASS; 1.247 + } 1.248 + return result; 1.249 + } 1.250 + 1.251 + /** 1.252 + * Return an array containing all the file names and types that need to be 1.253 + * generated for the given top-level type. The file names must NOT have an 1.254 + * extension (e.g. ".java"). 1.255 + * @param topType The type returned by getTopType(). 1.256 + * @param alreadyChecked A set of Types which have already been checked. 1.257 + * Intended to be passed to topType.collectMatching(filter,alreadyChecked). 1.258 + */ 1.259 + protected OutputType[] getOutputTypesFor(CompoundType topType, 1.260 + HashSet alreadyChecked) { 1.261 + 1.262 + // We want to generate stubs for all remote and implementation types, 1.263 + // so collect them up. 1.264 + // 1.265 + // We use the form of collectMatching which allows us to pass in a set of 1.266 + // types which have previously been checked. By doing so, we ensure that if 1.267 + // the command line contains Hello and HelloImpl, we will only generate 1.268 + // output for Hello once... 1.269 + 1.270 + int filter = TYPE_REMOTE | TYPE_IMPLEMENTATION; 1.271 + Type[] genTypes = topType.collectMatching(filter,alreadyChecked); 1.272 + int count = genTypes.length; 1.273 + Vector list = new Vector(count+5); 1.274 + BatchEnvironment theEnv = topType.getEnv(); 1.275 + 1.276 + // Now walk all types... 1.277 + 1.278 + for (int i = 0; i < genTypes.length; i++) { 1.279 + 1.280 + Type type = genTypes[i]; 1.281 + String typeName = type.getName(); 1.282 + boolean createStub = true; 1.283 + 1.284 + // Is it an implementation type? 1.285 + 1.286 + if (type instanceof ImplementationType) { 1.287 + 1.288 + // Yes, so add a tie for it... 1.289 + 1.290 + list.addElement(new OutputType(Utility.tieNameForCompiler(typeName), type)); 1.291 + 1.292 + // Does it have more than 1 remote interface? If so, we 1.293 + // want to create a stub for it... 1.294 + 1.295 + int remoteInterfaceCount = 0; 1.296 + InterfaceType[] interfaces = ((CompoundType)type).getInterfaces(); 1.297 + for (int j = 0; j < interfaces.length; j++) { 1.298 + if (interfaces[j].isType(TYPE_REMOTE) && 1.299 + !interfaces[j].isType(TYPE_ABSTRACT)) { 1.300 + remoteInterfaceCount++; 1.301 + } 1.302 + } 1.303 + 1.304 + if (remoteInterfaceCount <= 1) { 1.305 + 1.306 + // No, so do not create a stub for this type... 1.307 + 1.308 + createStub = false; 1.309 + } 1.310 + } 1.311 + 1.312 + // Is it an abstract interface type? 1.313 + 1.314 + if (type instanceof AbstractType) { 1.315 + 1.316 + // Do not create a stub for this type... 1.317 + 1.318 + createStub = false; // d11141 1.319 + } 1.320 + 1.321 + if (createStub) { 1.322 + 1.323 + // Add a stub for the type... 1.324 + 1.325 + list.addElement(new OutputType(Utility.stubNameForCompiler(typeName), type)); 1.326 + } 1.327 + } 1.328 + 1.329 + // Copy list into array.. 1.330 + 1.331 + OutputType[] outputTypes = new OutputType[list.size()]; 1.332 + list.copyInto(outputTypes); 1.333 + return outputTypes; 1.334 + } 1.335 + 1.336 + /** 1.337 + * Return the file name extension for the given file name (e.g. ".java"). 1.338 + * All files generated with the ".java" extension will be compiled. To 1.339 + * change this behavior for ".java" files, override the compileJavaSourceFile 1.340 + * method to return false. 1.341 + * @param outputType One of the items returned by getOutputTypesFor(...) 1.342 + */ 1.343 + protected String getFileNameExtensionFor(OutputType outputType) { 1.344 + return SOURCE_FILE_EXTENSION; 1.345 + } 1.346 + 1.347 + /** 1.348 + * Write the output for the given OutputFileName into the output stream. 1.349 + * @param name One of the items returned by getOutputTypesFor(...) 1.350 + * @param alreadyChecked A set of Types which have already been checked. 1.351 + * Intended to be passed to Type.collectMatching(filter,alreadyChecked). 1.352 + * @param writer The output stream. 1.353 + */ 1.354 + protected void writeOutputFor( OutputType outputType, 1.355 + HashSet alreadyChecked, 1.356 + IndentingWriter writer) throws IOException { 1.357 + 1.358 + String fileName = outputType.getName(); 1.359 + CompoundType theType = (CompoundType) outputType.getType(); 1.360 + 1.361 + // Are we doing a Stub or Tie? 1.362 + 1.363 + if (fileName.endsWith(Utility.RMI_STUB_SUFFIX)) { 1.364 + 1.365 + // Stub. 1.366 + 1.367 + writeStub(outputType,writer); 1.368 + 1.369 + } else { 1.370 + 1.371 + // Tie 1.372 + 1.373 + writeTie(outputType,writer); 1.374 + } 1.375 + } 1.376 + 1.377 + /** 1.378 + * Write a stub for the specified type. 1.379 + */ 1.380 + protected void writeStub(OutputType outputType, 1.381 + IndentingWriter p) throws IOException { 1.382 + 1.383 + CompoundType theType = (CompoundType) outputType.getType(); 1.384 + RemoteType[] remoteInterfaces = getDirectRemoteInterfaces(theType); 1.385 + 1.386 + // Write comment. 1.387 + 1.388 + p.pln("// Stub class generated by rmic, do not edit."); 1.389 + p.pln("// Contents subject to change without notice."); 1.390 + p.pln(); 1.391 + 1.392 + // Set our standard classes... 1.393 + 1.394 + setStandardClassesInUse(theType,true); 1.395 + 1.396 + // Add classes for this type... 1.397 + 1.398 + addClassesInUse(theType,remoteInterfaces); 1.399 + 1.400 + // Write package and import statements... 1.401 + 1.402 + writePackageAndImports(p); 1.403 + 1.404 +// generate 1.405 +// import java.security.AccessController; 1.406 +// import java.security.PrivilegedAction; 1.407 +// import java.io.SerializablePermission; 1.408 + if (emitPermissionCheck) { 1.409 + p.pln("import java.security.AccessController;"); 1.410 + p.pln("import java.security.PrivilegedAction;"); 1.411 + p.pln("import java.io.SerializablePermission;"); 1.412 + p.pln(); 1.413 + p.pln(); 1.414 + } 1.415 + 1.416 + // Declare the stub class; implement all remote interfaces. 1.417 + 1.418 + p.p("public class " + currentClass); 1.419 + 1.420 + p.p(" extends " + getName(stubBaseClass)); 1.421 + p.p(" implements "); 1.422 + if (remoteInterfaces.length > 0) { 1.423 + for(int i = 0; i < remoteInterfaces.length; i++) { 1.424 + if (i > 0) { 1.425 + p.pln(","); 1.426 + } 1.427 + String objName = testUtil(getName(remoteInterfaces[i]), theType); 1.428 + p.p(objName); 1.429 + } 1.430 + } 1.431 + 1.432 + // Add java.rmi.Remote if this type does not implement it. 1.433 + // This allows stubs for Abstract interfaces to be treated 1.434 + // uniformly... 1.435 + 1.436 + if (!implementsRemote(theType)) { 1.437 + p.pln(","); 1.438 + p.p(getName("java.rmi.Remote")); 1.439 + } 1.440 + 1.441 + p.plnI(" {"); 1.442 + p.pln(); 1.443 + 1.444 + // Write the ids... 1.445 + 1.446 + writeIds( p, theType, false ); 1.447 + p.pln(); 1.448 + 1.449 + if (emitPermissionCheck) { 1.450 + 1.451 + // produce the following generated code for example 1.452 + // private static Void checkPermission() { 1.453 + // SecurityManager sm = System.getSecurityManager(); 1.454 + // if (sm != null) { 1.455 + // sm.checkPermission(new SerializablePermission( 1.456 + // "enableSubclassImplementation")); // testing 1.457 + // } 1.458 + // return null; 1.459 + // } 1.460 + // 1.461 + // private _XXXXX_Stub(Void ignore) { 1.462 + // } 1.463 + // 1.464 + // public _XXXXX_Stub() { 1.465 + // this(checkPermission()); 1.466 + // } 1.467 + // 1.468 + // where XXXXX is the name of the remote interface 1.469 + 1.470 + p.pln(); 1.471 + p.plnI("private static Void checkPermission() {"); 1.472 + p.plnI("SecurityManager sm = System.getSecurityManager();"); 1.473 + p.pln("if (sm != null) {"); 1.474 + p.pI(); 1.475 + p.plnI("sm.checkPermission(new SerializablePermission("); 1.476 + p.plnI("\"enableSubclassImplementation\"));"); 1.477 + p.pO(); 1.478 + p.pO(); 1.479 + p.pOln("}"); 1.480 + p.pln("return null;"); 1.481 + p.pO(); 1.482 + p.pOln("}"); 1.483 + p.pln(); 1.484 + p.pO(); 1.485 + 1.486 + p.pI(); 1.487 + p.pln("private " + currentClass + "(Void ignore) { }"); 1.488 + p.pln(); 1.489 + 1.490 + p.plnI("public " + currentClass + "() { "); 1.491 + p.pln("this(checkPermission());"); 1.492 + p.pOln("}"); 1.493 + p.pln(); 1.494 + } 1.495 + 1.496 + if (!emitPermissionCheck) { 1.497 + p.pI(); 1.498 + } 1.499 + 1.500 + // Write the _ids() method... 1.501 + 1.502 + p.plnI("public String[] _ids() { "); 1.503 + p.pln("return (String[]) _type_ids.clone();"); 1.504 + p.pOln("}"); 1.505 + 1.506 + // Get all the methods and write each stub method... 1.507 + 1.508 + CompoundType.Method[] remoteMethods = theType.getMethods(); 1.509 + int methodCount = remoteMethods.length; 1.510 + if (methodCount > 0) { 1.511 + boolean writeHeader = true; 1.512 + for(int i = 0; i < methodCount; i++) { 1.513 + if (!remoteMethods[i].isConstructor()) { 1.514 + if (writeHeader) { 1.515 + writeHeader = false; 1.516 + } 1.517 + p.pln(); 1.518 + writeStubMethod(p, remoteMethods[i], theType); 1.519 + } 1.520 + } 1.521 + } 1.522 + 1.523 + // Write the cast array hack... 1.524 + 1.525 + writeCastArray(p); 1.526 + 1.527 + p.pOln("}"); // end stub class 1.528 + } 1.529 + 1.530 + void addClassInUse(String qualifiedName) { 1.531 + String unqualifiedName = qualifiedName; 1.532 + String packageName = null; 1.533 + int index = qualifiedName.lastIndexOf('.'); 1.534 + if (index > 0) { 1.535 + unqualifiedName = qualifiedName.substring(index+1); 1.536 + packageName = qualifiedName.substring(0,index); 1.537 + } 1.538 + addClassInUse(unqualifiedName,qualifiedName,packageName); 1.539 + } 1.540 + 1.541 + void addClassInUse(Type type) { 1.542 + if (!type.isPrimitive()) { 1.543 + Identifier id = type.getIdentifier(); 1.544 + String name = IDLNames.replace(id.getName().toString(),". ","."); 1.545 + String packageName = type.getPackageName(); 1.546 + String qualifiedName; 1.547 + if (packageName != null) { 1.548 + qualifiedName = packageName+"."+name; 1.549 + } else { 1.550 + qualifiedName = name; 1.551 + } 1.552 + addClassInUse(name,qualifiedName,packageName); 1.553 + } 1.554 + } 1.555 + 1.556 + void addClassInUse(Type[] types) { 1.557 + for (int i = 0; i < types.length; i++) { 1.558 + addClassInUse(types[i]); 1.559 + } 1.560 + } 1.561 + 1.562 + void addStubInUse(Type type) { 1.563 + if (type.getIdentifier() != idCorbaObject && 1.564 + type.isType(TYPE_CORBA_OBJECT)) { 1.565 + String stubName = getStubNameFor(type,false); 1.566 + String packageName = type.getPackageName(); 1.567 + String fullName; 1.568 + if (packageName == null) { 1.569 + fullName = stubName; 1.570 + } else { 1.571 + fullName = packageName + "." + stubName; 1.572 + } 1.573 + addClassInUse(stubName,fullName,packageName); 1.574 + } 1.575 + if (type.isType(TYPE_REMOTE) || 1.576 + type.isType(TYPE_JAVA_RMI_REMOTE)) { 1.577 + addClassInUse("javax.rmi.PortableRemoteObject"); 1.578 + } 1.579 + } 1.580 + 1.581 + String getStubNameFor(Type type, boolean qualified) { 1.582 + String stubName; 1.583 + String className; 1.584 + if (qualified) { 1.585 + className = type.getQualifiedName(); 1.586 + } else { 1.587 + className = type.getName(); 1.588 + } 1.589 + if (((CompoundType)type).isCORBAObject()) { 1.590 + stubName = Utility.idlStubName(className); 1.591 + } else { 1.592 + stubName = Utility.stubNameForCompiler(className); 1.593 + } 1.594 + return stubName; 1.595 + } 1.596 + 1.597 + void addStubInUse(Type[] types) { 1.598 + for (int i = 0; i < types.length; i++) { 1.599 + addStubInUse(types[i]); 1.600 + } 1.601 + } 1.602 + 1.603 + private static final String NO_IMPORT = new String(); 1.604 + 1.605 + void addClassInUse(String unqualifiedName, String qualifiedName, String packageName) { 1.606 + 1.607 + // Have we already got an entry for this qualifiedName? 1.608 + 1.609 + String currentName = (String)classesInUse.get(qualifiedName); 1.610 + 1.611 + if (currentName == null) { 1.612 + 1.613 + // No, never seen it before. Grab any existing import 1.614 + // name and then decide what to do... 1.615 + 1.616 + String importName = (String) imports.get(unqualifiedName); 1.617 + String nameToUse = null; 1.618 + 1.619 + if (packageName == null) { 1.620 + 1.621 + // Default package, so doesn't matter which name to use... 1.622 + 1.623 + nameToUse = unqualifiedName; 1.624 + 1.625 + } else if (packageName.equals("java.lang")) { 1.626 + 1.627 + // java.lang.*, so use unqualified name... 1.628 + 1.629 + nameToUse = unqualifiedName; 1.630 + 1.631 + // unless you want to be able to import things from the right place :--) 1.632 + 1.633 + if(nameToUse.endsWith("_Stub")) nameToUse = Util.packagePrefix()+qualifiedName; 1.634 + 1.635 + } else if (currentPackage != null && packageName.equals(currentPackage)) { 1.636 + 1.637 + // Class in currentPackage, so use unqualified name... 1.638 + 1.639 + nameToUse = unqualifiedName; 1.640 + 1.641 + // Do we already have a previous import under this 1.642 + // unqualified name? 1.643 + 1.644 + if (importName != null) { 1.645 + 1.646 + // Yes, so we use qualifiedName... 1.647 + 1.648 + nameToUse = qualifiedName; 1.649 + 1.650 + } 1.651 + 1.652 + } else if (importName != null) { 1.653 + 1.654 + // It is in some package for which we normally 1.655 + // would import, but we have a previous import 1.656 + // under this unqualified name. We must use 1.657 + // the qualified name... 1.658 + 1.659 + nameToUse = qualifiedName; 1.660 + 1.661 + /* 1.662 + // Is the currentPackage the default package? 1.663 + 1.664 + if (currentPackage == null) { 1.665 + 1.666 + // Yes, so undo the import so that all 1.667 + // uses for this name will be qualified... 1.668 + 1.669 + String old = (String)imports.remove(unqualifiedName); 1.670 + classesInUse.put(old,old); 1.671 + importCount--; 1.672 + 1.673 + // Note that this name is in use but should 1.674 + // not be imported... 1.675 + 1.676 + imports.put(nameToUse,NO_IMPORT); 1.677 + } 1.678 + */ 1.679 + } else if (qualifiedName.equals("org.omg.CORBA.Object")) { 1.680 + 1.681 + // Always qualify this quy to avoid confusion... 1.682 + 1.683 + nameToUse = qualifiedName; 1.684 + 1.685 + } else { 1.686 + 1.687 + // Default to using unqualified name, and add 1.688 + // this guy to the imports... 1.689 + 1.690 + // Check for nested class in which case we use 1.691 + // the fully qualified name instead of imports 1.692 + if (unqualifiedName.indexOf('.') != -1) { 1.693 + nameToUse = qualifiedName; 1.694 + } else { 1.695 + nameToUse = unqualifiedName; 1.696 + imports.put(unqualifiedName,qualifiedName); 1.697 + importCount++; 1.698 + } 1.699 + } 1.700 + 1.701 + // Now add the name... 1.702 + 1.703 + classesInUse.put(qualifiedName,nameToUse); 1.704 + } 1.705 + } 1.706 + 1.707 + String getName(Type type) { 1.708 + if (type.isPrimitive()) { 1.709 + return type.getName() + type.getArrayBrackets(); 1.710 + } 1.711 + Identifier id = type.getIdentifier(); 1.712 + String name = IDLNames.replace(id.toString(),". ","."); 1.713 + return getName(name) + type.getArrayBrackets(); 1.714 + } 1.715 + 1.716 + // Added for Bug 4818753 1.717 + String getExceptionName(Type type) { 1.718 + Identifier id = type.getIdentifier(); 1.719 + return IDLNames.replace(id.toString(),". ","."); 1.720 + } 1.721 + 1.722 + String getName(String qualifiedName) { 1.723 + return (String)classesInUse.get(qualifiedName); 1.724 + } 1.725 + 1.726 + String getName(Identifier id) { 1.727 + return getName(id.toString()); 1.728 + } 1.729 + 1.730 + String getStubName(Type type) { 1.731 + String stubName = getStubNameFor(type,true); 1.732 + return getName(stubName); 1.733 + } 1.734 + 1.735 + void setStandardClassesInUse(CompoundType type, 1.736 + boolean stub) throws IOException { 1.737 + 1.738 + // Reset our state... 1.739 + 1.740 + currentPackage = type.getPackageName(); 1.741 + imports.clear(); 1.742 + classesInUse.clear(); 1.743 + namesInUse.clear(); 1.744 + importCount = 0; 1.745 + castArray = false; 1.746 + 1.747 + // Add the top-level type... 1.748 + 1.749 + addClassInUse(type); 1.750 + 1.751 + // Set current class name... 1.752 + 1.753 + if (stub) { 1.754 + currentClass = Utility.stubNameForCompiler(type.getName()); 1.755 + } else { 1.756 + currentClass = Utility.tieNameForCompiler(type.getName()); 1.757 + } 1.758 + 1.759 + // Add current class... 1.760 + 1.761 + if (currentPackage == null) { 1.762 + addClassInUse(currentClass,currentClass,currentPackage); 1.763 + } else { 1.764 + addClassInUse(currentClass,(currentPackage+"."+currentClass),currentPackage); 1.765 + } 1.766 + 1.767 + // Add standard classes... 1.768 + 1.769 + addClassInUse("javax.rmi.CORBA.Util"); 1.770 + addClassInUse(idRemote.toString()); 1.771 + addClassInUse(idRemoteException.toString()); 1.772 + addClassInUse(idOutputStream.toString()); 1.773 + addClassInUse(idInputStream.toString()); 1.774 + addClassInUse(idSystemException.toString()); 1.775 + addClassInUse(idJavaIoSerializable.toString()); 1.776 + addClassInUse(idCorbaORB.toString()); 1.777 + addClassInUse(idReplyHandler.toString()); 1.778 + 1.779 + // Add stub/tie specific imports... 1.780 + 1.781 + if (stub) { 1.782 + addClassInUse(stubBaseClass); 1.783 + addClassInUse("java.rmi.UnexpectedException"); 1.784 + addClassInUse(idRemarshalException.toString()); 1.785 + addClassInUse(idApplicationException.toString()); 1.786 + if (localStubs) { 1.787 + addClassInUse("org.omg.CORBA.portable.ServantObject"); 1.788 + } 1.789 + } else { 1.790 + addClassInUse(type); 1.791 + addClassInUse(tieBaseClass); 1.792 + addClassInUse(idTieInterface.toString()); 1.793 + addClassInUse(idBadMethodException.toString()); 1.794 + addClassInUse(idPortableUnknownException.toString()); 1.795 + addClassInUse(idJavaLangThrowable.toString()); 1.796 + } 1.797 + } 1.798 + 1.799 + void addClassesInUse(CompoundType type, RemoteType[] interfaces) { 1.800 + 1.801 + // Walk all methods and add types in use... 1.802 + 1.803 + CompoundType.Method[] methods = type.getMethods(); 1.804 + for (int i = 0; i < methods.length; i++) { 1.805 + addClassInUse(methods[i].getReturnType()); 1.806 + addStubInUse(methods[i].getReturnType()); 1.807 + addClassInUse(methods[i].getArguments()); 1.808 + addStubInUse(methods[i].getArguments()); 1.809 + addClassInUse(methods[i].getExceptions()); 1.810 + // bug 4473859: Also include narrower subtypes for use 1.811 + addClassInUse(methods[i].getImplExceptions()); 1.812 + } 1.813 + 1.814 + // If this is a stub, add all interfaces... 1.815 + 1.816 + if (interfaces != null) { 1.817 + addClassInUse(interfaces); 1.818 + } 1.819 + } 1.820 + 1.821 + void writePackageAndImports(IndentingWriter p) throws IOException { 1.822 + 1.823 + // Write package declaration... 1.824 + 1.825 + if (currentPackage != null) { 1.826 + p.pln("package " + 1.827 + Util.correctPackageName( 1.828 + currentPackage, false, standardPackage) 1.829 + + ";"); 1.830 + p.pln(); 1.831 + } 1.832 + 1.833 + // Get imports into an array and sort them... 1.834 + 1.835 + String[] names = new String[importCount]; 1.836 + int index = 0; 1.837 + for (Enumeration e = imports.elements() ; e.hasMoreElements() ;) { 1.838 + String it = (String) e.nextElement(); 1.839 + if (it != NO_IMPORT) { 1.840 + names[index++] = it; 1.841 + } 1.842 + } 1.843 + 1.844 + Arrays.sort(names,new StringComparator()); 1.845 + 1.846 + // Now dump them out... 1.847 + 1.848 + for (int i = 0; i < importCount; i++) { 1.849 + if( 1.850 + Util.isOffendingPackage(names[i]) 1.851 + && names[i].endsWith("_Stub") 1.852 + && String.valueOf(names[i].charAt(names[i].lastIndexOf(".")+1)).equals("_") 1.853 + ){ 1.854 + p.pln("import " + PackagePrefixChecker.packagePrefix()+names[i]+";"); 1.855 + } else{ 1.856 + p.pln("import " + names[i] + ";"); 1.857 + } 1.858 + } 1.859 + p.pln(); 1.860 + 1.861 + // Include offending packages . . . 1.862 + if ( currentPackage!=null && Util.isOffendingPackage(currentPackage) ){ 1.863 + p.pln("import " + currentPackage +".* ;"); 1.864 + } 1.865 + p.pln(); 1.866 + 1.867 + } 1.868 + 1.869 + boolean implementsRemote(CompoundType theType) { 1.870 + boolean result = theType.isType(TYPE_REMOTE) && !theType.isType(TYPE_ABSTRACT); 1.871 + 1.872 + // If theType is not remote, look at all the interfaces 1.873 + // until we find one that is... 1.874 + 1.875 + if (!result) { 1.876 + InterfaceType[] interfaces = theType.getInterfaces(); 1.877 + for (int i = 0; i < interfaces.length; i++) { 1.878 + result = implementsRemote(interfaces[i]); 1.879 + if (result) { 1.880 + break; 1.881 + } 1.882 + } 1.883 + } 1.884 + 1.885 + return result; 1.886 + } 1.887 + 1.888 + void writeStubMethod ( IndentingWriter p, 1.889 + CompoundType.Method method, 1.890 + CompoundType theType) throws IOException { 1.891 + 1.892 + // Wtite the method declaration and opening brace... 1.893 + String methodName = method.getName(); 1.894 + String methodIDLName = method.getIDLName(); 1.895 + 1.896 + Type paramTypes[] = method.getArguments(); 1.897 + String paramNames[] = method.getArgumentNames(); 1.898 + Type returnType = method.getReturnType(); 1.899 + ValueType[] exceptions = getStubExceptions(method,false); 1.900 + 1.901 + addNamesInUse(method); 1.902 + addNameInUse("_type_ids"); 1.903 + 1.904 + String objName = testUtil(getName(returnType), returnType); 1.905 + p.p("public " + objName + " " + methodName + "("); 1.906 + for(int i = 0; i < paramTypes.length; i++) { 1.907 + if (i > 0) 1.908 + p.p(", "); 1.909 + p.p(getName(paramTypes[i]) + " " + paramNames[i]); 1.910 + } 1.911 + 1.912 + p.p(")"); 1.913 + if (exceptions.length > 0) { 1.914 + p.p(" throws "); 1.915 + for(int i = 0; i < exceptions.length; i++) { 1.916 + if (i > 0) { 1.917 + p.p(", "); 1.918 + } 1.919 + // Added for Bug 4818753 1.920 + p.p(getExceptionName(exceptions[i])); 1.921 + } 1.922 + } 1.923 + 1.924 + p.plnI(" {"); 1.925 + 1.926 + // Now create the method body... 1.927 + 1.928 + if (localStubs) { 1.929 + writeLocalStubMethodBody(p,method,theType); 1.930 + } else { 1.931 + writeNonLocalStubMethodBody(p,method,theType); 1.932 + } 1.933 + 1.934 + // Close out the method... 1.935 + 1.936 + p.pOln("}"); 1.937 + } 1.938 + 1.939 + 1.940 + void writeLocalStubMethodBody (IndentingWriter p, 1.941 + CompoundType.Method method, 1.942 + CompoundType theType) throws IOException { 1.943 + 1.944 + String objName; 1.945 + String paramNames[] = method.getArgumentNames(); 1.946 + Type returnType = method.getReturnType(); 1.947 + ValueType[] exceptions = getStubExceptions(method,false); 1.948 + String methodName = method.getName(); 1.949 + String methodIDLName = method.getIDLName(); 1.950 + 1.951 + p.plnI("if (!Util.isLocal(this)) {"); 1.952 + writeNonLocalStubMethodBody(p,method,theType); 1.953 + p.pOlnI("} else {"); 1.954 + String so = getVariableName("so"); 1.955 + 1.956 + p.pln("ServantObject "+so+" = _servant_preinvoke(\""+methodIDLName+"\","+getName(theType)+".class);"); 1.957 + p.plnI("if ("+so+" == null) {"); 1.958 + if (!returnType.isType(TYPE_VOID)) { 1.959 + p.p("return "); 1.960 + } 1.961 + p.p(methodName+"("); 1.962 + for (int i = 0; i < paramNames.length; i++) { 1.963 + if (i > 0) 1.964 + p.p(", "); 1.965 + p.p(paramNames[i]); 1.966 + } 1.967 + p.pln(");"); 1.968 + if (returnType.isType(TYPE_VOID)) { 1.969 + p.pln( "return ;" ) ; 1.970 + } 1.971 + 1.972 + p.pOln("}"); 1.973 + p.plnI("try {"); 1.974 + 1.975 + // Generate code to copy required arguments, and 1.976 + // get back the names by which all arguments are known... 1.977 + 1.978 + String[] argNames = writeCopyArguments(method,p); 1.979 + 1.980 + // Now write the method... 1.981 + 1.982 + boolean copyReturn = mustCopy(returnType); 1.983 + String resultName = null; 1.984 + if (!returnType.isType(TYPE_VOID)) { 1.985 + if (copyReturn) { 1.986 + resultName = getVariableName("result"); 1.987 + objName = testUtil(getName(returnType), returnType); 1.988 + p.p(objName+" "+resultName + " = "); 1.989 + } else { 1.990 + p.p("return "); 1.991 + } 1.992 + } 1.993 + objName = testUtil(getName(theType), theType); 1.994 + p.p("(("+objName+")"+so+".servant)."+methodName+"("); 1.995 + 1.996 + for (int i = 0; i < argNames.length; i++) { 1.997 + if (i > 0) 1.998 + p.p(", "); 1.999 + p.p(argNames[i]); 1.1000 + } 1.1001 + 1.1002 + if (copyReturn) { 1.1003 + p.pln(");"); 1.1004 + objName = testUtil(getName(returnType), returnType); 1.1005 + p.pln("return ("+objName+")Util.copyObject("+resultName+",_orb());"); 1.1006 + } else { 1.1007 + p.pln(");"); 1.1008 + } 1.1009 + 1.1010 + String e1 = getVariableName("ex"); 1.1011 + String e2 = getVariableName("exCopy"); 1.1012 + p.pOlnI("} catch (Throwable "+e1+") {"); 1.1013 + 1.1014 + p.pln("Throwable "+e2+" = (Throwable)Util.copyObject("+e1+",_orb());"); 1.1015 + for(int i = 0; i < exceptions.length; i++) { 1.1016 + if (exceptions[i].getIdentifier() != idRemoteException && 1.1017 + exceptions[i].isType(TYPE_VALUE)) { 1.1018 + // Added for Bug 4818753 1.1019 + p.plnI("if ("+e2+" instanceof "+getExceptionName(exceptions[i])+") {"); 1.1020 + p.pln("throw ("+getExceptionName(exceptions[i])+")"+e2+";"); 1.1021 + p.pOln("}"); 1.1022 + } 1.1023 + } 1.1024 + 1.1025 + p.pln("throw Util.wrapException("+e2+");"); 1.1026 + p.pOlnI("} finally {"); 1.1027 + p.pln("_servant_postinvoke("+so+");"); 1.1028 + p.pOln("}"); 1.1029 + p.pOln("}"); 1.1030 + } 1.1031 + 1.1032 + 1.1033 + void writeNonLocalStubMethodBody ( IndentingWriter p, 1.1034 + CompoundType.Method method, 1.1035 + CompoundType theType) throws IOException { 1.1036 + 1.1037 + String methodName = method.getName(); 1.1038 + String methodIDLName = method.getIDLName(); 1.1039 + 1.1040 + Type paramTypes[] = method.getArguments(); 1.1041 + String paramNames[] = method.getArgumentNames(); 1.1042 + Type returnType = method.getReturnType(); 1.1043 + ValueType[] exceptions = getStubExceptions(method,true); 1.1044 + 1.1045 + String in = getVariableName("in"); 1.1046 + String out = getVariableName("out"); 1.1047 + String ex = getVariableName("ex"); 1.1048 + 1.1049 + // Decide if we need to use the new streams for 1.1050 + // any of the read calls... 1.1051 + 1.1052 + boolean needNewReadStreamClass = false; 1.1053 + for (int i = 0; i < exceptions.length; i++) { 1.1054 + if (exceptions[i].getIdentifier() != idRemoteException && 1.1055 + exceptions[i].isType(TYPE_VALUE) && 1.1056 + needNewReadStreamClass(exceptions[i])) { 1.1057 + needNewReadStreamClass = true; 1.1058 + break; 1.1059 + } 1.1060 + } 1.1061 + if (!needNewReadStreamClass) { 1.1062 + for (int i = 0; i < paramTypes.length; i++) { 1.1063 + if (needNewReadStreamClass(paramTypes[i])) { 1.1064 + needNewReadStreamClass = true; 1.1065 + break; 1.1066 + } 1.1067 + } 1.1068 + } 1.1069 + if (!needNewReadStreamClass) { 1.1070 + needNewReadStreamClass = needNewReadStreamClass(returnType); 1.1071 + } 1.1072 + 1.1073 + // Decide if we need to use the new streams for 1.1074 + // any of the write calls... 1.1075 + 1.1076 + boolean needNewWriteStreamClass = false; 1.1077 + for (int i = 0; i < paramTypes.length; i++) { 1.1078 + if (needNewWriteStreamClass(paramTypes[i])) { 1.1079 + needNewWriteStreamClass = true; 1.1080 + break; 1.1081 + } 1.1082 + } 1.1083 + 1.1084 + // Now write the method, inserting casts where needed... 1.1085 + 1.1086 + p.plnI("try {"); 1.1087 + if (needNewReadStreamClass) { 1.1088 + p.pln(idExtInputStream + " "+in+" = null;"); 1.1089 + } else { 1.1090 + p.pln(idInputStream + " "+in+" = null;"); 1.1091 + } 1.1092 + p.plnI("try {"); 1.1093 + 1.1094 + String argStream = "null"; 1.1095 + 1.1096 + if (needNewWriteStreamClass) { 1.1097 + p.plnI(idExtOutputStream + " "+out+" = "); 1.1098 + p.pln("(" + idExtOutputStream + ")"); 1.1099 + p.pln("_request(\"" + methodIDLName + "\", true);"); 1.1100 + p.pO(); 1.1101 + } else { 1.1102 + p.pln("OutputStream "+out+" = _request(\"" + methodIDLName + "\", true);"); 1.1103 + } 1.1104 + 1.1105 + if (paramTypes.length > 0) { 1.1106 + writeMarshalArguments(p, out, paramTypes, paramNames); 1.1107 + p.pln(); 1.1108 + } 1.1109 + argStream = out; 1.1110 + 1.1111 + if (returnType.isType(TYPE_VOID)) { 1.1112 + p.pln("_invoke(" + argStream + ");" ); 1.1113 + } else { 1.1114 + if (needNewReadStreamClass) { 1.1115 + p.plnI(in+" = (" + idExtInputStream + ")_invoke(" + argStream + ");"); 1.1116 + p.pO(); 1.1117 + } else { 1.1118 + p.pln(in+" = _invoke(" + argStream + ");"); 1.1119 + } 1.1120 + p.p("return "); 1.1121 + writeUnmarshalArgument(p, in, returnType, null); 1.1122 + p.pln(); 1.1123 + } 1.1124 + 1.1125 + // Handle ApplicationException... 1.1126 + 1.1127 + p.pOlnI("} catch ("+getName(idApplicationException)+" "+ex+") {"); 1.1128 + if (needNewReadStreamClass) { 1.1129 + p.pln(in + " = (" + idExtInputStream + ") "+ex+".getInputStream();"); 1.1130 + } else { 1.1131 + p.pln(in + " = "+ex+".getInputStream();"); 1.1132 + } 1.1133 + 1.1134 + boolean idRead = false; 1.1135 + boolean idAllocated = false; 1.1136 + for(int i = 0; i < exceptions.length; i++) { 1.1137 + if (exceptions[i].getIdentifier() != idRemoteException) { 1.1138 + 1.1139 + // Is this our special-case IDLEntity exception? 1.1140 + 1.1141 + if (exceptions[i].isIDLEntityException() && !exceptions[i].isCORBAUserException()) { 1.1142 + 1.1143 + // Yes. 1.1144 + 1.1145 + if (!idAllocated && !idRead) { 1.1146 + p.pln("String $_id = "+ex+".getId();"); 1.1147 + idAllocated = true; 1.1148 + } 1.1149 + 1.1150 + String helperName = IDLNames.replace(exceptions[i].getQualifiedIDLName(false),"::","."); 1.1151 + helperName += "Helper"; 1.1152 + p.plnI("if ($_id.equals("+helperName+".id())) {"); 1.1153 + p.pln("throw "+helperName+".read("+in+");"); 1.1154 + 1.1155 + } else { 1.1156 + 1.1157 + // No. 1.1158 + 1.1159 + if (!idAllocated && !idRead) { 1.1160 + p.pln("String $_id = "+in+".read_string();"); 1.1161 + idAllocated = true; 1.1162 + idRead = true; 1.1163 + } else if (idAllocated && !idRead) { 1.1164 + p.pln("$_id = "+in+".read_string();"); 1.1165 + idRead = true; 1.1166 + } 1.1167 + p.plnI("if ($_id.equals(\""+getExceptionRepositoryID(exceptions[i])+"\")) {"); 1.1168 + // Added for Bug 4818753 1.1169 + p.pln("throw ("+getExceptionName(exceptions[i])+") "+in+".read_value(" + getExceptionName(exceptions[i]) + ".class);"); 1.1170 + } 1.1171 + p.pOln("}"); 1.1172 + } 1.1173 + } 1.1174 + if (!idAllocated && !idRead) { 1.1175 + p.pln("String $_id = "+in+".read_string();"); 1.1176 + idAllocated = true; 1.1177 + idRead = true; 1.1178 + } else if (idAllocated && !idRead) { 1.1179 + p.pln("$_id = "+in+".read_string();"); 1.1180 + idRead = true; 1.1181 + } 1.1182 + p.pln("throw new UnexpectedException($_id);"); 1.1183 + 1.1184 + // Handle RemarshalException... 1.1185 + 1.1186 + p.pOlnI("} catch ("+getName(idRemarshalException)+" "+ex+") {"); 1.1187 + if (!returnType.isType(TYPE_VOID)) { 1.1188 + p.p("return "); 1.1189 + } 1.1190 + p.p(methodName + "("); 1.1191 + for(int i = 0; i < paramTypes.length; i++) { 1.1192 + if (i > 0) { 1.1193 + p.p(","); 1.1194 + } 1.1195 + p.p(paramNames[i]); 1.1196 + } 1.1197 + p.pln(");"); 1.1198 + 1.1199 + // Ensure that we release the reply... 1.1200 + 1.1201 + p.pOlnI("} finally {"); 1.1202 + p.pln("_releaseReply("+in+");"); 1.1203 + 1.1204 + p.pOln("}"); 1.1205 + 1.1206 + // Handle SystemException... 1.1207 + 1.1208 + p.pOlnI("} catch (SystemException "+ex+") {"); 1.1209 + p.pln("throw Util.mapSystemException("+ex+");"); 1.1210 + p.pOln("}"); 1.1211 + 1.1212 + // returnResult(p,returnType); 1.1213 + } 1.1214 + 1.1215 + void allocateResult (IndentingWriter p, 1.1216 + Type returnType) throws IOException { 1.1217 + if (!returnType.isType(TYPE_VOID)) { 1.1218 + String objName = testUtil(getName(returnType), returnType); 1.1219 + p.p(objName + " result = "); 1.1220 + } 1.1221 + } 1.1222 + 1.1223 + int getTypeCode(Type type) { 1.1224 + 1.1225 + int typeCode = type.getTypeCode(); 1.1226 + 1.1227 + // Handle late-breaking special case for 1.1228 + // abstract IDL entities... 1.1229 + 1.1230 + if ((type instanceof CompoundType) && 1.1231 + ((CompoundType)type).isAbstractBase()) { 1.1232 + typeCode = TYPE_ABSTRACT; 1.1233 + } 1.1234 + 1.1235 + return typeCode; 1.1236 + } 1.1237 + 1.1238 + 1.1239 + /** 1.1240 + * Write a snippet of Java code to marshal a value named "name" of 1.1241 + * type "type" to the java.io.ObjectOutput stream named "stream". 1.1242 + */ 1.1243 + void writeMarshalArgument(IndentingWriter p, 1.1244 + String streamName, 1.1245 + Type type, String name) throws IOException { 1.1246 + 1.1247 + int typeCode = getTypeCode(type); 1.1248 + 1.1249 + switch (typeCode) { 1.1250 + case TYPE_BOOLEAN: 1.1251 + p.p(streamName + ".write_boolean(" + name + ");"); 1.1252 + break; 1.1253 + case TYPE_BYTE: 1.1254 + p.p(streamName + ".write_octet(" + name + ");"); 1.1255 + break; 1.1256 + case TYPE_CHAR: 1.1257 + p.p(streamName + ".write_wchar(" + name + ");"); 1.1258 + break; 1.1259 + case TYPE_SHORT: 1.1260 + p.p(streamName + ".write_short(" + name + ");"); 1.1261 + break; 1.1262 + case TYPE_INT: 1.1263 + p.p(streamName + ".write_long(" + name + ");"); 1.1264 + break; 1.1265 + case TYPE_LONG: 1.1266 + p.p(streamName + ".write_longlong(" + name + ");"); 1.1267 + break; 1.1268 + case TYPE_FLOAT: 1.1269 + p.p(streamName + ".write_float(" + name + ");"); 1.1270 + break; 1.1271 + case TYPE_DOUBLE: 1.1272 + p.p(streamName + ".write_double(" + name + ");"); 1.1273 + break; 1.1274 + case TYPE_STRING: 1.1275 + p.p(streamName + ".write_value(" + name + "," + getName(type) + ".class);"); 1.1276 + break; 1.1277 + case TYPE_ANY: 1.1278 + p.p("Util.writeAny("+ streamName + "," + name + ");"); 1.1279 + break; 1.1280 + case TYPE_CORBA_OBJECT: 1.1281 + p.p(streamName + ".write_Object(" + name + ");"); 1.1282 + break; 1.1283 + case TYPE_REMOTE: 1.1284 + p.p("Util.writeRemoteObject("+ streamName + "," + name + ");"); 1.1285 + break; 1.1286 + case TYPE_ABSTRACT: 1.1287 + p.p("Util.writeAbstractObject("+ streamName + "," + name + ");"); 1.1288 + break; 1.1289 + case TYPE_NC_INTERFACE: 1.1290 + p.p(streamName + ".write_value((Serializable)" + name + "," + getName(type) + ".class);"); 1.1291 + break; 1.1292 + case TYPE_VALUE: 1.1293 + p.p(streamName + ".write_value(" + name + "," + getName(type) + ".class);"); 1.1294 + break; 1.1295 + case TYPE_IMPLEMENTATION: 1.1296 + p.p(streamName + ".write_value((Serializable)" + name + "," + getName(type) + ".class);"); 1.1297 + break; 1.1298 + case TYPE_NC_CLASS: 1.1299 + p.p(streamName + ".write_value((Serializable)" + name + "," + getName(type) + ".class);"); 1.1300 + break; 1.1301 + case TYPE_ARRAY: 1.1302 + castArray = true; 1.1303 + p.p(streamName + ".write_value(cast_array(" + name + ")," + getName(type) + ".class);"); 1.1304 + break; 1.1305 + case TYPE_JAVA_RMI_REMOTE: 1.1306 + p.p("Util.writeRemoteObject("+ streamName + "," + name + ");"); 1.1307 + break; 1.1308 + default: 1.1309 + throw new Error("unexpected type code: " + typeCode); 1.1310 + } 1.1311 + } 1.1312 + 1.1313 + /** 1.1314 + * Write a snippet of Java code to unmarshal a value of type "type" 1.1315 + * from the java.io.ObjectInput stream named "stream" into a variable 1.1316 + * named "name" (if "name" is null, the value in unmarshalled and 1.1317 + * discarded). 1.1318 + */ 1.1319 + void writeUnmarshalArgument(IndentingWriter p, 1.1320 + String streamName, 1.1321 + Type type, 1.1322 + String name) throws IOException { 1.1323 + 1.1324 + int typeCode = getTypeCode(type); 1.1325 + 1.1326 + if (name != null) { 1.1327 + p.p(name + " = "); 1.1328 + } 1.1329 + 1.1330 + switch (typeCode) { 1.1331 + case TYPE_BOOLEAN: 1.1332 + p.p(streamName + ".read_boolean();"); 1.1333 + break; 1.1334 + case TYPE_BYTE: 1.1335 + p.p(streamName + ".read_octet();"); 1.1336 + break; 1.1337 + case TYPE_CHAR: 1.1338 + p.p(streamName + ".read_wchar();"); 1.1339 + break; 1.1340 + case TYPE_SHORT: 1.1341 + p.p(streamName + ".read_short();"); 1.1342 + break; 1.1343 + case TYPE_INT: 1.1344 + p.p(streamName + ".read_long();"); 1.1345 + break; 1.1346 + case TYPE_LONG: 1.1347 + p.p(streamName + ".read_longlong();"); 1.1348 + break; 1.1349 + case TYPE_FLOAT: 1.1350 + p.p(streamName + ".read_float();"); 1.1351 + break; 1.1352 + case TYPE_DOUBLE: 1.1353 + p.p(streamName + ".read_double();"); 1.1354 + break; 1.1355 + case TYPE_STRING: 1.1356 + p.p("(String) " + streamName + ".read_value(" + getName(type) + ".class);"); 1.1357 + break; 1.1358 + case TYPE_ANY: 1.1359 + if (type.getIdentifier() != idJavaLangObject) { 1.1360 + p.p("(" + getName(type) + ") "); 1.1361 + } 1.1362 + p.p("Util.readAny(" + streamName + ");"); 1.1363 + break; 1.1364 + case TYPE_CORBA_OBJECT: 1.1365 + if (type.getIdentifier() == idCorbaObject) { 1.1366 + p.p("(" + getName(type) + ") " + streamName + ".read_Object();"); 1.1367 + } else { 1.1368 + p.p("(" + getName(type) + ") " + streamName + ".read_Object(" + getStubName(type) + ".class);"); 1.1369 + } 1.1370 + break; 1.1371 + case TYPE_REMOTE: 1.1372 + String objName = testUtil(getName(type), type); 1.1373 + p.p("(" + objName + ") " + 1.1374 + "PortableRemoteObject.narrow(" + streamName + ".read_Object(), " + objName + ".class);"); 1.1375 + break; 1.1376 + case TYPE_ABSTRACT: 1.1377 + p.p("(" + getName(type) + ") " + streamName + ".read_abstract_interface();"); 1.1378 + break; 1.1379 + case TYPE_NC_INTERFACE: 1.1380 + p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);"); 1.1381 + break; 1.1382 + case TYPE_VALUE: 1.1383 + p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);"); 1.1384 + break; 1.1385 + case TYPE_IMPLEMENTATION: 1.1386 + p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);"); 1.1387 + break; 1.1388 + case TYPE_NC_CLASS: 1.1389 + p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);"); 1.1390 + break; 1.1391 + case TYPE_ARRAY: 1.1392 + p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);"); 1.1393 + break; 1.1394 + case TYPE_JAVA_RMI_REMOTE: 1.1395 + p.p("(" + getName(type) + ") " + 1.1396 + "PortableRemoteObject.narrow(" + streamName + ".read_Object(), " + getName(type) + ".class);"); 1.1397 + // p.p("(" + getName(type) + ") " + streamName + ".read_Object(" + getStubName(type) + ".class);"); 1.1398 + break; 1.1399 + default: 1.1400 + throw new Error("unexpected type code: " + typeCode); 1.1401 + } 1.1402 + } 1.1403 + 1.1404 + /** 1.1405 + * Get a list of all the RepositoryIDs for interfaces 1.1406 + * implemented directly or indirectly by theType. In the 1.1407 + * case of an ImplementationType which implements 2 or 1.1408 + * more remote interfaces, this list will begin with the 1.1409 + * Identifier for the implementation (see section 5.9 in 1.1410 + * the Java -> IDL mapping). Ensures that the most derived 1.1411 + * type is first in the list because the IOR is generated 1.1412 + * using that entry in the _ids array. 1.1413 + */ 1.1414 + String[] getAllRemoteRepIDs (CompoundType theType) { 1.1415 + 1.1416 + String[] result; 1.1417 + 1.1418 + // Collect up all the (inherited) remote interfaces 1.1419 + // (ignores all the 'special' interfaces: Remote, 1.1420 + // Serializable, Externalizable)... 1.1421 + 1.1422 + Type[] types = collectAllRemoteInterfaces(theType); 1.1423 + 1.1424 + int length = types.length; 1.1425 + boolean haveImpl = theType instanceof ImplementationType; 1.1426 + InterfaceType[] interfaces = theType.getInterfaces(); 1.1427 + int remoteCount = countRemote(interfaces,false); 1.1428 + int offset = 0; 1.1429 + 1.1430 + // Do we have an implementation type that implements 1.1431 + // more than one remote interface? 1.1432 + 1.1433 + if (haveImpl && remoteCount > 1) { 1.1434 + 1.1435 + // Yes, so we need to insert it at the beginning... 1.1436 + 1.1437 + result = new String[length + 1]; 1.1438 + result[0] = getRepositoryID(theType); 1.1439 + offset = 1; 1.1440 + 1.1441 + } else { 1.1442 + 1.1443 + // No. 1.1444 + 1.1445 + result = new String[length]; 1.1446 + 1.1447 + // Here we need to ensure that the most derived 1.1448 + // interface ends up being first in the list. If 1.1449 + // there is only one, we're done. 1.1450 + 1.1451 + if (length > 1) { 1.1452 + 1.1453 + // First, decide what the most derived type is... 1.1454 + 1.1455 + String mostDerived = null; 1.1456 + 1.1457 + if (haveImpl) { 1.1458 + 1.1459 + // If we get here, we know that there is only one 1.1460 + // direct remote interface, so just find it... 1.1461 + 1.1462 + for (int i = 0; i < interfaces.length; i++) { 1.1463 + if (interfaces[i].isType(TYPE_REMOTE)) { 1.1464 + mostDerived = interfaces[i].getRepositoryID(); 1.1465 + break; 1.1466 + } 1.1467 + } 1.1468 + } else { 1.1469 + 1.1470 + // If we get here we know that theType is a RemoteType 1.1471 + // so just use its id... 1.1472 + 1.1473 + mostDerived = theType.getRepositoryID(); 1.1474 + } 1.1475 + 1.1476 + // Now search types list and make sure mostDerived is 1.1477 + // at index zero... 1.1478 + 1.1479 + for (int i = 0; i < length; i++) { 1.1480 + if (types[i].getRepositoryID() == mostDerived) { 1.1481 + 1.1482 + // Found it. Swap it if we need to... 1.1483 + 1.1484 + if (i > 0) { 1.1485 + Type temp = types[0]; 1.1486 + types[0] = types[i]; 1.1487 + types[i] = temp; 1.1488 + } 1.1489 + 1.1490 + break; 1.1491 + } 1.1492 + } 1.1493 + } 1.1494 + } 1.1495 + 1.1496 + // Now copy contents of the types array... 1.1497 + 1.1498 + for (int i = 0; i < types.length; i++) { 1.1499 + result[offset++] = getRepositoryID(types[i]); 1.1500 + } 1.1501 + 1.1502 + // If we're supposed to, reverse the array. This 1.1503 + // is only done when the -testReverseIDs flag is 1.1504 + // passed, and that should ONLY be done for test 1.1505 + // cases. This is an undocumented feature. 1.1506 + 1.1507 + if (reverseIDs) { 1.1508 + int start = 0; 1.1509 + int end = result.length -1; 1.1510 + while (start < end) { 1.1511 + String temp = result[start]; 1.1512 + result[start++] = result[end]; 1.1513 + result[end--] = temp; 1.1514 + } 1.1515 + } 1.1516 + 1.1517 + return result; 1.1518 + } 1.1519 + 1.1520 + /** 1.1521 + * Collect all the inherited remote interfaces. 1.1522 + */ 1.1523 + Type[] collectAllRemoteInterfaces (CompoundType theType) { 1.1524 + Vector list = new Vector(); 1.1525 + 1.1526 + // Collect up all the Remote interfaces, and get an instance 1.1527 + // for java.rmi.Remote... 1.1528 + 1.1529 + addRemoteInterfaces(list,theType); 1.1530 + 1.1531 + // Create and return our results... 1.1532 + 1.1533 + Type[] result = new Type[list.size()]; 1.1534 + list.copyInto(result); 1.1535 + 1.1536 + return result; 1.1537 + } 1.1538 + 1.1539 + /** 1.1540 + * Add all the inherited remote interfaces to list. 1.1541 + */ 1.1542 + void addRemoteInterfaces(Vector list, CompoundType theType) { 1.1543 + 1.1544 + if (theType != null) { 1.1545 + if (theType.isInterface() && !list.contains(theType)) { 1.1546 + list.addElement(theType); 1.1547 + } 1.1548 + 1.1549 + InterfaceType[] interfaces = theType.getInterfaces(); 1.1550 + for (int i = 0; i < interfaces.length; i++) { 1.1551 + 1.1552 + if (interfaces[i].isType(TYPE_REMOTE)) { 1.1553 + addRemoteInterfaces(list,interfaces[i]); 1.1554 + } 1.1555 + } 1.1556 + 1.1557 + addRemoteInterfaces(list,theType.getSuperclass()); 1.1558 + } 1.1559 + } 1.1560 + 1.1561 + /** 1.1562 + * Get a list of all the remote interfaces which this stub 1.1563 + * should declare. 1.1564 + */ 1.1565 + RemoteType[] getDirectRemoteInterfaces (CompoundType theType) { 1.1566 + 1.1567 + RemoteType[] result; 1.1568 + InterfaceType[] interfaces = theType.getInterfaces(); 1.1569 + 1.1570 + // First, get a list of all the interfaces... 1.1571 + 1.1572 + InterfaceType[] list; 1.1573 + 1.1574 + // Because we can be passed either an ImplementationType 1.1575 + // (which has interfaces) or a RemoteType (which is an 1.1576 + // interface and may have interfaces) we must handle each 1.1577 + // separately... 1.1578 + 1.1579 + // Do we have an implementation type? 1.1580 + 1.1581 + if (theType instanceof ImplementationType) { 1.1582 + 1.1583 + // Yes, so list is exactly what this type 1.1584 + // implements and is correct already. 1.1585 + 1.1586 + list = interfaces; 1.1587 + 1.1588 + } else { 1.1589 + 1.1590 + // No, so list is just theType... 1.1591 + 1.1592 + list = new InterfaceType[1]; 1.1593 + list[0] = (InterfaceType) theType; 1.1594 + } 1.1595 + 1.1596 + // Ok, now count up the remote interfaces, allocate 1.1597 + // our result and fill it in... 1.1598 + 1.1599 + int remoteCount = countRemote(list,false); 1.1600 + 1.1601 + if (remoteCount == 0) { 1.1602 + throw new CompilerError("iiop.StubGenerator: No remote interfaces!"); 1.1603 + } 1.1604 + 1.1605 + result = new RemoteType[remoteCount]; 1.1606 + int offset = 0; 1.1607 + for (int i = 0; i < list.length; i++) { 1.1608 + if (list[i].isType(TYPE_REMOTE)) { 1.1609 + result[offset++] = (RemoteType)list[i]; 1.1610 + } 1.1611 + } 1.1612 + 1.1613 + return result; 1.1614 + } 1.1615 + 1.1616 + int countRemote (Type[] list, boolean includeAbstract) { 1.1617 + int remoteCount = 0; 1.1618 + for (int i = 0; i < list.length; i++) { 1.1619 + if (list[i].isType(TYPE_REMOTE) && 1.1620 + (includeAbstract || !list[i].isType(TYPE_ABSTRACT))) { 1.1621 + remoteCount++; 1.1622 + } 1.1623 + } 1.1624 + 1.1625 + return remoteCount; 1.1626 + } 1.1627 + 1.1628 + void writeCastArray(IndentingWriter p) throws IOException { 1.1629 + if (castArray) { 1.1630 + p.pln(); 1.1631 + p.pln("// This method is required as a work-around for"); 1.1632 + p.pln("// a bug in the JDK 1.1.6 verifier."); 1.1633 + p.pln(); 1.1634 + p.plnI("private "+getName(idJavaIoSerializable)+" cast_array(Object obj) {"); 1.1635 + p.pln("return ("+getName(idJavaIoSerializable)+")obj;"); 1.1636 + p.pOln("}"); 1.1637 + } 1.1638 + } 1.1639 + void writeIds(IndentingWriter p, CompoundType theType, boolean isTie 1.1640 + ) throws IOException { 1.1641 + p.plnI("private static final String[] _type_ids = {"); 1.1642 + 1.1643 + String[] ids = getAllRemoteRepIDs(theType); 1.1644 + 1.1645 + if (ids.length >0 ) { 1.1646 + for(int i = 0; i < ids.length; i++) { 1.1647 + if (i > 0) 1.1648 + p.pln(", "); 1.1649 + p.p("\"" + ids[i] + "\""); 1.1650 + } 1.1651 + } else { 1.1652 + // Must be an implementation which only implements Remote... 1.1653 + p.pln("\"\""); 1.1654 + } 1.1655 + String qname = theType.getQualifiedName() ; 1.1656 + boolean isTransactional = isTie && transactionalObjects.containsKey( qname ) ; 1.1657 + // Add TransactionalObject if needed. 1.1658 + if (isTransactional) { 1.1659 + // Have already written an id. 1.1660 + p.pln( ", " ) ; 1.1661 + p.pln( "\"IDL:omg.org/CosTransactions/TransactionalObject:1.0\"" ) ; 1.1662 + } else if (ids.length > 0) { 1.1663 + p.pln(); 1.1664 + } 1.1665 + p.pOln("};"); 1.1666 + } 1.1667 + 1.1668 + 1.1669 + /** 1.1670 + * Write the Tie for the remote class to a stream. 1.1671 + */ 1.1672 + protected void writeTie(OutputType outputType, 1.1673 + IndentingWriter p) throws IOException 1.1674 + { 1.1675 + CompoundType theType = (CompoundType) outputType.getType(); 1.1676 + RemoteType[] remoteInterfaces = null; 1.1677 + 1.1678 + // Write comment... 1.1679 + p.pln("// Tie class generated by rmic, do not edit."); 1.1680 + p.pln("// Contents subject to change without notice."); 1.1681 + p.pln(); 1.1682 + 1.1683 + // Set our standard classes... 1.1684 + setStandardClassesInUse(theType,false); 1.1685 + 1.1686 + // Add classes for this type... 1.1687 + addClassesInUse(theType,remoteInterfaces); 1.1688 + 1.1689 + // Write package and import statements... 1.1690 + writePackageAndImports(p); 1.1691 + 1.1692 + // Declare the tie class. 1.1693 + p.p("public class " + currentClass + " extends " + 1.1694 + getName(tieBaseClass) + " implements Tie"); 1.1695 + 1.1696 + // Add java.rmi.Remote if this type does not implement it. 1.1697 + // This allows stubs for Abstract interfaces to be treated 1.1698 + // uniformly... 1.1699 + if (!implementsRemote(theType)) { 1.1700 + p.pln(","); 1.1701 + p.p(getName("java.rmi.Remote")); 1.1702 + } 1.1703 + 1.1704 + p.plnI(" {"); 1.1705 + 1.1706 + // Write data members... 1.1707 + p.pln(); 1.1708 + p.pln("volatile private " + getName(theType) + " target = null;"); 1.1709 + p.pln(); 1.1710 + 1.1711 + // Write the ids... 1.1712 + writeIds( p, theType, true ) ; 1.1713 + 1.1714 + // Write setTarget method... 1.1715 + p.pln(); 1.1716 + p.plnI("public void setTarget(Remote target) {"); 1.1717 + p.pln("this.target = (" + getName(theType) + ") target;"); 1.1718 + p.pOln("}"); 1.1719 + 1.1720 + // Write getTarget method... 1.1721 + p.pln(); 1.1722 + p.plnI("public Remote getTarget() {"); 1.1723 + p.pln("return target;"); 1.1724 + p.pOln("}"); 1.1725 + 1.1726 + // Write thisObject method... 1.1727 + p.pln(); 1.1728 + write_tie_thisObject_method(p,idCorbaObject); 1.1729 + 1.1730 + // Write deactivate method... 1.1731 + p.pln(); 1.1732 + write_tie_deactivate_method(p); 1.1733 + 1.1734 + // Write get orb method... 1.1735 + p.pln(); 1.1736 + p.plnI("public ORB orb() {"); 1.1737 + p.pln("return _orb();"); 1.1738 + p.pOln("}"); 1.1739 + 1.1740 + // Write set orb method... 1.1741 + p.pln(); 1.1742 + write_tie_orb_method(p); 1.1743 + 1.1744 + // Write the _ids() method... 1.1745 + p.pln(); 1.1746 + write_tie__ids_method(p); 1.1747 + 1.1748 + // Get all the methods... 1.1749 + CompoundType.Method[] remoteMethods = theType.getMethods(); 1.1750 + 1.1751 + // Register all the argument names used, plus our 1.1752 + // data member names... 1.1753 + 1.1754 + addNamesInUse(remoteMethods); 1.1755 + addNameInUse("target"); 1.1756 + addNameInUse("_type_ids"); 1.1757 + 1.1758 + // Write the _invoke method... 1.1759 + p.pln(); 1.1760 + 1.1761 + String in = getVariableName("in"); 1.1762 + String _in = getVariableName("_in"); 1.1763 + String ex = getVariableName("ex"); 1.1764 + String method = getVariableName("method"); 1.1765 + String reply = getVariableName("reply"); 1.1766 + 1.1767 + p.plnI("public OutputStream _invoke(String "+method+", InputStream "+_in+", " + 1.1768 + "ResponseHandler "+reply+") throws SystemException {"); 1.1769 + 1.1770 + if (remoteMethods.length > 0) { 1.1771 + p.plnI("try {"); 1.1772 + p.pln(getName(theType) + " target = this.target;"); 1.1773 + p.plnI("if (target == null) {"); 1.1774 + p.pln("throw new java.io.IOException();"); 1.1775 + p.pOln("}"); 1.1776 + p.plnI(idExtInputStream + " "+in+" = "); 1.1777 + p.pln("(" + idExtInputStream + ") "+_in+";"); 1.1778 + p.pO(); 1.1779 + 1.1780 + // See if we should use a hash table style 1.1781 + // comparison... 1.1782 + 1.1783 + StaticStringsHash hash = getStringsHash(remoteMethods); 1.1784 + 1.1785 + if (hash != null) { 1.1786 + p.plnI("switch ("+method+"."+hash.method+") {"); 1.1787 + for (int i = 0; i < hash.buckets.length; i++) { 1.1788 + p.plnI("case "+hash.keys[i]+": "); 1.1789 + for (int j = 0; j < hash.buckets[i].length; j++) { 1.1790 + CompoundType.Method current = remoteMethods[hash.buckets[i][j]]; 1.1791 + if (j > 0) { 1.1792 + p.pO("} else "); 1.1793 + } 1.1794 + p.plnI("if ("+method+".equals(\""+ current.getIDLName() +"\")) {"); 1.1795 + writeTieMethod(p, theType,current); 1.1796 + } 1.1797 + p.pOln("}"); 1.1798 + p.pO(); 1.1799 + } 1.1800 + } else { 1.1801 + for(int i = 0; i < remoteMethods.length; i++) { 1.1802 + CompoundType.Method current = remoteMethods[i]; 1.1803 + if (i > 0) { 1.1804 + p.pO("} else "); 1.1805 + } 1.1806 + 1.1807 + p.plnI("if ("+method+".equals(\""+ current.getIDLName() +"\")) {"); 1.1808 + writeTieMethod(p, theType, current); 1.1809 + } 1.1810 + } 1.1811 + 1.1812 + if (hash != null) { 1.1813 + p.pI(); 1.1814 + // p.plnI("default:"); 1.1815 + } else { 1.1816 + // p.pOlnI("} else {"); 1.1817 + } 1.1818 + // p.pln("throw new "+getName(idBadMethodException)+"();"); 1.1819 + 1.1820 + if (hash != null) { 1.1821 + p.pO(); 1.1822 + } 1.1823 + p.pOln("}"); 1.1824 + p.pln("throw new "+getName(idBadMethodException)+"();"); 1.1825 + 1.1826 + p.pOlnI("} catch ("+getName(idSystemException)+" "+ex+") {"); 1.1827 + p.pln("throw "+ex+";"); 1.1828 + 1.1829 + p.pOlnI("} catch ("+getName(idJavaLangThrowable)+" "+ex+") {"); 1.1830 + p.pln("throw new " + getName(idPortableUnknownException) + "("+ex+");"); 1.1831 + p.pOln("}"); 1.1832 + } else { 1.1833 + // No methods... 1.1834 + 1.1835 + p.pln("throw new " + getName(idBadMethodException) + "();"); 1.1836 + } 1.1837 + 1.1838 + p.pOln("}"); // end invoke 1.1839 + 1.1840 + // Write the cast array hack... 1.1841 + 1.1842 + writeCastArray(p); 1.1843 + 1.1844 + // End tie class... 1.1845 + p.pOln("}"); 1.1846 + } 1.1847 + public void catchWrongPolicy(IndentingWriter p) throws IOException { 1.1848 + p.pln(""); 1.1849 + } 1.1850 + public void catchServantNotActive(IndentingWriter p) throws IOException { 1.1851 + p.pln(""); 1.1852 + } 1.1853 + public void catchObjectNotActive(IndentingWriter p) throws IOException { 1.1854 + p.pln(""); 1.1855 + } 1.1856 + 1.1857 + public void write_tie_thisObject_method(IndentingWriter p, 1.1858 + Identifier idCorbaObject) 1.1859 + throws IOException 1.1860 + { 1.1861 + if(POATie){ 1.1862 + p.plnI("public " + idCorbaObject + " thisObject() {"); 1.1863 + /* 1.1864 + p.pln("org.omg.CORBA.Object objref = null;"); 1.1865 + p.pln("try{"); 1.1866 + p.pln("objref = _poa().servant_to_reference(this);"); 1.1867 + p.pln("}catch (org.omg.PortableServer.POAPackage.WrongPolicy exception){"); 1.1868 + catchWrongPolicy(p); 1.1869 + p.pln("}catch (org.omg.PortableServer.POAPackage.ServantNotActive exception){"); 1.1870 + catchServantNotActive(p); 1.1871 + p.pln("}"); 1.1872 + p.pln("return objref;"); 1.1873 + */ 1.1874 + p.pln("return _this_object();"); 1.1875 + p.pOln("}"); 1.1876 + } else { 1.1877 + p.plnI("public " + idCorbaObject + " thisObject() {"); 1.1878 + p.pln("return this;"); 1.1879 + p.pOln("}"); 1.1880 + } 1.1881 + } 1.1882 + 1.1883 + public void write_tie_deactivate_method(IndentingWriter p) 1.1884 + throws IOException 1.1885 + { 1.1886 + if(POATie){ 1.1887 + p.plnI("public void deactivate() {"); 1.1888 + p.pln("try{"); 1.1889 + p.pln("_poa().deactivate_object(_poa().servant_to_id(this));"); 1.1890 + p.pln("}catch (org.omg.PortableServer.POAPackage.WrongPolicy exception){"); 1.1891 + catchWrongPolicy(p); 1.1892 + p.pln("}catch (org.omg.PortableServer.POAPackage.ObjectNotActive exception){"); 1.1893 + catchObjectNotActive(p); 1.1894 + p.pln("}catch (org.omg.PortableServer.POAPackage.ServantNotActive exception){"); 1.1895 + catchServantNotActive(p); 1.1896 + p.pln("}"); 1.1897 + p.pOln("}"); 1.1898 + } else { 1.1899 + p.plnI("public void deactivate() {"); 1.1900 + p.pln("_orb().disconnect(this);"); 1.1901 + p.pln("_set_delegate(null);"); 1.1902 + p.pln("target = null;"); 1.1903 + p.pOln("}"); 1.1904 + } 1.1905 + } 1.1906 + 1.1907 + public void write_tie_orb_method(IndentingWriter p) 1.1908 + throws IOException 1.1909 + { 1.1910 + if(POATie){ 1.1911 + p.plnI("public void orb(ORB orb) {"); 1.1912 + /* 1.1913 + p.pln("try{"); 1.1914 + p.pln("orb.connect(_poa().servant_to_reference(this));"); 1.1915 + p.pln("}catch (org.omg.PortableServer.POAPackage.WrongPolicy exception){"); 1.1916 + catchWrongPolicy(p); 1.1917 + p.pln("}catch (org.omg.PortableServer.POAPackage.ServantNotActive exception){"); 1.1918 + catchServantNotActive(p); 1.1919 + p.pln("}"); 1.1920 + */ 1.1921 + p.pln("try {"); 1.1922 + p.pln(" ((org.omg.CORBA_2_3.ORB)orb).set_delegate(this);"); 1.1923 + p.pln("}"); 1.1924 + p.pln("catch(ClassCastException e) {"); 1.1925 + p.pln(" throw new org.omg.CORBA.BAD_PARAM"); 1.1926 + p.pln(" (\"POA Servant requires an instance of org.omg.CORBA_2_3.ORB\");"); 1.1927 + p.pln("}"); 1.1928 + p.pOln("}"); 1.1929 + } else { 1.1930 + p.plnI("public void orb(ORB orb) {"); 1.1931 + p.pln("orb.connect(this);"); 1.1932 + p.pOln("}"); 1.1933 + } 1.1934 + } 1.1935 + 1.1936 + public void write_tie__ids_method(IndentingWriter p) 1.1937 + throws IOException 1.1938 + { 1.1939 + if(POATie){ 1.1940 + p.plnI("public String[] _all_interfaces(org.omg.PortableServer.POA poa, byte[] objectId){"); 1.1941 + p.pln("return (String[]) _type_ids.clone();"); 1.1942 + p.pOln("}"); 1.1943 + } else { 1.1944 + p.plnI("public String[] _ids() { "); 1.1945 + p.pln("return (String[]) _type_ids.clone();"); 1.1946 + p.pOln("}"); 1.1947 + } 1.1948 + } 1.1949 + 1.1950 + 1.1951 + StaticStringsHash getStringsHash (CompoundType.Method[] methods) { 1.1952 + if (useHash && methods.length > 1) { 1.1953 + String[] methodNames = new String[methods.length]; 1.1954 + for (int i = 0; i < methodNames.length; i++) { 1.1955 + methodNames[i] = methods[i].getIDLName(); 1.1956 + } 1.1957 + return new StaticStringsHash(methodNames); 1.1958 + } 1.1959 + return null; 1.1960 + } 1.1961 + 1.1962 + static boolean needNewReadStreamClass(Type type) { 1.1963 + if (type.isType(TYPE_ABSTRACT)) { 1.1964 + return true; 1.1965 + } 1.1966 + // Handle late-breaking special case for 1.1967 + // abstract IDL entities... 1.1968 + if ((type instanceof CompoundType) && 1.1969 + ((CompoundType)type).isAbstractBase()) { 1.1970 + return true; 1.1971 + } 1.1972 + return needNewWriteStreamClass(type); 1.1973 + } 1.1974 + 1.1975 + static boolean needNewWriteStreamClass(Type type) { 1.1976 + switch (type.getTypeCode()) { 1.1977 + case TYPE_VOID: 1.1978 + case TYPE_BOOLEAN: 1.1979 + case TYPE_BYTE: 1.1980 + case TYPE_CHAR: 1.1981 + case TYPE_SHORT: 1.1982 + case TYPE_INT: 1.1983 + case TYPE_LONG: 1.1984 + case TYPE_FLOAT: 1.1985 + case TYPE_DOUBLE: return false; 1.1986 + 1.1987 + case TYPE_STRING: return true; 1.1988 + case TYPE_ANY: return false; 1.1989 + case TYPE_CORBA_OBJECT: return false; 1.1990 + case TYPE_REMOTE: return false; 1.1991 + case TYPE_ABSTRACT: return false; 1.1992 + case TYPE_NC_INTERFACE: return true; 1.1993 + case TYPE_VALUE: return true; 1.1994 + case TYPE_IMPLEMENTATION: return true; 1.1995 + case TYPE_NC_CLASS: return true; 1.1996 + case TYPE_ARRAY: return true; 1.1997 + case TYPE_JAVA_RMI_REMOTE: return false; 1.1998 + 1.1999 + default: throw new Error("unexpected type code: " + type.getTypeCode()); 1.2000 + } 1.2001 + } 1.2002 + 1.2003 + /* 1.2004 + * Decide which arguments need to be copied and write 1.2005 + * the copy code. Returns an array of argument names to 1.2006 + * use to refer to either the copy or the original. 1.2007 + */ 1.2008 + String[] writeCopyArguments(CompoundType.Method method, 1.2009 + IndentingWriter p) throws IOException { 1.2010 + 1.2011 + Type[] args = method.getArguments(); 1.2012 + String[] origNames = method.getArgumentNames(); 1.2013 + 1.2014 + // Copy the current parameter names to a result array... 1.2015 + 1.2016 + String[] result = new String[origNames.length]; 1.2017 + for (int i = 0; i < result.length; i++) { 1.2018 + result[i] = origNames[i]; 1.2019 + } 1.2020 + 1.2021 + // Decide which arguments must be copied, if any. If 1.2022 + // any of the arguments are types for which a 'real' copy 1.2023 + // will be done, rather than just an autoConnect, set 1.2024 + // realCopy = true. Note that abstract types may only 1.2025 + // need autoConnect, but we cannot know that at compile 1.2026 + // time... 1.2027 + 1.2028 + boolean realCopy = false; 1.2029 + boolean[] copyArg = new boolean[args.length]; 1.2030 + int copyCount = 0; 1.2031 + int firstCopiedArg = 0; // Only used in single copy case. It is only the first arg that 1.2032 + // needs copying IF copyCount == 1. 1.2033 + 1.2034 + for (int i = 0; i < args.length; i++) { 1.2035 + if (mustCopy(args[i])) { 1.2036 + copyArg[i] = true; 1.2037 + copyCount++; 1.2038 + firstCopiedArg = i; 1.2039 + if (args[i].getTypeCode() != TYPE_REMOTE && 1.2040 + args[i].getTypeCode() != TYPE_IMPLEMENTATION) { 1.2041 + realCopy = true; 1.2042 + } 1.2043 + } else { 1.2044 + copyArg[i] = false; 1.2045 + } 1.2046 + } 1.2047 + 1.2048 + // Do we have any types which must be copied? 1.2049 + if (copyCount > 0) { 1.2050 + // Yes. Are we only doing the copy to ensure 1.2051 + // that autoConnect occurs? 1.2052 + if (realCopy) { 1.2053 + // Nope. We need to go back thru the list and 1.2054 + // mark any strings so that they will be copied 1.2055 + // to preserve any shared references... 1.2056 + for (int i = 0; i < args.length; i++) { 1.2057 + if (args[i].getTypeCode() == TYPE_STRING) { 1.2058 + copyArg[i] = true; 1.2059 + copyCount++; 1.2060 + } 1.2061 + } 1.2062 + } 1.2063 + 1.2064 + // We're ready to generate code. Do we have more than 1.2065 + // one to copy? 1.2066 + if (copyCount > 1) { 1.2067 + // Generate a call to copyObjects... 1.2068 + String arrayName = getVariableName("copies"); 1.2069 + p.p("Object[] " + arrayName + " = Util.copyObjects(new Object[]{"); 1.2070 + boolean first = true; 1.2071 + for (int i = 0; i < args.length; i++) { 1.2072 + if (copyArg[i]) { 1.2073 + if (!first) { 1.2074 + p.p(","); 1.2075 + } 1.2076 + first = false; 1.2077 + p.p(origNames[i]); 1.2078 + } 1.2079 + } 1.2080 + p.pln("},_orb());"); 1.2081 + 1.2082 + // For each of the types which was copied, create 1.2083 + // a local temporary for it, updating the result 1.2084 + // array with the new local parameter name... 1.2085 + int copyIndex = 0 ; 1.2086 + for (int i = 0; i < args.length; i++) { 1.2087 + if (copyArg[i]) { 1.2088 + result[i] = getVariableName(result[i]+"Copy"); 1.2089 + p.pln( getName(args[i]) + " " + result[i] + " = (" + getName(args[i]) + ") " + 1.2090 + arrayName + "[" + copyIndex++ +"];"); 1.2091 + } 1.2092 + } 1.2093 + } else { 1.2094 + // Generate a call to copyObject, updating the result 1.2095 + // with the new local parameter name... 1.2096 + result[firstCopiedArg] = getVariableName(result[firstCopiedArg]+"Copy"); 1.2097 + p.pln( getName(args[firstCopiedArg]) + " " + result[firstCopiedArg] + " = (" + 1.2098 + getName(args[firstCopiedArg]) + ") Util.copyObject(" + 1.2099 + origNames[firstCopiedArg] + ",_orb());"); 1.2100 + } 1.2101 + } 1.2102 + 1.2103 + return result; 1.2104 + } 1.2105 + 1.2106 + static final String SINGLE_SLASH = "\\"; 1.2107 + static final String DOUBLE_SLASH = SINGLE_SLASH + SINGLE_SLASH; 1.2108 + 1.2109 + String getRepositoryID(Type type) { 1.2110 + return IDLNames.replace(type.getRepositoryID(), SINGLE_SLASH, DOUBLE_SLASH); 1.2111 + } 1.2112 + 1.2113 + String getExceptionRepositoryID(Type type) { 1.2114 + ClassType theType = (ClassType) type; 1.2115 + return IDLNames.getIDLRepositoryID(theType.getQualifiedIDLExceptionName(false)); 1.2116 + } 1.2117 + 1.2118 + String getVariableName(String proposed) { 1.2119 + while (namesInUse.contains(proposed)) { 1.2120 + proposed = "$" + proposed; 1.2121 + } 1.2122 + 1.2123 + return proposed; 1.2124 + } 1.2125 + 1.2126 + void addNamesInUse(CompoundType.Method[] methods) { 1.2127 + for (int i = 0; i < methods.length; i++) { 1.2128 + addNamesInUse(methods[i]); 1.2129 + } 1.2130 + } 1.2131 + 1.2132 + void addNamesInUse(CompoundType.Method method) { 1.2133 + String paramNames[] = method.getArgumentNames(); 1.2134 + for (int i = 0; i < paramNames.length; i++) { 1.2135 + addNameInUse(paramNames[i]); 1.2136 + } 1.2137 + } 1.2138 + 1.2139 + void addNameInUse(String name) { 1.2140 + namesInUse.add(name); 1.2141 + } 1.2142 + 1.2143 + static boolean mustCopy(Type type) { 1.2144 + switch (type.getTypeCode()) { 1.2145 + case TYPE_VOID: 1.2146 + case TYPE_BOOLEAN: 1.2147 + case TYPE_BYTE: 1.2148 + case TYPE_CHAR: 1.2149 + case TYPE_SHORT: 1.2150 + case TYPE_INT: 1.2151 + case TYPE_LONG: 1.2152 + case TYPE_FLOAT: 1.2153 + case TYPE_DOUBLE: 1.2154 + case TYPE_STRING: return false; 1.2155 + 1.2156 + case TYPE_ANY: return true; 1.2157 + 1.2158 + case TYPE_CORBA_OBJECT: return false; 1.2159 + 1.2160 + case TYPE_REMOTE: 1.2161 + case TYPE_ABSTRACT: 1.2162 + case TYPE_NC_INTERFACE: 1.2163 + case TYPE_VALUE: 1.2164 + case TYPE_IMPLEMENTATION: 1.2165 + case TYPE_NC_CLASS: 1.2166 + case TYPE_ARRAY: 1.2167 + case TYPE_JAVA_RMI_REMOTE: return true; 1.2168 + 1.2169 + default: throw new Error("unexpected type code: " + type.getTypeCode()); 1.2170 + } 1.2171 + } 1.2172 + 1.2173 + ValueType[] getStubExceptions (CompoundType.Method method, boolean sort) { 1.2174 + 1.2175 + ValueType[] list = method.getFilteredStubExceptions(method.getExceptions()); 1.2176 + 1.2177 + // Sort the list so that all org.omg.CORBA.UserException 1.2178 + // subtypes are at the beginning of the list. This ensures 1.2179 + // that the stub will not call read_string() before calling 1.2180 + // XXHelper.read(). 1.2181 + 1.2182 + if (sort) { 1.2183 + Arrays.sort(list,new UserExceptionComparator()); 1.2184 + } 1.2185 + 1.2186 + return list; 1.2187 + } 1.2188 + 1.2189 + ValueType[] getTieExceptions (CompoundType.Method method) { 1.2190 + return method.getUniqueCatchList(method.getImplExceptions()); 1.2191 + } 1.2192 + 1.2193 + void writeTieMethod(IndentingWriter p, CompoundType type, 1.2194 + CompoundType.Method method) throws IOException { 1.2195 + String methodName = method.getName(); 1.2196 + Type paramTypes[] = method.getArguments(); 1.2197 + String paramNames[] = method.getArgumentNames(); 1.2198 + Type returnType = method.getReturnType(); 1.2199 + ValueType[] exceptions = getTieExceptions(method); 1.2200 + String in = getVariableName("in"); 1.2201 + String ex = getVariableName("ex"); 1.2202 + String out = getVariableName("out"); 1.2203 + String reply = getVariableName("reply"); 1.2204 + 1.2205 + for (int i = 0; i < paramTypes.length; i++) { 1.2206 + p.p(getName(paramTypes[i])+" "+paramNames[i]+" = "); 1.2207 + writeUnmarshalArgument(p, in, paramTypes[i], null); 1.2208 + p.pln(); 1.2209 + } 1.2210 + 1.2211 + boolean handleExceptions = exceptions != null; 1.2212 + boolean doReturn = !returnType.isType(TYPE_VOID); 1.2213 + 1.2214 + if (handleExceptions && doReturn) { 1.2215 + String objName = testUtil(getName(returnType), returnType); 1.2216 + p.pln(objName+" result;"); 1.2217 + } 1.2218 + 1.2219 + if (handleExceptions) 1.2220 + p.plnI("try {"); 1.2221 + 1.2222 + if (doReturn) { 1.2223 + if (handleExceptions) { 1.2224 + p.p("result = "); 1.2225 + } else { 1.2226 + p.p(getName(returnType)+" result = "); 1.2227 + } 1.2228 + } 1.2229 + 1.2230 + p.p("target."+methodName+"("); 1.2231 + for(int i = 0; i < paramNames.length; i++) { 1.2232 + if (i > 0) 1.2233 + p.p(", "); 1.2234 + p.p(paramNames[i]); 1.2235 + } 1.2236 + p.pln(");"); 1.2237 + 1.2238 + if (handleExceptions) { 1.2239 + for(int i = 0; i < exceptions.length; i++) { 1.2240 + p.pOlnI("} catch ("+getName(exceptions[i])+" "+ex+") {"); 1.2241 + 1.2242 + // Is this our IDLEntity Exception special case? 1.2243 + 1.2244 + if (exceptions[i].isIDLEntityException() && !exceptions[i].isCORBAUserException()) { 1.2245 + 1.2246 + // Yes... 1.2247 + 1.2248 + String helperName = IDLNames.replace(exceptions[i].getQualifiedIDLName(false),"::","."); 1.2249 + helperName += "Helper"; 1.2250 + p.pln(idOutputStream+" "+out +" = "+reply+".createExceptionReply();"); 1.2251 + p.pln(helperName+".write("+out+","+ex+");"); 1.2252 + 1.2253 + } else { 1.2254 + 1.2255 + // No... 1.2256 + 1.2257 + p.pln("String id = \"" + getExceptionRepositoryID(exceptions[i]) + "\";"); 1.2258 + p.plnI(idExtOutputStream + " "+out+" = "); 1.2259 + p.pln("(" + idExtOutputStream + ") "+reply+".createExceptionReply();"); 1.2260 + p.pOln(out+".write_string(id);"); 1.2261 + p.pln(out+".write_value("+ex+"," + getName(exceptions[i]) + ".class);"); 1.2262 + } 1.2263 + 1.2264 + p.pln("return "+out+";"); 1.2265 + } 1.2266 + p.pOln("}"); 1.2267 + } 1.2268 + 1.2269 + if (needNewWriteStreamClass(returnType)) { 1.2270 + p.plnI(idExtOutputStream + " "+out+" = "); 1.2271 + p.pln("(" + idExtOutputStream + ") "+reply+".createReply();"); 1.2272 + p.pO(); 1.2273 + } else { 1.2274 + p.pln("OutputStream "+out+" = "+reply+".createReply();"); 1.2275 + } 1.2276 + 1.2277 + if (doReturn) { 1.2278 + writeMarshalArgument(p, out, returnType, "result"); 1.2279 + p.pln(); 1.2280 + } 1.2281 + 1.2282 + p.pln("return "+out+";"); 1.2283 + } 1.2284 + 1.2285 + 1.2286 + /** 1.2287 + * Write Java statements to marshal a series of values in order as 1.2288 + * named in the "names" array, with types as specified in the "types" 1.2289 + * array", to the java.io.ObjectOutput stream named "stream". 1.2290 + */ 1.2291 + void writeMarshalArguments(IndentingWriter p, 1.2292 + String streamName, 1.2293 + Type[] types, String[] names) 1.2294 + throws IOException 1.2295 + { 1.2296 + if (types.length != names.length) { 1.2297 + throw new Error("paramter type and name arrays different sizes"); 1.2298 + } 1.2299 + 1.2300 + for (int i = 0; i < types.length; i++) { 1.2301 + writeMarshalArgument(p, streamName, types[i], names[i]); 1.2302 + if (i != types.length -1) { 1.2303 + p.pln(); 1.2304 + } 1.2305 + } 1.2306 + } 1.2307 + 1.2308 + /** 1.2309 + * Added for IASRI 4987274. Remote classes named "Util" were 1.2310 + * getting confused with javax.rmi.CORBA.Util and the 1.2311 + * unqualifiedName "Util". 1.2312 + */ 1.2313 + String testUtil(String objectName, Type ttype) { 1.2314 + if (objectName.equals("Util")) { 1.2315 + String correctedName = (String)ttype.getPackageName() + "." + objectName; 1.2316 + return correctedName; 1.2317 + } else { 1.2318 + return objectName; 1.2319 + } 1.2320 + } 1.2321 +} 1.2322 + 1.2323 +class StringComparator implements java.util.Comparator { 1.2324 + public int compare(Object o1, Object o2) { 1.2325 + String s1 = (String)o1; 1.2326 + String s2 = (String)o2; 1.2327 + return s1.compareTo(s2); 1.2328 + } 1.2329 +} 1.2330 + 1.2331 + 1.2332 +class UserExceptionComparator implements java.util.Comparator { 1.2333 + public int compare(Object o1, Object o2) { 1.2334 + ValueType v1 = (ValueType)o1; 1.2335 + ValueType v2 = (ValueType)o2; 1.2336 + int result = 0; 1.2337 + if (isUserException(v1)) { 1.2338 + if (!isUserException(v2)) { 1.2339 + result = -1; 1.2340 + } 1.2341 + } else if (isUserException(v2)) { 1.2342 + if (!isUserException(v1)) { 1.2343 + result = 1; 1.2344 + } 1.2345 + } 1.2346 + return result; 1.2347 + } 1.2348 + 1.2349 + final boolean isUserException(ValueType it) { 1.2350 + return it.isIDLEntityException() && !it.isCORBAUserException(); 1.2351 + } 1.2352 +}