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