KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > orb > TypeCode


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

22
23 import java.lang.reflect.Field JavaDoc;
24 import java.lang.reflect.Modifier JavaDoc;
25 import java.util.*;
26
27 import org.jacorb.ir.RepositoryID;
28
29 import org.omg.CORBA.TCKind JavaDoc;
30 import org.omg.CORBA.ValueMember JavaDoc;
31
32
33 /**
34  * JacORB implementation of CORBA TypeCodes
35  *
36  * @author Gerald Brose, FU Berlin
37  * @version $Id: TypeCode.java,v 1.39 2004/10/18 13:12:41 simon.mcqueen Exp $
38  */

39
40 public class TypeCode
41     extends org.omg.CORBA.TypeCode JavaDoc
42 {
43     private int kind = -1;
44
45     private String JavaDoc id = null;
46     private String JavaDoc name = null;
47
48     private int member_count = 0;
49     private String JavaDoc [] member_name = null;
50     private org.omg.CORBA.TypeCode JavaDoc [] member_type = null;
51     private short [] member_visibility = null;
52     private Any [] member_label = null;
53     private short value_modifier = 0;
54
55     private org.omg.CORBA.TypeCode JavaDoc discriminator_type = null;
56     private int default_index = -1;
57     private int length = -1;
58     private org.omg.CORBA.TypeCode JavaDoc content_type = null;
59
60     /** for fixed point types */
61     private short scale;
62     private short digits;
63
64     /** if this TC is recursive */
65     private boolean recursive = false;
66     private TypeCode actualTypecode = null;
67     private boolean secondIteration = false;
68
69     private static boolean class_init = false;
70     private static org.omg.CORBA.TypeCode JavaDoc[] primitive_tcs = new TypeCode[34];
71
72     /**
73      * Maps the java.lang.Class objects for primitive types to
74      * their corresponding TypeCode objects.
75      */

76     private static Map primitive_tcs_map = new HashMap();
77
78     static
79     {
80         /** statically create primitive TypeCodes for fast lookup */
81         for( int i = 0; i <= 13; i++ )
82         {
83             primitive_tcs[i] = new TypeCode(i);
84         }
85         for( int i = 23; i <= 26; i++ )
86         {
87             primitive_tcs[i] = new TypeCode(i);
88         }
89         primitive_tcs [TCKind._tk_string]
90             = new TypeCode( TCKind._tk_string, 0 );
91         primitive_tcs [TCKind._tk_wstring]
92             = new TypeCode( TCKind._tk_wstring, 0 );
93         primitive_tcs [TCKind._tk_fixed]
94             = new TypeCode( (short)1, (short)0 );
95
96         // Sun's ValueHandler in JDK 1.3 and 1.4 calls
97
// ORB.get_primitive_tc() for TCKind._tk_objref and TCKind._tk_value.
98
// These don't exactly look "primitive" to us, but as a courtesy to
99
// Sun we provide the following bogus TypeCode objects so that
100
// we can return something in these cases.
101
primitive_tcs [TCKind._tk_objref]
102             = new TypeCode( TCKind._tk_objref,
103                             "IDL:omg.org/CORBA/Object:1.0",
104                             "Object" );
105         primitive_tcs [TCKind._tk_value]
106             = new TypeCode( "IDL:omg.org/CORBA/portable/ValueBase:1.0",
107                             "ValueBase", org.omg.CORBA.VM_NONE.value,
108                             null,
109                             new org.omg.CORBA.ValueMember JavaDoc[0] );
110
111         put_primitive_tcs (Boolean.TYPE, TCKind._tk_boolean);
112         put_primitive_tcs (Character.TYPE, TCKind._tk_wchar);
113         put_primitive_tcs (Byte.TYPE, TCKind._tk_octet);
114         put_primitive_tcs (Short.TYPE, TCKind._tk_short);
115         put_primitive_tcs (Integer.TYPE, TCKind._tk_long);
116         put_primitive_tcs (Long.TYPE, TCKind._tk_longlong);
117         put_primitive_tcs (Float.TYPE, TCKind._tk_float);
118         put_primitive_tcs (Double.TYPE, TCKind._tk_double);
119     }
120
121     /**
122      * Internal method for populating `primitive_tcs_map'.
123      */

124     private static void put_primitive_tcs (Class JavaDoc clz, int kind)
125     {
126         primitive_tcs_map.put (clz, primitive_tcs[kind]);
127     }
128
129     /**
130      * Constructor for primitive types, called only from
131      * static initializer and org.jacorb.ir.TypeCodeUtil
132      */

133
134     public TypeCode( int _kind )
135     {
136         kind = _kind;
137     }
138
139     /**
140      * @param _kind kind identifying a primitive TypeCode
141      * @return TypeCode with integer kind _kind
142      */

143
144     static org.omg.CORBA.TypeCode JavaDoc get_primitive_tc( int _kind )
145     {
146        if ( primitive_tcs[_kind] == null )
147        {
148            throw new org.omg.CORBA.BAD_PARAM JavaDoc ("No primitive TypeCode for kind " + _kind);
149        }
150
151         return primitive_tcs[_kind];
152     }
153
154     /**
155      * @return True if this TypeCode represents a primitive type,
156      * false otherwise
157      */

158
159     public boolean is_primitive()
160     {
161         return ( ! is_recursive() && primitive_tcs[kind] != null );
162     }
163
164
165     /*
166      * TypeCode constructors for every conceivable type follow.
167      * These are called exclusively by the ORBSingleton, which is
168      * the only legal TypeCode factory
169      */

170
171
172     /**
173      * Constructor for recursive types
174      */

175
176     public TypeCode( String JavaDoc id )
177     {
178         this.id = id;
179         recursive = true;
180         kind = -1;
181         actualTypecode = null;
182     }
183
184     /**
185      * Constructor for tk_struct and tk_except
186      */

187
188     public TypeCode ( int _kind,
189                       String JavaDoc _id,
190                       String JavaDoc _name,
191                       org.omg.CORBA.StructMember JavaDoc[] _members)
192     {
193         kind = _kind;
194         id = _id;
195         if( _name != null )
196         {
197             name = _name.replace('.','_'); // for orbixWeb Interop
198
}
199         else
200         {
201             name = "";
202         }
203         member_count = _members.length;
204         member_name = new String JavaDoc[member_count];
205         member_type = new org.omg.CORBA.TypeCode JavaDoc[member_count];
206         for( int i = 0; i < member_count; i++ )
207         {
208             member_name[i] = _members[i].name;
209             member_type[i] = _members[i].type;
210         }
211     }
212
213     /**
214      * Constructor for tk_union
215      */

216
217     public TypeCode ( String JavaDoc _id,
218                       String JavaDoc _name,
219                       org.omg.CORBA.TypeCode JavaDoc _discriminator_type,
220                       org.omg.CORBA.UnionMember JavaDoc[] _members )
221     {
222         kind = TCKind._tk_union;
223         id = _id ;
224         if (_name != null)
225         {
226             name = _name.replace('.','_'); // for orbixWeb Interop
227
}
228         else
229         {
230             name = "";
231         }
232         discriminator_type = _discriminator_type;
233
234         member_count = _members.length;
235         member_name = new String JavaDoc[member_count];
236         member_label = new Any[member_count];
237         member_type = new org.omg.CORBA.TypeCode JavaDoc[member_count];
238
239         for( int i = 0; i < member_count; i++ )
240         {
241             member_name[i] = _members[i].name;
242             member_label[i] = (Any)_members[i].label;
243             if( member_label[i].kind().equals( TCKind.tk_octet ) &&
244                 ((Byte JavaDoc)member_label[i].value()).byteValue() == (byte)0 )
245             {
246                 default_index = i;
247             }
248             member_type[i] = _members[i].type;
249         }
250     }
251
252     /**
253      * Constructor for tk_enum
254      */

255
256     public TypeCode (java.lang.String JavaDoc _id,
257                      java.lang.String JavaDoc _name,
258                      java.lang.String JavaDoc[] _members)
259     {
260         kind = TCKind._tk_enum;
261         id = _id;
262         if (_name != null)
263         {
264             name = _name.replace('.','_'); // for orbixWeb Interop
265
}
266         else
267         {
268             name = "";
269         }
270         member_count = _members.length;
271         member_name = new String JavaDoc[member_count];
272
273         for( int i = 0; i < member_count; i++ )
274         {
275             member_name[i] = _members[i];
276         }
277     }
278
279     /**
280      * Constructor for tk_alias, tk_value_box
281      */

282
283     public TypeCode (int _kind,
284                      String JavaDoc _id,
285                      String JavaDoc _name,
286                      org.omg.CORBA.TypeCode JavaDoc _original_type)
287     {
288         id = _id;
289         kind = _kind;
290         if (_name != null)
291         {
292             name = _name.replace('.','_'); // for orbixWeb Interop
293
}
294         else
295         {
296             name = "";
297         }
298         content_type = _original_type;
299     }
300
301     /**
302      * Constructor for tk_objref, tk_abstract_interface, tk_native,
303      * tk_local_interface
304      */

305
306     public TypeCode (int _kind,
307                      java.lang.String JavaDoc _id,
308                      java.lang.String JavaDoc _name)
309     {
310         kind = _kind;
311         id = _id;
312         if (_name != null)
313         {
314             name = _name.replace('.','_'); // for orbixWeb Interop
315
}
316         else
317         {
318             name = "";
319         }
320     }
321
322     /**
323      * Constructor for tk_string, tk_wstring
324      */

325
326     public TypeCode ( int _kind, int _bound )
327     {
328         kind = _kind;
329         length = _bound;
330     }
331
332     /**
333      * Constructor for tk_sequence, tk_array
334      */

335
336     public TypeCode (int _kind,
337                      int _bound,
338                      org.omg.CORBA.TypeCode JavaDoc _element_type)
339     {
340         kind = _kind;
341         length = _bound;
342         content_type = _element_type;
343         if (content_type == null)
344         {
345            throw new org.omg.CORBA.BAD_PARAM JavaDoc ("TypeCode.ctor, content_type null");
346         }
347     }
348
349     /**
350      * Constructor for tk_fixed
351      */

352
353     public TypeCode (short _digits, short _scale)
354     {
355         kind = TCKind._tk_fixed;
356         digits = _digits;
357         scale = _scale;
358     }
359
360     /**
361      * Constructor for tk_value
362      */

363
364     public TypeCode (String JavaDoc id,
365                      String JavaDoc _name,
366                      short type_modifier,
367                      org.omg.CORBA.TypeCode JavaDoc concrete_base,
368                      org.omg.CORBA.ValueMember JavaDoc[] members)
369     {
370         kind = TCKind._tk_value;
371         this.id = id;
372         if (_name != null)
373         {
374             name = _name.replace('.','_'); // for orbixWeb Interop
375
}
376         else
377         {
378             name = "";
379         }
380         value_modifier = type_modifier;
381         content_type = concrete_base;
382         setValueMembers(members);
383     }
384
385     /**
386      * Auxiliary method that sets the members of a tk_value.
387      */

388
389     private void setValueMembers(org.omg.CORBA.ValueMember JavaDoc[] members)
390     {
391         member_count = (members != null) ? members.length : 0;
392         member_name = new String JavaDoc[member_count];
393         member_type = new org.omg.CORBA.TypeCode JavaDoc[member_count];
394         member_visibility = new short[member_count];
395         for( int i = 0; i < member_count; i++ )
396         {
397             member_name[i] = members[i].name;
398             member_type[i] = members[i].type;
399             member_visibility[i] = members[i].access;
400         }
401     }
402
403     /**
404      * check TypeCodes for equality
405      */

406
407     public boolean equal( org.omg.CORBA.TypeCode JavaDoc tc )
408     {
409         try
410         {
411             if( is_recursive() )
412             {
413                 checkActualTC();
414                 if( tc instanceof org.jacorb.orb.TypeCode &&
415                     ((org.jacorb.orb.TypeCode)tc).is_recursive() )
416                 {
417                     org.jacorb.orb.TypeCode jtc = (org.jacorb.orb.TypeCode)tc;
418
419                     jtc.checkActualTC();
420                     if ( secondIteration )
421                     {
422                         return true;
423                     }
424                     else
425                     {
426                         secondIteration = true;
427                         boolean result = actualTypecode.equal( jtc.actualTypecode );
428                         secondIteration = false;
429                         return result;
430                     }
431                 }
432                 return tc.equal( actualTypecode );
433             }
434             else if( tc instanceof org.jacorb.orb.TypeCode &&
435                      ((org.jacorb.orb.TypeCode)tc).is_recursive() )
436             {
437                 org.jacorb.orb.TypeCode jtc = (org.jacorb.orb.TypeCode)tc;
438
439                 jtc.checkActualTC();
440                 return equal( jtc.actualTypecode );
441             }
442
443             if ( kind().value() != tc.kind().value() )
444             {
445                 return false;
446             }
447
448             if ( kind == TCKind._tk_objref || kind == TCKind._tk_struct ||
449                  kind == TCKind._tk_union || kind == TCKind._tk_enum ||
450                  kind == TCKind._tk_alias || kind == TCKind._tk_except ||
451                  kind == TCKind._tk_value || kind == TCKind._tk_value_box ||
452                  kind == TCKind._tk_native || kind == TCKind._tk_abstract_interface ||
453                  kind == TCKind._tk_local_interface )
454             {
455                 if ( ! id().equals( tc.id() ) || ! name().equals( tc.name() ) )
456                 {
457                     return false;
458                 }
459             }
460
461             if ( kind == TCKind._tk_struct || kind == TCKind._tk_union ||
462                  kind == TCKind._tk_enum || kind == TCKind._tk_value ||
463                  kind == TCKind._tk_except )
464             {
465                 if ( member_count() != tc.member_count() )
466                 {
467                     return false;
468                 }
469
470                 for (int i = 0; i < member_count(); i++)
471                 {
472                     if ( ! member_name(i).equals( tc.member_name(i) ) )
473                     {
474                         return false;
475                     }
476
477                     if ( kind != TCKind._tk_enum &&
478                          ! member_type(i).equal( tc.member_type(i) ) )
479                     {
480                         return false;
481                     }
482
483                     if ( kind == TCKind._tk_union &&
484                          ! member_label(i).equal( tc.member_label(i) ) )
485                     {
486                         return false;
487                     }
488
489                     if ( kind == TCKind._tk_value &&
490                          member_visibility(i) != tc.member_visibility(i) )
491                     {
492                         return false;
493                     }
494                 }
495             }
496
497             if ( kind == TCKind._tk_union )
498             {
499                 if ( ! discriminator_type().equal( tc.discriminator_type() ) ||
500                      default_index() != tc.default_index() )
501                 {
502                     return false;
503                 }
504             }
505
506             if ( kind == TCKind._tk_string || kind == TCKind._tk_wstring ||
507                  kind == TCKind._tk_array || kind == TCKind._tk_sequence)
508             {
509                 if ( length() != tc.length() )
510                 {
511                     return false;
512                 }
513             }
514
515             if ( kind == TCKind._tk_array || kind == TCKind._tk_sequence ||
516                  kind == TCKind._tk_alias || kind == TCKind._tk_value_box)
517             {
518                if ( ! content_type().equal( tc.content_type() ) )
519                 {
520                     return false;
521                 }
522             }
523
524             if (kind == TCKind._tk_fixed)
525             {
526                 if ( fixed_digits() != tc.fixed_digits() ||
527                      fixed_scale() != tc.fixed_scale() )
528                 {
529                     return false;
530                 }
531             }
532
533             if (kind == TCKind._tk_value)
534             {
535                 if ( type_modifier() != tc.type_modifier() ||
536                      ! concrete_base_type().equal( tc.concrete_base_type() ) )
537                 {
538                     return false;
539                 }
540             }
541         }
542         // Equal does not raise Bounds or BadKind so just return false.
543
catch( org.omg.CORBA.TypeCodePackage.Bounds JavaDoc b )
544         {
545             return false;
546         }
547         catch( org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk )
548         {
549             return false;
550         }
551
552         return true;
553     }
554
555
556     public org.omg.CORBA.TCKind JavaDoc kind()
557     {
558        if (is_recursive ())
559        {
560           checkActualTC ();
561           return actualTypecode.kind ();
562        }
563
564        return org.omg.CORBA.TCKind.from_int (kind);
565     }
566
567
568     public int _kind()
569     {
570        if (is_recursive ())
571        {
572           checkActualTC ();
573           return actualTypecode._kind ();
574        }
575
576        return kind;
577     }
578
579     public java.lang.String JavaDoc id()
580         throws org.omg.CORBA.TypeCodePackage.BadKind JavaDoc
581     {
582         if( is_recursive() )
583         {
584             return id;
585         }
586         else
587             switch( kind )
588             {
589             case TCKind._tk_objref:
590             case TCKind._tk_struct:
591             case TCKind._tk_union:
592             case TCKind._tk_enum:
593             case TCKind._tk_alias:
594             case TCKind._tk_value:
595             case TCKind._tk_value_box:
596             case TCKind._tk_native:
597             case TCKind._tk_abstract_interface:
598             case TCKind._tk_local_interface:
599             case TCKind._tk_except: return id;
600             default: throw new org.omg.CORBA.TypeCodePackage.BadKind JavaDoc();
601             }
602     }
603
604     public java.lang.String JavaDoc name()
605         throws org.omg.CORBA.TypeCodePackage.BadKind JavaDoc
606     {
607         if (is_recursive ())
608         {
609            checkActualTC ();
610            return actualTypecode.name ();
611         }
612
613         switch( kind )
614         {
615         case TCKind._tk_objref:
616         case TCKind._tk_struct:
617         case TCKind._tk_union:
618         case TCKind._tk_enum:
619         case TCKind._tk_alias:
620         case TCKind._tk_value:
621         case TCKind._tk_value_box:
622         case TCKind._tk_native:
623         case TCKind._tk_abstract_interface:
624         case TCKind._tk_local_interface:
625         case TCKind._tk_except: return name;
626         default: throw new org.omg.CORBA.TypeCodePackage.BadKind JavaDoc();
627         }
628     }
629
630     public int member_count()
631         throws org.omg.CORBA.TypeCodePackage.BadKind JavaDoc
632     {
633         if (is_recursive ())
634         {
635            checkActualTC ();
636            return actualTypecode.member_count ();
637         }
638
639         switch( kind )
640         {
641         case TCKind._tk_struct:
642         case TCKind._tk_except:
643         case TCKind._tk_union:
644         case TCKind._tk_value:
645         case TCKind._tk_enum: return member_count;
646         default: throw new org.omg.CORBA.TypeCodePackage.BadKind JavaDoc();
647         }
648     }
649
650     public java.lang.String JavaDoc member_name(int index)
651         throws org.omg.CORBA.TypeCodePackage.BadKind JavaDoc,
652                org.omg.CORBA.TypeCodePackage.Bounds JavaDoc
653     {
654         if (is_recursive ())
655         {
656            checkActualTC ();
657            return actualTypecode.member_name (index);
658         }
659
660         switch( kind )
661         {
662         case TCKind._tk_struct:
663         case TCKind._tk_except:
664         case TCKind._tk_union:
665         case TCKind._tk_value:
666         case TCKind._tk_enum:
667             if( index >= 0 && index < member_count )
668                 return member_name[index];
669             else
670                 throw new org.omg.CORBA.TypeCodePackage.Bounds JavaDoc();
671         default: throw new org.omg.CORBA.TypeCodePackage.BadKind JavaDoc();
672         }
673     }
674
675     public org.omg.CORBA.TypeCode JavaDoc member_type(int index)
676         throws org.omg.CORBA.TypeCodePackage.BadKind JavaDoc,
677                org.omg.CORBA.TypeCodePackage.Bounds JavaDoc
678     {
679         if (is_recursive ())
680         {
681            checkActualTC ();
682            return actualTypecode.member_type (index);
683         }
684
685         switch( kind )
686         {
687         case TCKind._tk_struct:
688         case TCKind._tk_except:
689         case TCKind._tk_union:
690         case TCKind._tk_value:
691             if( index >= 0 && index < member_count )
692                 return member_type[index];
693             else
694                 throw new org.omg.CORBA.TypeCodePackage.Bounds JavaDoc();
695         default: throw new org.omg.CORBA.TypeCodePackage.BadKind JavaDoc();
696         }
697     }
698
699     public org.omg.CORBA.Any JavaDoc member_label( int index )
700         throws org.omg.CORBA.TypeCodePackage.BadKind JavaDoc,
701                org.omg.CORBA.TypeCodePackage.Bounds JavaDoc
702     {
703         if (is_recursive ())
704         {
705             checkActualTC ();
706             return actualTypecode.member_label (index);
707         }
708
709         if( kind != TCKind._tk_union )
710             throw new org.omg.CORBA.TypeCodePackage.BadKind JavaDoc();
711         if( index < 0 || index >= member_count )
712             throw new org.omg.CORBA.TypeCodePackage.Bounds JavaDoc();
713         return member_label[index];
714     }
715
716     public org.omg.CORBA.TypeCode JavaDoc discriminator_type()
717         throws org.omg.CORBA.TypeCodePackage.BadKind JavaDoc
718     {
719         if (is_recursive ())
720         {
721            checkActualTC ();
722            return actualTypecode.discriminator_type ();
723         }
724
725         if( kind != TCKind._tk_union )
726             throw new org.omg.CORBA.TypeCodePackage.BadKind JavaDoc();
727         return discriminator_type;
728     }
729
730
731     public int default_index()
732         throws org.omg.CORBA.TypeCodePackage.BadKind JavaDoc
733     {
734         if (is_recursive ())
735         {
736             checkActualTC ();
737             return actualTypecode.default_index ();
738         }
739
740         if( kind != TCKind._tk_union )
741             throw new org.omg.CORBA.TypeCodePackage.BadKind JavaDoc();
742         return default_index;
743     }
744
745
746     public int length()
747         throws org.omg.CORBA.TypeCodePackage.BadKind JavaDoc
748     {
749         switch( kind )
750         {
751         case TCKind._tk_string:
752         case TCKind._tk_wstring:
753         case TCKind._tk_sequence:
754         case TCKind._tk_array: return length;
755         default: throw new org.omg.CORBA.TypeCodePackage.BadKind JavaDoc();
756         }
757     }
758
759     public org.omg.CORBA.TypeCode JavaDoc content_type()
760         throws org.omg.CORBA.TypeCodePackage.BadKind JavaDoc
761     {
762         switch( kind )
763         {
764         case TCKind._tk_array:
765         case TCKind._tk_sequence:
766         case TCKind._tk_alias:
767         case TCKind._tk_value_box: return content_type;
768         default: throw new org.omg.CORBA.TypeCodePackage.BadKind JavaDoc();
769         }
770     }
771
772     public short fixed_digits()
773         throws org.omg.CORBA.TypeCodePackage.BadKind JavaDoc
774     {
775         if( kind != TCKind._tk_fixed )
776             throw new org.omg.CORBA.TypeCodePackage.BadKind JavaDoc();
777         return digits;
778     }
779
780     public short fixed_scale()
781         throws org.omg.CORBA.TypeCodePackage.BadKind JavaDoc
782     {
783         if( kind != TCKind._tk_fixed )
784             throw new org.omg.CORBA.TypeCodePackage.BadKind JavaDoc();
785         return scale;
786     }
787
788     /**
789      * <code>get_compact_typecode</code> returns a new TypeCode with all
790      * type and member information removed. RepositoryID and alias are
791      * preserved.
792      * This method effectively clones the original typecode - simpler than
793      * trying to work out what type so what to duplicate (and compact).
794      *
795      * @return an <code>org.omg.CORBA.TypeCode</code> value
796      */

797     public org.omg.CORBA.TypeCode JavaDoc get_compact_typecode()
798     {
799         // New typecode with same kind, id and a blank name.
800
TypeCode result = new TypeCode (kind, id, "");
801
802         // Duplicate the original typecode.
803
result.member_count = member_count;
804
805         // Member names are optional, so compact them down for transmission.
806
// Check whether we are doing full compaction or not.
807
// if (Environment.getCompactTypecodes() > 1 && member_name != null)
808
if ( member_name != null)
809         {
810             result.member_name = new String JavaDoc [member_name.length];
811             for (int i = 0; i < result.member_name.length; i++)
812             {
813                 result.member_name[i] = "";
814             }
815         }
816         else
817         {
818             result.member_name = member_name;
819         }
820
821         // Compact the member types down as well.
822
if (member_type != null)
823         {
824             result.member_type = new TypeCode [member_type.length];
825             for (int i = 0; i < result.member_type.length; i++)
826             {
827                 result.member_type[i] = member_type[i].get_compact_typecode ();
828             }
829         }
830
831         result.member_visibility = member_visibility;
832         result.member_label = member_label;
833         result.value_modifier = value_modifier;
834
835         result.discriminator_type = discriminator_type;
836         result.default_index = default_index;
837         result.length = length;
838         result.content_type = content_type;
839
840         result.scale = scale;
841         result.digits = digits;
842
843         result.recursive = recursive;
844         result.actualTypecode = actualTypecode;
845         result.secondIteration = secondIteration;
846
847         result.resolveRecursion ();
848         return result;
849     }
850
851     public short member_visibility(int index)
852         throws org.omg.CORBA.TypeCodePackage.BadKind JavaDoc,
853                org.omg.CORBA.TypeCodePackage.Bounds JavaDoc
854     {
855         if (kind != TCKind._tk_value)
856             throw new org.omg.CORBA.TypeCodePackage.BadKind JavaDoc();
857         if (index < 0 || index >= member_count)
858             throw new org.omg.CORBA.TypeCodePackage.Bounds JavaDoc();
859
860         return member_visibility[index];
861     }
862
863     public short type_modifier()
864         throws org.omg.CORBA.TypeCodePackage.BadKind JavaDoc
865     {
866         if (kind != TCKind._tk_value)
867             throw new org.omg.CORBA.TypeCodePackage.BadKind JavaDoc();
868
869         return value_modifier;
870     }
871
872     public org.omg.CORBA.TypeCode JavaDoc concrete_base_type()
873         throws org.omg.CORBA.TypeCodePackage.BadKind JavaDoc
874     {
875         if (kind != TCKind._tk_value)
876             throw new org.omg.CORBA.TypeCodePackage.BadKind JavaDoc();
877
878         return content_type;
879     }
880
881     /**
882      * less strict equivalence check, unwinds aliases
883      */

884     public boolean equivalent( org.omg.CORBA.TypeCode JavaDoc tc )
885     {
886         try
887         {
888             if( is_recursive() )
889             {
890                 checkActualTC();
891                 if( tc instanceof org.jacorb.orb.TypeCode &&
892                     ((org.jacorb.orb.TypeCode)tc).is_recursive() )
893                 {
894                     org.jacorb.orb.TypeCode jtc = (org.jacorb.orb.TypeCode)tc;
895
896                     jtc.checkActualTC();
897                     if ( secondIteration )
898                     {
899                         return true;
900                     }
901                     else
902                     {
903                         secondIteration = true;
904                         boolean result = actualTypecode.equivalent( jtc.actualTypecode );
905                         secondIteration = false;
906                         return result;
907                     }
908                 }
909                 return tc.equivalent( actualTypecode );
910             }
911             else if( tc instanceof org.jacorb.orb.TypeCode &&
912                      ((org.jacorb.orb.TypeCode)tc).is_recursive() )
913             {
914                 org.jacorb.orb.TypeCode jtc = (org.jacorb.orb.TypeCode)tc;
915
916                 jtc.checkActualTC();
917                 return equivalent( jtc.actualTypecode );
918             }
919
920             /* unalias any typedef'd types */
921
922             if( kind().value() == TCKind._tk_alias )
923             {
924                 return content_type().equivalent( tc );
925             }
926
927             if( tc.kind().value() == TCKind._tk_alias )
928             {
929                 return equivalent( tc.content_type() );
930             }
931
932             if( kind().value() != tc.kind().value() )
933             {
934                 return false;
935             }
936
937             if( kind == TCKind._tk_objref || kind == TCKind._tk_struct ||
938                 kind == TCKind._tk_union || kind == TCKind._tk_enum ||
939                 kind == TCKind._tk_alias || kind == TCKind._tk_except ||
940                 kind == TCKind._tk_value || kind == TCKind._tk_value_box ||
941                 kind == TCKind._tk_native || kind == TCKind._tk_abstract_interface ||
942                 kind == TCKind._tk_local_interface )
943             {
944                 if( id().length() > 0 && tc.id().length() > 0 )
945                 {
946                     if ( id().equals( tc.id() ) )
947                     {
948                         return true;
949                     }
950                     return false;
951                 }
952             }
953
954             if ( kind == TCKind._tk_struct || kind == TCKind._tk_union ||
955                  kind == TCKind._tk_enum || kind == TCKind._tk_value ||
956                  kind == TCKind._tk_except )
957             {
958                 if ( member_count() != tc.member_count() )
959                 {
960                     return false;
961                 }
962
963                 for (int i = 0; i < member_count(); i++)
964                 {
965                     if ( kind != TCKind._tk_enum &&
966                          ! member_type(i).equivalent( tc.member_type(i) ) )
967                     {
968                         return false;
969                     }
970
971                     if ( kind == TCKind._tk_union &&
972                          ! member_label(i).equal( tc.member_label(i) ) )
973                     {
974                         return false;
975                     }
976
977                     if ( kind == TCKind._tk_value &&
978                          member_visibility(i) != tc.member_visibility(i) )
979                     {
980                         return false;
981                     }
982                 }
983             }
984
985             if ( kind == TCKind._tk_union )
986             {
987                 if ( ! discriminator_type().equivalent( tc.discriminator_type() ) ||
988                     default_index() != tc.default_index() )
989                 {
990                     return false;
991                 }
992             }
993
994             if ( kind == TCKind._tk_string || kind == TCKind._tk_wstring ||
995                  kind == TCKind._tk_array || kind == TCKind._tk_sequence)
996             {
997                 if ( length() != tc.length() )
998                 {
999                     return false;
1000                }
1001            }
1002
1003            if ( kind == TCKind._tk_array || kind == TCKind._tk_sequence ||
1004                 kind == TCKind._tk_alias || kind == TCKind._tk_value_box)
1005            {
1006                if ( ! content_type().equivalent( tc.content_type() ) )
1007                {
1008                    return false;
1009                }
1010            }
1011
1012            if (kind == TCKind._tk_fixed)
1013            {
1014                if ( fixed_digits() != tc.fixed_digits() ||
1015                     fixed_scale() != tc.fixed_scale() )
1016                {
1017                    return false;
1018                }
1019            }
1020
1021            if (kind == TCKind._tk_value)
1022            {
1023                if ( type_modifier() != tc.type_modifier() ||
1024                     ! concrete_base_type().equivalent( tc.concrete_base_type() ) )
1025                {
1026                    return false;
1027                }
1028            }
1029        }
1030        // Equivalent does not raise Bounds or BadKind so just return false.
1031
catch( org.omg.CORBA.TypeCodePackage.Bounds JavaDoc b )
1032        {
1033            return false;
1034        }
1035        catch( org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk )
1036        {
1037            return false;
1038        }
1039
1040        return true;
1041    }
1042
1043    // useful additional functionality
1044

1045    public void toSequence()
1046    {
1047        kind = TCKind._tk_sequence;
1048    }
1049
1050    public String JavaDoc toString()
1051    {
1052        return idlTypeName();
1053    }
1054
1055    /**
1056     * @return TRUE is this TypeCode is recursive. Both the initial
1057     * place holder TypeCode and the real TypeCode which replaces
1058     * the place holder return TRUE.
1059     */

1060
1061    public boolean is_recursive()
1062    {
1063        return recursive;
1064    }
1065
1066    /**
1067     * @return TRUE if the argument is a JacORB typecode and is recursive.
1068     */

1069    public static boolean isRecursive(org.omg.CORBA.TypeCode JavaDoc tc)
1070    {
1071        return (tc instanceof TypeCode) ? ((TypeCode)tc).is_recursive()
1072                                        : false;
1073    }
1074
1075    /**
1076     * called after replacing the placeholder
1077     * to be able to break off recursion
1078     */

1079
1080    private void set_recursive()
1081    {
1082        recursive = true;
1083    }
1084
1085    /** convenience method */
1086
1087    public static String JavaDoc idlTypeName( org.omg.CORBA.TypeCode JavaDoc tc )
1088    {
1089        return (tc instanceof org.jacorb.orb.TypeCode)
1090                                  ? ((org.jacorb.orb.TypeCode)tc).idlTypeName()
1091                                  : "(foreign typecode)";
1092    }
1093
1094    /** convenience method */
1095
1096    public String JavaDoc idlTypeName()
1097    {
1098       if (is_recursive ())
1099       {
1100          checkActualTC ();
1101          return actualTypecode.idlTypeName ();
1102       }
1103
1104       switch( kind().value() )
1105       {
1106       case TCKind._tk_objref:
1107       case TCKind._tk_struct:
1108       case TCKind._tk_union:
1109       case TCKind._tk_enum:
1110       case TCKind._tk_alias:
1111       case TCKind._tk_except:
1112       case TCKind._tk_native:
1113       case TCKind._tk_abstract_interface:
1114       case TCKind._tk_local_interface:
1115          try
1116          {
1117             return idToIDL(id());
1118          }
1119          catch ( org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk )
1120          {}
1121       case TCKind._tk_void: return "void";
1122       case TCKind._tk_string: return "string";
1123       case TCKind._tk_wstring: return "wstring";
1124       case TCKind._tk_array:
1125          try
1126          {
1127             return idlTypeName(content_type()) + "[]";
1128          } catch ( org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk )
1129          {}
1130       case TCKind._tk_long: return "long";
1131       case TCKind._tk_ulong: return "ulong";
1132       case TCKind._tk_longlong: return "long long";
1133       case TCKind._tk_ulonglong: return "ulong long";
1134       case TCKind._tk_ushort: return "ushort";
1135       case TCKind._tk_short: return "short";
1136       case TCKind._tk_float: return "float";
1137       case TCKind._tk_double: return "double";
1138       case TCKind._tk_fixed:
1139          try
1140          {
1141             return "fixed <" + fixed_digits() + "," + fixed_scale() + ">";
1142          }
1143          catch ( org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk )
1144          {}
1145       case TCKind._tk_boolean: return "boolean";
1146       case TCKind._tk_octet: return "octet";
1147       case TCKind._tk_char: return "char";
1148       case TCKind._tk_wchar: return "wchar";
1149       case TCKind._tk_any: return "any";
1150       case TCKind._tk_sequence:
1151          try
1152          {
1153             return "sequence <" + idlTypeName(content_type()) + ">";
1154          } catch ( org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk )
1155          {}
1156       default: return "* no typeName for TK " + kind().value() + " *";
1157       }
1158    }
1159
1160    private static String JavaDoc idToIDL( String JavaDoc s )
1161    {
1162        if (s.length () > 4)
1163        {
1164            if (s.startsWith ("IDL:"))
1165            {
1166                s = s.substring (4, s.lastIndexOf (":"));
1167            }
1168            else
1169            {
1170                s = s.replace ('.','/') + ":1.0";
1171            }
1172        }
1173
1174        StringBuffer JavaDoc sb = new StringBuffer JavaDoc( s );
1175        int i = 0;
1176        while( i < sb.length() )
1177        {
1178            if( sb.charAt(i) == '/' )
1179            {
1180                sb.setCharAt(i,':');
1181                sb.insert(i,':');
1182            }
1183            i++;
1184        }
1185        return sb.toString();
1186    }
1187
1188    /**
1189     * @return the content type if the argument is an alias, or the argument
1190     * itself otherwise
1191     */

1192    public static org.omg.CORBA.TypeCode JavaDoc originalType(org.omg.CORBA.TypeCode JavaDoc tc)
1193    {
1194        if (isRecursive(tc))
1195        {
1196            // Recursive typecodes must be structs or unions so there is no
1197
// unwinding of aliases to be done. By returning here we avoid
1198
// calling kind() on a recursive typecode that might not have been
1199
// resolved yet. (If you remove the return statement below, you
1200
// will get org.omg.CORBA.BAD_INV_ORDER exceptions within kind()
1201
// calls on non-resolved recursive typecodes!)
1202
return tc;
1203        }
1204
1205        try
1206        {
1207            while (tc.kind() == org.omg.CORBA.TCKind.tk_alias)
1208                tc = tc.content_type();
1209        }
1210        catch (org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk)
1211        {
1212            // does not happen
1213
}
1214        return tc;
1215    }
1216
1217    /**
1218     * Creates a TypeCode for an arbitrary Java class.
1219     * Right now, this only covers RMI classes, not those derived from IDL.
1220     */

1221    public static TypeCode create_tc (Class JavaDoc clz)
1222    {
1223        return create_tc (clz, new HashMap());
1224    }
1225
1226    /**
1227     * Creates a TypeCode for class `clz'. `knownTypes' is a map
1228     * containing classes as keys and their corresponding type codes
1229     * as values. If there is an entry for `clz' in `knownTypes',
1230     * then a recursive type code is returned for it. If there is no
1231     * entry for `clz' in `knownTypes', and a value type code is
1232     * created for it, then an entry for `clz' is also inserted into
1233     * `knownTypes'.
1234     */

1235    private static TypeCode create_tc(Class JavaDoc clz, Map knownTypes)
1236    {
1237        if (clz.isPrimitive())
1238            return (TypeCode)primitive_tcs_map.get(clz);
1239        else if (knownTypes.containsKey(clz))
1240        {
1241            // recursive type code
1242
TypeCode newTypeCode = new TypeCode(RepositoryID.repId(clz));
1243            newTypeCode.setActualTC((TypeCode)knownTypes.get(clz));
1244            return newTypeCode;
1245        }
1246        else if (clz.isArray())
1247        {
1248            // a Java array is mapped to a valuebox containing an IDL sequence
1249
TypeCode newTypeCode =
1250                new TypeCode(TCKind._tk_value_box,
1251                             RepositoryID.repId(clz),
1252                             "Java_array",
1253                             new TypeCode(TCKind._tk_sequence,
1254                                          0,
1255                                          create_tc(clz.getComponentType(),
1256                                                    knownTypes)));
1257            knownTypes.put(clz, newTypeCode);
1258            return newTypeCode;
1259        }
1260        else if (java.rmi.Remote JavaDoc.class.isAssignableFrom(clz))
1261            return new TypeCode(TCKind._tk_objref, RepositoryID.repId(clz),
1262                                clz.getName());
1263        else if (org.omg.CORBA.portable.IDLEntity JavaDoc.class.isAssignableFrom(clz))
1264        {
1265            // an IDL entity has a helper class with a static method type()
1266
String JavaDoc helperClassName = clz.getName() + "Helper";
1267            try
1268            {
1269                Class JavaDoc helperClass =
1270                    clz.getClassLoader().loadClass(helperClassName);
1271                java.lang.reflect.Method JavaDoc typeMethod =
1272                    helperClass.getMethod("type", (Class JavaDoc[]) null);
1273                TypeCode newTypeCode =
1274                    (TypeCode)typeMethod.invoke(null, (Object JavaDoc[]) null);
1275                knownTypes.put(clz, newTypeCode);
1276                return newTypeCode;
1277            }
1278            catch (ClassNotFoundException JavaDoc e)
1279            {
1280                throw new RuntimeException JavaDoc(
1281                                    "Cannot create TypeCode for class " + clz
1282                                    + "\nReason: Error loading helper class "
1283                                    + helperClassName
1284                                    + "\n" + e);
1285            }
1286            catch (NoSuchMethodException JavaDoc e)
1287            {
1288                throw new RuntimeException JavaDoc(
1289                            "Cannot create TypeCode for class: " + clz
1290                            + "\nReason: no type() method in helper class "
1291                            + helperClassName + "\n" + e);
1292            }
1293            catch (IllegalAccessException JavaDoc e)
1294            {
1295                throw new RuntimeException JavaDoc(
1296                                    "Cannot create TypeCode for class: " + clz
1297                                    + "\n" + e);
1298            }
1299            catch (java.lang.reflect.InvocationTargetException JavaDoc e)
1300            {
1301                throw new RuntimeException JavaDoc(
1302                                    "Cannot create TypeCode for class: " + clz
1303                                    + "\nReason: exception in type() method\n "
1304                                    + e.getTargetException());
1305            }
1306        }
1307        else if (clz == java.io.Serializable JavaDoc.class ||
1308                 clz == java.io.Externalizable JavaDoc.class ||
1309                 clz == java.lang.Object JavaDoc.class)
1310        {
1311            // Each such Java type is mapped to an IDL typedef for an IDL any
1312
return (TypeCode)get_primitive_tc(TCKind._tk_any);
1313        }
1314        else if (isMappedToAnAbstractInterface(clz))
1315        {
1316            TypeCode newTypeCode = new TypeCode(TCKind._tk_abstract_interface,
1317                                                RepositoryID.repId(clz),
1318                                                clz.getName());
1319            knownTypes.put(clz, newTypeCode);
1320            return newTypeCode;
1321        }
1322        else // clz is mapped to a valuetype
1323
{
1324            Class JavaDoc superClass = clz.getSuperclass();
1325            TypeCode superTypeCode = null;
1326            if (superClass != null && superClass != java.lang.Object JavaDoc.class)
1327                superTypeCode = create_tc(superClass, knownTypes);
1328            TypeCode newTypeCode =
1329                new TypeCode(RepositoryID.repId(clz),
1330                             clz.getName(),
1331                             org.omg.CORBA.VM_NONE.value,
1332                             superTypeCode,
1333                             new ValueMember JavaDoc[0]);
1334            knownTypes.put(clz, newTypeCode);
1335            newTypeCode.setValueMembers(getValueMembers(clz, knownTypes));
1336            return newTypeCode;
1337        }
1338    }
1339
1340    /*
1341     * Java interfaces whose method definitions (including inherited method
1342     * definitions) all throw java.rmi.RemoteException or a superclass of
1343     * java.rmi.RemoteException are mapped to IDL abstract interfaces.
1344     */

1345    private static boolean isMappedToAnAbstractInterface(Class JavaDoc clz)
1346    {
1347        if (!clz.isInterface())
1348        {
1349            return false;
1350        }
1351        else
1352        {
1353            java.lang.reflect.Method JavaDoc[] methods = clz.getMethods();
1354            for (int i = 0; i < methods.length; i++)
1355            {
1356                Class JavaDoc[] exceps = methods[i].getExceptionTypes();
1357                int j = 0;
1358                while (j < exceps.length)
1359                {
1360                    if (exceps[j].isAssignableFrom(
1361                                               java.rmi.RemoteException JavaDoc.class))
1362                        break;
1363                    else
1364                        j++;
1365                }
1366                if (j == exceps.length)
1367                {
1368                    // method[i] does not throw java.rmi.RemoteException
1369
// or a superclass of java.rmi.RemoteException
1370
return false;
1371                }
1372            }
1373            // every method throws java.rmi.RemoteException
1374
// or a superclass of java.rmi.RemoteException
1375
return true;
1376        }
1377    }
1378
1379    /**
1380     * Returns the array of ValueMembers of class `clz'. `knownTypes'
1381     * is a map of classes and corresponding type codes for which
1382     * recursive type codes must be created; this is passed through
1383     * from `create_tc (Class, Map)' above.
1384     */

1385    private static ValueMember JavaDoc[] getValueMembers (Class JavaDoc clz, Map knownTypes)
1386    {
1387        List result = new ArrayList();
1388        Field JavaDoc[] fields = clz.getDeclaredFields();
1389        for (int i=0; i < fields.length; i++)
1390        {
1391            if ((fields[i].getModifiers()
1392                 & (Modifier.STATIC | Modifier.FINAL | Modifier.TRANSIENT))
1393                == 0)
1394                result.add (createValueMember (fields[i], knownTypes));
1395        }
1396        return (ValueMember JavaDoc[])result.toArray (new ValueMember JavaDoc[0]);
1397    }
1398
1399    /**
1400     * Creates a ValueMember for field `f'. `knownTypes' is a map of
1401     * classes and their corresponding type codes for which recursive
1402     * type codes must be created; this is passed through from
1403     * `create_tc (Class, Map)' above.
1404     */

1405    private static ValueMember JavaDoc createValueMember (Field JavaDoc f, Map knownTypes)
1406    {
1407        Class JavaDoc type = f.getType();
1408        String JavaDoc id = RepositoryID.repId (type);
1409        TypeCode tc = create_tc (type, knownTypes);
1410        short access = ((f.getModifiers() & Modifier.PUBLIC) != 0)
1411                              ? org.omg.CORBA.PUBLIC_MEMBER.value
1412                              : org.omg.CORBA.PRIVATE_MEMBER.value;
1413        return new ValueMember JavaDoc (f.getName(), id, "", "1.0", tc, null, access);
1414    }
1415
1416   /*
1417    * Resolve any recursive TypeCodes contained within this TypeCode. This
1418    * TypeCode is the actual (non-recursive) TypeCode that replaces any
1419    * recursive TypeCodes with the same RepositoryId. This operation should
1420    * only be called on union or struct TypeCodes since it is only these
1421    * TypeCodes that can be recursive.
1422    */

1423   void resolveRecursion ()
1424   {
1425      if (kind == TCKind._tk_struct || kind == TCKind._tk_union)
1426      {
1427         resolveRecursion (this);
1428      }
1429   }
1430
1431   /*
1432    * Resolve any recursive TypeCodes contained within this TypeCode.
1433    * @param actual The actual (non-recursive) TypeCode that replaces any
1434    * recursive TypeCodes contained in the actual TypeCode that have the same
1435    * RepositoryId
1436    */

1437   private void resolveRecursion (TypeCode actual)
1438   {
1439      if (member_type == null)
1440      {
1441         return;
1442      }
1443
1444      org.omg.CORBA.TypeCode JavaDoc typeCode;
1445      TypeCode tc;
1446      for (int i = 0; i < member_type.length; i++)
1447      {
1448         typeCode = originalType (member_type[i]);
1449         if (typeCode instanceof TypeCode)
1450         {
1451            tc = (TypeCode)typeCode;
1452
1453            switch (tc.kind)
1454            {
1455            case TCKind._tk_struct:
1456            case TCKind._tk_union:
1457               tc.resolveRecursion (actual);
1458               break;
1459            case TCKind._tk_sequence:
1460               typeCode = originalType (tc.content_type);
1461               if (typeCode instanceof TypeCode)
1462               {
1463                  tc = (TypeCode)typeCode;
1464
1465                  if (tc.is_recursive () && tc.id.equals (actual.id))
1466                  {
1467                     tc.setActualTC (actual);
1468                  }
1469                  else
1470                  {
1471                     tc.resolveRecursion (actual);
1472                  }
1473               }
1474               break;
1475            }
1476         }
1477      }
1478   }
1479   /*
1480    * Set the actual TypeCode if this TypeCode is recursive.
1481    * @param tc The actual TypeCode
1482    */

1483   private void setActualTC (TypeCode tc)
1484   {
1485      if (is_recursive ())
1486      {
1487         actualTypecode = tc;
1488      }
1489   }
1490
1491   /*
1492    * Check that the actual TypeCode is set if this TypeCode is recursive.
1493    * This method ensures that operations aren't called on a recursive TypeCode
1494    * until the enclosing TypeCode has been fully resolved.
1495    * @exception BAD_INV_ORDER if this TypeCode is recursive and an operation
1496    * is called on it before the enclosing TypeCode has been fully resolved
1497    */

1498   private void checkActualTC ()
1499   {
1500      if (is_recursive () && actualTypecode == null)
1501      {
1502         throw new org.omg.CORBA.BAD_INV_ORDER JavaDoc ();
1503      }
1504   }
1505}
1506
Popular Tags