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 36 package com.sun.tools.corba.se.idl.toJavaPortable; 37 38 // NOTES: 39 // - Think about arrays (and sequences?) as members 40 // - A sequence must be converted to an array, but a memory of the 41 // max size must be retained. 42 // - After demarshalling an IOR, think about how to deal with the exceptions. 43 // - The demarshall method should be throwing a ClientException, 44 // but should it, really? 45 // -D60929 <klr> Update for RTF2.4 changes 46 // -D61056 <klr> Use Util.helperName 47 // -D62023 <klr> Use corbaLevel in read/write generation 48 // -D59437 <daz> Modify read() to enit qualified name of value box helper. 49 50 import java.io.File; 51 import java.io.PrintWriter; 52 import java.util.Enumeration; 53 import java.util.Hashtable; 54 import java.util.Vector; 55 56 import com.sun.tools.corba.se.idl.GenFileStream; 57 import com.sun.tools.corba.se.idl.EnumEntry; 58 import com.sun.tools.corba.se.idl.InterfaceEntry; 59 import com.sun.tools.corba.se.idl.PrimitiveEntry; 60 import com.sun.tools.corba.se.idl.SequenceEntry; 61 import com.sun.tools.corba.se.idl.StringEntry; 62 import com.sun.tools.corba.se.idl.StructEntry; 63 import com.sun.tools.corba.se.idl.SymtabEntry; 64 import com.sun.tools.corba.se.idl.TypedefEntry; 65 import com.sun.tools.corba.se.idl.ValueEntry; 66 import com.sun.tools.corba.se.idl.ValueBoxEntry; 67 import com.sun.tools.corba.se.idl.InterfaceState; 68 69 /** 70 * 71 **/ 72 public class StructGen implements com.sun.tools.corba.se.idl.StructGen, JavaGenerator 73 { 74 /** 75 * Public zero-argument constructor. 76 **/ 77 public StructGen () 78 { 79 } // ctor 80 81 /** 82 * Constructor for ExceptionGen. 83 **/ 84 protected StructGen (boolean exception) 85 { 86 thisIsReallyAnException = exception; 87 } // ctor 88 89 /** 90 * 91 **/ 92 public void generate (Hashtable symbolTable, StructEntry s, PrintWriter str) 93 { 94 this.symbolTable = symbolTable; 95 this.s = s; 96 //init (); 97 98 openStream (); 99 if (stream == null) 100 return; 101 generateHelper (); 102 generateHolder (); 103 writeHeading (); 104 writeBody (); 105 writeClosing (); 106 closeStream (); 107 generateContainedTypes (); 108 } // generate 109 110 /** 111 * Initialize members unique to this generator. 112 **/ 113 protected void init () 114 { 115 } // init 116 117 /** 118 * 119 **/ 120 protected void openStream () 121 { 122 stream = Util.stream (s, ".java"); 123 } // openStream 124 125 /** 126 * 127 **/ 128 protected void generateHelper () 129 { 130 ((Factories)Compile.compiler.factories ()).helper ().generate (symbolTable, s); 131 } // generateHelper 132 133 /** 134 * 135 **/ 136 protected void generateHolder () 137 { 138 ((Factories)Compile.compiler.factories ()).holder ().generate (symbolTable, s); 139 } // generateHolder 140 141 /** 142 * 143 **/ 144 protected void writeHeading () 145 { 146 Util.writePackage (stream, s); 147 Util.writeProlog (stream, ((GenFileStream)stream).name ()); 148 149 if (s.comment () != null) 150 s.comment ().generate ("", stream); 151 152 stream.print ("public final class " + s.name ()); 153 if (thisIsReallyAnException) 154 stream.print (" extends org.omg.CORBA.UserException"); 155 else 156 stream.print(" implements org.omg.CORBA.portable.IDLEntity"); 157 stream.println (); 158 stream.println ("{"); 159 } // writeHeading 160 161 /** 162 * 163 **/ 164 protected void writeBody () 165 { 166 writeMembers (); 167 writeCtors (); 168 } // writeBody 169 170 /** 171 * 172 **/ 173 protected void writeClosing () 174 { 175 stream.println ("} // class " + s.name ()); 176 } // writeClosing 177 178 /** 179 * 180 **/ 181 protected void closeStream () 182 { 183 stream.close (); 184 } // closeStream 185 186 /** 187 * 188 **/ 189 protected void generateContainedTypes () 190 { 191 // Generate all of the contained types 192 Enumeration e = s.contained ().elements (); 193 while (e.hasMoreElements ()) 194 { 195 SymtabEntry entry = (SymtabEntry)e.nextElement (); 196 197 // Don't generate contained entries if they are sequences. 198 // Sequences are unnamed and since they translate to arrays, 199 // no classes are generated for them, not even holders in this 200 // case since they cannot be accessed outside of this struct. 201 202 if (!(entry instanceof SequenceEntry)) 203 entry.generate (symbolTable, stream); 204 } 205 } // generateContainedTypes 206 207 /** 208 * 209 **/ 210 protected void writeMembers () 211 { 212 // Write members and populate quality arrays 213 int size = s.members ().size (); 214 memberIsPrimitive = new boolean [size]; 215 memberIsInterface = new boolean [size]; 216 memberIsTypedef = new boolean [size]; 217 for (int i = 0; i < s.members ().size (); ++i) 218 { 219 SymtabEntry member = (SymtabEntry)s.members ().elementAt (i); 220 memberIsPrimitive[i] = member.type () instanceof PrimitiveEntry; 221 memberIsInterface[i] = member.type () instanceof InterfaceEntry; 222 memberIsTypedef[i] = member.type () instanceof TypedefEntry; 223 Util.fillInfo (member); 224 // Transfer member comment to target <31jul1997>. 225 if (member.comment () != null) 226 member.comment ().generate (" ", stream); 227 Util.writeInitializer (" public ", member.name (), "", member, stream); 228 } 229 } // writeMembers 230 231 /** 232 * 233 **/ 234 protected void writeCtors () 235 { 236 // Write default ctor 237 stream.println (); 238 stream.println (" public " + s.name () + " ()"); 239 stream.println (" {"); 240 // fixed mapping for exceptions 241 if (thisIsReallyAnException) 242 stream.println (" super(" + s.name() + "Helper.id());"); 243 stream.println (" } // ctor"); 244 writeInitializationCtor(true); 245 if (thisIsReallyAnException) { 246 // for exception according to mapping we should always 247 // have a full constructor 248 writeInitializationCtor(false); 249 } 250 } 251 252 private void writeInitializationCtor(boolean init) 253 { 254 // Write initialization ctor 255 if (!init || (s.members ().size () > 0)) 256 { 257 stream.println (); 258 stream.print (" public " + s.name () + " ("); 259 boolean firstTime = true; 260 if (!init) { 261 stream.print ("String $reason"); 262 firstTime = false; 263 } 264 265 for (int i = 0; i < s.members ().size (); ++i) 266 { 267 SymtabEntry member = (SymtabEntry)s.members ().elementAt (i); 268 if (firstTime) 269 firstTime = false; 270 else 271 stream.print (", "); 272 stream.print (Util.javaName (member) + " _" + member.name ()); 273 } 274 stream.println (")"); 275 stream.println (" {"); 276 // fixed mapping for exceptions 277 if (thisIsReallyAnException) { 278 if (init) 279 stream.println (" super(" + s.name() + "Helper.id());"); 280 else 281 stream.println (" super(" + s.name() + "Helper.id() + \" \" + $reason);"); 282 } 283 for (int i = 0; i < s.members ().size (); ++i) 284 { 285 SymtabEntry member = (SymtabEntry)s.members ().elementAt (i); 286 stream.println (" " + member.name () + " = _" + member.name () + ";"); 287 } 288 stream.println (" } // ctor"); 289 } 290 stream.println (); 291 } // writeInitializationCtor 292 293 /////////////// 294 // From JavaGenerator 295 296 public int helperType (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream) 297 { 298 TCOffsets innerOffsets = new TCOffsets (); 299 innerOffsets.set (entry); 300 int offsetForStruct = innerOffsets.currentOffset (); 301 StructEntry s = (StructEntry)entry; 302 String membersName = "_members" + index++; 303 stream.println (indent + "org.omg.CORBA.StructMember[] " + membersName + " = new org.omg.CORBA.StructMember [" + s.members ().size () + "];"); 304 String tcOfMembers = "_tcOf" + membersName; 305 stream.println (indent + "org.omg.CORBA.TypeCode " + tcOfMembers + " = null;"); 306 for (int i = 0; i < s.members ().size (); ++i) 307 { 308 TypedefEntry member = (TypedefEntry)s.members ().elementAt (i); 309 String memberName = member.name (); 310 // Generate and assign member TypeCode to tcofMembers 311 index = ((JavaGenerator)member.generator ()).type (index, indent, innerOffsets, tcOfMembers, member, stream); 312 stream.println (indent + membersName + '[' + i + "] = new org.omg.CORBA.StructMember ("); 313 stream.println (indent + " \"" + Util.stripLeadingUnderscores (memberName) + "\","); 314 stream.println (indent + " " + tcOfMembers + ','); 315 stream.println (indent + " null);"); 316 int offsetSoFar = innerOffsets.currentOffset (); 317 innerOffsets = new TCOffsets (); 318 innerOffsets.set (entry); 319 innerOffsets.bumpCurrentOffset (offsetSoFar - offsetForStruct); 320 321 } 322 tcoffsets.bumpCurrentOffset (innerOffsets.currentOffset ()); 323 // <54697> 324 //stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_struct_tc (id (), \"" + Util.stripLeadingUnderscores (entry.name ()) + "\", " + membersName + ");"); 325 stream.println (indent + name + " = org.omg.CORBA.ORB.init ().create_" + (thisIsReallyAnException ? "exception" : "struct") + "_tc (" + Util.helperName (s, true) + ".id (), \"" + Util.stripLeadingUnderscores (entry.name ()) + "\", " + membersName + ");"); // <d61056> 326 return index; 327 } // helperType 328 329 public int type (int index, String indent, TCOffsets tcoffsets, String name, SymtabEntry entry, PrintWriter stream) { 330 stream.println (indent + name + " = " + Util.helperName (entry, true) + ".type ();"); // <d61056> 331 return index; 332 } // type 333 334 public void helperRead (String entryName, SymtabEntry entry, PrintWriter stream) 335 { 336 stream.println (" " + entryName + " value = new " + entryName + " ();"); 337 read (0, " ", "value", entry, stream); 338 stream.println (" return value;"); 339 } // helperRead 340 341 public int read (int index, String indent, String name, SymtabEntry entry, PrintWriter stream) 342 { 343 if (thisIsReallyAnException) 344 { 345 stream.println (indent + "// read and discard the repository ID"); 346 stream.println (indent + "istream.read_string ();"); 347 } 348 349 Enumeration e = ((StructEntry)entry).members ().elements (); 350 while (e.hasMoreElements ()) 351 { 352 TypedefEntry member = (TypedefEntry)e.nextElement (); 353 SymtabEntry mType = member.type (); 354 355 if (!member.arrayInfo ().isEmpty () || mType instanceof SequenceEntry || 356 mType instanceof PrimitiveEntry || mType instanceof StringEntry || 357 mType instanceof TypedefEntry) 358 index = ((JavaGenerator)member.generator ()).read (index, indent, name + '.' + member.name (), member, stream); 359 else if (mType instanceof ValueBoxEntry) 360 { 361 // call read_value instead of Helper.read for the value 362 Vector st = ((ValueBoxEntry) mType).state (); 363 TypedefEntry vbMember = ((InterfaceState) st.elementAt (0)).entry; 364 SymtabEntry vbType = vbMember.type (); 365 366 String jName = null; 367 String jHelper = null; 368 369 if (vbType instanceof SequenceEntry || vbType instanceof StringEntry || 370 !vbMember.arrayInfo ().isEmpty ()) 371 { 372 jName = Util.javaName (vbType); // name of mapped Java type 373 // <d59437> REVISIT. Typename info. now correct for value boxes, so 374 // these two cases may be obsolete. See UnionGen.read(). 375 //jHelper = Util.helperName (vbType, false); // <d61056> 376 jHelper = Util.helperName (mType, true); 377 } 378 else 379 { 380 jName = Util.javaName (mType); // name of mapped Java class 381 // <d59437> 382 //jHelper = Util.helperName (mType, false); // <d61056> 383 jHelper = Util.helperName (mType, true); 384 } 385 // <d62023> Call xHelper.read() for valueboxes for RTF2.4 386 if (Util.corbaLevel (2.4f, 99.0f)) 387 stream.println (indent + name + '.' + member.name () + " = (" + jName + ") " + jHelper + ".read (istream);"); 388 else 389 stream.println (indent + name + '.' + member.name () + " = (" + jName + ") ((org.omg.CORBA_2_3.portable.InputStream)istream).read_value (" + jHelper + ".get_instance ());"); // <d60929> <d61056> 390 } 391 // <d62023-klr> for corbaLevel 2.4 and up, use Helper.read like 392 // everything else 393 else if ((mType instanceof ValueEntry) && 394 !Util.corbaLevel (2.4f, 99.0f)) // <d62023> 395 { 396 // call read_value instead of Helper.read for the value 397 stream.println (indent + name + '.' + member.name () + " = (" + Util.javaName (mType) + ") ((org.omg.CORBA_2_3.portable.InputStream)istream).read_value (" + Util.helperName (mType, false) + ".get_instance ());"); // <d60929> // <d61056> 398 } 399 else 400 stream.println (indent + name + '.' + member.name () + " = " + Util.helperName (member.type (), true) + ".read (istream);"); // <d61056> 401 } 402 return index; 403 } // read 404 405 public void helperWrite (SymtabEntry entry, PrintWriter stream) 406 { 407 write (0, " ", "value", entry, stream); 408 } // helperWrite 409 410 public int write (int index, String indent, String name, SymtabEntry entry, PrintWriter stream) 411 { 412 if (thisIsReallyAnException) 413 { 414 stream.println (indent + "// write the repository ID"); 415 stream.println (indent + "ostream.write_string (id ());"); 416 } 417 418 Vector members = ((StructEntry)entry).members (); 419 for (int i = 0; i < members.size (); ++i) 420 { 421 TypedefEntry member = (TypedefEntry)members.elementAt (i); 422 SymtabEntry mType = member.type (); 423 424 if (!member.arrayInfo ().isEmpty () || mType instanceof SequenceEntry || 425 mType instanceof TypedefEntry || mType instanceof PrimitiveEntry || 426 mType instanceof StringEntry) 427 index = ((JavaGenerator)member.generator ()).write (index, " ", name + '.' + member.name (), member, stream); 428 429 // <d62023-klr> for corbaLevel 2.4 and up, use Helper.write like 430 // everything else 431 else if ((mType instanceof ValueEntry || mType instanceof ValueBoxEntry) 432 && !Util.corbaLevel (2.4f, 99.0f)) { // <d62023> 433 stream.println (indent + "((org.omg.CORBA_2_3.portable.OutputStream)ostream).write_value ((java.io.Serializable) " // <d60929> 434 + name + '.' + member.name () + ", " 435 + Util.helperName (member.type (), true) // <d61056> 436 + ".get_instance ());"); // <d61056> 437 } 438 else 439 stream.println (indent + Util.helperName (member.type (), true) + ".write (ostream, " + name + '.' + member.name () + ");"); // <d61056> 440 } 441 return index; 442 } // write 443 444 // From JavaGenerator 445 /////////////// 446 447 protected Hashtable symbolTable = null; 448 protected StructEntry s = null; 449 protected PrintWriter stream = null; 450 451 protected boolean thisIsReallyAnException = false; 452 private boolean[] memberIsPrimitive; 453 private boolean[] memberIsInterface; 454 private boolean[] memberIsTypedef; 455 } // class StructGen