001: /*
002: * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025: /*
026: * COMPONENT_NAME: idl.toJava
027: *
028: * ORIGINS: 27
029: *
030: * Licensed Materials - Property of IBM
031: * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999
032: * RMI-IIOP v1.0
033: *
034: * @(#)Skeleton.java 1.8 99/08/18
035: */
036:
037: package com.sun.tools.corba.se.idl.toJavaPortable;
038:
039: // NOTES:
040: // -F46082.51<daz> Remove -stateful feature; javaStatefulName() obsolete.
041: // -D57147 <klr> Make _Tie implement org.omg.CORBA.portable.InvokeHandler
042: // -D58037 <klr> Make _Tie delegate to Operations interface
043: // -D62739 <klr> no TIE for values that support abstract interfaces, etc.
044:
045: import java.io.File;
046: import java.io.PrintWriter;
047:
048: import java.util.Enumeration;
049: import java.util.Hashtable;
050: import java.util.Vector;
051:
052: import com.sun.tools.corba.se.idl.AttributeEntry;
053: import com.sun.tools.corba.se.idl.GenFileStream;
054:
055: import com.sun.tools.corba.se.idl.InterfaceEntry;
056: import com.sun.tools.corba.se.idl.InterfaceState;
057: import com.sun.tools.corba.se.idl.MethodEntry;
058: import com.sun.tools.corba.se.idl.SymtabEntry;
059: import com.sun.tools.corba.se.idl.TypedefEntry;
060: import com.sun.tools.corba.se.idl.ValueEntry;
061:
062: /**
063: *
064: **/
065: public class Skeleton implements AuxGen {
066: private NameModifier skeletonNameModifier;
067: private NameModifier tieNameModifier;
068:
069: public Skeleton() {
070: }
071:
072: public void generate(Hashtable symbolTable, SymtabEntry entry) {
073: // <d62739-begin>
074: // Per Simon, 5-12-99, don't generate TIE or Skeleton for
075: //
076: // 1) valuetypes supporting abstract interfaces
077: // 2) valuetypes with no supports.
078: // 3) abstract interfaces
079: //
080: if (entry instanceof ValueEntry) {
081: ValueEntry v = (ValueEntry) entry;
082: if ((v.supports().size() == 0)
083: || ((InterfaceEntry) v.supports().elementAt(0))
084: .isAbstract()) {
085: return;
086: }
087: }
088: if (((InterfaceEntry) entry).isAbstract()) {
089: return;
090: }
091: // <d62739-end>
092:
093: this .symbolTable = symbolTable;
094:
095: this .i = (InterfaceEntry) entry;
096: init();
097: openStream();
098: if (stream == null)
099: return;
100: writeHeading();
101: writeBody();
102: writeClosing();
103: closeStream();
104: } // generate
105:
106: /**
107: * Initialize members unique to this generator.
108: **/
109: protected void init() {
110: tie = ((Arguments) Compile.compiler.arguments).TIEServer;
111: poa = ((Arguments) Compile.compiler.arguments).POAServer;
112:
113: skeletonNameModifier = ((Arguments) Compile.compiler.arguments).skeletonNameModifier;
114: tieNameModifier = ((Arguments) Compile.compiler.arguments).tieNameModifier;
115:
116: tieClassName = tieNameModifier.makeName(i.name());
117: skeletonClassName = skeletonNameModifier.makeName(i.name());
118:
119: intfName = Util.javaName(i);
120: // for valuetype, get the name of the interface the valuetype supports
121: if (i instanceof ValueEntry) {
122: ValueEntry v = (ValueEntry) i;
123: InterfaceEntry intf = (InterfaceEntry) v.supports()
124: .elementAt(0);
125: intfName = Util.javaName(intf);
126: }
127: } // init
128:
129: protected void openStream() {
130: if (tie)
131: stream = Util.stream(i, tieNameModifier, ".java");
132: else
133: stream = Util.stream(i, skeletonNameModifier, ".java");
134: } // openStream
135:
136: protected void writeHeading() {
137: Util.writePackage(stream, i, Util.StubFile);
138: Util.writeProlog(stream, ((GenFileStream) stream).name());
139: if (i.comment() != null)
140: i.comment().generate("", stream);
141: writeClassDeclaration();
142: stream.println('{');
143: stream.println();
144: } // writeHeading
145:
146: protected void writeClassDeclaration() {
147: if (tie) {
148: stream.println("public class " + tieClassName + " extends "
149: + skeletonClassName);
150: } else {
151: if (poa) {
152: stream.println("public abstract class "
153: + skeletonClassName
154: + " extends org.omg.PortableServer.Servant");
155: stream
156: .print(" implements " + intfName
157: + "Operations, ");
158: stream.println("org.omg.CORBA.portable.InvokeHandler");
159: } else {
160: stream.println("public abstract class "
161: + skeletonClassName
162: + " extends org.omg.CORBA.portable.ObjectImpl");
163: stream.print(" implements " + intfName
164: + ", ");
165: stream.println("org.omg.CORBA.portable.InvokeHandler");
166: }
167: }
168: } // writeClassDeclaration
169:
170: /**
171: *
172: **/
173: protected void writeBody() {
174: // <f46082.51> Remove -stateful feature. ?????
175: //if (i.state () != null)
176: // writeState ();
177: writeCtors();
178: if (i instanceof ValueEntry) {
179: // use the interface the valuetype supports to generate the
180: // tie class instead of using the valuetype itself
181: ValueEntry v = (ValueEntry) i;
182: this .i = (InterfaceEntry) v.supports().elementAt(0);
183: }
184: buildMethodList();
185: //DispatchMethod and MethodTable
186: if (tie) { //Concrete class implementing the remote interface
187: //The logic is here for future use
188: if (poa) {
189: writeMethods();
190: stream.println(" private " + intfName
191: + "Operations _impl;");
192: stream
193: .println(" private org.omg.PortableServer.POA _poa;");
194: } else {
195: writeMethods();
196: stream.println(" private " + intfName
197: + "Operations _impl;");
198: }
199: } else { //Both POA and ImplBase are abstract InvokeHandler
200: //The logic is here for future use
201: if (poa) {
202: writeMethodTable();
203: writeDispatchMethod();
204: writeCORBAOperations();
205: } else {
206: writeMethodTable();
207: writeDispatchMethod();
208: writeCORBAOperations();
209: }
210: }
211: //legacy !!
212: writeOperations();
213: } // writeBody
214:
215: /**
216: * Close the skeleton class. The singleton ORB member is
217: * necessary only for portable skeletons.
218: **/
219: protected void writeClosing() {
220: stream.println();
221: if (tie) {
222: stream.println("} // class " + tieClassName);
223: } else {
224: stream.println("} // class " + skeletonClassName);
225: }
226: } // writeClosing
227:
228: /**
229: * Close the print stream, which flushes the stream to file.
230: **/
231: protected void closeStream() {
232: stream.close();
233: } // closeStream
234:
235: protected void writeCtors() {
236: stream.println(" // Constructors");
237: // Empty argument constructors
238: if (!poa) {
239: if (tie) {
240: stream.println(" public " + tieClassName + " ()");
241: stream.println(" {");
242: stream.println(" }");
243: } else {
244: stream.println(" public " + skeletonClassName + " ()");
245: stream.println(" {");
246: stream.println(" }");
247: }
248: }
249: stream.println();
250: // Argumented constructors
251: if (tie) {
252: if (poa) {
253: //Write constructors
254: writePOATieCtors();
255: //Write state setters and getters
256: writePOATieFieldAccessMethods();
257: } else {
258: stream.println(" public " + tieClassName + " ("
259: + intfName + "Operations impl)");
260: stream.println(" {");
261: // Does it derive from a interface having state, e.g., valuetype?
262: if (((InterfaceEntry) i.derivedFrom().firstElement())
263: .state() != null)
264: stream.println(" super (impl);");
265: else
266: stream.println(" super ();");
267: stream.println(" _impl = impl;");
268: stream.println(" }");
269: stream.println();
270: }
271: } else { //Skeleton is not Tie so it has no constructors.
272: if (poa) {
273: } else {
274: }
275: }
276:
277: } // writeCtors
278:
279: private void writePOATieCtors() {
280: //First constructor
281: stream.println(" public " + tieClassName + " ( " + intfName
282: + "Operations delegate ) {");
283: stream.println(" this._impl = delegate;");
284: stream.println(" }");
285: //Second constructor specifying default poa.
286: stream
287: .println(" public "
288: + tieClassName
289: + " ( "
290: + 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
300: + "Operations _delegate() {");
301: stream.println(" return this._impl;");
302: stream.println(" }");
303: //Setting delegate
304: stream.println(" public void _delegate (" + intfName
305: + "Operations delegate ) {");
306: stream.println(" this._impl = delegate;");
307: stream.println(" }");
308: //Overriding default poa
309: stream
310: .println(" public org.omg.PortableServer.POA _default_POA() {");
311: stream.println(" if(_poa != null) {");
312: stream.println(" return _poa;");
313: stream.println(" }");
314: stream.println(" else {");
315: stream.println(" return super._default_POA();");
316: stream.println(" }");
317: stream.println(" }");
318: }
319:
320: /**
321: * Build a list of all of the methods, keeping out duplicates.
322: **/
323: protected void buildMethodList() {
324: // Start from scratch
325: methodList = new Vector();
326:
327: buildMethodList(i);
328: } // buildMethodList
329:
330: /**
331: *
332: **/
333: private void buildMethodList(InterfaceEntry entry) {
334: // Add the local methods
335: Enumeration locals = entry.methods().elements();
336: while (locals.hasMoreElements())
337: addMethod((MethodEntry) locals.nextElement());
338:
339: // Add the inherited methods
340: Enumeration parents = entry.derivedFrom().elements();
341: while (parents.hasMoreElements()) {
342: InterfaceEntry parent = (InterfaceEntry) parents
343: .nextElement();
344: if (!parent.name().equals("Object"))
345: buildMethodList(parent);
346: }
347: } // buildMethodList
348:
349: /**
350: *
351: **/
352: private void addMethod(MethodEntry method) {
353: if (!methodList.contains(method))
354: methodList.addElement(method);
355: } // addMethod
356:
357: /**
358: *
359: **/
360: protected void writeDispatchMethod() {
361: String indent = " ";
362: stream
363: .println(" public org.omg.CORBA.portable.OutputStream _invoke (String $method,");
364: stream.println(indent
365: + "org.omg.CORBA.portable.InputStream in,");
366: stream.println(indent
367: + "org.omg.CORBA.portable.ResponseHandler $rh)");
368: stream.println(" {");
369:
370: // this is a special case code generation for cases servantLocator and
371: // servantActivator, where OMG is taking too long to define them
372: // as local objects
373:
374: boolean isLocalInterface = false;
375: if (i instanceof InterfaceEntry) {
376: isLocalInterface = i.isLocalServant();
377: }
378:
379: if (!isLocalInterface) {
380: // Per Simon 8/26/98, create and return reply stream for all methods - KLR
381: stream
382: .println(" org.omg.CORBA.portable.OutputStream out = null;");
383: stream
384: .println(" java.lang.Integer __method = (java.lang.Integer)_methods.get ($method);");
385: stream.println(" if (__method == null)");
386: stream
387: .println(" throw new org.omg.CORBA.BAD_OPERATION (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);");
388: stream.println();
389: if (methodList.size() > 0) {
390: stream.println(" switch (__method.intValue ())");
391: stream.println(" {");
392:
393: // Write the method case statements
394: int realI = 0;
395: for (int i = 0; i < methodList.size(); ++i) {
396: MethodEntry method = (MethodEntry) methodList
397: .elementAt(i);
398: ((MethodGen) method.generator()).dispatchSkeleton(
399: symbolTable, method, stream, realI);
400: if (method instanceof AttributeEntry
401: && !((AttributeEntry) method).readOnly())
402: realI += 2;
403: else
404: ++realI;
405: }
406:
407: indent = " ";
408: stream.println(indent + "default:");
409: stream
410: .println(indent
411: + " throw new org.omg.CORBA.BAD_OPERATION (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);");
412: stream.println(" }");
413: stream.println();
414: }
415: stream.println(" return out;");
416: } else {
417: stream
418: .println(" throw new org.omg.CORBA.BAD_OPERATION();");
419: }
420: stream.println(" } // _invoke");
421: stream.println();
422: } // writeDispatchMethod
423:
424: /**
425: *
426: **/
427: protected void writeMethodTable() {
428: // Write the methods hashtable
429: stream
430: .println(" private static java.util.Hashtable _methods = new java.util.Hashtable ();");
431: stream.println(" static");
432: stream.println(" {");
433:
434: int count = -1;
435: Enumeration e = methodList.elements();
436: while (e.hasMoreElements()) {
437: MethodEntry method = (MethodEntry) e.nextElement();
438: if (method instanceof AttributeEntry) {
439: stream.println(" _methods.put (\"_get_"
440: + Util.stripLeadingUnderscores(method.name())
441: + "\", new java.lang.Integer (" + (++count)
442: + "));");
443: if (!((AttributeEntry) method).readOnly())
444: stream.println(" _methods.put (\"_set_"
445: + Util.stripLeadingUnderscores(method
446: .name())
447: + "\", new java.lang.Integer (" + (++count)
448: + "));");
449: } else
450: stream.println(" _methods.put (\""
451: + Util.stripLeadingUnderscores(method.name())
452: + "\", new java.lang.Integer (" + (++count)
453: + "));");
454: }
455: stream.println(" }");
456: stream.println();
457: } // writeMethodTable
458:
459: /**
460: *
461: **/
462: protected void writeMethods() {
463: int realI = 0;
464: for (int i = 0; i < methodList.size(); ++i) {
465: MethodEntry method = (MethodEntry) methodList.elementAt(i);
466: ((MethodGen) method.generator()).skeleton(symbolTable,
467: method, stream, realI);
468: if (method instanceof AttributeEntry
469: && !((AttributeEntry) method).readOnly())
470: realI += 2;
471: else
472: ++realI;
473: stream.println();
474: }
475: } // writeMethods
476:
477: /**
478: *
479: **/
480: private void writeIDs() {
481: Vector list = new Vector();
482: buildIDList(i, list);
483: Enumeration e = list.elements();
484: boolean first = true;
485: while (e.hasMoreElements()) {
486: if (first)
487: first = false;
488: else
489: stream.println(", ");
490: stream.print(" \"" + (String) e.nextElement() + '"');
491: }
492: } // writeIDs
493:
494: /**
495: *
496: **/
497: private void buildIDList(InterfaceEntry entry, Vector list) {
498: if (!entry.fullName().equals("org/omg/CORBA/Object")) {
499: String id = Util.stripLeadingUnderscoresFromID(entry
500: .repositoryID().ID());
501: if (!list.contains(id))
502: list.addElement(id);
503: Enumeration e = entry.derivedFrom().elements();
504: while (e.hasMoreElements())
505: buildIDList((InterfaceEntry) e.nextElement(), list);
506: }
507: } // buildIDList
508:
509: /**
510: *
511: **/
512: protected void writeCORBAOperations() {
513: stream.println(" // Type-specific CORBA::Object operations");
514:
515: stream.println(" private static String[] __ids = {");
516: writeIDs();
517: stream.println("};");
518: stream.println();
519: if (poa)
520: writePOACORBAOperations();
521: else
522: writeNonPOACORBAOperations();
523:
524: } // writeCORBAOperations
525:
526: protected void writePOACORBAOperations() {
527: stream
528: .println(" public String[] _all_interfaces (org.omg.PortableServer.POA poa, byte[] objectId)");
529: //Right now, with our POA implementation, the same
530: //implementation of _ids() type methods seem to work for both non-POA
531: //as well as POA servers. We need to REVISIT since the equivalent
532: //POA interface, i.e. _all_interfaces, has parameters which are not being
533: //used in the _ids() implementation.
534: stream.println(" {");
535: stream.println(" return (String[])__ids.clone ();");
536: stream.println(" }");
537: stream.println();
538: //_this()
539: stream.println(" public " + i.name() + " _this() ");
540: stream.println(" {");
541: stream.println(" return " + i.name() + "Helper.narrow(");
542: stream.println(" super._this_object());");
543: stream.println(" }");
544: stream.println();
545: //_this(org.omg.CORBA.ORB orb)
546: stream.println(" public " + i.name()
547: + " _this(org.omg.CORBA.ORB orb) ");
548: stream.println(" {");
549: stream.println(" return " + i.name() + "Helper.narrow(");
550: stream.println(" super._this_object(orb));");
551: stream.println(" }");
552: stream.println();
553: }
554:
555: protected void writeNonPOACORBAOperations() {
556: stream.println(" public String[] _ids ()");
557: stream.println(" {");
558: stream.println(" return (String[])__ids.clone ();");
559: stream.println(" }");
560: stream.println();
561: }
562:
563: /**
564: *
565: **/
566: protected void writeOperations() {
567: // _get_ids removed at Simon's request 8/26/98 - KLR
568: } // writeOperations
569:
570: protected Hashtable symbolTable = null;
571: protected InterfaceEntry i = null;
572: protected PrintWriter stream = null;
573:
574: // Unique to this generator
575: protected String tieClassName = null;
576: protected String skeletonClassName = null;
577: protected boolean tie = false;
578: protected boolean poa = false;
579: protected Vector methodList = null;
580: protected String intfName = "";
581: } // class Skeleton
|