2 Copyright (C) 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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)
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.
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
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
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. */
41 import gnu.CORBA.CDR.Vio;
42 import gnu.CORBA.CDR.cdrBufInput;
43 import gnu.CORBA.CDR.cdrBufOutput;
45 import org.omg.CORBA.Any;
46 import org.omg.CORBA.AnyHolder;
47 import org.omg.CORBA.BAD_OPERATION;
48 import org.omg.CORBA.BooleanHolder;
49 import org.omg.CORBA.CharHolder;
50 import org.omg.CORBA.DoubleHolder;
51 import org.omg.CORBA.FixedHolder;
52 import org.omg.CORBA.FloatHolder;
53 import org.omg.CORBA.IntHolder;
54 import org.omg.CORBA.LongHolder;
55 import org.omg.CORBA.MARSHAL;
56 import org.omg.CORBA.ORB;
57 import org.omg.CORBA.ObjectHolder;
58 import org.omg.CORBA.Principal;
59 import org.omg.CORBA.PrincipalHolder;
60 import org.omg.CORBA.ShortHolder;
61 import org.omg.CORBA.StringHolder;
62 import org.omg.CORBA.TCKind;
63 import org.omg.CORBA.TypeCode;
64 import org.omg.CORBA.TypeCodeHolder;
65 import org.omg.CORBA.TypeCodePackage.BadKind;
66 import org.omg.CORBA.ValueBaseHolder;
67 import org.omg.CORBA.portable.BoxedValueHelper;
68 import org.omg.CORBA.portable.Streamable;
70 import java.io.IOException;
71 import java.io.Serializable;
73 import java.lang.reflect.Field;
75 import java.math.BigDecimal;
77 import java.util.Arrays;
80 * The implementation of {@link Any}.
82 * For performance reasonse, the inserted values are not cloned.
83 * If the value object allows modifications (like {@link Streamable}),
84 * these subsequent alterations are reflected by the instance of
85 * this gnuAny, and the gnuAny alterations are reflected by the
86 * returned value. If it is required to have the uncoupled value,
87 * it must be requested from the copy of the current instance.
88 * The {@link gnuAny} can be simply cloned by the provided
89 * {@link Clone()} method.
91 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
97 * The value, returned by {@link #type()} if the value has been
100 protected static final TypeCode nullType =
101 new primitiveTypeCode(TCKind.tk_null);
104 * The Streamable, representing the value, held by this gnuAny.
106 protected Streamable has;
109 * The complete typecode of the Streamable, if explicitly set.
111 protected TypeCode typecode;
114 * The typecode kind of the Streamable, if explicitly set.
116 protected int xKind = -1;
119 * The associated ORB.
124 * Set the associated orb.
126 public void setOrb(ORB an_orb)
132 * Creates a deep copy of this gnuAny, writing to and subsequently
133 * reading from from the byte buffer.
135 * @return the uncoupled gnuAny with all fields set to identical
138 public gnuAny Clone()
140 cdrBufOutput out = new cdrBufOutput();
144 cdrBufInput in = new cdrBufInput(out.buffer.toByteArray());
146 return (gnuAny) in.read_any();
150 * Create the buffered CDR input stream, containing the
151 * value, stored inside of this {@link Any}.
153 public org.omg.CORBA.portable.InputStream create_input_stream()
155 if (has instanceof universalHolder)
157 universalHolder u = (universalHolder) has;
158 return u.getInputStream();
162 cdrBufOutput out = new cdrBufOutput();
166 cdrBufInput in = new cdrBufInput(out.buffer.toByteArray());
173 * Create the buffered CDR output stream (empty).
175 public org.omg.CORBA.portable.OutputStream create_output_stream()
177 cdrBufOutput stream = new cdrBufOutput();
183 * Compare two Any's for equality.
184 * @param other the other Any to compare.
186 public boolean equal(Any other)
190 if (type().kind() != other.type().kind())
193 if (has != null && other instanceof gnuAny)
194 if (has.equals(((gnuAny) other).has))
197 cdrBufOutput a = new cdrBufOutput();
201 cdrBufOutput b = new cdrBufOutput();
203 other.write_value(b);
205 byte[] ba = a.buffer.toByteArray();
206 byte[] bb = b.buffer.toByteArray();
208 return Arrays.equals(ba, bb);
212 * Delegates functionality to {@link #equal(Any)}.
214 public boolean equals(java.lang.Object other)
218 if (!(other instanceof Any))
221 return equal((Any) other);
225 * Extract the previously stored object.
227 public org.omg.CORBA.Object extract_Object()
231 return ((ObjectHolder) has).value;
233 catch (ClassCastException ex)
235 throw new BAD_OPERATION();
240 * Extract the previously inserted CORBA <code>Principal</code>/
241 * @return the previously inserted value.
243 * @throws org.omg.CORBA.BAD_OPERATION if the holder contains something
244 * else than Principal.
246 * @deprecated by CORBA 2.2.
248 public Principal extract_Principal()
250 check(TCKind._tk_Principal);
251 return ((PrincipalHolder) has).value;
255 * Return the value, encapsulated in a suitable holder.
256 * This implementation returns the direct reference,
257 * so the alterations on the returned streamable are
258 * directly reflected to the content of this {@link Any}.
260 public Streamable extract_Streamable()
265 public TypeCode extract_TypeCode()
268 check(TCKind._tk_TypeCode);
269 return ((TypeCodeHolder) has).value;
273 * Extract the stored value type.
275 * @return the previously stored value type.
277 * @throws BAD_OPERATION if the Any contains something different.
279 * @see org.omg.CORBA.portable.ValueBase
281 public Serializable extract_Value()
286 if (has instanceof ValueBaseHolder)
287 return ((ValueBaseHolder) has).value;
290 // Normally, ValueBase holder must be an instance of the
291 // ValueBaseHolder. However some IDL compilers probably
292 // have a bug, do not deriving this way. The the only
293 // way to access the wrapped value is via reflection.
294 Field f = has.getClass().getField("value");
295 return (Serializable) f.get(has);
300 return new BAD_OPERATION("Value type expected");
305 public Any extract_any()
308 check(TCKind._tk_any);
309 return ((AnyHolder) has).value;
313 public boolean extract_boolean()
316 check(TCKind._tk_boolean);
317 return ((BooleanHolder) has).value;
321 public char extract_char()
324 check(TCKind._tk_char);
325 return ((CharHolder) has).value;
329 public double extract_double()
332 check(TCKind._tk_double);
333 return ((DoubleHolder) has).value;
337 * Extract the previously inserted CORBA <code>fixed</code>/
338 * @return the previously inserted value.
340 * @throws org.omg.CORBA.BAD_OPERATION if the holder contains something
341 * else than BigDecimal.
343 public BigDecimal extract_fixed()
344 throws org.omg.CORBA.BAD_OPERATION
346 check(TCKind._tk_fixed);
347 return ((FixedHolder) has).value;
351 public float extract_float()
354 check(TCKind._tk_float);
355 return ((FloatHolder) has).value;
359 public int extract_long()
362 // CORBA long = java int.
363 check(TCKind._tk_long);
364 return ((IntHolder) has).value;
368 public long extract_longlong()
371 check(TCKind._tk_longlong);
372 return ((LongHolder) has).value;
376 public byte extract_octet()
379 // ShortHolder holds also octets.
380 check(TCKind._tk_octet);
381 return (byte) ((OctetHolder) has).value;
385 public short extract_short()
388 check(TCKind._tk_short);
389 return ((ShortHolder) has).value;
393 public String extract_string()
396 check(TCKind._tk_string);
397 return ((StringHolder) has).value;
401 public int extract_ulong()
404 // IntHolder also holds ulongs.
405 check(TCKind._tk_ulong);
406 return ((IntHolder) has).value;
410 public long extract_ulonglong()
413 // LongHolder also holds ulonglong
414 check(TCKind._tk_ulonglong);
415 return ((LongHolder) has).value;
419 public short extract_ushort()
422 // ShortHolder also holds ushorts.
423 check(TCKind._tk_ushort);
424 return ((ShortHolder) has).value;
428 public char extract_wchar()
431 check(TCKind._tk_wchar);
432 return ((WCharHolder) has).value;
436 public String extract_wstring()
439 // StringHolder also holds wstrings.
440 check(TCKind._tk_wstring);
441 return ((WStringHolder) has).value;
445 * Inserts the CORBA object and sets the typecode to the given type.
447 public void insert_Object(org.omg.CORBA.Object x, TypeCode typecode)
449 has = new ObjectHolder(x);
454 * Inserts the CORBA object.
456 public void insert_Object(org.omg.CORBA.Object x)
458 has = new ObjectHolder(x);
462 * Insert the CORBA Principal.
463 * This implementation uses direct assignment, so the later
464 * alterations of that BigDecimal are reflected on the
465 * content of this {@link Any}.
467 * @deprecated by CORBA 2.2.
469 public void insert_Principal(Principal x)
472 if (has instanceof PrincipalHolder)
473 ((PrincipalHolder) has).value = x;
475 has = new PrincipalHolder(x);
479 * Sets the value to the value, encapsulated in this holder.
480 * This implementation uses direct assignment, so the later
481 * alterations of that streamable are reflected on the
482 * content of this {@link Any}.
484 public void insert_Streamable(Streamable x)
491 * Insert the typecode into this Any
492 * @param typecode the typecode to insert.
494 public void insert_TypeCode(TypeCode typecode)
497 if (has instanceof TypeCodeHolder)
498 ((TypeCodeHolder) has).value = typecode;
500 has = new TypeCodeHolder(typecode);
504 public void insert_Value(Serializable x, TypeCode c_typecode)
506 if (typecode != null && typecode.kind() == TCKind.tk_value_box)
508 has = new gnuValueHolder(x, typecode);
518 public void insert_Value(Serializable x)
520 if (typecode != null && typecode.kind() == TCKind.tk_value_box)
522 has = new gnuValueHolder(x, typecode);
526 if (has instanceof ValueBaseHolder)
527 ((ValueBaseHolder) has).value = x;
529 has = new ValueBaseHolder(x);
534 * Insert another {@link Any} into this {@link Any}.
535 * This implementation uses direct assignment, so the later
536 * alterations of that {@link Any} are reflected on the
537 * content of this {@link Any}.
539 public void insert_any(Any an_any)
542 if (has instanceof AnyHolder)
543 ((AnyHolder) has).value = an_any;
545 has = new AnyHolder(an_any);
549 public void insert_boolean(boolean x)
552 if (has instanceof BooleanHolder)
553 ((BooleanHolder) has).value = x;
555 has = new BooleanHolder(x);
559 public void insert_char(char x)
562 if (has instanceof CharHolder)
563 ((CharHolder) has).value = x;
565 has = new CharHolder(x);
569 public void insert_double(double x)
572 if (has instanceof DoubleHolder)
573 ((DoubleHolder) has).value = x;
575 has = new DoubleHolder(x);
579 * Inserts the CORBA <code>fixed</code>, setting the typecode
581 * This implementation uses direct assignment, so the later
582 * alterations of that BigDecimal are reflected on the
583 * content of this {@link Any}.
585 public void insert_fixed(BigDecimal x, TypeCode x_typecode)
589 typecode = x_typecode;
593 * Inserts the CORBA <code>fixed</code>, setting the typecode
594 * by example of the currently passed value.
595 * This implementation uses direct assignment, so the later
596 * alterations of that BigDecimal are reflected on the
597 * content of this {@link Any}, including the typecode.
599 public void insert_fixed(BigDecimal x)
602 if (has instanceof FixedHolder)
603 ((FixedHolder) has).value = x;
605 has = new FixedHolder(x);
609 public void insert_float(float x)
612 if (has instanceof FloatHolder)
613 ((FloatHolder) has).value = x;
615 has = new FloatHolder(x);
619 public void insert_long(int x)
622 if (has instanceof IntHolder)
623 ((IntHolder) has).value = x;
625 has = new IntHolder(x);
629 public void insert_longlong(long x)
632 if (has instanceof LongHolder)
633 ((LongHolder) has).value = x;
635 has = new LongHolder(x);
639 public void insert_octet(byte x)
642 if (has instanceof OctetHolder)
643 ((OctetHolder) has).value = x;
645 has = new OctetHolder(x);
649 public void insert_short(short x)
652 if (has instanceof ShortHolder)
653 ((ShortHolder) has).value = x;
655 has = new ShortHolder(x);
659 public void insert_string(String x)
662 if (has instanceof StringHolder)
663 ((StringHolder) has).value = x;
665 has = new StringHolder(x);
667 typecode = new stringTypeCode(TCKind.tk_string);
671 public void insert_ulong(int x)
674 if (has instanceof IntHolder)
675 ((IntHolder) has).value = x;
677 has = new IntHolder(x);
678 xKind = TCKind._tk_ulong;
682 public void insert_ulonglong(long x)
685 if (has instanceof LongHolder)
686 ((LongHolder) has).value = x;
688 has = new LongHolder(x);
689 xKind = TCKind._tk_ulonglong;
693 public void insert_ushort(short x)
696 if (has instanceof ShortHolder)
697 ((ShortHolder) has).value = x;
699 has = new ShortHolder(x);
700 xKind = TCKind._tk_ushort;
704 public void insert_wchar(char x)
707 if (has instanceof WCharHolder)
708 ((WCharHolder) has).value = x;
710 has = new WCharHolder(x);
714 public void insert_wstring(String x)
717 if (has instanceof WStringHolder)
718 ((WStringHolder) has).value = x;
720 has = new WStringHolder(x);
724 * Return the associated orb.
732 * Read the value of the given type from the given stream.
734 * @param input a stream to read from.
735 * @param a_type a typecode of the value to read.
737 public void read_value(org.omg.CORBA.portable.InputStream input,
744 int kind = a_type.kind().value();
746 // Fixed needs special handling.
747 if (kind == TCKind._tk_fixed)
749 BigDecimal dec = BigDecimalHelper.read(input, a_type.fixed_scale());
750 has = new FixedHolder(dec);
754 has = holderFactory.createHolder(a_type);
757 // Use the Universal Holder that reads till the end of stream.
758 // This works with the extract/insert pair of the typical
760 cdrBufOutput buffer = new cdrBufOutput();
762 has = new universalHolder(buffer);
767 if (!(has instanceof universalHolder) &&
768 (kind == TCKind._tk_value_box))
770 // The streamable only contains operations for
771 // reading the value, not the value header.
772 Field vField = has.getClass().getField("value");
774 BoxedValueHelper helper;
779 Class.forName(ObjectCreator.toHelperName(a_type.id()));
780 helper = (BoxedValueHelper) helperClass.newInstance();
787 Object content = Vio.read(input, helper);
788 vField.set(has, content);
795 MARSHAL m = new MARSHAL();
802 public TypeCode type()
804 if (typecode != null)
808 typecode = new primitiveTypeCode(TCKind.from_int(xKind));
812 return has != null ? has._type() : nullType;
816 * Explicitly set the typecode of the value to the given type.
818 * @param valueTypeCode the typecode of the value.
820 public void type(TypeCode valueTypeCode)
822 xKind = valueTypeCode.kind().value();
823 typecode = valueTypeCode;
827 public void write_value(org.omg.CORBA.portable.OutputStream output)
832 // These kinds support null.
833 if (xKind == TCKind._tk_null || xKind == TCKind._tk_objref ||
834 xKind == TCKind._tk_value || xKind == TCKind._tk_value_box
836 output.write_long(0);
840 * Check if the current value if the value of the given kind.
841 * @param kind a kind to check.
842 * @throws BAD_OPERATION if the value is not set of is different kind.
844 protected void check(int kind)
848 throw new BAD_OPERATION("value not set");
854 xKind == TCKind._tk_alias &&
855 has._type().kind().value() == kind
858 throw new BAD_OPERATION("Extracting " + typeNamer.nameIt(kind) +
859 " when stored " + typeNamer.nameIt(xKind)
864 if (type().kind().value() != kind)
866 type().kind().value() == TCKind._tk_alias &&
867 has._type().kind().value() == kind
870 throw new BAD_OPERATION("Extracting " + typeNamer.nameIt(kind) +
871 " stored " + typeNamer.nameIt(type())
877 * Clear the additional type information before reusing this instance.
879 private final void resetTypes()