001: /*
002: * Copyright 1999-2004 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: * @(#)Helper.java 1.23 07/05/05
035: */
036:
037: package com.sun.tools.corba.se.idl.toJavaPortable;
038:
039: // NOTES:
040: // -F46082.51<daz> Remove -stateful feature.
041: // -D57118 <klr> Fix "narrow" in helper for abstract interface
042: // -D58889 <klr> re-Fix "narrow" in helper for abstract interface
043: // -D59383 <klr> 'get_class' in value helper returns value class, not helper.
044: // -D59413 <klr> Remove Helper interface references for non-value types.
045: // -D59435 <klr> Remove read_Object, write_Object completely.
046: // -D59418 <klr> Move read_Value, write_Value to generator's helperRead.
047:
048: import java.io.PrintWriter;
049:
050: import java.util.Enumeration;
051: import java.util.Vector;
052:
053: import com.sun.tools.corba.se.idl.GenFileStream;
054: import com.sun.tools.corba.se.idl.InterfaceEntry;
055: import com.sun.tools.corba.se.idl.MethodEntry;
056: import com.sun.tools.corba.se.idl.ParameterEntry;
057: import com.sun.tools.corba.se.idl.SymtabEntry;
058: import com.sun.tools.corba.se.idl.ValueEntry;
059: import com.sun.tools.corba.se.idl.ValueBoxEntry;
060: import com.sun.tools.corba.se.idl.TypedefEntry;
061: import com.sun.tools.corba.se.idl.InterfaceState;
062: import com.sun.tools.corba.se.idl.PrimitiveEntry;
063: import com.sun.tools.corba.se.idl.StructEntry;
064:
065: /**
066: *
067: **/
068: public class Helper implements AuxGen {
069: /**
070: * Public zero-argument constructor.
071: **/
072: public Helper() {
073: } // ctor
074:
075: /**
076: * Generate the helper class. Provides general algorithm
077: * for auxiliary binding generation:
078: *
079: * 1.) Initialize symbol table and symbol table entry members,
080: * common to all generators.
081: * 2.) Initialize members unique to this generator.
082: * 3.) Open print stream
083: * 4.) Write class heading: package, prologue, class statement, open curly
084: * 5.) Write class body: member data and methods
085: * 6.) Write class closing: close curly
086: * 7.) Close the print stream
087: **/
088: public void generate(java.util.Hashtable symbolTable,
089: com.sun.tools.corba.se.idl.SymtabEntry entry) {
090: this .symbolTable = symbolTable;
091: this .entry = entry;
092: init();
093:
094: openStream();
095: if (stream == null)
096: return;
097: writeHeading();
098: writeBody();
099: writeClosing();
100: closeStream();
101: } // generate
102:
103: /**
104: * Initialize variables unique to this generator.
105: **/
106: protected void init() {
107: helperClass = entry.name() + "Helper";
108: if (entry instanceof ValueBoxEntry) {
109: ValueBoxEntry v = (ValueBoxEntry) entry;
110: TypedefEntry member = ((InterfaceState) v.state()
111: .elementAt(0)).entry;
112: SymtabEntry mType = member.type();
113:
114: if (mType instanceof PrimitiveEntry)
115: helperType = Util.javaName(entry);
116: else
117: helperType = Util.javaName(mType);
118: } else
119: helperType = Util.javaName(entry);
120: } // init
121:
122: /**
123: * Open the print stream for subsequent output.
124: **/
125: protected void openStream() {
126: stream = Util.stream(entry, "Helper.java");
127: } // openStream
128:
129: /**
130: * Generate the heading, including package, imports, class statements,
131: * and open curly.
132: **/
133: protected void writeHeading() {
134: Util.writePackage(stream, entry, Util.HelperFile);
135: Util.writeProlog(stream, stream.name());
136:
137: // Transfer comment to target <30jul1997daz>.
138: if (entry.comment() != null)
139: entry.comment().generate("", stream);
140:
141: stream.print("public final class " + helperClass);
142: if (entry instanceof ValueEntry)
143: stream
144: .println(" implements org.omg.CORBA.portable.ValueHelper");
145: else
146: stream.println();
147: stream.println('{');
148: }
149:
150: /**
151: * Generate members of this class.
152: **/
153: protected void writeBody() {
154: writeInstVars();
155: writeCtors();
156: writeInsert();
157: writeExtract();
158: writeType();
159: writeID();
160: writeRead();
161: writeWrite();
162: if (entry instanceof InterfaceEntry
163: && !(entry instanceof ValueEntry)) {
164: writeNarrow();
165: writeUncheckedNarrow();
166: }
167: writeHelperInterface();
168: if (entry instanceof ValueEntry)
169: writeValueHelperInterface();
170: } // writeBody
171:
172: /**
173: * Generate members of the Helper interface.
174: **/
175: protected void writeHelperInterface() {
176: } // writeHelperInterface
177:
178: /**
179: * Generate members of the ValueHelper interface.
180: **/
181: protected void writeValueHelperInterface() {
182: writeGetID(); // moved for <d59413>
183: writeGetType(); // moved for <d59413>
184: writeGetInstance(); // not in ValueHelper interface
185: writeGetClass();
186: writeGetSafeBaseIds();
187: } // writeHelperInterface
188:
189: /**
190: * Generate the closing statements.
191: **/
192: protected void writeClosing() {
193: stream.println('}');
194: }
195:
196: /**
197: * Write the stream to file by closing the print stream.
198: **/
199: protected void closeStream() {
200: stream.close();
201: }
202:
203: /**
204: * Generate the instance variables.
205: **/
206: protected void writeInstVars() {
207: stream.println(" private static String _id = \""
208: + Util.stripLeadingUnderscoresFromID(entry
209: .repositoryID().ID()) + "\";");
210: if (entry instanceof ValueEntry) {
211: stream.println();
212: stream.println(" private static " + helperClass
213: + " helper = new " + helperClass + " ();");
214: stream.println();
215: stream
216: .println(" private static String[] _truncatable_ids = {");
217: stream.print(" _id");
218:
219: // Any safe ValueEntry must have a concete value parent.
220: // The topmost parent cannot be safe since it doesn't have
221: // a concrete parent.
222: ValueEntry child = (ValueEntry) entry;
223: while (child.isSafe()) {
224: stream.println(",");
225: ValueEntry parent = (ValueEntry) child.derivedFrom()
226: .elementAt(0);
227: stream.print(" \""
228: + Util.stripLeadingUnderscoresFromID(parent
229: .repositoryID().ID()) + "\"");
230: child = parent;
231: }
232: stream.println(" };");
233: }
234: stream.println();
235: } // writeInstVars
236:
237: /**
238: * Generate the constructors.
239: **/
240: protected void writeCtors() {
241: stream.println(" public " + helperClass + "()");
242: stream.println(" {");
243: stream.println(" }");
244: stream.println();
245: } // writeCtors
246:
247: /**
248: * Generate the insert method.
249: **/
250: protected void writeInsert() {
251: stream
252: .println(" public static void insert (org.omg.CORBA.Any a, "
253: + helperType + " that)");
254: stream.println(" {");
255: stream
256: .println(" org.omg.CORBA.portable.OutputStream out = a.create_output_stream ();");
257: stream.println(" a.type (type ());");
258: stream.println(" write (out, that);");
259: stream
260: .println(" a.read_value (out.create_input_stream (), type ());");
261: stream.println(" }");
262: stream.println();
263: } // writeInsert
264:
265: /**
266: * Generate the extract method.
267: **/
268: protected void writeExtract() {
269: stream.println(" public static " + helperType
270: + " extract (org.omg.CORBA.Any a)");
271: stream.println(" {");
272: stream.println(" return read (a.create_input_stream ());");
273: stream.println(" }");
274: stream.println();
275: } // writeExtract
276:
277: /**
278: * Generate the typecode variable and type method.
279: **/
280: protected void writeType() {
281: boolean canRecurse = entry instanceof ValueEntry
282: || entry instanceof ValueBoxEntry
283: || entry instanceof StructEntry;
284: stream
285: .println(" private static org.omg.CORBA.TypeCode __typeCode = null;");
286: if (canRecurse)
287: stream
288: .println(" private static boolean __active = false;");
289: stream
290: .println(" synchronized public static org.omg.CORBA.TypeCode type ()");
291: stream.println(" {");
292: stream.println(" if (__typeCode == null)");
293: stream.println(" {");
294: if (canRecurse) {
295: stream
296: .println(" synchronized (org.omg.CORBA.TypeCode.class)");
297: stream.println(" {");
298: stream.println(" if (__typeCode == null)");
299: stream.println(" {");
300: stream.println(" if (__active)");
301: stream.println(" {");
302: stream
303: .println(" return org.omg.CORBA.ORB.init().create_recursive_tc ( _id );");
304: stream.println(" }");
305: stream.println(" __active = true;");
306: ((JavaGenerator) entry.generator()).helperType(0,
307: " ", new TCOffsets(), "__typeCode", entry,
308: stream);
309: } else
310: ((JavaGenerator) entry.generator()).helperType(0, " ",
311: new TCOffsets(), "__typeCode", entry, stream);
312:
313: // Generate body of type() method
314:
315: if (canRecurse) {
316: stream.println(" __active = false;");
317: stream.println(" }");
318: stream.println(" }");
319: }
320: stream.println(" }");
321: stream.println(" return __typeCode;");
322: stream.println(" }");
323: stream.println();
324: } // writeType
325:
326: /**
327: * Generate the ID method.
328: **/
329: protected void writeID() {
330: stream.println(" public static String id ()");
331: stream.println(" {");
332: stream.println(" return _id;");
333: stream.println(" }");
334: stream.println();
335: } // writeID
336:
337: /**
338: * Generate the read method.
339: **/
340: protected void writeRead() {
341:
342: boolean isLocalInterface = false;
343:
344: if (entry instanceof InterfaceEntry) {
345: InterfaceEntry ie = (InterfaceEntry) entry;
346:
347: // for #pragma sun_local or sun_localservant, or actual local
348: // local interface, set the flag by checking on both
349: isLocalInterface = ie.isLocal() | ie.isLocalServant();
350: }
351:
352: stream.println(" public static " + helperType
353: + " read (org.omg.CORBA.portable.InputStream istream)");
354: stream.println(" {");
355: if (!isLocalInterface) { // nonLocal Interface and other types
356: ((JavaGenerator) entry.generator()).helperRead(helperType,
357: entry, stream);
358: } else { //Local interface should throw exception
359: stream.println(" throw new org.omg.CORBA.MARSHAL ();");
360: }
361: stream.println(" }");
362: stream.println();
363: } // writeRead
364:
365: /**
366: * Generate the write method.
367: **/
368: protected void writeWrite() {
369:
370: boolean isLocalInterface = false;
371:
372: if (entry instanceof InterfaceEntry) {
373: InterfaceEntry ie = (InterfaceEntry) entry;
374:
375: // for #pragma sun_local or sun_localservant, or actual local
376: // local interface, set the flag by checking on both
377: isLocalInterface = ie.isLocal() | ie.isLocalServant();
378: }
379:
380: stream
381: .println(" public static void write (org.omg.CORBA.portable.OutputStream ostream, "
382: + helperType + " value)");
383: stream.println(" {");
384: if (!isLocalInterface) { // nonLocal Interface and other types
385: ((JavaGenerator) entry.generator()).helperWrite(entry,
386: stream);
387: } else { //Local interface should throw exception
388: stream.println(" throw new org.omg.CORBA.MARSHAL ();");
389: }
390: stream.println(" }");
391: stream.println();
392: } // writeWrite
393:
394: /**
395: * Generate the narrow method.
396: **/
397: protected void writeNarrow() {
398: writeRemoteNarrow();
399: stream.println();
400: }
401:
402: /**
403: * Write the narrow() method for a remotable object.
404: **/
405: protected void writeRemoteNarrow() {
406: InterfaceEntry ie = (InterfaceEntry) entry;
407:
408: // narrow for LocalObject interface
409: if (ie.isLocal()) {
410: writeRemoteNarrowForLocal(false);
411: return;
412: }
413:
414: // narrow for Abstract interface
415: if (ie.isAbstract()) {
416: writeRemoteNarrowForAbstract(false);
417: return;
418: } else {
419: // Determine if the non-abstract interface has any abstract parents
420: for (int i = 0; i < ie.derivedFrom().size(); i++) {
421: SymtabEntry parent = (SymtabEntry) ie.derivedFrom()
422: .elementAt(i);
423: if (((InterfaceEntry) parent).isAbstract()) {
424: writeRemoteNarrowForAbstract(true);
425: break;
426: }
427: }
428: }
429:
430: stream.println(" public static " + helperType
431: + " narrow (org.omg.CORBA.Object obj)");
432: stream.println(" {");
433: stream.println(" if (obj == null)");
434: stream.println(" return null;");
435: stream.println(" else if (obj instanceof " + helperType
436: + ')');
437: stream.println(" return (" + helperType + ")obj;");
438: stream.println(" else if (!obj._is_a (id ()))");
439: stream.println(" throw new org.omg.CORBA.BAD_PARAM ();");
440: stream.println(" else");
441: stream.println(" {");
442: stream
443: .println(" org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate ();");
444: String stubNameofEntry = stubName((InterfaceEntry) entry);
445: stream.println(" " + stubNameofEntry + " stub = new "
446: + stubNameofEntry + " ();");
447: stream.println(" stub._set_delegate(delegate);");
448: stream.println(" return stub;");
449: stream.println(" }");
450: stream.println(" }");
451: } // writeRemoteNarrow
452:
453: /**
454: * Write the narrow() method for local interface.
455: **/
456: private void writeRemoteNarrowForLocal(boolean hasAbstractParent) {
457: stream.println(" public static " + helperType
458: + " narrow (org.omg.CORBA.Object obj)");
459: stream.println(" {");
460: stream.println(" if (obj == null)");
461: stream.println(" return null;");
462: stream.println(" else if (obj instanceof " + helperType
463: + ')');
464: stream.println(" return (" + helperType + ")obj;");
465: stream.println(" else");
466: stream.println(" throw new org.omg.CORBA.BAD_PARAM ();");
467: stream.println(" }");
468: } // writeRemoteNarrowForLocal
469:
470: /**
471: * Write the narrow() method for abstract interface.
472: **/
473: private void writeRemoteNarrowForAbstract(boolean hasAbstractParent) {
474: stream.print(" public static " + helperType
475: + " narrow (java.lang.Object obj)");
476: stream.println(" {");
477: stream.println(" if (obj == null)");
478: stream.println(" return null;");
479: if (hasAbstractParent) {
480: stream
481: .println(" else if (obj instanceof org.omg.CORBA.Object)");
482: stream
483: .println(" return narrow ((org.omg.CORBA.Object) obj);");
484: } else {
485: stream.println(" else if (obj instanceof " + helperType
486: + ')');
487: stream.println(" return (" + helperType + ")obj;");
488: }
489:
490: // If hasAbstractParent is false, then THIS entry must be abstract.
491: // This method is also called in case THIS entry is not abstract, but
492: // there is an abstract parent. If this entry is not abstract,
493: // it can never narrow to a CORBA object reference.
494: if (!hasAbstractParent) { // <d58889>
495: String stubNameofEntry = stubName((InterfaceEntry) entry);
496:
497: stream
498: .println(" else if ((obj instanceof org.omg.CORBA.portable.ObjectImpl) &&");
499: stream
500: .println(" (((org.omg.CORBA.Object)obj)._is_a (id ()))) {");
501: stream
502: .println(" org.omg.CORBA.portable.ObjectImpl impl = (org.omg.CORBA.portable.ObjectImpl)obj ;");
503: stream
504: .println(" org.omg.CORBA.portable.Delegate delegate = impl._get_delegate() ;");
505: stream.println(" " + stubNameofEntry + " stub = new "
506: + stubNameofEntry + " ();");
507: stream.println(" stub._set_delegate(delegate);");
508: stream.println(" return stub;");
509: stream.println(" }");
510: }
511: ;
512: // end <d57118 - check for remotable - klr>
513:
514: stream.println(" throw new org.omg.CORBA.BAD_PARAM ();");
515: stream.println(" }");
516: stream.println();
517: } // writeRemoteNarrowForAbstract
518:
519: /**
520: * Generate the unchecked narrow method.
521: **/
522: protected void writeUncheckedNarrow() {
523: writeUncheckedRemoteNarrow();
524: stream.println();
525: }
526:
527: /**
528: * Write the unchecked narrow() method for a remotable object.
529: **/
530: protected void writeUncheckedRemoteNarrow() {
531: InterfaceEntry ie = (InterfaceEntry) entry;
532:
533: // unchecked narrow for LocalObject interface
534: if (ie.isLocal()) {
535: writeRemoteUncheckedNarrowForLocal(false);
536: return;
537: }
538:
539: // unchecked narrow for Abstract interface
540: if (ie.isAbstract()) {
541: writeRemoteUncheckedNarrowForAbstract(false);
542: return;
543: } else {
544: // Determine if the non-abstract interface has any abstract parents
545: for (int i = 0; i < ie.derivedFrom().size(); i++) {
546: SymtabEntry parent = (SymtabEntry) ie.derivedFrom()
547: .elementAt(i);
548: if (((InterfaceEntry) parent).isAbstract()) {
549: writeRemoteUncheckedNarrowForAbstract(true);
550: break;
551: }
552: }
553: }
554:
555: stream.println(" public static " + helperType
556: + " unchecked_narrow (org.omg.CORBA.Object obj)");
557: stream.println(" {");
558: stream.println(" if (obj == null)");
559: stream.println(" return null;");
560: stream.println(" else if (obj instanceof " + helperType
561: + ')');
562: stream.println(" return (" + helperType + ")obj;");
563: stream.println(" else");
564: stream.println(" {");
565: stream
566: .println(" org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate ();");
567: String stubNameofEntry = stubName((InterfaceEntry) entry);
568: stream.println(" " + stubNameofEntry + " stub = new "
569: + stubNameofEntry + " ();");
570: stream.println(" stub._set_delegate(delegate);");
571: stream.println(" return stub;");
572: stream.println(" }");
573: stream.println(" }");
574: } // writeUncheckedRemoteNarrow
575:
576: /**
577: * Write the unchecked narrow() method for local interface.
578: **/
579: private void writeRemoteUncheckedNarrowForLocal(
580: boolean hasAbstractParent) {
581: stream.println(" public static " + helperType
582: + " unchecked_narrow (org.omg.CORBA.Object obj)");
583: stream.println(" {");
584: stream.println(" if (obj == null)");
585: stream.println(" return null;");
586: stream.println(" else if (obj instanceof " + helperType
587: + ')');
588: stream.println(" return (" + helperType + ")obj;");
589: stream.println(" else");
590: stream.println(" throw new org.omg.CORBA.BAD_PARAM ();");
591: stream.println(" }");
592: } // writeRemoteUncheckedNarrowForLocal
593:
594: /**
595: * Write the unchecked narrow() method for abstract interface.
596: **/
597: private void writeRemoteUncheckedNarrowForAbstract(
598: boolean hasAbstractParent) {
599: stream.print(" public static " + helperType
600: + " unchecked_narrow (java.lang.Object obj)");
601: stream.println(" {");
602: stream.println(" if (obj == null)");
603: stream.println(" return null;");
604: if (hasAbstractParent) {
605: stream
606: .println(" else if (obj instanceof org.omg.CORBA.Object)");
607: stream
608: .println(" return unchecked_narrow ((org.omg.CORBA.Object) obj);");
609: } else {
610: stream.println(" else if (obj instanceof " + helperType
611: + ')');
612: stream.println(" return (" + helperType + ")obj;");
613: }
614:
615: if (!hasAbstractParent) {
616: String stubNameofEntry = stubName((InterfaceEntry) entry);
617:
618: stream
619: .println(" else if (obj instanceof org.omg.CORBA.portable.ObjectImpl) {");
620: stream
621: .println(" org.omg.CORBA.portable.ObjectImpl impl = (org.omg.CORBA.portable.ObjectImpl)obj ;");
622: stream
623: .println(" org.omg.CORBA.portable.Delegate delegate = impl._get_delegate() ;");
624: stream.println(" " + stubNameofEntry + " stub = new "
625: + stubNameofEntry + " ();");
626: stream.println(" stub._set_delegate(delegate);");
627: stream.println(" return stub;");
628: stream.println(" }");
629: }
630: ;
631:
632: stream.println(" throw new org.omg.CORBA.BAD_PARAM ();");
633: stream.println(" }");
634: stream.println();
635: } // writeRemoteUncheckedNarrowForAbstract
636:
637: /**
638: * Generate the GetID method.
639: **/
640: protected void writeGetID() {
641: if (!Util.IDLEntity(entry))
642: return;
643: stream.println(" public String get_id ()");
644: stream.println(" {");
645: stream.println(" return _id;");
646: stream.println(" }");
647: stream.println();
648: } // writeGetID
649:
650: /**
651: * Generate the GetType method.
652: **/
653: protected void writeGetType() {
654: if (!Util.IDLEntity(entry))
655: return;
656: stream.println(" public org.omg.CORBA.TypeCode get_type ()");
657: stream.println(" {");
658: stream.println(" return type ();");
659: stream.println(" }");
660: stream.println();
661: } // writeGetID
662:
663: /**
664: * Generate the get_class method.
665: **/
666: protected void writeGetClass() {
667: stream.println(" public Class get_class ()");
668: stream.println(" {");
669: stream.println(" return " + helperType + ".class;"); //<d59383>
670: stream.println(" }");
671: stream.println();
672: } // writeGetClass
673:
674: /**
675: * Generate the get_instance method.
676: **/
677: protected void writeGetInstance() {
678: stream
679: .println(" public static org.omg.CORBA.portable.ValueHelper get_instance ()");
680: stream.println(" {");
681: stream.println(" return helper;");
682: stream.println(" }");
683: stream.println();
684: } // writeGetInstance
685:
686: /**
687: * Generate the GetSafeBaseIds method.
688: **/
689: protected void writeGetSafeBaseIds() {
690: stream.println(" public String[] get_truncatable_base_ids ()");
691: stream.println(" {");
692: stream.println(" return _truncatable_ids;");
693: stream.println(" }");
694: stream.println();
695: } // writeGetSafeBaseIds
696:
697: /**
698: * Return the stub name for the interface entry.
699: **/
700: protected String stubName(InterfaceEntry entry) {
701: String name;
702: if (entry.container().name().equals(""))
703: name = '_' + entry.name() + "Stub";
704: else {
705: name = Util.containerFullName(entry.container()) + "._"
706: + entry.name() + "Stub";
707: }
708: return name.replace('/', '.');
709: } // stubName
710:
711: protected java.util.Hashtable symbolTable;
712: protected com.sun.tools.corba.se.idl.SymtabEntry entry;
713: protected GenFileStream stream;
714:
715: // Unique to this generator
716: protected String helperClass;
717: protected String helperType;
718: } // class Helper
|