/* * @(#)DynAnyUtil.java 1.12 03/12/19 * * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package com.sun.corba.se.impl.dynamicany; import org.omg.CORBA.Any; import org.omg.CORBA.TypeCode; import org.omg.CORBA.TCKind; import org.omg.CORBA.portable.OutputStream; //import org.omg.CORBA.ORBPackage.*; import org.omg.CORBA.TypeCodePackage.BadKind; import org.omg.CORBA.TypeCodePackage.Bounds; import org.omg.CORBA.portable.InputStream; import org.omg.DynamicAny.*; import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode; import java.math.BigDecimal; import com.sun.corba.se.impl.corba.AnyImpl; import com.sun.corba.se.spi.orb.ORB ; import com.sun.corba.se.spi.logging.CORBALogDomains ; import com.sun.corba.se.impl.logging.ORBUtilSystemException ; public class DynAnyUtil { static boolean isConsistentType(TypeCode typeCode) { int kind = typeCode.kind().value(); return (kind != TCKind._tk_Principal && kind != TCKind._tk_native && kind != TCKind._tk_abstract_interface); } static boolean isConstructedDynAny(DynAny dynAny) { // DynFixed is constructed but not a subclass of DynAnyConstructedImpl //return (dynAny instanceof DynAnyConstructedImpl); int kind = dynAny.type().kind().value(); return (kind == TCKind._tk_sequence || kind == TCKind._tk_struct || kind == TCKind._tk_array || kind == TCKind._tk_union || kind == TCKind._tk_enum || kind == TCKind._tk_fixed || kind == TCKind._tk_value || kind == TCKind._tk_value_box); } static DynAny createMostDerivedDynAny(Any any, ORB orb, boolean copyValue) throws org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode { if (any == null || ! DynAnyUtil.isConsistentType(any.type())) throw new org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode(); switch (any.type().kind().value()) { case TCKind._tk_sequence: return new DynSequenceImpl(orb, any, copyValue); case TCKind._tk_struct: return new DynStructImpl(orb, any, copyValue); case TCKind._tk_array: return new DynArrayImpl(orb, any, copyValue); case TCKind._tk_union: return new DynUnionImpl(orb, any, copyValue); case TCKind._tk_enum: return new DynEnumImpl(orb, any, copyValue); case TCKind._tk_fixed: return new DynFixedImpl(orb, any, copyValue); case TCKind._tk_value: return new DynValueImpl(orb, any, copyValue); case TCKind._tk_value_box: return new DynValueBoxImpl(orb, any, copyValue); default: return new DynAnyBasicImpl(orb, any, copyValue); } } static DynAny createMostDerivedDynAny(TypeCode typeCode, ORB orb) throws org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode { if (typeCode == null || ! DynAnyUtil.isConsistentType(typeCode)) throw new org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode(); switch (typeCode.kind().value()) { case TCKind._tk_sequence: return new DynSequenceImpl(orb, typeCode); case TCKind._tk_struct: return new DynStructImpl(orb, typeCode); case TCKind._tk_array: return new DynArrayImpl(orb, typeCode); case TCKind._tk_union: return new DynUnionImpl(orb, typeCode); case TCKind._tk_enum: return new DynEnumImpl(orb, typeCode); case TCKind._tk_fixed: return new DynFixedImpl(orb, typeCode); case TCKind._tk_value: return new DynValueImpl(orb, typeCode); case TCKind._tk_value_box: return new DynValueBoxImpl(orb, typeCode); default: return new DynAnyBasicImpl(orb, typeCode); } } // Extracts a member value according to the given TypeCode from the given complex Any // (at the Anys current internal stream position, consuming the anys stream on the way) // and returns it wrapped into a new Any /* static Any extractAnyFromAny(TypeCode memberType, Any any, ORB orb) { // Moved this functionality into AnyImpl because it is needed for Any.equal() return ((AnyImpl)any).extractAny(memberType, orb); } */ // Extracts a member value according to the given TypeCode from the given complex Any // (at the Anys current internal stream position, consuming the anys stream on the way) // and returns it wrapped into a new Any static Any extractAnyFromStream(TypeCode memberType, InputStream input, ORB orb) { return AnyImpl.extractAnyFromStream(memberType, input, orb); } // Creates a default Any of the given type. static Any createDefaultAnyOfType(TypeCode typeCode, ORB orb) { ORBUtilSystemException wrapper = ORBUtilSystemException.get( orb, CORBALogDomains.RPC_PRESENTATION ) ; Any returnValue = orb.create_any(); // The spec for DynAny differs from Any on initialization via type code: // - false for boolean // - zero for numeric types // - zero for types octet, char, and wchar // - the empty string for string and wstring // - nil for object references // - a type code with a TCKind value of tk_null for type codes // - for Any values, an Any containing a type code with a TCKind value of tk_null // type and no value switch (typeCode.kind().value()) { case TCKind._tk_boolean: // false for boolean returnValue.insert_boolean(false); break; case TCKind._tk_short: // zero for numeric types returnValue.insert_short((short)0); break; case TCKind._tk_ushort: // zero for numeric types returnValue.insert_ushort((short)0); break; case TCKind._tk_long: // zero for numeric types returnValue.insert_long(0); break; case TCKind._tk_ulong: // zero for numeric types returnValue.insert_ulong(0); break; case TCKind._tk_longlong: // zero for numeric types returnValue.insert_longlong((long)0); break; case TCKind._tk_ulonglong: // zero for numeric types returnValue.insert_ulonglong((long)0); break; case TCKind._tk_float: // zero for numeric types returnValue.insert_float((float)0.0); break; case TCKind._tk_double: // zero for numeric types returnValue.insert_double((double)0.0); break; case TCKind._tk_octet: // zero for types octet, char, and wchar returnValue.insert_octet((byte)0); break; case TCKind._tk_char: // zero for types octet, char, and wchar returnValue.insert_char((char)0); break; case TCKind._tk_wchar: // zero for types octet, char, and wchar returnValue.insert_wchar((char)0); break; case TCKind._tk_string: // the empty string for string and wstring // Make sure that type code for bounded strings gets respected returnValue.type(typeCode); // Doesn't erase the type of bounded string returnValue.insert_string(""); break; case TCKind._tk_wstring: // the empty string for string and wstring // Make sure that type code for bounded strings gets respected returnValue.type(typeCode); // Doesn't erase the type of bounded string returnValue.insert_wstring(""); break; case TCKind._tk_objref: // nil for object references returnValue.insert_Object(null); break; case TCKind._tk_TypeCode: // a type code with a TCKind value of tk_null for type codes // We can reuse the type code that's already in the any. returnValue.insert_TypeCode(returnValue.type()); break; case TCKind._tk_any: // for Any values, an Any containing a type code with a TCKind value // of tk_null type and no value. // This is exactly what the default AnyImpl constructor provides. // _REVISIT_ Note that this inner Any is considered uninitialized. returnValue.insert_any(orb.create_any()); break; case TCKind._tk_struct: case TCKind._tk_union: case TCKind._tk_enum: case TCKind._tk_sequence: case TCKind._tk_array: case TCKind._tk_except: case TCKind._tk_value: case TCKind._tk_value_box: // There are no default value for complex types since there is no // concept of a hierarchy of Anys. Only DynAnys can be arrange in // a hierarchy to mirror the TypeCode hierarchy. // See DynAnyConstructedImpl.initializeComponentsFromTypeCode() // on how this DynAny hierarchy is created from TypeCodes. returnValue.type(typeCode); break; case TCKind._tk_fixed: returnValue.insert_fixed(new BigDecimal("0.0"), typeCode); break; case TCKind._tk_native: case TCKind._tk_alias: case TCKind._tk_void: case TCKind._tk_Principal: case TCKind._tk_abstract_interface: returnValue.type(typeCode); break; case TCKind._tk_null: // Any is already initialized to null break; case TCKind._tk_longdouble: // Unspecified for Java throw wrapper.tkLongDoubleNotSupported() ; default: throw wrapper.typecodeNotSupported() ; } return returnValue; } /* static Any setTypeOfAny(TypeCode typeCode, Any value) { if (value != null) { value.read_value(value.create_input_stream(), typeCode); } return value; } */ static Any copy(Any inAny, ORB orb) { return new AnyImpl(orb, inAny); } /* static Any copy(Any inAny, ORB orb) { Any outAny = null; if (inAny != null && orb != null) { outAny = orb.create_any(); outAny.read_value(inAny.create_input_stream(), inAny.type()); // isInitialized is set to true } return outAny; } */ static DynAny convertToNative(DynAny dynAny, ORB orb) { if (dynAny instanceof DynAnyImpl) { return dynAny; } else { // if copy flag wasn't true we would be using our DynAny with // a foreign Any in it. try { return createMostDerivedDynAny(dynAny.to_any(), orb, true); } catch (InconsistentTypeCode ictc) { return null; } } } static boolean isInitialized(Any any) { // Returning simply the value of Any.isInitialized() is not enough. // The DynAny spec says that Anys containing null strings do not contain // a "legal value" (see ptc 99-10-07, 9.2.3.3) boolean isInitialized = ((AnyImpl)any).isInitialized(); switch (any.type().kind().value()) { case TCKind._tk_string: return (isInitialized && (any.extract_string() != null)); case TCKind._tk_wstring: return (isInitialized && (any.extract_wstring() != null)); } return isInitialized; } // This is a convenient method to reset the current component to where it was // before we changed it. See DynAnyConstructedImpl.equal for use. static boolean set_current_component(DynAny dynAny, DynAny currentComponent) { if (currentComponent != null) { try { dynAny.rewind(); do { if (dynAny.current_component() == currentComponent) return true; } while (dynAny.next()); } catch (TypeMismatch tm) { /* impossible */ } } return false; } }