Skeleton.java revision 608:7e06bf1dcb09
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 36package com.sun.tools.corba.se.idl.toJavaPortable; 37 38// NOTES: 39// -F46082.51<daz> Remove -stateful feature; javaStatefulName() obsolete. 40// -D57147 <klr> Make _Tie implement org.omg.CORBA.portable.InvokeHandler 41// -D58037 <klr> Make _Tie delegate to Operations interface 42// -D62739 <klr> no TIE for values that support abstract interfaces, etc. 43 44import java.io.File; 45import java.io.PrintWriter; 46 47import java.util.Enumeration; 48import java.util.Hashtable; 49import java.util.Vector; 50 51import com.sun.tools.corba.se.idl.AttributeEntry; 52import com.sun.tools.corba.se.idl.GenFileStream; 53 54import com.sun.tools.corba.se.idl.InterfaceEntry; 55import com.sun.tools.corba.se.idl.InterfaceState; 56import com.sun.tools.corba.se.idl.MethodEntry; 57import com.sun.tools.corba.se.idl.SymtabEntry; 58import com.sun.tools.corba.se.idl.TypedefEntry; 59import com.sun.tools.corba.se.idl.ValueEntry; 60 61/** 62 * 63 **/ 64public class Skeleton implements AuxGen 65{ 66 private NameModifier skeletonNameModifier ; 67 private NameModifier tieNameModifier ; 68 69 public Skeleton () 70 { 71 } 72 73 public void generate (Hashtable symbolTable, SymtabEntry entry) 74 { 75 // <d62739-begin> 76 // Per Simon, 5-12-99, don't generate TIE or Skeleton for 77 // 78 // 1) valuetypes supporting abstract interfaces 79 // 2) valuetypes with no supports. 80 // 3) abstract interfaces 81 // 82 if (entry instanceof ValueEntry) 83 { 84 ValueEntry v = (ValueEntry) entry; 85 if ((v.supports ().size () == 0) || 86 ((InterfaceEntry) v.supports ().elementAt (0)).isAbstract ()) { 87 return; 88 } 89 } 90 if (((InterfaceEntry) entry).isAbstract ()) { 91 return; 92 } 93 // <d62739-end> 94 95 this.symbolTable = symbolTable; 96 97 this.i = (InterfaceEntry)entry; 98 init (); 99 openStream (); 100 if (stream == null) 101 return; 102 writeHeading (); 103 writeBody (); 104 writeClosing (); 105 closeStream (); 106 } // generate 107 108 /** 109 * Initialize members unique to this generator. 110 **/ 111 protected void init () 112 { 113 tie = ((Arguments)Compile.compiler.arguments).TIEServer ; 114 poa = ((Arguments)Compile.compiler.arguments).POAServer ; 115 116 skeletonNameModifier = 117 ((Arguments)Compile.compiler.arguments).skeletonNameModifier ; 118 tieNameModifier = 119 ((Arguments)Compile.compiler.arguments).tieNameModifier ; 120 121 tieClassName = tieNameModifier.makeName( i.name() ) ; 122 skeletonClassName = skeletonNameModifier.makeName( i.name() ) ; 123 124 intfName = Util.javaName (i); 125 // for valuetype, get the name of the interface the valuetype supports 126 if (i instanceof ValueEntry) 127 { 128 ValueEntry v = (ValueEntry) i; 129 InterfaceEntry intf = (InterfaceEntry) v.supports ().elementAt (0); 130 intfName = Util.javaName (intf); 131 } 132 } // init 133 134 protected void openStream () 135 { 136 if (tie) 137 stream = Util.stream( i, tieNameModifier, ".java" ) ; 138 else 139 stream = Util.stream( i, skeletonNameModifier, ".java" ) ; 140 } // openStream 141 142 protected void writeHeading () 143 { 144 Util.writePackage (stream, i, Util.StubFile); 145 Util.writeProlog (stream, ((GenFileStream)stream).name ()); 146 if (i.comment () != null) 147 i.comment ().generate ("", stream); 148 writeClassDeclaration (); 149 stream.println ('{'); 150 stream.println (); 151 } // writeHeading 152 153 protected void writeClassDeclaration () 154 { 155 if (tie){ 156 stream.println ("public class " + tieClassName + 157 " extends " + skeletonClassName ) ; 158 } else { 159 if (poa) { 160 stream.println ("public abstract class " + skeletonClassName + 161 " extends org.omg.PortableServer.Servant"); 162 stream.print (" implements " + intfName + "Operations, "); 163 stream.println ("org.omg.CORBA.portable.InvokeHandler"); 164 } else { 165 stream.println ("public abstract class " + skeletonClassName + 166 " extends org.omg.CORBA.portable.ObjectImpl"); 167 stream.print (" implements " + intfName + ", "); 168 stream.println ("org.omg.CORBA.portable.InvokeHandler"); 169 } 170 } 171 } // writeClassDeclaration 172 173 /** 174 * 175 **/ 176 protected void writeBody () 177 { 178 // <f46082.51> Remove -stateful feature. ????? 179 //if (i.state () != null) 180 // writeState (); 181 writeCtors (); 182 if (i instanceof ValueEntry) 183 { 184 // use the interface the valuetype supports to generate the 185 // tie class instead of using the valuetype itself 186 ValueEntry v = (ValueEntry) i; 187 this.i = (InterfaceEntry) v.supports ().elementAt (0); 188 } 189 buildMethodList (); 190 //DispatchMethod and MethodTable 191 if (tie){ //Concrete class implementing the remote interface 192 //The logic is here for future use 193 if (poa) { 194 writeMethods (); 195 stream.println (" private " + intfName + "Operations _impl;"); 196 stream.println (" private org.omg.PortableServer.POA _poa;"); 197 } else { 198 writeMethods (); 199 stream.println (" private " + intfName + "Operations _impl;"); 200 } 201 } else { //Both POA and ImplBase are abstract InvokeHandler 202 //The logic is here for future use 203 if (poa) { 204 writeMethodTable (); 205 writeDispatchMethod (); 206 writeCORBAOperations (); 207 } else { 208 writeMethodTable (); 209 writeDispatchMethod (); 210 writeCORBAOperations (); 211 } 212 } 213 //legacy !! 214 writeOperations (); 215 } // writeBody 216 217 /** 218 * Close the skeleton class. The singleton ORB member is 219 * necessary only for portable skeletons. 220 **/ 221 protected void writeClosing () 222 { 223 stream.println (); 224 if (tie){ 225 stream.println ("} // class " + tieClassName); 226 } else { 227 stream.println ("} // class " + skeletonClassName); 228 } 229 } // writeClosing 230 231 /** 232 * Close the print stream, which flushes the stream to file. 233 **/ 234 protected void closeStream () 235 { 236 stream.close (); 237 } // closeStream 238 239 protected void writeCtors () 240 { 241 stream.println (" // Constructors"); 242 // Empty argument constructors 243 if (!poa) { 244 if (tie){ 245 stream.println (" public " + tieClassName + " ()"); 246 stream.println (" {"); 247 stream.println (" }"); 248 } else { 249 stream.println (" public " + skeletonClassName + " ()"); 250 stream.println (" {"); 251 stream.println (" }"); 252 } 253 } 254 stream.println (); 255 // Argumented constructors 256 if (tie){ 257 if (poa) { 258 //Write constructors 259 writePOATieCtors(); 260 //Write state setters and getters 261 writePOATieFieldAccessMethods(); 262 } else { 263 stream.println (" public " + tieClassName + 264 " (" + intfName + "Operations impl)"); 265 stream.println (" {"); 266 // Does it derive from a interface having state, e.g., valuetype? 267 if (((InterfaceEntry)i.derivedFrom ().firstElement ()).state () != null) 268 stream.println (" super (impl);"); 269 else 270 stream.println (" super ();"); 271 stream.println (" _impl = impl;"); 272 stream.println (" }"); 273 stream.println (); 274 } 275 } else { //Skeleton is not Tie so it has no constructors. 276 if (poa) { 277 } else { 278 } 279 } 280 281 } // writeCtors 282 283 284 private void writePOATieCtors(){ 285 //First constructor 286 stream.println (" public " + tieClassName + " ( " + intfName + "Operations delegate ) {"); 287 stream.println (" this._impl = delegate;"); 288 stream.println (" }"); 289 //Second constructor specifying default poa. 290 stream.println (" public " + tieClassName + " ( " + intfName + 291 "Operations delegate , org.omg.PortableServer.POA poa ) {"); 292 stream.println (" this._impl = delegate;"); 293 stream.println (" this._poa = poa;"); 294 stream.println (" }"); 295 } 296 297 private void writePOATieFieldAccessMethods(){ 298 //Getting delegate 299 stream.println (" public " + intfName+ "Operations _delegate() {"); 300 stream.println (" return this._impl;"); 301 stream.println (" }"); 302 //Setting delegate 303 stream.println (" public void _delegate (" + intfName + "Operations delegate ) {"); 304 stream.println (" this._impl = delegate;"); 305 stream.println (" }"); 306 //Overriding default poa 307 stream.println (" public org.omg.PortableServer.POA _default_POA() {"); 308 stream.println (" if(_poa != null) {"); 309 stream.println (" return _poa;"); 310 stream.println (" }"); 311 stream.println (" else {"); 312 stream.println (" return super._default_POA();"); 313 stream.println (" }"); 314 stream.println (" }"); 315 } 316 317 /** 318 * Build a list of all of the methods, keeping out duplicates. 319 **/ 320 protected void buildMethodList () 321 { 322 // Start from scratch 323 methodList = new Vector (); 324 325 buildMethodList (i); 326 } // buildMethodList 327 328 /** 329 * 330 **/ 331 private void buildMethodList (InterfaceEntry entry) 332 { 333 // Add the local methods 334 Enumeration locals = entry.methods ().elements (); 335 while (locals.hasMoreElements ()) 336 addMethod ((MethodEntry)locals.nextElement ()); 337 338 // Add the inherited methods 339 Enumeration parents = entry.derivedFrom ().elements (); 340 while (parents.hasMoreElements ()) 341 { 342 InterfaceEntry parent = (InterfaceEntry)parents.nextElement (); 343 if (!parent.name ().equals ("Object")) 344 buildMethodList (parent); 345 } 346 } // buildMethodList 347 348 /** 349 * 350 **/ 351 private void addMethod (MethodEntry method) 352 { 353 if (!methodList.contains (method)) 354 methodList.addElement (method); 355 } // addMethod 356 357 /** 358 * 359 **/ 360 protected void writeDispatchMethod () 361 { 362 String indent = " "; 363 stream.println (" public org.omg.CORBA.portable.OutputStream _invoke (String $method,"); 364 stream.println (indent + "org.omg.CORBA.portable.InputStream in,"); 365 stream.println (indent + "org.omg.CORBA.portable.ResponseHandler $rh)"); 366 stream.println (" {"); 367 368 // this is a special case code generation for cases servantLocator and 369 // servantActivator, where OMG is taking too long to define them 370 // as local objects 371 372 boolean isLocalInterface = false; 373 if (i instanceof InterfaceEntry) { 374 isLocalInterface = i.isLocalServant(); 375 } 376 377 if (!isLocalInterface) { 378 // Per Simon 8/26/98, create and return reply stream for all methods - KLR 379 stream.println (" org.omg.CORBA.portable.OutputStream out = null;"); 380 stream.println (" java.lang.Integer __method = (java.lang.Integer)_methods.get ($method);"); 381 stream.println (" if (__method == null)"); 382 stream.println (" throw new org.omg.CORBA.BAD_OPERATION (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);"); 383 stream.println (); 384 if (methodList.size () > 0) 385 { 386 stream.println (" switch (__method.intValue ())"); 387 stream.println (" {"); 388 389 // Write the method case statements 390 int realI = 0; 391 for (int i = 0; i < methodList.size (); ++i) 392 { 393 MethodEntry method = (MethodEntry)methodList.elementAt (i); 394 ((MethodGen)method.generator ()).dispatchSkeleton (symbolTable, method, stream, realI); 395 if (method instanceof AttributeEntry && !((AttributeEntry)method).readOnly ()) 396 realI += 2; 397 else 398 ++realI; 399 } 400 401 indent = " "; 402 stream.println (indent + "default:"); 403 stream.println (indent + " throw new org.omg.CORBA.BAD_OPERATION (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);"); 404 stream.println (" }"); 405 stream.println (); 406 } 407 stream.println (" return out;"); 408 } else { 409 stream.println(" throw new org.omg.CORBA.BAD_OPERATION();"); 410 } 411 stream.println (" } // _invoke"); 412 stream.println (); 413 } // writeDispatchMethod 414 415 /** 416 * 417 **/ 418 protected void writeMethodTable () 419 { 420 // Write the methods hashtable 421 stream.println (" private static java.util.Hashtable _methods = new java.util.Hashtable ();"); 422 stream.println (" static"); 423 stream.println (" {"); 424 425 int count = -1; 426 Enumeration e = methodList.elements (); 427 while (e.hasMoreElements ()) 428 { 429 MethodEntry method = (MethodEntry)e.nextElement (); 430 if (method instanceof AttributeEntry) 431 { 432 stream.println (" _methods.put (\"_get_" + Util.stripLeadingUnderscores (method.name ()) + "\", new java.lang.Integer (" + (++count) + "));"); 433 if (!((AttributeEntry)method).readOnly ()) 434 stream.println (" _methods.put (\"_set_" + Util.stripLeadingUnderscores (method.name ()) + "\", new java.lang.Integer (" + (++count) + "));"); 435 } 436 else 437 stream.println (" _methods.put (\"" + Util.stripLeadingUnderscores (method.name ()) + "\", new java.lang.Integer (" + (++count) + "));"); 438 } 439 stream.println (" }"); 440 stream.println (); 441 } // writeMethodTable 442 443 /** 444 * 445 **/ 446 protected void writeMethods () 447 { 448 int realI = 0; 449 for (int i = 0; i < methodList.size (); ++i) 450 { 451 MethodEntry method = (MethodEntry)methodList.elementAt (i); 452 ((MethodGen)method.generator ()).skeleton 453 (symbolTable, method, stream, realI); 454 if (method instanceof AttributeEntry && 455 !((AttributeEntry)method).readOnly ()) 456 realI += 2; 457 else 458 ++realI; 459 stream.println (); 460 } 461 } // writeMethods 462 463 /** 464 * 465 **/ 466 private void writeIDs () 467 { 468 Vector list = new Vector (); 469 buildIDList (i, list); 470 Enumeration e = list.elements (); 471 boolean first = true; 472 while (e.hasMoreElements ()) 473 { 474 if (first) 475 first = false; 476 else 477 stream.println (", "); 478 stream.print (" \"" + (String)e.nextElement () + '"'); 479 } 480 } // writeIDs 481 482 /** 483 * 484 **/ 485 private void buildIDList (InterfaceEntry entry, Vector list) 486 { 487 if (!entry.fullName ().equals ("org/omg/CORBA/Object")) 488 { 489 String id = Util.stripLeadingUnderscoresFromID (entry.repositoryID ().ID ()); 490 if (!list.contains (id)) 491 list.addElement (id); 492 Enumeration e = entry.derivedFrom ().elements (); 493 while (e.hasMoreElements ()) 494 buildIDList ((InterfaceEntry)e.nextElement (), list); 495 } 496 } // buildIDList 497 498 /** 499 * 500 **/ 501 protected void writeCORBAOperations () 502 { 503 stream.println (" // Type-specific CORBA::Object operations"); 504 505 stream.println (" private static String[] __ids = {"); 506 writeIDs (); 507 stream.println ("};"); 508 stream.println (); 509 if (poa) 510 writePOACORBAOperations(); 511 else 512 writeNonPOACORBAOperations(); 513 514 } // writeCORBAOperations 515 516 protected void writePOACORBAOperations(){ 517 stream.println (" public String[] _all_interfaces (org.omg.PortableServer.POA poa, byte[] objectId)"); 518 //Right now, with our POA implementation, the same 519 //implementation of _ids() type methods seem to work for both non-POA 520 //as well as POA servers. We need to REVISIT since the equivalent 521 //POA interface, i.e. _all_interfaces, has parameters which are not being 522 //used in the _ids() implementation. 523 stream.println (" {"); 524 stream.println (" return (String[])__ids.clone ();"); 525 stream.println (" }"); 526 stream.println (); 527 //_this() 528 stream.println (" public "+ i.name() +" _this() "); 529 stream.println (" {"); 530 stream.println (" return "+ i.name() +"Helper.narrow(" ); 531 stream.println (" super._this_object());"); 532 stream.println (" }"); 533 stream.println (); 534 //_this(org.omg.CORBA.ORB orb) 535 stream.println (" public "+ i.name() +" _this(org.omg.CORBA.ORB orb) "); 536 stream.println (" {"); 537 stream.println (" return "+ i.name() +"Helper.narrow(" ); 538 stream.println (" super._this_object(orb));"); 539 stream.println (" }"); 540 stream.println (); 541 } 542 protected void writeNonPOACORBAOperations(){ 543 stream.println (" public String[] _ids ()"); 544 stream.println (" {"); 545 stream.println (" return (String[])__ids.clone ();"); 546 stream.println (" }"); 547 stream.println (); 548 } 549 /** 550 * 551 **/ 552 protected void writeOperations () 553 { 554 // _get_ids removed at Simon's request 8/26/98 - KLR 555 } // writeOperations 556 557 protected Hashtable symbolTable = null; 558 protected InterfaceEntry i = null; 559 protected PrintWriter stream = null; 560 561 // Unique to this generator 562 protected String tieClassName = null; 563 protected String skeletonClassName = null; 564 protected boolean tie = false; 565 protected boolean poa = false; 566 protected Vector methodList = null; 567 protected String intfName = ""; 568} // class Skeleton 569