InterfaceGen.java revision 672:2bb058ce572e
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
36package 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
48import java.io.PrintWriter;
49import java.util.Enumeration;
50import java.util.Hashtable;
51import java.util.Vector;
52
53import com.sun.tools.corba.se.idl.GenFileStream;
54import com.sun.tools.corba.se.idl.ConstEntry;
55import com.sun.tools.corba.se.idl.InterfaceEntry;
56import com.sun.tools.corba.se.idl.InterfaceState;
57import com.sun.tools.corba.se.idl.MethodEntry;
58import com.sun.tools.corba.se.idl.PrimitiveEntry;
59import com.sun.tools.corba.se.idl.SequenceEntry;
60import com.sun.tools.corba.se.idl.StringEntry;
61import com.sun.tools.corba.se.idl.SymtabEntry;
62import com.sun.tools.corba.se.idl.TypedefEntry;
63
64/**
65 *
66 **/
67public 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   * <ol>
194   * <li> Initialize members unique to this generator - init()</li>
195   * <li> Open print stream - openStream()</li>
196   * <li> Write class heading (package, prologue, class statement, open curly - writeHeading()</li>
197   * <li> Write class body (member data and methods) - write*Body()</li>
198   * <li> Write class closing (close curly) - writeClosing()</li>
199   * <li> Close the print stream - closeStream ()</li>
200   * </ol>
201   *
202   * For CORBA 2.3, interfaces are mapped to Operations and Signature
203   * interfaces. The Operations interface contains the method definitions.
204   * The Signature interface extends the Operations interface and adds
205   * CORBA::Object. (klr)
206   **/
207  protected void generateInterface ()
208  {
209    init ();
210    openStream ();
211    if (stream == null)
212      return;
213    writeHeading ();
214    if (intfType == OPERATIONS)
215      writeOperationsBody ();
216    if (intfType == SIGNATURE)
217      writeSignatureBody ();
218    writeClosing ();
219    closeStream ();
220  } // generateInterface
221
222  /**
223   *
224   **/
225  protected void openStream ()
226  {
227    if (i.isAbstract () || intfType == SIGNATURE)
228       stream = Util.stream (i, ".java");
229    else if (intfType == OPERATIONS)
230       stream = Util.stream (i, "Operations.java");
231  } // openStream
232
233  /**
234   *
235   **/
236  protected void writeHeading ()
237  {
238    Util.writePackage (stream, i, Util.TypeFile);
239    Util.writeProlog (stream, ((GenFileStream)stream).name ());
240
241    // Transfer interface comment to target <31jul1997>.
242    if (i.comment () != null)
243      i.comment ().generate ("", stream);
244
245    String className = i.name ();
246//  if (((Arguments)Compile.compiler.arguments).TIEServer)
247//  {
248//    // For the delegate model, don't make interface a subclass of CORBA.Object
249//    stream.print ("public interface " + className);
250//    boolean firstTime = true;
251//    for (int ii = 0; ii < i.derivedFrom ().size (); ++ii)
252//    {
253//      SymtabEntry parent = (SymtabEntry)i.derivedFrom ().elementAt (ii);
254//      if (!parent.fullName ().equals ("org/omg/CORBA/Object"))
255//      {
256//        if (firstTime)
257//        {
258//          firstTime = false;
259//          stream.print (" extends ");
260//        }
261//        else
262//          stream.print (", ");
263//        stream.print (Util.javaName (parent));
264//      }
265//    }
266//    if (i.derivedFrom ().size () > 0)
267//      stream.print (", ");
268//    stream.print ("org.omg.CORBA.portable.IDLEntity ");
269//  }
270//
271//  else
272//  {
273      if (intfType == SIGNATURE)
274         writeSignatureHeading ();
275      else if (intfType == OPERATIONS)
276         writeOperationsHeading ();
277//  }
278
279    stream.println ();
280    stream.println ('{');
281  } // writeHeading
282
283  /**
284   *
285   **/
286  protected void writeSignatureHeading ()
287  {
288    String className = i.name ();
289    stream.print ("public interface " + className + " extends " + className + "Operations, ");
290    boolean firstTime = true;
291    boolean hasNonAbstractParent = false; // <d62310-klr>
292    for (int k = 0; k < i.derivedFrom ().size (); ++k)
293    {
294      if (firstTime)
295        firstTime = false;
296      else
297        stream.print (", ");
298      InterfaceEntry parent = (InterfaceEntry)i.derivedFrom ().elementAt (k);
299      stream.print (Util.javaName (parent));
300      if (! parent.isAbstract ()) // <d62310-klr>
301        hasNonAbstractParent = true; // <d62310-klr>
302    }
303    // <d62310-klr> - begin
304    // If this interface extends only abstract interfaces,
305    // it should extend both org.omg.CORBA.Object and IDLEntity.
306    if (!hasNonAbstractParent) {
307      stream.print (", org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity ");
308    }
309    else {
310    // <d62310-klr> - end
311        // extends IDLEntity if there's only one default parent - CORBA.Object
312        if (i.derivedFrom ().size () == 1)
313          stream.print (", org.omg.CORBA.portable.IDLEntity ");
314    }
315  } // writeSignatureHeading
316
317  /**
318   *
319   **/
320  protected void writeOperationsHeading ()
321  {
322    stream.print ("public interface " + i.name ());
323    if ( !i.isAbstract ())
324      stream.print ("Operations ");
325    else {
326        // <d60929> - base abstract interfaces extend AbstractBase
327        // changed to IDLEntity by SCN per latest spec...
328        if (i.derivedFrom ().size () == 0)
329          stream.print (" extends org.omg.CORBA.portable.IDLEntity");
330    }
331
332    boolean firstTime = true;
333    for (int k = 0; k < i.derivedFrom ().size (); ++k)
334    {
335      InterfaceEntry parent = (InterfaceEntry) i.derivedFrom ().elementAt (k);
336      String parentName = Util.javaName (parent);
337
338      // ignore the default parent - CORBA.Object
339      if (parentName.equals ("org.omg.CORBA.Object"))
340          continue;
341
342      if (firstTime)
343      {
344        firstTime = false;
345        stream.print (" extends ");
346      }
347      else
348        stream.print (", ");
349
350      // Don't append suffix Operations to the parents of abstract interface
351      // or to the abstract parents of regular interface
352      if (parent.isAbstract () || i.isAbstract ())
353        stream.print (parentName);
354      else
355        stream.print (parentName + "Operations");
356    }
357  } // writeOperationsHeading
358
359
360  /**
361   *
362   **/
363  protected void writeOperationsBody ()
364  {
365    // Generate everything but constants
366    Enumeration e = i.contained ().elements ();
367    while (e.hasMoreElements ())
368    {
369      SymtabEntry contained = (SymtabEntry)e.nextElement ();
370      if (contained instanceof MethodEntry)
371      {
372        MethodEntry element = (MethodEntry)contained;
373        ((MethodGen)element.generator ()).interfaceMethod (symbolTable, element, stream);
374      }
375      else
376        if ( !(contained instanceof ConstEntry))
377          contained.generate (symbolTable, stream);
378    }
379  } // writeOperationsBody
380
381  /**
382   *
383   **/
384  protected void writeSignatureBody ()
385  {
386    // Generate only constants
387    Enumeration e = i.contained ().elements ();
388    while (e.hasMoreElements ())
389    {
390      SymtabEntry contained = (SymtabEntry)e.nextElement ();
391      if (contained instanceof ConstEntry)
392        contained.generate (symbolTable, stream);
393    }
394  } // writeSignatureBody
395
396  /**
397   *
398   **/
399  protected void writeClosing ()
400  {
401    String intfName = i.name ();
402    if ( !i.isAbstract () && intfType == OPERATIONS)
403      intfName = intfName + "Operations";
404    stream.println ("} // interface " + intfName);
405  } // writeClosing
406
407  /**
408   *
409   **/
410  protected void closeStream ()
411  {
412    stream.close ();
413  } // closeStream
414
415  ///////////////
416  // From JavaGenerator
417
418  // <f46082.51> Remove -stateful feature.
419  /*
420  public int helperType (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream)
421  {
422    InterfaceEntry i = (InterfaceEntry)entry;
423    if (i.state () != null && i.state ().size () > 0)
424      index = structHelperType (index, indent, tcoffsets, name, entry, stream);
425    else
426    {
427      tcoffsets.set (entry);
428      if (entry.fullName ().equals ("org/omg/CORBA/Object"))
429        stream.println (indent + name
430            + " = org.omg.CORBA.ORB.init ().get_primitive_tc (org.omg.CORBA.TCKind.tk_objref);");
431      else
432        stream.println (indent + name
433            // <54697>
434            //+ " = org.omg.CORBA.ORB.init ().create_interface_tc (_id, "
435            + " = org.omg.CORBA.ORB.init ().create_interface_tc (" + Util.helperName (i, true) + ".id (), " // <d61056>
436            + '\"' + Util.stripLeadingUnderscores (entry.name ()) + "\");");
437    }
438    return index;
439  } // helperType
440  */
441  public int helperType (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream)
442  {
443    InterfaceEntry i = (InterfaceEntry)entry;
444    tcoffsets.set (entry);
445    if (entry.fullName ().equals ("org/omg/CORBA/Object"))
446      stream.println (indent + name
447          + " = org.omg.CORBA.ORB.init ().get_primitive_tc (org.omg.CORBA.TCKind.tk_objref);");
448    else
449      stream.println (indent + name
450          // <54697>
451          //+ " = org.omg.CORBA.ORB.init ().create_interface_tc (_id, "
452          + " = org.omg.CORBA.ORB.init ().create_interface_tc (" + Util.helperName (i, true) + ".id (), " // <d61056>
453          + '\"' + Util.stripLeadingUnderscores (entry.name ()) + "\");");
454    return index;
455  } // helperType
456
457  public int type (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream) {
458    stream.println (indent + name + " = " + Util.helperName (entry, true) + ".type ();"); // <d61056>
459    return index;
460  } // type
461
462  // <f46082.51> Remove -stateful feature.
463  /*
464  public void helperRead (String entryName, SymtabEntry entry, PrintWriter stream)
465  {
466    InterfaceEntry i = (InterfaceEntry)entry;
467    if (i.state () != null)
468      structHelperRead (entryName, i, stream);
469    else
470    {
471      if (i.isAbstract ())
472         stream.println ("    return narrow (((org.omg.CORBA_2_3.portable.InputStream)istream).read_abstract_interface (_" + i.name () + "Stub.class));"); // <d60929>
473      else
474         stream.println ("    return narrow (istream.read_Object (_" + i.name () + "Stub.class));");
475    }
476  } // helperRead
477
478  */
479  public void helperRead (String entryName, SymtabEntry entry, PrintWriter stream)
480  {
481    InterfaceEntry i = (InterfaceEntry)entry;
482    if (i.isAbstract ())
483      stream.println ("    return narrow (((org.omg.CORBA_2_3.portable.InputStream)istream).read_abstract_interface (_" + i.name () + "Stub.class));"); // <d60929>
484    else
485      stream.println ("    return narrow (istream.read_Object (_" + i.name () + "Stub.class));");
486  } // helperRead
487
488  // <f46082.51> Remove -stateful feature.
489  /*
490  public void helperWrite (SymtabEntry entry, PrintWriter stream)
491  {
492    InterfaceEntry i = (InterfaceEntry)entry;
493    if (i.state () != null)
494      structHelperWrite (entry, stream);
495    else
496      write (0, "    ", "value", entry, stream);
497  } // helperWrite
498  */
499  public void helperWrite (SymtabEntry entry, PrintWriter stream)
500  {
501    write (0, "    ", "value", entry, stream);
502  } // helperWrite
503
504  // <f46082.51> Remove -stateful feature.
505  /*
506  public int read (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
507  {
508    InterfaceEntry i = (InterfaceEntry)entry;
509    if (i.state () != null)
510      index = structRead (index, indent, name, i, stream);
511    else
512    {
513      if (entry.fullName ().equals ("org/omg/CORBA/Object"))
514        stream.println (indent + name + " = istream.read_Object (_" + i.name () + "Stub.class);");
515      else
516        stream.println (indent + name + " = " + Util.helperName (entry, false) + ".narrow (istream.read_Object (_" + i.name () + "Stub.class));"); // <d61056>
517    }
518    return index;
519  } // read
520  */
521  public int read (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
522  {
523    InterfaceEntry i = (InterfaceEntry)entry;
524    if (entry.fullName ().equals ("org/omg/CORBA/Object"))
525      stream.println (indent + name + " = istream.read_Object (_" + i.name () + "Stub.class);");
526    else
527      stream.println (indent + name + " = " + Util.helperName (entry, false) + ".narrow (istream.read_Object (_" + i.name () + "Stub.class));"); // <d61056>
528    return index;
529  } // read
530
531  // <f46082.51> Remove -stateful feature.
532  /*
533  public int write (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
534  {
535    InterfaceEntry i = (InterfaceEntry)entry;
536    if (i.state () != null)
537      index = structWrite (index, indent, name, entry, stream);
538    else
539    {
540      if (i.isAbstract ())
541         stream.println (indent + "((org.omg.CORBA_2_3.portable.OutputStream)ostream).write_abstract_interface ((java.lang.Object) " + name + ");"); // <d60929>
542      else
543         stream.println (indent + "ostream.write_Object ((org.omg.CORBA.Object) " + name + ");");
544    }
545    return index;
546  } // write
547  */
548  public int write (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
549  {
550    InterfaceEntry i = (InterfaceEntry)entry;
551    if (i.isAbstract ())
552      stream.println (indent + "((org.omg.CORBA_2_3.portable.OutputStream)ostream).write_abstract_interface ((java.lang.Object) " + name + ");"); // <d60929>
553    else
554      stream.println (indent + "ostream.write_Object ((org.omg.CORBA.Object) " + name + ");");
555    return index;
556  } // write
557
558  // <f46082.51> Remove -stateful feature.
559  /*
560  // These methods are cobbled from StructGen.  Stateful interfaces
561  // are sent across the wire as if they were structs, with the first
562  // element being a string - the Java name of the class.
563
564  public int structHelperType (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream)
565  {
566    TCOffsets innerOffsets = new TCOffsets ();
567    innerOffsets.set (entry);
568    int offsetForStruct = innerOffsets.currentOffset ();
569    InterfaceEntry i = (InterfaceEntry)entry;
570    String membersName = "_members" + index++;
571    Vector state = i.state ();
572    stream.println (indent + "org.omg.CORBA.StructMember[] " + membersName + " = new org.omg.CORBA.StructMember [" + (state.size () + 1) + "];");
573    String tcOfMembers = "_tcOf" + membersName;
574    stream.println (indent + "org.omg.CORBA.TypeCode " + tcOfMembers + ';');
575
576    // The name string is the first element of the struct
577    String memberName = "_name";
578    StringEntry stringEntry = Compile.compiler.factory.stringEntry ();
579    index = ((JavaGenerator)stringEntry.generator ()).helperType (index, indent, innerOffsets, tcOfMembers, stringEntry, stream);
580    stream.println (indent + membersName + "[0] = new org.omg.CORBA.StructMember (");
581    stream.println (indent + "  \"" + memberName + "\",");
582    stream.println (indent + "  " + tcOfMembers + ',');
583    stream.println (indent + "  null);");
584    int offsetSoFar = innerOffsets.currentOffset ();
585    innerOffsets = new TCOffsets ();
586    innerOffsets.set (entry);
587    innerOffsets.bumpCurrentOffset (offsetSoFar - offsetForStruct);
588
589    for (int idx = 0; idx < state.size (); ++idx)
590    {
591      TypedefEntry member = ((InterfaceState)state.elementAt (idx)).entry;
592      memberName = member.name ();
593      index = ((JavaGenerator)member.generator ()).helperType (index, indent, innerOffsets, tcOfMembers, member, stream);
594      stream.println (indent + membersName + '[' + (idx + 1) + "] = new org.omg.CORBA.StructMember (");
595      stream.println (indent + "  \"" + memberName + "\",");
596      stream.println (indent + "  " + tcOfMembers + ',');
597      stream.println (indent + "  null);");
598      offsetSoFar = innerOffsets.currentOffset ();
599      innerOffsets = new TCOffsets ();
600      innerOffsets.set (entry);
601      innerOffsets.bumpCurrentOffset (offsetSoFar - offsetForStruct);
602    }
603    tcoffsets.bumpCurrentOffset (innerOffsets.currentOffset ());
604    stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_struct_tc (id (), \"" + entry.name () + "\", " + membersName + ");");
605    return index;
606  } // structHelperType
607
608  public void structHelperRead (String entryName, InterfaceEntry entry, PrintWriter stream)
609  {
610    String impl = implName ((InterfaceEntry)entry);
611    stream.println ("      " + Util.javaStatefulName (entry) + " value = null;");
612    structRead (0, "      ", "value", entry, stream);
613    stream.println ("      return value;");
614  } // structHelperRead
615
616  private String implName (InterfaceEntry entry)
617  {
618    String name;
619    if (entry.container ().name ().equals (""))
620      name =  '_' + entry.name () + "Impl";
621    else
622      name = Util.containerFullName (entry.container ()) + "._" + entry.name () + "Impl";
623    return name.replace ('/', '.');
624  } // implName
625
626  public int structRead (int index, String indent, String name, InterfaceEntry entry, PrintWriter stream)
627  {
628    // The first element will be the name of the Java implementation class.
629    String stringName = "_name" + index++;
630    stream.println (indent + "String " + stringName + " = istream.read_string ();");
631    stream.println (indent + "try");
632    stream.println (indent + "{");
633    stream.println (indent + "  " + name + " = (" + Util.javaStatefulName (entry) + ")com.sun.CORBA.iiop.ORB.getImpl (" + stringName + ".replace ('/', '.'));");
634    stream.println (indent + "}");
635    stream.println (indent + "catch (Exception e)");
636    stream.println (indent + "{");
637    stream.println (indent + "  " + name + " = null;");
638    stream.println (indent + "}");
639    stream.println (indent + "if (" + name + " == null)");
640    stream.println (indent + "  throw new org.omg.CORBA.NO_IMPLEMENT (0, org.omg.CORBA.CompletionStatus.COMPLETED_NO);");
641    stream.println ();
642
643    stream.println (indent + "if (!" + stringName + ".equals (\"" + entry.fullName () + "\"))");
644    stream.println (indent + '{');
645    stream.println (indent + "  Class _cls = " + name + ".getClass ();");
646    stream.println (indent + "  boolean _found = false;");
647    stream.println (indent + "  while (!_found && _cls != null)");
648    stream.println (indent + "  {");
649    stream.println (indent + "    Class[] interfaces = _cls.getInterfaces ();");
650    stream.println (indent + "    for (int i = 0; i < interfaces.length; ++i)");
651    stream.println (indent + "      if (interfaces[i].getName ().indexOf (\"State\") > 0)");
652    stream.println (indent + "      {");
653    stream.println (indent + "        _cls = interfaces[i];");
654    stream.println (indent + "        _found = true;");
655    stream.println (indent + "        break;");
656    stream.println (indent + "      }");
657    stream.println (indent + "    if (!_found)");
658    stream.println (indent + "      _cls = _cls.getSuperclass ();");
659    stream.println (indent + "  }");
660    stream.println (indent + "  if (_cls == null)");
661    stream.println (indent + "    throw new org.omg.CORBA.NO_IMPLEMENT (0, org.omg.CORBA.CompletionStatus.COMPLETED_NO);");
662    stream.println ();
663    stream.println (indent + "  String _className = _cls.getName ();");
664    stream.println (indent + "  int _index = _className.lastIndexOf ('.');");
665    stream.println (indent + "  String _helperName = _className.substring (0, _index + 1) + _className.substring (_index + 2, _className.length () - 5) + \"Helper\"; // 5 == \"State\".length");
666    stream.println (indent + "  try");
667    stream.println (indent + "  {");
668    stream.println (indent + "    Class _helperClass = Class.forName (_helperName);");
669    stream.println (indent + "    Class[] _formalParms = new Class [1];");
670    stream.println (indent + "    _formalParms[0] = Class.forName (\"org.omg.CORBA.portable.InputStream\");");
671    stream.println (indent + "    java.lang.reflect.Method _read = _helperClass.getMethod (\"read\", _formalParms);");
672    stream.println (indent + "    Object[] _actualParms = new Object [1];");
673    stream.println (indent + "    _actualParms[0] = istream;");
674    stream.println (indent + "      " + name + " = (" + Util.javaStatefulName (entry) + ")_read.invoke (null, _actualParms);");
675    stream.println (indent + "  }");
676    stream.println (indent + "  catch (Exception e)");
677    stream.println (indent + "  {");
678    stream.println (indent + "    throw new org.omg.CORBA.NO_IMPLEMENT (0, org.omg.CORBA.CompletionStatus.COMPLETED_NO);");
679    stream.println (indent + "  }");
680    stream.println (indent + '}');
681
682    // instantiate an implementation
683    stream.println (indent + "else");
684    stream.println (indent + '{');
685
686    // Load the state
687    readState (index, indent, name, (InterfaceEntry)entry, stream);
688
689    stream.println (indent + '}');
690    return index;
691  } // structRead
692
693  private void readState (int index, String indent, String name, InterfaceEntry entry, PrintWriter stream)
694  {
695    // First write the state from all parents
696    Enumeration e = entry.derivedFrom ().elements ();
697    while (e.hasMoreElements ())
698    {
699      InterfaceEntry parent = (InterfaceEntry)e.nextElement ();
700      if (parent.state () != null)
701      {
702        if (parent.state ().size () > 0)
703          readState (index, indent, name, parent, stream);
704        break;
705      }
706    }
707
708    // Now write the state for the local entry
709    e = entry.state ().elements ();
710    while (e.hasMoreElements ())
711    {
712      TypedefEntry member = ((InterfaceState)e.nextElement ()).entry;
713      String tmpName = '_' + member.name () + "Tmp";
714      Util.writeInitializer (indent + "  ", tmpName, "", member, stream);
715      if (!member.arrayInfo ().isEmpty () || member.type () instanceof SequenceEntry || member.type () instanceof PrimitiveEntry || member.type () instanceof StringEntry)
716        index = ((JavaGenerator)member.generator ()).read (index, indent + "  ", tmpName, member, stream);
717      else
718        stream.println (indent + "  " + tmpName + " = " + Util.helperName (member.type (), true) + ".read (istream);"); // <d61056>
719      stream.println (indent + "  " + name + '.' + member.name () + " (" + tmpName + ");");
720    }
721  } // readState
722
723  public void structHelperWrite (SymtabEntry entry, PrintWriter stream)
724  {
725    structWrite (0, "      ", "value", entry, stream);
726  } // structHelperWrite
727
728  public int structWrite (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
729  {
730    // The first element of the struct must be the name of the real interface.
731    stream.println (indent + "Class _cls = " + name + ".getClass ();");
732    stream.println (indent + "boolean _found = false;");
733    stream.println (indent + "while (!_found && _cls != null)");
734    stream.println (indent + "{");
735    stream.println (indent + "  Class[] interfaces = _cls.getInterfaces ();");
736    stream.println (indent + "  for (int i = 0; i < interfaces.length; ++i)");
737    stream.println (indent + "    if (interfaces[i].getName ().indexOf (\"State\") > 0)");
738    stream.println (indent + "    {");
739    stream.println (indent + "      _cls = interfaces[i];");
740    stream.println (indent + "      _found = true;");
741    stream.println (indent + "      break;");
742    stream.println (indent + "    }");
743    stream.println (indent + "  if (!_found)");
744    stream.println (indent + "    _cls = _cls.getSuperclass ();");
745    stream.println (indent + '}');
746    stream.println ();
747    stream.println (indent + "if (_cls == null)");
748    stream.println (indent + "  throw new org.omg.CORBA.MARSHAL (0, org.omg.CORBA.CompletionStatus.COMPLETED_NO);");
749    stream.println ();
750    stream.println (indent + "String _className = _cls.getName ();");
751    stream.println (indent + "int _index = _className.lastIndexOf ('.');");
752    stream.println (indent + "String _interfaceName = _className.substring (0, _index + 1) + _className.substring (_index + 2, _className.length () - 5); // 5 == \"State\".length");
753    stream.println (indent + "ostream.write_string (_interfaceName.replace ('.', '/'));");
754
755    // If _className != Util.javaName (entry), then call that class's helper class.
756    stream.println ();
757    stream.println (indent + "if (!_interfaceName.equals (\"" + Util.javaName (entry) + "\"))");
758    stream.println (indent + '{');
759    stream.println (indent + "  try");
760    stream.println (indent + "  {");
761    stream.println (indent + "    Class _helperClass = Class.forName (_interfaceName + \"Helper\");");
762    stream.println (indent + "    Class[] _formalParms = new Class [2];");
763    stream.println (indent + "    _formalParms[0] = Class.forName (\"org.omg.CORBA.portable.OutputStream\");");
764    stream.println (indent + "    _formalParms[1] = _cls;");
765    stream.println (indent + "    java.lang.reflect.Method _write = _helperClass.getMethod (\"write\", _formalParms);");
766    stream.println (indent + "    Object[] _actualParms = new Object [2];");
767    stream.println (indent + "    _actualParms[0] = ostream;");
768    stream.println (indent + "    _actualParms[1] = " + name + ';');
769    stream.println (indent + "    _write.invoke (null, _actualParms);");
770    stream.println (indent + "  }");
771    stream.println (indent + "  catch (Exception e)");
772    stream.println (indent + "  {");
773    stream.println (indent + "    throw new org.omg.CORBA.MARSHAL (0, org.omg.CORBA.CompletionStatus.COMPLETED_NO);");
774    stream.println (indent + "  }");
775    stream.println (indent + '}');
776
777    stream.println (indent + "else");
778    stream.println (indent + '{');
779
780    writeState (index, indent, name, (InterfaceEntry)entry, stream);
781
782    stream.println (indent + '}');
783    return index;
784  } // structWrite
785
786  private void writeState (int index, String indent, String name, InterfaceEntry entry, PrintWriter stream)
787  {
788    // First write the state from all parents
789    Enumeration e = entry.derivedFrom ().elements ();
790    while (e.hasMoreElements ())
791    {
792      InterfaceEntry parent = (InterfaceEntry)e.nextElement ();
793      if (parent.state () != null)
794      {
795        if (parent.state ().size () > 0)
796          writeState (index, indent, name, parent, stream);
797        break;
798      }
799    }
800
801    // Now write the state for the local entry
802    Vector members = entry.state ();
803    for (int i = 0; i < members.size (); ++i)
804    {
805      TypedefEntry member = ((InterfaceState)members.elementAt (i)).entry;
806      if (!member.arrayInfo ().isEmpty () || member.type () instanceof SequenceEntry || member.type () instanceof PrimitiveEntry || member.type () instanceof StringEntry)
807        index = ((JavaGenerator)member.generator ()).write (index, indent + "  ", name + '.' + member.name () + "()", member, stream);
808      else
809        stream.println (indent + "  " + Util.helperName (member.type (), true) + ".write (ostream, " + name + '.' + member.name () + " ());"); // <d61056>
810    }
811  } // writeState
812  */
813
814  /**
815   * @return true if the entry is for a CORBA pseudo-object.
816   **/
817  private boolean isPseudo(InterfaceEntry i) {
818    java.lang.String fullname = i.fullName();
819    if (fullname.equalsIgnoreCase("CORBA/TypeCode"))
820        return true;
821    if (fullname.equalsIgnoreCase("CORBA/Principal"))
822        return true;
823    if (fullname.equalsIgnoreCase("CORBA/ORB"))
824        return true;
825    if (fullname.equalsIgnoreCase("CORBA/Any"))
826        return true;
827    if (fullname.equalsIgnoreCase("CORBA/Context"))
828        return true;
829    if (fullname.equalsIgnoreCase("CORBA/ContextList"))
830        return true;
831    if (fullname.equalsIgnoreCase("CORBA/DynamicImplementation"))
832        return true;
833    if (fullname.equalsIgnoreCase("CORBA/Environment"))
834        return true;
835    if (fullname.equalsIgnoreCase("CORBA/ExceptionList"))
836        return true;
837    if (fullname.equalsIgnoreCase("CORBA/NVList"))
838        return true;
839    if (fullname.equalsIgnoreCase("CORBA/NamedValue"))
840        return true;
841    if (fullname.equalsIgnoreCase("CORBA/Request"))
842        return true;
843    if (fullname.equalsIgnoreCase("CORBA/ServerRequest"))
844        return true;
845    if (fullname.equalsIgnoreCase("CORBA/UserException"))
846        return true;
847    return false;
848  }
849
850  // From JavaGenerator
851  ///////////////
852
853  protected int            emit        = 0;
854  protected Factories      factories   = null;
855
856  protected Hashtable      symbolTable = null;
857  protected InterfaceEntry i           = null;
858  protected PrintWriter    stream      = null;
859
860  // <f46082.03, f46838.1/.2/.3> Modify access to protected.
861  protected static final   int SIGNATURE  = 1;
862  protected static final   int OPERATIONS = 2;
863  protected                int intfType   = 0;
864} // class InterfaceGen
865