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 **/ 75 public UnionGen () 76 { 77 } // ctor 78 79 /** 80 * 81 **/ 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 **/ 103 protected void init () 104 { 105 utype = Util.typeOf (u.type ()); 106 unionIsEnum = utype instanceof EnumEntry; 107 } // init 108 109 /** 110 * 111 **/ 112 protected void openStream () 113 { 114 stream = Util.stream (u, ".java"); 115 } // openStream 116 117 /** 118 * 119 **/ 120 protected void generateHelper () 121 { 122 ((Factories)Compile.compiler.factories ()).helper ().generate (symbolTable, u); 123 } // generateHelper 124 125 /** 126 * 127 **/ 128 protected void generateHolder () 129 { 130 ((Factories)Compile.compiler.factories ()).holder ().generate (symbolTable, u); 131 } // generateHolder 132 133 /** 134 * 135 **/ 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 **/ 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 **/ 225 protected void writeClosing () 226 { 227 stream.println ("} // class " + u.name ()); 228 } // writeClosing 229 230 /** 231 * 232 **/ 233 protected void closeStream () 234 { 235 stream.close (); 236 } // closeStream 237 238 /** 239 * 240 **/ 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 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 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 **/ 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 **/ 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 **/ 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 **/ 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. 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 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 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 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 712 public void helperWrite (SymtabEntry entry, PrintWriter stream) 713 { 714 write (0, " ", "value", entry, stream); 715 } 716 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 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 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 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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