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: import org.apache.log.*;
027:
028: /**
029: * Base class for all classes of the abstract IDL syntax tree
030: *
031: * @author Gerald Brose
032: * @version $Id: IdlSymbol.java,v 1.45 2006/08/03 12:31:17 alphonse.bendt Exp $
033: */
034:
035: public class IdlSymbol extends org.jacorb.idl.runtime.symbol {
036: private static int num = 10000;
037: public String pack_name = "";
038: String name = "";
039:
040: protected boolean is_pseudo = false; // is this a PIDL spec.?
041: protected boolean included = false;
042: protected boolean inhibitionFlag = false;
043:
044: str_token token;
045:
046: protected String _id;
047: private String _version;
048:
049: protected IdlSymbol enclosing_symbol;
050:
051: protected String omg_package_prefix = "";
052: private Hashtable imports = new Hashtable();
053:
054: String typeName;
055:
056: protected static final char fileSeparator = System.getProperty(
057: "file.separator").charAt(0);
058:
059: Logger logger;
060:
061: /** the posizion in the IDL file where this symbol was found by the lexer,
062: needed for better error messages */
063: PositionInfo myPosition = null;
064:
065: /**
066: * class constructor
067: */
068:
069: public IdlSymbol(int num) {
070: super (num);
071: inhibitionFlag = parser.getInhibitionState();
072: logger = parser.getLogger();
073: myPosition = lexer.getPosition();
074: }
075:
076: /**
077: * used by the lexer to mark this symbol as included from another
078: * IDL file
079: */
080:
081: void set_included(boolean i) {
082: included = i;
083: }
084:
085: /**
086: * is this a symbol included from another IDL file?
087: * Used to determine if code should be generated or not.
088: */
089:
090: public boolean is_included() {
091: return included;
092: }
093:
094: /**
095: *
096: */
097:
098: public void set_pseudo() {
099: is_pseudo = true;
100: }
101:
102: /**
103: * is this a PIDL symbol?
104: */
105:
106: public boolean is_pseudo() {
107: return is_pseudo;
108: }
109:
110: public void set_token(str_token i) {
111: token = i;
112: if (token != null) {
113: if (token.pragma_prefix.equals("omg.org")) {
114: omg_package_prefix = "org.omg.";
115: }
116: set_name(token.str_val);
117: }
118: }
119:
120: public str_token get_token() {
121: return token;
122: }
123:
124: /**
125: * get this symbol's name
126: */
127:
128: public String name() {
129: return name;
130: }
131:
132: /**
133: * A number of IDL constructs need to have their names
134: * checked for clashes with name reserved by Java or
135: * the Java Language Mapping.
136: */
137:
138: public void escapeName() {
139: if (!isEscaped()
140: &&
141: // Not escaping Messaging.ExceptionHolder
142: !pack_name.startsWith("org.omg.Messaging")
143: && lexer.strictJavaEscapeCheck(name)) {
144: if (name.indexOf('.') > 0)
145: logger.warn("Dots within a simple name!");
146: name = "_" + name;
147: }
148: }
149:
150: public boolean isEscaped() {
151: return name().startsWith("_");
152: }
153:
154: public String deEscapeName() {
155: String tmp = name();
156:
157: if (tmp.startsWith("_")) {
158: tmp = tmp.substring(1);
159: }
160:
161: return tmp;
162: }
163:
164: public void setPackage(String s) {
165: s = parser.pack_replace(s);
166: if (pack_name.length() > 0)
167: pack_name = s + "." + pack_name;
168: else
169: pack_name = s;
170: }
171:
172: public void setEnclosingSymbol(IdlSymbol s) {
173: if (enclosing_symbol != null && enclosing_symbol != s)
174: throw new RuntimeException(
175: "Compiler Error: trying to reassign container for "
176: + name);
177:
178: enclosing_symbol = s;
179: }
180:
181: public IdlSymbol getEnclosingSymbol() {
182: return enclosing_symbol;
183: }
184:
185: public static int new_num() {
186: return num++;
187: }
188:
189: /** the name of this symbol */
190:
191: public void set_name(String n) {
192: name = n;
193: }
194:
195: /**
196: * @return fully scoped IDL identifier
197: */
198:
199: String full_name() {
200: if (name.length() == 0) {
201: return null;
202: }
203:
204: if (pack_name.length() > 0) {
205: return pack_name + "." + name;
206: }
207: return name;
208: }
209:
210: /**
211: * @return fully scoped Java identifier, only used in
212: * code generation phase
213: */
214:
215: String javaName() {
216: if (name.length() == 0)
217: return null;
218: if (pack_name.length() > 0) {
219: if (!pack_name.startsWith("org.omg")) {
220: return omg_package_prefix + pack_name + "." + name;
221: }
222: return pack_name + "." + name;
223: }
224: return name;
225: }
226:
227: /**
228: * @return "org.omg." if the symbol has been declared inside a
229: * scope with a pragma prefix of "omg.org".
230: */
231:
232: public String omgPrefix() {
233: return omg_package_prefix;
234: }
235:
236: /** empty parse */
237:
238: public void parse() throws ParseException {
239: }
240:
241: public void print(PrintWriter ps) {
242: throw new java.lang.RuntimeException("--abstract--!");
243: }
244:
245: public void printImport(PrintWriter ps) {
246: if (!pack_name.equals("")) {
247: for (Enumeration e = imports.keys(); e.hasMoreElements();) {
248: String name = (String) e.nextElement();
249: ps.println("import " + name + ";");
250: }
251: ps.println();
252: }
253: }
254:
255: /**
256: * Called by derived classes to potentially add the aliasHelper
257: * name to the generated Java class's import list, which is
258: * necessary in case the mapped code is in the unnamed package.
259: *
260: * @param alias the name of the alias
261: */
262:
263: public void addImportedAlias(String alias) {
264: if (logger.isDebugEnabled())
265: logger.debug("addImportedAlias " + alias);
266: if (alias.indexOf('.') < 0 && !BaseType.isBasicName(alias)) {
267: imports.put(alias + "Helper", "");
268: }
269: }
270:
271: /**
272: * Called by derived classes to potentially add the name and the
273: * nameHelper to the generated Java class's import list, which is
274: * necessary in case the mapped code is in the unnamed package.
275: *
276: * @param name
277: */
278:
279: public void addImportedName(String name) {
280: // Ensure that we strip [] from names.
281: if (name != null && name.endsWith("[]")) {
282: name = name.substring(0, name.length() - 2);
283: }
284:
285: // Only enter this if its an alias.
286: if (name != null && name.indexOf('.') < 0
287: && !BaseType.isBasicName(name)) {
288: addImportedName(name, null);
289: }
290: }
291:
292: /**
293: * Called by derived classes to potentially add the name and the
294: * nameHelper to the generated Java class's import list, which is
295: * necessary in case the mapped code is in the unnamed package.
296: *
297: * @param name
298: * @param type
299: */
300:
301: public void addImportedName(String name, TypeSpec type) {
302: if (name != null && name.indexOf('.') < 0
303: && !BaseType.isBasicName(name)) {
304: if (logger.isDebugEnabled())
305: logger.debug("addImportedName " + name);
306:
307: // If we have a typedef for a basic type we only want
308: // to import the helper class.
309:
310: if ((type == null)
311: || !BaseType.isBasicName(type.toString())) {
312: imports.put(name, "");
313: }
314: imports.put(name + "Helper", "");
315: }
316: }
317:
318: /**
319: * Called by derived classes to potentially add the name, the
320: * nameHelper and nameHolder to the generated Java class's import
321: * list, which is necessary in case the mapped code is in the
322: * unnamed package.
323: *
324: * @param name
325: */
326:
327: public void addImportedNameHolder(String name) {
328: if (name.indexOf('.') < 0 && !BaseType.isBasicName(name)) {
329: if (logger.isDebugEnabled())
330: logger.debug("addImportedNameHolder " + name);
331:
332: imports.put(name, "");
333: }
334: }
335:
336: public void setPrintPhaseNames() {
337: if (pack_name.length() > 0) {
338: typeName = ScopedName.unPseudoName(pack_name + "." + name);
339: if (!typeName.startsWith("org.omg")) {
340: typeName = omg_package_prefix + typeName;
341: }
342: pack_name = typeName
343: .substring(0, typeName.lastIndexOf("."));
344: } else {
345: typeName = ScopedName.unPseudoName(name);
346: }
347:
348: if (logger.isDebugEnabled()) {
349: logger.debug("setPrintPhaseNames: pack_name " + pack_name
350: + ", name " + name + " typename " + typeName);
351: }
352: }
353:
354: public void printIdMethod(PrintWriter ps) {
355: ps.println("\tpublic static String id()");
356: ps.println("\t{");
357: ps.println("\t\treturn \"" + id() + "\";");
358: ps.println("\t}");
359: }
360:
361: /**
362: * @return this symbol's repository Id
363: */
364:
365: public String id() {
366: IdlSymbol enc = enclosing_symbol;
367: StringBuffer sb = new StringBuffer();
368: ScopeData sd = null;
369: str_token enctoken = null;
370:
371: if (logger.isDebugEnabled())
372: logger.debug("Id for name " + name);
373:
374: if (_id == null) {
375: do {
376: if (enc != null) {
377: // Get enclosing token and check idMap then, if not in
378: // there, determine prefix manually.
379: enctoken = enc.get_token();
380:
381: if (enc instanceof Scope) {
382: sd = ((Scope) enc).getScopeData();
383: if (sd == null) {
384: org.jacorb.idl.parser
385: .fatal_error(
386: "ScopeDate null for "
387: + name
388: + " "
389: + this .getClass()
390: .getName(),
391: null);
392: }
393: }
394:
395: if (sd != null && sd.idMap.get(name) != null) {
396: _id = (String) sd.idMap.get(name);
397: break;
398: }
399: // Not had a #pragma prefix, attempt to determine using prefix
400:
401: // Slightly horrible...this says 'if the current token prefix
402: // is blank' then use the enclosing tokens prefix OR
403: // if the current token has a matching prefix to the parent
404: // then also do this (this prevents:
405: // prefix Foo
406: // module F {
407: // prefix X
408: // interface Y {}
409: // }
410: if (token != null
411: && ("".equals(token.pragma_prefix) || enctoken.pragma_prefix
412: .equals(token.pragma_prefix))) {
413: String enclosingName = enc.name;
414: // if the enclosing symbol is a module, its name
415: // is a package name and might have been modified
416: // by the -i2jpackage switch. We want its unchanged
417: // name as part of the RepositoryId, however.
418: if (enc instanceof Module) {
419: String enclosingModuleName = ((Module) enc)
420: .originalModuleName();
421:
422: if (!enclosingModuleName.startsWith("org")) {
423: enclosingName = ((Module) enc)
424: .originalModuleName();
425: }
426:
427: // remove leading "_" in repository Ids
428: if (enc.isEscaped()) {
429: enclosingName = enclosingName
430: .substring(1);
431: }
432: }
433: sb.insert(0, enclosingName + "/");
434: enc = enc.getEnclosingSymbol();
435: } else {
436: break;
437: }
438: }
439: // Global Scope
440: else if (parser.scopes.size() == 1
441: && parser.currentScopeData().idMap.get(name) != null) {
442: _id = (String) parser.currentScopeData().idMap
443: .get(name);
444: break;
445: } else {
446: // This is global scope - there is no enclosing symbol and no
447: // defining #pragma. The ID can be built simply from the name
448: break;
449: }
450: } while (enc != null);
451:
452: if (_id == null) {
453: // There was no #pragma.
454: if (isEscaped()) {
455: sb.append(name.substring(1));
456: } else {
457: sb.append(name);
458: }
459: if (token != null && token.pragma_prefix.length() > 0) {
460: _id = ("IDL:" + token.pragma_prefix + "/"
461: + sb.toString().replace('.', '/') + ":" + version());
462: } else {
463: _id = "IDL:" + sb.toString().replace('.', '/')
464: + ":" + version();
465: }
466: }
467: }
468: if (logger.isDebugEnabled()) {
469: logger.debug("Id for name " + name + " is " + _id);
470: }
471: return _id;
472: }
473:
474: private String version() {
475: IdlSymbol enc = this ;
476: String tmp;
477:
478: if (_version == null) {
479: while (true) {
480: while (enc != null && !(enc instanceof Scope)) {
481: enc = enc.getEnclosingSymbol();
482: }
483: if (enc != null) {
484: ScopeData sd = ((Scope) enc).getScopeData();
485: if (sd == null) {
486: org.jacorb.idl.parser.fatal_error(
487: "ScopeData null for " + name + " "
488: + this .getClass().getName(),
489: null);
490: }
491: Hashtable h = sd.versionMap;
492:
493: // check for version settings in this scope
494: tmp = (String) h.get(name);
495: if (tmp != null) {
496: _version = tmp;
497: break;
498: }
499: enc = enc.getEnclosingSymbol();
500: }
501: // Global Scope
502: else if (parser.scopes.size() == 1
503: && parser.currentScopeData().versionMap
504: .get(name) != null) {
505: _version = (String) parser.currentScopeData().versionMap
506: .get(name);
507: break;
508: } else {
509: _version = "1.0";
510: break;
511: }
512: }
513:
514: // check for further versions (which would be an error!)
515:
516: if (enc != null)
517: enc = enc.getEnclosingSymbol();
518:
519: while (true) {
520: while (enc != null && !(enc instanceof Scope)) {
521: enc = enc.getEnclosingSymbol();
522: }
523: if (enc != null) {
524: // check for version settings in this scope
525: Hashtable h = ((Scope) enc).getScopeData().versionMap;
526: tmp = (String) h.get(name);
527:
528: if (tmp != null) {
529: lexer
530: .emit_error("Version for " + name
531: + " already declared!", enc
532: .get_token());
533: break;
534: }
535: enc = enc.getEnclosingSymbol();
536: } else {
537: break;
538: }
539: }
540: }
541: return _version;
542: }
543:
544: /**
545: * access to parser state (e.g. options)
546: */
547:
548: protected boolean generateIncluded() {
549: return parser.generateIncluded() && !(inhibitionFlag);
550: }
551:
552: /**
553: * this method will prepend the
554: * specified name with the omg prefix if
555: * necessary
556: *
557: * @return the full qualified java name
558: */
559: protected String getFullName(String name) {
560: if (!name.startsWith("org.omg")
561: && !name.startsWith("java.lang")) {
562: return omgPrefix() + name;
563: }
564: return name;
565: }
566:
567: /**
568: * let the visitor pattern do its work...
569: */
570: public void accept(IDLTreeVisitor visitor) {
571: // nothing here, all work done in subclasses.
572: }
573:
574: /**
575: * <code>printClassComment</code> is used by inherited classes to print
576: * the class comment.
577: *
578: * @param name a <code>String</code> value
579: * @param ps a <code>PrintWriter</code> value
580: */
581: protected final void printClassComment(String type, String name,
582: PrintWriter ps) {
583: ps.println("/**");
584: ps.println(" * Generated from IDL " + type.trim() + " \""
585: + name + "\".");
586: ps.println(" *");
587: ps.println(" * @author JacORB IDL compiler V "
588: + parser.compiler_version);
589: ps.println(" * @version generated at " + parser.currentDate);
590: ps.println(" */\n");
591: }
592: }
|