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 // -F46082.51<daz> Remove -stateful feature; javaStatefulName() obsolete.
  40 // -D61056   <klr> Use Util.helperName
  41 
  42 import java.io.PrintWriter;
  43 import java.util.Hashtable;
  44 
  45 import com.sun.tools.corba.se.idl.InterfaceEntry;
  46 import com.sun.tools.corba.se.idl.PrimitiveEntry;
  47 import com.sun.tools.corba.se.idl.SequenceEntry;
  48 import com.sun.tools.corba.se.idl.StringEntry;
  49 import com.sun.tools.corba.se.idl.SymtabEntry;
  50 
  51 import com.sun.tools.corba.se.idl.constExpr.Expression;
  52 
  53 /**
  54  *
  55  **/
  56 public class SequenceGen implements com.sun.tools.corba.se.idl.SequenceGen, JavaGenerator
  57 {
  58   /**
  59    * Public zero-argument constructor.
  60    **/
  61   public SequenceGen ()
  62   {
  63   } // ctor
  64 
  65   /**
  66    *
  67    **/
  68   public void generate (Hashtable symbolTable, SequenceEntry s, PrintWriter stream)
  69   {
  70   } // generator
  71 
  72   ///////////////
  73   // From JavaGenerator
  74 
  75   public int helperType (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream)
  76   {
  77     int offsetOfType = tcoffsets.offset (entry.type ().fullName ());
  78     if (offsetOfType >= 0)
  79     {
  80       // This code uses the deprecated create_recursive_sequence_tc()
  81       // It should be eliminated when the API is removed from the ORB class
  82       // Regardles, this code will not be emitted since updated emitters invoke
  83       // method type() below instead of helperType() when handling sequences
  84 
  85       // This is a recursive sequence
  86       tcoffsets.set (null);
  87       Expression maxSize = ((SequenceEntry)entry).maxSize ();
  88       if (maxSize == null)
  89         stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_recursive_sequence_tc (0, " + (offsetOfType - tcoffsets.currentOffset ()) + ");");
  90       else
  91         stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_recursive_sequence_tc (" + Util.parseExpression (maxSize) + ", " + (offsetOfType - tcoffsets.currentOffset ()) + ");");
  92       tcoffsets.bumpCurrentOffset (4); // add indirection field
  93     }
  94     else
  95     {
  96       // This is a normal sequence
  97       tcoffsets.set (entry);
  98       index = ((JavaGenerator)entry.type ().generator ()).helperType (index + 1, indent, tcoffsets, name, entry.type (), stream);
  99       Expression maxSize = ((SequenceEntry)entry).maxSize ();
 100       if (maxSize == null)
 101         stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_sequence_tc (0, " + name + ");");
 102       else
 103         stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_sequence_tc (" + Util.parseExpression (maxSize) + ", " + name + ");");
 104     }
 105     tcoffsets.bumpCurrentOffset (4); // add on the seq max size
 106     return index;
 107   } // helperType
 108 
 109   public int type (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream) {
 110     int offsetOfType = tcoffsets.offset (entry.type ().fullName ());
 111     if (offsetOfType >= 0)
 112     {
 113       // This is a recursive sequence
 114       tcoffsets.set (null);
 115 
 116       // Need to fix later: how to get repositoryId of IDL type containing this sequence?
 117       // entry.repositoryID().ID() returns empty string and
 118       // Util.javaQualifiedName(entry) returns internal name which is not valid repId
 119 
 120       stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_recursive_tc (" + "\"\"" + ");");
 121       tcoffsets.bumpCurrentOffset (4); // add indirection field
 122     }
 123     else
 124     {
 125       // This is a normal sequence
 126       tcoffsets.set (entry);
 127       index = ((JavaGenerator)entry.type ().generator ()).type (index + 1, indent, tcoffsets, name, entry.type (), stream);
 128       Expression maxSize = ((SequenceEntry)entry).maxSize ();
 129       if (maxSize == null)
 130         stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_sequence_tc (0, " + name + ");");
 131       else
 132         stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_sequence_tc (" + Util.parseExpression (maxSize) + ", " + name + ");");
 133     }
 134     //stream.println (indent + name + " = " + Util.helperName (entry, true) + ".type ();"); // <d61056>
 135     return index;
 136   } // type
 137 
 138   public void helperRead (String entryName, SymtabEntry entry, PrintWriter stream)
 139   {
 140   } // helperRead
 141 
 142   public void helperWrite (SymtabEntry entry, PrintWriter stream)
 143   {
 144   } // helperWrite
 145 
 146   public int read (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
 147   {
 148     SequenceEntry seq = (SequenceEntry)entry;
 149     String length = "_len" + index++;
 150     stream.println (indent + "int " + length + " = istream.read_long ();");
 151     if (seq.maxSize () != null)
 152     {
 153       stream.println (indent + "if (" + length + " > (" + Util.parseExpression (seq.maxSize ()) + "))");
 154       stream.println (indent + "  throw new org.omg.CORBA.MARSHAL (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);");
 155     }
 156     String seqOfName;
 157     try
 158     {
 159       seqOfName = Util.sansArrayInfo ((String)seq.dynamicVariable (Compile.typedefInfo));
 160     }
 161     catch (NoSuchFieldException e)
 162     {
 163       seqOfName = seq.name ();
 164     }
 165     int startArray = seqOfName.indexOf ('[');
 166     String arrayDcl = seqOfName.substring (startArray);
 167     seqOfName = seqOfName.substring (0, startArray);
 168 
 169     // For interfaces having state, e.g., valuetypes.
 170     SymtabEntry seqOfEntry = (SymtabEntry)Util.symbolTable.get (seqOfName.replace ('.', '/'));
 171     if (seqOfEntry != null && seqOfEntry instanceof InterfaceEntry && ((InterfaceEntry)seqOfEntry).state () != null)
 172       // <f46082.51> Remove -stateful feature; javaStatefulName() obsolete.
 173       //seqOfName = Util.javaStatefulName ((InterfaceEntry)seqOfEntry);
 174       seqOfName = Util.javaName ((InterfaceEntry)seqOfEntry);
 175 
 176     arrayDcl = arrayDcl.substring (2);
 177     stream.println (indent + name + " = new " + seqOfName + '[' + length + ']' + arrayDcl + ';');
 178     if (seq.type () instanceof PrimitiveEntry)
 179       // <d61961> Check for CORBA::Principal, too
 180       //if (seq.type ().name ().equals ("any") || seq.type ().name ().equals ("TypeCode"))
 181       if (seq.type ().name ().equals ("any") ||
 182           seq.type ().name ().equals ("TypeCode") ||
 183           seq.type ().name ().equals ("Principal"))
 184       {
 185         String loopIndex = "_o" + index;
 186         stream.println (indent + "for (int " + loopIndex + " = 0;" + loopIndex + " < " + name + ".length; ++" + loopIndex + ')');
 187         stream.println (indent + "  " + name + '[' + loopIndex + "] = istream.read_" + seq.type ().name () + " ();");
 188       }
 189       else
 190       { // special case for ValueBox: if name is "xxx tmp", drop xxx
 191         String varName = name;
 192         int nameIndex = varName.indexOf (' ');
 193         if ( nameIndex != -1 )
 194           varName = varName.substring( nameIndex + 1 );
 195         stream.println (indent + "istream.read_" + Util.collapseName (entry.type ().name ()) + "_array (" + varName + ", 0, " + length + ");");
 196       }
 197     else if (entry.type () instanceof StringEntry)
 198     {
 199       String loopIndex = "_o" + index;
 200       stream.println (indent + "for (int " + loopIndex + " = 0;" + loopIndex + " < " + name + ".length; ++" + loopIndex + ')');
 201       stream.println (indent + "  " + name + '[' + loopIndex + "] = istream.read_" + seq.type ().name () + " ();");
 202     }
 203     else if (entry.type () instanceof SequenceEntry)
 204     {
 205       String loopIndex = "_o" + index;
 206       stream.println (indent + "for (int " + loopIndex + " = 0;" + loopIndex + " < " + name + ".length; ++" + loopIndex + ')');
 207       stream.println (indent + '{');
 208       index = ((JavaGenerator)seq.type ().generator ()).read (index, indent + "  ", name + '[' + loopIndex + ']', seq.type (), stream);
 209       stream.println (indent + '}');
 210     }
 211     else
 212     { // special case for ValueBox: if name is "xxx tmp", drop xxx
 213       String varName = name;
 214       int nameIndex = varName.indexOf (' ');
 215       if ( nameIndex != -1 )
 216         varName = varName.substring( nameIndex + 1 );
 217       String loopIndex = "_o" + index;
 218       stream.println (indent + "for (int " + loopIndex + " = 0;" + loopIndex + " < " + varName + ".length; ++" + loopIndex + ')');
 219       stream.println (indent + "  " + varName + '[' + loopIndex + "] = " + Util.helperName (seq.type (), true) + ".read (istream);"); // <d61056>
 220     }
 221     return index;
 222   } // read
 223 
 224   public int write (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
 225   {
 226     SequenceEntry seq = (SequenceEntry)entry;
 227     if (seq.maxSize () != null)
 228     {
 229       stream.println (indent + "if (" + name + ".length > (" + Util.parseExpression (seq.maxSize ()) + "))");
 230       stream.println (indent + "  throw new org.omg.CORBA.MARSHAL (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);");
 231     }
 232     stream.println (indent + "ostream.write_long (" + name + ".length);");
 233     if (entry.type () instanceof PrimitiveEntry)
 234       // <d61961> Check for CORBA::Principal, too.
 235       //if (entry.type ().name ().equals ("any") || entry.type ().name ().equals ("TypeCode"))
 236       if (entry.type ().name ().equals ("any") ||
 237           entry.type ().name ().equals ("TypeCode") ||
 238           entry.type ().name ().equals ("Principal"))
 239       {
 240         String loopIndex = "_i" + index++;
 241         stream.println (indent + "for (int " + loopIndex + " = 0;" + loopIndex + " < " + name + ".length; ++" + loopIndex + ')');
 242         stream.println (indent + "  ostream.write_" + seq.type ().name () + " (" + name + '[' + loopIndex + "]);");
 243       }
 244       else
 245         stream.println (indent + "ostream.write_" + Util.collapseName (entry.type ().name ()) + "_array (" + name + ", 0, " + name + ".length);");
 246     else if (entry.type () instanceof StringEntry)
 247     {
 248       String loopIndex = "_i" + index++;
 249       stream.println (indent + "for (int " + loopIndex + " = 0;" + loopIndex + " < " + name + ".length; ++" + loopIndex + ')');
 250       stream.println (indent + "  ostream.write_" + seq.type ().name () + " (" + name + '[' + loopIndex + "]);");
 251     }
 252     else if (entry.type () instanceof SequenceEntry)
 253     {
 254       String loopIndex = "_i" + index++;
 255       stream.println (indent + "for (int " + loopIndex + " = 0;" + loopIndex + " < " + name + ".length; ++" + loopIndex + ')');
 256       stream.println (indent + '{');
 257       index = ((JavaGenerator)seq.type ().generator ()).write (index, indent + "  ", name + '[' + loopIndex + ']', seq.type (), stream);
 258       stream.println (indent + '}');
 259     }
 260     else
 261     {
 262       String loopIndex = "_i" + index++;
 263       stream.println (indent + "for (int " + loopIndex + " = 0;" + loopIndex + " < " + name + ".length; ++" + loopIndex + ')');
 264       stream.println (indent + "  " + Util.helperName (seq.type (), true) + ".write (ostream, " + name + '[' + loopIndex + "]);"); // <d61056>
 265     }
 266     return index;
 267   } // write
 268 
 269   // From JavaGenerator
 270   ///////////////
 271 } // class SequenceGen