1 /*
   2  * Copyright (c) 1999, 2002, 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 // -After demarshalling an IOR, think about how to deal with the exceptions.
  40 // -catching Exception throws a string which should be in a properties file.
  41 // -30jul1997<daz> Modified to write comment immediately preceding method signature.
  42 // -07May1998<ktp> Modified to support RMI Portable Stub
  43 // -26Aug1998<klr> Modified to pass helper instance to read_Value.
  44 // -F46082.51<daz> Remove -stateful feature; javaStatefulName() obsolete.
  45 // -D56554   <klr> Port bounded string checks from toJava to toJavaPortable
  46 // -D58549   <klr> bounded string checks on in/inout parms throw BAD_PARAM
  47 // -D57112<daz> Valuetype initializers map to ctor, regardless of name, and
  48 //  "void _init(...)" methods now mapped correctly.
  49 // -D59297   <klr> pass context parm when Remarshalling
  50 // -D59560   <klr> call read/write_Context
  51 // -D60929   <klr> Update for RTF2.4 changes
  52 // -D61056   <klr> Use Util.helperName
  53 // -D61650<daz> Remove '\n' from generated strings; use println()'s.
  54 
  55 import java.io.PrintWriter;
  56 import java.util.Enumeration;
  57 import java.util.Hashtable;
  58 
  59 import com.sun.tools.corba.se.idl.EnumEntry;
  60 import com.sun.tools.corba.se.idl.ExceptionEntry;
  61 import com.sun.tools.corba.se.idl.InterfaceEntry;
  62 import com.sun.tools.corba.se.idl.MethodEntry;
  63 import com.sun.tools.corba.se.idl.ParameterEntry;
  64 import com.sun.tools.corba.se.idl.PrimitiveEntry;
  65 import com.sun.tools.corba.se.idl.StringEntry;
  66 import com.sun.tools.corba.se.idl.SymtabEntry;
  67 import com.sun.tools.corba.se.idl.SequenceEntry;
  68 import com.sun.tools.corba.se.idl.ValueEntry;
  69 import com.sun.tools.corba.se.idl.ValueBoxEntry;
  70 import com.sun.tools.corba.se.idl.InterfaceState;
  71 import com.sun.tools.corba.se.idl.TypedefEntry;
  72 import com.sun.tools.corba.se.idl.AttributeEntry;
  73 
  74 import com.sun.tools.corba.se.idl.constExpr.Expression;
  75 
  76 /**
  77  *
  78  **/
  79 public class MethodGen implements com.sun.tools.corba.se.idl.MethodGen
  80 {
  81   private static final String ONE_INDENT   = "    ";
  82   private static final String TWO_INDENT   = "        ";
  83   private static final String THREE_INDENT = "            ";
  84   private static final String FOUR_INDENT  = "                ";
  85   private static final String FIVE_INDENT  = "                    ";
  86   // This is the length of _get_ and _set_
  87   private static final int ATTRIBUTE_METHOD_PREFIX_LENGTH  = 5;
  88   /**
  89    * Public zero-argument constructor.
  90    **/
  91   public MethodGen ()
  92   {
  93   } // ctor
  94 
  95   /**
  96    * Method generate() is not used in MethodGen.  They are replaced by the
  97    * more granular interfaceMethod, stub, skeleton, dispatchSkeleton.
  98    **/
  99   public void generate (Hashtable symbolTable, MethodEntry m, PrintWriter stream)
 100   {
 101   } // generate
 102 
 103   /**
 104    *
 105    **/
 106   protected void interfaceMethod (Hashtable symbolTable, MethodEntry m, PrintWriter stream)
 107   {
 108     this.symbolTable = symbolTable;
 109     this.m           = m;
 110     this.stream      = stream;
 111     if (m.comment () != null)
 112       m.comment ().generate ("", stream);
 113     stream.print ("  ");
 114     SymtabEntry container = (SymtabEntry)m.container ();
 115     boolean isAbstract = false;
 116     boolean valueContainer = false;
 117     if (container instanceof ValueEntry)
 118     {
 119       isAbstract = ((ValueEntry)container).isAbstract ();
 120       valueContainer = true;
 121     }
 122     if (valueContainer && !isAbstract)
 123       stream.print ("public ");
 124     writeMethodSignature ();
 125     if (valueContainer && !isAbstract)
 126     {
 127       stream.println ();
 128       stream.println ("  {");
 129       stream.println ("  }");
 130       stream.println ();
 131     }
 132     else
 133       stream.println (";");
 134   } // interfaceMethod
 135 
 136   /**
 137    *
 138    **/
 139   protected void stub (String className, boolean isAbstract,
 140       Hashtable symbolTable, MethodEntry m, PrintWriter stream, int index)
 141   {
 142     localOptimization =
 143         ((Arguments)Compile.compiler.arguments).LocalOptimization;
 144     this.isAbstract  = isAbstract;
 145     this.symbolTable = symbolTable;
 146     this.m           = m;
 147     this.stream      = stream;
 148     this.methodIndex = index;
 149     if (m.comment () != null)
 150       m.comment ().generate ("  ", stream);
 151     stream.print ("  public ");
 152     writeMethodSignature ();
 153     stream.println ();
 154     stream.println ("  {");
 155     writeStubBody ( className );
 156     stream.println ("  } // " + m.name ());
 157     stream.println ();
 158   } // stub
 159 
 160   /**
 161    *
 162    **/
 163   protected void localstub (Hashtable symbolTable, MethodEntry m, PrintWriter stream, int index, InterfaceEntry i)
 164   {
 165     this.symbolTable = symbolTable;
 166     this.m           = m;
 167     this.stream      = stream;
 168     this.methodIndex = index;
 169     if (m.comment () != null)
 170       m.comment ().generate ("  ", stream);
 171     stream.print ("  public ");
 172     writeMethodSignature ();
 173     stream.println ();
 174     stream.println ("  {");
 175     writeLocalStubBody (i);
 176     stream.println ("  } // " + m.name ());
 177     stream.println ();
 178   } // stub
 179   /**
 180    *
 181    **/
 182   protected void skeleton (Hashtable symbolTable, MethodEntry m, PrintWriter stream, int index)
 183   {
 184     this.symbolTable = symbolTable;
 185     this.m           = m;
 186     this.stream      = stream;
 187     this.methodIndex = index;
 188     if (m.comment () != null)
 189       m.comment ().generate ("  ", stream);
 190     stream.print ("  public ");
 191     writeMethodSignature ();
 192     stream.println ();
 193     stream.println ("  {");
 194     writeSkeletonBody ();
 195     stream.println ("  } // " + m.name ());
 196   } // skeleton
 197 
 198   /**
 199    *
 200    **/
 201   protected void dispatchSkeleton (Hashtable symbolTable, MethodEntry m, PrintWriter stream, int index)
 202   {
 203     this.symbolTable = symbolTable;
 204     this.m           = m;
 205     this.stream      = stream;
 206     this.methodIndex = index;
 207     if (m.comment () != null)
 208       m.comment ().generate ("  ", stream);
 209     writeDispatchCall ();
 210   } // dispatchSkeleton
 211 
 212   // <d57112>
 213   /**
 214    * Determine whether method entry m is a valuetype initializer.
 215    * @return true if is m is valuetype initializer, false otherwise.
 216    **/
 217   protected boolean isValueInitializer ()
 218   {
 219     MethodEntry currentInit = null;
 220     if ((m.container () instanceof ValueEntry))
 221     {
 222       Enumeration e = ((ValueEntry)m.container ()).initializers ().elements ();
 223       while (currentInit != m && e.hasMoreElements ())
 224         currentInit = (MethodEntry)e.nextElement ();
 225     }
 226     return (currentInit == m) && (null != m);  // True ==> yes, false ==> no.
 227   } // isValueInitializer
 228 
 229   /**
 230    *
 231    **/
 232   protected void writeMethodSignature ()
 233   {
 234     boolean isValueInitializer = isValueInitializer ();  // <d57112>
 235 
 236     // Step 0.  Print the return type and name.
 237     // A return type of null indicates the "void" return type. If m is a
 238     // Valuetype intitializer, it has name "init" and a null return type,
 239     // but it maps to a ctor.
 240     // <d57112>
 241     //if (m.type () == null)
 242     //{
 243     //  if (m.name ().compareTo ("init") != 0)
 244     //    stream.print ("void");
 245     //}
 246     if (m.type () == null)
 247     {
 248       if (!isValueInitializer)
 249         stream.print ("void");
 250     }
 251     else
 252     {
 253       // <f46082.51> Remove -stateful feature; javaStatefulName() obsolete.
 254       //stream.print (Util.javaStatefulName (m.type ()));
 255       stream.print (Util.javaName (m.type ()));
 256     }
 257     // <d57112> Value initializers map to constructors.
 258     // If the value has an 'init' method with a return type, handle
 259     // the method like other regular methods
 260     //if (m.valueMethod () && m.name ().compareTo ("init") == 0 &&
 261     //    m.type () == null)
 262     if (isValueInitializer)
 263       stream.print (' ' + m.container ().name () + " (");
 264     else
 265       stream.print (' ' + m.name () + " (");
 266 
 267     // Step 1.  Print the parameter list.
 268     boolean firstTime = true;
 269     Enumeration e = m.parameters ().elements ();
 270     while (e.hasMoreElements ())
 271     {
 272       if (firstTime)
 273         firstTime = false;
 274       else
 275         stream.print (", ");
 276       ParameterEntry parm = (ParameterEntry)e.nextElement ();
 277 
 278       writeParmType (parm.type (), parm.passType ());
 279 
 280       // Print parm name
 281       stream.print (' ' + parm.name ());
 282     }
 283 
 284     // Step 2.  Add the context parameter if necessary.
 285     if (m.contexts ().size () > 0)
 286     {
 287       if (!firstTime)
 288         stream.print (", ");
 289       stream.print ("org.omg.CORBA.Context $context");
 290     }
 291 
 292     // Step 3.  Print the throws clause (if necessary).
 293     if (m.exceptions ().size () > 0)
 294     {
 295       stream.print (") throws ");
 296       e = m.exceptions ().elements ();
 297       firstTime = true;
 298       while (e.hasMoreElements ())
 299       {
 300         if (firstTime)
 301           firstTime = false;
 302         else
 303           stream.print (", ");
 304         stream.print (Util.javaName ((SymtabEntry)e.nextElement ()));
 305       }
 306     }
 307     else
 308       stream.print (')');
 309   } // writeMethodSignature
 310 
 311   /**
 312    *
 313    **/
 314   protected void writeParmType (SymtabEntry parm, int passType)
 315   {
 316     if (passType != ParameterEntry.In)
 317     {
 318       parm = Util.typeOf (parm);
 319       stream.print (Util.holderName (parm));
 320     }
 321     else // passType is `in'
 322       // <f46082.51> Remove -stateful feature; javaStatefulName() obsolete.
 323       //stream.print (Util.javaStatefulName (parm));
 324       stream.print (Util.javaName (parm));
 325   } // writeParmType
 326 
 327   /**
 328    *
 329    **/
 330   protected void writeDispatchCall ()
 331   {
 332     String indent = "       ";
 333     String fullMethodName = m.fullName ();
 334     if (m instanceof AttributeEntry)
 335     {
 336       // determine the index at which the attribute name starts in the full name
 337       int index = fullMethodName.lastIndexOf ('/') + 1;
 338       if (m.type () == null)          // if it's a modifier
 339         fullMethodName = fullMethodName.substring (0, index) + "_set_" + m.name ();
 340       else
 341         fullMethodName = fullMethodName.substring (0, index) + "_get_" + m.name ();
 342     }
 343     stream.println (indent + "case " + methodIndex + ":  // " + fullMethodName);
 344     stream.println (indent + "{");
 345     indent = indent + "  ";
 346     if (m.exceptions ().size () > 0)
 347     {
 348       stream.println (indent + "try {");
 349       indent = indent + "  ";
 350     }
 351 
 352     // Step 1 Read arguments from the input stream
 353     SymtabEntry mtype = Util.typeOf (m.type ());
 354     Enumeration parms = m.parameters ().elements ();
 355     parms = m.parameters ().elements ();
 356     while (parms.hasMoreElements ())
 357     {
 358       ParameterEntry parm     = (ParameterEntry) parms.nextElement ();
 359       String         name     = parm.name ();
 360       String         anyName  = '_' + name;
 361       SymtabEntry    type     = parm.type ();
 362       int            passType = parm.passType ();
 363 
 364       if (passType == ParameterEntry.In)
 365         Util.writeInitializer (indent, name, "", type, writeInputStreamRead ("in", type), stream);
 366 
 367       else // the parm is a holder
 368       {
 369         String holderName = Util.holderName (type);
 370         stream.println (indent + holderName + ' ' + name + " = new " + holderName + " ();");
 371         if (passType == ParameterEntry.Inout)
 372         {
 373           if (type instanceof ValueBoxEntry)
 374           {
 375             ValueBoxEntry v = (ValueBoxEntry) type;
 376             TypedefEntry member = ((InterfaceState) v.state ().elementAt (0)).entry;
 377             SymtabEntry mType = member.type ();
 378             if (mType instanceof PrimitiveEntry)
 379               stream.println (indent + name + ".value = (" + writeInputStreamRead ("in", parm.type ()) + ").value;");
 380             else
 381               stream.println (indent + name + ".value = " + writeInputStreamRead ("in", parm.type ()) + ";");
 382           }
 383           else
 384             stream.println (indent +  name  + ".value = " + writeInputStreamRead ("in", parm.type ()) + ";");
 385         }
 386       }
 387     }
 388 
 389     // Step 1a.  Read the context parameter if necessary. <d59560>
 390     if (m.contexts ().size () > 0)
 391     {
 392       stream.println (indent + "org.omg.CORBA.Context $context = in.read_Context ();");
 393     }
 394 
 395     // Step 2 Load return if necessary
 396     if (mtype != null)
 397       Util.writeInitializer (indent, "$result", "", mtype, stream);
 398 
 399     // Step 3 Call the method with the list of parameters
 400     writeMethodCall (indent);
 401 
 402     parms = m.parameters ().elements ();
 403     boolean firstTime = true;
 404     while (parms.hasMoreElements ())
 405     {
 406       ParameterEntry parm = (ParameterEntry)parms.nextElement ();
 407       if (firstTime)
 408         firstTime = false;
 409       else
 410         stream.print (", ");
 411       stream.print (parm.name ());
 412     }
 413 
 414     // Step 3a.  Add the context parameter if necessary. <d59560>
 415     if (m.contexts ().size () > 0)
 416     {
 417       if (!firstTime)
 418         stream.print (", ");
 419       stream.print ("$context");
 420     }
 421 
 422     stream.println (");");
 423 
 424     //Step 3b. Create reply;
 425     writeCreateReply (indent);
 426 
 427     // Step 4 Write method's result to the output stream
 428     if (mtype != null)
 429     {
 430       writeOutputStreamWrite (indent, "out", "$result", mtype, stream);
 431     }
 432 
 433     // Step 5 Write inout/out value to the output stream
 434     parms = m.parameters ().elements ();
 435     while (parms.hasMoreElements ())
 436     {
 437       ParameterEntry parm = (ParameterEntry)parms.nextElement ();
 438       int passType = parm.passType ();
 439       if (passType != ParameterEntry.In)
 440       {
 441         writeOutputStreamWrite (indent, "out", parm.name () + ".value", parm.type (), stream);
 442       }
 443     }
 444 
 445     // Step 6 Handle exception
 446     if (m.exceptions ().size () > 0)
 447     {
 448       Enumeration exceptions = m.exceptions ().elements ();
 449       while (exceptions.hasMoreElements ())
 450       {
 451         indent = "         ";
 452         ExceptionEntry exc = (ExceptionEntry) exceptions.nextElement ();
 453         String fullName = Util.javaQualifiedName (exc);
 454         stream.println (indent + "} catch (" +  fullName + " $ex) {");
 455         indent = indent + "  ";
 456         stream.println (indent + "out = $rh.createExceptionReply ();");
 457         stream.println (indent + Util.helperName (exc, true) + ".write (out, $ex);"); // <d61056>
 458       }
 459 
 460       indent = "         ";
 461       stream.println (indent + "}");
 462     }
 463 
 464     stream.println ("         break;");
 465     stream.println ("       }");
 466     stream.println ();
 467   } // writeDispatchCall
 468 
 469   /**
 470    *
 471    **/
 472   protected void writeStubBody ( String className )
 473   {
 474     // Step 1  Create a request
 475     String methodName = Util.stripLeadingUnderscores (m.name ());
 476     if (m instanceof AttributeEntry)
 477     {
 478       if (m.type () == null)          // if it's a modifier
 479         methodName = "_set_" + methodName;
 480       else
 481         methodName = "_get_" + methodName;
 482     }
 483     if( localOptimization && !isAbstract ) {
 484         stream.println (ONE_INDENT + "while(true) {" );
 485         stream.println(TWO_INDENT + "if(!this._is_local()) {" );
 486     }
 487     stream.println(THREE_INDENT +
 488         "org.omg.CORBA.portable.InputStream $in = null;");
 489     stream.println(THREE_INDENT + "try {");
 490     stream.println(FOUR_INDENT + "org.omg.CORBA.portable.OutputStream $out =" +
 491         " _request (\"" +  methodName + "\", " + !m.oneway() + ");");
 492 
 493     // Step 1.b.  Check string bounds <d56554 - klr>
 494     // begin <d56554> in/inout string bounds check
 495     Enumeration parms = m.parameters ().elements ();
 496     while (parms.hasMoreElements ())
 497     {
 498       ParameterEntry parm = (ParameterEntry)parms.nextElement ();
 499       SymtabEntry parmType = Util.typeOf (parm.type ());
 500       if (parmType instanceof StringEntry)
 501         if ((parm.passType () == ParameterEntry.In) ||
 502             (parm.passType () == ParameterEntry.Inout))
 503         {
 504           StringEntry string = (StringEntry)parmType;
 505           if (string.maxSize () != null)
 506           {
 507             stream.print (THREE_INDENT + "if (" + parm.name ());
 508             if (parm.passType () == ParameterEntry.Inout)
 509               stream.print (".value"); // get from holder
 510             stream.print (" == null || " + parm.name ());
 511             if (parm.passType () == ParameterEntry.Inout)
 512               stream.print (".value"); // get from holder
 513             stream.println (".length () > (" +
 514                 Util.parseExpression (string.maxSize ()) + "))");
 515             stream.println (THREE_INDENT +
 516                 "throw new org.omg.CORBA.BAD_PARAM (0," +
 517                 " org.omg.CORBA.CompletionStatus.COMPLETED_NO);");
 518           }
 519         }
 520     }
 521     // end <d56554> in/inout string bounds check
 522 
 523     // Step 2  Load the parameters into the outputStream
 524     parms = m.parameters ().elements ();
 525     while (parms.hasMoreElements ())
 526     {
 527       ParameterEntry parm = (ParameterEntry)parms.nextElement ();
 528       if (parm.passType () == ParameterEntry.In)
 529         writeOutputStreamWrite(FOUR_INDENT, "$out", parm.name (), parm.type (),
 530             stream);
 531       else if (parm.passType () == ParameterEntry.Inout)
 532         writeOutputStreamWrite(FOUR_INDENT, "$out", parm.name () + ".value",
 533             parm.type (), stream);
 534     }
 535 
 536     // Step 2a.  Write the context parameter if necessary. <d59560>
 537     if (m.contexts ().size () > 0)
 538     {
 539       stream.println(FOUR_INDENT + "org.omg.CORBA.ContextList $contextList =" +
 540          "_orb ().create_context_list ();");
 541 
 542       for (int cnt = 0; cnt < m.contexts ().size (); cnt++)
 543       {
 544           stream.println(FOUR_INDENT +
 545              "$contextList.add (\"" + m.contexts (). elementAt (cnt) + "\");");
 546       }
 547       stream.println(FOUR_INDENT +
 548           "$out.write_Context ($context, $contextList);");
 549     }
 550 
 551     // Step 3 Invoke the method with the output stream
 552     stream.println (FOUR_INDENT + "$in = _invoke ($out);");
 553 
 554     SymtabEntry mtype = m.type ();
 555     if (mtype != null)
 556       Util.writeInitializer (FOUR_INDENT, "$result", "", mtype,
 557           writeInputStreamRead ("$in", mtype), stream);
 558 
 559     // Step 4  Read the inout/out values
 560     parms = m.parameters ().elements ();
 561     while (parms.hasMoreElements ())
 562     {
 563       ParameterEntry parm = (ParameterEntry)parms.nextElement ();
 564       if (parm.passType () != ParameterEntry.In)
 565       {
 566         if (parm.type () instanceof ValueBoxEntry)
 567         {
 568           ValueBoxEntry v = (ValueBoxEntry) parm.type ();
 569           TypedefEntry member =
 570               ((InterfaceState) v.state ().elementAt (0)).entry;
 571           SymtabEntry mType = member.type ();
 572           if (mType instanceof PrimitiveEntry)
 573             stream.println(FOUR_INDENT +  parm.name () +
 574                 ".value = (" + writeInputStreamRead ("$in", parm.type ()) +
 575                 ").value;");
 576           else
 577             stream.println(FOUR_INDENT +  parm.name () +
 578                 ".value = " + writeInputStreamRead ("$in", parm.type ()) +";");
 579         }
 580         else
 581           stream.println (FOUR_INDENT +  parm.name () + ".value = " +
 582               writeInputStreamRead ("$in", parm.type ()) + ";");
 583       }
 584     }
 585     // Step 4.b.  Check string bounds <d56554 - klr>
 586     // begin <d56554> out/inout/return string bounds check
 587     parms = m.parameters ().elements ();
 588     while (parms.hasMoreElements ())
 589     {
 590       ParameterEntry parm = (ParameterEntry)parms.nextElement ();
 591       SymtabEntry parmType = Util.typeOf (parm.type ());
 592       if (parmType instanceof StringEntry)
 593         if ((parm.passType () == ParameterEntry.Out) ||
 594             (parm.passType () == ParameterEntry.Inout))
 595         {
 596           StringEntry string = (StringEntry)parmType;
 597           if (string.maxSize () != null)
 598           {
 599             stream.print (FOUR_INDENT + "if (" + parm.name () +
 600                 ".value.length ()");
 601             stream.println ("         > (" +
 602                 Util.parseExpression (string.maxSize ()) + "))");
 603             stream.println (FIVE_INDENT + "throw new org.omg.CORBA.MARSHAL(0,"+
 604                 "org.omg.CORBA.CompletionStatus.COMPLETED_NO);");
 605           }
 606         }
 607     }
 608     if (mtype instanceof StringEntry)
 609     {
 610       StringEntry string = (StringEntry)mtype;
 611       if (string.maxSize () != null)
 612       {
 613         stream.println(FOUR_INDENT + "if ($result.length () > (" +
 614             Util.parseExpression (string.maxSize ()) + "))");
 615         stream.println (FIVE_INDENT + "throw new org.omg.CORBA.MARSHAL (0," +
 616             " org.omg.CORBA.CompletionStatus.COMPLETED_NO);");
 617       }
 618     }
 619     // end <d56554> out/inout/return string bounds check
 620 
 621     // Step 5  Handle return if necessary
 622     if (mtype != null) {
 623       stream.println(FOUR_INDENT + "return $result;");
 624     } else {
 625       stream.println(FOUR_INDENT + "return;");
 626     }
 627 
 628     // Step 6  Handle exceptions
 629     stream.println(THREE_INDENT +
 630         "} catch (org.omg.CORBA.portable.ApplicationException " + "$ex) {");
 631     stream.println(FOUR_INDENT + "$in = $ex.getInputStream ();");
 632     stream.println(FOUR_INDENT + "String _id = $ex.getId ();");
 633 
 634     if (m.exceptions ().size () > 0)
 635     {
 636       Enumeration exceptions = m.exceptions ().elements ();
 637       boolean firstExc = true;
 638       while (exceptions.hasMoreElements ())
 639       {
 640         ExceptionEntry exc = (ExceptionEntry)exceptions.nextElement ();
 641         if (firstExc)
 642         {
 643           stream.print(FOUR_INDENT + "if ");
 644           firstExc = false;
 645         }
 646         else
 647           stream.print(FOUR_INDENT + "else if ");
 648 
 649         stream.println( "(_id.equals (\"" + exc.repositoryID ().ID () + "\"))");
 650         stream.println (FIVE_INDENT + "throw " +
 651             Util.helperName ((SymtabEntry)exc, false) + ".read ($in);");
 652       }
 653       stream.println(FOUR_INDENT + "else");
 654       stream.println(FIVE_INDENT + "throw new org.omg.CORBA.MARSHAL (_id);");
 655     }
 656     else
 657       stream.println(FOUR_INDENT + "throw new org.omg.CORBA.MARSHAL (_id);");
 658 
 659     stream.println(THREE_INDENT +
 660         "} catch (org.omg.CORBA.portable.RemarshalException $rm) {");
 661     stream.print( FOUR_INDENT );
 662     if (m.type () != null) // not a void method
 663       stream.print ("return ");
 664     stream.print (m.name () + " (");
 665     {
 666       // write parm names
 667       boolean firstTime = true;
 668       Enumeration e = m.parameters ().elements ();
 669       while (e.hasMoreElements ())
 670       {
 671         if (firstTime)
 672           firstTime = false;
 673         else
 674           stream.print (", ");
 675         ParameterEntry parm = (ParameterEntry)e.nextElement ();
 676         stream.print (parm.name ());
 677       }
 678       // Step 2.  Add the context parameter if necessary. <d59297>
 679       if (m.contexts ().size () > 0)
 680       {
 681         if (!firstTime)
 682           stream.print (", ");
 683         stream.print ("$context");
 684       }
 685     }
 686     stream.println (TWO_INDENT + ");");
 687     stream.println (THREE_INDENT + "} finally {");
 688     stream.println (FOUR_INDENT + "_releaseReply ($in);");
 689     stream.println (THREE_INDENT + "}");
 690     if( localOptimization && !isAbstract ) {
 691         stream.println (TWO_INDENT + "}");
 692         writeStubBodyForLocalInvocation( className, methodName );
 693     }
 694 
 695   } // writeStubBody
 696 
 697 
 698   /**
 699    * This method writes the else part of the stub method invocation to
 700    * enable local invocation in case of collocation.
 701    * NOTE: This will only be invoked from writeStubBody.
 702    */
 703   private void writeStubBodyForLocalInvocation( String className,
 704       String methodName )
 705   {
 706     stream.println (TWO_INDENT + "else {" );
 707     stream.println (THREE_INDENT +
 708         "org.omg.CORBA.portable.ServantObject _so =");
 709     stream.println (FOUR_INDENT + "_servant_preinvoke(\"" + methodName +
 710                     "\", _opsClass);" );
 711     stream.println(THREE_INDENT + "if (_so == null ) {");
 712     stream.println(FOUR_INDENT + "continue;" );
 713     stream.println(THREE_INDENT + "}");
 714     stream.println(THREE_INDENT + className + "Operations _self =" );
 715     stream.println(FOUR_INDENT + "(" + className + "Operations) _so.servant;");
 716     stream.println(THREE_INDENT + "try {" );
 717     Enumeration parms = m.parameters ().elements ();
 718     if (m instanceof AttributeEntry)
 719     {
 720         // Local Method Name should drop _get_ or _set_ prefix for attribute
 721         // entry
 722         methodName = methodName.substring( ATTRIBUTE_METHOD_PREFIX_LENGTH );
 723     }
 724     boolean voidReturnType = (this.m.type() == null);
 725     if ( !voidReturnType ) {
 726         stream.println (FOUR_INDENT + Util.javaName (this.m.type ()) +
 727             " $result;");
 728     }
 729     if( !isValueInitializer() ) {
 730         if ( voidReturnType ) {
 731             stream.print(FOUR_INDENT + "_self." + methodName + "( " );
 732         } else {
 733             stream.print(FOUR_INDENT + "$result = _self." +
 734                      methodName + "( " );
 735         }
 736         while (parms.hasMoreElements ()) {
 737             ParameterEntry param = (ParameterEntry)parms.nextElement ();
 738             if( parms.hasMoreElements( ) ) {
 739                 stream.print( " " + param.name() +  "," );
 740             } else  {
 741                 stream.print( " " + param.name() );
 742             }
 743         }
 744         stream.print( ");" );
 745         stream.println( " " );
 746         if( voidReturnType ) {
 747             stream.println(FOUR_INDENT + "return;" );
 748         } else {
 749             stream.println(FOUR_INDENT + "return $result;" );
 750         }
 751     }
 752     stream.println(" ");
 753     stream.println (THREE_INDENT + "}" );
 754     stream.println (THREE_INDENT + "finally {" );
 755     stream.println (FOUR_INDENT + "_servant_postinvoke(_so);" );
 756     stream.println (THREE_INDENT + "}" );
 757     stream.println (TWO_INDENT + "}" );
 758     stream.println (ONE_INDENT + "}" );
 759   }
 760 
 761 
 762   protected void writeLocalStubBody (InterfaceEntry i)
 763   {
 764     // Step 1  Create a request
 765     String methodName = Util.stripLeadingUnderscores (m.name ());
 766     if (m instanceof AttributeEntry)
 767     {
 768       if (m.type () == null)          // if it's a modifier
 769         methodName = "_set_" + methodName;
 770       else
 771         methodName = "_get_" + methodName;
 772     }
 773     //stream.println ("    while(true) {");
 774     stream.println ("      org.omg.CORBA.portable.ServantObject $so = " +
 775                     "_servant_preinvoke (\"" + methodName + "\", " + "_opsClass);");
 776     //stream.println ("      if ($so == null) {");
 777     //stream.println ("          continue;");
 778     //stream.println ("      }");
 779     String opsName = i.name() + "Operations";
 780     stream.println ("      " + opsName + "  $self = " + "(" + opsName + ") " + "$so.servant;");
 781     stream.println ();
 782     stream.println ("      try {");
 783     stream.print ("         ");
 784     if (m.type () != null) // not a void method
 785         stream.print ("return ");
 786     stream.print ("$self." + m.name () + " (");
 787     {
 788         // write parm names
 789         boolean firstTime = true;
 790         Enumeration e = m.parameters ().elements ();
 791         while (e.hasMoreElements ())
 792         {
 793           if (firstTime)
 794             firstTime = false;
 795           else
 796             stream.print (", ");
 797           ParameterEntry parm = (ParameterEntry)e.nextElement ();
 798           stream.print (parm.name ());
 799         }
 800         // Step 2.  Add the context parameter if necessary. <d59297>
 801         if (m.contexts ().size () > 0)
 802         {
 803           if (!firstTime)
 804             stream.print (", ");
 805           stream.print ("$context");
 806         }
 807     }
 808     stream.println (");");
 809     //stream.println ("      } catch (org.omg.CORBA.portable.RemarshalException $rm) {");
 810     //stream.println ("         continue; ");
 811     stream.println ("      } finally {");
 812     stream.println ("          _servant_postinvoke ($so);");
 813     stream.println ("      }");
 814     //stream.println ("    }");
 815 
 816   } // writeLocalStubBody
 817 
 818 
 819 
 820   /**
 821    *
 822    **/
 823   private void writeInsert (String indent, String target, String source, SymtabEntry type, PrintWriter stream)
 824   {
 825     String typeName = type.name ();
 826     if (type instanceof PrimitiveEntry)
 827     {
 828       // RJB does something have to be done with TC offsets?
 829       if (typeName.equals ("long long"))
 830         stream.println (indent + source + ".insert_longlong (" + target + ");");
 831       else if (typeName.equals ("unsigned short"))
 832         stream.println (indent + source + ".insert_ushort (" + target + ");");
 833       else if (typeName.equals ("unsigned long"))
 834         stream.println (indent + source + ".insert_ulong (" + target + ");");
 835       else if (typeName.equals ("unsigned long long"))
 836         stream.println (indent + source + ".insert_ulonglong (" + target + ");");
 837       else
 838         stream.println (indent + source + ".insert_" + typeName + " (" + target + ");");
 839     }
 840     else if (type instanceof StringEntry)
 841       stream.println (indent + source + ".insert_" + typeName + " (" + target + ");");
 842     else
 843       stream.println (indent + Util.helperName (type, true) + ".insert (" + source + ", " + target + ");"); // <d61056>
 844   } // writeInsert
 845 
 846   /**
 847    *
 848    **/
 849   private void writeType (String indent, String name, SymtabEntry type, PrintWriter stream)
 850   {
 851     if (type instanceof PrimitiveEntry)
 852     {
 853       // RJB does something have to be done with TC offsets?
 854       if (type.name ().equals ("long long"))
 855         stream.println (indent + name + " (org.omg.CORBA.ORB.init ().get_primitive_tc (org.omg.CORBA.TCKind.tk_longlong));");
 856       else if (type.name ().equals ("unsigned short"))
 857         stream.println (indent + name + " (org.omg.CORBA.ORB.init ().get_primitive_tc (org.omg.CORBA.TCKind.tk_ushort));");
 858       else if (type.name ().equals ("unsigned long"))
 859         stream.println (indent + name + " (org.omg.CORBA.ORB.init ().get_primitive_tc (org.omg.CORBA.TCKind.tk_ulong));");
 860       else if (type.name ().equals ("unsigned long long"))
 861         stream.println (indent + name + " (org.omg.CORBA.ORB.init ().get_primitive_tc (org.omg.CORBA.TCKind.tk_ulonglong));");
 862       else
 863         stream.println (indent + name + " (org.omg.CORBA.ORB.init ().get_primitive_tc (org.omg.CORBA.TCKind.tk_" + type.name () + "));");
 864     }
 865     else if (type instanceof StringEntry)
 866     {
 867       StringEntry s = (StringEntry)type;
 868       Expression e  = s.maxSize ();
 869       if (e == null)
 870         stream.println (indent + name + " (org.omg.CORBA.ORB.init ().create_" + type.name () + "_tc (" + Util.parseExpression (e) + "));");
 871      else
 872         stream.println (indent + name + " (org.omg.CORBA.ORB.init ().create_" + type.name () + "_tc (0));");
 873     }
 874     else
 875       stream.println (indent + name + '(' + Util.helperName (type, true) + ".type ());"); // <d61056>
 876   } // writeType
 877 
 878   /**
 879    *
 880    **/
 881   private void writeExtract (String indent, String target, String source, SymtabEntry type, PrintWriter stream)
 882   {
 883     if (type instanceof PrimitiveEntry)
 884     {
 885       if (type.name ().equals ("long long"))
 886         stream.println (indent + target + " = " + source + ".extract_longlong ();");
 887       else if (type.name ().equals ("unsigned short"))
 888         stream.println (indent + target + " = " + source + ".extract_ushort ();");
 889       else if (type.name ().equals ("unsigned long"))
 890         stream.println (indent + target + " = " + source + ".extract_ulong ();");
 891       else if (type.name ().equals ("unsigned long long"))
 892         stream.println (indent + target + " = " + source + ".extract_ulonglong ();");
 893       else
 894         stream.println (indent + target + " = " + source + ".extract_" + type.name () + " ();");
 895     }
 896     else if (type instanceof StringEntry)
 897       stream.println (indent + target + " = " + source + ".extract_" + type.name () + " ();");
 898     else
 899       stream.println (indent + target + " = " + Util.helperName (type, true) + ".extract (" + source + ");"); // <d61056>
 900   } // writeExtract
 901 
 902   /**
 903    *
 904    **/
 905   private String writeExtract (String source, SymtabEntry type)
 906   {
 907     String extract;
 908     if (type instanceof PrimitiveEntry)
 909     {
 910       if (type.name ().equals ("long long"))
 911         extract = source + ".extract_longlong ()";
 912       else if (type.name ().equals ("unsigned short"))
 913         extract = source + ".extract_ushort ()";
 914       else if (type.name ().equals ("unsigned long"))
 915         extract = source + ".extract_ulong ()";
 916       else if (type.name ().equals ("unsigned long long"))
 917         extract = source + ".extract_ulonglong ()";
 918       else
 919         extract = source + ".extract_" + type.name () + " ()";
 920     }
 921     else if (type instanceof StringEntry)
 922       extract = source + ".extract_" + type.name () + " ()";
 923     else
 924       extract = Util.helperName (type, true) + ".extract (" + source + ')'; // <d61056>
 925     return extract;
 926   } // writeExtract
 927 
 928   /**
 929    *
 930    **/
 931   private void writeSkeletonBody ()
 932   {
 933     SymtabEntry mtype = Util.typeOf (m.type ());
 934 
 935     // If there is a return value, increment the appropriate counter
 936     stream.print ("    ");
 937     if (mtype != null)
 938       stream.print ("return ");
 939     stream.print ("_impl." + m.name () + '(');
 940 
 941     // Load the parameters
 942     Enumeration parms = m.parameters ().elements ();
 943     boolean first = true;
 944     while (parms.hasMoreElements ())
 945     {
 946       ParameterEntry parm = (ParameterEntry)parms.nextElement ();
 947       if (first)
 948         first = false;
 949       else
 950         stream.print (", ");
 951       stream.print (parm.name ());
 952     }
 953     if (m.contexts ().size () != 0)
 954     {
 955       if (!first)
 956         stream.print (", ");
 957       stream.print ("$context");
 958     }
 959 
 960     stream.println (");");
 961   } // writeSkeletonBody
 962 
 963   /**
 964    *
 965    **/
 966   protected String passType (int passType)
 967   {
 968     String type;
 969     switch (passType)
 970     {
 971       case ParameterEntry.Inout:
 972         type = "org.omg.CORBA.ARG_INOUT.value";
 973         break;
 974       case ParameterEntry.Out:
 975         type = "org.omg.CORBA.ARG_OUT.value";
 976         break;
 977       case ParameterEntry.In:
 978       default:
 979         type = "org.omg.CORBA.ARG_IN.value";
 980         break;
 981     }
 982     return type;
 983   } // passType
 984 
 985   /**
 986    * This is only used by AttributeGen.  The java mapping says
 987    * the names should be getXXX and setXXX, but CORBA says they
 988    * should be _get_XXX and _set_XXX.  this.name () will be
 989    * getXXX.  realName is set by AttributeGen to _get_XXX.
 990    **/
 991   protected void serverMethodName (String name)
 992   {
 993     realName = (name == null) ? "" : name;
 994   } // serverMethodName
 995 
 996   /**
 997    *
 998    **/
 999   private void writeOutputStreamWrite (String indent, String oStream, String name, SymtabEntry type, PrintWriter stream)
1000   {
1001     String typeName = type.name ();
1002     stream.print (indent);
1003     if (type instanceof PrimitiveEntry)
1004     {
1005       if (typeName.equals ("long long"))
1006         stream.println (oStream + ".write_longlong (" + name +");");
1007       else if (typeName.equals ("unsigned short"))
1008         stream.println (oStream + ".write_ushort (" + name + ");");
1009       else if (typeName.equals ("unsigned long"))
1010         stream.println (oStream + ".write_ulong (" + name + ");");
1011       else if (typeName.equals ("unsigned long long"))
1012         stream.println (oStream + ".write_ulonglong (" + name + ");");
1013       else
1014         stream.println (oStream + ".write_" + typeName + " (" + name + ");");
1015     }
1016     else if (type instanceof StringEntry)
1017       stream.println (oStream + ".write_" + typeName + " (" + name + ");");
1018     else if (type instanceof SequenceEntry)
1019       stream.println (oStream + ".write_" + type.type().name() + " (" + name + ");");
1020     else if (type instanceof ValueBoxEntry)
1021     {
1022       ValueBoxEntry v = (ValueBoxEntry) type;
1023       TypedefEntry member = ((InterfaceState) v.state ().elementAt (0)).entry;
1024       SymtabEntry mType = member.type ();
1025 
1026       // if write value to the boxed holder indicated by the name ending with ".value"
1027       if (mType instanceof PrimitiveEntry && name.endsWith (".value"))
1028         stream.println (Util.helperName (type, true) + ".write (" + oStream + ", "  // <d61056>
1029         + " new " + Util.javaQualifiedName (type) + " (" + name + "));"); //<d60929>
1030       else
1031         stream.println (Util.helperName (type, true) + ".write (" + oStream + ", " + name + ");"); //<d60929> // <d61056>
1032     }
1033     else if (type instanceof ValueEntry)
1034         stream.println (Util.helperName (type, true) + ".write (" + oStream + ", " + name + ");"); //<d60929> // <d61056>
1035     else
1036       stream.println (Util.helperName (type, true) + ".write (" + oStream + ", " + name + ");"); // <d61056>
1037   } // writeOutputStreamWrite
1038 
1039   /**
1040    *
1041    **/
1042   private String writeInputStreamRead (String source, SymtabEntry type)
1043   {
1044     String read = "";
1045     if (type instanceof PrimitiveEntry)
1046     {
1047       if (type.name ().equals ("long long"))
1048         read = source + ".read_longlong ()";
1049       else if (type.name ().equals ("unsigned short"))
1050         read = source + ".read_ushort ()";
1051       else if (type.name ().equals ("unsigned long"))
1052         read = source + ".read_ulong ()";
1053       else if (type.name ().equals ("unsigned long long"))
1054         read = source + ".read_ulonglong ()";
1055       else
1056         read = source + ".read_" + type.name () + " ()";
1057     }
1058     else if (type instanceof StringEntry)
1059       read = source + ".read_" + type.name () + " ()";
1060     else
1061       read = Util.helperName (type, true) + ".read (" + source + ')'; // <d61056>
1062     return read;
1063   } // writeInputStreamRead
1064 
1065   /**
1066    *
1067    **/
1068   protected void writeMethodCall (String indent)
1069   {
1070     SymtabEntry mtype = Util.typeOf (m.type ());
1071     if (mtype == null)
1072       stream.print (indent + "this." + m.name () + " (");
1073     else
1074       stream.print (indent + "$result = this." + m.name () + " (");
1075   } // writeMethodCall
1076 
1077   /**
1078    *
1079    **/
1080   protected void writeCreateReply(String indent){
1081     stream.println(indent + "out = $rh.createReply();");
1082   }
1083 
1084   protected int           methodIndex = 0;
1085   protected String        realName    = "";
1086   protected Hashtable     symbolTable = null;
1087   protected MethodEntry   m           = null;
1088   protected PrintWriter   stream      = null;
1089   protected boolean localOptimization = false;
1090   protected boolean isAbstract        = false;
1091 } // class MethodGen