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 
36 package 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 
43 import java.io.File;
44 import java.io.PrintWriter;
45 import java.util.Hashtable;
46 import java.util.Enumeration;
47 import java.util.Vector;
48 
49 import com.sun.tools.corba.se.idl.GenFileStream;
50 import com.sun.tools.corba.se.idl.InterfaceEntry;
51 import com.sun.tools.corba.se.idl.SymtabEntry;
52 import com.sun.tools.corba.se.idl.TypedefEntry;
53 import com.sun.tools.corba.se.idl.ValueEntry;
54 import com.sun.tools.corba.se.idl.ValueBoxEntry;
55 import com.sun.tools.corba.se.idl.InterfaceState;
56 import com.sun.tools.corba.se.idl.MethodEntry;
57 import com.sun.tools.corba.se.idl.AttributeEntry;
58 import com.sun.tools.corba.se.idl.PrimitiveEntry;
59 import com.sun.tools.corba.se.idl.SequenceEntry;
60 import com.sun.tools.corba.se.idl.StringEntry;
61 import com.sun.tools.corba.se.idl.StructEntry;
62 
63 /**
64  *
65  **/
66 public class ValueGen24 extends ValueGen
67 {
68   /**
69    * Public zero-argument constructor.
70    **/
ValueGen24()71   public ValueGen24 ()
72   {
73   } // ctor
74 
75   /**
76    * <d62023> - delete constructor; helper is abstract
77    **/
writeConstructor()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    **/
helperWrite(SymtabEntry entry, PrintWriter stream)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    **/
helperRead(String entryName, SymtabEntry entry, PrintWriter stream)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    **/
writeInitializers()107   protected void writeInitializers ()
108   {
109         // override to do nothing
110   } // writeInitializers
111 
112   /**
113    * <d62023> - Goes in mapped class, not Helper
114    **/
writeTruncatable()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 
writeClassName( String name )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    **/
writeHeading()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    **/
writeMembers()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    **/
writeMethods()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    **/
read(int index, String indent, String name, SymtabEntry entry, PrintWriter stream)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    **/
write(int index, String indent, String name, SymtabEntry entry, PrintWriter stream)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    **/
generate(Hashtable symbolTable, ValueEntry v, PrintWriter str)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    **/
generateValueFactory()404   protected void generateValueFactory ()
405   {
406     ((Factories)Compile.compiler.factories ()).valueFactory ().generate (symbolTable, v);
407   } // generateValueFactory
408 
409   /**
410    *
411    **/
generateDefaultFactory()412   protected void generateDefaultFactory ()
413   {
414     ((Factories)Compile.compiler.factories ()).defaultFactory ().generate (symbolTable, v);
415   } // generateDefaultFactory
416 }
417