MethodGen.java revision 608:7e06bf1dcb09
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
36package 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
55import java.io.PrintWriter;
56import java.util.Enumeration;
57import java.util.Hashtable;
58
59import com.sun.tools.corba.se.idl.EnumEntry;
60import com.sun.tools.corba.se.idl.ExceptionEntry;
61import com.sun.tools.corba.se.idl.InterfaceEntry;
62import com.sun.tools.corba.se.idl.MethodEntry;
63import com.sun.tools.corba.se.idl.ParameterEntry;
64import com.sun.tools.corba.se.idl.PrimitiveEntry;
65import com.sun.tools.corba.se.idl.StringEntry;
66import com.sun.tools.corba.se.idl.SymtabEntry;
67import com.sun.tools.corba.se.idl.SequenceEntry;
68import com.sun.tools.corba.se.idl.ValueEntry;
69import com.sun.tools.corba.se.idl.ValueBoxEntry;
70import com.sun.tools.corba.se.idl.InterfaceState;
71import com.sun.tools.corba.se.idl.TypedefEntry;
72import com.sun.tools.corba.se.idl.AttributeEntry;
73
74import com.sun.tools.corba.se.idl.constExpr.Expression;
75
76/**
77 *
78 **/
79public 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
1092