1 /* 2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 /* 26 * COMPONENT_NAME: idl.toJava 27 * 28 * ORIGINS: 27 29 * 30 * Licensed Materials - Property of IBM 31 * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999 32 * RMI-IIOP v1.0 33 * 34 */ 35 36 package com.sun.tools.corba.se.idl.toJavaPortable; 37 38 // NOTES: 39 // -cast() does not support longlong types yet. 40 // -Deal with typedef changes. 41 // -Scoped names for the discriminator are ignored at the moment. 42 // -F46082.51<daz> Remove -stateful feature; javaStatefulName() obsolete. 43 // -D61056 <klr> Use Util.helperName 44 45 import java.io.File; 46 import java.io.IOException; 47 import java.io.PrintWriter; 48 import java.util.Enumeration; 49 import java.util.Hashtable; 50 import java.util.Vector; 51 52 import com.sun.tools.corba.se.idl.GenFileStream; 53 import com.sun.tools.corba.se.idl.ConstEntry; 54 import com.sun.tools.corba.se.idl.EnumEntry; 55 import com.sun.tools.corba.se.idl.InterfaceEntry; 56 import com.sun.tools.corba.se.idl.PrimitiveEntry; 57 import com.sun.tools.corba.se.idl.SequenceEntry; 58 import com.sun.tools.corba.se.idl.StringEntry; 59 import com.sun.tools.corba.se.idl.SymtabEntry; 60 import com.sun.tools.corba.se.idl.TypedefEntry; 61 import com.sun.tools.corba.se.idl.UnionBranch; 62 import com.sun.tools.corba.se.idl.UnionEntry; 63 64 import com.sun.tools.corba.se.idl.constExpr.Expression; 65 import com.sun.tools.corba.se.idl.constExpr.EvaluationException; 66 67 /** 68 * 69 **/ 70 public class UnionGen implements com.sun.tools.corba.se.idl.UnionGen, JavaGenerator 71 { 72 /** 73 * Public zero-argument constructor. 74 **/ UnionGen()75 public UnionGen () 76 { 77 } // ctor 78 79 /** 80 * 81 **/ generate(Hashtable symbolTable, UnionEntry u, PrintWriter s)82 public void generate (Hashtable symbolTable, UnionEntry u, PrintWriter s) 83 { 84 this.symbolTable = symbolTable; 85 this.u = u; 86 init (); 87 88 openStream (); 89 if (stream == null) 90 return; 91 generateHelper (); 92 generateHolder (); 93 writeHeading (); 94 writeBody (); 95 writeClosing (); 96 closeStream (); 97 generateContainedTypes (); 98 } // generate 99 100 /** 101 * Initialize members unique to this generator. 102 **/ init()103 protected void init () 104 { 105 utype = Util.typeOf (u.type ()); 106 unionIsEnum = utype instanceof EnumEntry; 107 } // init 108 109 /** 110 * 111 **/ openStream()112 protected void openStream () 113 { 114 stream = Util.stream (u, ".java"); 115 } // openStream 116 117 /** 118 * 119 **/ generateHelper()120 protected void generateHelper () 121 { 122 ((Factories)Compile.compiler.factories ()).helper ().generate (symbolTable, u); 123 } // generateHelper 124 125 /** 126 * 127 **/ generateHolder()128 protected void generateHolder () 129 { 130 ((Factories)Compile.compiler.factories ()).holder ().generate (symbolTable, u); 131 } // generateHolder 132 133 /** 134 * 135 **/ writeHeading()136 protected void writeHeading () 137 { 138 // If the discriminator is an enum, assign the typePackage string. 139 if (unionIsEnum) 140 typePackage = Util.javaQualifiedName (utype) + '.'; 141 else 142 typePackage = ""; 143 144 Util.writePackage (stream, u); 145 Util.writeProlog (stream, ((GenFileStream)stream).name ()); 146 147 String className = u.name (); 148 stream.println ("public final class " + u.name () + " implements org.omg.CORBA.portable.IDLEntity"); 149 stream.println ("{"); 150 } // writeHeading 151 152 /** 153 * 154 **/ writeBody()155 protected void writeBody () 156 { 157 // Write branches and populate quality arrays 158 int size = u.branches ().size () + 1; 159 Enumeration e = u.branches ().elements (); 160 int i = 0; 161 while (e.hasMoreElements ()) 162 { 163 UnionBranch branch = (UnionBranch)e.nextElement (); 164 Util.fillInfo (branch.typedef); 165 // <f46082.51> Remove -stateful feature; javaStatefulName() obsolete. 166 //stream.println (" private " + Util.javaStatefulName (branch.typedef) + " ___" + branch.typedef.name () + ";"); 167 stream.println (" private " + Util.javaName (branch.typedef) + " ___" + branch.typedef.name () + ";"); 168 ++i; 169 } 170 stream.println (" private " + Util.javaName (utype) + " __discriminator;"); 171 stream.println (" private boolean __uninitialized = true;"); 172 173 // Write ctor 174 stream.println (); 175 stream.println (" public " + u.name () + " ()"); 176 stream.println (" {"); 177 stream.println (" }"); 178 179 // Write discriminator 180 stream.println (); 181 stream.println (" public " + Util.javaName (utype) + " " + safeName (u, "discriminator") + " ()"); 182 stream.println (" {"); 183 stream.println (" if (__uninitialized)"); 184 stream.println (" throw new org.omg.CORBA.BAD_OPERATION ();"); 185 stream.println (" return __discriminator;"); 186 stream.println (" }"); 187 188 // Write for each branch: 189 // - setter 190 // - getter 191 // - private verifyXXX 192 e = u.branches ().elements (); 193 i = 0; 194 while (e.hasMoreElements ()) 195 { 196 UnionBranch branch = (UnionBranch)e.nextElement (); 197 writeBranchMethods (stream, u, branch, i++); 198 } 199 if (u.defaultBranch () == null && !coversAll (u)) 200 { 201 stream.println (); 202 stream.println (" public void _default ()"); 203 stream.println (" {"); 204 stream.println (" __discriminator = " + defaultDiscriminator (u) + ';'); 205 stream.println (" __uninitialized = false;"); 206 stream.println (" }"); 207 208 stream.println (); 209 stream.println (" public void _default (" + Util.javaName(utype) + 210 " discriminator)"); 211 stream.println (" {"); 212 stream.println (" verifyDefault( discriminator ) ;" ); 213 stream.println (" __discriminator = discriminator ;"); 214 stream.println (" __uninitialized = false;"); 215 stream.println (" }"); 216 217 writeVerifyDefault() ; 218 } 219 stream.println (); 220 } // writeBody 221 222 /** 223 * 224 **/ writeClosing()225 protected void writeClosing () 226 { 227 stream.println ("} // class " + u.name ()); 228 } // writeClosing 229 230 /** 231 * 232 **/ closeStream()233 protected void closeStream () 234 { 235 stream.close (); 236 } // closeStream 237 238 /** 239 * 240 **/ generateContainedTypes()241 protected void generateContainedTypes () 242 { 243 Enumeration e = u.contained ().elements (); 244 while (e.hasMoreElements ()) 245 { 246 SymtabEntry entry = (SymtabEntry)e.nextElement (); 247 248 // Don't generate contained entries if they are sequences. 249 // Sequences are unnamed and since they translate to arrays, 250 // no classes are generated for them, not even holders in this 251 // case since they cannot be accessed outside of this union. 252 if (!(entry instanceof SequenceEntry)) 253 entry.generate (symbolTable, stream); 254 } 255 } // generateContainedTypes 256 writeVerifyDefault()257 private void writeVerifyDefault() 258 { 259 Vector labels = vectorizeLabels (u.branches (), true); 260 261 if (Util.javaName(utype).equals ("boolean")) { 262 stream.println( "" ) ; 263 stream.println( " private void verifyDefault (boolean discriminator)" ) ; 264 stream.println( " {" ) ; 265 if (labels.contains ("true")) 266 stream.println (" if ( discriminator )"); 267 else 268 stream.println (" if ( !discriminator )"); 269 stream.println( " throw new org.omg.CORBA.BAD_OPERATION();" ) ; 270 stream.println( " }" ) ; 271 return; 272 } 273 274 stream.println( "" ) ; 275 stream.println( " private void verifyDefault( " + Util.javaName(utype) + 276 " value )" ) ; 277 stream.println( " {" ) ; 278 279 if (unionIsEnum) 280 stream.println( " switch (value.value()) {" ) ; 281 else 282 stream.println( " switch (value) {" ) ; 283 284 Enumeration e = labels.elements() ; 285 while (e.hasMoreElements()) { 286 String str = (String)(e.nextElement()) ; 287 stream.println( " case " + str + ":" ) ; 288 } 289 290 stream.println( " throw new org.omg.CORBA.BAD_OPERATION() ;" ) ; 291 stream.println( "" ) ; 292 stream.println( " default:" ) ; 293 stream.println( " return;" ) ; 294 stream.println( " }" ) ; 295 stream.println( " }" ) ; 296 } 297 defaultDiscriminator(UnionEntry u)298 private String defaultDiscriminator (UnionEntry u) 299 { 300 Vector labels = vectorizeLabels (u.branches (), false ); 301 String ret = null; 302 SymtabEntry utype = Util.typeOf (u.type ()); 303 if (utype instanceof PrimitiveEntry && utype.name ().equals ("boolean")) { 304 // If it got this far, then: 305 // - there is only one branch; 306 // - that branch has only one label. 307 if (labels.contains ("true")) 308 ret = "false"; 309 else 310 ret = "true"; 311 } else if (utype.name ().equals ("char")) { 312 // This doesn't handle '\u0030' == '0'. Unions are so 313 // seldom used. I don't have time to make this perfect. 314 int def = 0; 315 String string = "'\\u0000'"; 316 while (def != 0xFFFF && labels.contains (string)) 317 if (++def / 0x10 == 0) 318 string = "'\\u000" + def + "'"; 319 else if (def / 0x100 == 0) 320 string = "\\u00" + def + "'"; 321 else if (def / 0x1000 == 0) 322 string = "\\u0" + def + "'"; 323 else 324 string = "\\u" + def + "'"; 325 ret = string; 326 } else if (utype instanceof EnumEntry) { 327 Enumeration e = labels.elements (); 328 EnumEntry enumEntry = (EnumEntry)utype; 329 Vector enumList = (Vector)enumEntry.elements ().clone (); 330 // cull out those elements in the enumeration list that are 331 // in the cases of this union 332 while (e.hasMoreElements ()) 333 enumList.removeElement (e.nextElement ()); 334 // If all of the enum elements are covered in this union and 335 // there is a default statement, just pick one of the 336 // elements for the default. If there are enum elements 337 // which are NOT covered by the cases, pick one as the 338 // default. 339 if (enumList.size () == 0) 340 ret = typePackage + (String)enumEntry.elements ().lastElement (); 341 else 342 ret = typePackage + (String)enumList.firstElement (); 343 } else if (utype.name ().equals ("octet")) { 344 short def = Byte.MIN_VALUE; 345 while (def != Byte.MAX_VALUE && labels.contains (Integer.toString (def))) 346 ++def; 347 ret = Integer.toString (def); 348 } else if (utype.name ().equals ("short")) { 349 short def = Short.MIN_VALUE; 350 while (def != Short.MAX_VALUE && labels.contains (Integer.toString (def))) 351 ++def; 352 ret = Integer.toString (def); 353 } else if (utype.name ().equals ("long")) { 354 int def = Integer.MIN_VALUE; 355 while (def != Integer.MAX_VALUE && labels.contains (Integer.toString (def))) 356 ++def; 357 ret = Integer.toString (def); 358 } else if (utype.name ().equals ("long long")) { 359 long def = Long.MIN_VALUE; 360 while (def != Long.MAX_VALUE && labels.contains (Long.toString (def))) 361 ++def; 362 ret = Long.toString (def); 363 } else if (utype.name ().equals ("unsigned short")) { 364 short def = 0; 365 while (def != Short.MAX_VALUE && labels.contains (Integer.toString (def))) 366 ++def; 367 ret = Integer.toString (def); 368 } else if (utype.name ().equals ("unsigned long")) { 369 int def = 0; 370 while (def != Integer.MAX_VALUE && labels.contains (Integer.toString (def))) 371 ++def; 372 ret = Integer.toString (def); 373 } else if (utype.name ().equals ("unsigned long long")) { 374 long def = 0; 375 while (def != Long.MAX_VALUE && labels.contains (Long.toString (def))) 376 ++def; 377 ret = Long.toString (def); 378 } 379 380 return ret; 381 } // defaultDiscriminator 382 383 /** 384 * 385 **/ vectorizeLabels(Vector branchVector, boolean useIntsForEnums )386 private Vector vectorizeLabels (Vector branchVector, boolean useIntsForEnums ) 387 { 388 Vector mergedLabels = new Vector (); 389 Enumeration branches = branchVector.elements (); 390 while (branches.hasMoreElements ()) 391 { 392 UnionBranch branch = (UnionBranch)branches.nextElement (); 393 Enumeration labels = branch.labels.elements (); 394 while (labels.hasMoreElements ()) 395 { 396 Expression expr = (Expression)labels.nextElement (); 397 String str ; 398 399 if (unionIsEnum) 400 if (useIntsForEnums) 401 str = typePackage + "_" + Util.parseExpression( expr ) ; 402 else 403 str = typePackage + Util.parseExpression( expr ) ; 404 else 405 str = Util.parseExpression( expr ) ; 406 407 mergedLabels.addElement (str); 408 } 409 } 410 return mergedLabels; 411 } // vectorizeLabels 412 413 /** 414 * 415 **/ safeName(UnionEntry u, String name)416 private String safeName (UnionEntry u, String name) 417 { 418 Enumeration e = u.branches ().elements (); 419 while (e.hasMoreElements ()) 420 if (((UnionBranch)e.nextElement ()).typedef.name ().equals (name)) 421 { 422 name = '_' + name; 423 break; 424 } 425 return name; 426 } // safeName 427 428 /** 429 * 430 **/ coversAll(UnionEntry u)431 private boolean coversAll (UnionEntry u) 432 { 433 // This assumes that it is not possible to cover types other than 434 // boolean and enums. This is not quite correct, but since octet 435 // is not a valid discriminator type, it's not too bad in practice. 436 // It may also be possible to cover a char type, but we won't worry 437 // about that either. 438 SymtabEntry utype = Util.typeOf (u.type ()); 439 440 boolean coversAll = false; 441 if (utype.name ().equals ("boolean")) { 442 if (u.branches ().size () == 2) 443 coversAll = true; 444 } else if (utype instanceof EnumEntry) { 445 Vector labels = vectorizeLabels (u.branches (), true); 446 if (labels.size () == ((EnumEntry)utype).elements ().size ()) 447 coversAll = true; 448 } 449 450 return coversAll; 451 } // coversAll 452 453 /** 454 * 455 **/ writeBranchMethods(PrintWriter stream, UnionEntry u, UnionBranch branch, int i)456 private void writeBranchMethods (PrintWriter stream, UnionEntry u, UnionBranch branch, int i) 457 { 458 // Write getter 459 stream.println (); 460 // <f46082.51> Remove -stateful feature; javaStatefulName() obsolete. 461 //stream.println (" public " + Util.javaStatefulName (branch.typedef) + " " + branch.typedef.name () + " ()"); 462 stream.println (" public " + Util.javaName (branch.typedef) + " " + branch.typedef.name () + " ()"); 463 stream.println (" {"); 464 stream.println (" if (__uninitialized)"); 465 stream.println (" throw new org.omg.CORBA.BAD_OPERATION ();"); 466 stream.println (" verify" + branch.typedef.name () + " (__discriminator);"); 467 stream.println (" return ___" + branch.typedef.name () + ";"); 468 stream.println (" }"); 469 470 // Write setter(s) 471 stream.println (); 472 // <f46082.51> Remove -stateful feature; javaStatefulName() obsolete. 473 //stream.println (" public void " + branch.typedef.name () + " (" + Util.javaStatefulName (branch.typedef) + " value)"); 474 stream.println (" public void " + branch.typedef.name () + " (" + Util.javaName (branch.typedef) + " value)"); 475 stream.println (" {"); 476 if (branch.labels.size () == 0) 477 { 478 // This is a default branch 479 stream.println (" __discriminator = " + defaultDiscriminator (u) + ";"); 480 } 481 else 482 { 483 // This is a non-default branch 484 if (unionIsEnum) 485 stream.println (" __discriminator = " + typePackage + Util.parseExpression ((Expression)branch.labels.firstElement ()) + ";"); 486 else 487 stream.println (" __discriminator = " + cast ((Expression)branch.labels.firstElement (), u.type ()) + ";"); 488 } 489 stream.println (" ___" + branch.typedef.name () + " = value;"); 490 stream.println (" __uninitialized = false;"); 491 stream.println (" }"); 492 493 SymtabEntry utype = Util.typeOf (u.type ()); 494 495 // If there are multiple labels for one branch, write the 496 // setter that takes a discriminator. 497 if (branch.labels.size () > 0 || branch.isDefault) 498 { 499 stream.println (); 500 // <f46082.51> Remove -stateful feature; javaStatefulName() obsolete. 501 //stream.println (" public void " + branch.typedef.name () + " (" + Util.javaName (utype) + " discriminator, " + Util.javaStatefulName (branch.typedef) + " value)"); 502 stream.println (" public void " + branch.typedef.name () + " (" + Util.javaName (utype) + " discriminator, " + Util.javaName (branch.typedef) + " value)"); 503 stream.println (" {"); 504 stream.println (" verify" + branch.typedef.name () + " (discriminator);"); 505 stream.println (" __discriminator = discriminator;"); 506 stream.println (" ___" + branch.typedef.name () + " = value;"); 507 stream.println (" __uninitialized = false;"); 508 stream.println (" }"); 509 } 510 511 // Write verifyXXX 512 stream.println (); 513 stream.println (" private void verify" + branch.typedef.name () + " (" + Util.javaName (utype) + " discriminator)"); 514 stream.println (" {"); 515 516 boolean onlyOne = true; 517 518 if (branch.isDefault && u.branches ().size () == 1) 519 ;// If all that is in this union is a default branch, 520 // all discriminators are legal. Don't print any 521 // body to this method in that case. 522 else 523 { 524 // Otherwise this code is executed and a body is printed. 525 stream.print (" if ("); 526 if (branch.isDefault) 527 { 528 Enumeration eBranches = u.branches ().elements (); 529 while (eBranches.hasMoreElements ()) 530 { 531 UnionBranch b = (UnionBranch)eBranches.nextElement (); 532 if (b != branch) 533 { 534 Enumeration eLabels = b.labels.elements (); 535 while (eLabels.hasMoreElements ()) 536 { 537 Expression label = (Expression)eLabels.nextElement (); 538 if (!onlyOne) 539 stream.print (" || "); 540 if (unionIsEnum) 541 stream.print ("discriminator == " + typePackage + Util.parseExpression (label)); 542 else 543 stream.print ("discriminator == " + Util.parseExpression (label)); 544 onlyOne = false; 545 } 546 } 547 } 548 } 549 else 550 { 551 Enumeration e = branch.labels.elements (); 552 while (e.hasMoreElements ()) 553 { 554 Expression label = (Expression)e.nextElement (); 555 if (!onlyOne) 556 stream.print (" && "); 557 if (unionIsEnum) 558 stream.print ("discriminator != " + typePackage + Util.parseExpression (label)); 559 else 560 stream.print ("discriminator != " + Util.parseExpression (label)); 561 onlyOne = false; 562 } 563 } 564 stream.println (")"); 565 stream.println (" throw new org.omg.CORBA.BAD_OPERATION ();"); 566 } 567 stream.println (" }"); 568 } // writeBranchMethods 569 570 /////////////// 571 // From JavaGenerator 572 573 /** 574 * 575 **/ 576 577 // Computes the total number of labels in the union, which is the sum 578 // of the number of labels in each branch of the union. Note that the 579 // label for the default branch has size 0, but still counts in the total 580 // size. unionLabelSize( UnionEntry un )581 private int unionLabelSize( UnionEntry un ) 582 { 583 int size = 0 ; 584 Vector branches = un.branches() ; 585 for (int i = 0; i < branches.size (); ++i) { 586 UnionBranch branch = (UnionBranch)(branches.get(i)) ; 587 int branchSize = branch.labels.size() ; 588 size += ((branchSize == 0) ? 1 : branchSize) ; 589 } 590 return size ; 591 } 592 helperType(int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream)593 public int helperType (int index, String indent, TCOffsets tcoffsets, 594 String name, SymtabEntry entry, PrintWriter stream) 595 { 596 TCOffsets innerOffsets = new TCOffsets (); 597 UnionEntry u = (UnionEntry)entry; 598 String discTypeCode = "_disTypeCode" + index; 599 String membersName = "_members" + index; 600 601 // Build discriminator tc 602 stream.println (indent + "org.omg.CORBA.TypeCode " + discTypeCode + ';'); 603 index = ((JavaGenerator)u.type ().generator ()).type (index + 1, indent, 604 innerOffsets, discTypeCode, u.type (), stream); 605 tcoffsets.bumpCurrentOffset (innerOffsets.currentOffset ()); 606 607 stream.println (indent + "org.omg.CORBA.UnionMember[] " + membersName + 608 " = new org.omg.CORBA.UnionMember [" + unionLabelSize(u) + "];"); 609 String tcOfMembers = "_tcOf" + membersName; 610 String anyOfMembers = "_anyOf" + membersName; 611 stream.println (indent + "org.omg.CORBA.TypeCode " + tcOfMembers + ';'); 612 stream.println (indent + "org.omg.CORBA.Any " + anyOfMembers + ';'); 613 614 innerOffsets = new TCOffsets (); 615 innerOffsets.set (entry); 616 int offsetForUnion = innerOffsets.currentOffset (); 617 for (int i = 0; i < u.branches ().size (); ++i) { 618 UnionBranch branch = (UnionBranch)u.branches ().elementAt (i); 619 TypedefEntry member = branch.typedef; 620 Vector labels = branch.labels; 621 String memberName = Util.stripLeadingUnderscores (member.name ()); 622 623 if (labels.size() == 0) { 624 stream.println (); 625 stream.println (indent + "// Branch for " + memberName + 626 " (Default case)" ); 627 SymtabEntry utype = Util.typeOf (u.type ()); 628 stream.println (indent + anyOfMembers + " = org.omg.CORBA.ORB.init ().create_any ();"); 629 // For default member, label is the zero octet (per CORBA spec.) 630 stream.println (indent + anyOfMembers + ".insert_octet ((byte)0); // default member label"); 631 632 // Build typecode 633 innerOffsets.bumpCurrentOffset (4); // label value 634 index = ((JavaGenerator)member.generator ()).type (index, indent, innerOffsets, tcOfMembers, member, stream); 635 int offsetSoFar = innerOffsets.currentOffset (); 636 innerOffsets = new TCOffsets (); 637 innerOffsets.set (entry); 638 innerOffsets.bumpCurrentOffset (offsetSoFar - offsetForUnion); 639 640 // Build union member 641 stream.println (indent + membersName + '[' + i + "] = new org.omg.CORBA.UnionMember ("); 642 stream.println (indent + " \"" + memberName + "\","); 643 stream.println (indent + " " + anyOfMembers + ','); 644 stream.println (indent + " " + tcOfMembers + ','); 645 stream.println (indent + " null);"); 646 } else { 647 Enumeration enumeration = labels.elements() ; 648 while (enumeration.hasMoreElements()) { 649 Expression expr = (Expression)(enumeration.nextElement()) ; 650 String elem = Util.parseExpression( expr ) ; 651 652 stream.println (); 653 stream.println (indent + "// Branch for " + memberName + 654 " (case label " + elem + ")" ); 655 656 SymtabEntry utype = Util.typeOf (u.type ()); 657 658 // Build any 659 stream.println (indent + anyOfMembers + " = org.omg.CORBA.ORB.init ().create_any ();"); 660 661 if (utype instanceof PrimitiveEntry) 662 stream.println (indent + anyOfMembers + ".insert_" + 663 Util.collapseName (utype.name ()) + " ((" + Util.javaName (utype) + 664 ')' + elem + ");"); 665 else { // it must be enum 666 String enumClass = Util.javaName (utype); 667 stream.println (indent + Util.helperName (utype, false) + ".insert (" + 668 anyOfMembers + ", " + enumClass + '.' + elem + ");"); // <d61056> 669 } 670 671 // Build typecode 672 innerOffsets.bumpCurrentOffset (4); // label value 673 index = ((JavaGenerator)member.generator ()).type (index, indent, innerOffsets, tcOfMembers, member, stream); 674 int offsetSoFar = innerOffsets.currentOffset (); 675 innerOffsets = new TCOffsets (); 676 innerOffsets.set (entry); 677 innerOffsets.bumpCurrentOffset (offsetSoFar - offsetForUnion); 678 679 // Build union member 680 stream.println (indent + membersName + '[' + i + "] = new org.omg.CORBA.UnionMember ("); 681 stream.println (indent + " \"" + memberName + "\","); 682 stream.println (indent + " " + anyOfMembers + ','); 683 stream.println (indent + " " + tcOfMembers + ','); 684 stream.println (indent + " null);"); 685 } 686 } 687 } 688 689 tcoffsets.bumpCurrentOffset (innerOffsets.currentOffset ()); 690 691 // Build create_union_tc 692 stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_union_tc (" + 693 Util.helperName (u, true) + ".id (), \"" + entry.name () + "\", " + 694 discTypeCode + ", " + membersName + ");"); 695 return index; 696 } // helperType 697 type(int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream)698 public int type (int index, String indent, TCOffsets tcoffsets, String name, 699 SymtabEntry entry, PrintWriter stream) 700 { 701 stream.println (indent + name + " = " + Util.helperName (entry, true) + ".type ();"); 702 return index; 703 } 704 helperRead(String entryName, SymtabEntry entry, PrintWriter stream)705 public void helperRead (String entryName, SymtabEntry entry, PrintWriter stream) 706 { 707 stream.println (" " + entryName + " value = new " + entryName + " ();"); 708 read (0, " ", "value", entry, stream); 709 stream.println (" return value;"); 710 } 711 helperWrite(SymtabEntry entry, PrintWriter stream)712 public void helperWrite (SymtabEntry entry, PrintWriter stream) 713 { 714 write (0, " ", "value", entry, stream); 715 } 716 read(int index, String indent, String name, SymtabEntry entry, PrintWriter stream)717 public int read (int index, String indent, String name, 718 SymtabEntry entry, PrintWriter stream) 719 { 720 UnionEntry u = (UnionEntry)entry; 721 String disName = "_dis" + index++; 722 SymtabEntry utype = Util.typeOf (u.type ()); 723 Util.writeInitializer (indent, disName, "", utype, stream); 724 725 if (utype instanceof PrimitiveEntry) 726 index = ((JavaGenerator)utype.generator ()).read (index, indent, disName, utype, stream); 727 else 728 stream.println (indent + disName + " = " + Util.helperName (utype, true) + ".read (istream);"); 729 730 if (utype.name ().equals ("boolean")) 731 index = readBoolean (disName, index, indent, name, u, stream); 732 else 733 index = readNonBoolean (disName, index, indent, name, u, stream); 734 735 return index; 736 } 737 readBoolean(String disName, int index, String indent, String name, UnionEntry u, PrintWriter stream)738 private int readBoolean (String disName, int index, String indent, 739 String name, UnionEntry u, PrintWriter stream) 740 { 741 UnionBranch firstBranch = (UnionBranch)u.branches ().firstElement (); 742 UnionBranch secondBranch; 743 744 if (u.branches ().size () == 2) 745 secondBranch = (UnionBranch)u.branches ().lastElement (); 746 else 747 secondBranch = null; 748 749 boolean firstBranchIsTrue = false; 750 boolean noCases = false; 751 try { 752 if (u.branches ().size () == 1 && 753 (u.defaultBranch () != null || firstBranch.labels.size () == 2)) { 754 noCases = true; 755 } else { 756 Expression expr = (Expression)(firstBranch.labels.firstElement()) ; 757 Boolean bool = (Boolean)(expr.evaluate()) ; 758 firstBranchIsTrue = bool.booleanValue (); 759 } 760 } catch (EvaluationException ex) { 761 // no action 762 } 763 764 if (noCases) { 765 // There is only a default label. Since there are no cases, 766 // there is no need for if...else branches. 767 index = readBranch (index, indent, firstBranch.typedef.name (), "", firstBranch.typedef, stream); 768 } else { 769 // If first branch is false, swap branches 770 if (!firstBranchIsTrue) { 771 UnionBranch tmp = firstBranch; 772 firstBranch = secondBranch; 773 secondBranch = tmp; 774 } 775 776 stream.println (indent + "if (" + disName + ')'); 777 778 if (firstBranch == null) 779 stream.println (indent + " value._default(" + disName + ");"); 780 else { 781 stream.println (indent + '{'); 782 index = readBranch (index, indent + " ", firstBranch.typedef.name (), 783 disName, firstBranch.typedef, stream); 784 stream.println (indent + '}'); 785 } 786 787 stream.println (indent + "else"); 788 789 if (secondBranch == null) 790 stream.println (indent + " value._default(" + disName + ");"); 791 else { 792 stream.println (indent + '{'); 793 index = readBranch (index, indent + " ", secondBranch.typedef.name (), 794 disName, secondBranch.typedef, stream); 795 stream.println (indent + '}'); 796 } 797 } 798 799 return index; 800 } 801 readNonBoolean(String disName, int index, String indent, String name, UnionEntry u, PrintWriter stream)802 private int readNonBoolean (String disName, int index, String indent, 803 String name, UnionEntry u, PrintWriter stream) 804 { 805 SymtabEntry utype = Util.typeOf (u.type ()); 806 807 if (utype instanceof EnumEntry) 808 stream.println (indent + "switch (" + disName + ".value ())"); 809 else 810 stream.println (indent + "switch (" + disName + ')'); 811 812 stream.println (indent + '{'); 813 String typePackage = Util.javaQualifiedName (utype) + '.'; 814 815 Enumeration e = u.branches ().elements (); 816 while (e.hasMoreElements ()) { 817 UnionBranch branch = (UnionBranch)e.nextElement (); 818 Enumeration labels = branch.labels.elements (); 819 820 while (labels.hasMoreElements ()) { 821 Expression label = (Expression)labels.nextElement (); 822 823 if (utype instanceof EnumEntry) { 824 String key = Util.parseExpression (label); 825 stream.println (indent + " case " + typePackage + '_' + key + ':'); 826 } else 827 stream.println (indent + " case " + cast (label, utype) + ':'); 828 } 829 830 if (!branch.typedef.equals (u.defaultBranch ())) { 831 index = readBranch (index, indent + " ", branch.typedef.name (), 832 branch.labels.size() > 1 ? disName : "" , 833 branch.typedef, stream); 834 stream.println (indent + " break;"); 835 } 836 } 837 838 // We need a default branch unless all of the case of the discriminator type 839 // are listed in the case branches. 840 if (!coversAll(u)) { 841 stream.println( indent + " default:") ; 842 843 if (u.defaultBranch () == null) { 844 // If the union does not have a default branch, we still need to initialize 845 // the discriminator. 846 stream.println( indent + " value._default( " + disName + " ) ;" ) ; 847 } else { 848 index = readBranch (index, indent + " ", u.defaultBranch ().name (), disName, 849 u.defaultBranch (), stream); 850 } 851 852 stream.println (indent + " break;"); 853 } 854 855 stream.println (indent + '}'); 856 857 return index; 858 } 859 readBranch(int index, String indent, String name, String disName, TypedefEntry entry, PrintWriter stream)860 private int readBranch (int index, String indent, String name, String disName, TypedefEntry entry, PrintWriter stream) 861 { 862 SymtabEntry type = entry.type (); 863 Util.writeInitializer (indent, '_' + name, "", entry, stream); 864 865 if (!entry.arrayInfo ().isEmpty () || 866 type instanceof SequenceEntry || 867 type instanceof PrimitiveEntry || 868 type instanceof StringEntry) { 869 index = ((JavaGenerator)entry.generator ()).read (index, indent, '_' + name, entry, stream); 870 } else { 871 stream.println (indent + '_' + name + " = " + Util.helperName (type, true) + ".read (istream);"); 872 } 873 874 stream.print (indent + "value." + name + " ("); 875 if( disName == "" ) 876 stream.println("_" + name + ");"); 877 else 878 stream.println(disName + ", " + "_" + name + ");"); 879 880 return index; 881 } 882 883 /** 884 * 885 **/ write(int index, String indent, String name, SymtabEntry entry, PrintWriter stream)886 public int write (int index, String indent, String name, SymtabEntry entry, PrintWriter stream) 887 { 888 UnionEntry u = (UnionEntry)entry; 889 SymtabEntry utype = Util.typeOf (u.type ()); 890 if (utype instanceof PrimitiveEntry) 891 index = ((JavaGenerator)utype.generator ()).write (index, indent, name + ".discriminator ()", utype, stream); 892 else 893 stream.println (indent + Util.helperName (utype, true) + ".write (ostream, " + name + ".discriminator ());"); // <d61056> 894 if (utype.name ().equals ("boolean")) 895 index = writeBoolean (name + ".discriminator ()", index, indent, name, u, stream); 896 else 897 index = writeNonBoolean (name + ".discriminator ()", index, indent, name, u, stream); 898 return index; 899 } // write 900 901 /** 902 * 903 **/ writeBoolean(String disName, int index, String indent, String name, UnionEntry u, PrintWriter stream)904 private int writeBoolean (String disName, int index, String indent, String name, UnionEntry u, PrintWriter stream) 905 { 906 SymtabEntry utype = Util.typeOf (u.type ()); 907 UnionBranch firstBranch = (UnionBranch)u.branches ().firstElement (); 908 UnionBranch secondBranch; 909 if (u.branches ().size () == 2) 910 secondBranch = (UnionBranch)u.branches ().lastElement (); 911 else 912 secondBranch = null; 913 boolean firstBranchIsTrue = false; 914 boolean noCases = false; 915 try 916 { 917 if (u.branches ().size () == 1 && (u.defaultBranch () != null || firstBranch.labels.size () == 2)) 918 noCases = true; 919 else 920 firstBranchIsTrue = ((Boolean)((Expression)firstBranch.labels.firstElement ()).evaluate ()).booleanValue (); 921 } 922 catch (EvaluationException ex) 923 {} 924 925 if (noCases) 926 { 927 // There is only a default label. Since there are no cases, 928 // there is no need for if...else branches. 929 index = writeBranch (index, indent, name, firstBranch.typedef, stream); 930 } 931 else 932 { 933 // If first branch is false, swap branches 934 if (!firstBranchIsTrue) 935 { 936 UnionBranch tmp = firstBranch; 937 firstBranch = secondBranch; 938 secondBranch = tmp; 939 } 940 if (firstBranch != null && secondBranch != null) { 941 stream.println (indent + "if (" + disName + ')'); 942 stream.println (indent + '{'); 943 index = writeBranch (index, indent + " ", name, firstBranch.typedef, stream); 944 stream.println (indent + '}'); 945 stream.println (indent + "else"); 946 stream.println (indent + '{'); 947 index = writeBranch (index, indent + " ", name, secondBranch.typedef, stream); 948 stream.println (indent + '}'); 949 } else if (firstBranch != null) { 950 stream.println (indent + "if (" + disName + ')'); 951 stream.println (indent + '{'); 952 index = writeBranch (index, indent + " ", name, firstBranch.typedef, stream); 953 stream.println (indent + '}'); 954 } else { 955 stream.println (indent + "if (!" + disName + ')'); 956 stream.println (indent + '{'); 957 index = writeBranch (index, indent + " ", name, secondBranch.typedef, stream); 958 stream.println (indent + '}'); 959 } 960 } 961 return index; 962 } // writeBoolean 963 964 /** 965 * 966 **/ writeNonBoolean(String disName, int index, String indent, String name, UnionEntry u, PrintWriter stream)967 private int writeNonBoolean (String disName, int index, String indent, String name, UnionEntry u, PrintWriter stream) 968 { 969 SymtabEntry utype = Util.typeOf (u.type ()); 970 if (utype instanceof EnumEntry) 971 stream.println (indent + "switch (" + name + ".discriminator ().value ())"); 972 else 973 stream.println (indent + "switch (" + name + ".discriminator ())"); 974 stream.println (indent + "{"); 975 String typePackage = Util.javaQualifiedName (utype) + '.'; 976 Enumeration e = u.branches ().elements (); 977 while (e.hasMoreElements ()) 978 { 979 UnionBranch branch = (UnionBranch)e.nextElement (); 980 Enumeration labels = branch.labels.elements (); 981 while (labels.hasMoreElements ()) 982 { 983 Expression label = (Expression)labels.nextElement (); 984 if (utype instanceof EnumEntry) 985 { 986 String key = Util.parseExpression (label); 987 stream.println (indent + " case " + typePackage + '_' + key + ":"); 988 } 989 else 990 stream.println (indent + " case " + cast (label, utype) + ':'); 991 } 992 if (!branch.typedef.equals (u.defaultBranch ())) 993 { 994 index = writeBranch (index, indent + " ", name, branch.typedef, stream); 995 stream.println (indent + " break;"); 996 } 997 } 998 if (u.defaultBranch () != null) { 999 stream.println (indent + " default:"); 1000 index = writeBranch (index, indent + " ", name, u.defaultBranch (), stream); 1001 stream.println (indent + " break;"); 1002 } 1003 stream.println (indent + "}"); 1004 return index; 1005 } // writeNonBoolean 1006 1007 /** 1008 * 1009 **/ writeBranch(int index, String indent, String name, TypedefEntry entry, PrintWriter stream)1010 private int writeBranch (int index, String indent, String name, TypedefEntry entry, PrintWriter stream) 1011 { 1012 SymtabEntry type = entry.type (); 1013 if (!entry.arrayInfo ().isEmpty () || type instanceof SequenceEntry || type instanceof PrimitiveEntry || type instanceof StringEntry) 1014 index = ((JavaGenerator)entry.generator ()).write (index, indent, name + '.' + entry.name () + " ()", entry, stream); 1015 else 1016 stream.println (indent + Util.helperName (type, true) + ".write (ostream, " + name + '.' + entry.name () + " ());"); // <d61056> 1017 return index; 1018 } // writeBranch 1019 1020 // From JavaGenerator 1021 /////////////// 1022 1023 /** 1024 * 1025 **/ cast(Expression expr, SymtabEntry type)1026 private String cast (Expression expr, SymtabEntry type) 1027 { 1028 String ret = Util.parseExpression (expr); 1029 if (type.name ().indexOf ("short") >= 0) 1030 { 1031 if (expr.value () instanceof Long) 1032 { 1033 long value = ((Long)expr.value ()).longValue (); 1034 if (value > Short.MAX_VALUE) 1035 ret = "(short)(" + ret + ')'; 1036 } 1037 else if (expr.value () instanceof Integer) 1038 { 1039 int value = ((Integer)expr.value ()).intValue (); 1040 if (value > Short.MAX_VALUE) 1041 ret = "(short)(" + ret + ')'; 1042 } 1043 } 1044 else if (type.name ().indexOf ("long") >= 0) 1045 { 1046 if (expr.value () instanceof Long) 1047 { 1048 long value = ((Long)expr.value ()).longValue (); 1049 // value == Integer.MIN_VALUE because if the number is 1050 // Integer.MIN_VALUE, then it will have the 'L' suffix and 1051 // the cast will be necessary. 1052 if (value > Integer.MAX_VALUE || value == Integer.MIN_VALUE) 1053 ret = "(int)(" + ret + ')'; 1054 } 1055 else if (expr.value () instanceof Integer) 1056 { 1057 int value = ((Integer)expr.value ()).intValue (); 1058 // value == Integer.MIN_VALUE because if the number is 1059 // Integer.MIN_VALUE, then it will have the 'L' suffix and 1060 // the cast will be necessary. 1061 if (value > Integer.MAX_VALUE || value == Integer.MIN_VALUE) 1062 ret = "(int)(" + ret + ')'; 1063 } 1064 } 1065 return ret; 1066 } // cast 1067 1068 protected Hashtable symbolTable = null; 1069 protected UnionEntry u = null; 1070 protected PrintWriter stream = null; 1071 protected SymtabEntry utype = null; 1072 protected boolean unionIsEnum; 1073 protected String typePackage = ""; 1074 } // class UnionGen 1075