1 /*
   2  * Copyright (c) 1999, 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 // -11aug1997<daz> No modification: comments for type_defs will appear in
  40 //  helper, holder classes as a result of modifications to routines
  41 //  makeHelper(), makeHolder() in class com.sun.tools.corba.se.idl.toJava.Util.
  42 // -F46082.51<daz> Remove -stateful feature; javaStatefulName() obsolete.
  43 // -D61056   <klr> Use Util.helperName
  44 
  45 import java.io.PrintWriter;
  46 
  47 import java.util.Enumeration;
  48 import java.util.Hashtable;
  49 
  50 import com.sun.tools.corba.se.idl.InterfaceEntry;
  51 import com.sun.tools.corba.se.idl.InterfaceState;
  52 import com.sun.tools.corba.se.idl.PrimitiveEntry;
  53 import com.sun.tools.corba.se.idl.SequenceEntry;
  54 import com.sun.tools.corba.se.idl.StringEntry;
  55 import com.sun.tools.corba.se.idl.StructEntry;
  56 import com.sun.tools.corba.se.idl.SymtabEntry;
  57 import com.sun.tools.corba.se.idl.TypedefEntry;
  58 import com.sun.tools.corba.se.idl.UnionEntry;
  59 
  60 import com.sun.tools.corba.se.idl.constExpr.Expression;
  61 
  62 // Notes:
  63 
  64 /**
  65  *
  66  **/
  67 public class TypedefGen implements com.sun.tools.corba.se.idl.TypedefGen, JavaGenerator
  68 {
  69   /**
  70    * Public zero-argument constructor.
  71    **/
  72   public TypedefGen ()
  73   {
  74   } // ctor
  75 
  76   /**
  77    *
  78    **/
  79   public void generate (Hashtable symbolTable, TypedefEntry t, PrintWriter stream)
  80   {
  81     this.symbolTable = symbolTable;
  82     this.t           = t;
  83 
  84     if (t.arrayInfo ().size () > 0 || t.type () instanceof SequenceEntry)
  85       generateHolder ();
  86     generateHelper ();
  87   } // generator
  88 
  89   /**
  90    *
  91    **/
  92   protected void generateHolder ()
  93   {
  94     ((Factories)Compile.compiler.factories ()).holder ().generate (symbolTable, t);
  95   }
  96 
  97   /**
  98    *
  99    **/
 100   protected void generateHelper ()
 101   {
 102     ((Factories)Compile.compiler.factories ()).helper ().generate (symbolTable, t);
 103   }
 104 
 105   ///////////////
 106   // From JavaGenerator
 107 
 108   private boolean inStruct (TypedefEntry entry)
 109   {
 110     boolean inStruct = false;
 111     if (entry.container () instanceof StructEntry || entry.container () instanceof UnionEntry)
 112       inStruct = true;
 113     else if (entry.container () instanceof InterfaceEntry)
 114     {
 115       InterfaceEntry i = (InterfaceEntry)entry.container ();
 116       if (i.state () != null)
 117       {
 118         Enumeration e = i.state ().elements ();
 119         while (e.hasMoreElements ())
 120           if (((InterfaceState)e.nextElement ()).entry == entry)
 121           {
 122             inStruct = true;
 123             break;
 124           }
 125       }
 126     }
 127     return inStruct;
 128   } // inStruct
 129 
 130   public int helperType (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream)
 131   {
 132     TypedefEntry td = (TypedefEntry)entry;
 133     boolean inStruct = inStruct (td);
 134     if (inStruct)
 135       tcoffsets.setMember (entry);
 136     else
 137       tcoffsets.set (entry);
 138 
 139     // Print the base types typecode
 140     index = ((JavaGenerator)td.type ().generator ()).type (index, indent, tcoffsets, name, td.type (), stream);
 141 
 142     if (inStruct && td.arrayInfo ().size () != 0)
 143       tcoffsets.bumpCurrentOffset (4); // for array length field
 144 
 145     // Print the array typecodes (if there are any)
 146     int dimensions = td.arrayInfo ().size ();
 147     for (int i = 0; i < dimensions; ++i)
 148     {
 149       String size = Util.parseExpression ((Expression)td.arrayInfo ().elementAt (i));
 150       stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_array_tc (" + size + ", " + name + " );");
 151     }
 152 
 153     // If this typedef describes a struct/union member, don't put it
 154     // in an alias typedef; otherwise that's where it belongs.
 155     if (!inStruct)
 156       // <54697>
 157       //stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_alias_tc (id (), \"" + Util.stripLeadingUnderscores (td.name ()) + "\", " + name + ");");
 158       stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_alias_tc (" + Util.helperName (td, true) + ".id (), \"" + Util.stripLeadingUnderscores (td.name ()) + "\", " + name + ");"); // <d61056>
 159 
 160     return index;
 161   } // helperType
 162 
 163   public int type (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream)
 164   {
 165     // The type() method is invoked from other emitters instead of when an IDL
 166     // typedef statement is being processed.  Code generated is identical minus the
 167     // generation of a create_alias_tc() which is required for IDL typedef's but not
 168     // needed when typedef is being processed as a member of struct/union/valuetype.
 169 
 170     return helperType( index, indent, tcoffsets, name, entry, stream);
 171   } // type
 172 
 173   public void helperRead (String entryName, SymtabEntry entry, PrintWriter stream)
 174   {
 175     Util.writeInitializer ("    ", "value", "", entry, stream);
 176     read (0, "    ", "value", entry, stream);
 177     stream.println ("    return value;");
 178   } // helperRead
 179 
 180   public void helperWrite (SymtabEntry entry, PrintWriter stream)
 181   {
 182     write (0, "    ", "value", entry, stream);
 183   } // helperWrite
 184 
 185   public int read (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
 186   {
 187     TypedefEntry td = (TypedefEntry)entry;
 188     String modifier = Util.arrayInfo (td.arrayInfo ());
 189     if (!modifier.equals (""))
 190     {
 191       // arrayInfo is a vector of Expressions which indicate the
 192       // number of array dimensions for this typedef.  But what if
 193       // this is a typedef of a sequence?
 194       // The `new' statement being generated must know the full
 195       // number of brackets.  That can be found in td.info.
 196       // For instance:
 197       // typedef sequence<short> A[10][10];
 198       // void proc (out A a);
 199       // typeModifier = "[10][10]"
 200       // td.info    = "short[][][]";
 201       // The first new statement generated is:
 202       // a.value = new short[10][][];
 203       // Note that the 3 sets of brackets come from td.info, not
 204       // arrayInfo;
 205       // The second new statement generated is:
 206       // a.value[_i1] = new short[10][];
 207       // ------------     ---- ------
 208       //    \           \    \
 209       //    name      baseName   arrayDcl
 210       int closingBrackets = 0;
 211       String loopIndex = "";
 212       String baseName;
 213       try
 214       {
 215         baseName = (String)td.dynamicVariable (Compile.typedefInfo);
 216       }
 217       catch (NoSuchFieldException e)
 218       {
 219         baseName = td.name ();
 220       }
 221       int startArray = baseName.indexOf ('[');
 222       String arrayDcl = Util.sansArrayInfo (baseName.substring (startArray)) + "[]"; // Add an extra set because the first gets stripped off in the loop.
 223       baseName = baseName.substring (0, startArray);
 224 
 225       // For interfaces having state, e.g., valuetypes.
 226       SymtabEntry baseEntry = (SymtabEntry)Util.symbolTable.get (baseName.replace ('.', '/'));
 227       if (baseEntry instanceof InterfaceEntry && ((InterfaceEntry)baseEntry).state () != null)
 228         // <f46082.51> Remove -stateful feature; javaStatefulName() obsolete.
 229         //baseName = Util.javaStatefulName ((InterfaceEntry)baseEntry);
 230         baseName = Util.javaName ((InterfaceEntry)baseEntry);
 231 
 232       int end1stArray;
 233       while (!modifier.equals (""))
 234       {
 235         int rbracket = modifier.indexOf (']');
 236         String size = modifier.substring (1, rbracket);
 237         end1stArray = arrayDcl.indexOf (']');
 238         arrayDcl = '[' + size + arrayDcl.substring (end1stArray + 2);
 239         stream.println (indent + name + " = new " + baseName + arrayDcl + ';');
 240         loopIndex = "_o" + index++;
 241         stream.println (indent + "for (int " + loopIndex + " = 0;" + loopIndex + " < (" + size + "); ++" + loopIndex + ')');
 242         stream.println (indent + '{');
 243         ++closingBrackets;
 244         modifier = modifier.substring (rbracket + 1);
 245         indent = indent + "  ";
 246         name = name + '[' + loopIndex + ']';
 247       }
 248       end1stArray = arrayDcl.indexOf (']');
 249       if (td.type () instanceof SequenceEntry || td.type () instanceof PrimitiveEntry || td.type () instanceof StringEntry)
 250         index = ((JavaGenerator)td.type ().generator ()).read (index, indent, name, td.type (), stream);
 251       else if (td.type () instanceof InterfaceEntry && td.type ().fullName ().equals ("org/omg/CORBA/Object"))
 252         stream.println (indent + name + " = istream.read_Object ();");
 253       else
 254         stream.println (indent + name + " = " + Util.helperName (td.type (), true) + ".read (istream);"); // <d61056>
 255       for (int i = 0; i < closingBrackets; ++i)
 256       {
 257         indent = indent.substring (2);
 258         stream.println (indent + '}');
 259       }
 260     }
 261     else
 262     {
 263       SymtabEntry tdtype = Util.typeOf (td.type ());
 264       if (tdtype instanceof SequenceEntry || tdtype instanceof PrimitiveEntry || tdtype instanceof StringEntry)
 265         index = ((JavaGenerator)tdtype.generator ()).read (index, indent, name, tdtype, stream);
 266       else if (tdtype instanceof InterfaceEntry && tdtype.fullName ().equals ("org/omg/CORBA/Object"))
 267         stream.println (indent + name + " = istream.read_Object ();");
 268       else
 269         stream.println (indent + name + " = " + Util.helperName (tdtype, true) + ".read (istream);"); // <d61056>
 270     }
 271     return index;
 272   } // read
 273 
 274   public int write (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
 275   {
 276     TypedefEntry td = (TypedefEntry)entry;
 277     String modifier = Util.arrayInfo (td.arrayInfo ());
 278     if (!modifier.equals (""))
 279     {
 280       int closingBrackets = 0;
 281       String loopIndex = "";
 282       while (!modifier.equals (""))
 283       {
 284         int rbracket = modifier.indexOf (']');
 285         String size = modifier.substring (1, rbracket);
 286         stream.println (indent + "if (" + name + ".length != (" + size + "))");
 287         stream.println (indent + "  throw new org.omg.CORBA.MARSHAL (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);");
 288         loopIndex = "_i" + index++;
 289         stream.println (indent + "for (int " + loopIndex + " = 0;" + loopIndex + " < (" + size + "); ++" + loopIndex + ')');
 290         stream.println (indent + '{');
 291         ++closingBrackets;
 292         modifier = modifier.substring (rbracket + 1);
 293         indent = indent + "  ";
 294         name = name + '[' + loopIndex + ']';
 295       }
 296       if (td.type () instanceof SequenceEntry || td.type () instanceof PrimitiveEntry || td.type () instanceof StringEntry)
 297         index = ((JavaGenerator)td.type ().generator ()).write (index, indent, name, td.type (), stream);
 298       else if (td.type () instanceof InterfaceEntry && td.type ().fullName ().equals ("org/omg/CORBA/Object"))
 299         stream.println (indent + "ostream.write_Object (" + name + ");");
 300       else
 301         stream.println (indent + Util.helperName (td.type (), true) + ".write (ostream, " + name + ");"); // <d61056>
 302       for (int i = 0; i < closingBrackets; ++i)
 303       {
 304         indent = indent.substring (2);
 305         stream.println (indent + '}');
 306       }
 307     }
 308     else
 309     {
 310       SymtabEntry tdtype = Util.typeOf (td.type ());
 311       if (tdtype instanceof SequenceEntry || tdtype instanceof PrimitiveEntry || tdtype instanceof StringEntry)
 312         index = ((JavaGenerator)tdtype.generator ()).write (index, indent, name, tdtype, stream);
 313       else if (tdtype instanceof InterfaceEntry && tdtype.fullName ().equals ("org/omg/CORBA/Object"))
 314         stream.println (indent + "ostream.write_Object (" + name + ");");
 315       else
 316         stream.println (indent + Util.helperName (tdtype, true) + ".write (ostream, " + name + ");"); // <d61056>
 317     }
 318     return index;
 319   } // write
 320 
 321   // From JavaGenerator
 322   ////////////////
 323 
 324   protected Hashtable     symbolTable = null;
 325   protected TypedefEntry  t           = null;
 326 } // class TypedefGen