/*
* Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
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;
}
}