ValueGen24.java revision 672:2bb058ce572e
1/*
2 * Copyright (c) 1999, 2004, 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// -D62023 <klr> Update for Java 2.4 RTF
40// -D62794.1 <klr> Don't include operations inherited from abstract valuetypes
41// -D62794.1 <scn> Don't include operations inherited from supported interfaces
42
43import java.io.File;
44import java.io.PrintWriter;
45import java.util.Hashtable;
46import java.util.Enumeration;
47import java.util.Vector;
48
49import com.sun.tools.corba.se.idl.GenFileStream;
50import com.sun.tools.corba.se.idl.InterfaceEntry;
51import com.sun.tools.corba.se.idl.SymtabEntry;
52import com.sun.tools.corba.se.idl.TypedefEntry;
53import com.sun.tools.corba.se.idl.ValueEntry;
54import com.sun.tools.corba.se.idl.ValueBoxEntry;
55import com.sun.tools.corba.se.idl.InterfaceState;
56import com.sun.tools.corba.se.idl.MethodEntry;
57import com.sun.tools.corba.se.idl.AttributeEntry;
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.StructEntry;
62
63/**
64 *
65 **/
66public class ValueGen24 extends ValueGen
67{
68  /**
69   * Public zero-argument constructor.
70   **/
71  public ValueGen24 ()
72  {
73  } // ctor
74
75  /**
76   * d62023 - delete constructor; helper is abstract
77   **/
78  protected void writeConstructor ()
79  {
80  } // writeConstructor
81
82  /**
83   * <pre>
84   * d62023 - delete write_value from non-boxed helpers
85   *        - delete _write from non-boxed helpers
86   * </pre>
87   **/
88  public void helperWrite (SymtabEntry entry, PrintWriter stream)
89  {
90    // REVISIT: Abstract/Custom??
91    // per Simon mail 5/17/99
92    stream.println ("    ((org.omg.CORBA_2_3.portable.OutputStream) ostream).write_value (value, id ());");
93  } // helperWrite
94
95  /**
96   * d62023
97   **/
98  public void helperRead (String entryName, SymtabEntry entry, PrintWriter stream)
99  {
100    // REVISIT: Abstract/Custom??
101    // per Simon mail 5/17/99
102    stream.println ("    return (" + entryName + ")((org.omg.CORBA_2_3.portable.InputStream) istream).read_value (id ());");
103  } // helperRead
104
105  /**
106   * d62023 - suppress initializers from mapped value; now generated in
107   *    the Helper class and Factory class
108   **/
109  protected void writeInitializers ()
110  {
111        // override to do nothing
112  } // writeInitializers
113
114  /**
115   * d62023 - goes in mapped class, not Helper
116   **/
117  protected void writeTruncatable () // <d60929>
118  {
119    if (!v.isAbstract ()) {
120       stream.println ("  private static String[] _truncatable_ids = {");
121       stream.print   ("    " + Util.helperName(v, true) + ".id ()");
122
123       // Any safe ValueEntry must have a concete value parent.
124       // The topmost parent cannot be safe since it doesn't have
125       // a concrete parent.
126       ValueEntry child = v;
127       while (child.isSafe ())
128       {
129        stream.println(",");
130        ValueEntry parent = (ValueEntry)child.derivedFrom ().elementAt (0);
131        stream.print("    \"" + Util.stripLeadingUnderscoresFromID (parent.repositoryID ().ID ()) + "\"");
132        child = parent;
133      }
134      stream.println();
135      stream.println("  };");
136      stream.println();
137      stream.println ("  public String[] _truncatable_ids() {");
138      stream.println ("    return _truncatable_ids;");
139      stream.println ("  }");
140      stream.println ();
141    }
142  } // writeTruncatable
143
144  class ImplStreamWriter {
145    private boolean isImplementsWritten = false ;
146
147    public void writeClassName( String name )
148    {
149        if (!isImplementsWritten) {
150            stream.print( " implements " ) ;
151            isImplementsWritten = true ;
152        } else
153            stream.print( ", " ) ;
154
155        stream.print( name ) ;
156    }
157  }
158
159  /**
160   * d62023 - CustomMarshal {@literal ->} CustomValue for custom valuetypes
161   *          mapped class is abstract
162   **/
163  protected void writeHeading ()
164  {
165    ImplStreamWriter isw = new ImplStreamWriter() ;
166
167    Util.writePackage (stream, v);
168    Util.writeProlog (stream, ((GenFileStream)stream).name ());
169
170    if (v.comment () != null)
171        v.comment ().generate ("", stream);
172
173    if (v.isAbstract ()) {
174        writeAbstract ();
175        return;
176    } else
177        stream.print ("public abstract class " + v.name ());
178
179    // There should always be at least one parent: ValueBase
180    SymtabEntry parent = (SymtabEntry) v.derivedFrom ().elementAt (0);
181
182    // If parent is ValueBase, it's mapped to java.io.Serializable
183    String parentName = Util.javaName (parent);
184    boolean cv = false; // true if we've already implemented CustomValue
185
186    if (parentName.equals ("java.io.Serializable")) {
187        if (((ValueEntry)v).isCustom ()) {
188              isw.writeClassName( "org.omg.CORBA.portable.CustomValue" ) ;
189              cv = true;
190        } else
191              isw.writeClassName( "org.omg.CORBA.portable.StreamableValue" ) ;
192    } else if ( !((ValueEntry)parent).isAbstract ())
193        stream.print (" extends " + parentName);
194
195    // if inheriting from abstract values
196    for (int i = 0; i < v.derivedFrom ().size (); i++) {
197        parent = (SymtabEntry) v.derivedFrom ().elementAt (i);
198        if ( ((ValueEntry)parent).isAbstract ()) {
199            isw.writeClassName( Util.javaName(parent) ) ;
200        }
201    }
202
203    // Write out the supported interfaces
204    Enumeration enumeration = v.supports().elements();
205    while (enumeration.hasMoreElements())  {
206        InterfaceEntry ie = (InterfaceEntry)(enumeration.nextElement()) ;
207        String cname = Util.javaName(ie) ;
208        if (!ie.isAbstract())
209            cname += "Operations" ;
210        isw.writeClassName( cname ) ;
211    }
212
213    // for when a custom valuetype inherits from a non-custom valuetype
214    if ( v.isCustom () && !cv)
215        isw.writeClassName( "org.omg.CORBA.portable.CustomValue" ) ;
216
217    stream.println ();
218    stream.println ("{");
219  } // writeHeading
220
221  /**
222   * d62023 - private state maps to protected, not default
223   **/
224  protected void writeMembers ()
225  {
226    // if the value type contains no data members, a null return is expected
227    if (v.state () == null)
228      return;
229
230    for (int i = 0; i < v.state ().size (); i ++)
231    {
232      InterfaceState member = (InterfaceState) v.state ().elementAt (i);
233      SymtabEntry entry = (SymtabEntry) member.entry;
234      Util.fillInfo (entry);
235
236      if (entry.comment () != null)
237        entry.comment ().generate (" ", stream);
238
239      String modifier = "  ";
240      if (member.modifier == InterfaceState.Public)
241        modifier = "  public ";
242      else
243        modifier = "  protected ";
244      Util.writeInitializer (modifier, entry.name (), "", entry, stream);
245    }
246    stream.println();
247  } // writeMembers
248
249  /**
250   * d62023 - methods need to be abstract writeStreamable
251   **/
252  protected void writeMethods ()
253  {
254    // contained vector contains methods, attributes, const, enums, exceptions,
255    // structs, unions, or typedefs that are declared inside the value object.
256    // State members of the nested types are also included in this vector.
257    // Thus, if the declaration of a constructed type is nested in the decl.
258    // of a state member, e.g   struct x {boolean b;}  memberx;
259    // the generation of the nested type must be handled here.
260    Enumeration e = v.contained ().elements ();
261    while (e.hasMoreElements ())
262    {
263      SymtabEntry contained = (SymtabEntry)e.nextElement ();
264      if (contained instanceof AttributeEntry)
265      {
266        AttributeEntry element = (AttributeEntry)contained;
267        ((AttributeGen24)element.generator ()).abstractMethod (symbolTable, element, stream);
268      }
269      else if (contained instanceof MethodEntry)
270      {
271        MethodEntry element = (MethodEntry)contained;
272        ((MethodGen24)element.generator ()).abstractMethod (symbolTable, element, stream);
273      }
274      else
275      {
276        // Generate the type referenced by the typedef.
277        if (contained instanceof TypedefEntry)
278          contained.type ().generate (symbolTable, stream);
279
280        // Note that we also need to generate the typedef itself if
281        // contained is a typedef.
282        contained.generate (symbolTable, stream);
283      }
284    }
285
286    // Abstract values are mapped to interfaces. There is no need to generate
287    // the bindings for inheriting methods in case of inheritance from other
288    // abstract values or supporting interface
289    if (v.isAbstract ())
290        return;
291
292  // Non-abstract, Non-Custom valuetypes support the Streamable interface
293  if (!(v.isCustom () || v.isAbstract ()))
294      writeStreamableMethods ();
295  } // writeMethods
296
297  /**
298   * d62023 - call super._read()
299   **/
300  public int read (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
301  {
302    // First do the state members from concrete parent hierarchy
303    Vector vParents = ((ValueEntry) entry).derivedFrom ();
304    if (vParents != null && vParents.size() != 0)
305    {
306      ValueEntry parent = (ValueEntry) vParents.elementAt (0);
307      if (parent == null)
308        return index;
309
310      // call super._read if non-abstract value parent
311      if ((!parent.isAbstract ()) && (! Util.javaQualifiedName(parent).equals ("java.io.Serializable"))) // <d60929>
312          stream.println(indent + "super._read (istream);");
313    }
314
315    Vector vMembers = ((ValueEntry) entry).state ();
316    int noOfMembers = vMembers == null ? 0 : vMembers.size ();
317
318    for (int k = 0; k < noOfMembers; k++)
319    {
320      TypedefEntry member = (TypedefEntry)((InterfaceState)vMembers.elementAt (k)).entry;
321      String memberName = member.name ();
322      SymtabEntry mType = member.type ();
323
324      if (mType instanceof PrimitiveEntry ||
325          mType instanceof TypedefEntry   ||
326          mType instanceof SequenceEntry  ||
327          mType instanceof StringEntry    ||
328          !member.arrayInfo ().isEmpty ())
329        index = ((JavaGenerator)member.generator ()).read (index, indent, name + '.' + memberName, member, stream);
330      else
331        stream.println (indent + name + '.' + memberName + " = " +
332                        Util.helperName (mType, true) + ".read (istream);"); // <d61056>
333    }
334
335    return index;
336  } // read
337
338  /**
339   * d62023 - call super._write()
340   **/
341  public int write (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
342  {
343    // First do the state members from concrete parent hierarchy
344    Vector vParents = ((ValueEntry)entry).derivedFrom ();
345    if (vParents != null && vParents.size () != 0)
346    {
347      ValueEntry parent = (ValueEntry)vParents.elementAt (0);
348      if (parent == null)
349        return index;
350      // call super._read if non-abstract value parent
351      if ((!parent.isAbstract ()) && (! Util.javaQualifiedName(parent).equals ("java.io.Serializable"))) // <d60929>
352          stream.println(indent + "super._write (ostream);");
353    }
354
355    Vector vMembers = ((ValueEntry) entry ).state ();
356    int noOfMembers = vMembers == null ? 0 : vMembers.size ();
357    for (int k = 0; k < noOfMembers; k++)
358    {
359      TypedefEntry member = (TypedefEntry)((InterfaceState)vMembers.elementAt (k)).entry;
360      String memberName = member.name ();
361      SymtabEntry mType = member.type ();
362
363      if (mType instanceof PrimitiveEntry ||
364          mType instanceof TypedefEntry   ||
365          mType instanceof SequenceEntry  ||
366          mType instanceof StringEntry    ||
367          !member.arrayInfo ().isEmpty ())
368        index = ((JavaGenerator)member.generator ()).write (index, indent, name + '.' + memberName, member, stream);
369      else
370        stream.println (indent + Util.helperName (mType, true) + // <d61056>
371                              ".write (ostream, " + name + '.' + memberName + ");");
372    }
373
374    return index;
375  } // write
376
377  /**
378   * d62023 - generate factory interface and default factory
379   **/
380  public void generate (Hashtable symbolTable, ValueEntry v, PrintWriter str)
381  {
382    this.symbolTable = symbolTable;
383    this.v = v;
384    init ();
385
386    openStream ();
387    if (stream == null)
388      return;
389    generateTie ();
390    generateHelper ();
391    generateHolder ();
392    if (!v.isAbstract ()) {
393      generateValueFactory ();
394      generateDefaultFactory ();
395    }
396    writeHeading ();
397    writeBody ();
398    writeClosing ();
399    closeStream ();
400  } // generate
401
402  /**
403   *
404   **/
405  protected void generateValueFactory ()
406  {
407    ((Factories)Compile.compiler.factories ()).valueFactory ().generate (symbolTable, v);
408  } // generateValueFactory
409
410  /**
411   *
412   **/
413  protected void generateDefaultFactory ()
414  {
415    ((Factories)Compile.compiler.factories ()).defaultFactory ().generate (symbolTable, v);
416  } // generateDefaultFactory
417}
418