0001: /*
0002: * JacORB - a free Java ORB
0003: *
0004: * Copyright (C) 1997-2004 Gerald Brose.
0005: *
0006: * This library is free software; you can redistribute it and/or
0007: * modify it under the terms of the GNU Library General Public
0008: * License as published by the Free Software Foundation; either
0009: * version 2 of the License, or (at your option) any later version.
0010: *
0011: * This library is distributed in the hope that it will be useful,
0012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * Library General Public License for more details.
0015: *
0016: * You should have received a copy of the GNU Library General Public
0017: * License along with this library; if not, write to the Free
0018: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
0019: */
0020:
0021: package org.jacorb.idl;
0022:
0023: /**
0024: * @author Gerald Brose
0025: * @version $Id: Interface.java,v 1.76 2006/10/14 12:25:25 andre.spiegel Exp $
0026: */
0027:
0028: import java.io.File;
0029: import java.io.IOException;
0030: import java.io.PrintWriter;
0031: import java.util.*;
0032:
0033: import org.jacorb.idl.util.PrettyPrinter;
0034:
0035: public class Interface extends TypeDeclaration implements Scope {
0036: public InterfaceBody body = null;
0037: public SymbolList inheritanceSpec = null;
0038:
0039: private String[] ids = null;
0040: private boolean is_local = false;
0041: private boolean is_abstract = false;
0042: private ScopeData scopeData;
0043: private boolean parsed = false;
0044:
0045: private ReplyHandler replyHandler = null;
0046:
0047: /** IR information that would otherwise be lost */
0048: private Hashtable irInfoTable = new Hashtable();
0049:
0050: /** <code>abstractInterfaces</code> is to keep a record of those interfaces
0051: * that are abstract so any inheriting interface know what to inherit from.
0052: */
0053: protected static HashSet abstractInterfaces;
0054:
0055: public Interface(int num) {
0056: super (num);
0057: pack_name = "";
0058: }
0059:
0060: public void setScopeData(ScopeData data) {
0061: scopeData = data;
0062: }
0063:
0064: public ScopeData getScopeData() {
0065: return scopeData;
0066: }
0067:
0068: public void setPackage(String s) {
0069: if (logger.isDebugEnabled())
0070: logger.debug("Interface setPackage " + s);
0071:
0072: s = parser.pack_replace(s);
0073:
0074: if (pack_name.length() > 0)
0075: pack_name = s + "." + pack_name;
0076: else
0077: pack_name = s;
0078:
0079: if (body != null) // could've been a forward declaration)
0080: body.setPackage(s); // a new scope!
0081:
0082: if (inheritanceSpec != null)
0083: inheritanceSpec.setPackage(s);
0084: }
0085:
0086: public void set_abstract() {
0087: is_abstract = true;
0088: }
0089:
0090: /** override methods from superclass TypeDeclaration */
0091:
0092: public TypeDeclaration declaration() {
0093: return this ;
0094: };
0095:
0096: public String typeName() {
0097: return full_name();
0098: }
0099:
0100: public Object clone() {
0101: throw new RuntimeException("Don't clone me, i am an interface!");
0102: }
0103:
0104: private ConstrTypeSpec unwindTypedefs(ScopedName scopedName) {
0105: TypeSpec resolvedTSpec = scopedName.resolvedTypeSpec();
0106: //unwind any typedefs
0107: while (resolvedTSpec instanceof AliasTypeSpec) {
0108: resolvedTSpec = ((AliasTypeSpec) resolvedTSpec)
0109: .originalType();
0110: }
0111:
0112: if (!(resolvedTSpec instanceof ConstrTypeSpec)) {
0113: if (logger.isDebugEnabled()) {
0114: logger
0115: .debug("Illegal inheritance spec in Interface.unwindTypeDefs, not a constr. type but "
0116: + resolvedTSpec.getClass()
0117: + ", name "
0118: + scopedName);
0119: }
0120: parser.fatal_error(
0121: "Illegal inheritance spec in Interface.unwindTypeDefs (not a constr. type): "
0122: + inheritanceSpec, token);
0123: }
0124:
0125: return (ConstrTypeSpec) resolvedTSpec;
0126: }
0127:
0128: public void setEnclosingSymbol(IdlSymbol s) {
0129: if (enclosing_symbol != null && enclosing_symbol != s)
0130: throw new RuntimeException(
0131: "Compiler Error: trying to reassign container for "
0132: + name);
0133:
0134: enclosing_symbol = s;
0135:
0136: if (inheritanceSpec != null)
0137: inheritanceSpec.setEnclosingSymbol(s);
0138: }
0139:
0140: /**
0141: * set by the parser after creating this object depending
0142: * on the presence of the "local" modifier.
0143: */
0144:
0145: public void set_locality(boolean local) {
0146: this .is_local = local;
0147: }
0148:
0149: /**
0150: * <code>getTypeCodeExpression</code> produces a string for an expression
0151: * of type TypeCode that describes this type.
0152: * @return a string value.
0153: */
0154:
0155: public String getTypeCodeExpression() {
0156: if (is_abstract) {
0157: return ("org.omg.CORBA.ORB.init().create_abstract_interface_tc(\""
0158: + id() + "\", \"" + name + "\")");
0159: }
0160: return ("org.omg.CORBA.ORB.init().create_interface_tc(\""
0161: + id() + "\", \"" + name + "\")");
0162: }
0163:
0164: public String getTypeCodeExpression(Set knownTypes) {
0165: if (knownTypes.contains(this )) {
0166: return this .getRecursiveTypeCodeExpression();
0167: }
0168:
0169: return this .getTypeCodeExpression();
0170: }
0171:
0172: public boolean basic() {
0173: return true;
0174: }
0175:
0176: public String holderName() {
0177: return toString() + "Holder";
0178: }
0179:
0180: public String helperName() {
0181: return toString() + "Helper";
0182: }
0183:
0184: public String toString() {
0185: return getFullName(typeName());
0186: }
0187:
0188: public void set_included(boolean i) {
0189: included = i;
0190: }
0191:
0192: public String printReadExpression(String Streamname) {
0193: return javaName() + "Helper.read(" + Streamname + ")";
0194: }
0195:
0196: public String printWriteStatement(String var_name, String Streamname) {
0197: return javaName() + "Helper.write(" + Streamname + ","
0198: + var_name + ");";
0199: }
0200:
0201: public void parse() {
0202: boolean justAnotherOne = false;
0203:
0204: if (parsed) {
0205: // there are occasions where the compiler may try to parse
0206: // an Interface type spec for a second time, viz if it is
0207: // referred to through a scoped name in another struct member.
0208: // that's not a problem, but we have to skip parsing again!
0209: // Fixes bug #629, copied from fix for bug #84
0210: return;
0211: }
0212:
0213: escapeName();
0214:
0215: ConstrTypeSpec ctspec = new ConstrTypeSpec(new_num());
0216:
0217: if (is_abstract) {
0218: if (logger.isDebugEnabled()) {
0219: logger.debug("Adding " + full_name()
0220: + " to abstract interface list");
0221: }
0222:
0223: if (abstractInterfaces == null) {
0224: abstractInterfaces = new HashSet();
0225: }
0226:
0227: abstractInterfaces.add(full_name());
0228: }
0229:
0230: try {
0231: ScopedName.definePseudoScope(full_name());
0232: ctspec.c_type_spec = this ;
0233:
0234: if (is_pseudo)
0235: NameTable.define(full_name(), "pseudo interface");
0236: else
0237: NameTable.define(full_name(), "interface");
0238:
0239: TypeMap.typedef(full_name(), ctspec);
0240: } catch (IllegalRedefinition ill) {
0241: parser.fatal_error("Cannot redefine " + token.str_val
0242: + " in nested scope as " + ill.newDef, token);
0243: } catch (NameAlreadyDefined nad) {
0244: // if we get here, there is already a type spec for this interface
0245: // in the global type table for a forward declaration of this
0246: // interface. We must replace that table entry with this type spec
0247: // unless this is yet another forward declaration
0248:
0249: if (parser.get_pending(full_name()) != null) {
0250: if (body == null) {
0251: justAnotherOne = true;
0252: }
0253:
0254: // else actual definition
0255:
0256: if ((!(full_name().equals("CORBA.TypeCode") || full_name()
0257: .equals("org.omg.CORBA.TypeCode")))
0258: && body != null) {
0259: TypeMap.replaceForwardDeclaration(full_name(),
0260: ctspec);
0261: }
0262: } else {
0263: // this is another forward declaration, ignore
0264: }
0265: }
0266:
0267: if (body != null) {
0268: if (inheritanceSpec != null && inheritanceSpec.v.size() > 0) {
0269: if (logger.isDebugEnabled())
0270: logger.debug("Checking inheritanceSpec of "
0271: + full_name());
0272:
0273: HashSet h = new HashSet();
0274:
0275: for (Enumeration e = inheritanceSpec.v.elements(); e
0276: .hasMoreElements();) {
0277: ScopedName name = (ScopedName) e.nextElement();
0278:
0279: ConstrTypeSpec ts = unwindTypedefs(name);
0280:
0281: if (ts.declaration() instanceof Interface) {
0282: if (h.contains(ts.full_name())) {
0283: parser
0284: .fatal_error(
0285: "Illegal inheritance spec: "
0286: + inheritanceSpec
0287: + " (repeated inheritance not allowed).",
0288: token);
0289: }
0290:
0291: // else:
0292: h.add(ts.full_name());
0293:
0294: continue;
0295: }
0296:
0297: // else:
0298: parser.fatal_error("Illegal inheritance spec: "
0299: + inheritanceSpec + " (ancestor "
0300: + ts.full_name() + " not an interface)",
0301: token);
0302: }
0303:
0304: body.set_ancestors(inheritanceSpec);
0305: }
0306:
0307: body.parse();
0308: NameTable.parsed_interfaces.put(full_name(), "");
0309:
0310: if (parser.generate_ami_callback) {
0311: replyHandler = new ReplyHandler(this );
0312: replyHandler.parse();
0313: }
0314:
0315: } else if (!justAnotherOne) {
0316: // i am forward declared, must set myself as
0317: // pending further parsing
0318: parser.set_pending(full_name());
0319: }
0320:
0321: parsed = true;
0322: }
0323:
0324: InterfaceBody getBody() {
0325: if (parser.get_pending(full_name()) != null) {
0326: parser.fatal_error(full_name()
0327: + " is forward declared and still pending!", token);
0328: } else if (body == null) {
0329: if (((Interface) ((ConstrTypeSpec) TypeMap.map(full_name())).c_type_spec) != this )
0330: body = ((Interface) ((ConstrTypeSpec) TypeMap
0331: .map(full_name())).c_type_spec).getBody();
0332:
0333: if (body == null)
0334: parser.fatal_error(full_name()
0335: + " still has an empty body!", token);
0336: }
0337:
0338: return body;
0339: }
0340:
0341: /**
0342: * Open a PrintWriter to write to the .java file for typeName.
0343: * @return null, if the output file already exists and is more
0344: * recent than the input IDL file.
0345: */
0346:
0347: protected PrintWriter openOutput(String typeName) {
0348: String path = parser.out_dir + fileSeparator
0349: + pack_name.replace('.', fileSeparator);
0350: File dir = new File(path);
0351:
0352: if (!dir.exists()) {
0353: if (!dir.mkdirs()) {
0354: org.jacorb.idl.parser.fatal_error("Unable to create "
0355: + path, null);
0356: }
0357: }
0358:
0359: try {
0360: final File f = new File(dir, typeName + ".java");
0361: if (GlobalInputStream.isMoreRecentThan(f)) {
0362: PrintWriter ps = new PrintWriter(
0363: new java.io.FileWriter(f)) {
0364: public void close() {
0365: super .close();
0366: PrettyPrinter.prettify(f);
0367: }
0368: };
0369: return ps;
0370: }
0371:
0372: // no need to open file for printing, existing file is more
0373: // recent than IDL file.
0374:
0375: return null;
0376: } catch (IOException e) {
0377: throw new RuntimeException(
0378: "Could not open output file for " + typeName + " ("
0379: + e + ")");
0380: }
0381: }
0382:
0383: protected void printPackage(PrintWriter ps) {
0384: if (Environment.JAVA14 && pack_name.equals(""))
0385: lexer.emit_warn("No package defined for " + name
0386: + " - illegal in JDK1.4", token);
0387:
0388: if (!pack_name.equals(""))
0389: ps.println("package " + pack_name + ";\n");
0390: }
0391:
0392: /**
0393: * If this interface inherits from classes in the unnamed package,
0394: * generate explicit import statements for them.
0395: */
0396: protected void printSuperclassImports(PrintWriter ps) {
0397: if (inheritanceSpec.v.size() > 0) {
0398: Enumeration e = inheritanceSpec.v.elements();
0399:
0400: for (; e.hasMoreElements();) {
0401: ScopedName sn = (ScopedName) e.nextElement();
0402:
0403: if (sn.resolvedName().indexOf('.') < 0) {
0404: ps.println("import " + sn + ";");
0405: }
0406: }
0407: }
0408: }
0409:
0410: /**
0411: * generate the signature interface
0412: */
0413:
0414: protected void printInterface() {
0415: PrintWriter ps = openOutput(name);
0416: if (ps == null) {
0417: return;
0418: }
0419:
0420: printPackage(ps);
0421: printSuperclassImports(ps);
0422: printClassComment("interface", name, ps);
0423:
0424: if (is_pseudo) {
0425: ps.println("public abstract class " + name);
0426:
0427: if (inheritanceSpec.v.size() > 0) {
0428: StringBuffer pseudo_bases = new StringBuffer();
0429: StringBuffer regular_bases = new StringBuffer();
0430: String comma = " ";
0431:
0432: for (Enumeration e = inheritanceSpec.v.elements(); e
0433: .hasMoreElements();) {
0434: ScopedName sn = ((ScopedName) e.nextElement());
0435: String name = sn.resolvedName();
0436:
0437: if (sn.is_pseudo()) {
0438: pseudo_bases.append(comma + name);
0439: } else {
0440: regular_bases.append(comma + name);
0441: }
0442:
0443: if (inheritanceSpec.v.size() > 1)
0444: comma = ",";
0445: }
0446:
0447: if (pseudo_bases.length() > 0)
0448: ps.println("\textends " + pseudo_bases.toString());
0449:
0450: if (regular_bases.length() > 0)
0451: ps.println("\timplements "
0452: + regular_bases.toString());
0453:
0454: }
0455: } else {
0456: ps.println("public interface " + name);
0457:
0458: if (is_abstract) {
0459: ps.print("\textends org.omg.CORBA.portable.IDLEntity");
0460: } else {
0461: ps.print("\textends " + name + "Operations");
0462:
0463: if (is_local) {
0464: // Looking at RTF work it
0465: // seems a new interface 'LocalInterface' will be used for this purpose.
0466:
0467: ps
0468: .print(", org.omg.CORBA.LocalInterface, org.omg.CORBA.portable.IDLEntity");
0469: } else {
0470: ps
0471: .print(", org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity");
0472: }
0473: }
0474:
0475: if (inheritanceSpec.v.size() > 0) {
0476: Enumeration e = inheritanceSpec.v.elements();
0477:
0478: while (e.hasMoreElements()) {
0479: ScopedName sne = (ScopedName) e.nextElement();
0480: if (sne.resolvedTypeSpec() instanceof ReplyHandlerTypeSpec
0481: && parser.generate_ami_callback) {
0482: ps.print(", " + sne);
0483: } else {
0484: ConstrTypeSpec ts = unwindTypedefs(sne);
0485: ps.print(", " + ts);
0486: }
0487: }
0488: }
0489: }
0490:
0491: ps.println("\n{");
0492:
0493: // body can be null for forward declaration
0494: if (body != null) {
0495: body.printInterfaceMethods(ps);
0496:
0497: // for an abstract interface, the generated abstract class contains
0498: // the operation signatures since there is no separate signature
0499: // interface
0500: if (is_abstract) {
0501: body.printConstants(ps);
0502: body.printOperationSignatures(ps);
0503: }
0504: }
0505:
0506: ps.println("}");
0507: ps.close();
0508: }
0509:
0510: /**
0511: * generate the operations Java interface (not for pseudo interfaces)
0512: */
0513:
0514: protected void printOperations() {
0515: PrintWriter ps = openOutput(name + "Operations");
0516: if (ps == null) {
0517: return;
0518: }
0519:
0520: printPackage(ps);
0521: printSuperclassImports(ps);
0522: printImport(ps);
0523: printClassComment("interface", name, ps);
0524:
0525: ps.println("public interface " + name + "Operations");
0526:
0527: if (inheritanceSpec.v.size() > 0) {
0528: ps.print("\textends ");
0529: Enumeration e = inheritanceSpec.v.elements();
0530:
0531: do {
0532: ScopedName sne = (ScopedName) e.nextElement();
0533:
0534: // See description of abstractInterfaces for logic here.
0535: if (abstractInterfaces != null
0536: && abstractInterfaces.contains(sne.toString())) {
0537: ps.print(sne);
0538: } else {
0539: if (sne.resolvedTypeSpec() instanceof ReplyHandlerTypeSpec
0540: && parser.generate_ami_callback) {
0541: ps.print(sne + "Operations");
0542: } else {
0543: ConstrTypeSpec ts = unwindTypedefs(sne);
0544: ps.print(ts + "Operations");
0545: }
0546: }
0547:
0548: if (e.hasMoreElements()) {
0549: ps.print(" , ");
0550: }
0551: } while (e.hasMoreElements());
0552:
0553: ps.print("\n");
0554: }
0555:
0556: ps.println("{");
0557:
0558: if (body != null) {
0559: // forward declaration
0560: body.printConstants(ps);
0561: body.printOperationSignatures(ps);
0562: }
0563:
0564: ps.println("}");
0565: ps.close();
0566: }
0567:
0568: /**
0569: * Print the holder class for the interface.
0570: */
0571: protected void printHolder() {
0572: PrintWriter ps = openOutput(name + "Holder");
0573: if (ps == null) {
0574: return;
0575: }
0576:
0577: printPackage(ps);
0578: printClassComment("interface", name, ps);
0579:
0580: ps.print("public" + parser.getFinalString() + " class " + name
0581: + "Holder");
0582: ps.print("\timplements org.omg.CORBA.portable.Streamable");
0583:
0584: ps.println("{");
0585: ps.println("\t public " + name + " value;");
0586:
0587: ps.println("\tpublic " + name + "Holder()");
0588: ps.println("\t{");
0589: ps.println("\t}");
0590:
0591: ps.println("\tpublic " + name + "Holder (final " + name
0592: + " initial)");
0593: ps.println("\t{");
0594: ps.println("\t\tvalue = initial;");
0595: ps.println("\t}");
0596:
0597: ps.println("\tpublic org.omg.CORBA.TypeCode _type()");
0598: ps.println("\t{");
0599: ps.println("\t\treturn " + name + "Helper.type();");
0600: ps.println("\t}");
0601:
0602: ps
0603: .println("\tpublic void _read (final org.omg.CORBA.portable.InputStream in)");
0604: ps.println("\t{");
0605: ps.println("\t\tvalue = " + name + "Helper.read (in);");
0606: ps.println("\t}");
0607:
0608: ps
0609: .println("\tpublic void _write (final org.omg.CORBA.portable.OutputStream _out)");
0610: ps.println("\t{");
0611: ps.println("\t\t" + name + "Helper.write (_out,value);");
0612: ps.println("\t}");
0613:
0614: ps.println("}");
0615: ps.close();
0616: }
0617:
0618: /**
0619: * Generates a narrow method for the Helper class.
0620: * @param ps the PrintWriter to which the method will be written
0621: * @param checked determines whether an ordinary narrow() method or an
0622: * unchecked_narrow() method should be generated
0623: * @param forCorbaObject determines whether the parameter type of the
0624: * narrow method is org.omg.CORBA.Object or
0625: * java.lang.Object
0626: */
0627: protected void printNarrow(PrintWriter ps, boolean checked,
0628: boolean forCorbaObject) {
0629: ps.print("\tpublic static " + typeName());
0630: ps.print(checked ? " narrow" : " unchecked_narrow");
0631: ps.println(forCorbaObject ? "(final org.omg.CORBA.Object obj)"
0632: : "(final java.lang.Object obj)");
0633: ps.println("\t{");
0634: ps.println("\t\tif (obj == null)");
0635: ps.println("\t\t{");
0636: ps.println("\t\t\treturn null;");
0637: ps.println("\t\t}");
0638: ps.println("\t\telse if (obj instanceof " + typeName() + ")");
0639: ps.println("\t\t{");
0640: ps.println("\t\t\treturn (" + typeName() + ")obj;");
0641: ps.println("\t\t}");
0642:
0643: if (parser.generate_stubs && !is_local) {
0644: if (checked && forCorbaObject) {
0645: ps.println("\t\telse if (obj._is_a(\"" + id() + "\"))");
0646: printStubInterposition(ps);
0647: printElseNarrowFailed(ps);
0648: } else if (!checked && forCorbaObject) {
0649: ps.println("\t\telse");
0650: printStubInterposition(ps);
0651: } else if (checked && !forCorbaObject) {
0652: ps
0653: .println("\t\telse if (obj instanceof org.omg.CORBA.Object &&");
0654: ps
0655: .println("\t\t ((org.omg.CORBA.Object)obj)._is_a(\""
0656: + id() + "\"))");
0657: printStubInterposition(ps);
0658: printElseNarrowFailed(ps);
0659: } else if (!checked && !forCorbaObject) {
0660: ps
0661: .println("\t\tif (obj instanceof org.omg.CORBA.Object)");
0662: printStubInterposition(ps);
0663: printElseNarrowFailed(ps);
0664: }
0665: } else {
0666: printElseNarrowFailed(ps);
0667: }
0668: ps.println("\t}");
0669: }
0670:
0671: /**
0672: * Generates the code for a narrow method with which a stub is inserted
0673: * between an object implementation and the client.
0674: */
0675: protected void printStubInterposition(PrintWriter ps) {
0676: final String stub_name = stubName(typeName());
0677: ps.println("\t\t{");
0678: ps.println("\t\t\t" + stub_name + " stub;");
0679: ps.println("\t\t\tstub = new " + stub_name + "();");
0680: ps
0681: .println("\t\t\tstub._set_delegate(((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate());");
0682: ps.println("\t\t\treturn stub;");
0683: ps.println("\t\t}");
0684: }
0685:
0686: /**
0687: * Prints the else clause of a narrow method that signals general failure.
0688: */
0689: protected void printElseNarrowFailed(PrintWriter ps) {
0690: ps.println("\t\telse");
0691: ps.println("\t\t{");
0692: ps
0693: .println("\t\t\tthrow new org.omg.CORBA.BAD_PARAM(\"Narrow failed\");");
0694: ps.println("\t\t}");
0695: }
0696:
0697: /**
0698: * Generate the helper class for an interface
0699: */
0700: protected void printHelper() {
0701: PrintWriter ps = openOutput(name + "Helper");
0702: if (ps == null) {
0703: return;
0704: }
0705:
0706: printPackage(ps);
0707: printImport(ps);
0708:
0709: printClassComment("interface", name, ps);
0710:
0711: ps.println("public" + parser.getFinalString() + " class "
0712: + name + "Helper");
0713: ps.println("{");
0714:
0715: // Generate insert (handle either CORBA.Object or Serializable case)
0716: ps
0717: .println("\tpublic static void insert (final org.omg.CORBA.Any any, final "
0718: + typeName() + " s)");
0719: ps.println("\t{");
0720:
0721: if (is_abstract) {
0722: ps.println("\t\tif (s instanceof org.omg.CORBA.Object)");
0723: ps.println("\t\t{");
0724: ps
0725: .println("\t\t\tany.insert_Object((org.omg.CORBA.Object)s);");
0726: ps.println("\t\t}");
0727: ps
0728: .println("\t\telse if (s instanceof java.io.Serializable)");
0729: ps.println("\t\t{");
0730: ps
0731: .println("\t\t\tany.insert_Value((java.io.Serializable)s);");
0732: ps.println("\t\t}");
0733: ps.println("\t\telse");
0734: ps.println("\t\t{");
0735: ps
0736: .println("\t\t\tthrow new org.omg.CORBA.BAD_PARAM(\"Failed to insert in helper\");");
0737: ps.println("\t\t}");
0738: } else {
0739: ps.println("\t\t\tany.insert_Object(s);");
0740: }
0741:
0742: ps.println("\t}");
0743:
0744: // Generate extract
0745: ps.println("\tpublic static " + typeName()
0746: + " extract(final org.omg.CORBA.Any any)");
0747: ps.println("\t{");
0748:
0749: if (is_abstract) {
0750: ps.println("\t\ttry");
0751: ps.println("\t\t{");
0752: ps.println("\t\t\treturn narrow(any.extract_Object());");
0753: ps.println("\t\t}");
0754: ps.println("\t\tcatch (org.omg.CORBA.BAD_OPERATION ex)");
0755: ps.println("\t\t{");
0756: ps.println("\t\t\ttry");
0757: ps.println("\t\t\t{");
0758: ps.println("\t\t\t\treturn (" + typeName()
0759: + ")any.extract_Value();");
0760: ps.println("\t\t\t}");
0761: ps.println("\t\t\tcatch (ClassCastException e)");
0762: ps.println("\t\t\t{");
0763: ps
0764: .println("\t\t\t\tthrow new org.omg.CORBA.MARSHAL(e.getMessage());");
0765: ps.println("\t\t\t}");
0766: ps.println("\t\t}");
0767: } else {
0768: if (parser.useUncheckedNarrow) {
0769: ps
0770: .println("\t\treturn unchecked_narrow(any.extract_Object());");
0771: } else {
0772: ps.println("\t\treturn narrow(any.extract_Object()) ;");
0773: }
0774: }
0775:
0776: ps.println("\t}");
0777:
0778: // Generate the typecode
0779: ps.println("\tpublic static org.omg.CORBA.TypeCode type()");
0780: ps.println("\t{");
0781: ps.println("\t\treturn " + getTypeCodeExpression() + ";");
0782: ps.println("\t}");
0783:
0784: printIdMethod(ps);
0785:
0786: // Generate the read
0787: ps.println("\tpublic static " + name
0788: + " read(final org.omg.CORBA.portable.InputStream in)");
0789: ps.println("\t{");
0790:
0791: if (is_local) {
0792: ps.println("\t\tthrow new org.omg.CORBA.MARSHAL();");
0793: } else {
0794: if (is_abstract) {
0795: ps
0796: .println("\t\treturn narrow(((org.omg.CORBA_2_3.portable.InputStream)in).read_abstract_interface());");
0797: } else {
0798: final String stubClass = parser.generate_stubs ? stubName(typeName())
0799: + ".class"
0800: : "";
0801: if (parser.useUncheckedNarrow) {
0802: ps
0803: .println("\t\treturn unchecked_narrow(in.read_Object("
0804: + stubClass + "));");
0805: } else {
0806: ps.println("\t\treturn narrow(in.read_Object("
0807: + stubClass + "));");
0808: }
0809: }
0810: }
0811:
0812: ps.println("\t}");
0813:
0814: // Generate the write
0815: ps
0816: .println("\tpublic static void write(final org.omg.CORBA.portable.OutputStream _out, final "
0817: + typeName() + " s)");
0818: ps.println("\t{");
0819:
0820: if (is_local) {
0821: ps.println("\t\tthrow new org.omg.CORBA.MARSHAL();");
0822: } else {
0823: if (is_abstract) {
0824: ps
0825: .println("\t\t((org.omg.CORBA_2_3.portable.OutputStream)_out).write_abstract_interface(s);");
0826: } else {
0827: ps.println("\t\t_out.write_Object(s);");
0828: }
0829: }
0830:
0831: ps.println("\t}");
0832:
0833: // Generate narrow methods (cf. Java Mapping 1.2, sect. 1.5.2)
0834: if (is_abstract) {
0835: printNarrow(ps, true, false); // checked, java.lang.Object
0836: printNarrow(ps, false, false); // unchecked, java.lang.Object
0837: } else if (hasAbstractBase()) {
0838: printNarrow(ps, true, true); // checked, CORBA Object
0839: printNarrow(ps, true, false); // checked, java.lang.Object
0840: printNarrow(ps, false, true); // unchecked, CORBA Object
0841: printNarrow(ps, false, false); // unchecked, java.lang.Object
0842: } else {
0843: printNarrow(ps, true, true); // checked, CORBA Object
0844: printNarrow(ps, false, true); // unchecked, CORBA Object
0845: }
0846:
0847: ps.println("}");
0848: ps.close();
0849: }
0850:
0851: public String[] get_ids() {
0852: if (ids == null) {
0853: Set base_ids = new HashSet();
0854:
0855: if (inheritanceSpec != null && inheritanceSpec.v.size() > 0) {
0856: for (Iterator i = inheritanceSpec.v.iterator(); i
0857: .hasNext();) {
0858: TypeSpec ts = ((ScopedName) i.next())
0859: .resolvedTypeSpec();
0860:
0861: if (ts instanceof ConstrTypeSpec) {
0862: Interface base = (Interface) ((ConstrTypeSpec) ts).c_type_spec;
0863: base_ids.addAll(Arrays.asList(base.get_ids()));
0864: } else if (ts instanceof ReplyHandlerTypeSpec) {
0865: base_ids
0866: .add("IDL:omg.org/Messaging/ReplyHandler:1.0");
0867: }
0868: }
0869: }
0870:
0871: ids = new String[base_ids.size() + 1];
0872: ids[0] = id();
0873: int i = 1;
0874:
0875: for (Iterator j = base_ids.iterator(); j.hasNext(); i++) {
0876: ids[i] = (String) j.next();
0877: }
0878: }
0879:
0880: return ids;
0881: }
0882:
0883: /**
0884: * Returns true if this interface has at least one abstract base type.
0885: */
0886: protected boolean hasAbstractBase() {
0887: if (inheritanceSpec != null && inheritanceSpec.v.size() > 0) {
0888: for (Iterator i = inheritanceSpec.v.iterator(); i.hasNext();) {
0889: TypeSpec ts = ((ScopedName) i.next())
0890: .resolvedTypeSpec();
0891: if (ts instanceof ConstrTypeSpec) {
0892: Interface base = (Interface) ((ConstrTypeSpec) ts).c_type_spec;
0893: if (base.is_abstract || base.hasAbstractBase()) {
0894: return true;
0895: }
0896: }
0897: }
0898: }
0899: return false;
0900: }
0901:
0902: /**
0903: * Generates a stub class for this Interface
0904: */
0905:
0906: protected void printStub() {
0907: PrintWriter ps = openOutput("_" + name + "Stub");
0908: if (ps == null) {
0909: return;
0910: }
0911:
0912: printPackage(ps);
0913: printImport(ps);
0914: printClassComment("interface", name, ps);
0915:
0916: ps.println("public class _" + name + "Stub");
0917: ps.println("\textends org.omg.CORBA.portable.ObjectImpl");
0918:
0919: ps.println("\timplements " + javaName());
0920: ps.println("{");
0921:
0922: ps.print("\tprivate String[] ids = {");
0923: String[] ids = get_ids();
0924: for (int i = 0; i < ids.length - 1; i++)
0925: ps.print("\"" + ids[i] + "\",");
0926:
0927: ps.println("\"" + ids[ids.length - 1] + "\"};");
0928: ps.println("\tpublic String[] _ids()");
0929: ps.println("\t{");
0930: ps.println("\t\treturn ids;");
0931: ps.println("\t}\n");
0932:
0933: if (!parser.cldc10) {
0934: ps
0935: .print("\tpublic final static java.lang.Class _opsClass = ");
0936: if (!pack_name.equals("")) {
0937: ps.print(pack_name + ".");
0938: }
0939: if (is_abstract) {
0940: ps.println(name + ".class;");
0941: } else {
0942: ps.println(name + "Operations.class;");
0943: }
0944: } else {
0945: // code supplied byte Nokia for CLDC10 compatibility
0946: // avoids use of the static .class variable.
0947: String fullName = null;
0948: if (!pack_name.equals("")) {
0949: fullName = pack_name + "." + name;
0950: } else {
0951: fullName = name;
0952: }
0953:
0954: ps
0955: .println("\tpublic static final java.lang.Class _opsClass;");
0956: ps.println("\tstatic");
0957: ps.println("\t{");
0958: ps.println("\t\ttry"); //try
0959: ps.println("\t\t{"); //{
0960:
0961: ps.print("\t\t\t_opsClass = Class.forName(\"");
0962: if (!pack_name.equals(""))
0963: ps.print(pack_name + ".");
0964: ps.println(name + "Operations\");");
0965:
0966: ps.println("\t\t}"); //}
0967: ps.println("\t\tcatch(ClassNotFoundException cnfe)");
0968: ps.println("\t\t{"); //{
0969: ps.println("\t\t\tthrow new RuntimeException(\"Class "
0970: + fullName + " was not found.\");");
0971: ps.println("\t\t}"); //}
0972: ps.println("\t}\n");
0973: }
0974:
0975: body.printStubMethods(ps, name, is_local, is_abstract);
0976:
0977: ps.println("}");
0978: ps.close();
0979: }
0980:
0981: protected void printImplSkeleton() {
0982: PrintWriter ps = openOutput(name + "POA");
0983: if (ps == null) {
0984: return;
0985: }
0986:
0987: printPackage(ps);
0988: printImport(ps);
0989: printClassComment("interface", name, ps);
0990:
0991: ps.print("public abstract class " + name + "POA");
0992: ps.println("\n\textends org.omg.PortableServer.Servant");
0993: ps
0994: .println("\timplements org.omg.CORBA.portable.InvokeHandler, "
0995: + javaName() + "Operations");
0996: ps.println("{");
0997:
0998: body.printOperationsHash(ps);
0999:
1000: ps.print("\tprivate String[] ids = {");
1001: String[] ids = get_ids();
1002:
1003: for (int i = 0; i < ids.length - 1; i++) {
1004: ps.print("\"" + ids[i] + "\",");
1005: }
1006:
1007: ps.println("\"" + ids[ids.length - 1] + "\"};");
1008:
1009: ps.println("\tpublic " + javaName() + " _this()");
1010:
1011: ps.println("\t{");
1012:
1013: ps.println("\t\treturn " + javaName()
1014: + "Helper.narrow(_this_object());");
1015:
1016: ps.println("\t}");
1017:
1018: ps.println("\tpublic " + javaName()
1019: + " _this(org.omg.CORBA.ORB orb)");
1020:
1021: ps.println("\t{");
1022:
1023: ps.println("\t\treturn " + javaName()
1024: + "Helper.narrow(_this_object(orb));");
1025:
1026: ps.println("\t}");
1027:
1028: ps
1029: .println("\tpublic org.omg.CORBA.portable.OutputStream _invoke(String method, org.omg.CORBA.portable.InputStream _input, org.omg.CORBA.portable.ResponseHandler handler)");
1030:
1031: ps.println("\t\tthrows org.omg.CORBA.SystemException");
1032:
1033: ps.println("\t{");
1034:
1035: if (body.getMethods().length > 0) {
1036: ps
1037: .println("\t\torg.omg.CORBA.portable.OutputStream _out = null;");
1038:
1039: ps.println("\t\t// do something");
1040: }
1041:
1042: body.printSkelInvocations(ps);
1043:
1044: ps.println("\t}\n");
1045:
1046: ps
1047: .println("\tpublic String[] _all_interfaces(org.omg.PortableServer.POA poa, byte[] obj_id)");
1048:
1049: ps.println("\t{");
1050:
1051: ps.println("\t\treturn ids;");
1052:
1053: ps.println("\t}");
1054:
1055: ps.println("}");
1056:
1057: ps.close();
1058: }
1059:
1060: /**
1061: * print the stream-based skeleton class
1062: */
1063:
1064: protected void printTieSkeleton() {
1065: PrintWriter ps = openOutput(name + "POATie");
1066: if (ps == null) {
1067: return;
1068: }
1069:
1070: printPackage(ps);
1071: ps.println("import org.omg.PortableServer.POA;");
1072: printImport(ps);
1073:
1074: printClassComment("interface", name, ps);
1075:
1076: ps.println("public class " + name + "POATie");
1077: ps.println("\textends " + name + "POA");
1078: ps.println("{");
1079:
1080: ps.println("\tprivate " + name + "Operations _delegate;\n");
1081: ps.println("\tprivate POA _poa;");
1082:
1083: ps.println("\tpublic " + name + "POATie(" + name
1084: + "Operations delegate)");
1085: ps.println("\t{");
1086: ps.println("\t\t_delegate = delegate;");
1087: ps.println("\t}");
1088:
1089: ps.println("\tpublic " + name + "POATie(" + name
1090: + "Operations delegate, POA poa)");
1091: ps.println("\t{");
1092: ps.println("\t\t_delegate = delegate;");
1093: ps.println("\t\t_poa = poa;");
1094: ps.println("\t}");
1095:
1096: ps.println("\tpublic " + javaName() + " _this()");
1097: ps.println("\t{");
1098: ps.println("\t\treturn " + javaName()
1099: + "Helper.narrow(_this_object());");
1100: ps.println("\t}");
1101:
1102: ps.println("\tpublic " + javaName()
1103: + " _this(org.omg.CORBA.ORB orb)");
1104: ps.println("\t{");
1105: ps.println("\t\treturn " + javaName()
1106: + "Helper.narrow(_this_object(orb));");
1107: ps.println("\t}");
1108:
1109: ps.println("\tpublic " + name + "Operations _delegate()");
1110: ps.println("\t{");
1111: ps.println("\t\treturn _delegate;");
1112: ps.println("\t}");
1113:
1114: ps.println("\tpublic void _delegate(" + name
1115: + "Operations delegate)");
1116: ps.println("\t{");
1117: ps.println("\t\t_delegate = delegate;");
1118: ps.println("\t}");
1119:
1120: ps.println("\tpublic POA _default_POA()");
1121: ps.println("\t{");
1122: ps.println("\t\tif (_poa != null)");
1123: ps.println("\t\t{");
1124: ps.println("\t\t\treturn _poa;");
1125: ps.println("\t\t}");
1126: ps.println("\t\treturn super._default_POA();");
1127: ps.println("\t}");
1128:
1129: body.printDelegatedMethods(ps);
1130: ps.println("}");
1131: ps.close();
1132: }
1133:
1134: protected void printIRHelper() {
1135: PrintWriter ps = openOutput(name + "IRHelper");
1136: if (ps == null) {
1137: return;
1138: }
1139:
1140: printPackage(ps);
1141: ps.println("\n/**");
1142: ps
1143: .println(" * This class contains generated Interface Repository information.");
1144: ps.println(" * @author JacORB IDL compiler.");
1145: ps.println(" */");
1146:
1147: ps.println("\npublic class " + name + "IRHelper");
1148: ps.println("{");
1149:
1150: String HASHTABLE = System.getProperty("java.version")
1151: .startsWith("1.1") ? "com.sun.java.util.collections.Hashtable"
1152: : "java.util.Hashtable";
1153:
1154: ps.println("\tpublic static " + HASHTABLE + " irInfo = new "
1155: + HASHTABLE + "();");
1156: ps.println("\tstatic");
1157: ps.println("\t{");
1158: body.getIRInfo(irInfoTable);
1159:
1160: for (Enumeration e = irInfoTable.keys(); e.hasMoreElements();) {
1161: String key = (String) e.nextElement();
1162: ps.println("\t\tirInfo.put(\"" + key + "\", \""
1163: + (String) irInfoTable.get(key) + "\");");
1164: }
1165:
1166: ps.println("\t}");
1167: ps.println("}");
1168: ps.close();
1169: }
1170:
1171: protected void printLocalBase() {
1172: PrintWriter ps = openOutput("_" + name + "LocalBase");
1173: if (ps == null) {
1174: return;
1175: }
1176:
1177: printPackage(ps);
1178: ps.println("\n/**");
1179: ps
1180: .println(" * Abstract base class for implementations of local interface "
1181: + name);
1182: ps.println(" * @author JacORB IDL compiler.");
1183: ps.println(" */");
1184:
1185: ps.println("\npublic abstract class _" + name + "LocalBase");
1186: ps.println("\textends org.omg.CORBA.LocalObject");
1187: ps.println("\timplements " + name);
1188: ps.println("{");
1189: ps.print("\tprivate String[] _type_ids = {");
1190: String[] ids = get_ids();
1191:
1192: for (int i = 0; i < ids.length - 1; i++)
1193: ps.print("\"" + ids[i] + "\",");
1194:
1195: ps.println("\"" + ids[ids.length - 1] + "\"};");
1196:
1197: ps.print("\tpublic String[] _ids()");
1198:
1199: ps.println("\t{");
1200:
1201: ps.println("\t\treturn(String[])_type_ids.clone();");
1202:
1203: ps.println("\t}");
1204:
1205: ps.println("}");
1206:
1207: ps.close();
1208: }
1209:
1210: protected void printLocalTie() {
1211: PrintWriter ps = openOutput(name + "LocalTie");
1212: if (ps == null) {
1213: return;
1214: }
1215:
1216: printPackage(ps);
1217: printImport(ps);
1218:
1219: printClassComment("interface", name, ps);
1220:
1221: ps.println("public class " + name + "LocalTie");
1222: ps.println("\textends _" + name + "LocalBase");
1223: ps.println("{");
1224:
1225: ps.println("\tprivate " + name + "Operations _delegate;\n");
1226:
1227: ps.println("\tpublic " + name + "LocalTie(" + name
1228: + "Operations delegate)");
1229: ps.println("\t{");
1230: ps.println("\t\t_delegate = delegate;");
1231: ps.println("\t}");
1232:
1233: ps.println("\tpublic " + name + "Operations _delegate()");
1234: ps.println("\t{");
1235: ps.println("\t\treturn _delegate;");
1236: ps.println("\t}");
1237:
1238: ps.println("\tpublic void _delegate(" + name
1239: + "Operations delegate)");
1240: ps.println("\t{");
1241: ps.println("\t\t_delegate = delegate;");
1242: ps.println("\t}");
1243:
1244: body.printDelegatedMethods(ps);
1245: ps.println("}");
1246: ps.close();
1247: }
1248:
1249: public void print(PrintWriter _ps) {
1250: if (included && !generateIncluded())
1251: return;
1252:
1253: // divert output into individual .java files
1254: if (body != null) // forward declaration
1255: {
1256: printInterface();
1257:
1258: if (!is_pseudo) {
1259: if (!is_abstract) {
1260: printOperations();
1261: }
1262:
1263: printHelper();
1264: printHolder();
1265:
1266: if (parser.generate_stubs && !is_local) {
1267: printStub();
1268: }
1269:
1270: if (parser.generate_skeletons && !is_local
1271: && !is_abstract) {
1272: printImplSkeleton();
1273: printTieSkeleton();
1274: }
1275:
1276: if (parser.generateIR) {
1277: printIRHelper();
1278: }
1279:
1280: if (is_local) {
1281: printLocalBase();
1282: printLocalTie();
1283: }
1284: }
1285:
1286: // print class files for interface local definitions
1287: body.print(null);
1288:
1289: if (replyHandler != null)
1290: replyHandler.print(_ps);
1291: }
1292: }
1293:
1294: public void printInsertIntoAny(PrintWriter ps, String anyname,
1295: String varname) {
1296: if (is_abstract) {
1297: throw new RuntimeException(
1298: "DII stubs not yet implemented for abstract interfaces");
1299: /*
1300: ps.println("\t\tif (s instanceof org.omg.CORBA.Object)");
1301: ps.println("\t\t{");
1302: ps.println("\t\t\tany.insert_Object((org.omg.CORBA.Object)s);");
1303: ps.println("\t\t}");
1304: ps.println("\t\telse if (s instanceof java.io.Serializable)");
1305: ps.println("\t\t{");
1306: ps.println("\t\t\tany.insert_Value((java.io.Serializable)s);");
1307: ps.println("\t\t}");
1308: ps.println("\t\telse");
1309: ps.println("\t\t{");
1310: ps.println("\t\t\tthrow new org.omg.CORBA.BAD_PARAM(\"Failed to insert in helper\");");
1311: ps.println("\t\t}"); */
1312: }
1313:
1314: ps.println("\t\t" + anyname + ".insert_Object(" + varname
1315: + ");");
1316: }
1317:
1318: public void printExtractResult(PrintWriter ps, String resultname,
1319: String anyname, String resulttype) {
1320: ps.println("\t\t" + resultname + " = " + helperName()
1321: + ".extract(" + anyname + ");");
1322: }
1323:
1324: public void accept(IDLTreeVisitor visitor) {
1325: visitor.visitInterface(this );
1326: }
1327:
1328: private static final String stubName(final String typeName) {
1329: final String stub_name;
1330: if (typeName.indexOf('.') > -1) {
1331: stub_name = typeName
1332: .substring(0, typeName.lastIndexOf('.'))
1333: + "._"
1334: + typeName.substring(typeName.lastIndexOf('.') + 1)
1335: + "Stub";
1336: } else {
1337: stub_name = "_" + typeName + "Stub";
1338: }
1339:
1340: return stub_name;
1341: }
1342: }
|