Mon, 04 May 2009 18:40:45 -0700
6529590: flaw in com.sun.corba.se.impl.presentation.rmi.IDLNameTranslatorImpl
Reviewed-by: darcy
1 /*
2 * Copyright 1999-2001 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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 */
36 package com.sun.tools.corba.se.idl.toJavaPortable;
38 // NOTES:
39 // -F46082.51<daz> Remove -stateful feature; javaStatefulName() obsolete.
40 // -D57067 <klr> suppress default init if an emit init explicitly specified.
41 // -D59071 <daz> Clone method entries when their content needs modification.
42 // -D59092 <klr> Valuetype supporting interfaces should implement interface.
43 // -D59418 <klr> Custom values implement org.omg.CORBA.CustomMarshal
44 // -D59418 <klr> Invert read/read_Value, write/write_Value for Simon
45 // -D60929 <klr> Update for RTF2.4 changes
46 // -D62018 <klr> write_value for value with value field x calls xHelper.write.
47 // -D62062 <klr> Add _write to value Helper to marshal state.
48 // write_value for value subclass calls parent._write
49 // -D61650<daz> Remove '\n' from generated strings; use println()'s.
51 import java.io.File;
52 import java.io.PrintWriter;
53 import java.util.Hashtable;
54 import java.util.Enumeration;
55 import java.util.Vector;
57 import com.sun.tools.corba.se.idl.GenFileStream;
58 import com.sun.tools.corba.se.idl.InterfaceEntry;
59 import com.sun.tools.corba.se.idl.SymtabEntry;
60 import com.sun.tools.corba.se.idl.TypedefEntry;
61 import com.sun.tools.corba.se.idl.ValueEntry;
62 import com.sun.tools.corba.se.idl.ValueBoxEntry;
63 import com.sun.tools.corba.se.idl.InterfaceState;
64 import com.sun.tools.corba.se.idl.MethodEntry;
65 import com.sun.tools.corba.se.idl.PrimitiveEntry;
66 import com.sun.tools.corba.se.idl.SequenceEntry;
67 import com.sun.tools.corba.se.idl.StringEntry;
68 import com.sun.tools.corba.se.idl.StructEntry;
70 /**
71 *
72 **/
73 public class ValueGen implements com.sun.tools.corba.se.idl.ValueGen, JavaGenerator
74 {
75 /**
76 * Public zero-argument constructor.
77 **/
78 public ValueGen ()
79 {
80 } // ctor
82 /**
83 *
84 **/
85 public void generate (Hashtable symbolTable, ValueEntry v, PrintWriter str)
86 {
87 this.symbolTable = symbolTable;
88 this.v = v;
89 init ();
91 openStream ();
92 if (stream == null)
93 return;
94 generateTie ();
95 generateHelper ();
96 generateHolder ();
97 writeHeading ();
98 writeBody ();
99 writeClosing ();
100 closeStream ();
101 } // generate
103 /**
104 * Initialize members unique to this generator.
105 **/
106 protected void init ()
107 {
108 emit = ((Arguments)Compile.compiler.arguments).emit;
109 factories = (Factories)Compile.compiler.factories ();
110 } // init
112 /**
113 *
114 **/
115 protected void openStream ()
116 {
117 stream = Util.stream (v, ".java");
118 } // openStream
120 /**
121 * Generate a Tie class only when the user specifies the TIE option
122 * and the valuetype does support an interface.
123 **/
124 protected void generateTie ()
125 {
126 boolean tie = ((Arguments)Compile.compiler.arguments).TIEServer;
127 if (v.supports ().size () > 0 && tie)
128 {
129 Factories factories = (Factories)Compile.compiler.factories ();
130 factories.skeleton ().generate (symbolTable, v);
131 }
132 } // generateTie
134 /**
135 *
136 **/
137 protected void generateHelper ()
138 {
139 ((Factories)Compile.compiler.factories ()).helper ().generate (symbolTable, v);
140 } // generateHelper
142 /**
143 *
144 **/
145 protected void generateHolder ()
146 {
147 ((Factories)Compile.compiler.factories ()).holder ().generate (symbolTable, v);
148 } // generateHolder
150 /**
151 *
152 **/
153 protected void writeHeading ()
154 {
155 Util.writePackage (stream, v);
156 Util.writeProlog (stream, ((GenFileStream)stream).name ());
158 if (v.comment () != null)
159 v.comment ().generate ("", stream);
161 if (v.isAbstract ())
162 {
163 writeAbstract ();
164 return;
165 }
166 else
167 stream.print ("public class " + v.name ());
169 // There should always be at least one parent: ValueBase
170 SymtabEntry parent = (SymtabEntry) v.derivedFrom ().elementAt (0);
172 // If parent is ValueBase, it's mapped to java.io.Serializable
173 String parentName = Util.javaName (parent);
174 boolean impl = false;
176 if (parentName.equals ("java.io.Serializable"))
177 {
178 // stream.print (" implements org.omg.CORBA.portable.ValueBase, org.omg.CORBA.portable.Streamable");
179 stream.print (" implements org.omg.CORBA.portable.ValueBase"); // <d60929>
180 impl = true;
181 }
182 else if ( !((ValueEntry)parent).isAbstract ())
183 stream.print (" extends " + parentName);
185 // if inheriting from abstract values
186 for (int i = 0; i < v.derivedFrom ().size (); i++) {
187 parent = (SymtabEntry) v.derivedFrom ().elementAt (i);
188 if ( ((ValueEntry)parent).isAbstract ())
189 {
190 if (!impl)
191 {
192 stream.print (" implements ");
193 impl = true;
194 }
195 else
196 stream.print (", ");
197 stream.print (Util.javaName (parent));
198 }
199 }
200 // <d59092-klr> Valuetype supporting interface implement Operations interface
201 // for supported IDL interface
202 if (((ValueEntry)v).supports ().size () > 0) {
203 if (!impl)
204 {
205 stream.print (" implements ");
206 impl = true;
207 }
208 else
209 stream.print (", ");
211 InterfaceEntry s =(InterfaceEntry)((ValueEntry)v).supports().elementAt(0);
212 // abstract supported classes don't have "Operations"
213 if (s.isAbstract ())
214 stream.print (Util.javaName (s));
215 else
216 stream.print (Util.javaName (s) + "Operations");
217 }
219 // <d59418> Custom valuetypes implement org.omg.CORBA.CustomMarshal.
220 if ( ((ValueEntry)v).isCustom ()) {
221 if (!impl)
222 {
223 stream.print (" implements ");
224 impl = true;
225 }
226 else
227 stream.print (", ");
229 stream.print ("org.omg.CORBA.CustomMarshal ");
230 }
232 stream.println ();
233 stream.println ("{");
234 } // writeHeading
236 /**
237 *
238 **/
239 protected void writeBody ()
240 {
241 writeMembers ();
242 writeInitializers ();
243 writeConstructor (); // <d57067>
244 writeTruncatable (); // <d60929>
245 writeMethods ();
246 } // writeBody
248 /**
249 *
250 **/
251 protected void writeClosing ()
252 {
253 if (v.isAbstract ())
254 stream.println ("} // interface " + v.name ());
255 else
256 stream.println ("} // class " + v.name ());
257 } // writeClosing
259 /**
260 *
261 **/
262 protected void closeStream ()
263 {
264 stream.close ();
265 } // closeStream
267 /**
268 *
269 **/
270 protected void writeConstructor ()
271 {
272 // Per Simon, 9/3/98, emit a protected default constructor
273 if (!v.isAbstract () && !explicitDefaultInit) { // <d57067 - klr>
274 stream.println (" protected " + v.name () + " () {}");
275 stream.println ();
276 }
277 } // writeConstructor
279 /**
280 *
281 **/
282 protected void writeTruncatable () // <d60929>
283 {
284 // Per Simon, 4/6/98, emit _truncatable_ids()
285 if (!v.isAbstract ()) {
286 stream.println (" public String[] _truncatable_ids() {");
287 stream.println (" return " + Util.helperName(v, true) + ".get_instance().get_truncatable_base_ids();"); // <d61056>
288 stream.println (" }");
289 stream.println ();
290 }
291 } // writeTruncatable
293 /**
294 *
295 **/
296 protected void writeMembers ()
297 {
298 // if the value type contains no data members, a null return is expected
299 if (v.state () == null)
300 return;
302 for (int i = 0; i < v.state ().size (); i ++)
303 {
304 InterfaceState member = (InterfaceState) v.state ().elementAt (i);
305 SymtabEntry entry = (SymtabEntry) member.entry;
306 Util.fillInfo (entry);
308 if (entry.comment () != null)
309 entry.comment ().generate (" ", stream);
311 String modifier = " ";
312 if (member.modifier == InterfaceState.Public)
313 modifier = " public ";
314 Util.writeInitializer (modifier, entry.name (), "", entry, stream);
315 }
316 } // writeMembers
318 /**
319 *
320 **/
321 protected void writeInitializers ()
322 {
323 Vector init = v.initializers ();
324 if (init != null)
325 {
326 stream.println ();
327 for (int i = 0; i < init.size (); i++)
328 {
329 MethodEntry element = (MethodEntry) init.elementAt (i);
330 element.valueMethod (true);
331 ((MethodGen) element.generator ()). interfaceMethod (symbolTable, element, stream);
332 if (element.parameters ().isEmpty ()) // <d57067-klr>
333 explicitDefaultInit = true;
334 }
335 }
336 } // writeInitializers
338 /**
339 *
340 **/
341 protected void writeMethods ()
342 {
343 // contained vector contains methods, attributes, const, enums, exceptions,
344 // structs, unions, or typedefs that are declared inside the value object.
345 // State members of the nested types are also included in this vector.
346 // Thus, if the declaration of a constructed type is nested in the decl.
347 // of a state member, e.g struct x {boolean b;} memberx;
348 // the generation of the nested type must be handled here.
349 Enumeration e = v.contained ().elements ();
350 while (e.hasMoreElements ())
351 {
352 SymtabEntry contained = (SymtabEntry)e.nextElement ();
353 if (contained instanceof MethodEntry)
354 {
355 MethodEntry element = (MethodEntry)contained;
356 ((MethodGen)element.generator ()).interfaceMethod (symbolTable, element, stream);
357 }
358 else
359 {
360 // Generate the type referenced by the typedef.
361 if (contained instanceof TypedefEntry)
362 contained.type ().generate (symbolTable, stream);
364 // Note that we also need to generate the typedef itself if
365 // contained is a typedef.
366 contained.generate (symbolTable, stream);
367 }
368 }
370 // Abstract values are mapped to interfaces. There is no need to generate
371 // the bindings for inheriting methods in case of inheritance from other
372 // abstract values or supporting interface
373 if (v.isAbstract ())
374 return;
376 // workaround: if the value type doesnot support any interfaces, a null
377 // return is expected instead of an empty vector
379 // if supporting an interfaces, generate bindings for inheriting methods
380 if (v.supports ().size () > 0)
381 {
382 InterfaceEntry intf = (InterfaceEntry) v.supports ().elementAt (0);
383 Enumeration el = intf.allMethods ().elements ();
384 while (el.hasMoreElements ())
385 {
386 MethodEntry m = (MethodEntry) el.nextElement ();
387 // <d59071> Don't alter the symbol table/emit list elements!
388 //m.container (v);
389 //((MethodGen)m.generator ()).interfaceMethod (symbolTable, m, stream);
390 MethodEntry mClone = (MethodEntry)m.clone ();
391 mClone.container (v);
392 ((MethodGen)mClone.generator ()).interfaceMethod (symbolTable, mClone, stream);
393 }
394 }
396 // if inheriting from abstract values, generating bindings for all
397 // inheriting methods
398 for (int i = 0; i < v.derivedFrom ().size (); i++) {
399 ValueEntry parentValue = (ValueEntry) v.derivedFrom ().elementAt (i);
400 if (parentValue.isAbstract ())
401 {
402 Enumeration el = parentValue.allMethods ().elements ();
403 while (el.hasMoreElements ())
404 {
405 MethodEntry m = (MethodEntry) el.nextElement ();
406 // <d59071> Don't alter the symbol table/emit list elements!
407 //m.container (v);
408 //((MethodGen)m.generator ()).interfaceMethod (symbolTable, m, stream);
409 MethodEntry mClone = (MethodEntry)m.clone ();
410 mClone.container (v);
411 ((MethodGen)mClone.generator ()).interfaceMethod (symbolTable, mClone, stream);
412 }
413 }
414 }
416 //writeStreamableMethods ();
417 } // writeMethods
419 /**
420 *
421 **/
422 protected void writeStreamableMethods ()
423 {
424 stream.println (" public void _read (org.omg.CORBA.portable.InputStream istream)");
425 stream.println (" {");
426 read (0, " ", "this", v, stream);
427 stream.println (" }");
428 stream.println ();
429 stream.println (" public void _write (org.omg.CORBA.portable.OutputStream ostream)");
430 stream.println (" {");
431 write (0, " ", "this", v, stream);
432 stream.println (" }");
433 stream.println ();
434 stream.println (" public org.omg.CORBA.TypeCode _type ()");
435 stream.println (" {");
436 stream.println (" return " + Util.helperName (v, false) + ".type ();"); // <d61056>
437 stream.println (" }");
438 } // writeStreamableMethods
440 ///////////////
441 // From JavaGenerator
443 public int helperType (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream)
444 {
445 ValueEntry vt = (ValueEntry) entry;
446 Vector state = vt.state ();
447 int noOfMembers = state == null ? 0 : state.size ();
448 String members = "_members" + index++;
449 String tcOfMembers = "_tcOf" + members;
451 stream.println (indent + "org.omg.CORBA.ValueMember[] "
452 + members + " = new org.omg.CORBA.ValueMember["
453 + noOfMembers
454 + "];");
455 stream.println (indent + "org.omg.CORBA.TypeCode " + tcOfMembers + " = null;");
456 //stream.println (""); // <d61650>
458 String definedInrepId = "_id";
459 String repId, version;
461 for (int k=0; k<noOfMembers; k++)
462 {
463 InterfaceState valueMember = (InterfaceState)state.elementAt (k);
464 TypedefEntry member = (TypedefEntry)valueMember.entry;
465 SymtabEntry mType = Util.typeOf (member);
466 if (hasRepId (member))
467 {
468 repId = Util.helperName (mType, true) + ".id ()"; // <d61056>
469 if (mType instanceof ValueEntry || mType instanceof ValueBoxEntry)
470 // OBV spec is silent on defining VersionSpec for valuetype RepIds
471 version = "\"\"";
472 else
473 {
474 String id = mType.repositoryID ().ID ();
475 version = '"' + id.substring (id.lastIndexOf (':')+1) + '"';
476 }
477 }
478 else
479 {
480 repId = "\"\"";
481 version = "\"\"";
482 }
484 // Get TypeCode for valuetype member and store it var. name given by tcOfMembers
485 stream.println (indent + "// ValueMember instance for " + member.name ());
486 index = ((JavaGenerator)member.generator ()).type (index, indent, tcoffsets, tcOfMembers, member, stream);
487 stream.println (indent + members + "[" + k + "] = new org.omg.CORBA.ValueMember (" // <d61650>
488 + '"' + member.name () + "\", "); // name
489 stream.println (indent + " " + repId + ", "); // id
490 stream.println (indent + " " + definedInrepId + ", "); // defined_in
491 stream.println (indent + " " + version + ", "); // version
492 stream.println (indent + " " + tcOfMembers + ", "); // type
493 stream.println (indent + " " + "null, "); // type_def
494 stream.println (indent + " " + "org.omg.CORBA." +
495 (valueMember.modifier == InterfaceState.Public ?
496 "PUBLIC_MEMBER" : "PRIVATE_MEMBER") + ".value" + ");"); // access
497 } // end for
499 stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_value_tc ("
500 + "_id, "
501 + '"' + entry.name () + "\", "
502 + getValueModifier (vt) + ", "
503 + getConcreteBaseTypeCode (vt) + ", "
504 + members
505 + ");");
507 return index;
508 } // helperType
510 public int type (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream) {
511 stream.println (indent + name + " = " + Util.helperName (entry, true) + ".type ();"); // <d61056>
512 return index;
513 } // type
515 // Check for types which don't have a Repository ID: primitive,
516 // string, arrays and sequences.
518 private static boolean hasRepId (SymtabEntry member)
519 {
520 SymtabEntry mType = Util.typeOf (member);
521 return !( mType instanceof PrimitiveEntry ||
522 mType instanceof StringEntry ||
523 ( mType instanceof TypedefEntry &&
524 !(((TypedefEntry)mType).arrayInfo ().isEmpty ()) ) ||
525 ( mType instanceof TypedefEntry && member.type () instanceof SequenceEntry) );
526 } // hasRepId
528 private static String getValueModifier (ValueEntry vt)
529 {
530 String mod = "NONE";
531 if (vt.isCustom ())
532 mod = "CUSTOM";
533 else if (vt.isAbstract ())
534 mod = "ABSTRACT";
535 else if (vt.isSafe ())
536 mod = "TRUNCATABLE";
537 return "org.omg.CORBA.VM_" + mod + ".value";
538 } // getValueModifier
540 private static String getConcreteBaseTypeCode (ValueEntry vt)
541 {
542 Vector v = vt.derivedFrom ();
543 if (!vt.isAbstract ())
544 {
545 SymtabEntry base = (SymtabEntry)vt.derivedFrom ().elementAt (0);
546 if (!"ValueBase".equals (base.name ()))
547 return Util.helperName (base, true) + ".type ()"; // <d61056>
548 }
549 return "null";
550 } // getConcreteBaseTypeCode
552 public void helperRead (String entryName, SymtabEntry entry, PrintWriter stream)
553 {
554 // <d59418 - KLR> per Simon, make "static" read call istream.read_value.
555 // put real marshalling code in read_value.
557 if (((ValueEntry)entry).isAbstract ())
558 {
559 stream.println (" throw new org.omg.CORBA.BAD_OPERATION (\"abstract value cannot be instantiated\");");
560 }
561 else
562 {
563 stream.println (" return (" + entryName +") ((org.omg.CORBA_2_3.portable.InputStream) istream).read_value (get_instance());"); // <d60929>
564 }
565 stream.println (" }");
566 stream.println ();
568 // done with "read", now do "read_value with real marshalling code.
570 stream.println (" public java.io.Serializable read_value (org.omg.CORBA.portable.InputStream istream)"); // <d60929>
571 stream.println (" {");
573 // per Simon, 3/3/99, read_value for custom values throws an exception
574 if (((ValueEntry)entry).isAbstract ())
575 {
576 stream.println (" throw new org.omg.CORBA.BAD_OPERATION (\"abstract value cannot be instantiated\");");
577 }
578 else
579 if (((ValueEntry)entry).isCustom ())
580 {
581 stream.println (" throw new org.omg.CORBA.BAD_OPERATION (\"custom values should use unmarshal()\");");
582 }
583 else
584 {
585 stream.println (" " + entryName + " value = new " + entryName + " ();");
586 read (0, " ", "value", entry, stream);
587 stream.println (" return value;");
588 }
589 stream.println (" }");
590 stream.println ();
591 // End of normal read method
593 // Per Simon, 8/26/98 - Value helpers get an additional overloaded
594 // read method where the value is passed in instead of "new'd" up. This is
595 // used for reading parent value state.
597 // Per Simon, 3/3/99 - Don't change this "read" for custom marshalling
598 stream.println (" public static void read (org.omg.CORBA.portable.InputStream istream, " + entryName + " value)");
599 stream.println (" {");
600 read (0, " ", "value", entry, stream);
601 } // helperRead
603 public int read (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
604 {
605 // First do the state members from concrete parent hierarchy
606 Vector vParents = ((ValueEntry) entry).derivedFrom ();
607 if (vParents != null && vParents.size() != 0)
608 {
609 ValueEntry parent = (ValueEntry) vParents.elementAt (0);
610 if (parent == null)
611 return index;
612 // Per Simon, 4/6/99 - call parent read. <d60929>
613 if (! Util.javaQualifiedName(parent).equals ("java.io.Serializable")) // <d60929>
614 stream.println(indent + Util.helperName (parent, true) + ".read (istream, value);"); // <d60929> // <d61056>
615 }
617 Vector vMembers = ((ValueEntry) entry).state ();
618 int noOfMembers = vMembers == null ? 0 : vMembers.size ();
620 for (int k = 0; k < noOfMembers; k++)
621 {
622 TypedefEntry member = (TypedefEntry)((InterfaceState)vMembers.elementAt (k)).entry;
623 String memberName = member.name ();
624 SymtabEntry mType = member.type ();
626 if (mType instanceof PrimitiveEntry ||
627 mType instanceof TypedefEntry ||
628 mType instanceof SequenceEntry ||
629 mType instanceof StringEntry ||
630 !member.arrayInfo ().isEmpty ())
631 index = ((JavaGenerator)member.generator ()).read (index, indent, name + '.' + memberName, member, stream);
632 else if (mType instanceof ValueEntry)
633 {
634 String returnType = Util.javaQualifiedName (mType);
635 if (mType instanceof ValueBoxEntry)
636 // <f46082.51> Remove -stateful.
637 //returnType = Util.javaStatefulName (mType);
638 returnType = Util.javaName (mType);
639 stream.println (" " + name + '.' + memberName + " = (" + returnType +
640 ") ((org.omg.CORBA_2_3.portable.InputStream)istream).read_value (" + Util.helperName (mType, true) + // <d61056>
641 ".get_instance ());"); // <d61056>
642 }
643 else
644 stream.println (indent + name + '.' + memberName + " = " +
645 Util.helperName (mType, true) + ".read (istream);"); // <d61056>
646 }
648 return index;
649 } // read
651 public void helperWrite (SymtabEntry entry, PrintWriter stream)
652 {
653 // <d59418 - KLR> per Simon, make "static" write call istream.write_value.
654 // put real marshalling code in write_value.
655 stream.println (" ((org.omg.CORBA_2_3.portable.OutputStream) ostream).write_value (value, get_instance());"); // <d60929>
656 stream.println (" }");
657 stream.println ();
659 // <d62062>
660 // per Simon, 4/27/99, add static _write that marshals the state of this
661 // value for non-custom valuetypes
662 if (!((ValueEntry)entry).isCustom ())
663 {
664 stream.println (" public static void _write (org.omg.CORBA.portable.OutputStream ostream, " + Util.javaName (entry) + " value)");
665 stream.println (" {");
666 write (0, " ", "value", entry, stream);
667 stream.println (" }");
668 stream.println ();
669 }
671 // done with "_write", now do "write_value
672 stream.println (" public void write_value (org.omg.CORBA.portable.OutputStream ostream, java.io.Serializable obj)"); // <d60929>
673 stream.println (" {");
675 // per Simon, 3/3/99, write_value for custom values throws an exception
676 if (((ValueEntry)entry).isCustom ())
677 {
678 stream.println (" throw new org.omg.CORBA.BAD_OPERATION (\"custom values should use marshal()\");");
679 }
680 else {
681 String entryName = Util.javaName(entry);
682 stream.println (" _write (ostream, (" + entryName + ") obj);"); // <d62062>
683 // write (0, " ", "value", entry, stream); <d62062>
684 }
685 } // helperWrite
687 public int write (int index, String indent, String name, SymtabEntry entry, PrintWriter stream)
688 {
689 // First do the state members from concrete parent hierarchy
690 Vector vParents = ((ValueEntry)entry).derivedFrom ();
691 if (vParents != null && vParents.size () != 0)
692 {
693 ValueEntry parent = (ValueEntry)vParents.elementAt (0);
694 if (parent == null)
695 return index;
696 // Per Simon, 4/06/99 - call parent write. <d60929>
697 // Per Simon, 4/27/99 - call parent _write. <d62062>
698 if (! Util.javaQualifiedName(parent).equals ("java.io.Serializable")) // <d60929>
699 stream.println(indent + Util.helperName (parent, true) + "._write (ostream, value);"); // <d60929> <d61056> <d62062>
700 }
702 Vector vMembers = ((ValueEntry) entry ).state ();
703 int noOfMembers = vMembers == null ? 0 : vMembers.size ();
704 for (int k = 0; k < noOfMembers; k++)
705 {
706 TypedefEntry member = (TypedefEntry)((InterfaceState)vMembers.elementAt (k)).entry;
707 String memberName = member.name ();
708 SymtabEntry mType = member.type ();
710 if (mType instanceof PrimitiveEntry ||
711 mType instanceof TypedefEntry ||
712 mType instanceof SequenceEntry ||
713 mType instanceof StringEntry ||
714 !member.arrayInfo ().isEmpty ())
715 index = ((JavaGenerator)member.generator ()).write (index, indent, name + '.' + memberName, member, stream);
716 else
717 stream.println (indent + Util.helperName (mType, true) + // <d61056>
718 ".write (ostream, " + name + '.' + memberName + ");");
719 }
721 return index;
722 } // write
724 /**
725 *
726 **/
727 protected void writeAbstract ()
728 {
729 stream.print ("public interface " + v.name ());
731 // workaround: if the abstract value type does not have any parent, a vector
732 // containing ValueBase should be returned instead of an empty vector
733 if (v.derivedFrom ().size () == 0)
734 stream.print (" extends org.omg.CORBA.portable.ValueBase"); // <d60929>
735 else
736 {
737 SymtabEntry parent;
738 // list the values the abstract value type inherits
739 for (int i = 0; i < v.derivedFrom ().size (); i++)
740 {
741 if (i == 0)
742 stream.print (" extends ");
743 else
744 stream.print (", ");
745 parent = (SymtabEntry) v.derivedFrom ().elementAt (i);
746 stream.print (Util.javaName (parent));
747 }
748 }
750 // list the interface the abstract value type supports
751 if (v.supports ().size () > 0)
752 {
753 stream.print (", ");
754 SymtabEntry intf = (SymtabEntry) v.supports ().elementAt (0);
755 stream.print (Util.javaName (intf));
756 }
757 stream.println ();
758 stream.println ("{");
759 }
761 protected int emit = 0;
762 protected Factories factories = null;
763 protected Hashtable symbolTable = null;
764 protected ValueEntry v = null;
765 protected PrintWriter stream = null;
766 protected boolean explicitDefaultInit = false; // <d57067 - klr>
767 } // class ValueGen