View Javadoc
1   /*
2    * Copyright (c) 1999, 2001, 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  // -The ctor should really throw an exception, but then it must have a
40  //  throws clause. How much of a ripple effect is this?
41  // -F46082.51<daz> Remove -stateful feature.
42  // -D60929   <klr> Update for RTF2.4 changes
43  // -D61056   <klr> Use Util.helperName
44  // -D62014   <klr> Move const definitions from signature to operations interf.
45  // -D62310   <klr> Fix declaration of interfaces extending abstract intf.
46  // -D62023   <klr> Move const definitions back from operations to signature.
47  
48  import java.io.PrintWriter;
49  import java.util.Enumeration;
50  import java.util.Hashtable;
51  import java.util.Vector;
52  
53  import com.sun.tools.corba.se.idl.GenFileStream;
54  import com.sun.tools.corba.se.idl.ConstEntry;
55  import com.sun.tools.corba.se.idl.InterfaceEntry;
56  import com.sun.tools.corba.se.idl.InterfaceState;
57  import com.sun.tools.corba.se.idl.MethodEntry;
58  import com.sun.tools.corba.se.idl.PrimitiveEntry;
59  import com.sun.tools.corba.se.idl.SequenceEntry;
60  import com.sun.tools.corba.se.idl.StringEntry;
61  import com.sun.tools.corba.se.idl.SymtabEntry;
62  import com.sun.tools.corba.se.idl.TypedefEntry;
63  
64  /**
65   *
66   **/
67  public class InterfaceGen implements com.sun.tools.corba.se.idl.InterfaceGen, JavaGenerator
68  {
69    /**
70     * Public zero-argument constructor.
71     **/
72    public InterfaceGen ()
73    {
74      //emit = ((Arguments)Compile.compiler.arguments).emit;
75      //factories = (Factories)Compile.compiler.factories ();
76    } // ctor
77  
78    /**
79     * Generate the interface and all the files associated with it.
80     * Provides general algorithm for binding generation:
81     * 1.) Initialize symbol table and symbol table entry members, common to all generators.
82     * 2.) Generate the skeleton if required by calling generateSkeletn ()
83     * 3.) Generate the holder by calling generateHolder ()
84     * 4.) Generate the helper by calling generateHelper ()
85     * 5.) Generate the stub if required by calling generateStub ()
86     * 6.) Generate the interface by calling generateInterface ()
87     **/
88    public void generate (Hashtable symbolTable, InterfaceEntry i, PrintWriter stream)
89    {
90      if (!isPseudo(i))
91      {
92        this.symbolTable = symbolTable;
93        this.i           = i;
94        init ();
95  
96        // for sun_local pragma, just generate the signature and operations interfaces
97        // for sun_localservant pragma, generate the Local Stubs, and Skel, should not
98        // have _invoke defined.
99        // for local (is_local()) case, generate only Helpers and Holder, where they
100       // have been modified to throw appropriate exceptions for read and write, and
101       // narrow is modified to not invoke _is_a
102 
103       if (! (i.isLocalSignature())) {
104           // generate the stubs and skeletons for non-local interfaces
105           if (! (i.isLocal())) {
106               // for local servant case just generate the skeleton, but
107               // for others generate the stubs also
108               generateSkeleton ();
109 
110               // _REVISIT_, Whenever there is time restructure the code to
111               // encapsulate stub and skeleton generation.
112 
113               // If the option is -fallTie then generate the Tie class first
114               // and then generate the ImplBase class to make the generation
115               // complete for the Hierarchy.
116               Arguments theArguments = (Arguments)Compile.compiler.arguments;
117               if( (theArguments.TIEServer == true )
118                 &&(theArguments.emit == theArguments.All ) )
119               {
120                   theArguments.TIEServer = false;
121                   // Generate the ImplBase class
122                   generateSkeleton ();
123                   // Revert in case file contains multiple interfaces
124                   theArguments.TIEServer = true;
125               }
126               generateStub ();
127           }
128           generateHolder ();
129           generateHelper ();
130       }
131       intfType = SIGNATURE;
132       generateInterface ();
133       intfType = OPERATIONS;
134       generateInterface ();
135       intfType = 0;
136     }
137   } // generate
138 
139   /**
140    * Initialize members unique to this generator.
141    **/
142   protected void init ()
143   {
144     emit = ((Arguments)Compile.compiler.arguments).emit;
145     factories = (Factories)Compile.compiler.factories ();
146   } // init
147 
148   /**
149    * Generate a Skeleton when the user does not want just the client-side code.
150    **/
151   protected void generateSkeleton ()
152   {
153     // <f46082.51> Remove -stateful feature.
154     // The Skeleton is generated only when the user doesn't want
155     // JUST the client code OR when the interface is stateful
156     //if (emit != Arguments.Client || i.state () != null)
157     //  factories.skeleton ().generate (symbolTable, i);
158     if (emit != Arguments.Client)
159       factories.skeleton ().generate (symbolTable, i);
160   } // generateSkeleton
161 
162   /**
163    * Generate a Stub when the user does not want just the server-side code.
164    **/
165   protected void generateStub ()
166   {
167     // <klr> According to Simon on 10/28/98, we should generate stubs for
168     // abstract interfaces too.
169     if (emit != Arguments.Server /* && !i.isAbstract () */)
170       factories.stub ().generate (symbolTable, i);
171   } // generateStub
172 
173   /**
174    * Generate a Helper when the user does not want just the server-side code.
175    **/
176   protected void generateHelper ()
177   {
178     if (emit != Arguments.Server)
179       factories.helper ().generate (symbolTable, i);
180   } // generateHelper
181 
182   /**
183    * Generate a Holder when the user does not want just the server-side code.
184    **/
185   protected void generateHolder ()
186   {
187     if (emit != Arguments.Server)
188       factories.holder ().generate (symbolTable, i);
189   } // generateHolder
190 
191   /**
192    * Generate the interface. Provides general algorithm for binding generation:
193    * 1.) Initialize members unique to this generator. - init ()
194    * 2.) Open print stream - openStream ()
195    * 3.) Write class heading (package, prologue, class statement, open curly - writeHeading ()
196    * 4.) Write class body (member data and methods) - write*Body ()
197    * 5.) Write class closing (close curly) - writeClosing ()
198    * 6.) Close the print stream - closeStream ()
199    *
200    * For CORBA 2.3, interfaces are mapped to Operations and Signature
201    * interfaces. The Operations interface contains the method definitions.
202    * The Signature interface extends the Operations interface and adds
203    * CORBA::Object. <klr>
204    **/
205   protected void generateInterface ()
206   {
207     init ();
208     openStream ();
209     if (stream == null)
210       return;
211     writeHeading ();
212     if (intfType == OPERATIONS)
213       writeOperationsBody ();
214     if (intfType == SIGNATURE)
215       writeSignatureBody ();
216     writeClosing ();
217     closeStream ();
218   } // generateInterface
219 
220   /**
221    *
222    **/
223   protected void openStream ()
224   {
225     if (i.isAbstract () || intfType == SIGNATURE)
226        stream = Util.stream (i, ".java");
227     else if (intfType == OPERATIONS)
228        stream = Util.stream (i, "Operations.java");
229   } // openStream
230 
231   /**
232    *
233    **/
234   protected void writeHeading ()
235   {
236     Util.writePackage (stream, i, Util.TypeFile);
237     Util.writeProlog (stream, ((GenFileStream)stream).name ());
238 
239     // Transfer interface comment to target <31jul1997>.
240     if (i.comment () != null)
241       i.comment ().generate ("", stream);
242 
243     String className = i.name ();
244 //  if (((Arguments)Compile.compiler.arguments).TIEServer)
245 //  {
246 //    // For the delegate model, don't make interface a subclass of CORBA.Object
247 //    stream.print ("public interface " + className);
248 //    boolean firstTime = true;
249 //    for (int ii = 0; ii < i.derivedFrom ().size (); ++ii)
250 //    {
251 //      SymtabEntry parent = (SymtabEntry)i.derivedFrom ().elementAt (ii);
252 //      if (!parent.fullName ().equals ("org/omg/CORBA/Object"))
253 //      {
254 //        if (firstTime)
255 //        {
256 //          firstTime = false;
257 //          stream.print (" extends ");
258 //        }
259 //        else
260 //          stream.print (", ");
261 //        stream.print (Util.javaName (parent));
262 //      }
263 //    }
264 //    if (i.derivedFrom ().size () > 0)
265 //      stream.print (", ");
266 //    stream.print ("org.omg.CORBA.portable.IDLEntity ");
267 //  }
268 //
269 //  else
270 //  {
271       if (intfType == SIGNATURE)
272          writeSignatureHeading ();
273       else if (intfType == OPERATIONS)
274          writeOperationsHeading ();
275 //  }
276 
277     stream.println ();
278     stream.println ('{');
279   } // writeHeading
280 
281   /**
282    *
283    **/
284   protected void writeSignatureHeading ()
285   {
286     String className = i.name ();
287     stream.print ("public interface " + className + " extends " + className + "Operations, ");
288     boolean firstTime = true;
289     boolean hasNonAbstractParent = false; // <d62310-klr>
290     for (int k = 0; k < i.derivedFrom ().size (); ++k)
291     {
292       if (firstTime)
293         firstTime = false;
294       else
295         stream.print (", ");
296       InterfaceEntry parent = (InterfaceEntry)i.derivedFrom ().elementAt (k);
297       stream.print (Util.javaName (parent));
298       if (! parent.isAbstract ()) // <d62310-klr>
299         hasNonAbstractParent = true; // <d62310-klr>
300     }
301     // <d62310-klr> - begin
302     // If this interface extends only abstract interfaces,
303     // it should extend both org.omg.CORBA.Object and IDLEntity.
304     if (!hasNonAbstractParent) {
305       stream.print (", org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity ");
306     }
307     else {
308     // <d62310-klr> - end
309         // extends IDLEntity if there's only one default parent - CORBA.Object
310         if (i.derivedFrom ().size () == 1)
311           stream.print (", org.omg.CORBA.portable.IDLEntity ");
312     }
313   } // writeSignatureHeading
314 
315   /**
316    *
317    **/
318   protected void writeOperationsHeading ()
319   {
320     stream.print ("public interface " + i.name ());
321     if ( !i.isAbstract ())
322       stream.print ("Operations ");
323     else {
324         // <d60929> - base abstract interfaces extend AbstractBase
325         // changed to IDLEntity by SCN per latest spec...
326         if (i.derivedFrom ().size () == 0)
327           stream.print (" extends org.omg.CORBA.portable.IDLEntity");
328     }
329 
330     boolean firstTime = true;
331     for (int k = 0; k < i.derivedFrom ().size (); ++k)
332     {
333       InterfaceEntry parent = (InterfaceEntry) i.derivedFrom ().elementAt (k);
334       String parentName = Util.javaName (parent);
335 
336       // ignore the default parent - CORBA.Object
337       if (parentName.equals ("org.omg.CORBA.Object"))
338           continue;
339 
340       if (firstTime)
341       {
342         firstTime = false;
343         stream.print (" extends ");
344       }
345       else
346         stream.print (", ");
347 
348       // Don't append suffix Operations to the parents of abstract interface
349       // or to the abstract parents of regular interface
350       if (parent.isAbstract () || i.isAbstract ())
351         stream.print (parentName);
352       else
353         stream.print (parentName + "Operations");
354     }
355   } // writeOperationsHeading
356 
357 
358   /**
359    *
360    **/
361   protected void writeOperationsBody ()
362   {
363     // Generate everything but constants
364     Enumeration e = i.contained ().elements ();
365     while (e.hasMoreElements ())
366     {
367       SymtabEntry contained = (SymtabEntry)e.nextElement ();
368       if (contained instanceof MethodEntry)
369       {
370         MethodEntry element = (MethodEntry)contained;
371         ((MethodGen)element.generator ()).interfaceMethod (symbolTable, element, stream);
372       }
373       else
374         if ( !(contained instanceof ConstEntry))
375           contained.generate (symbolTable, stream);
376     }
377   } // writeOperationsBody
378 
379   /**
380    *
381    **/
382   protected void writeSignatureBody ()
383   {
384     // Generate only constants
385     Enumeration e = i.contained ().elements ();
386     while (e.hasMoreElements ())
387     {
388       SymtabEntry contained = (SymtabEntry)e.nextElement ();
389       if (contained instanceof ConstEntry)
390         contained.generate (symbolTable, stream);
391     }
392   } // writeSignatureBody
393 
394   /**
395    *
396    **/
397   protected void writeClosing ()
398   {
399     String intfName = i.name ();
400     if ( !i.isAbstract () && intfType == OPERATIONS)
401       intfName = intfName + "Operations";
402     stream.println ("} // interface " + intfName);
403   } // writeClosing
404 
405   /**
406    *
407    **/
408   protected void closeStream ()
409   {
410     stream.close ();
411   } // closeStream
412 
413   ///////////////
414   // From JavaGenerator
415 
416   // <f46082.51> Remove -stateful feature.
417   /*
418   public int helperType (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream)
419   {
420     InterfaceEntry i = (InterfaceEntry)entry;
421     if (i.state () != null && i.state ().size () > 0)
422       index = structHelperType (index, indent, tcoffsets, name, entry, stream);
423     else
424     {
425       tcoffsets.set (entry);
426       if (entry.fullName ().equals ("org/omg/CORBA/Object"))
427         stream.println (indent + name
428             + " = org.omg.CORBA.ORB.init ().get_primitive_tc (org.omg.CORBA.TCKind.tk_objref);");
429       else
430         stream.println (indent + name
431             // <54697>
432             //+ " = org.omg.CORBA.ORB.init ().create_interface_tc (_id, "
433             + " = org.omg.CORBA.ORB.init ().create_interface_tc (" + Util.helperName (i, true) + ".id (), " // <d61056>
434             + '\"' + Util.stripLeadingUnderscores (entry.name ()) + "\");");
435     }
436     return index;
437   } // helperType
438   */
439   public int helperType (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream)
440   {
441     InterfaceEntry i = (InterfaceEntry)entry;
442     tcoffsets.set (entry);
443     if (entry.fullName ().equals ("org/omg/CORBA/Object"))
444       stream.println (indent + name
445           + " = org.omg.CORBA.ORB.init ().get_primitive_tc (org.omg.CORBA.TCKind.tk_objref);");
446     else
447       stream.println (indent + name
448           // <54697>
449           //+ " = org.omg.CORBA.ORB.init ().create_interface_tc (_id, "
450           + " = org.omg.CORBA.ORB.init ().create_interface_tc (" + Util.helperName (i, true) + ".id (), " // <d61056>
451           + '\"' + Util.stripLeadingUnderscores (entry.name ()) + "\");");
452     return index;
453   } // helperType
454 
455   public int type (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream) {
456     stream.println (indent + name + " = " + Util.helperName (entry, true) + ".type ();"); // <d61056>
457     return index;
458   } // type
459 
460   // <f46082.51> Remove -stateful feature.
461   /*
462   public void helperRead (String entryName, SymtabEntry entry, PrintWriter stream)
463   {
464     InterfaceEntry i = (InterfaceEntry)entry;
465     if (i.state () != null)
466       structHelperRead (entryName, i, stream);
467     else
468     {
469       if (i.isAbstract ())
470          stream.println ("    return narrow (((org.omg.CORBA_2_3.portable.InputStream)istream).read_abstract_interface (_" + i.name () + "Stub.class));"); // <d60929>
471       else
472          stream.println ("    return narrow (istream.read_Object (_" + i.name () + "Stub.class));");
473     }
474   } // helperRead
475 
476   */
477   public void helperRead (String entryName, SymtabEntry entry, PrintWriter stream)
478   {
479     InterfaceEntry i = (InterfaceEntry)entry;
480     if (i.isAbstract ())
481       stream.println ("    return narrow (((org.omg.CORBA_2_3.portable.InputStream)istream).read_abstract_interface (_" + i.name () + "Stub.class));"); // <d60929>
482     else
483       stream.println ("    return narrow (istream.read_Object (_" + i.name () + "Stub.class));");
484   } // helperRead
485 
486   // <f46082.51> Remove -stateful feature.
487   /*
488   public void helperWrite (SymtabEntry entry, PrintWriter stream)
489   {
490     InterfaceEntry i = (InterfaceEntry)entry;
491     if (i.state () != null)
492       structHelperWrite (entry, stream);
493     else
494       write (0, "    ", "value", entry, stream);
495   } // helperWrite
496   */
497   public void helperWrite (SymtabEntry entry, PrintWriter stream)
498   {
499     write (0, "    ", "value", entry, stream);
500   } // helperWrite
501 
502   // <f46082.51> Remove -stateful feature.
503   /*
504   public int read (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
505   {
506     InterfaceEntry i = (InterfaceEntry)entry;
507     if (i.state () != null)
508       index = structRead (index, indent, name, i, stream);
509     else
510     {
511       if (entry.fullName ().equals ("org/omg/CORBA/Object"))
512         stream.println (indent + name + " = istream.read_Object (_" + i.name () + "Stub.class);");
513       else
514         stream.println (indent + name + " = " + Util.helperName (entry, false) + ".narrow (istream.read_Object (_" + i.name () + "Stub.class));"); // <d61056>
515     }
516     return index;
517   } // read
518   */
519   public int read (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
520   {
521     InterfaceEntry i = (InterfaceEntry)entry;
522     if (entry.fullName ().equals ("org/omg/CORBA/Object"))
523       stream.println (indent + name + " = istream.read_Object (_" + i.name () + "Stub.class);");
524     else
525       stream.println (indent + name + " = " + Util.helperName (entry, false) + ".narrow (istream.read_Object (_" + i.name () + "Stub.class));"); // <d61056>
526     return index;
527   } // read
528 
529   // <f46082.51> Remove -stateful feature.
530   /*
531   public int write (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
532   {
533     InterfaceEntry i = (InterfaceEntry)entry;
534     if (i.state () != null)
535       index = structWrite (index, indent, name, entry, stream);
536     else
537     {
538       if (i.isAbstract ())
539          stream.println (indent + "((org.omg.CORBA_2_3.portable.OutputStream)ostream).write_abstract_interface ((java.lang.Object) " + name + ");"); // <d60929>
540       else
541          stream.println (indent + "ostream.write_Object ((org.omg.CORBA.Object) " + name + ");");
542     }
543     return index;
544   } // write
545   */
546   public int write (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
547   {
548     InterfaceEntry i = (InterfaceEntry)entry;
549     if (i.isAbstract ())
550       stream.println (indent + "((org.omg.CORBA_2_3.portable.OutputStream)ostream).write_abstract_interface ((java.lang.Object) " + name + ");"); // <d60929>
551     else
552       stream.println (indent + "ostream.write_Object ((org.omg.CORBA.Object) " + name + ");");
553     return index;
554   } // write
555 
556   // <f46082.51> Remove -stateful feature.
557   /*
558   // These methods are cobbled from StructGen.  Stateful interfaces
559   // are sent across the wire as if they were structs, with the first
560   // element being a string - the Java name of the class.
561 
562   public int structHelperType (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream)
563   {
564     TCOffsets innerOffsets = new TCOffsets ();
565     innerOffsets.set (entry);
566     int offsetForStruct = innerOffsets.currentOffset ();
567     InterfaceEntry i = (InterfaceEntry)entry;
568     String membersName = "_members" + index++;
569     Vector state = i.state ();
570     stream.println (indent + "org.omg.CORBA.StructMember[] " + membersName + " = new org.omg.CORBA.StructMember [" + (state.size () + 1) + "];");
571     String tcOfMembers = "_tcOf" + membersName;
572     stream.println (indent + "org.omg.CORBA.TypeCode " + tcOfMembers + ';');
573 
574     // The name string is the first element of the struct
575     String memberName = "_name";
576     StringEntry stringEntry = Compile.compiler.factory.stringEntry ();
577     index = ((JavaGenerator)stringEntry.generator ()).helperType (index, indent, innerOffsets, tcOfMembers, stringEntry, stream);
578     stream.println (indent + membersName + "[0] = new org.omg.CORBA.StructMember (");
579     stream.println (indent + "  \"" + memberName + "\",");
580     stream.println (indent + "  " + tcOfMembers + ',');
581     stream.println (indent + "  null);");
582     int offsetSoFar = innerOffsets.currentOffset ();
583     innerOffsets = new TCOffsets ();
584     innerOffsets.set (entry);
585     innerOffsets.bumpCurrentOffset (offsetSoFar - offsetForStruct);
586 
587     for (int idx = 0; idx < state.size (); ++idx)
588     {
589       TypedefEntry member = ((InterfaceState)state.elementAt (idx)).entry;
590       memberName = member.name ();
591       index = ((JavaGenerator)member.generator ()).helperType (index, indent, innerOffsets, tcOfMembers, member, stream);
592       stream.println (indent + membersName + '[' + (idx + 1) + "] = new org.omg.CORBA.StructMember (");
593       stream.println (indent + "  \"" + memberName + "\",");
594       stream.println (indent + "  " + tcOfMembers + ',');
595       stream.println (indent + "  null);");
596       offsetSoFar = innerOffsets.currentOffset ();
597       innerOffsets = new TCOffsets ();
598       innerOffsets.set (entry);
599       innerOffsets.bumpCurrentOffset (offsetSoFar - offsetForStruct);
600     }
601     tcoffsets.bumpCurrentOffset (innerOffsets.currentOffset ());
602     stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_struct_tc (id (), \"" + entry.name () + "\", " + membersName + ");");
603     return index;
604   } // structHelperType
605 
606   public void structHelperRead (String entryName, InterfaceEntry entry, PrintWriter stream)
607   {
608     String impl = implName ((InterfaceEntry)entry);
609     stream.println ("      " + Util.javaStatefulName (entry) + " value = null;");
610     structRead (0, "      ", "value", entry, stream);
611     stream.println ("      return value;");
612   } // structHelperRead
613 
614   private String implName (InterfaceEntry entry)
615   {
616     String name;
617     if (entry.container ().name ().equals (""))
618       name =  '_' + entry.name () + "Impl";
619     else
620       name = Util.containerFullName (entry.container ()) + "._" + entry.name () + "Impl";
621     return name.replace ('/', '.');
622   } // implName
623 
624   public int structRead (int index, String indent, String name, InterfaceEntry entry, PrintWriter stream)
625   {
626     // The first element will be the name of the Java implementation class.
627     String stringName = "_name" + index++;
628     stream.println (indent + "String " + stringName + " = istream.read_string ();");
629     stream.println (indent + "try");
630     stream.println (indent + "{");
631     stream.println (indent + "  " + name + " = (" + Util.javaStatefulName (entry) + ")com.sun.CORBA.iiop.ORB.getImpl (" + stringName + ".replace ('/', '.'));");
632     stream.println (indent + "}");
633     stream.println (indent + "catch (Exception e)");
634     stream.println (indent + "{");
635     stream.println (indent + "  " + name + " = null;");
636     stream.println (indent + "}");
637     stream.println (indent + "if (" + name + " == null)");
638     stream.println (indent + "  throw new org.omg.CORBA.NO_IMPLEMENT (0, org.omg.CORBA.CompletionStatus.COMPLETED_NO);");
639     stream.println ();
640 
641     stream.println (indent + "if (!" + stringName + ".equals (\"" + entry.fullName () + "\"))");
642     stream.println (indent + '{');
643     stream.println (indent + "  Class _cls = " + name + ".getClass ();");
644     stream.println (indent + "  boolean _found = false;");
645     stream.println (indent + "  while (!_found && _cls != null)");
646     stream.println (indent + "  {");
647     stream.println (indent + "    Class[] interfaces = _cls.getInterfaces ();");
648     stream.println (indent + "    for (int i = 0; i < interfaces.length; ++i)");
649     stream.println (indent + "      if (interfaces[i].getName ().indexOf (\"State\") > 0)");
650     stream.println (indent + "      {");
651     stream.println (indent + "        _cls = interfaces[i];");
652     stream.println (indent + "        _found = true;");
653     stream.println (indent + "        break;");
654     stream.println (indent + "      }");
655     stream.println (indent + "    if (!_found)");
656     stream.println (indent + "      _cls = _cls.getSuperclass ();");
657     stream.println (indent + "  }");
658     stream.println (indent + "  if (_cls == null)");
659     stream.println (indent + "    throw new org.omg.CORBA.NO_IMPLEMENT (0, org.omg.CORBA.CompletionStatus.COMPLETED_NO);");
660     stream.println ();
661     stream.println (indent + "  String _className = _cls.getName ();");
662     stream.println (indent + "  int _index = _className.lastIndexOf ('.');");
663     stream.println (indent + "  String _helperName = _className.substring (0, _index + 1) + _className.substring (_index + 2, _className.length () - 5) + \"Helper\"; // 5 == \"State\".length");
664     stream.println (indent + "  try");
665     stream.println (indent + "  {");
666     stream.println (indent + "    Class _helperClass = Class.forName (_helperName);");
667     stream.println (indent + "    Class[] _formalParms = new Class [1];");
668     stream.println (indent + "    _formalParms[0] = Class.forName (\"org.omg.CORBA.portable.InputStream\");");
669     stream.println (indent + "    java.lang.reflect.Method _read = _helperClass.getMethod (\"read\", _formalParms);");
670     stream.println (indent + "    Object[] _actualParms = new Object [1];");
671     stream.println (indent + "    _actualParms[0] = istream;");
672     stream.println (indent + "      " + name + " = (" + Util.javaStatefulName (entry) + ")_read.invoke (null, _actualParms);");
673     stream.println (indent + "  }");
674     stream.println (indent + "  catch (Exception e)");
675     stream.println (indent + "  {");
676     stream.println (indent + "    throw new org.omg.CORBA.NO_IMPLEMENT (0, org.omg.CORBA.CompletionStatus.COMPLETED_NO);");
677     stream.println (indent + "  }");
678     stream.println (indent + '}');
679 
680     // instantiate an implementation
681     stream.println (indent + "else");
682     stream.println (indent + '{');
683 
684     // Load the state
685     readState (index, indent, name, (InterfaceEntry)entry, stream);
686 
687     stream.println (indent + '}');
688     return index;
689   } // structRead
690 
691   private void readState (int index, String indent, String name, InterfaceEntry entry, PrintWriter stream)
692   {
693     // First write the state from all parents
694     Enumeration e = entry.derivedFrom ().elements ();
695     while (e.hasMoreElements ())
696     {
697       InterfaceEntry parent = (InterfaceEntry)e.nextElement ();
698       if (parent.state () != null)
699       {
700         if (parent.state ().size () > 0)
701           readState (index, indent, name, parent, stream);
702         break;
703       }
704     }
705 
706     // Now write the state for the local entry
707     e = entry.state ().elements ();
708     while (e.hasMoreElements ())
709     {
710       TypedefEntry member = ((InterfaceState)e.nextElement ()).entry;
711       String tmpName = '_' + member.name () + "Tmp";
712       Util.writeInitializer (indent + "  ", tmpName, "", member, stream);
713       if (!member.arrayInfo ().isEmpty () || member.type () instanceof SequenceEntry || member.type () instanceof PrimitiveEntry || member.type () instanceof StringEntry)
714         index = ((JavaGenerator)member.generator ()).read (index, indent + "  ", tmpName, member, stream);
715       else
716         stream.println (indent + "  " + tmpName + " = " + Util.helperName (member.type (), true) + ".read (istream);"); // <d61056>
717       stream.println (indent + "  " + name + '.' + member.name () + " (" + tmpName + ");");
718     }
719   } // readState
720 
721   public void structHelperWrite (SymtabEntry entry, PrintWriter stream)
722   {
723     structWrite (0, "      ", "value", entry, stream);
724   } // structHelperWrite
725 
726   public int structWrite (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
727   {
728     // The first element of the struct must be the name of the real interface.
729     stream.println (indent + "Class _cls = " + name + ".getClass ();");
730     stream.println (indent + "boolean _found = false;");
731     stream.println (indent + "while (!_found && _cls != null)");
732     stream.println (indent + "{");
733     stream.println (indent + "  Class[] interfaces = _cls.getInterfaces ();");
734     stream.println (indent + "  for (int i = 0; i < interfaces.length; ++i)");
735     stream.println (indent + "    if (interfaces[i].getName ().indexOf (\"State\") > 0)");
736     stream.println (indent + "    {");
737     stream.println (indent + "      _cls = interfaces[i];");
738     stream.println (indent + "      _found = true;");
739     stream.println (indent + "      break;");
740     stream.println (indent + "    }");
741     stream.println (indent + "  if (!_found)");
742     stream.println (indent + "    _cls = _cls.getSuperclass ();");
743     stream.println (indent + '}');
744     stream.println ();
745     stream.println (indent + "if (_cls == null)");
746     stream.println (indent + "  throw new org.omg.CORBA.MARSHAL (0, org.omg.CORBA.CompletionStatus.COMPLETED_NO);");
747     stream.println ();
748     stream.println (indent + "String _className = _cls.getName ();");
749     stream.println (indent + "int _index = _className.lastIndexOf ('.');");
750     stream.println (indent + "String _interfaceName = _className.substring (0, _index + 1) + _className.substring (_index + 2, _className.length () - 5); // 5 == \"State\".length");
751     stream.println (indent + "ostream.write_string (_interfaceName.replace ('.', '/'));");
752 
753     // If _className != Util.javaName (entry), then call that class's helper class.
754     stream.println ();
755     stream.println (indent + "if (!_interfaceName.equals (\"" + Util.javaName (entry) + "\"))");
756     stream.println (indent + '{');
757     stream.println (indent + "  try");
758     stream.println (indent + "  {");
759     stream.println (indent + "    Class _helperClass = Class.forName (_interfaceName + \"Helper\");");
760     stream.println (indent + "    Class[] _formalParms = new Class [2];");
761     stream.println (indent + "    _formalParms[0] = Class.forName (\"org.omg.CORBA.portable.OutputStream\");");
762     stream.println (indent + "    _formalParms[1] = _cls;");
763     stream.println (indent + "    java.lang.reflect.Method _write = _helperClass.getMethod (\"write\", _formalParms);");
764     stream.println (indent + "    Object[] _actualParms = new Object [2];");
765     stream.println (indent + "    _actualParms[0] = ostream;");
766     stream.println (indent + "    _actualParms[1] = " + name + ';');
767     stream.println (indent + "    _write.invoke (null, _actualParms);");
768     stream.println (indent + "  }");
769     stream.println (indent + "  catch (Exception e)");
770     stream.println (indent + "  {");
771     stream.println (indent + "    throw new org.omg.CORBA.MARSHAL (0, org.omg.CORBA.CompletionStatus.COMPLETED_NO);");
772     stream.println (indent + "  }");
773     stream.println (indent + '}');
774 
775     stream.println (indent + "else");
776     stream.println (indent + '{');
777 
778     writeState (index, indent, name, (InterfaceEntry)entry, stream);
779 
780     stream.println (indent + '}');
781     return index;
782   } // structWrite
783 
784   private void writeState (int index, String indent, String name, InterfaceEntry entry, PrintWriter stream)
785   {
786     // First write the state from all parents
787     Enumeration e = entry.derivedFrom ().elements ();
788     while (e.hasMoreElements ())
789     {
790       InterfaceEntry parent = (InterfaceEntry)e.nextElement ();
791       if (parent.state () != null)
792       {
793         if (parent.state ().size () > 0)
794           writeState (index, indent, name, parent, stream);
795         break;
796       }
797     }
798 
799     // Now write the state for the local entry
800     Vector members = entry.state ();
801     for (int i = 0; i < members.size (); ++i)
802     {
803       TypedefEntry member = ((InterfaceState)members.elementAt (i)).entry;
804       if (!member.arrayInfo ().isEmpty () || member.type () instanceof SequenceEntry || member.type () instanceof PrimitiveEntry || member.type () instanceof StringEntry)
805         index = ((JavaGenerator)member.generator ()).write (index, indent + "  ", name + '.' + member.name () + "()", member, stream);
806       else
807         stream.println (indent + "  " + Util.helperName (member.type (), true) + ".write (ostream, " + name + '.' + member.name () + " ());"); // <d61056>
808     }
809   } // writeState
810   */
811 
812   /**
813    * @return true if the entry is for a CORBA pseudo-object.
814    **/
815   private boolean isPseudo(InterfaceEntry i) {
816     java.lang.String fullname = i.fullName();
817     if (fullname.equalsIgnoreCase("CORBA/TypeCode"))
818         return true;
819     if (fullname.equalsIgnoreCase("CORBA/Principal"))
820         return true;
821     if (fullname.equalsIgnoreCase("CORBA/ORB"))
822         return true;
823     if (fullname.equalsIgnoreCase("CORBA/Any"))
824         return true;
825     if (fullname.equalsIgnoreCase("CORBA/Context"))
826         return true;
827     if (fullname.equalsIgnoreCase("CORBA/ContextList"))
828         return true;
829     if (fullname.equalsIgnoreCase("CORBA/DynamicImplementation"))
830         return true;
831     if (fullname.equalsIgnoreCase("CORBA/Environment"))
832         return true;
833     if (fullname.equalsIgnoreCase("CORBA/ExceptionList"))
834         return true;
835     if (fullname.equalsIgnoreCase("CORBA/NVList"))
836         return true;
837     if (fullname.equalsIgnoreCase("CORBA/NamedValue"))
838         return true;
839     if (fullname.equalsIgnoreCase("CORBA/Request"))
840         return true;
841     if (fullname.equalsIgnoreCase("CORBA/ServerRequest"))
842         return true;
843     if (fullname.equalsIgnoreCase("CORBA/UserException"))
844         return true;
845     return false;
846   }
847 
848   // From JavaGenerator
849   ///////////////
850 
851   protected int            emit        = 0;
852   protected Factories      factories   = null;
853 
854   protected Hashtable      symbolTable = null;
855   protected InterfaceEntry i           = null;
856   protected PrintWriter    stream      = null;
857 
858   // <f46082.03, f46838.1/.2/.3> Modify access to protected.
859   protected static final   int SIGNATURE  = 1;
860   protected static final   int OPERATIONS = 2;
861   protected                int intfType   = 0;
862 } // class InterfaceGen