alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (UnionGen.java)

This example Java source code file (UnionGen.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

enumentry, enumeration, expression, primitiveentry, printwriter, sequenceentry, string, symtabentry, tcoffsets, typedefentry, unionbranch, unionentry, uniongen, util, vector

The UnionGen.java Java example source code

/*
 * 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

Other Java examples (source code examples)

Here is a short list of links related to this Java UnionGen.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.