InterfaceGen.java revision 608:7e06bf1dcb09
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   * 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
863