KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > orb > dynany > DynUnion


1 package org.jacorb.orb.dynany;
2
3 /*
4  * JacORB - a free Java ORB
5  *
6  * Copyright (C) 1997-2004 Gerald Brose, FU Berlin.
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 org.omg.DynamicAny.NameValuePair JavaDoc;
24 import org.omg.DynamicAny.DynAnyPackage.*;
25 import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode JavaDoc;
26 import org.omg.DynamicAny.*;
27
28 import org.jacorb.orb.*;
29 import org.omg.CORBA.TCKind JavaDoc;
30
31 /**
32  * CORBA DynUnion
33  *
34  * @author (c) Gerald Brose, FU Berlin 1999
35  * $Id: DynUnion.java,v 1.24 2005/03/25 13:15:55 andre.spiegel Exp $
36  *
37  */

38
39 public final class DynUnion
40    extends DynAny
41    implements org.omg.DynamicAny.DynUnion JavaDoc
42 {
43    private org.omg.CORBA.Any JavaDoc discriminator;
44    private org.omg.DynamicAny.DynAny JavaDoc member;
45    private String JavaDoc member_name;
46    private int member_index;
47     
48    /**
49     * constructor from TypeCode
50     */

51     
52    DynUnion( org.omg.DynamicAny.DynAnyFactory JavaDoc dynFactory,
53              org.omg.CORBA.TypeCode JavaDoc tc )
54       throws InvalidValue, TypeMismatch
55    {
56       org.omg.CORBA.TypeCode JavaDoc _type = TypeCode.originalType( tc );
57
58       if( _type.kind() != org.omg.CORBA.TCKind.tk_union )
59          throw new TypeMismatch();
60
61       type = _type;
62
63       this.orb = org.omg.CORBA.ORB.init();
64       this.dynFactory = dynFactory;
65
66       pos = 0;
67       limit = 2;
68
69       try
70       {
71          for( int i = 0; i < type.member_count(); i++ )
72          {
73             discriminator = type.member_label(i);
74
75             if( discriminator.type().kind().value() !=
76                 org.omg.CORBA.TCKind._tk_octet )
77             {
78                break;
79             }
80          }
81
82          // rare case when the union only has a default case label
83
if( discriminator.type().kind().value() ==
84              org.omg.CORBA.TCKind._tk_octet )
85          {
86             try
87             {
88                set_to_unlisted_label ();
89             }
90             catch (TypeMismatch ex)
91             {
92                // should never happen
93
ex.printStackTrace ();
94             }
95          }
96
97          select_member();
98       }
99       catch( org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk )
100       {
101          bk.printStackTrace();
102       }
103       catch( org.omg.CORBA.TypeCodePackage.Bounds JavaDoc b )
104       {
105          b.printStackTrace();
106       }
107    }
108
109    DynUnion( org.omg.DynamicAny.DynAnyFactory JavaDoc dynFactory,
110            org.omg.CORBA.TypeCode JavaDoc tc, org.omg.CORBA.ORB JavaDoc orb )
111     throws InvalidValue, TypeMismatch
112    {
113     org.omg.CORBA.TypeCode JavaDoc _type = TypeCode.originalType( tc );
114
115     if( _type.kind() != org.omg.CORBA.TCKind.tk_union )
116        throw new TypeMismatch();
117
118     type = _type;
119
120     this.orb = orb;
121     this.dynFactory = dynFactory;
122
123     pos = 0;
124     limit = 2;
125
126     try
127     {
128        for( int i = 0; i < type.member_count(); i++ )
129        {
130           discriminator = type.member_label(i);
131
132           if( discriminator.type().kind().value() !=
133               org.omg.CORBA.TCKind._tk_octet )
134           {
135              break;
136           }
137        }
138
139        // rare case when the union only has a default case label
140
if( discriminator.type().kind().value() ==
141            org.omg.CORBA.TCKind._tk_octet )
142        {
143           try
144           {
145              set_to_unlisted_label ();
146           }
147           catch (TypeMismatch ex)
148           {
149              // should never happen
150
ex.printStackTrace ();
151           }
152        }
153
154        select_member();
155     }
156     catch( org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk )
157     {
158        bk.printStackTrace();
159     }
160     catch( org.omg.CORBA.TypeCodePackage.Bounds JavaDoc b )
161     {
162        b.printStackTrace();
163     }
164    }
165   
166    /**
167     * Overrides from_any() in DynAny
168     */

169
170    public void from_any( org.omg.CORBA.Any JavaDoc value )
171       throws InvalidValue, TypeMismatch
172    {
173       checkDestroyed ();
174       if( ! type().equivalent( value.type() ))
175          throw new TypeMismatch();
176
177       try
178       {
179          type = TypeCode.originalType( value.type() );
180          super.from_any( value );
181
182          limit = 2;
183          org.omg.CORBA.portable.InputStream JavaDoc is =
184             value.create_input_stream();
185
186          discriminator = org.omg.CORBA.ORB.init().create_any();
187          discriminator.type( type().discriminator_type());
188             
189          discriminator.read_value(is, type().discriminator_type());
190
191          org.omg.CORBA.Any JavaDoc member_any = null;
192          for( int i = 0; i < type ().member_count (); i++ )
193          {
194             if( type().member_label(i).equal( discriminator ))
195             {
196                member_any = org.omg.CORBA.ORB.init().create_any();
197                member_any.read_value( is, type().member_type(i) );
198                member_name = type().member_name(i);
199                member_index = i;
200                break;
201             }
202          }
203
204          if( member_any == null )
205          {
206             int def_idx = type().default_index();
207             if( def_idx != -1 )
208             {
209                member_any = org.omg.CORBA.ORB.init().create_any();
210                member_any.read_value( is, type().member_type(def_idx) );
211                member_name = type().member_name(def_idx);
212                member_index = def_idx;
213             }
214          }
215
216          if( member_any != null )
217          {
218             try
219             {
220                member = dynFactory.create_dyn_any( member_any );
221             }
222             catch( InconsistentTypeCode JavaDoc itc )
223             {
224                // should never happen
225
itc.printStackTrace();
226             }
227          }
228       }
229       catch( org.omg.CORBA.TypeCodePackage.Bounds JavaDoc b )
230       {
231          b.printStackTrace();
232       }
233       catch( org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk )
234       {
235          // should not happen anymore
236
bk.printStackTrace();
237       }
238    }
239
240    /**
241     * @return an Any that holds a copy of this union
242     */

243
244    public org.omg.CORBA.Any JavaDoc to_any()
245    {
246       checkDestroyed ();
247       CDROutputStream os = new CDROutputStream();
248
249       os.write_value( discriminator.type(),
250                       (CDRInputStream)discriminator.create_input_stream() );
251
252       os.write_value( member.type(),
253                       (CDRInputStream) member.to_any().create_input_stream());
254
255       org.jacorb.orb.Any out_any =
256          (org.jacorb.orb.Any)org.omg.CORBA.ORB.init().create_any();
257
258       out_any.type( type() );
259       out_any.read_value( new CDRInputStream( orb, os.getBufferCopy()), type());
260       return out_any;
261    }
262
263    /**
264     * Overrides component_count() in DynAny
265     */

266    public int component_count ()
267    {
268       if (has_no_active_member ())
269       {
270          return 1;
271       }
272       return limit;
273    }
274    
275    /**
276     * Overrides next() in DynAny
277     */

278    public boolean next()
279    {
280       checkDestroyed ();
281       if( pos < component_count () - 1 )
282       {
283          pos++;
284          return true;
285       }
286       pos = -1;
287       return false;
288    }
289
290    /**
291     * Overrides seek() in DynAny
292     */

293    public boolean seek(int index)
294    {
295       checkDestroyed ();
296       if( index < 0 )
297       {
298          pos = -1;
299          return false;
300       }
301       if( index < component_count () )
302       {
303          pos = index;
304          return true;
305       }
306       pos = -1;
307       return false;
308    }
309
310    
311    /**
312     * Overrides equal() in DynAny
313     */

314    public boolean equal( org.omg.DynamicAny.DynAny JavaDoc dyn_any )
315    {
316       checkDestroyed ();
317       if( !type().equal( dyn_any.type()) )
318          return false;
319
320       org.omg.DynamicAny.DynUnion JavaDoc other = DynUnionHelper.narrow( dyn_any );
321
322       if( ! get_discriminator().equal( other.get_discriminator()))
323          return false;
324
325       if( !has_no_active_member() )
326       {
327          // other must have the same here because we know the
328
// discriminators are equal
329

330          try
331          {
332             if( ! member.equal( other.member()))
333                return false;
334          }
335          catch( Exception JavaDoc e )
336          {
337             // should not happen
338
e.printStackTrace();
339          }
340       }
341       return true;
342    }
343
344
345
346    /**
347     * @return the current discriminator value
348     */

349
350    public org.omg.DynamicAny.DynAny JavaDoc get_discriminator()
351    {
352       checkDestroyed ();
353       try
354       {
355          return dynFactory.create_dyn_any( discriminator );
356       }
357       catch( InconsistentTypeCode JavaDoc itc )
358       {
359          // should never happen
360
itc.printStackTrace();
361       }
362       return null;
363    }
364
365    /**
366     * sets the discriminator to d
367     * @throws TypeMismatch if the TypeCode of the d parameter
368     * is not equivalent to the TypeCode of the union's discriminator
369     */

370
371    public void set_discriminator( org.omg.DynamicAny.DynAny JavaDoc d )
372       throws TypeMismatch
373    {
374       checkDestroyed ();
375       if( ! d.type().equivalent( discriminator.type() ))
376       {
377          throw new TypeMismatch();
378       }
379       discriminator = d.to_any();
380       pos = 1;
381       
382       /* check if the new discriminator is consistent with the
383          currently active member. If not, select a new one */

384
385       try
386       {
387          if (member_index == type.default_index ())
388          {
389             // default member, only change the member if a non-default
390
// discriminator value is specified
391
for (int i = 0; i < type.member_count (); i++)
392             {
393                if( type().member_label(i).equal( discriminator ))
394                {
395                   select_member();
396                   break;
397                }
398             }
399          }
400          else
401          {
402             // non-default member, check if the member has changed
403
if( ! type().member_label( member_index ).equal( discriminator ))
404                select_member();
405          }
406       }
407       catch( org.omg.CORBA.TypeCodePackage.Bounds JavaDoc b )
408       {
409          b.printStackTrace();
410       }
411       catch( org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk )
412       {
413          bk.printStackTrace();
414       }
415
416       // set the current position to zero if there is no active member
417
if (has_no_active_member ())
418       {
419          pos = 0;
420       }
421    }
422
423    /**
424     * updates the private instance variables member, member_name and
425     * member_index according to the current discriminator value
426     */

427
428    private void select_member()
429    {
430       member = null;
431       try
432       {
433          /* search through all members and compare their label with
434             the discriminator */

435          for( int i = 0; i < type().member_count(); i++ )
436          {
437             if( type().member_label(i).equal( discriminator ))
438             {
439                try
440                {
441                   member =
442                      dynFactory.create_dyn_any_from_type_code(
443                                                               type().member_type(i));
444                }
445                catch( InconsistentTypeCode JavaDoc itc )
446                {
447                   itc.printStackTrace();
448                }
449                member_name = type().member_name(i);
450                member_index = i;
451                break;
452             }
453          }
454
455          /* none found, use default, if there is one */
456
457          if( member == null )
458          {
459             int def_idx = type().default_index();
460             if( def_idx != -1 )
461             {
462                try
463                {
464                   member =
465                      dynFactory.create_dyn_any_from_type_code(type().member_type(def_idx));
466                }
467                catch( InconsistentTypeCode JavaDoc itc )
468                {
469                   itc.printStackTrace();
470                }
471                member_name = type().member_name(def_idx);
472                member_index = def_idx;
473             }
474          }
475       }
476       catch( org.omg.CORBA.TypeCodePackage.Bounds JavaDoc b )
477       {
478          b.printStackTrace();
479       }
480       catch( org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk )
481       {
482          // should not happen anymore
483
bk.printStackTrace();
484       }
485    }
486
487    /**
488     * sets the discriminator to a value that is consistent with the
489     * value of the default case of a union; it sets the current
490     * position to zero and causes component_count to return 2.
491     *
492     * @throws TypeMismatch if the union does not have an explicit
493     * default case.
494     */

495
496    public void set_to_default_member()
497       throws TypeMismatch
498    {
499       checkDestroyed ();
500       try
501       {
502          int def_idx = type().default_index();
503          if( def_idx == -1 )
504             throw new TypeMismatch();
505          pos = 0;
506
507          // do nothing if the discriminator is already set to a default value
508
if (member_index != def_idx)
509          {
510             try
511             {
512                set_to_unlisted_label ();
513             }
514             catch (TypeMismatch ex)
515             {
516                // should never happen
517
ex.printStackTrace ();
518             }
519             select_member();
520          }
521       }
522       catch( org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk )
523       {
524          // should not happen anymore
525
bk.printStackTrace();
526       }
527    }
528
529    /**
530     * sets the discriminator to a value that does not correspond to
531     * any of the union's case labels; it sets the current position
532     * to zero and causes component_count to return 1.
533     *
534     * @throws TypeMismatch if the union has an explicit default
535     * case or uses the entire range of discriminator values for
536     * explicit case labels.
537     */

538
539    public void set_to_no_active_member()
540       throws TypeMismatch
541    {
542       checkDestroyed ();
543       try
544       {
545          /* if there is a default index, we do have active members */
546          if( type().default_index() != -1 )
547             throw new TypeMismatch();
548          pos = 0;
549
550          // do nothing if discriminator is already set to no active member
551
if (!has_no_active_member ())
552          {
553             set_to_unlisted_label ();
554          }
555       }
556       catch( org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk )
557       {
558          // should not happen anymore
559
bk.printStackTrace();
560       }
561    }
562
563    /* find a discriminator value that is not an explicit case label */
564    private void set_to_unlisted_label ()
565       throws TypeMismatch
566    {
567       try
568       {
569          switch( type().discriminator_type().kind().value() )
570          {
571          case TCKind._tk_boolean:
572             {
573                boolean found;
574                boolean cur_bool;
575                org.omg.CORBA.Any JavaDoc check_val = null;
576                org.omg.CORBA.Any JavaDoc cur_label = null;
577
578                for (int i = 0; i < 2; i++)
579                {
580                   if (i == 0)
581                   {
582                      cur_bool = true;
583                   }
584                   else
585                   {
586                      cur_bool = false;
587                   }
588                   check_val = orb.create_any ();
589                   check_val.insert_boolean (cur_bool);
590
591                   found = false; // is the value used as a label?
592
for( int j = 0; j < type().member_count() && !found; j++ )
593                   {
594                      if( check_val.equal( type().member_label(j)) )
595                      {
596                         found = true;
597                      }
598                   }
599                
600                   if( !found )
601                   {
602                      // the value is not found among the union's label
603
discriminator = check_val;
604                      return;
605                   }
606                }
607                // no unused value found
608
throw new TypeMismatch();
609             }
610          case TCKind._tk_char:
611             {
612                // assume there is a printable char not used as a label!
613
boolean found;
614                org.omg.CORBA.Any JavaDoc check_val = null;
615                org.omg.CORBA.Any JavaDoc cur_label = null;
616
617                // 33 to 126 defines a reasonable set of printable chars
618
for (int i = 0; i < 127; i++)
619                {
620                   check_val = orb.create_any ();
621                   check_val.insert_char ((char) i);
622
623                   found = false; // is the value used as a label?
624
for( int j = 0; j < type().member_count() && !found; j++ )
625                   {
626                      if( check_val.equal( type().member_label(j)) )
627                      {
628                         found = true;
629                      }
630                   }
631
632                   if( !found )
633                   {
634                      // the value is not found among the union's label
635
discriminator = check_val;
636                      return;
637                   }
638                }
639                // no unused value found, should not happen
640
throw new TypeMismatch();
641             }
642          case TCKind._tk_short:
643             {
644                // assume there is an unsigned short not used as a label!
645
boolean found;
646                org.omg.CORBA.Any JavaDoc check_val = null;
647                org.omg.CORBA.Any JavaDoc cur_label = null;
648
649                short max_short = 32767;
650                for (short i = 0; i < max_short; i++)
651                {
652                   check_val = orb.create_any ();
653                   check_val.insert_short (i);
654
655                   found = false; // is the value used as a label?
656
for( int j = 0; j < type().member_count() && !found; j++ )
657                   {
658                      if( check_val.equal( type().member_label(j)) )
659                      {
660                         found = true;
661                      }
662                   }
663
664                   if( !found )
665                   {
666                      // the value is not found among the union's label
667
discriminator = check_val;
668                      return;
669                   }
670                }
671                // no unused value found, should not happen
672
throw new TypeMismatch();
673             }
674          case TCKind._tk_long:
675             {
676                // assume there is an unsigned int not used as a label!
677
boolean found;
678                org.omg.CORBA.Any JavaDoc check_val = null;
679                org.omg.CORBA.Any JavaDoc cur_label = null;
680
681                int max_int = 2147483647;
682                for (int i = 0; i < max_int; i++)
683                {
684                   check_val = orb.create_any ();
685                   check_val.insert_long (i);
686
687                   found = false; // is the value used as a label?
688
for( int j = 0; j < type().member_count() && !found; j++ )
689                   {
690                      if( check_val.equal( type().member_label(j)) )
691                      {
692                         found = true;
693                      }
694                   }
695
696                   if( !found )
697                   {
698                      // the value is not found among the union's label
699
discriminator = check_val;
700                      return;
701                   }
702                }
703                // no unused value found, should not happen
704
throw new TypeMismatch();
705             }
706          case TCKind._tk_longlong:
707             {
708                // assume there is an unsigned long not used as a label!
709
boolean found;
710                org.omg.CORBA.Any JavaDoc check_val = null;
711                org.omg.CORBA.Any JavaDoc cur_label = null;
712
713                long max_long = 2147483647; // this should be sufficient!
714
for (long i = 0; i < max_long; i++)
715                {
716                   check_val = orb.create_any ();
717                   check_val.insert_longlong (i);
718
719                   found = false; // is the value used as a label?
720
for( int j = 0; j < type().member_count() && !found; j++ )
721                   {
722                      if( check_val.equal( type().member_label(j)) )
723                      {
724                         found = true;
725                      }
726                   }
727
728                   if( !found )
729                   {
730                      // the value is not found among the union's label
731
discriminator = check_val;
732                      return;
733                   }
734                }
735                // no unused value found, should not happen
736
throw new TypeMismatch();
737             }
738          case TCKind._tk_enum:
739             {
740                org.omg.DynamicAny.DynEnum JavaDoc dynEnum = null;
741                try
742                {
743                   dynEnum = (org.omg.DynamicAny.DynEnum JavaDoc) dynFactory.create_dyn_any_from_type_code (discriminator.type());
744                }
745                catch( InconsistentTypeCode JavaDoc it )
746                {
747                   it.printStackTrace();
748                }
749
750                boolean found;
751                for( int i = 0; i < discriminator.type().member_count(); i++ )
752                {
753                   try
754                   {
755                      dynEnum.set_as_string( discriminator.type().member_name(i) );
756                   }
757                   catch( InvalidValue iv )
758                   {
759                      // should not happen anymore
760
iv.printStackTrace();
761                   }
762
763                   found = false; // is the value used as a label?
764
for( int j = 0; j < type().member_count() && !found; j++ )
765                   {
766                      if( dynEnum.to_any ().equal( type().member_label(j) ) )
767                      {
768                         found = true;
769                      }
770                   }
771
772                   if( !found )
773                   {
774                      // the enum value is not found among the union's label
775
discriminator = dynEnum.to_any();
776                      return;
777                   }
778                }
779                // no unused value found
780
throw new TypeMismatch();
781             }
782          default:
783             throw new TypeMismatch();
784          }
785       }
786       catch (org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk)
787       {
788          // should never happen
789
bk.printStackTrace ();
790       }
791       catch (org.omg.CORBA.TypeCodePackage.Bounds JavaDoc b)
792       {
793          // should never happen
794
b.printStackTrace ();
795       }
796    }
797    
798    /**
799     * @return true, if the union has no active member (that is, the
800     * union's value consists solely of its discriminator because
801     * the discriminator has a value that is not listed as an explicit
802     * case label). Calling this operation on a union that has a
803     * default case returns false. Calling this operation on a union
804     * that uses the entire range of discriminator values for explicit
805     * case labels returns false.
806     */

807
808   public boolean has_no_active_member()
809    {
810       checkDestroyed ();
811       try
812       {
813          if( type().default_index() != -1 )
814          {
815             return false;
816          }
817
818          for( int i = 0; i < type.member_count(); i++ )
819          {
820             if( discriminator.equal( type.member_label(i) ))
821             {
822                return false;
823             }
824          }
825          return true;
826       }
827       catch( org.omg.CORBA.TypeCodePackage.Bounds JavaDoc b )
828       {
829          // should not happen anymore
830
b.printStackTrace();
831       }
832       catch( org.omg.CORBA.TypeCodePackage.BadKind JavaDoc bk )
833       {
834          // should not happen anymore
835
bk.printStackTrace();
836       }
837       return( member == null );
838    }
839
840    /**
841     * @return the TCKind value of the discriminator's TypeCode.
842     */

843
844    public org.omg.CORBA.TCKind JavaDoc discriminator_kind()
845    {
846       checkDestroyed ();
847       return discriminator.type().kind();
848    }
849
850    /**
851     * @return the currently active member.
852     * @throws InvalidValue if the union has no active member
853     */

854
855    public org.omg.DynamicAny.DynAny JavaDoc member()
856       throws InvalidValue
857    {
858       checkDestroyed ();
859       if( has_no_active_member() )
860          throw new InvalidValue();
861
862       return member;
863    }
864
865    /**
866     * @return the TypeCode kind of the currently active member.
867     * @throws InvalidValue if the union has no active member
868     */

869
870    public org.omg.CORBA.TCKind JavaDoc member_kind()
871       throws InvalidValue
872    {
873       checkDestroyed ();
874       if( has_no_active_member() )
875          throw new InvalidValue();
876
877       return member.type().kind();
878    }
879
880    /**
881     * @return the name of the currently active member.
882     * @throws InvalidValue if the union has no active member
883     */

884
885    public String JavaDoc member_name()
886       throws InvalidValue
887    {
888       checkDestroyed ();
889       if( has_no_active_member() )
890          throw new InvalidValue();
891       return member_name;
892    }
893
894    public void destroy()
895    {
896       super.destroy();
897       discriminator = null;
898       member = null;
899       member_name = null;
900       member_index = -1;
901    }
902
903    /* iteration interface */
904
905    public org.omg.DynamicAny.DynAny JavaDoc current_component()
906    {
907       checkDestroyed ();
908       if( pos == -1 )
909          return null;
910
911       if( pos == 0 )
912          return get_discriminator();
913       else
914       {
915          try
916          {
917             return member();
918          }
919          catch( org.omg.DynamicAny.DynAnyPackage.InvalidValue JavaDoc iv )
920          {
921             iv.printStackTrace();
922          }
923          return null;
924       }
925    }
926
927 }
928
Popular Tags