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 }