Source for gnu.CORBA.gnuAny

   1: /* gnuAny.java --
   2:    Copyright (C) 2005 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package gnu.CORBA;
  40: 
  41: import gnu.CORBA.CDR.Vio;
  42: import gnu.CORBA.CDR.BufferredCdrInput;
  43: import gnu.CORBA.CDR.BufferedCdrOutput;
  44: import gnu.CORBA.typecodes.PrimitiveTypeCode;
  45: import gnu.CORBA.typecodes.StringTypeCode;
  46: 
  47: import org.omg.CORBA.Any;
  48: import org.omg.CORBA.AnyHolder;
  49: import org.omg.CORBA.BAD_OPERATION;
  50: import org.omg.CORBA.BooleanHolder;
  51: import org.omg.CORBA.CharHolder;
  52: import org.omg.CORBA.DoubleHolder;
  53: import org.omg.CORBA.FixedHolder;
  54: import org.omg.CORBA.FloatHolder;
  55: import org.omg.CORBA.IntHolder;
  56: import org.omg.CORBA.LongHolder;
  57: import org.omg.CORBA.MARSHAL;
  58: import org.omg.CORBA.ORB;
  59: import org.omg.CORBA.ObjectHolder;
  60: import org.omg.CORBA.Principal;
  61: import org.omg.CORBA.PrincipalHolder;
  62: import org.omg.CORBA.ShortHolder;
  63: import org.omg.CORBA.StringHolder;
  64: import org.omg.CORBA.TCKind;
  65: import org.omg.CORBA.TypeCode;
  66: import org.omg.CORBA.TypeCodeHolder;
  67: import org.omg.CORBA.ValueBaseHolder;
  68: import org.omg.CORBA.portable.Streamable;
  69: 
  70: import java.io.Serializable;
  71: import java.lang.reflect.Field;
  72: import java.math.BigDecimal;
  73: import java.util.Arrays;
  74: import java.util.zip.Adler32;
  75: 
  76: /**
  77:  * The implementation of {@link Any}.
  78:  *
  79:  * For performance reasonse, the inserted values are not cloned.
  80:  * If the value object allows modifications (like {@link Streamable}),
  81:  * these subsequent alterations are reflected by the instance of
  82:  * this gnuAny, and the gnuAny alterations are reflected by the
  83:  * returned value. If it is required to have the uncoupled value,
  84:  * it must be requested from the copy of the current instance.
  85:  * The {@link gnuAny} can be simply cloned by the provided
  86:  * {@link Clone()} method.
  87:  *
  88:  * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
  89:  */
  90: public class gnuAny
  91:   extends Any
  92: {
  93:   /**
  94:    * Use serialVersionUID for interoperability.
  95:    */
  96:   private static final long serialVersionUID = 1;
  97: 
  98:   /**
  99:    * The value, returned by {@link #type()} if the value has been
 100:    * not intialized.
 101:    */
 102:   protected static final TypeCode nullType =
 103:     new PrimitiveTypeCode(TCKind.tk_null);
 104: 
 105:   /**
 106:    * The Streamable, representing the value, held by this gnuAny.
 107:    */
 108:   protected Streamable has;
 109: 
 110:   /**
 111:    * The complete typecode of the Streamable, if explicitly set.
 112:    */
 113:   protected TypeCode typecode;
 114: 
 115:   /**
 116:    * The typecode kind of the Streamable, if explicitly set.
 117:    */
 118:   protected int xKind = -1;
 119: 
 120:   /**
 121:    * The associated ORB.
 122:    */
 123:   private ORB orb;
 124: 
 125:   /**
 126:    * Set the associated orb.
 127:    */
 128:   public void setOrb(ORB an_orb)
 129:   {
 130:     orb = an_orb;
 131:   }
 132: 
 133:   /**
 134:    * Creates a deep copy of this gnuAny, writing to and subsequently
 135:    * reading from from the byte buffer.
 136:    *
 137:    * @return the uncoupled gnuAny with all fields set to identical
 138:    * values.
 139:    */
 140:   public gnuAny Clone()
 141:   {
 142:     BufferedCdrOutput out = new BufferedCdrOutput();
 143:     out.setOrb(orb);
 144:     out.write_any(this);
 145: 
 146:     BufferredCdrInput in = new BufferredCdrInput(out.buffer.toByteArray());
 147:     in.setOrb(orb);
 148:     return (gnuAny) in.read_any();
 149:   }
 150: 
 151:   /**
 152:    * Create the buffered CDR input stream, containing the
 153:    * value, stored inside of this {@link Any}.
 154:    */
 155:   public org.omg.CORBA.portable.InputStream create_input_stream()
 156:   {
 157:     if (has instanceof GeneralHolder)
 158:       {
 159:         GeneralHolder u = (GeneralHolder) has;
 160:         return u.getInputStream();
 161:       }
 162:     else
 163:       {
 164:         BufferedCdrOutput out = new BufferedCdrOutput();
 165:         out.setOrb(orb);
 166:         write_value(out);
 167: 
 168:         BufferredCdrInput in = new BufferredCdrInput(out.buffer.toByteArray());
 169:         in.setOrb(orb);
 170:         return in;
 171:       }
 172:   }
 173: 
 174:   /**
 175:    * Create the buffered CDR output stream (empty).
 176:    */
 177:   public org.omg.CORBA.portable.OutputStream create_output_stream()
 178:   {
 179:     BufferedCdrOutput stream = new BufferedCdrOutput();
 180:     stream.setOrb(orb);
 181:     return stream;
 182:   }
 183: 
 184:   /**
 185:    * Compare two Any's for equality.
 186:    * @param other the other Any to compare.
 187:    */
 188:   public boolean equal(Any other)
 189:   {
 190:     if (other == this)
 191:       return true;
 192:     if (type().kind() != other.type().kind())
 193:       return false;
 194: 
 195:     if (has != null && other instanceof gnuAny)
 196:       if (has.equals(((gnuAny) other).has))
 197:         return true;
 198: 
 199:     BufferedCdrOutput a = new BufferedCdrOutput();
 200:     a.setOrb(orb);
 201:     write_value(a);
 202: 
 203:     BufferedCdrOutput b = new BufferedCdrOutput();
 204:     b.setOrb(orb);
 205:     other.write_value(b);
 206: 
 207:     byte[] ba = a.buffer.toByteArray();
 208:     byte[] bb = b.buffer.toByteArray();
 209: 
 210:     return Arrays.equals(ba, bb);
 211:   }
 212: 
 213:   /**
 214:    * Get the content - dependent hashcode.
 215:    */
 216:   public int hashCode()
 217:   {
 218:     if (has == null)
 219:       return type().kind().value();
 220:     else
 221:       {
 222:         Adler32 adler = new Adler32();
 223: 
 224:         BufferedCdrOutput a = new BufferedCdrOutput();
 225:         a.setOrb(orb);
 226:         write_value(a);
 227: 
 228:         adler.update(a.buffer.toByteArray());
 229:         adler.update(type().kind().value());
 230: 
 231:         return (int) adler.getValue() & Integer.MAX_VALUE;
 232:       }
 233:   }
 234: 
 235:   /**
 236:    * Delegates functionality to {@link #equal(Any)}.
 237:    */
 238:   public boolean equals(java.lang.Object other)
 239:   {
 240:     if (other == this)
 241:       return true;
 242:     if (!(other instanceof Any))
 243:       return false;
 244: 
 245:     return equal((Any) other);
 246:   }
 247: 
 248:   /**
 249:    * Extract the previously stored object.
 250:    */
 251:   public org.omg.CORBA.Object extract_Object()
 252:   {
 253:     try
 254:       {
 255:         return ((ObjectHolder) has).value;
 256:       }
 257:     catch (ClassCastException ex)
 258:       {
 259:         BAD_OPERATION bad = new BAD_OPERATION();
 260:         bad.initCause(ex);
 261:         bad.minor = Minor.Any;
 262:         throw bad;
 263:       }
 264:   }
 265: 
 266:   /**
 267:    * Extract the previously inserted CORBA <code>Principal</code>/
 268:    * @return the previously inserted value.
 269:    *
 270:    * @throws org.omg.CORBA.BAD_OPERATION if the holder contains something
 271:    * else than Principal.
 272:    *
 273:    * @deprecated by CORBA 2.2.
 274:    */
 275:   public Principal extract_Principal()
 276:   {
 277:     check(TCKind._tk_Principal);
 278:     return ((PrincipalHolder) has).value;
 279:   }
 280: 
 281:   /**
 282:    * Return the value, encapsulated in a suitable holder.
 283:    * This implementation returns the direct reference,
 284:    * so the alterations on the returned streamable are
 285:    * directly reflected to the content of this {@link Any}.
 286:    */
 287:   public Streamable extract_Streamable()
 288:   {
 289:     return has;
 290:   }
 291: 
 292:   public TypeCode extract_TypeCode()
 293:                             throws BAD_OPERATION
 294:   {
 295:     check(TCKind._tk_TypeCode);
 296:     return ((TypeCodeHolder) has).value;
 297:   }
 298: 
 299:   /**
 300:    * Extract the stored value type.
 301:    *
 302:    * @return the previously stored value type.
 303:    *
 304:    * @throws BAD_OPERATION if the Any contains something different.
 305:    *
 306:    * @see org.omg.CORBA.portable.ValueBase
 307:    */
 308:   public Serializable extract_Value()
 309:                              throws BAD_OPERATION
 310:   {
 311:     try
 312:       {
 313:         if (has instanceof ValueBaseHolder)
 314:           return ((ValueBaseHolder) has).value;
 315:         else
 316:           {
 317:             // Normally, ValueBase holder must be an instance of the
 318:             // ValueBaseHolder. However some IDL compilers probably
 319:             // have a bug, do not deriving this way. The the only
 320:             // way to access the wrapped value is via reflection.
 321:             Field f = has.getClass().getField("value");
 322:             return (Serializable) f.get(has);
 323:           }
 324:       }
 325:     catch (Exception ex)
 326:       {
 327:         BAD_OPERATION bad = new BAD_OPERATION("Value type expected");
 328:         bad.minor = Minor.Any;
 329:         bad.initCause(ex);
 330:         throw bad;
 331:       }
 332:   }
 333: 
 334:   /** {@inheritDoc} */
 335:   public Any extract_any()
 336:                   throws BAD_OPERATION
 337:   {
 338:     check(TCKind._tk_any);
 339:     return ((AnyHolder) has).value;
 340:   }
 341: 
 342:   /** {@inheritDoc} */
 343:   public boolean extract_boolean()
 344:                           throws BAD_OPERATION
 345:   {
 346:     check(TCKind._tk_boolean);
 347:     return ((BooleanHolder) has).value;
 348:   }
 349: 
 350:   /** {@inheritDoc} */
 351:   public char extract_char()
 352:                     throws BAD_OPERATION
 353:   {
 354:     check(TCKind._tk_char);
 355:     return ((CharHolder) has).value;
 356:   }
 357: 
 358:   /** {@inheritDoc} */
 359:   public double extract_double()
 360:                         throws BAD_OPERATION
 361:   {
 362:     check(TCKind._tk_double);
 363:     return ((DoubleHolder) has).value;
 364:   }
 365: 
 366:   /**
 367:    * Extract the previously inserted CORBA <code>fixed</code>/
 368:    * @return the previously inserted value.
 369:    *
 370:    * @throws org.omg.CORBA.BAD_OPERATION if the holder contains something
 371:    * else than BigDecimal.
 372:    */
 373:   public BigDecimal extract_fixed()
 374:                            throws org.omg.CORBA.BAD_OPERATION
 375:   {
 376:     check(TCKind._tk_fixed);
 377:     return ((FixedHolder) has).value;
 378:   }
 379: 
 380:   /** {@inheritDoc} */
 381:   public float extract_float()
 382:                       throws BAD_OPERATION
 383:   {
 384:     check(TCKind._tk_float);
 385:     return ((FloatHolder) has).value;
 386:   }
 387: 
 388:   /** {@inheritDoc} */
 389:   public int extract_long()
 390:                    throws BAD_OPERATION
 391:   {
 392:     // CORBA long = java int.
 393:     check(TCKind._tk_long);
 394:     return ((IntHolder) has).value;
 395:   }
 396: 
 397:   /** {@inheritDoc} */
 398:   public long extract_longlong()
 399:                         throws BAD_OPERATION
 400:   {
 401:     check(TCKind._tk_longlong);
 402:     return ((LongHolder) has).value;
 403:   }
 404: 
 405:   /** {@inheritDoc} */
 406:   public byte extract_octet()
 407:                      throws BAD_OPERATION
 408:   {
 409:     // ShortHolder holds also octets.
 410:     check(TCKind._tk_octet);
 411:     return (byte) ((OctetHolder) has).value;
 412:   }
 413: 
 414:   /** {@inheritDoc} */
 415:   public short extract_short()
 416:                       throws BAD_OPERATION
 417:   {
 418:     check(TCKind._tk_short);
 419:     return ((ShortHolder) has).value;
 420:   }
 421: 
 422:   /** {@inheritDoc} */
 423:   public String extract_string()
 424:                         throws BAD_OPERATION
 425:   {
 426:     check(TCKind._tk_string);
 427:     return ((StringHolder) has).value;
 428:   }
 429: 
 430:   /** {@inheritDoc} */
 431:   public int extract_ulong()
 432:                     throws BAD_OPERATION
 433:   {
 434:     // IntHolder also holds ulongs.
 435:     check(TCKind._tk_ulong);
 436:     return ((IntHolder) has).value;
 437:   }
 438: 
 439:   /** {@inheritDoc} */
 440:   public long extract_ulonglong()
 441:                          throws BAD_OPERATION
 442:   {
 443:     // LongHolder also holds ulonglong
 444:     check(TCKind._tk_ulonglong);
 445:     return ((LongHolder) has).value;
 446:   }
 447: 
 448:   /** {@inheritDoc} */
 449:   public short extract_ushort()
 450:                        throws BAD_OPERATION
 451:   {
 452:     // ShortHolder also holds ushorts.
 453:     check(TCKind._tk_ushort);
 454:     return ((ShortHolder) has).value;
 455:   }
 456: 
 457:   /** {@inheritDoc} */
 458:   public char extract_wchar()
 459:                      throws BAD_OPERATION
 460:   {
 461:     check(TCKind._tk_wchar);
 462:     return ((WCharHolder) has).value;
 463:   }
 464: 
 465:   /** {@inheritDoc} */
 466:   public String extract_wstring()
 467:                          throws BAD_OPERATION
 468:   {
 469:     // StringHolder also holds wstrings.
 470:     check(TCKind._tk_wstring);
 471:     return ((WStringHolder) has).value;
 472:   }
 473: 
 474:   /**
 475:    * Inserts the CORBA object and sets the typecode to the given type.
 476:    */
 477:   public void insert_Object(org.omg.CORBA.Object x, TypeCode typecode)
 478:   {
 479:     has = new ObjectHolder(x);
 480:     type(typecode);
 481:   }
 482: 
 483:   /**
 484:    * Inserts the CORBA object.
 485:    */
 486:   public void insert_Object(org.omg.CORBA.Object x)
 487:   {
 488:     has = new ObjectHolder(x);
 489:   }
 490: 
 491:   /**
 492:    * Insert the CORBA Principal.
 493:    * This implementation uses direct assignment, so the later
 494:    * alterations of that BigDecimal are reflected on the
 495:    * content of this {@link Any}.
 496:    *
 497:    * @deprecated by CORBA 2.2.
 498:    */
 499:   public void insert_Principal(Principal x)
 500:   {
 501:     resetTypes();
 502:     if (has instanceof PrincipalHolder)
 503:       ((PrincipalHolder) has).value = x;
 504:     else
 505:       has = new PrincipalHolder(x);
 506:   }
 507: 
 508:   /**
 509:    * Sets the value to the value, encapsulated in this holder.
 510:    * This implementation uses direct assignment, so the later
 511:    * alterations of that streamable are reflected on the
 512:    * content of this {@link Any}.
 513:    */
 514:   public void insert_Streamable(Streamable x)
 515:   {
 516:     resetTypes();
 517:     has = x;
 518:   }
 519: 
 520:   /**
 521:    * Insert the typecode into this Any
 522:    * @param typecode the typecode to insert.
 523:    */
 524:   public void insert_TypeCode(TypeCode typecode)
 525:   {
 526:     resetTypes();
 527:     if (has instanceof TypeCodeHolder)
 528:       ((TypeCodeHolder) has).value = typecode;
 529:     else
 530:       has = new TypeCodeHolder(typecode);
 531:   }
 532: 
 533:   /** {@inheritDoc} */
 534:   public void insert_Value(Serializable x, TypeCode c_typecode)
 535:   {
 536:     if (typecode != null && typecode.kind() == TCKind.tk_value_box)
 537:       {
 538:         has = new gnuValueHolder(x, typecode);
 539:       }
 540:     else
 541:       {
 542:         type(typecode);
 543:         insert_Value(x);
 544:       }
 545:   }
 546: 
 547:   /** {@inheritDoc} */
 548:   public void insert_Value(Serializable x)
 549:   {
 550:     if (typecode != null && typecode.kind() == TCKind.tk_value_box)
 551:       {
 552:         has = new gnuValueHolder(x, typecode);
 553:       }
 554:     else
 555:       {
 556:         if (has instanceof ValueBaseHolder)
 557:           ((ValueBaseHolder) has).value = x;
 558:         else
 559:           has = new ValueBaseHolder(x);
 560:       }
 561:   }
 562: 
 563:   /**
 564:   * Insert another {@link Any} into this {@link Any}.
 565:   * This implementation uses direct assignment, so the later
 566:   * alterations of that {@link Any} are reflected on the
 567:   * content of this {@link Any}.
 568:   */
 569:   public void insert_any(Any an_any)
 570:   {
 571:     resetTypes();
 572:     if (has instanceof AnyHolder)
 573:       ((AnyHolder) has).value = an_any;
 574:     else
 575:       has = new AnyHolder(an_any);
 576:   }
 577: 
 578:   /** {@inheritDoc} */
 579:   public void insert_boolean(boolean x)
 580:   {
 581:     resetTypes();
 582:     if (has instanceof BooleanHolder)
 583:       ((BooleanHolder) has).value = x;
 584:     else
 585:       has = new BooleanHolder(x);
 586:   }
 587: 
 588:   /** {@inheritDoc} */
 589:   public void insert_char(char x)
 590:   {
 591:     resetTypes();
 592:     if (has instanceof CharHolder)
 593:       ((CharHolder) has).value = x;
 594:     else
 595:       has = new CharHolder(x);
 596:   }
 597: 
 598:   /** {@inheritDoc} */
 599:   public void insert_double(double x)
 600:   {
 601:     resetTypes();
 602:     if (has instanceof DoubleHolder)
 603:       ((DoubleHolder) has).value = x;
 604:     else
 605:       has = new DoubleHolder(x);
 606:   }
 607: 
 608:   /**
 609:    * Inserts the CORBA <code>fixed</code>, setting the typecode
 610:    * explicitly.
 611:    * This implementation uses direct assignment, so the later
 612:    * alterations of that BigDecimal are reflected on the
 613:    * content of this {@link Any}.
 614:    */
 615:   public void insert_fixed(BigDecimal x, TypeCode x_typecode)
 616:   {
 617:     resetTypes();
 618:     insert_fixed(x);
 619:     typecode = x_typecode;
 620:   }
 621: 
 622:   /**
 623:    * Inserts the CORBA <code>fixed</code>, setting the typecode
 624:    * by example of the currently passed value.
 625:    * This implementation uses direct assignment, so the later
 626:    * alterations of that BigDecimal are reflected on the
 627:    * content of this {@link Any}, including the typecode.
 628:    */
 629:   public void insert_fixed(BigDecimal x)
 630:   {
 631:     resetTypes();
 632:     if (has instanceof FixedHolder)
 633:       ((FixedHolder) has).value = x;
 634:     else
 635:       has = new FixedHolder(x);
 636:   }
 637: 
 638:   /** {@inheritDoc} */
 639:   public void insert_float(float x)
 640:   {
 641:     resetTypes();
 642:     if (has instanceof FloatHolder)
 643:       ((FloatHolder) has).value = x;
 644:     else
 645:       has = new FloatHolder(x);
 646:   }
 647: 
 648:   /** {@inheritDoc} */
 649:   public void insert_long(int x)
 650:   {
 651:     resetTypes();
 652:     if (has instanceof IntHolder)
 653:       ((IntHolder) has).value = x;
 654:     else
 655:       has = new IntHolder(x);
 656:   }
 657: 
 658:   /** {@inheritDoc} */
 659:   public void insert_longlong(long x)
 660:   {
 661:     resetTypes();
 662:     if (has instanceof LongHolder)
 663:       ((LongHolder) has).value = x;
 664:     else
 665:       has = new LongHolder(x);
 666:   }
 667: 
 668:   /** {@inheritDoc} */
 669:   public void insert_octet(byte x)
 670:   {
 671:     resetTypes();
 672:     if (has instanceof OctetHolder)
 673:       ((OctetHolder) has).value = x;
 674:     else
 675:       has = new OctetHolder(x);
 676:   }
 677: 
 678:   /** {@inheritDoc} */
 679:   public void insert_short(short x)
 680:   {
 681:     resetTypes();
 682:     if (has instanceof ShortHolder)
 683:       ((ShortHolder) has).value = x;
 684:     else
 685:       has = new ShortHolder(x);
 686:   }
 687: 
 688:   /** {@inheritDoc} */
 689:   public void insert_string(String x)
 690:   {
 691:     resetTypes();
 692:     if (has instanceof StringHolder)
 693:       ((StringHolder) has).value = x;
 694:     else
 695:       has = new StringHolder(x);
 696: 
 697:     typecode = new StringTypeCode(TCKind.tk_string);
 698:   }
 699: 
 700:   /** {@inheritDoc} */
 701:   public void insert_ulong(int x)
 702:   {
 703:     resetTypes();
 704:     if (has instanceof IntHolder)
 705:       ((IntHolder) has).value = x;
 706:     else
 707:       has = new IntHolder(x);
 708:     xKind = TCKind._tk_ulong;
 709:   }
 710: 
 711:   /** {@inheritDoc} */
 712:   public void insert_ulonglong(long x)
 713:   {
 714:     resetTypes();
 715:     if (has instanceof LongHolder)
 716:       ((LongHolder) has).value = x;
 717:     else
 718:       has = new LongHolder(x);
 719:     xKind = TCKind._tk_ulonglong;
 720:   }
 721: 
 722:   /** {@inheritDoc} */
 723:   public void insert_ushort(short x)
 724:   {
 725:     resetTypes();
 726:     if (has instanceof ShortHolder)
 727:       ((ShortHolder) has).value = x;
 728:     else
 729:       has = new ShortHolder(x);
 730:     xKind = TCKind._tk_ushort;
 731:   }
 732: 
 733:   /** {@inheritDoc} */
 734:   public void insert_wchar(char x)
 735:   {
 736:     resetTypes();
 737:     if (has instanceof WCharHolder)
 738:       ((WCharHolder) has).value = x;
 739:     else
 740:       has = new WCharHolder(x);
 741:   }
 742: 
 743:   /** {@inheritDoc} */
 744:   public void insert_wstring(String x)
 745:   {
 746:     resetTypes();
 747:     if (has instanceof WStringHolder)
 748:       ((WStringHolder) has).value = x;
 749:     else
 750:       has = new WStringHolder(x);
 751:   }
 752: 
 753:   /**
 754:    * Return the associated orb.
 755:    */
 756:   public ORB orb()
 757:   {
 758:     return orb;
 759:   }
 760: 
 761:   /**
 762:    * Read the value of the given type from the given stream.
 763:    *
 764:    * @param input a stream to read from.
 765:    * @param a_type a typecode of the value to read.
 766:    */
 767:   public void read_value(org.omg.CORBA.portable.InputStream input,
 768:                          TypeCode a_type
 769:                         )
 770:                   throws MARSHAL
 771:   {
 772:     try
 773:       {
 774:         int kind = a_type.kind().value();
 775: 
 776:         // Fixed needs special handling.
 777:         if (kind == TCKind._tk_fixed)
 778:           {
 779:             BigDecimal dec = BigDecimalHelper.read(input, a_type.fixed_scale());
 780:             has = new FixedHolder(dec);
 781:           }
 782:         else
 783:           {
 784:             has = HolderLocator.createHolder(a_type);
 785:             if (has == null)
 786:               {
 787:                 // Use the Universal Holder that reads till the end of stream.
 788:                 // This works with the extract/insert pair of the typical
 789:                 // Helper.
 790:                 BufferedCdrOutput buffer = new BufferedCdrOutput();
 791:                 buffer.setOrb(orb);
 792:                 has = new GeneralHolder(buffer);
 793:               }
 794:           }
 795:         type(a_type);
 796: 
 797:         if (!(has instanceof GeneralHolder) &&
 798:             (kind == TCKind._tk_value_box))
 799:           {
 800:             // The streamable only contains operations for
 801:             // reading the value, not the value header.
 802:             Field vField = has.getClass().getField("value");
 803: 
 804:             Object content = Vio.read(input, a_type.id());
 805:             vField.set(has, content);
 806:           }
 807:         else
 808:           has._read(input);
 809:       }
 810:     catch (Exception ex)
 811:       {
 812:         MARSHAL m = new MARSHAL();
 813:         m.minor = Minor.Any;
 814:         m.initCause(ex);
 815:         throw m;
 816:       }
 817:   }
 818: 
 819:   /** {@inheritDoc} */
 820:   public TypeCode type()
 821:   {
 822:     if (typecode != null)
 823:       return typecode;
 824:     else if (xKind >= 0)
 825:       {
 826:         typecode = new PrimitiveTypeCode(TCKind.from_int(xKind));
 827:         return typecode;
 828:       }
 829:     else
 830:       return has != null ? has._type() : nullType;
 831:   }
 832: 
 833:   /**
 834:    * Explicitly set the typecode of the value to the given type.
 835:    *
 836:    * @param valueTypeCode the typecode of the value.
 837:    */
 838:   public void type(TypeCode valueTypeCode)
 839:   {
 840:     xKind = valueTypeCode.kind().value();
 841:     typecode = valueTypeCode;
 842:   }
 843: 
 844:   /** {@inheritDoc} */
 845:   public void write_value(org.omg.CORBA.portable.OutputStream output)
 846:   {
 847:     if (has != null)
 848:       has._write(output);
 849:     else
 850:     // These kinds support null.
 851:     if (xKind == TCKind._tk_null || xKind == TCKind._tk_objref ||
 852:         xKind == TCKind._tk_value || xKind == TCKind._tk_value_box
 853:        )
 854:       output.write_long(0);
 855:   }
 856: 
 857:   /**
 858:    * Check if the current value if the value of the given kind.
 859:    *
 860:    * @param kind a kind to check.
 861:    * @throws BAD_OPERATION if the value is not set of is different kind.
 862:    */
 863:   protected void check(int kind)
 864:     throws BAD_OPERATION
 865:   {
 866:     if (has == null)
 867:       {
 868:         BAD_OPERATION bad = new BAD_OPERATION("value not set");
 869:         bad.minor = Minor.Any;
 870:         throw bad;
 871:       }
 872: 
 873:     if (xKind >= 0)
 874:       {
 875:         if (xKind != kind)
 876:           if (!(xKind == TCKind._tk_alias && has._type().kind().value() == kind))
 877:             {
 878:               BAD_OPERATION bad = new BAD_OPERATION("Extracting "
 879:                 + TypeKindNamer.nameIt(kind) + " when stored "
 880:                 + TypeKindNamer.nameIt(xKind));
 881:               bad.minor = Minor.Any;
 882:               throw bad;
 883:             }
 884:       }
 885:     else
 886:       {
 887:         if (type().kind().value() != kind)
 888:           if (!(type().kind().value() == TCKind._tk_alias && has._type().kind().value() == kind))
 889:             {
 890:               BAD_OPERATION bad = new BAD_OPERATION("Extracting "
 891:                 + TypeKindNamer.nameIt(kind) + " stored "
 892:                 + TypeKindNamer.nameIt(type()));
 893:               bad.minor = Minor.Any;
 894:               throw bad;
 895:             }
 896:       }
 897:   }
 898: 
 899:   /**
 900:    * Clear the additional type information before reusing this instance.
 901:    */
 902:   private final void resetTypes()
 903:   {
 904:     typecode = null;
 905:     xKind = -1;
 906:   }
 907: }