KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > idl > ScopedName


1 /*
2  * JacORB - a free Java ORB
3  *
4  * Copyright (C) 1997-2004 Gerald Brose.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the Free
18  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */

20
21 package org.jacorb.idl;
22
23 /**
24  * IDL scoped names
25  *
26  * @author Gerald Brose
27  * @version $Id: ScopedName.java,v 1.33 2005/03/28 19:57:58 brose Exp $
28  *
29  */

30
31 import java.io.PrintWriter JavaDoc;
32 import java.util.*;
33
34 public class ScopedName
35     extends SimpleTypeSpec
36     implements SwitchTypeSpec
37 {
38     private static Hashtable pseudoScopes = new Hashtable();
39
40     private static Hashtable enumMap = new Hashtable();
41
42     private static Stack recursionStack = new Stack();
43
44     /**
45      * Interfaces define a new scope, but since we can't do that
46      * in Java, this kind of scope is called a 'pseudo scope' and
47      * is just prepended to the interface name
48      */

49
50     public static void definePseudoScope( String JavaDoc name )
51     {
52         pseudoScopes.put( name, "" );
53     }
54
55     public static boolean isPseudoScope( String JavaDoc name )
56     {
57         return ( pseudoScopes.containsKey( name ) );
58     }
59
60     /**
61      * unPseudo transforms scoped names like
62      * module.Interface1.Interface2.Type_name to
63      * module.Interface1Package.Interface2Package.Type_name
64      */

65
66     public static String JavaDoc unPseudoName( String JavaDoc name )
67     {
68         String JavaDoc n = unPseudo( name );
69         if( n.endsWith( "PackagePackage" ) || !n.startsWith( "_" ) && n.endsWith( "Package" ) )
70             n = n.substring( 0, n.lastIndexOf( "Package" ) );
71         return n;
72     }
73
74     private static String JavaDoc unPseudo( String JavaDoc name )
75     {
76         if( name.charAt( 0 ) == '.' )
77         {
78             name = name.substring( 1 );
79         }
80
81         String JavaDoc head = name;
82         String JavaDoc tail = null;
83         int lastDot = name.lastIndexOf( '.' );
84
85         if( lastDot < 0 )
86             return name;
87
88         while( !isPseudoScope( head ) )
89         {
90             // search for longest tail in scope name which
91
// does not contain a pseudo scope
92

93             lastDot = head.lastIndexOf( '.' );
94             if( lastDot < 0 ) return name;
95             head = name.substring( 0, lastDot );
96             tail = name.substring( lastDot + 1 );
97         }
98
99         java.util.StringTokenizer JavaDoc strtok =
100         new java.util.StringTokenizer JavaDoc( head, "." );
101         String JavaDoc scopes[] = new String JavaDoc[ strtok.countTokens() ];
102
103         for( int i = 0; strtok.hasMoreTokens(); scopes[ i++ ] = strtok.nextToken() )
104             ;
105
106         StringBuffer JavaDoc newHead = new StringBuffer JavaDoc();
107         int j = 1;
108
109         newHead.append( scopes[ 0 ] );
110
111         while( !isPseudoScope( newHead.toString() ) )
112         {
113             if( j == scopes.length )
114                 return ( name );
115             newHead.append( "." );
116             newHead.append( scopes[ j++ ] );
117         }
118
119         StringBuffer JavaDoc copy = new StringBuffer JavaDoc( newHead.toString() );
120         // we have to remember this...
121

122         newHead.append( "Package" );
123
124         while( j < scopes.length )
125         {
126             newHead.append( "." + scopes[ j ] );
127             copy.append( "." + scopes[ j ] );
128             if( isPseudoScope( copy.toString() ) )
129                 newHead.append( "Package" );
130             j++;
131         }
132
133         if( tail != null )
134             newHead.append( "." + tail );
135         return newHead.toString();
136
137     }
138
139     /**
140      * enumerations don't define new scopes in IDL, but their
141      * mapping to Java introduces a new scope by generating
142      * a new class for the enum's type. Thus, enumeration values
143      * have to be additionally scoped in Java.
144      */

145
146     public static void enumMap( String JavaDoc n, String JavaDoc m )
147     {
148         enumMap.put( n, m );
149     }
150
151     private static String JavaDoc unEnum( String JavaDoc _name )
152     {
153         String JavaDoc n = (String JavaDoc)enumMap.get( _name );
154         if( n != null )
155             return n;
156         else
157             return _name;
158     }
159
160     /* end of static part */
161
162     /* instance part */
163
164     private TypeSpec resolvedSpec = null;
165     private String JavaDoc resolvedName = null;
166     private boolean resolved = false;
167     private Interface resolvedInterface = null;
168     boolean set = false;
169     public String JavaDoc typeName = null;
170
171     public ScopedName( int num )
172     {
173         super( num );
174     }
175
176     public Object JavaDoc clone()
177     {
178         ScopedName sn = new ScopedName( new_num() );
179         sn.resolvedSpec = this.resolvedSpec;
180         sn.resolvedName = this.resolvedName;
181         sn.resolved = this.resolved;
182         sn.typeName = this.typeName;
183         sn.token = this.token;
184         sn.set = this.set;
185
186         /* superclass instance vars */
187         sn.pack_name = this.pack_name;
188         sn.name = this.name;
189         sn.is_pseudo = this.is_pseudo;
190         sn.included = this.included;
191         sn.inhibitionFlag = this.inhibitionFlag;
192         return sn;
193     }
194
195     public void setId( String JavaDoc _id )
196     {
197         if( logger.isInfoEnabled() )
198             logger.info( "ScopedName.setId " + _id );
199
200         typeName = _id;
201         escapeName();
202     }
203
204     /**
205      */

206
207     public void escapeName()
208     {
209         if( !name.startsWith( "_" ) )
210         {
211             // if the type name is not a simple name, then insert the escape
212
// char after the last dot
213
if( typeName.indexOf( '.' ) > 0 )
214             {
215                 if( lexer.strictJavaEscapeCheck( typeName.substring( typeName.lastIndexOf( '.' ) + 1 )))
216                 {
217                     typeName =
218                     typeName.substring( 0, typeName.lastIndexOf( '.' ) + 1 ) +
219                     "_" + typeName.substring( typeName.lastIndexOf( '.' ) + 1 );
220                 }
221             }
222             else
223             {
224                 if( lexer.strictJavaEscapeCheck( typeName ))
225                     typeName = "_" + typeName;
226             }
227             if( logger.isInfoEnabled() )
228                 logger.info( "ScopedName.escapeName " + typeName );
229         }
230     }
231
232     public void setEnclosingSymbol( IdlSymbol s )
233     {
234         if( enclosing_symbol != null && enclosing_symbol != s )
235             throw new RuntimeException JavaDoc( "Compiler Error: trying to reassign container for " + name );
236         enclosing_symbol = s;
237     }
238
239     public void parse()
240     {
241     }
242
243     public boolean resolved()
244     {
245         return resolved;
246     }
247
248     public boolean basic()
249     {
250         TypeSpec t = resolvedTypeSpec();
251         return t.basic();
252     }
253
254     public boolean is_pseudo()
255     {
256         return NameTable.isDefined( resolvedName(), "pseudo interface" );
257     }
258
259     public TypeSpec resolvedTypeSpec()
260     {
261         if( !resolved )
262             resolvedName = resolvedName();
263         if( resolvedSpec == null )
264             parser.fatal_error( "Not a type: " + resolvedName, token );
265         return resolvedSpec;
266     }
267
268
269     public String JavaDoc resolvedName()
270     {
271         if( !resolved )
272             resolvedName = resolvedName( pack_name, typeName );
273
274         ConstDecl constDecl = ConstDecl.getDeclaration( resolvedName );
275
276         if( constDecl != null )
277         {
278             if( !constDecl.contained() )
279             {
280                 resolvedName += ".value";
281             }
282         }
283         resolved = true;
284         return resolvedName;
285     }
286
287
288     /**
289      * This is the main name resolution algorithm. It resolves a qualified name
290      * s by replacing it by a fully qualified one, (watch out for typedef'd
291      * names!)
292      *
293      * @param name
294      * the name that is to be resolved. This may be a simple name,
295      * a partially qualified name, or even a fully qualifed name.
296      * @param scopeOfOrigin
297      * the scope from within which the resolution starts
298      * @return a fully qualified IDL identifier
299      */

300
301     private String JavaDoc resolvedName( String JavaDoc scopeOfOrigin, String JavaDoc name )
302     {
303         if( logger.isInfoEnabled() )
304             logger.info( "Resolve " + scopeOfOrigin + ":" + name );
305
306         if( name == null )
307             throw new RuntimeException JavaDoc( "Parser Error: null string in ScopedName (pack_name: " + scopeOfOrigin + ") !" );
308
309         String JavaDoc result = null;
310
311         // a fully qualified name starts with a '.'
312
boolean global = false;
313         if( name.charAt( 0 ) == '.' )
314         {
315             // strip the dot
316
name = name.substring( 1 );
317             global = true;
318         }
319
320         // strip any "[]" but remember them for later
321
String JavaDoc bracketSuffix = "";
322         if( name.endsWith( "[]" ) )
323         {
324             result = name.substring( 0, name.indexOf( "[" ) );
325             bracketSuffix = "[]";
326         }
327         else
328             result = name;
329
330         // see if "scope.name" is a defined name. If so, return that
331
// definition. First, try to form a combined name
332
if( !global &&
333                 NameTable.isDefined( scopeOfOrigin + "." + result ))
334         {
335             String JavaDoc unmappedResult =
336                 unMap( scopeOfOrigin + "." + result );
337
338             if( logger.isInfoEnabled() )
339                 logger.info( "resolve, " + scopeOfOrigin + "." + result +
340                              " was in name table, returning " + unmappedResult +
341                              " suffix: " + bracketSuffix );
342
343             return unmappedResult + bracketSuffix;
344         }
345
346         // now, check if name is known by itself (either because it is global
347
// or it is a qualified name)
348
if( (global || result.indexOf('.') > 0 )
349                 && NameTable.isDefined(result) )
350         {
351             String JavaDoc unmappedResult = unMap( result );
352
353             if( logger.isInfoEnabled() )
354                 logger.info( "resolve, found " + result +
355                              " in name table, returning " + unmappedResult +
356                              " suffix: " + bracketSuffix );
357
358             return unmappedResult + bracketSuffix;
359         }
360
361         
362         // split up all scopes contained in the name
363
java.util.StringTokenizer JavaDoc strtok =
364             new java.util.StringTokenizer JavaDoc( name, "." );
365         String JavaDoc nameScopes[] = new String JavaDoc[ strtok.countTokens() ];
366         for( int i = 0; strtok.hasMoreTokens(); i++ ) {
367             nameScopes[ i ] = strtok.nextToken();
368         }
369
370         // if there are scopes in the name itself...
371
if( nameScopes.length > 0 )
372         {
373             // see if the compiler has registerd replacement names for
374
// our scopes
375
String JavaDoc replacedPackageName = parser.pack_replace( nameScopes[ 0 ] );
376             if( !replacedPackageName.equals( nameScopes[ 0 ] ) )
377             {
378                 // okay, it has, so rebuild the fully scoped name
379
StringBuffer JavaDoc tmpString = new StringBuffer JavaDoc();
380                 tmpString.append( replacedPackageName );
381                 for( int i = 1; i < nameScopes.length; ++i )
382                 {
383                     tmpString.append( "." );
384                     tmpString.append( nameScopes[ i ] );
385                 }
386
387                 // check if this is a defined name now
388
result = tmpString.toString();
389                 if( NameTable.isDefined( result ) )
390                 {
391                     String JavaDoc unmappedResult = unMap( result );
392
393                     if( logger.isInfoEnabled() )
394                         logger.info( "resolve b, " + result + " was in name table, returning " + unmappedResult + " suffix: " + bracketSuffix );
395                     return unmappedResult + bracketSuffix;
396                 }
397             }
398         }
399
400         // split up the individual scopes in the scopeOfOrigin
401
java.util.StringTokenizer JavaDoc p_strtok =
402             new java.util.StringTokenizer JavaDoc( scopeOfOrigin, "." );
403         String JavaDoc packageScopes[] = new String JavaDoc[ p_strtok.countTokens() ];
404         for( int i = 0; p_strtok.hasMoreTokens(); i++ )
405         {
406             packageScopes[ i ] = p_strtok.nextToken();
407         }
408
409         // If the simple name was not known and we have no scopes at
410
// all, try the global scope.
411
if( nameScopes.length == 0 || packageScopes.length == 0 )
412         {
413             if( NameTable.isDefined( result ) )
414             {
415                 return unMap( result ) + bracketSuffix;
416             }
417             // else: the name is not found, emit an error message
418
parser.fatal_error( "Undefined name: " + name + " .", token );
419         }
420
421         // if package name and the name which is to be resolved begin
422
// with the same scoping qualifiers, strip these from name
423
if( nameScopes[ 0 ].equals( packageScopes[ 0 ] ) )
424         {
425             StringBuffer JavaDoc tmpString = new StringBuffer JavaDoc();
426             int minScopesLength = nameScopes.length < packageScopes.length ?
427                     nameScopes.length : packageScopes.length;
428
429             if( minScopesLength > 1 )
430             {
431                 int i;
432                 for( i = 1; i < minScopesLength - 1; i++ )
433                 {
434                     if( !( nameScopes[ i ].equals( packageScopes[ i ] ) ) )
435                         break;
436                 }
437                 tmpString.append( nameScopes[ i ] );
438
439                 for( int k = i + 1; k < nameScopes.length; k++ )
440                 {
441                     tmpString.append( "." );
442                     tmpString.append( nameScopes[ k ] );
443                 }
444                 name = tmpString.toString();
445             }
446         }
447
448         String JavaDoc prefix = "";
449         int start_index = 0;
450
451         if( parser.package_prefix != null )
452         {
453             prefix = parser.package_prefix + ".";
454             java.util.StringTokenizer JavaDoc prefix_strtok =
455                 new java.util.StringTokenizer JavaDoc( prefix, "." );
456             String JavaDoc prefix_scopes[] = new String JavaDoc[ prefix_strtok.countTokens() ];
457
458             for( int i = 0; prefix_strtok.hasMoreTokens(); i++ )
459                 prefix_scopes[ i ] = prefix_strtok.nextToken();
460
461             while( start_index < prefix_scopes.length &&
462                    prefix_scopes[ start_index ].equals( packageScopes[ start_index ] ) )
463                 start_index++;
464         }
465
466         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
467         int k = packageScopes.length - start_index;
468
469         if( k > 0 )
470             buf.append( packageScopes[ start_index ] + "." );
471
472         for( int j = start_index + 1; j < packageScopes.length; j++ )
473         {
474             buf.append( packageScopes[ j ] );
475             buf.append( "." );
476         }
477
478         buf.append( name );
479
480         int sub = start_index + 1;
481
482         while( !NameTable.isDefined( prefix + buf.toString() ) )
483         {
484             if( sub > packageScopes.length )
485             {
486                 parser.fatal_error( "Undefined name: " + scopeOfOrigin + "." + name, token );
487                 return "/* unresolved name */";
488             }
489             buf = new StringBuffer JavaDoc();
490             k = packageScopes.length - sub++;
491             if( k > 0 )
492             {
493                 buf.append( packageScopes[ start_index ] + "." );
494                 for( int j = start_index + 1; j < k + start_index; j++ )
495                 {
496                     buf.append( packageScopes[ j ] );
497                     buf.append( "." );
498
499                 }
500             }
501             buf.append( name );
502         }
503         String JavaDoc res = unMap( prefix + buf.toString() ) + bracketSuffix;
504         if( logger.isDebugEnabled() )
505             logger.debug( "ScopedName.resolve (at end) returns: " + res );
506         return res;
507     }
508
509     public TypeSpec typeSpec()
510     {
511         return this;
512     }
513
514     public void setPackage( String JavaDoc s )
515     {
516         s = parser.pack_replace( s );
517         set = true;
518         if( pack_name.length() > 0 )
519             pack_name = s + "." + pack_name;
520         else
521             pack_name = s;
522     }
523
524     private String JavaDoc qualify( String JavaDoc str )
525     {
526         if( str.charAt( 0 ) == '.' )
527         {
528             return ( str.substring( 1 ) );
529         }
530         else
531         {
532             if( !pack_name.equals( "" ) )
533                 return ( pack_name + "." + str );
534             else
535                 return str;
536         }
537     }
538
539     /**
540      * replace _name by the type name it stands for (through
541      * as many levels of typedef's as necessary) As a side effect,
542      * set resolvedSpec to point to type spec object if the name
543      * resolved was defined as a type name
544      */

545
546     private String JavaDoc unMap( String JavaDoc _name )
547     {
548         if( logger.isDebugEnabled() )
549             logger.debug( "ScopedName.unmap: " + _name );
550
551         String JavaDoc tmp = null;
552         TypeSpec y = TypeMap.map( _name );
553
554         if( logger.isDebugEnabled() )
555             logger.debug( "ScopedName.unmap: " + _name + ", Type.map( " + _name + " ) is : " + y);
556
557         TypeSpec x = null;
558
559         while( y != null && !( y instanceof ScopedName )
560                && !( y instanceof ConstrTypeSpec ) )
561         {
562             x = y;
563             y = y.typeSpec();
564             if( x.equals( y ) )
565                 break; // necessary?
566
}
567
568         if( y == null )
569         {
570             if( x != null )
571             {
572                 resolvedSpec = x;
573                 return x.typeName();
574             }
575             else
576                 resolvedSpec = y;
577             return unEnum( _name );
578         }
579
580         if( y instanceof ConstrTypeSpec )
581         {
582             resolvedSpec = y;
583             return y.typeName();
584         }
585
586         if( y instanceof ScopedName && y != null && x != y )
587             return unMap( y.typeName() );
588
589         if( y == null )
590         {
591             resolvedSpec = x;
592             return x.typeName();
593         }
594         else
595         {
596             resolvedSpec = y;
597             return _name;
598         }
599     }
600
601
602     /**
603      * @return the fully qualified and resolved name in an intermediate
604      * format, i.e. with "Package" suffixes but without potential "omg.org"
605      * scopes
606      */

607
608     public String JavaDoc typeName()
609     {
610         String JavaDoc n = unPseudo( resolvedName( pack_name, typeName ) );
611
612         if( n.endsWith( "PackagePackage" ) || !n.startsWith( "_" ) && n.endsWith( "Package" ) )
613             n = n.substring( 0, n.lastIndexOf( "Package" ) );
614
615         return n;
616     }
617
618
619     public String JavaDoc holderName()
620     {
621         return resolvedTypeSpec().holderName();
622     }
623
624     public String JavaDoc printReadExpression( String JavaDoc streamname )
625     {
626         return resolvedTypeSpec().printReadExpression( streamname );
627     }
628
629     public String JavaDoc printWriteStatement( String JavaDoc var_name, String JavaDoc streamname )
630     {
631         return resolvedTypeSpec().printWriteStatement( var_name, streamname );
632     }
633
634     public String JavaDoc printInsertExpression()
635     {
636         return resolvedTypeSpec().printInsertExpression();
637     }
638
639     public String JavaDoc printExtractExpression()
640     {
641         return resolvedTypeSpec().printExtractExpression();
642     }
643
644     /**
645      * @return a string for an expression of type TypeCode that describes this type
646      */

647
648     public String JavaDoc getTypeCodeExpression()
649     {
650         return resolvedTypeSpec().getTypeCodeExpression();
651     }
652
653     public String JavaDoc id()
654     {
655         return resolvedTypeSpec().id();
656     }
657
658     public String JavaDoc toString()
659     {
660         String JavaDoc n = typeName();
661         if( resolvedTypeSpec() != null && ( !n.startsWith( "org.omg" ) ) )
662             n = resolvedTypeSpec().omgPrefix() + n;
663         return n;
664     }
665
666     public void print( PrintWriter JavaDoc ps )
667     {
668     }
669
670     public String JavaDoc IDLName()
671     {
672         String JavaDoc n = toString();
673         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
674         int from = 0;
675         while( n.substring( from ).indexOf( '.' ) > 0 )
676         {
677             int to = from + n.substring( from ).indexOf( '.' );
678             sb.append( n.substring( from, to ) + "::" );
679             from = to + 1;
680         }
681         sb.append( n.substring( from ) );
682
683         return sb.toString();
684     }
685
686     public static void addRecursionScope( String JavaDoc typeName )
687     {
688         recursionStack.push( typeName );
689     }
690
691     public static void removeRecursionScope( String JavaDoc typeName )
692     {
693         String JavaDoc check = (String JavaDoc)recursionStack.pop();
694         if( typeName != null && ( check == null || !check.equals( typeName ) ) )
695         {
696             throw new RuntimeException JavaDoc( "RecursionScope Error, expected " +
697                                         typeName + ", got " + check );
698         }
699     }
700
701     public static boolean isRecursionScope( String JavaDoc typeName )
702     {
703         return ( recursionStack.search( typeName ) != -1 );
704     }
705
706     public boolean isSwitchable()
707     {
708         TypeSpec t = resolvedTypeSpec();
709         return ( ( t instanceof SwitchTypeSpec ) &&
710                  ( (SwitchTypeSpec)t ).isSwitchable() );
711     }
712 }
713
Popular Tags