| /* |
| * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| /* |
| * COMPONENT_NAME: idl.toJava |
| * |
| * ORIGINS: 27 |
| * |
| * Licensed Materials - Property of IBM |
| * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999 |
| * RMI-IIOP v1.0 |
| * |
| */ |
| |
| package com.sun.tools.corba.se.idl.toJavaPortable; |
| |
| // NOTES: |
| // -cast() does not support longlong types yet. |
| // -Deal with typedef changes. |
| // -Scoped names for the discriminator are ignored at the moment. |
| // -F46082.51<daz> Remove -stateful feature; javaStatefulName() obsolete. |
| // -D61056 <klr> Use Util.helperName |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.util.Enumeration; |
| import java.util.Hashtable; |
| import java.util.Vector; |
| |
| import com.sun.tools.corba.se.idl.GenFileStream; |
| import com.sun.tools.corba.se.idl.ConstEntry; |
| import com.sun.tools.corba.se.idl.EnumEntry; |
| import com.sun.tools.corba.se.idl.InterfaceEntry; |
| import com.sun.tools.corba.se.idl.PrimitiveEntry; |
| import com.sun.tools.corba.se.idl.SequenceEntry; |
| import com.sun.tools.corba.se.idl.StringEntry; |
| import com.sun.tools.corba.se.idl.SymtabEntry; |
| import com.sun.tools.corba.se.idl.TypedefEntry; |
| import com.sun.tools.corba.se.idl.UnionBranch; |
| import com.sun.tools.corba.se.idl.UnionEntry; |
| |
| import com.sun.tools.corba.se.idl.constExpr.Expression; |
| import com.sun.tools.corba.se.idl.constExpr.EvaluationException; |
| |
| /** |
| * |
| **/ |
| public class UnionGen implements com.sun.tools.corba.se.idl.UnionGen, JavaGenerator |
| { |
| /** |
| * Public zero-argument constructor. |
| **/ |
| public UnionGen () |
| { |
| } // ctor |
| |
| /** |
| * |
| **/ |
| public void generate (Hashtable symbolTable, UnionEntry u, PrintWriter s) |
| { |
| this.symbolTable = symbolTable; |
| this.u = u; |
| init (); |
| |
| openStream (); |
| if (stream == null) |
| return; |
| generateHelper (); |
| generateHolder (); |
| writeHeading (); |
| writeBody (); |
| writeClosing (); |
| closeStream (); |
| generateContainedTypes (); |
| } // generate |
| |
| /** |
| * Initialize members unique to this generator. |
| **/ |
| protected void init () |
| { |
| utype = Util.typeOf (u.type ()); |
| unionIsEnum = utype instanceof EnumEntry; |
| } // init |
| |
| /** |
| * |
| **/ |
| protected void openStream () |
| { |
| stream = Util.stream (u, ".java"); |
| } // openStream |
| |
| /** |
| * |
| **/ |
| protected void generateHelper () |
| { |
| ((Factories)Compile.compiler.factories ()).helper ().generate (symbolTable, u); |
| } // generateHelper |
| |
| /** |
| * |
| **/ |
| protected void generateHolder () |
| { |
| ((Factories)Compile.compiler.factories ()).holder ().generate (symbolTable, u); |
| } // generateHolder |
| |
| /** |
| * |
| **/ |
| protected void writeHeading () |
| { |
| // If the discriminator is an enum, assign the typePackage string. |
| if (unionIsEnum) |
| typePackage = Util.javaQualifiedName (utype) + '.'; |
| else |
| typePackage = ""; |
| |
| Util.writePackage (stream, u); |
| Util.writeProlog (stream, ((GenFileStream)stream).name ()); |
| |
| String className = u.name (); |
| stream.println ("public final class " + u.name () + " implements org.omg.CORBA.portable.IDLEntity"); |
| stream.println ("{"); |
| } // writeHeading |
| |
| /** |
| * |
| **/ |
| protected void writeBody () |
| { |
| // Write branches and populate quality arrays |
| int size = u.branches ().size () + 1; |
| Enumeration e = u.branches ().elements (); |
| int i = 0; |
| while (e.hasMoreElements ()) |
| { |
| UnionBranch branch = (UnionBranch)e.nextElement (); |
| Util.fillInfo (branch.typedef); |
| // <f46082.51> Remove -stateful feature; javaStatefulName() obsolete. |
| //stream.println (" private " + Util.javaStatefulName (branch.typedef) + " ___" + branch.typedef.name () + ";"); |
| stream.println (" private " + Util.javaName (branch.typedef) + " ___" + branch.typedef.name () + ";"); |
| ++i; |
| } |
| stream.println (" private " + Util.javaName (utype) + " __discriminator;"); |
| stream.println (" private boolean __uninitialized = true;"); |
| |
| // Write ctor |
| stream.println (); |
| stream.println (" public " + u.name () + " ()"); |
| stream.println (" {"); |
| stream.println (" }"); |
| |
| // Write discriminator |
| stream.println (); |
| stream.println (" public " + Util.javaName (utype) + " " + safeName (u, "discriminator") + " ()"); |
| stream.println (" {"); |
| stream.println (" if (__uninitialized)"); |
| stream.println (" throw new org.omg.CORBA.BAD_OPERATION ();"); |
| stream.println (" return __discriminator;"); |
| stream.println (" }"); |
| |
| // Write for each branch: |
| // - setter |
| // - getter |
| // - private verifyXXX |
| e = u.branches ().elements (); |
| i = 0; |
| while (e.hasMoreElements ()) |
| { |
| UnionBranch branch = (UnionBranch)e.nextElement (); |
| writeBranchMethods (stream, u, branch, i++); |
| } |
| if (u.defaultBranch () == null && !coversAll (u)) |
| { |
| stream.println (); |
| stream.println (" public void _default ()"); |
| stream.println (" {"); |
| stream.println (" __discriminator = " + defaultDiscriminator (u) + ';'); |
| stream.println (" __uninitialized = false;"); |
| stream.println (" }"); |
| |
| stream.println (); |
| stream.println (" public void _default (" + Util.javaName(utype) + |
| " discriminator)"); |
| stream.println (" {"); |
| stream.println (" verifyDefault( discriminator ) ;" ); |
| stream.println (" __discriminator = discriminator ;"); |
| stream.println (" __uninitialized = false;"); |
| stream.println (" }"); |
| |
| writeVerifyDefault() ; |
| } |
| stream.println (); |
| } // writeBody |
| |
| /** |
| * |
| **/ |
| protected void writeClosing () |
| { |
| stream.println ("} // class " + u.name ()); |
| } // writeClosing |
| |
| /** |
| * |
| **/ |
| protected void closeStream () |
| { |
| stream.close (); |
| } // closeStream |
| |
| /** |
| * |
| **/ |
| protected void generateContainedTypes () |
| { |
| Enumeration e = u.contained ().elements (); |
| while (e.hasMoreElements ()) |
| { |
| SymtabEntry entry = (SymtabEntry)e.nextElement (); |
| |
| // Don't generate contained entries if they are sequences. |
| // Sequences are unnamed and since they translate to arrays, |
| // no classes are generated for them, not even holders in this |
| // case since they cannot be accessed outside of this union. |
| if (!(entry instanceof SequenceEntry)) |
| entry.generate (symbolTable, stream); |
| } |
| } // generateContainedTypes |
| |
| private void writeVerifyDefault() |
| { |
| Vector labels = vectorizeLabels (u.branches (), true); |
| |
| if (Util.javaName(utype).equals ("boolean")) { |
| stream.println( "" ) ; |
| stream.println( " private void verifyDefault (boolean discriminator)" ) ; |
| stream.println( " {" ) ; |
| if (labels.contains ("true")) |
| stream.println (" if ( discriminator )"); |
| else |
| stream.println (" if ( !discriminator )"); |
| stream.println( " throw new org.omg.CORBA.BAD_OPERATION();" ) ; |
| stream.println( " }" ) ; |
| return; |
| } |
| |
| stream.println( "" ) ; |
| stream.println( " private void verifyDefault( " + Util.javaName(utype) + |
| " value )" ) ; |
| stream.println( " {" ) ; |
| |
| if (unionIsEnum) |
| stream.println( " switch (value.value()) {" ) ; |
| else |
| stream.println( " switch (value) {" ) ; |
| |
| Enumeration e = labels.elements() ; |
| while (e.hasMoreElements()) { |
| String str = (String)(e.nextElement()) ; |
| stream.println( " case " + str + ":" ) ; |
| } |
| |
| stream.println( " throw new org.omg.CORBA.BAD_OPERATION() ;" ) ; |
| stream.println( "" ) ; |
| stream.println( " default:" ) ; |
| stream.println( " return;" ) ; |
| stream.println( " }" ) ; |
| stream.println( " }" ) ; |
| } |
| |
| private String defaultDiscriminator (UnionEntry u) |
| { |
| Vector labels = vectorizeLabels (u.branches (), false ); |
| String ret = null; |
| SymtabEntry utype = Util.typeOf (u.type ()); |
| if (utype instanceof PrimitiveEntry && utype.name ().equals ("boolean")) { |
| // If it got this far, then: |
| // - there is only one branch; |
| // - that branch has only one label. |
| if (labels.contains ("true")) |
| ret = "false"; |
| else |
| ret = "true"; |
| } else if (utype.name ().equals ("char")) { |
| // This doesn't handle '\u0030' == '0'. Unions are so |
| // seldom used. I don't have time to make this perfect. |
| int def = 0; |
| String string = "'\\u0000'"; |
| while (def != 0xFFFF && labels.contains (string)) |
| if (++def / 0x10 == 0) |
| string = "'\\u000" + def + "'"; |
| else if (def / 0x100 == 0) |
| string = "\\u00" + def + "'"; |
| else if (def / 0x1000 == 0) |
| string = "\\u0" + def + "'"; |
| else |
| string = "\\u" + def + "'"; |
| ret = string; |
| } else if (utype instanceof EnumEntry) { |
| Enumeration e = labels.elements (); |
| EnumEntry enumEntry = (EnumEntry)utype; |
| Vector enumList = (Vector)enumEntry.elements ().clone (); |
| // cull out those elements in the enumeration list that are |
| // in the cases of this union |
| while (e.hasMoreElements ()) |
| enumList.removeElement (e.nextElement ()); |
| // If all of the enum elements are covered in this union and |
| // there is a default statement, just pick one of the |
| // elements for the default. If there are enum elements |
| // which are NOT covered by the cases, pick one as the |
| // default. |
| if (enumList.size () == 0) |
| ret = typePackage + (String)enumEntry.elements ().lastElement (); |
| else |
| ret = typePackage + (String)enumList.firstElement (); |
| } else if (utype.name ().equals ("octet")) { |
| short def = Byte.MIN_VALUE; |
| while (def != Byte.MAX_VALUE && labels.contains (Integer.toString (def))) |
| ++def; |
| ret = Integer.toString (def); |
| } else if (utype.name ().equals ("short")) { |
| short def = Short.MIN_VALUE; |
| while (def != Short.MAX_VALUE && labels.contains (Integer.toString (def))) |
| ++def; |
| ret = Integer.toString (def); |
| } else if (utype.name ().equals ("long")) { |
| int def = Integer.MIN_VALUE; |
| while (def != Integer.MAX_VALUE && labels.contains (Integer.toString (def))) |
| ++def; |
| ret = Integer.toString (def); |
| } else if (utype.name ().equals ("long long")) { |
| long def = Long.MIN_VALUE; |
| while (def != Long.MAX_VALUE && labels.contains (Long.toString (def))) |
| ++def; |
| ret = Long.toString (def); |
| } else if (utype.name ().equals ("unsigned short")) { |
| short def = 0; |
| while (def != Short.MAX_VALUE && labels.contains (Integer.toString (def))) |
| ++def; |
| ret = Integer.toString (def); |
| } else if (utype.name ().equals ("unsigned long")) { |
| int def = 0; |
| while (def != Integer.MAX_VALUE && labels.contains (Integer.toString (def))) |
| ++def; |
| ret = Integer.toString (def); |
| } else if (utype.name ().equals ("unsigned long long")) { |
| long def = 0; |
| while (def != Long.MAX_VALUE && labels.contains (Long.toString (def))) |
| ++def; |
| ret = Long.toString (def); |
| } |
| |
| return ret; |
| } // defaultDiscriminator |
| |
| /** |
| * |
| **/ |
| private Vector vectorizeLabels (Vector branchVector, boolean useIntsForEnums ) |
| { |
| Vector mergedLabels = new Vector (); |
| Enumeration branches = branchVector.elements (); |
| while (branches.hasMoreElements ()) |
| { |
| UnionBranch branch = (UnionBranch)branches.nextElement (); |
| Enumeration labels = branch.labels.elements (); |
| while (labels.hasMoreElements ()) |
| { |
| Expression expr = (Expression)labels.nextElement (); |
| String str ; |
| |
| if (unionIsEnum) |
| if (useIntsForEnums) |
| str = typePackage + "_" + Util.parseExpression( expr ) ; |
| else |
| str = typePackage + Util.parseExpression( expr ) ; |
| else |
| str = Util.parseExpression( expr ) ; |
| |
| mergedLabels.addElement (str); |
| } |
| } |
| return mergedLabels; |
| } // vectorizeLabels |
| |
| /** |
| * |
| **/ |
| private String safeName (UnionEntry u, String name) |
| { |
| Enumeration e = u.branches ().elements (); |
| while (e.hasMoreElements ()) |
| if (((UnionBranch)e.nextElement ()).typedef.name ().equals (name)) |
| { |
| name = '_' + name; |
| break; |
| } |
| return name; |
| } // safeName |
| |
| /** |
| * |
| **/ |
| private boolean coversAll (UnionEntry u) |
| { |
| // This assumes that it is not possible to cover types other than |
| // boolean and enums. This is not quite correct, but since octet |
| // is not a valid discriminator type, it's not too bad in practice. |
| // It may also be possible to cover a char type, but we won't worry |
| // about that either. |
| SymtabEntry utype = Util.typeOf (u.type ()); |
| |
| boolean coversAll = false; |
| if (utype.name ().equals ("boolean")) { |
| if (u.branches ().size () == 2) |
| coversAll = true; |
| } else if (utype instanceof EnumEntry) { |
| Vector labels = vectorizeLabels (u.branches (), true); |
| if (labels.size () == ((EnumEntry)utype).elements ().size ()) |
| coversAll = true; |
| } |
| |
| return coversAll; |
| } // coversAll |
| |
| /** |
| * |
| **/ |
| private void writeBranchMethods (PrintWriter stream, UnionEntry u, UnionBranch branch, int i) |
| { |
| // Write getter |
| stream.println (); |
| // <f46082.51> Remove -stateful feature; javaStatefulName() obsolete. |
| //stream.println (" public " + Util.javaStatefulName (branch.typedef) + " " + branch.typedef.name () + " ()"); |
| stream.println (" public " + Util.javaName (branch.typedef) + " " + branch.typedef.name () + " ()"); |
| stream.println (" {"); |
| stream.println (" if (__uninitialized)"); |
| stream.println (" throw new org.omg.CORBA.BAD_OPERATION ();"); |
| stream.println (" verify" + branch.typedef.name () + " (__discriminator);"); |
| stream.println (" return ___" + branch.typedef.name () + ";"); |
| stream.println (" }"); |
| |
| // Write setter(s) |
| stream.println (); |
| // <f46082.51> Remove -stateful feature; javaStatefulName() obsolete. |
| //stream.println (" public void " + branch.typedef.name () + " (" + Util.javaStatefulName (branch.typedef) + " value)"); |
| stream.println (" public void " + branch.typedef.name () + " (" + Util.javaName (branch.typedef) + " value)"); |
| stream.println (" {"); |
| if (branch.labels.size () == 0) |
| { |
| // This is a default branch |
| stream.println (" __discriminator = " + defaultDiscriminator (u) + ";"); |
| } |
| else |
| { |
| // This is a non-default branch |
| if (unionIsEnum) |
| stream.println (" __discriminator = " + typePackage + Util.parseExpression ((Expression)branch.labels.firstElement ()) + ";"); |
| else |
| stream.println (" __discriminator = " + cast ((Expression)branch.labels.firstElement (), u.type ()) + ";"); |
| } |
| stream.println (" ___" + branch.typedef.name () + " = value;"); |
| stream.println (" __uninitialized = false;"); |
| stream.println (" }"); |
| |
| SymtabEntry utype = Util.typeOf (u.type ()); |
| |
| // If there are multiple labels for one branch, write the |
| // setter that takes a discriminator. |
| if (branch.labels.size () > 0 || branch.isDefault) |
| { |
| stream.println (); |
| // <f46082.51> Remove -stateful feature; javaStatefulName() obsolete. |
| //stream.println (" public void " + branch.typedef.name () + " (" + Util.javaName (utype) + " discriminator, " + Util.javaStatefulName (branch.typedef) + " value)"); |
| stream.println (" public void " + branch.typedef.name () + " (" + Util.javaName (utype) + " discriminator, " + Util.javaName (branch.typedef) + " value)"); |
| stream.println (" {"); |
| stream.println (" verify" + branch.typedef.name () + " (discriminator);"); |
| stream.println (" __discriminator = discriminator;"); |
| stream.println (" ___" + branch.typedef.name () + " = value;"); |
| stream.println (" __uninitialized = false;"); |
| stream.println (" }"); |
| } |
| |
| // Write verifyXXX |
| stream.println (); |
| stream.println (" private void verify" + branch.typedef.name () + " (" + Util.javaName (utype) + " discriminator)"); |
| stream.println (" {"); |
| |
| boolean onlyOne = true; |
| |
| if (branch.isDefault && u.branches ().size () == 1) |
| ;// If all that is in this union is a default branch, |
| // all discriminators are legal. Don't print any |
| // body to this method in that case. |
| else |
| { |
| // Otherwise this code is executed and a body is printed. |
| stream.print (" if ("); |
| if (branch.isDefault) |
| { |
| Enumeration eBranches = u.branches ().elements (); |
| while (eBranches.hasMoreElements ()) |
| { |
| UnionBranch b = (UnionBranch)eBranches.nextElement (); |
| if (b != branch) |
| { |
| Enumeration eLabels = b.labels.elements (); |
| while (eLabels.hasMoreElements ()) |
| { |
| Expression label = (Expression)eLabels.nextElement (); |
| if (!onlyOne) |
| stream.print (" || "); |
| if (unionIsEnum) |
| stream.print ("discriminator == " + typePackage + Util.parseExpression (label)); |
| else |
| stream.print ("discriminator == " + Util.parseExpression (label)); |
| onlyOne = false; |
| } |
| } |
| } |
| } |
| else |
| { |
| Enumeration e = branch.labels.elements (); |
| while (e.hasMoreElements ()) |
| { |
| Expression label = (Expression)e.nextElement (); |
| if (!onlyOne) |
| stream.print (" && "); |
| if (unionIsEnum) |
| stream.print ("discriminator != " + typePackage + Util.parseExpression (label)); |
| else |
| stream.print ("discriminator != " + Util.parseExpression (label)); |
| onlyOne = false; |
| } |
| } |
| stream.println (")"); |
| stream.println (" throw new org.omg.CORBA.BAD_OPERATION ();"); |
| } |
| stream.println (" }"); |
| } // writeBranchMethods |
| |
| /////////////// |
| // From JavaGenerator |
| |
| /** |
| * |
| **/ |
| |
| // Computes the total number of labels in the union, which is the sum |
| // of the number of labels in each branch of the union. Note that the |
| // label for the default branch has size 0, but still counts in the total |
| // size. |
| private int unionLabelSize( UnionEntry un ) |
| { |
| int size = 0 ; |
| Vector branches = un.branches() ; |
| for (int i = 0; i < branches.size (); ++i) { |
| UnionBranch branch = (UnionBranch)(branches.get(i)) ; |
| int branchSize = branch.labels.size() ; |
| size += ((branchSize == 0) ? 1 : branchSize) ; |
| } |
| return size ; |
| } |
| |
| public int helperType (int index, String indent, TCOffsets tcoffsets, |
| String name, SymtabEntry entry, PrintWriter stream) |
| { |
| TCOffsets innerOffsets = new TCOffsets (); |
| UnionEntry u = (UnionEntry)entry; |
| String discTypeCode = "_disTypeCode" + index; |
| String membersName = "_members" + index; |
| |
| // Build discriminator tc |
| stream.println (indent + "org.omg.CORBA.TypeCode " + discTypeCode + ';'); |
| index = ((JavaGenerator)u.type ().generator ()).type (index + 1, indent, |
| innerOffsets, discTypeCode, u.type (), stream); |
| tcoffsets.bumpCurrentOffset (innerOffsets.currentOffset ()); |
| |
| stream.println (indent + "org.omg.CORBA.UnionMember[] " + membersName + |
| " = new org.omg.CORBA.UnionMember [" + unionLabelSize(u) + "];"); |
| String tcOfMembers = "_tcOf" + membersName; |
| String anyOfMembers = "_anyOf" + membersName; |
| stream.println (indent + "org.omg.CORBA.TypeCode " + tcOfMembers + ';'); |
| stream.println (indent + "org.omg.CORBA.Any " + anyOfMembers + ';'); |
| |
| innerOffsets = new TCOffsets (); |
| innerOffsets.set (entry); |
| int offsetForUnion = innerOffsets.currentOffset (); |
| for (int i = 0; i < u.branches ().size (); ++i) { |
| UnionBranch branch = (UnionBranch)u.branches ().elementAt (i); |
| TypedefEntry member = branch.typedef; |
| Vector labels = branch.labels; |
| String memberName = Util.stripLeadingUnderscores (member.name ()); |
| |
| if (labels.size() == 0) { |
| stream.println (); |
| stream.println (indent + "// Branch for " + memberName + |
| " (Default case)" ); |
| SymtabEntry utype = Util.typeOf (u.type ()); |
| stream.println (indent + anyOfMembers + " = org.omg.CORBA.ORB.init ().create_any ();"); |
| // For default member, label is the zero octet (per CORBA spec.) |
| stream.println (indent + anyOfMembers + ".insert_octet ((byte)0); // default member label"); |
| |
| // Build typecode |
| innerOffsets.bumpCurrentOffset (4); // label value |
| index = ((JavaGenerator)member.generator ()).type (index, indent, innerOffsets, tcOfMembers, member, stream); |
| int offsetSoFar = innerOffsets.currentOffset (); |
| innerOffsets = new TCOffsets (); |
| innerOffsets.set (entry); |
| innerOffsets.bumpCurrentOffset (offsetSoFar - offsetForUnion); |
| |
| // Build union member |
| stream.println (indent + membersName + '[' + i + "] = new org.omg.CORBA.UnionMember ("); |
| stream.println (indent + " \"" + memberName + "\","); |
| stream.println (indent + " " + anyOfMembers + ','); |
| stream.println (indent + " " + tcOfMembers + ','); |
| stream.println (indent + " null);"); |
| } else { |
| Enumeration enumeration = labels.elements() ; |
| while (enumeration.hasMoreElements()) { |
| Expression expr = (Expression)(enumeration.nextElement()) ; |
| String elem = Util.parseExpression( expr ) ; |
| |
| stream.println (); |
| stream.println (indent + "// Branch for " + memberName + |
| " (case label " + elem + ")" ); |
| |
| SymtabEntry utype = Util.typeOf (u.type ()); |
| |
| // Build any |
| stream.println (indent + anyOfMembers + " = org.omg.CORBA.ORB.init ().create_any ();"); |
| |
| if (utype instanceof PrimitiveEntry) |
| stream.println (indent + anyOfMembers + ".insert_" + |
| Util.collapseName (utype.name ()) + " ((" + Util.javaName (utype) + |
| ')' + elem + ");"); |
| else { // it must be enum |
| String enumClass = Util.javaName (utype); |
| stream.println (indent + Util.helperName (utype, false) + ".insert (" + |
| anyOfMembers + ", " + enumClass + '.' + elem + ");"); // <d61056> |
| } |
| |
| // Build typecode |
| innerOffsets.bumpCurrentOffset (4); // label value |
| index = ((JavaGenerator)member.generator ()).type (index, indent, innerOffsets, tcOfMembers, member, stream); |
| int offsetSoFar = innerOffsets.currentOffset (); |
| innerOffsets = new TCOffsets (); |
| innerOffsets.set (entry); |
| innerOffsets.bumpCurrentOffset (offsetSoFar - offsetForUnion); |
| |
| // Build union member |
| stream.println (indent + membersName + '[' + i + "] = new org.omg.CORBA.UnionMember ("); |
| stream.println (indent + " \"" + memberName + "\","); |
| stream.println (indent + " " + anyOfMembers + ','); |
| stream.println (indent + " " + tcOfMembers + ','); |
| stream.println (indent + " null);"); |
| } |
| } |
| } |
| |
| tcoffsets.bumpCurrentOffset (innerOffsets.currentOffset ()); |
| |
| // Build create_union_tc |
| stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_union_tc (" + |
| Util.helperName (u, true) + ".id (), \"" + entry.name () + "\", " + |
| discTypeCode + ", " + membersName + ");"); |
| return index; |
| } // helperType |
| |
| public int type (int index, String indent, TCOffsets tcoffsets, String name, |
| SymtabEntry entry, PrintWriter stream) |
| { |
| stream.println (indent + name + " = " + Util.helperName (entry, true) + ".type ();"); |
| return index; |
| } |
| |
| public void helperRead (String entryName, SymtabEntry entry, PrintWriter stream) |
| { |
| stream.println (" " + entryName + " value = new " + entryName + " ();"); |
| read (0, " ", "value", entry, stream); |
| stream.println (" return value;"); |
| } |
| |
| public void helperWrite (SymtabEntry entry, PrintWriter stream) |
| { |
| write (0, " ", "value", entry, stream); |
| } |
| |
| public int read (int index, String indent, String name, |
| SymtabEntry entry, PrintWriter stream) |
| { |
| UnionEntry u = (UnionEntry)entry; |
| String disName = "_dis" + index++; |
| SymtabEntry utype = Util.typeOf (u.type ()); |
| Util.writeInitializer (indent, disName, "", utype, stream); |
| |
| if (utype instanceof PrimitiveEntry) |
| index = ((JavaGenerator)utype.generator ()).read (index, indent, disName, utype, stream); |
| else |
| stream.println (indent + disName + " = " + Util.helperName (utype, true) + ".read (istream);"); |
| |
| if (utype.name ().equals ("boolean")) |
| index = readBoolean (disName, index, indent, name, u, stream); |
| else |
| index = readNonBoolean (disName, index, indent, name, u, stream); |
| |
| return index; |
| } |
| |
| private int readBoolean (String disName, int index, String indent, |
| String name, UnionEntry u, PrintWriter stream) |
| { |
| UnionBranch firstBranch = (UnionBranch)u.branches ().firstElement (); |
| UnionBranch secondBranch; |
| |
| if (u.branches ().size () == 2) |
| secondBranch = (UnionBranch)u.branches ().lastElement (); |
| else |
| secondBranch = null; |
| |
| boolean firstBranchIsTrue = false; |
| boolean noCases = false; |
| try { |
| if (u.branches ().size () == 1 && |
| (u.defaultBranch () != null || firstBranch.labels.size () == 2)) { |
| noCases = true; |
| } else { |
| Expression expr = (Expression)(firstBranch.labels.firstElement()) ; |
| Boolean bool = (Boolean)(expr.evaluate()) ; |
| firstBranchIsTrue = bool.booleanValue (); |
| } |
| } catch (EvaluationException ex) { |
| // no action |
| } |
| |
| if (noCases) { |
| // There is only a default label. Since there are no cases, |
| // there is no need for if...else branches. |
| index = readBranch (index, indent, firstBranch.typedef.name (), "", firstBranch.typedef, stream); |
| } else { |
| // If first branch is false, swap branches |
| if (!firstBranchIsTrue) { |
| UnionBranch tmp = firstBranch; |
| firstBranch = secondBranch; |
| secondBranch = tmp; |
| } |
| |
| stream.println (indent + "if (" + disName + ')'); |
| |
| if (firstBranch == null) |
| stream.println (indent + " value._default(" + disName + ");"); |
| else { |
| stream.println (indent + '{'); |
| index = readBranch (index, indent + " ", firstBranch.typedef.name (), |
| disName, firstBranch.typedef, stream); |
| stream.println (indent + '}'); |
| } |
| |
| stream.println (indent + "else"); |
| |
| if (secondBranch == null) |
| stream.println (indent + " value._default(" + disName + ");"); |
| else { |
| stream.println (indent + '{'); |
| index = readBranch (index, indent + " ", secondBranch.typedef.name (), |
| disName, secondBranch.typedef, stream); |
| stream.println (indent + '}'); |
| } |
| } |
| |
| return index; |
| } |
| |
| private int readNonBoolean (String disName, int index, String indent, |
| String name, UnionEntry u, PrintWriter stream) |
| { |
| SymtabEntry utype = Util.typeOf (u.type ()); |
| |
| if (utype instanceof EnumEntry) |
| stream.println (indent + "switch (" + disName + ".value ())"); |
| else |
| stream.println (indent + "switch (" + disName + ')'); |
| |
| stream.println (indent + '{'); |
| String typePackage = Util.javaQualifiedName (utype) + '.'; |
| |
| Enumeration e = u.branches ().elements (); |
| while (e.hasMoreElements ()) { |
| UnionBranch branch = (UnionBranch)e.nextElement (); |
| Enumeration labels = branch.labels.elements (); |
| |
| while (labels.hasMoreElements ()) { |
| Expression label = (Expression)labels.nextElement (); |
| |
| if (utype instanceof EnumEntry) { |
| String key = Util.parseExpression (label); |
| stream.println (indent + " case " + typePackage + '_' + key + ':'); |
| } else |
| stream.println (indent + " case " + cast (label, utype) + ':'); |
| } |
| |
| if (!branch.typedef.equals (u.defaultBranch ())) { |
| index = readBranch (index, indent + " ", branch.typedef.name (), |
| branch.labels.size() > 1 ? disName : "" , |
| branch.typedef, stream); |
| stream.println (indent + " break;"); |
| } |
| } |
| |
| // We need a default branch unless all of the case of the discriminator type |
| // are listed in the case branches. |
| if (!coversAll(u)) { |
| stream.println( indent + " default:") ; |
| |
| if (u.defaultBranch () == null) { |
| // If the union does not have a default branch, we still need to initialize |
| // the discriminator. |
| stream.println( indent + " value._default( " + disName + " ) ;" ) ; |
| } else { |
| index = readBranch (index, indent + " ", u.defaultBranch ().name (), disName, |
| u.defaultBranch (), stream); |
| } |
| |
| stream.println (indent + " break;"); |
| } |
| |
| stream.println (indent + '}'); |
| |
| return index; |
| } |
| |
| private int readBranch (int index, String indent, String name, String disName, TypedefEntry entry, PrintWriter stream) |
| { |
| SymtabEntry type = entry.type (); |
| Util.writeInitializer (indent, '_' + name, "", entry, stream); |
| |
| if (!entry.arrayInfo ().isEmpty () || |
| type instanceof SequenceEntry || |
| type instanceof PrimitiveEntry || |
| type instanceof StringEntry) { |
| index = ((JavaGenerator)entry.generator ()).read (index, indent, '_' + name, entry, stream); |
| } else { |
| stream.println (indent + '_' + name + " = " + Util.helperName (type, true) + ".read (istream);"); |
| } |
| |
| stream.print (indent + "value." + name + " ("); |
| if( disName == "" ) |
| stream.println("_" + name + ");"); |
| else |
| stream.println(disName + ", " + "_" + name + ");"); |
| |
| return index; |
| } |
| |
| /** |
| * |
| **/ |
| public int write (int index, String indent, String name, SymtabEntry entry, PrintWriter stream) |
| { |
| UnionEntry u = (UnionEntry)entry; |
| SymtabEntry utype = Util.typeOf (u.type ()); |
| if (utype instanceof PrimitiveEntry) |
| index = ((JavaGenerator)utype.generator ()).write (index, indent, name + ".discriminator ()", utype, stream); |
| else |
| stream.println (indent + Util.helperName (utype, true) + ".write (ostream, " + name + ".discriminator ());"); // <d61056> |
| if (utype.name ().equals ("boolean")) |
| index = writeBoolean (name + ".discriminator ()", index, indent, name, u, stream); |
| else |
| index = writeNonBoolean (name + ".discriminator ()", index, indent, name, u, stream); |
| return index; |
| } // write |
| |
| /** |
| * |
| **/ |
| private int writeBoolean (String disName, int index, String indent, String name, UnionEntry u, PrintWriter stream) |
| { |
| SymtabEntry utype = Util.typeOf (u.type ()); |
| UnionBranch firstBranch = (UnionBranch)u.branches ().firstElement (); |
| UnionBranch secondBranch; |
| if (u.branches ().size () == 2) |
| secondBranch = (UnionBranch)u.branches ().lastElement (); |
| else |
| secondBranch = null; |
| boolean firstBranchIsTrue = false; |
| boolean noCases = false; |
| try |
| { |
| if (u.branches ().size () == 1 && (u.defaultBranch () != null || firstBranch.labels.size () == 2)) |
| noCases = true; |
| else |
| firstBranchIsTrue = ((Boolean)((Expression)firstBranch.labels.firstElement ()).evaluate ()).booleanValue (); |
| } |
| catch (EvaluationException ex) |
| {} |
| |
| if (noCases) |
| { |
| // There is only a default label. Since there are no cases, |
| // there is no need for if...else branches. |
| index = writeBranch (index, indent, name, firstBranch.typedef, stream); |
| } |
| else |
| { |
| // If first branch is false, swap branches |
| if (!firstBranchIsTrue) |
| { |
| UnionBranch tmp = firstBranch; |
| firstBranch = secondBranch; |
| secondBranch = tmp; |
| } |
| if (firstBranch != null && secondBranch != null) { |
| stream.println (indent + "if (" + disName + ')'); |
| stream.println (indent + '{'); |
| index = writeBranch (index, indent + " ", name, firstBranch.typedef, stream); |
| stream.println (indent + '}'); |
| stream.println (indent + "else"); |
| stream.println (indent + '{'); |
| index = writeBranch (index, indent + " ", name, secondBranch.typedef, stream); |
| stream.println (indent + '}'); |
| } else if (firstBranch != null) { |
| stream.println (indent + "if (" + disName + ')'); |
| stream.println (indent + '{'); |
| index = writeBranch (index, indent + " ", name, firstBranch.typedef, stream); |
| stream.println (indent + '}'); |
| } else { |
| stream.println (indent + "if (!" + disName + ')'); |
| stream.println (indent + '{'); |
| index = writeBranch (index, indent + " ", name, secondBranch.typedef, stream); |
| stream.println (indent + '}'); |
| } |
| } |
| return index; |
| } // writeBoolean |
| |
| /** |
| * |
| **/ |
| private int writeNonBoolean (String disName, int index, String indent, String name, UnionEntry u, PrintWriter stream) |
| { |
| SymtabEntry utype = Util.typeOf (u.type ()); |
| if (utype instanceof EnumEntry) |
| stream.println (indent + "switch (" + name + ".discriminator ().value ())"); |
| else |
| stream.println (indent + "switch (" + name + ".discriminator ())"); |
| stream.println (indent + "{"); |
| String typePackage = Util.javaQualifiedName (utype) + '.'; |
| Enumeration e = u.branches ().elements (); |
| while (e.hasMoreElements ()) |
| { |
| UnionBranch branch = (UnionBranch)e.nextElement (); |
| Enumeration labels = branch.labels.elements (); |
| while (labels.hasMoreElements ()) |
| { |
| Expression label = (Expression)labels.nextElement (); |
| if (utype instanceof EnumEntry) |
| { |
| String key = Util.parseExpression (label); |
| stream.println (indent + " case " + typePackage + '_' + key + ":"); |
| } |
| else |
| stream.println (indent + " case " + cast (label, utype) + ':'); |
| } |
| if (!branch.typedef.equals (u.defaultBranch ())) |
| { |
| index = writeBranch (index, indent + " ", name, branch.typedef, stream); |
| stream.println (indent + " break;"); |
| } |
| } |
| if (u.defaultBranch () != null) { |
| stream.println (indent + " default:"); |
| index = writeBranch (index, indent + " ", name, u.defaultBranch (), stream); |
| stream.println (indent + " break;"); |
| } |
| stream.println (indent + "}"); |
| return index; |
| } // writeNonBoolean |
| |
| /** |
| * |
| **/ |
| private int writeBranch (int index, String indent, String name, TypedefEntry entry, PrintWriter stream) |
| { |
| SymtabEntry type = entry.type (); |
| if (!entry.arrayInfo ().isEmpty () || type instanceof SequenceEntry || type instanceof PrimitiveEntry || type instanceof StringEntry) |
| index = ((JavaGenerator)entry.generator ()).write (index, indent, name + '.' + entry.name () + " ()", entry, stream); |
| else |
| stream.println (indent + Util.helperName (type, true) + ".write (ostream, " + name + '.' + entry.name () + " ());"); // <d61056> |
| return index; |
| } // writeBranch |
| |
| // From JavaGenerator |
| /////////////// |
| |
| /** |
| * |
| **/ |
| private String cast (Expression expr, SymtabEntry type) |
| { |
| String ret = Util.parseExpression (expr); |
| if (type.name ().indexOf ("short") >= 0) |
| { |
| if (expr.value () instanceof Long) |
| { |
| long value = ((Long)expr.value ()).longValue (); |
| if (value > Short.MAX_VALUE) |
| ret = "(short)(" + ret + ')'; |
| } |
| else if (expr.value () instanceof Integer) |
| { |
| int value = ((Integer)expr.value ()).intValue (); |
| if (value > Short.MAX_VALUE) |
| ret = "(short)(" + ret + ')'; |
| } |
| } |
| else if (type.name ().indexOf ("long") >= 0) |
| { |
| if (expr.value () instanceof Long) |
| { |
| long value = ((Long)expr.value ()).longValue (); |
| // value == Integer.MIN_VALUE because if the number is |
| // Integer.MIN_VALUE, then it will have the 'L' suffix and |
| // the cast will be necessary. |
| if (value > Integer.MAX_VALUE || value == Integer.MIN_VALUE) |
| ret = "(int)(" + ret + ')'; |
| } |
| else if (expr.value () instanceof Integer) |
| { |
| int value = ((Integer)expr.value ()).intValue (); |
| // value == Integer.MIN_VALUE because if the number is |
| // Integer.MIN_VALUE, then it will have the 'L' suffix and |
| // the cast will be necessary. |
| if (value > Integer.MAX_VALUE || value == Integer.MIN_VALUE) |
| ret = "(int)(" + ret + ')'; |
| } |
| } |
| return ret; |
| } // cast |
| |
| protected Hashtable symbolTable = null; |
| protected UnionEntry u = null; |
| protected PrintWriter stream = null; |
| protected SymtabEntry utype = null; |
| protected boolean unionIsEnum; |
| protected String typePackage = ""; |
| } // class UnionGen |