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