1 /*
   2  * Copyright (c) 1999, 2004, 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.
  40 // -D57118   <klr> Fix "narrow" in helper for abstract interface
  41 // -D58889   <klr> re-Fix "narrow" in helper for abstract interface
  42 // -D59383   <klr> 'get_class' in value helper returns value class, not helper.
  43 // -D59413   <klr> Remove Helper interface references for non-value types.
  44 // -D59435   <klr> Remove read_Object, write_Object completely.
  45 // -D59418   <klr> Move read_Value, write_Value to generator's helperRead.
  46 
  47 import java.io.PrintWriter;
  48 
  49 import java.util.Enumeration;
  50 import java.util.Vector;
  51 
  52 import com.sun.tools.corba.se.idl.GenFileStream;
  53 import com.sun.tools.corba.se.idl.InterfaceEntry;
  54 import com.sun.tools.corba.se.idl.MethodEntry;
  55 import com.sun.tools.corba.se.idl.ParameterEntry;
  56 import com.sun.tools.corba.se.idl.SymtabEntry;
  57 import com.sun.tools.corba.se.idl.ValueEntry;
  58 import com.sun.tools.corba.se.idl.ValueBoxEntry;
  59 import com.sun.tools.corba.se.idl.TypedefEntry;
  60 import com.sun.tools.corba.se.idl.InterfaceState;
  61 import com.sun.tools.corba.se.idl.PrimitiveEntry;
  62 import com.sun.tools.corba.se.idl.StructEntry;
  63 
  64 /**
  65  *
  66  **/
  67 public class Helper implements AuxGen
  68 {
  69   /**
  70    * Public zero-argument constructor.
  71    **/
  72   public Helper ()
  73   {
  74   } // ctor
  75 
  76   /**
  77    * Generate the helper class.  Provides general algorithm
  78    * for auxiliary binding generation:
  79    *
  80    * 1.) Initialize symbol table and symbol table entry members,
  81    *     common to all generators.
  82    * 2.) Initialize members unique to this generator.
  83    * 3.) Open print stream
  84    * 4.) Write class heading: package, prologue, class statement, open curly
  85    * 5.) Write class body: member data and methods
  86    * 6.) Write class closing: close curly
  87    * 7.) Close the print stream
  88    **/
  89   public void generate (java.util.Hashtable symbolTable, com.sun.tools.corba.se.idl.SymtabEntry entry)
  90   {
  91     this.symbolTable = symbolTable;
  92     this.entry       = entry;
  93     init ();
  94 
  95     openStream ();
  96     if (stream == null)
  97       return;
  98     writeHeading ();
  99     writeBody ();
 100     writeClosing ();
 101     closeStream ();
 102   } // generate
 103 
 104   /**
 105    * Initialize variables unique to this generator.
 106    **/
 107   protected void init ()
 108   {
 109     helperClass = entry.name () + "Helper";
 110     if (entry instanceof ValueBoxEntry)
 111     {
 112       ValueBoxEntry v = (ValueBoxEntry) entry;
 113       TypedefEntry member = ((InterfaceState) v.state ().elementAt (0)).entry;
 114       SymtabEntry mType =  member.type ();
 115 
 116       if (mType instanceof PrimitiveEntry)
 117         helperType = Util.javaName (entry);
 118       else
 119         helperType = Util.javaName (mType);
 120     }
 121     else
 122       helperType = Util.javaName (entry);
 123   } // init
 124 
 125   /**
 126    * Open the print stream for subsequent output.
 127    **/
 128   protected void openStream ()
 129   {
 130     stream = Util.stream (entry, "Helper.java");
 131   } // openStream
 132 
 133   /**
 134    * Generate the heading, including package, imports, class statements,
 135    * and open curly.
 136    **/
 137   protected void writeHeading ()
 138   {
 139     Util.writePackage (stream, entry, Util.HelperFile);
 140     Util.writeProlog (stream, stream.name ());
 141 
 142     // Transfer comment to target <30jul1997daz>.
 143     if (entry.comment () != null)
 144       entry.comment ().generate ("", stream);
 145 
 146     stream.print ("public final class " + helperClass);
 147     if (entry instanceof ValueEntry)
 148       stream.println (" implements org.omg.CORBA.portable.ValueHelper");
 149     else
 150       stream.println ();
 151     stream.println ('{');
 152   }
 153 
 154   /**
 155    * Generate members of this class.
 156    **/
 157   protected void writeBody ()
 158   {
 159     writeInstVars ();
 160     writeCtors ();
 161     writeInsert ();
 162     writeExtract ();
 163     writeType ();
 164     writeID ();
 165     writeRead ();
 166     writeWrite ();
 167     if (entry instanceof InterfaceEntry && !(entry instanceof ValueEntry)) {
 168       writeNarrow ();
 169       writeUncheckedNarrow ();
 170     }
 171     writeHelperInterface ();
 172     if (entry instanceof ValueEntry)
 173       writeValueHelperInterface ();
 174   } // writeBody
 175 
 176   /**
 177    * Generate members of the Helper interface.
 178    **/
 179   protected void writeHelperInterface ()
 180   {
 181   } // writeHelperInterface
 182 
 183   /**
 184    * Generate members of the ValueHelper interface.
 185    **/
 186   protected void writeValueHelperInterface ()
 187   {
 188     writeGetID ();       // moved for <d59413>
 189     writeGetType ();     // moved for <d59413>
 190     writeGetInstance (); // not in ValueHelper interface
 191     writeGetClass ();
 192     writeGetSafeBaseIds ();
 193   } // writeHelperInterface
 194 
 195   /**
 196    * Generate the closing statements.
 197    **/
 198   protected void writeClosing ()
 199   {
 200     stream.println ('}');
 201   }
 202 
 203   /**
 204    * Write the stream to file by closing the print stream.
 205    **/
 206   protected void closeStream ()
 207   {
 208     stream.close ();
 209   }
 210 
 211   /**
 212    * Generate the instance variables.
 213    **/
 214   protected void writeInstVars ()
 215   {
 216     stream.println ("  private static String  _id = \"" + Util.stripLeadingUnderscoresFromID (entry.repositoryID ().ID ()) + "\";");
 217     if (entry instanceof ValueEntry)
 218     {
 219       stream.println ();
 220       stream.println ("  private static " + helperClass + " helper = new " + helperClass + " ();");
 221       stream.println ();
 222       stream.println ("  private static String[] _truncatable_ids = {");
 223       stream.print   ("    _id");
 224 
 225       // Any safe ValueEntry must have a concete value parent.
 226       // The topmost parent cannot be safe since it doesn't have
 227       // a concrete parent.
 228       ValueEntry child = (ValueEntry) entry;
 229       while (child.isSafe ())
 230       {
 231         stream.println(",");
 232         ValueEntry parent = (ValueEntry)child.derivedFrom ().elementAt (0);
 233         stream.print("    \"" + Util.stripLeadingUnderscoresFromID (parent.repositoryID ().ID ()) + "\"");
 234         child = parent;
 235       }
 236       stream.println("   };");
 237     }
 238     stream.println ();
 239   } // writeInstVars
 240 
 241   /**
 242    * Generate the constructors.
 243    **/
 244   protected void writeCtors ()
 245   {
 246     stream.println ("  public " + helperClass + "()");
 247     stream.println ("  {");
 248     stream.println ("  }");
 249     stream.println ();
 250   } // writeCtors
 251 
 252   /**
 253    * Generate the insert method.
 254    **/
 255   protected void writeInsert ()
 256   {
 257     stream.println ("  public static void insert (org.omg.CORBA.Any a, " + helperType + " that)");
 258     stream.println ("  {");
 259     stream.println ("    org.omg.CORBA.portable.OutputStream out = a.create_output_stream ();");
 260     stream.println ("    a.type (type ());");
 261     stream.println ("    write (out, that);");
 262     stream.println ("    a.read_value (out.create_input_stream (), type ());");
 263     stream.println ("  }");
 264     stream.println ();
 265   } // writeInsert
 266 
 267   /**
 268    * Generate the extract method.
 269    **/
 270   protected void writeExtract ()
 271   {
 272     stream.println ("  public static " + helperType + " extract (org.omg.CORBA.Any a)");
 273     stream.println ("  {");
 274     stream.println ("    return read (a.create_input_stream ());");
 275     stream.println ("  }");
 276     stream.println ();
 277   } // writeExtract
 278 
 279   /**
 280    * Generate the typecode variable and type method.
 281    **/
 282   protected void writeType ()
 283   {
 284     boolean canRecurse = entry instanceof ValueEntry
 285         || entry instanceof ValueBoxEntry
 286         || entry instanceof StructEntry;
 287     stream.println ("  private static org.omg.CORBA.TypeCode __typeCode = null;");
 288     if (canRecurse)
 289       stream.println ("  private static boolean __active = false;");
 290     stream.println ("  synchronized public static org.omg.CORBA.TypeCode type ()");
 291     stream.println ("  {");
 292     stream.println ("    if (__typeCode == null)");
 293     stream.println ("    {");
 294     if (canRecurse) {
 295     stream.println ("      synchronized (org.omg.CORBA.TypeCode.class)");
 296     stream.println ("      {");
 297     stream.println ("        if (__typeCode == null)");
 298     stream.println ("        {");
 299     stream.println ("          if (__active)");
 300     stream.println ("          {");
 301     stream.println ("            return org.omg.CORBA.ORB.init().create_recursive_tc ( _id );");
 302     stream.println ("          }");
 303     stream.println ("          __active = true;");
 304     ((JavaGenerator)entry.generator ()).helperType (0, "          ", new TCOffsets (), "__typeCode", entry, stream);
 305     }
 306     else
 307     ((JavaGenerator)entry.generator ()).helperType (0, "      ", new TCOffsets (), "__typeCode", entry, stream);
 308 
 309     // Generate body of type() method
 310 
 311     if (canRecurse) {
 312     stream.println ("          __active = false;");
 313     stream.println ("        }");
 314     stream.println ("      }");
 315     }
 316     stream.println ("    }");
 317     stream.println ("    return __typeCode;");
 318     stream.println ("  }");
 319     stream.println ();
 320   } // writeType
 321 
 322   /**
 323    * Generate the ID method.
 324    **/
 325   protected void writeID ()
 326   {
 327     stream.println ("  public static String id ()");
 328     stream.println ("  {");
 329     stream.println ("    return _id;");
 330     stream.println ("  }");
 331     stream.println ();
 332   } // writeID
 333 
 334   /**
 335    * Generate the read method.
 336    **/
 337   protected void writeRead ()
 338   {
 339 
 340     boolean isLocalInterface = false;
 341 
 342     if (entry instanceof InterfaceEntry) {
 343         InterfaceEntry ie = (InterfaceEntry) entry;
 344 
 345         // for #pragma sun_local or sun_localservant, or actual local
 346         // local interface, set the flag by checking on both
 347         isLocalInterface = ie.isLocal() | ie.isLocalServant();
 348     }
 349 
 350     stream.println ("  public static " + helperType + " read (org.omg.CORBA.portable.InputStream istream)");
 351     stream.println ("  {");
 352     if ( !isLocalInterface ) { // nonLocal Interface and other types
 353       ((JavaGenerator)entry.generator ()).helperRead (helperType, entry, stream);
 354     } else { //Local interface should throw exception
 355       stream.println ("      throw new org.omg.CORBA.MARSHAL ();");
 356     }
 357     stream.println ("  }");
 358     stream.println ();
 359   } // writeRead
 360 
 361   /**
 362    * Generate the write method.
 363    **/
 364   protected void writeWrite ()
 365   {
 366 
 367     boolean isLocalInterface = false;
 368 
 369     if (entry instanceof InterfaceEntry) {
 370         InterfaceEntry ie = (InterfaceEntry) entry;
 371 
 372         // for #pragma sun_local or sun_localservant, or actual local
 373         // local interface, set the flag by checking on both
 374         isLocalInterface = ie.isLocal() | ie.isLocalServant();
 375     }
 376 
 377     stream.println ("  public static void write (org.omg.CORBA.portable.OutputStream ostream, " + helperType + " value)");
 378     stream.println ("  {");
 379     if ( !isLocalInterface ) { // nonLocal Interface and other types
 380       ((JavaGenerator)entry.generator ()).helperWrite (entry, stream);
 381     } else { //Local interface should throw exception
 382       stream.println ("      throw new org.omg.CORBA.MARSHAL ();");
 383     }
 384     stream.println ("  }");
 385     stream.println ();
 386   } // writeWrite
 387 
 388 
 389   /**
 390    * Generate the narrow method.
 391    **/
 392   protected void writeNarrow ()
 393   {
 394     writeRemoteNarrow ();
 395     stream.println ();
 396   }
 397 
 398   /**
 399    * Write the narrow() method for a remotable object.
 400    **/
 401   protected void writeRemoteNarrow ()
 402   {
 403     InterfaceEntry ie = (InterfaceEntry) entry;
 404 
 405     // narrow for LocalObject interface
 406     if (ie.isLocal ()) {
 407         writeRemoteNarrowForLocal (false);
 408         return;
 409     }
 410 
 411     // narrow for Abstract interface
 412     if (ie.isAbstract ()) {
 413         writeRemoteNarrowForAbstract (false);
 414         return;
 415     } else {
 416         // Determine if the non-abstract interface has any abstract parents
 417         for (int i = 0; i < ie.derivedFrom ().size (); i++) {
 418             SymtabEntry parent = (SymtabEntry) ie.derivedFrom ().elementAt (i);
 419             if (((InterfaceEntry) parent).isAbstract ()) {
 420                 writeRemoteNarrowForAbstract (true);
 421                 break;
 422             }
 423         }
 424     }
 425 
 426     stream.println ("  public static " + helperType + " narrow (org.omg.CORBA.Object obj)");
 427     stream.println ("  {");
 428     stream.println ("    if (obj == null)");
 429     stream.println ("      return null;");
 430     stream.println ("    else if (obj instanceof " + helperType + ')');
 431     stream.println ("      return (" + helperType + ")obj;");
 432     stream.println ("    else if (!obj._is_a (id ()))");
 433     stream.println ("      throw new org.omg.CORBA.BAD_PARAM ();");
 434     stream.println ("    else");
 435     stream.println ("    {");
 436     stream.println ("      org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate ();");
 437     String stubNameofEntry = stubName ((InterfaceEntry)entry);
 438     stream.println ("      " + stubNameofEntry + " stub = new " + stubNameofEntry + " ();");
 439     stream.println ("      stub._set_delegate(delegate);");
 440     stream.println ("      return stub;");
 441     stream.println ("    }");
 442     stream.println ("  }");
 443   } // writeRemoteNarrow
 444 
 445   /**
 446    * Write the narrow() method for local interface.
 447    **/
 448   private void writeRemoteNarrowForLocal (boolean hasAbstractParent)
 449   {
 450     stream.println ("  public static " + helperType + " narrow (org.omg.CORBA.Object obj)");
 451     stream.println ("  {");
 452     stream.println ("    if (obj == null)");
 453     stream.println ("      return null;");
 454     stream.println ("    else if (obj instanceof " + helperType + ')');
 455     stream.println ("      return (" + helperType + ")obj;");
 456     stream.println ("    else");
 457     stream.println ("      throw new org.omg.CORBA.BAD_PARAM ();");
 458     stream.println ("  }");
 459   } // writeRemoteNarrowForLocal
 460 
 461   /**
 462    * Write the narrow() method for abstract interface.
 463    **/
 464   private void writeRemoteNarrowForAbstract (boolean hasAbstractParent)
 465   {
 466     stream.print ("  public static " + helperType + " narrow (java.lang.Object obj)");
 467     stream.println ("  {");
 468     stream.println ("    if (obj == null)");
 469     stream.println ("      return null;");
 470     if (hasAbstractParent)
 471     {
 472       stream.println ("    else if (obj instanceof org.omg.CORBA.Object)");
 473       stream.println ("      return narrow ((org.omg.CORBA.Object) obj);");
 474     }
 475     else
 476     {
 477       stream.println ("    else if (obj instanceof " + helperType + ')');
 478       stream.println ("      return (" + helperType + ")obj;");
 479     }
 480 
 481     // If hasAbstractParent is false, then THIS entry must be abstract.
 482     // This method is also called in case THIS entry is not abstract, but
 483     // there is an abstract parent.  If this entry is not abstract,
 484     // it can never narrow to a CORBA object reference.
 485     if (!hasAbstractParent) { // <d58889>
 486       String stubNameofEntry = stubName ((InterfaceEntry)entry);
 487 
 488       stream.println ("    else if ((obj instanceof org.omg.CORBA.portable.ObjectImpl) &&");
 489       stream.println ("             (((org.omg.CORBA.Object)obj)._is_a (id ()))) {");
 490       stream.println ("      org.omg.CORBA.portable.ObjectImpl impl = (org.omg.CORBA.portable.ObjectImpl)obj ;" ) ;
 491       stream.println ("      org.omg.CORBA.portable.Delegate delegate = impl._get_delegate() ;" ) ;
 492       stream.println ("      " + stubNameofEntry + " stub = new " + stubNameofEntry + " ();");
 493       stream.println ("      stub._set_delegate(delegate);");
 494       stream.println ("      return stub;" ) ;
 495       stream.println ("    }" ) ;
 496     };
 497     // end <d57118 - check for remotable - klr>
 498 
 499     stream.println ("    throw new org.omg.CORBA.BAD_PARAM ();");
 500     stream.println ("  }");
 501     stream.println ();
 502   } // writeRemoteNarrowForAbstract
 503 
 504 
 505   /**
 506    * Generate the unchecked narrow method.
 507    **/
 508   protected void writeUncheckedNarrow ()
 509   {
 510     writeUncheckedRemoteNarrow ();
 511     stream.println ();
 512   }
 513 
 514   /**
 515    * Write the unchecked narrow() method for a remotable object.
 516    **/
 517   protected void writeUncheckedRemoteNarrow ()
 518   {
 519     InterfaceEntry ie = (InterfaceEntry) entry;
 520 
 521     // unchecked narrow for LocalObject interface
 522     if (ie.isLocal ()) {
 523         writeRemoteUncheckedNarrowForLocal (false);
 524         return;
 525     }
 526 
 527     // unchecked narrow for Abstract interface
 528     if (ie.isAbstract ()) {
 529         writeRemoteUncheckedNarrowForAbstract (false);
 530         return;
 531     } else {
 532         // Determine if the non-abstract interface has any abstract parents
 533         for (int i = 0; i < ie.derivedFrom ().size (); i++) {
 534             SymtabEntry parent = (SymtabEntry) ie.derivedFrom ().elementAt (i);
 535             if (((InterfaceEntry) parent).isAbstract ()) {
 536                 writeRemoteUncheckedNarrowForAbstract (true);
 537                 break;
 538             }
 539         }
 540     }
 541 
 542     stream.println ("  public static " + helperType + " unchecked_narrow (org.omg.CORBA.Object obj)");
 543     stream.println ("  {");
 544     stream.println ("    if (obj == null)");
 545     stream.println ("      return null;");
 546     stream.println ("    else if (obj instanceof " + helperType + ')');
 547     stream.println ("      return (" + helperType + ")obj;");
 548     stream.println ("    else");
 549     stream.println ("    {");
 550     stream.println ("      org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate ();");
 551     String stubNameofEntry = stubName ((InterfaceEntry)entry);
 552     stream.println ("      " + stubNameofEntry + " stub = new " + stubNameofEntry + " ();");
 553     stream.println ("      stub._set_delegate(delegate);");
 554     stream.println ("      return stub;");
 555     stream.println ("    }");
 556     stream.println ("  }");
 557   } // writeUncheckedRemoteNarrow
 558 
 559   /**
 560    * Write the unchecked narrow() method for local interface.
 561    **/
 562   private void writeRemoteUncheckedNarrowForLocal (boolean hasAbstractParent)
 563   {
 564     stream.println ("  public static " + helperType + " unchecked_narrow (org.omg.CORBA.Object obj)");
 565     stream.println ("  {");
 566     stream.println ("    if (obj == null)");
 567     stream.println ("      return null;");
 568     stream.println ("    else if (obj instanceof " + helperType + ')');
 569     stream.println ("      return (" + helperType + ")obj;");
 570     stream.println ("    else");
 571     stream.println ("      throw new org.omg.CORBA.BAD_PARAM ();");
 572     stream.println ("  }");
 573   } // writeRemoteUncheckedNarrowForLocal
 574 
 575   /**
 576    * Write the unchecked narrow() method for abstract interface.
 577    **/
 578   private void writeRemoteUncheckedNarrowForAbstract (boolean hasAbstractParent)
 579   {
 580     stream.print ("  public static " + helperType + " unchecked_narrow (java.lang.Object obj)");
 581     stream.println ("  {");
 582     stream.println ("    if (obj == null)");
 583     stream.println ("      return null;");
 584     if (hasAbstractParent)
 585     {
 586       stream.println ("    else if (obj instanceof org.omg.CORBA.Object)");
 587       stream.println ("      return unchecked_narrow ((org.omg.CORBA.Object) obj);");
 588     }
 589     else
 590     {
 591       stream.println ("    else if (obj instanceof " + helperType + ')');
 592       stream.println ("      return (" + helperType + ")obj;");
 593     }
 594 
 595     if (!hasAbstractParent) {
 596       String stubNameofEntry = stubName ((InterfaceEntry)entry);
 597 
 598       stream.println ("    else if (obj instanceof org.omg.CORBA.portable.ObjectImpl) {");
 599       stream.println ("      org.omg.CORBA.portable.ObjectImpl impl = (org.omg.CORBA.portable.ObjectImpl)obj ;" ) ;
 600       stream.println ("      org.omg.CORBA.portable.Delegate delegate = impl._get_delegate() ;" ) ;
 601       stream.println ("      " + stubNameofEntry + " stub = new " + stubNameofEntry + " ();");
 602       stream.println ("      stub._set_delegate(delegate);");
 603       stream.println ("      return stub;" ) ;
 604       stream.println ("    }" ) ;
 605     };
 606 
 607     stream.println ("    throw new org.omg.CORBA.BAD_PARAM ();");
 608     stream.println ("  }");
 609     stream.println ();
 610   } // writeRemoteUncheckedNarrowForAbstract
 611 
 612 
 613   /**
 614    * Generate the GetID method.
 615    **/
 616   protected void writeGetID ()
 617   {
 618     if ( !Util.IDLEntity (entry))
 619       return;
 620     stream.println ("  public String get_id ()");
 621     stream.println ("  {");
 622     stream.println ("    return _id;");
 623     stream.println ("  }");
 624     stream.println ();
 625   } // writeGetID
 626 
 627   /**
 628    * Generate the GetType method.
 629    **/
 630   protected void writeGetType ()
 631   {
 632     if ( !Util.IDLEntity (entry))
 633       return;
 634     stream.println ("  public org.omg.CORBA.TypeCode get_type ()");
 635     stream.println ("  {");
 636     stream.println ("    return type ();");
 637     stream.println ("  }");
 638     stream.println ();
 639   } // writeGetID
 640 
 641   /**
 642    * Generate the get_class method.
 643    **/
 644   protected void writeGetClass ()
 645   {
 646     stream.println ("  public Class get_class ()");
 647     stream.println ("  {");
 648     stream.println ("    return " + helperType + ".class;"); //<d59383>
 649     stream.println ("  }");
 650     stream.println ();
 651   } // writeGetClass
 652 
 653   /**
 654    * Generate the get_instance method.
 655    **/
 656   protected void writeGetInstance ()
 657   {
 658     stream.println ("  public static org.omg.CORBA.portable.ValueHelper get_instance ()");
 659     stream.println ("  {");
 660     stream.println ("    return helper;");
 661     stream.println ("  }");
 662     stream.println ();
 663   } // writeGetInstance
 664 
 665   /**
 666    * Generate the GetSafeBaseIds method.
 667    **/
 668   protected void writeGetSafeBaseIds ()
 669   {
 670     stream.println ("  public String[] get_truncatable_base_ids ()");
 671     stream.println ("  {");
 672     stream.println ("    return _truncatable_ids;");
 673     stream.println ("  }");
 674     stream.println ();
 675   } // writeGetSafeBaseIds
 676 
 677   /**
 678    * Return the stub name for the interface entry.
 679    **/
 680   protected String stubName (InterfaceEntry entry)
 681   {
 682     String name;
 683     if (entry.container ().name ().equals (""))
 684       name =  '_' + entry.name () + "Stub";
 685     else
 686     {
 687       name = Util.containerFullName (entry.container ()) + "._" + entry.name () + "Stub";
 688     }
 689     return name.replace ('/', '.');
 690   } // stubName
 691 
 692   protected java.util.Hashtable     symbolTable;
 693   protected com.sun.tools.corba.se.idl.SymtabEntry entry;
 694   protected GenFileStream           stream;
 695 
 696   // Unique to this generator
 697   protected String helperClass;
 698   protected String helperType;
 699 } // class Helper