001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.geronimo.corba.util;
018    
019    import org.omg.CORBA.TCKind;
020    import org.omg.CORBA.TypeCodePackage.BadKind;
021    import org.omg.CORBA.TypeCodePackage.Bounds;
022    
023    
024    /**
025     * @version $Revision: 451417 $ $Date: 2006-09-29 13:13:22 -0700 (Fri, 29 Sep 2006) $
026     */
027    public class TypeCode    extends org.omg.CORBA.TypeCode
028    {
029        // -----------------------------------------------------------------------
030        // public data
031        // -----------------------------------------------------------------------
032    
033        public static final TypeCode NULL = new TypeCode(TCKind.tk_null);
034    
035        public static final TypeCode VOID = new TypeCode(TCKind.tk_void);
036    
037        public static final TypeCode ANY = new TypeCode(TCKind.tk_any);
038    
039        public static final TypeCode BOOLEAN = new TypeCode(TCKind.tk_boolean);
040    
041        public static final TypeCode CHAR = new TypeCode(TCKind.tk_char);
042    
043        public static final TypeCode WCHAR = new TypeCode(TCKind.tk_wchar);
044    
045        public static final TypeCode OCTET = new TypeCode(TCKind.tk_octet);
046    
047        public static final TypeCode SHORT = new TypeCode(TCKind.tk_short);
048    
049        public static final TypeCode USHORT = new TypeCode(TCKind.tk_ushort);
050    
051        public static final TypeCode LONG = new TypeCode(TCKind.tk_long);
052    
053        public static final TypeCode ULONG = new TypeCode(TCKind.tk_ulong);
054    
055        public static final TypeCode LONGLONG = new TypeCode(TCKind.tk_longlong);
056    
057        public static final TypeCode ULONGLONG = new TypeCode(TCKind.tk_ulonglong);
058    
059        public static final TypeCode FLOAT = new TypeCode(TCKind.tk_float);
060    
061        public static final TypeCode DOUBLE = new TypeCode(TCKind.tk_double);
062    
063        public static final TypeCode LONGDOUBLE = new TypeCode(
064            TCKind.tk_longdouble);
065    
066        public static final TypeCode STRING = new TypeCode(TCKind.tk_string);
067    
068        public static final TypeCode WSTRING = new TypeCode(TCKind.tk_wstring);
069    
070        public static final TypeCode OBJREF = new TypeCode(TCKind.tk_objref);
071    
072        public static final TypeCode TYPECODE = new TypeCode(TCKind.tk_TypeCode);
073    
074        // -----------------------------------------------------------------------
075        // private data
076        // -----------------------------------------------------------------------
077    
078        private TCKind _kind;
079    
080        private String _name;
081    
082        private String _type;
083    
084        private String _id;
085    
086        private String _label;
087    
088        // content type, discriminator type, concrete base type,
089        // or other TypeCode for indirection.
090        private org.omg.CORBA.TypeCode _ref;
091    
092        private String[] _member_name;
093    
094        private org.omg.CORBA.TypeCode[] _member_type;
095    
096        private org.omg.CORBA.Any[] _member_label;
097    
098        private short[] _member_visibility;
099    
100        private int _default;
101    
102        private int _length;
103    
104        private short _digits;
105    
106        private short _scale;
107    
108        private short _type_modifier;
109    
110        private boolean _indirection;
111    
112        // -----------------------------------------------------------------------
113        // public methods
114        // -----------------------------------------------------------------------
115        /**
116         * @param kind
117         */
118        public TypeCode(TCKind kind)
119        {
120            _kind = kind;
121            _default = -1;
122            if (kind.value() == TCKind._tk_objref)
123            {
124                _type = "Object";
125            }
126        }
127    
128        public boolean equal(org.omg.CORBA.TypeCode tc)
129        {
130            if (_indirection)
131            {
132                return _ref.equal(tc);
133            }
134            try
135            {
136                int tk = _kind.value();
137                if (tk != tc.kind().value())
138                {
139                    return false;
140                }
141                // TODO: compare id()
142                if (_member_name != null)
143                {
144                    int n = _member_name.length;
145                    if (n != tc.member_count())
146                    {
147                        return false;
148                    }
149                    for (int i = 0; i < n; i++)
150                    {
151                        if (!equalIfNotEmpty(member_name(i), tc.member_name(i)))
152                        {
153                            return false;
154                        }
155                        if (!member_type(i).equal(tc.member_type(i)))
156                        {
157                            return false;
158                        }
159                    }
160                }
161                if (tk == TCKind._tk_union)
162                {
163                    if (!discriminator_type().equal(tc.discriminator_type()))
164                    {
165                        return false;
166                    }
167                    int n = _member_name.length;
168                    for (int i = 0; i < n; i++)
169                    {
170                        if (!member_label(i).equal(tc.member_label(i)))
171                        {
172                            return false;
173                        }
174                    }
175                }
176                if (tk == TCKind._tk_array
177                    ||
178                    tk == TCKind._tk_sequence
179                    ||
180                    tk == TCKind._tk_string
181                    || tk == TCKind._tk_wstring)
182                {
183                    if (length() != tc.length())
184                    {
185                        return false;
186                    }
187                }
188                if (tk == TCKind._tk_alias
189                    ||
190                    tk == TCKind._tk_array
191                    || tk == TCKind._tk_sequence)
192                {
193                    if (!content_type().equal(tc.content_type()))
194                    {
195                        return false;
196                    }
197                }
198                return true;
199            }
200            catch (org.omg.CORBA.TypeCodePackage.BadKind ex)
201            {
202                throw (org.omg.CORBA.UNKNOWN)new org.omg.CORBA.UNKNOWN(ex.toString()).initCause(ex);
203            }
204            catch (org.omg.CORBA.TypeCodePackage.Bounds ex)
205            {
206                throw (org.omg.CORBA.UNKNOWN)new org.omg.CORBA.UNKNOWN(ex.toString()).initCause(ex);
207            }
208        }
209    
210        public boolean equivalent
211            (org.omg.CORBA.TypeCode tc)
212        {
213            throw new org.omg.CORBA.NO_IMPLEMENT();
214        }
215    
216        public org.omg.CORBA.TypeCode get_compact_typecode()
217        {
218            throw new org.omg.CORBA.NO_IMPLEMENT();
219        }
220    
221        private boolean equalIfNotEmpty(String a, String b)
222        {
223            if (a.length() == 0 || b.length() == 0)
224            {
225                return true;
226            }
227            else
228            {
229                return a.equals(b);
230            }
231        }
232    
233        public TCKind kind()
234        {
235            if (_indirection)
236            {
237                return _ref.kind();
238            }
239            return _kind;
240        }
241    
242        /**
243         * @return
244         * @throws BadKind
245         */
246        public String id()
247            throws BadKind
248        {
249            if (_indirection)
250            {
251                return _ref.id();
252            }
253            if (_id != null)
254            {
255                return _id;
256            }
257            if (_type != null && _type.equals("Object"))
258            {
259                return "";
260            }
261            return default_id();
262        }
263    
264        // Sybase-internal
265        /**
266         * @param id
267         */
268        public void id(String id)
269        {
270            if (!id.equals(""))
271            {
272                _id = id;
273                if (id.startsWith("IDL:") && id.endsWith(":1.0"))
274                {
275                    // Infer _type field from standard IDL format _id
276                    id = id.substring(4, id.length() - 4);
277                    if (id.startsWith("omg.org/"))
278                    {
279                        id = id.substring(8);
280                    }
281                    _type = "";
282                    for (; ;)
283                    {
284                        int slash = id.indexOf('/');
285                        if (slash == -1)
286                        {
287                            break;
288                        }
289                        _type = _type + id.substring(0, slash) + "::";
290                        id = id.substring(slash + 1);
291                    }
292                    _type = _type + id;
293                }
294            }
295        }
296    
297        /**
298         * @return
299         * @throws BadKind
300         */
301        public String name()
302            throws BadKind
303        {
304            if (_indirection)
305            {
306                return _ref.name();
307            }
308            /* TODO?
309            if (_name == null)
310            {
311                _name = (String)_names.get(new Integer(_kind.value()));
312            }
313            */
314            if (_name == null)
315            {
316                throw new BadKind();
317            }
318            return _name;
319        }
320    
321        // Sybase-internal
322        /**
323         * @param name
324         */
325        public void name(String name)
326        {
327            _name = name;
328        }
329    
330        /**
331         * @return
332         * @throws BadKind
333         */
334        public int member_count()
335            throws BadKind
336        {
337            if (_indirection)
338            {
339                return _ref.member_count();
340            }
341            if (_member_name == null)
342            {
343                throw new BadKind();
344            }
345            return _member_name.length;
346        }
347    
348        // Sybase-internal
349        /**
350         * @param count
351         */
352        public void member_count(int count)
353        {
354            _member_name = new String[count];
355            _member_type = new org.omg.CORBA.TypeCode[count];
356            if (_kind.value() == TCKind._tk_union)
357            {
358                _member_label = new org.omg.CORBA.Any[count];
359            }
360            if (_kind.value() == TCKind._tk_value)
361            {
362                _member_visibility = new short[count];
363            }
364        }
365    
366        /**
367         * @param index
368         * @return
369         * @throws BadKind
370         * @throws Bounds
371         */
372        public String member_name(int index)
373            throws BadKind, Bounds
374        {
375            if (_indirection)
376            {
377                return _ref.member_name(index);
378            }
379            if (_member_name == null)
380            {
381                throw new BadKind();
382            }
383            if (index < 0 || index >= _member_name.length)
384            {
385                throw new Bounds();
386            }
387            return _member_name[index];
388        }
389    
390        // Sybase-internal
391        /**
392         * @param index
393         * @param name
394         */
395        public void member_name(int index, String name)
396        {
397            _member_name[index] = name;
398        }
399    
400        /**
401         * @param index
402         * @return
403         * @throws BadKind
404         * @throws Bounds
405         */
406        public org.omg.CORBA.TypeCode member_type(int index)
407            throws BadKind, Bounds
408        {
409            if (_indirection)
410            {
411                return _ref.member_type(index);
412            }
413            if (_member_type == null)
414            {
415                throw new BadKind();
416            }
417            if (index < 0 || index >= _member_type.length)
418            {
419                throw new Bounds();
420            }
421            return _member_type[index];
422        }
423    
424        // Sybase-internal
425        /**
426         * @param index
427         * @param type
428         */
429        public void member_type(int index, org.omg.CORBA.TypeCode type)
430        {
431            _member_type[index] = type;
432        }
433    
434        /**
435         * @param index
436         * @return
437         * @throws BadKind
438         * @throws Bounds
439         */
440        public org.omg.CORBA.Any member_label(int index)
441            throws BadKind, Bounds
442        {
443            if (_indirection)
444            {
445                return _ref.member_label(index);
446            }
447            if (_member_label == null)
448            {
449                throw new BadKind();
450            }
451            if (index < 0 || index >= _member_label.length)
452            {
453                throw new Bounds();
454            }
455            return _member_label[index];
456        }
457    
458        // Sybase-internal
459        /**
460         * @param index
461         * @param label
462         */
463        public void member_label(int index, org.omg.CORBA.Any label)
464        {
465            _member_label[index] = label;
466        }
467    
468        /**
469         * @return
470         * @throws BadKind
471         */
472        public org.omg.CORBA.TypeCode discriminator_type()
473            throws BadKind
474        {
475            if (_indirection)
476            {
477                return _ref.discriminator_type();
478            }
479            if (_ref == null
480                || _kind.value() != TCKind._tk_union)
481            {
482                throw new BadKind();
483            }
484            return _ref;
485        }
486    
487        // Sybase-internal
488        /**
489         * @param disc
490         */
491        public void discriminator_type(org.omg.CORBA.TypeCode disc)
492        {
493            _ref = disc;
494        }
495    
496        /**
497         * @return
498         * @throws BadKind
499         */
500        public int default_index()
501            throws BadKind
502        {
503            if (_indirection)
504            {
505                return _ref.default_index();
506            }
507            if (_kind.value() != TCKind._tk_union)
508            {
509                throw new BadKind();
510            }
511            return _default;
512        }
513    
514        /**
515         * @return
516         * @throws BadKind
517         */
518        public int length()
519            throws BadKind
520        {
521            if (_indirection)
522            {
523                return _ref.length();
524            }
525            int tk = _kind.value();
526            if (tk != TCKind._tk_string &&
527                tk != TCKind._tk_wstring
528                && tk != TCKind._tk_sequence && tk != TCKind._tk_array)
529            {
530                throw new BadKind();
531            }
532            return _length;
533        }
534    
535        // Sybase-internal
536        /**
537         * @param length
538         */
539        public void length(int length)
540        {
541            _length = length;
542        }
543    
544        /**
545         * @return
546         * @throws BadKind
547         */
548        public org.omg.CORBA.TypeCode content_type()
549            throws BadKind
550        {
551            if (_indirection)
552            {
553                return _ref.content_type();
554            }
555            int tk = _kind.value();
556            if (_ref == null
557                || (tk != TCKind._tk_alias
558                &&
559                tk != TCKind._tk_array
560                &&
561                tk != TCKind._tk_sequence
562                && tk != TCKind._tk_value_box))
563            {
564                throw new BadKind();
565            }
566            return _ref;
567        }
568    
569        // Sybase-internal
570        /**
571         * @param type
572         */
573        public void content_type(org.omg.CORBA.TypeCode type)
574        {
575            _ref = type;
576        }
577    
578        /**
579         * @return
580         * @throws BadKind
581         */
582        public short fixed_digits()
583            throws BadKind
584        {
585            if (_indirection)
586            {
587                return _ref.fixed_digits();
588            }
589            int tk = _kind.value();
590            if (tk != TCKind._tk_fixed)
591            {
592                throw new BadKind();
593            }
594            return _digits;
595        }
596    
597        // Sybase-internal
598        /**
599         * @param digits
600         */
601        public void fixed_digits(short digits)
602        {
603            _digits = digits;
604        }
605    
606        /**
607         * @return
608         * @throws BadKind
609         */
610        public short fixed_scale()
611            throws BadKind
612        {
613            if (_indirection)
614            {
615                return _ref.fixed_scale();
616            }
617            int tk = _kind.value();
618            if (tk != TCKind._tk_fixed)
619            {
620                throw new BadKind();
621            }
622            return _scale;
623        }
624    
625        // Sybase-internal
626        /**
627         * @param scale
628         */
629        public void fixed_scale(short scale)
630        {
631            _scale = scale;
632        }
633    
634        /**
635         * @param index
636         * @return
637         * @throws BadKind
638         * @throws Bounds
639         */
640        public short member_visibility
641            (int index)
642            throws BadKind, Bounds
643        {
644            if (_indirection)
645            {
646                return _ref.member_visibility(index);
647            }
648            if (_member_type == null)
649            {
650                throw new BadKind();
651            }
652            if (index < 0 || index >= _member_visibility.length)
653            {
654                throw new Bounds();
655            }
656            return _member_visibility[index];
657        }
658    
659        // Sybase-internal
660        /**
661         * @param index
662         * @param visibility
663         */
664        public void member_visibility(int index, short visibility)
665        {
666            _member_visibility[index] = visibility;
667        }
668    
669        /**
670         * @return
671         * @throws BadKind
672         */
673        public short type_modifier()
674            throws BadKind
675        {
676            if (_indirection)
677            {
678                return _ref.type_modifier();
679            }
680            int tk = _kind.value();
681            if (tk != TCKind._tk_value)
682            {
683                throw new BadKind();
684            }
685            return _type_modifier;
686        }
687    
688        // Sybase-internal
689        /**
690         * @param modifier
691         */
692        public void type_modifier(short modifier)
693        {
694            _type_modifier = modifier;
695        }
696    
697        /**
698         * @return
699         * @throws BadKind
700         */
701        public org.omg.CORBA.TypeCode concrete_base_type()
702            throws BadKind
703        {
704            if (_indirection)
705            {
706                return _ref.concrete_base_type();
707            }
708            int tk = _kind.value();
709            if (tk != TCKind._tk_value)
710            {
711                throw new BadKind();
712            }
713            return _ref;
714        }
715    
716        // Sybase-internal
717        /**
718         * @param base
719         */
720        public void concrete_base_type(org.omg.CORBA.TypeCode base)
721        {
722            _ref = base;
723        }
724    
725        // Sybase-internal
726        /**
727         * @param ref
728         */
729        public void indirection(org.omg.CORBA.TypeCode ref)
730        {
731            _ref = ref;
732            _indirection = true;
733        }
734    
735        // Sybase-internal
736        /**
737         * @param id
738         */
739        public void recursive(String id)
740        {
741            _id = id;
742            _ref = null;
743            _indirection = true;
744        }
745    
746        // Sybase-internal
747        /**
748         *
749         */
750        public void fix_recursive_members()
751        {
752            String id = _id == null ? default_id() : _id;
753            int n = _member_type.length;
754            for (int i = 0; i < n; i++)
755            {
756                TypeCode mt = (TypeCode) _member_type[i];
757                if (mt._kind.value() == TCKind._tk_sequence)
758                {
759                    TypeCode ct = (TypeCode) mt._ref;
760                    if (ct._indirection
761                        &&
762                        ct._ref == null
763                        && ct._id.equals(id))
764                    {
765                        ct._ref = this;
766                    }
767                }
768            }
769        }
770    
771        // -----------------------------------------------------------------------
772        // private methods
773        // -----------------------------------------------------------------------
774        private String default_id()
775        {
776            // Take _type, and generate _id, e.g.
777            // if _type = "SessionManager::Manager",
778            // then _id = "IDL:SessionManager/Manager:1.0".
779            if (_type == null)
780            {
781                return "";
782            }
783            StringBuffer id = new StringBuffer(_type.length() + 10);
784            id.append("IDL:");
785            int n = _type.length();
786            for (int i = 0; i < n; i++)
787            {
788                char c = _type.charAt(i);
789                if (c == ':' && i + 1 < n && _type.charAt(i + 1) == ':')
790                {
791                    i++;
792                }
793                id.append(c == ':' ? '/' : c);
794            }
795            id.append(":1.0");
796            return id.toString();
797        }
798    }