001: package org.jacorb.idl;
002:
003: /*
004: * JacORB - a free Java ORB
005: *
006: * Copyright (C) 1997-2004 Gerald Brose.
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Library General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Library General Public License for more details.
017: *
018: * You should have received a copy of the GNU Library General Public
019: * License along with this library; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: */
022:
023: import java.io.PrintWriter;
024: import java.util.*;
025:
026: /**
027: * @author Gerald Brose
028: * @version $Id: InterfaceBody.java,v 1.29 2006/07/19 13:57:14 alphonse.bendt Exp $
029: *
030: * directly known subclasses: ValueBody
031: */
032:
033: public class InterfaceBody extends IdlSymbol {
034: public Vector v;
035: public Interface my_interface;
036: SymbolList inheritance_spec = null;
037: private Operation[] methods = null;
038: private String waitingName = "";
039:
040: /** list of parse threads created and either active or still blocked */
041: public static Vector parseThreads = new Vector();
042:
043: public class ParseThread extends Thread {
044: private final InterfaceBody b;
045: private boolean running = false;
046:
047: public ParseThread(InterfaceBody _b) {
048: b = _b;
049: setDaemon(true);
050: parseThreads.addElement(this );
051: parser.incActiveParseThreads();
052: start();
053: }
054:
055: public void run() {
056: parser.set_pending(b.full_name());
057: Object o = null;
058: for (Enumeration e = inheritance_spec.v.elements(); e
059: .hasMoreElements();) {
060: waitingName = ((ScopedName) (e.nextElement()))
061: .resolvedName();
062: o = parser.get_pending(waitingName);
063: if (o != null) {
064: try {
065: synchronized (o) {
066: o.wait();
067: running = true;
068: }
069: } catch (InterruptedException ie) {
070: logger.info("ParseThread " + this
071: + " interrupted!");
072: }
073: }
074: }
075: b.internal_parse();
076:
077: exitParseThread();
078: }
079:
080: /**
081: * check whether this thread will eventually run
082: * @return true if the thread can run or is currently running
083: * false if it is still blocked or has just returned from run()
084: */
085:
086: public synchronized boolean isRunnable() {
087: boolean result = running || checkWaitCondition();
088: if (logger.isWarnEnabled())
089: logger.warn("Thread is runnable: " + result);
090: return result;
091: }
092:
093: private synchronized void exitParseThread() {
094: parser.remove_pending(b.full_name());
095: parser.decActiveParseThreads();
096: parseThreads.removeElement(this );
097: running = false;
098: }
099:
100: /**
101: * @return true, if waiting condition is true,
102: * i.e., if thread still needs to wait.
103: */
104:
105: private boolean checkWaitCondition() {
106: return (parser.get_pending(waitingName) == null);
107: }
108:
109: }
110:
111: public InterfaceBody(int num) {
112: super (num);
113: v = new Vector();
114: }
115:
116: public void commit() {
117: }
118:
119: public void setEnclosingSymbol(IdlSymbol s) {
120: if (enclosing_symbol != null && enclosing_symbol != s)
121: throw new RuntimeException(
122: "Compiler Error: trying to reassign container for "
123: + name);
124: enclosing_symbol = s;
125: for (Enumeration e = v.elements(); e.hasMoreElements();)
126: ((IdlSymbol) e.nextElement())
127: .setEnclosingSymbol(my_interface);
128: }
129:
130: public void set_ancestors(SymbolList _inheritance_spec) {
131: inheritance_spec = _inheritance_spec;
132: }
133:
134: public void set_name(String n) {
135: name = n;
136: for (Enumeration e = v.elements(); e.hasMoreElements();)
137: ((IdlSymbol) e.nextElement()).setPackage(name);
138: }
139:
140: public void setPackage(String s) {
141: s = parser.pack_replace(s);
142: if (pack_name.length() > 0)
143: pack_name = s + "." + pack_name;
144: else
145: pack_name = s;
146:
147: for (Enumeration e = v.elements(); e.hasMoreElements();)
148: ((IdlSymbol) e.nextElement()).setPackage(s);
149: }
150:
151: public void addDefinition(Declaration d) {
152: this .v.add(new Definition(d));
153: }
154:
155: public void parse() {
156: escapeName();
157:
158: if (logger.isDebugEnabled())
159: logger.debug("Interface Body parse " + full_name());
160:
161: if (inheritance_spec != null) {
162: Object o = null;
163: boolean pending = false;
164: for (Enumeration e = inheritance_spec.v.elements(); e
165: .hasMoreElements();) {
166: ScopedName scoped_name = (ScopedName) e.nextElement();
167:
168: if (logger.isDebugEnabled())
169: logger.debug("Trying to resolve " + scoped_name);
170:
171: o = parser.get_pending(scoped_name.resolvedName());
172: pending = pending || (o != null);
173: }
174: if (pending) {
175: parser.set_pending(full_name());
176: new ParseThread(this );
177: } else {
178: internal_parse();
179: parser.remove_pending(full_name());
180: }
181: } else {
182: internal_parse();
183: parser.remove_pending(full_name());
184: if (logger.isDebugEnabled())
185: logger.debug("Interface Body done parsing "
186: + full_name());
187: }
188: }
189:
190: public void internal_parse() {
191: if (logger.isDebugEnabled())
192: logger
193: .debug("Interface Body internal_parse "
194: + full_name());
195:
196: if (inheritance_spec != null) {
197: try {
198: NameTable.inheritFrom(full_name(), inheritance_spec);
199: } catch (NameAlreadyDefined nad) {
200: parser.fatal_error("Name " + nad.getMessage()
201: + " already defined in base interface(s)",
202: token);
203: }
204: }
205: Definition d = null;
206: for (Enumeration e = v.elements(); e.hasMoreElements();) {
207: d = (Definition) e.nextElement();
208: Declaration dec = d.get_declaration();
209: if (is_pseudo)
210: dec.set_pseudo();
211: dec.parse();
212: }
213: }
214:
215: /**
216: * print definitions that appeared in an interface scope
217: * do not call print() in OpDecls and on Typedefs
218: */
219:
220: public void print(PrintWriter ps) {
221: if (ps != null)
222: throw new RuntimeException(
223: "Compiler Error, interface body cannot be printed thus!");
224:
225: for (Enumeration e = v.elements(); e.hasMoreElements();) {
226: Declaration d = ((Definition) e.nextElement())
227: .get_declaration();
228: if (!(d instanceof OpDecl))
229: d.print(ps);
230: }
231: }
232:
233: /** print signatures to the operations file */
234:
235: public void printOperationSignatures(PrintWriter ps) {
236: if (v.size() > 0) {
237: ps.println("\t/* operations */");
238: }
239:
240: for (Enumeration e = v.elements(); e.hasMoreElements();) {
241: Definition d = (Definition) e.nextElement();
242: if (d.get_declaration() instanceof OpDecl) {
243: ((OpDecl) d.get_declaration()).printSignature(ps);
244: } else if (d.get_declaration() instanceof AttrDecl) {
245: for (Enumeration m = ((AttrDecl) d.get_declaration())
246: .getOperations(); m.hasMoreElements();) {
247: ((Operation) m.nextElement()).printSignature(ps);
248: }
249: }
250: }
251: }
252:
253: /** print signatures to the operations file */
254:
255: public void printConstants(PrintWriter ps) {
256: if (v.size() > 0) {
257: ps.println("\t/* constants */");
258: }
259:
260: for (Enumeration e = v.elements(); e.hasMoreElements();) {
261: Definition d = (Definition) e.nextElement();
262: if (d.get_declaration() instanceof ConstDecl) {
263: ((ConstDecl) d.get_declaration()).printContained(ps);
264: }
265: }
266: }
267:
268: /** print only constant definitions to the interface file */
269:
270: public void printInterfaceMethods(PrintWriter ps) {
271: for (Enumeration e = v.elements(); e.hasMoreElements();) {
272: Definition d = (Definition) e.nextElement();
273: if (!(d.get_declaration() instanceof ConstDecl)
274: && is_pseudo()) {
275: ((IdlSymbol) d).print(ps);
276: }
277: }
278: }
279:
280: public Operation[] getMethods() {
281: if (methods == null) {
282: Hashtable table = new Hashtable();
283: for (Enumeration e = v.elements(); e.hasMoreElements();) {
284: Definition d = (Definition) e.nextElement();
285: if (d.get_declaration() instanceof OpDecl) {
286: table.put(((OpDecl) d.get_declaration())
287: .signature(), d.get_declaration());
288: } else if (d.get_declaration() instanceof AttrDecl) {
289: for (Enumeration elems = ((AttrDecl) d
290: .get_declaration()).getOperations(); elems
291: .hasMoreElements();) {
292: Operation op = (Operation) elems.nextElement();
293: table.put(op.signature(), op);
294: }
295: }
296: }
297: for (Iterator i = my_interface.inheritanceSpec.v.iterator(); i
298: .hasNext();) {
299: TypeSpec ts = ((ScopedName) i.next())
300: .resolvedTypeSpec();
301: if (ts instanceof ConstrTypeSpec) {
302: Interface base = (Interface) ((ConstrTypeSpec) ts).c_type_spec;
303: Operation[] base_ops = base.getBody().getMethods();
304: for (int j = 0; j < base_ops.length; j++) {
305: if (!table.contains(base_ops[j].signature()))
306: table.put(base_ops[j].signature(),
307: base_ops[j]);
308: }
309:
310: }
311: }
312: Enumeration o = table.elements();
313: methods = new Operation[table.size()];
314: for (int i = 0; i < methods.length; i++)
315: methods[i] = (Operation) o.nextElement();
316: }
317: return methods;
318: }
319:
320: /**
321: * Print methods to the stub file
322: */
323:
324: public void printStubMethods(PrintWriter ps, String classname,
325: boolean is_local, boolean is_abstract) {
326: Operation[] ops = getMethods();
327: for (int i = 0; i < ops.length; i++) {
328: ops[i].printMethod(ps, classname, is_local, is_abstract);
329: }
330:
331: if (parser.generate_ami_callback
332: && !(my_interface instanceof ReplyHandler)) {
333: for (int i = 0; i < ops.length; i++)
334: ops[i].print_sendc_Method(ps, classname);
335: }
336: }
337:
338: /** print methods to the skeleton file */
339:
340: public void printDelegatedMethods(PrintWriter ps) {
341: Operation[] ops = getMethods();
342: if (ops.length > 0) {
343: for (int i = 0; i < ops.length; i++) {
344: ops[i].printDelegatedMethod(ps);
345: }
346: }
347: }
348:
349: /** print hash table that associates an operation string with an int */
350:
351: public void printOperationsHash(PrintWriter ps) {
352: Operation[] ops = getMethods();
353: if (ops.length <= 0)
354: return;
355:
356: String HASHTABLE = System.getProperty("java.version")
357: .startsWith("1.1") ? "com.sun.java.util.collections.Hashtable"
358: : "java.util.Hashtable";
359:
360: ps.println("\tstatic private final " + HASHTABLE
361: + " m_opsHash = new " + HASHTABLE + "();");
362: ps.println("\tstatic");
363: ps.println("\t{");
364:
365: for (int i = 0; i < ops.length; i++) {
366: /* Some operation names have been escaped with "_" to
367: avoid name clashes with Java names. The operation name
368: on the wire is the original IDL name, however, so we
369: need to ask for the right name here. We need to take
370: care not to scramble up "_set_/_get" accessor methods!
371: (hence the check on instanceof OpDecl).
372: */
373:
374: String name;
375: if (ops[i] instanceof OpDecl
376: && ops[i].opName().startsWith("_"))
377: name = ops[i].opName().substring(1);
378: else
379: name = ops[i].opName();
380:
381: ps.println("\t\tm_opsHash.put ( \"" + name
382: + "\", new java.lang.Integer(" + i + "));");
383: }
384:
385: ps.println("\t}");
386: }
387:
388: /** print methods for impl-based skeletons */
389:
390: public void printSkelInvocations(PrintWriter ps) {
391: Operation[] ops = getMethods();
392: if (ops.length <= 0) {
393: ps
394: .println("\t\tthrow new org.omg.CORBA.BAD_OPERATION(method + \" not found\");");
395: return;
396: }
397: ps.println("\t\t// quick lookup of operation");
398: ps
399: .println("\t\tjava.lang.Integer opsIndex = (java.lang.Integer)m_opsHash.get ( method );");
400: ps.println("\t\tif ( null == opsIndex )");
401: ps
402: .println("\t\t\tthrow new org.omg.CORBA.BAD_OPERATION(method + \" not found\");");
403:
404: ps.println("\t\tswitch ( opsIndex.intValue() )");
405: ps.println("\t\t{");
406:
407: int nextIndex = 0;
408: for (int i = 0; i < ops.length; i++) {
409: String name;
410: if (ops[i] instanceof OpDecl
411: && ops[i].opName().startsWith("_"))
412: name = ops[i].opName().substring(1);
413: else
414: name = ops[i].opName();
415:
416: ps.println("\t\t\tcase " + nextIndex++ + ": // " + name);
417: ps.println("\t\t\t{");
418: ops[i].printInvocation(ps);
419: ps.println("\t\t\t\tbreak;");
420: ps.println("\t\t\t}");
421: }
422:
423: ps.println("\t\t}");
424: ps.println("\t\treturn _out;");
425: }
426:
427: void getIRInfo(Hashtable irInfoTable) {
428: for (Enumeration e = v.elements(); e.hasMoreElements();) {
429: Definition d = (Definition) e.nextElement();
430: if (d.get_declaration() instanceof OpDecl) {
431: ((OpDecl) d.get_declaration()).getIRInfo(irInfoTable);
432: } else if (d.get_declaration() instanceof AttrDecl) {
433: ((AttrDecl) d.get_declaration()).getIRInfo(irInfoTable);
434: }
435: }
436: }
437:
438: /**
439: */
440:
441: public void accept(IDLTreeVisitor visitor) {
442: visitor.visitInterfaceBody(this);
443: }
444:
445: }
|