| /* |
| * Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| /* |
| * COMPONENT_NAME: idl.toJava |
| * |
| * ORIGINS: 27 |
| * |
| * Licensed Materials - Property of IBM |
| * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999 |
| * RMI-IIOP v1.0 |
| * |
| */ |
| |
| package com.sun.tools.corba.se.idl.toJavaPortable; |
| |
| // NOTES: |
| // -F46082.51<daz> Remove -stateful feature; javaStatefulName() obsolete. |
| // -D57147 <klr> Make _Tie implement org.omg.CORBA.portable.InvokeHandler |
| // -D58037 <klr> Make _Tie delegate to Operations interface |
| // -D62739 <klr> no TIE for values that support abstract interfaces, etc. |
| |
| import java.io.File; |
| import java.io.PrintWriter; |
| |
| import java.util.Enumeration; |
| import java.util.Hashtable; |
| import java.util.Vector; |
| |
| import com.sun.tools.corba.se.idl.AttributeEntry; |
| import com.sun.tools.corba.se.idl.GenFileStream; |
| |
| import com.sun.tools.corba.se.idl.InterfaceEntry; |
| import com.sun.tools.corba.se.idl.InterfaceState; |
| import com.sun.tools.corba.se.idl.MethodEntry; |
| import com.sun.tools.corba.se.idl.SymtabEntry; |
| import com.sun.tools.corba.se.idl.TypedefEntry; |
| import com.sun.tools.corba.se.idl.ValueEntry; |
| |
| /** |
| * |
| **/ |
| public class Skeleton implements AuxGen |
| { |
| private NameModifier skeletonNameModifier ; |
| private NameModifier tieNameModifier ; |
| |
| public Skeleton () |
| { |
| } |
| |
| public void generate (Hashtable symbolTable, SymtabEntry entry) |
| { |
| // <d62739-begin> |
| // Per Simon, 5-12-99, don't generate TIE or Skeleton for |
| // |
| // 1) valuetypes supporting abstract interfaces |
| // 2) valuetypes with no supports. |
| // 3) abstract interfaces |
| // |
| if (entry instanceof ValueEntry) |
| { |
| ValueEntry v = (ValueEntry) entry; |
| if ((v.supports ().size () == 0) || |
| ((InterfaceEntry) v.supports ().elementAt (0)).isAbstract ()) { |
| return; |
| } |
| } |
| if (((InterfaceEntry) entry).isAbstract ()) { |
| return; |
| } |
| // <d62739-end> |
| |
| this.symbolTable = symbolTable; |
| |
| this.i = (InterfaceEntry)entry; |
| init (); |
| openStream (); |
| if (stream == null) |
| return; |
| writeHeading (); |
| writeBody (); |
| writeClosing (); |
| closeStream (); |
| } // generate |
| |
| /** |
| * Initialize members unique to this generator. |
| **/ |
| protected void init () |
| { |
| tie = ((Arguments)Compile.compiler.arguments).TIEServer ; |
| poa = ((Arguments)Compile.compiler.arguments).POAServer ; |
| |
| skeletonNameModifier = |
| ((Arguments)Compile.compiler.arguments).skeletonNameModifier ; |
| tieNameModifier = |
| ((Arguments)Compile.compiler.arguments).tieNameModifier ; |
| |
| tieClassName = tieNameModifier.makeName( i.name() ) ; |
| skeletonClassName = skeletonNameModifier.makeName( i.name() ) ; |
| |
| intfName = Util.javaName (i); |
| // for valuetype, get the name of the interface the valuetype supports |
| if (i instanceof ValueEntry) |
| { |
| ValueEntry v = (ValueEntry) i; |
| InterfaceEntry intf = (InterfaceEntry) v.supports ().elementAt (0); |
| intfName = Util.javaName (intf); |
| } |
| } // init |
| |
| protected void openStream () |
| { |
| if (tie) |
| stream = Util.stream( i, tieNameModifier, ".java" ) ; |
| else |
| stream = Util.stream( i, skeletonNameModifier, ".java" ) ; |
| } // openStream |
| |
| protected void writeHeading () |
| { |
| Util.writePackage (stream, i, Util.StubFile); |
| Util.writeProlog (stream, ((GenFileStream)stream).name ()); |
| if (i.comment () != null) |
| i.comment ().generate ("", stream); |
| writeClassDeclaration (); |
| stream.println ('{'); |
| stream.println (); |
| } // writeHeading |
| |
| protected void writeClassDeclaration () |
| { |
| if (tie){ |
| stream.println ("public class " + tieClassName + |
| " extends " + skeletonClassName ) ; |
| } else { |
| if (poa) { |
| stream.println ("public abstract class " + skeletonClassName + |
| " extends org.omg.PortableServer.Servant"); |
| stream.print (" implements " + intfName + "Operations, "); |
| stream.println ("org.omg.CORBA.portable.InvokeHandler"); |
| } else { |
| stream.println ("public abstract class " + skeletonClassName + |
| " extends org.omg.CORBA.portable.ObjectImpl"); |
| stream.print (" implements " + intfName + ", "); |
| stream.println ("org.omg.CORBA.portable.InvokeHandler"); |
| } |
| } |
| } // writeClassDeclaration |
| |
| /** |
| * |
| **/ |
| protected void writeBody () |
| { |
| // <f46082.51> Remove -stateful feature. ????? |
| //if (i.state () != null) |
| // writeState (); |
| writeCtors (); |
| if (i instanceof ValueEntry) |
| { |
| // use the interface the valuetype supports to generate the |
| // tie class instead of using the valuetype itself |
| ValueEntry v = (ValueEntry) i; |
| this.i = (InterfaceEntry) v.supports ().elementAt (0); |
| } |
| buildMethodList (); |
| //DispatchMethod and MethodTable |
| if (tie){ //Concrete class implementing the remote interface |
| //The logic is here for future use |
| if (poa) { |
| writeMethods (); |
| stream.println (" private " + intfName + "Operations _impl;"); |
| stream.println (" private org.omg.PortableServer.POA _poa;"); |
| } else { |
| writeMethods (); |
| stream.println (" private " + intfName + "Operations _impl;"); |
| } |
| } else { //Both POA and ImplBase are abstract InvokeHandler |
| //The logic is here for future use |
| if (poa) { |
| writeMethodTable (); |
| writeDispatchMethod (); |
| writeCORBAOperations (); |
| } else { |
| writeMethodTable (); |
| writeDispatchMethod (); |
| writeCORBAOperations (); |
| } |
| } |
| //legacy !! |
| writeOperations (); |
| } // writeBody |
| |
| /** |
| * Close the skeleton class. The singleton ORB member is |
| * necessary only for portable skeletons. |
| **/ |
| protected void writeClosing () |
| { |
| stream.println (); |
| if (tie){ |
| stream.println ("} // class " + tieClassName); |
| } else { |
| stream.println ("} // class " + skeletonClassName); |
| } |
| } // writeClosing |
| |
| /** |
| * Close the print stream, which flushes the stream to file. |
| **/ |
| protected void closeStream () |
| { |
| stream.close (); |
| } // closeStream |
| |
| protected void writeCtors () |
| { |
| stream.println (" // Constructors"); |
| // Empty argument constructors |
| if (!poa) { |
| if (tie){ |
| stream.println (" public " + tieClassName + " ()"); |
| stream.println (" {"); |
| stream.println (" }"); |
| } else { |
| stream.println (" public " + skeletonClassName + " ()"); |
| stream.println (" {"); |
| stream.println (" }"); |
| } |
| } |
| stream.println (); |
| // Argumented constructors |
| if (tie){ |
| if (poa) { |
| //Write constructors |
| writePOATieCtors(); |
| //Write state setters and getters |
| writePOATieFieldAccessMethods(); |
| } else { |
| stream.println (" public " + tieClassName + |
| " (" + intfName + "Operations impl)"); |
| stream.println (" {"); |
| // Does it derive from a interface having state, e.g., valuetype? |
| if (((InterfaceEntry)i.derivedFrom ().firstElement ()).state () != null) |
| stream.println (" super (impl);"); |
| else |
| stream.println (" super ();"); |
| stream.println (" _impl = impl;"); |
| stream.println (" }"); |
| stream.println (); |
| } |
| } else { //Skeleton is not Tie so it has no constructors. |
| if (poa) { |
| } else { |
| } |
| } |
| |
| } // writeCtors |
| |
| |
| private void writePOATieCtors(){ |
| //First constructor |
| stream.println (" public " + tieClassName + " ( " + intfName + "Operations delegate ) {"); |
| stream.println (" this._impl = delegate;"); |
| stream.println (" }"); |
| //Second constructor specifying default poa. |
| stream.println (" public " + tieClassName + " ( " + intfName + |
| "Operations delegate , org.omg.PortableServer.POA poa ) {"); |
| stream.println (" this._impl = delegate;"); |
| stream.println (" this._poa = poa;"); |
| stream.println (" }"); |
| } |
| |
| private void writePOATieFieldAccessMethods(){ |
| //Getting delegate |
| stream.println (" public " + intfName+ "Operations _delegate() {"); |
| stream.println (" return this._impl;"); |
| stream.println (" }"); |
| //Setting delegate |
| stream.println (" public void _delegate (" + intfName + "Operations delegate ) {"); |
| stream.println (" this._impl = delegate;"); |
| stream.println (" }"); |
| //Overriding default poa |
| stream.println (" public org.omg.PortableServer.POA _default_POA() {"); |
| stream.println (" if(_poa != null) {"); |
| stream.println (" return _poa;"); |
| stream.println (" }"); |
| stream.println (" else {"); |
| stream.println (" return super._default_POA();"); |
| stream.println (" }"); |
| stream.println (" }"); |
| } |
| |
| /** |
| * Build a list of all of the methods, keeping out duplicates. |
| **/ |
| protected void buildMethodList () |
| { |
| // Start from scratch |
| methodList = new Vector (); |
| |
| buildMethodList (i); |
| } // buildMethodList |
| |
| /** |
| * |
| **/ |
| private void buildMethodList (InterfaceEntry entry) |
| { |
| // Add the local methods |
| Enumeration locals = entry.methods ().elements (); |
| while (locals.hasMoreElements ()) |
| addMethod ((MethodEntry)locals.nextElement ()); |
| |
| // Add the inherited methods |
| Enumeration parents = entry.derivedFrom ().elements (); |
| while (parents.hasMoreElements ()) |
| { |
| InterfaceEntry parent = (InterfaceEntry)parents.nextElement (); |
| if (!parent.name ().equals ("Object")) |
| buildMethodList (parent); |
| } |
| } // buildMethodList |
| |
| /** |
| * |
| **/ |
| private void addMethod (MethodEntry method) |
| { |
| if (!methodList.contains (method)) |
| methodList.addElement (method); |
| } // addMethod |
| |
| /** |
| * |
| **/ |
| protected void writeDispatchMethod () |
| { |
| String indent = " "; |
| stream.println (" public org.omg.CORBA.portable.OutputStream _invoke (String $method,"); |
| stream.println (indent + "org.omg.CORBA.portable.InputStream in,"); |
| stream.println (indent + "org.omg.CORBA.portable.ResponseHandler $rh)"); |
| stream.println (" {"); |
| |
| // this is a special case code generation for cases servantLocator and |
| // servantActivator, where OMG is taking too long to define them |
| // as local objects |
| |
| boolean isLocalInterface = false; |
| if (i instanceof InterfaceEntry) { |
| isLocalInterface = i.isLocalServant(); |
| } |
| |
| if (!isLocalInterface) { |
| // Per Simon 8/26/98, create and return reply stream for all methods - KLR |
| stream.println (" org.omg.CORBA.portable.OutputStream out = null;"); |
| stream.println (" java.lang.Integer __method = (java.lang.Integer)_methods.get ($method);"); |
| stream.println (" if (__method == null)"); |
| stream.println (" throw new org.omg.CORBA.BAD_OPERATION (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);"); |
| stream.println (); |
| if (methodList.size () > 0) |
| { |
| stream.println (" switch (__method.intValue ())"); |
| stream.println (" {"); |
| |
| // Write the method case statements |
| int realI = 0; |
| for (int i = 0; i < methodList.size (); ++i) |
| { |
| MethodEntry method = (MethodEntry)methodList.elementAt (i); |
| ((MethodGen)method.generator ()).dispatchSkeleton (symbolTable, method, stream, realI); |
| if (method instanceof AttributeEntry && !((AttributeEntry)method).readOnly ()) |
| realI += 2; |
| else |
| ++realI; |
| } |
| |
| indent = " "; |
| stream.println (indent + "default:"); |
| stream.println (indent + " throw new org.omg.CORBA.BAD_OPERATION (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);"); |
| stream.println (" }"); |
| stream.println (); |
| } |
| stream.println (" return out;"); |
| } else { |
| stream.println(" throw new org.omg.CORBA.BAD_OPERATION();"); |
| } |
| stream.println (" } // _invoke"); |
| stream.println (); |
| } // writeDispatchMethod |
| |
| /** |
| * |
| **/ |
| protected void writeMethodTable () |
| { |
| // Write the methods hashtable |
| stream.println (" private static java.util.Hashtable _methods = new java.util.Hashtable ();"); |
| stream.println (" static"); |
| stream.println (" {"); |
| |
| int count = -1; |
| Enumeration e = methodList.elements (); |
| while (e.hasMoreElements ()) |
| { |
| MethodEntry method = (MethodEntry)e.nextElement (); |
| if (method instanceof AttributeEntry) |
| { |
| stream.println (" _methods.put (\"_get_" + Util.stripLeadingUnderscores (method.name ()) + "\", new java.lang.Integer (" + (++count) + "));"); |
| if (!((AttributeEntry)method).readOnly ()) |
| stream.println (" _methods.put (\"_set_" + Util.stripLeadingUnderscores (method.name ()) + "\", new java.lang.Integer (" + (++count) + "));"); |
| } |
| else |
| stream.println (" _methods.put (\"" + Util.stripLeadingUnderscores (method.name ()) + "\", new java.lang.Integer (" + (++count) + "));"); |
| } |
| stream.println (" }"); |
| stream.println (); |
| } // writeMethodTable |
| |
| /** |
| * |
| **/ |
| protected void writeMethods () |
| { |
| int realI = 0; |
| for (int i = 0; i < methodList.size (); ++i) |
| { |
| MethodEntry method = (MethodEntry)methodList.elementAt (i); |
| ((MethodGen)method.generator ()).skeleton |
| (symbolTable, method, stream, realI); |
| if (method instanceof AttributeEntry && |
| !((AttributeEntry)method).readOnly ()) |
| realI += 2; |
| else |
| ++realI; |
| stream.println (); |
| } |
| } // writeMethods |
| |
| /** |
| * |
| **/ |
| private void writeIDs () |
| { |
| Vector list = new Vector (); |
| buildIDList (i, list); |
| Enumeration e = list.elements (); |
| boolean first = true; |
| while (e.hasMoreElements ()) |
| { |
| if (first) |
| first = false; |
| else |
| stream.println (", "); |
| stream.print (" \"" + (String)e.nextElement () + '"'); |
| } |
| } // writeIDs |
| |
| /** |
| * |
| **/ |
| private void buildIDList (InterfaceEntry entry, Vector list) |
| { |
| if (!entry.fullName ().equals ("org/omg/CORBA/Object")) |
| { |
| String id = Util.stripLeadingUnderscoresFromID (entry.repositoryID ().ID ()); |
| if (!list.contains (id)) |
| list.addElement (id); |
| Enumeration e = entry.derivedFrom ().elements (); |
| while (e.hasMoreElements ()) |
| buildIDList ((InterfaceEntry)e.nextElement (), list); |
| } |
| } // buildIDList |
| |
| /** |
| * |
| **/ |
| protected void writeCORBAOperations () |
| { |
| stream.println (" // Type-specific CORBA::Object operations"); |
| |
| stream.println (" private static String[] __ids = {"); |
| writeIDs (); |
| stream.println ("};"); |
| stream.println (); |
| if (poa) |
| writePOACORBAOperations(); |
| else |
| writeNonPOACORBAOperations(); |
| |
| } // writeCORBAOperations |
| |
| protected void writePOACORBAOperations(){ |
| stream.println (" public String[] _all_interfaces (org.omg.PortableServer.POA poa, byte[] objectId)"); |
| //Right now, with our POA implementation, the same |
| //implementation of _ids() type methods seem to work for both non-POA |
| //as well as POA servers. We need to REVISIT since the equivalent |
| //POA interface, i.e. _all_interfaces, has parameters which are not being |
| //used in the _ids() implementation. |
| stream.println (" {"); |
| stream.println (" return (String[])__ids.clone ();"); |
| stream.println (" }"); |
| stream.println (); |
| //_this() |
| stream.println (" public "+ i.name() +" _this() "); |
| stream.println (" {"); |
| stream.println (" return "+ i.name() +"Helper.narrow(" ); |
| stream.println (" super._this_object());"); |
| stream.println (" }"); |
| stream.println (); |
| //_this(org.omg.CORBA.ORB orb) |
| stream.println (" public "+ i.name() +" _this(org.omg.CORBA.ORB orb) "); |
| stream.println (" {"); |
| stream.println (" return "+ i.name() +"Helper.narrow(" ); |
| stream.println (" super._this_object(orb));"); |
| stream.println (" }"); |
| stream.println (); |
| } |
| protected void writeNonPOACORBAOperations(){ |
| stream.println (" public String[] _ids ()"); |
| stream.println (" {"); |
| stream.println (" return (String[])__ids.clone ();"); |
| stream.println (" }"); |
| stream.println (); |
| } |
| /** |
| * |
| **/ |
| protected void writeOperations () |
| { |
| // _get_ids removed at Simon's request 8/26/98 - KLR |
| } // writeOperations |
| |
| protected Hashtable symbolTable = null; |
| protected InterfaceEntry i = null; |
| protected PrintWriter stream = null; |
| |
| // Unique to this generator |
| protected String tieClassName = null; |
| protected String skeletonClassName = null; |
| protected boolean tie = false; |
| protected boolean poa = false; |
| protected Vector methodList = null; |
| protected String intfName = ""; |
| } // class Skeleton |