blob: 0f3428ac029bb4145ea98458f39eee8614349856 [file] [log] [blame]
/*
* Copyright (c) 1997, 2013, 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.
*/
/*
* Licensed Materials - Property of IBM
* RMI-IIOP v1.0
* Copyright IBM Corp. 1998 1999 All Rights Reserved
*
*/
package com.sun.corba.se.impl.corba;
import java.io.Serializable;
import java.math.BigDecimal;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.List ;
import java.util.ArrayList ;
import org.omg.CORBA.Principal ;
import org.omg.CORBA.TypeCode ;
import org.omg.CORBA.Any ;
import org.omg.CORBA.CompletionStatus ;
import org.omg.CORBA.TCKind ;
import org.omg.CORBA.portable.Streamable;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.TypeCodePackage.BadKind;
import org.omg.CORBA.TypeCodePackage.Bounds;
import com.sun.corba.se.spi.orb.ORB;
import com.sun.corba.se.spi.orb.ORBVersionFactory;
import com.sun.corba.se.spi.logging.CORBALogDomains;
import com.sun.corba.se.spi.presentation.rmi.StubAdapter;
import com.sun.corba.se.impl.encoding.CDRInputStream;
import com.sun.corba.se.impl.encoding.EncapsInputStream;
import com.sun.corba.se.impl.encoding.EncapsOutputStream;
import com.sun.corba.se.impl.io.ValueUtility;
import com.sun.corba.se.impl.orbutil.RepositoryIdFactory;
import com.sun.corba.se.impl.orbutil.RepositoryIdStrings;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.logging.ORBUtilSystemException;
// subclasses must provide a matching helper class
public class AnyImpl extends Any
{
private static final class AnyInputStream extends EncapsInputStream
{
public AnyInputStream(EncapsInputStream theStream )
{
super( theStream );
}
}
private static final class AnyOutputStream extends EncapsOutputStream
{
public AnyOutputStream(ORB orb)
{
super((ORB)orb);
}
public org.omg.CORBA.portable.InputStream create_input_stream() {
final org.omg.CORBA.portable.InputStream is = super
.create_input_stream();
AnyInputStream aIS = AccessController
.doPrivileged(new PrivilegedAction<AnyInputStream>() {
@Override
public AnyInputStream run() {
return new AnyInputStream(
(com.sun.corba.se.impl.encoding.EncapsInputStream) is);
}
});
return aIS;
}
}
//
// Always valid.
//
private TypeCodeImpl typeCode;
protected ORB orb;
private ORBUtilSystemException wrapper ;
//
// Validity depends upon typecode. The 'value' and 'object' instance
// members are used to hold immutable types as defined by the
// isStreamed[] table below. Otherwise, 'stream' is non-null and
// holds the value in CDR marshaled format. As an optimization, the
// stream type is an Any extension of CDR stream that is used to
// detect an optimization in read_value().
//
private CDRInputStream stream;
private long value;
private java.lang.Object object;
// Setting the typecode via the type() accessor wipes out the value.
// An attempt to extract before the value is set will result
// in a BAD_OPERATION exception being raised.
private boolean isInitialized = false;
private static final int DEFAULT_BUFFER_SIZE = 32;
/*
* This boolean array tells us if a given typecode must be
* streamed. Objects that are immutable don't have to be streamed.
*/
static boolean isStreamed[] = {
false, // null
false, // void
false, // short
false, // long
false, // ushort
false, // ulong
false, // float
false, // double
false, // boolean
false, // char
false, // octet
false, // any
false, // TypeCode
true, // Principal
false, // objref
true, // struct
true, // union
false, // enum
false, // string
true, // sequence
true, // array
true, // alias
true, // except
false, // longlong
false, // ulonglong
false, // longdouble
false, // wchar
false, // wstring
false, // fixed
false, // value
false, // value_box (used to be true)
false, // native
false // abstract interface
};
static AnyImpl convertToNative(ORB orb, Any any) {
if (any instanceof AnyImpl) {
return (AnyImpl)any;
} else {
AnyImpl anyImpl = new AnyImpl(orb, any);
anyImpl.typeCode = TypeCodeImpl.convertToNative(orb, anyImpl.typeCode);
return anyImpl;
}
}
///////////////////////////////////////////////////////////////////////////
// Constructors
/**
* A constructor that sets the Any to contain a null. It also marks
* the value as being invalid so that extractions throw an exception
* until an insertion has been performed.
*/
public AnyImpl(ORB orb)
{
this.orb = orb;
wrapper = ORBUtilSystemException.get( (com.sun.corba.se.spi.orb.ORB)orb,
CORBALogDomains.RPC_PRESENTATION ) ;
typeCode = orb.get_primitive_tc(TCKind._tk_null);
stream = null;
object = null;
value = 0;
// null is a valid value
isInitialized = true;
}
//
// Create a new AnyImpl which is a copy of obj.
//
public AnyImpl(ORB orb, Any obj) {
this(orb);
if ((obj instanceof AnyImpl)) {
AnyImpl objImpl = (AnyImpl)obj;
typeCode = objImpl.typeCode;
value = objImpl.value;
object = objImpl.object;
isInitialized = objImpl.isInitialized;
if (objImpl.stream != null)
stream = objImpl.stream.dup();
} else {
read_value(obj.create_input_stream(), obj.type());
}
}
///////////////////////////////////////////////////////////////////////////
// basic accessors
/**
* returns the type of the element contained in the Any.
*
* @result the TypeCode for the element in the Any
*/
public TypeCode type() {
return typeCode;
}
private TypeCode realType() {
return realType(typeCode);
}
private TypeCode realType(TypeCode aType) {
TypeCode realType = aType;
try {
// Note: Indirect types are handled in kind() method
while (realType.kind().value() == TCKind._tk_alias) {
realType = realType.content_type();
}
} catch (BadKind bad) { // impossible
throw wrapper.badkindCannotOccur( bad ) ;
}
return realType;
}
/**
* sets the type of the element to be contained in the Any.
*
* @param tc the TypeCode for the element in the Any
*/
public void type(TypeCode tc)
{
//debug.log ("type2");
// set the typecode
typeCode = TypeCodeImpl.convertToNative(orb, tc);
stream = null;
value = 0;
object = null;
// null is the only legal value this Any can have after resetting the type code
isInitialized = (tc.kind().value() == TCKind._tk_null);
}
/**
* checks for equality between Anys.
*
* @param otherAny the Any to be compared with.
* @result true if the Anys are equal, false otherwise.
*/
public boolean equal(Any otherAny)
{
//debug.log ("equal");
if (otherAny == this)
return true;
// first check for typecode equality.
// note that this will take aliases into account
if (!typeCode.equal(otherAny.type()))
return false;
// Resolve aliases here
TypeCode realType = realType();
// _REVISIT_ Possible optimization for the case where
// otherAny is a AnyImpl and the endianesses match.
// Need implementation of CDRInputStream.equals()
// For now we disable this to encourage testing the generic,
// unoptimized code below.
// Unfortunately this generic code needs to copy the whole stream
// at least once.
// if (AnyImpl.isStreamed[realType.kind().value()]) {
// if (otherAny instanceof AnyImpl) {
// return ((AnyImpl)otherAny).stream.equals(stream);
// }
// }
switch (realType.kind().value()) {
// handle primitive types
case TCKind._tk_null:
case TCKind._tk_void:
return true;
case TCKind._tk_short:
return (extract_short() == otherAny.extract_short());
case TCKind._tk_long:
return (extract_long() == otherAny.extract_long());
case TCKind._tk_ushort:
return (extract_ushort() == otherAny.extract_ushort());
case TCKind._tk_ulong:
return (extract_ulong() == otherAny.extract_ulong());
case TCKind._tk_float:
return (extract_float() == otherAny.extract_float());
case TCKind._tk_double:
return (extract_double() == otherAny.extract_double());
case TCKind._tk_boolean:
return (extract_boolean() == otherAny.extract_boolean());
case TCKind._tk_char:
return (extract_char() == otherAny.extract_char());
case TCKind._tk_wchar:
return (extract_wchar() == otherAny.extract_wchar());
case TCKind._tk_octet:
return (extract_octet() == otherAny.extract_octet());
case TCKind._tk_any:
return extract_any().equal(otherAny.extract_any());
case TCKind._tk_TypeCode:
return extract_TypeCode().equal(otherAny.extract_TypeCode());
case TCKind._tk_string:
return extract_string().equals(otherAny.extract_string());
case TCKind._tk_wstring:
return (extract_wstring().equals(otherAny.extract_wstring()));
case TCKind._tk_longlong:
return (extract_longlong() == otherAny.extract_longlong());
case TCKind._tk_ulonglong:
return (extract_ulonglong() == otherAny.extract_ulonglong());
case TCKind._tk_objref:
return (extract_Object().equals(otherAny.extract_Object()));
case TCKind._tk_Principal:
return (extract_Principal().equals(otherAny.extract_Principal()));
case TCKind._tk_enum:
return (extract_long() == otherAny.extract_long());
case TCKind._tk_fixed:
return (extract_fixed().compareTo(otherAny.extract_fixed()) == 0);
case TCKind._tk_except:
case TCKind._tk_struct:
case TCKind._tk_union:
case TCKind._tk_sequence:
case TCKind._tk_array:
InputStream copyOfMyStream = this.create_input_stream();
InputStream copyOfOtherStream = otherAny.create_input_stream();
return equalMember(realType, copyOfMyStream, copyOfOtherStream);
// Too complicated to handle value types the way we handle
// other complex types above. Don't try to decompose it here
// for faster comparison, just use Object.equals().
case TCKind._tk_value:
case TCKind._tk_value_box:
return extract_Value().equals(otherAny.extract_Value());
case TCKind._tk_alias:
throw wrapper.errorResolvingAlias() ;
case TCKind._tk_longdouble:
// Unspecified for Java
throw wrapper.tkLongDoubleNotSupported() ;
default:
throw wrapper.typecodeNotSupported() ;
}
}
// Needed for equal() in order to achieve linear performance for complex types.
// Uses up (recursively) copies of the InputStream in both Anys that got created in equal().
private boolean equalMember(TypeCode memberType, InputStream myStream, InputStream otherStream) {
// Resolve aliases here
TypeCode realType = realType(memberType);
try {
switch (realType.kind().value()) {
// handle primitive types
case TCKind._tk_null:
case TCKind._tk_void:
return true;
case TCKind._tk_short:
return (myStream.read_short() == otherStream.read_short());
case TCKind._tk_long:
return (myStream.read_long() == otherStream.read_long());
case TCKind._tk_ushort:
return (myStream.read_ushort() == otherStream.read_ushort());
case TCKind._tk_ulong:
return (myStream.read_ulong() == otherStream.read_ulong());
case TCKind._tk_float:
return (myStream.read_float() == otherStream.read_float());
case TCKind._tk_double:
return (myStream.read_double() == otherStream.read_double());
case TCKind._tk_boolean:
return (myStream.read_boolean() == otherStream.read_boolean());
case TCKind._tk_char:
return (myStream.read_char() == otherStream.read_char());
case TCKind._tk_wchar:
return (myStream.read_wchar() == otherStream.read_wchar());
case TCKind._tk_octet:
return (myStream.read_octet() == otherStream.read_octet());
case TCKind._tk_any:
return myStream.read_any().equal(otherStream.read_any());
case TCKind._tk_TypeCode:
return myStream.read_TypeCode().equal(otherStream.read_TypeCode());
case TCKind._tk_string:
return myStream.read_string().equals(otherStream.read_string());
case TCKind._tk_wstring:
return (myStream.read_wstring().equals(otherStream.read_wstring()));
case TCKind._tk_longlong:
return (myStream.read_longlong() == otherStream.read_longlong());
case TCKind._tk_ulonglong:
return (myStream.read_ulonglong() == otherStream.read_ulonglong());
case TCKind._tk_objref:
return (myStream.read_Object().equals(otherStream.read_Object()));
case TCKind._tk_Principal:
return (myStream.read_Principal().equals(otherStream.read_Principal()));
case TCKind._tk_enum:
return (myStream.read_long() == otherStream.read_long());
case TCKind._tk_fixed:
return (myStream.read_fixed().compareTo(otherStream.read_fixed()) == 0);
case TCKind._tk_except:
case TCKind._tk_struct: {
int length = realType.member_count();
for (int i=0; i<length; i++) {
if ( ! equalMember(realType.member_type(i), myStream, otherStream)) {
return false;
}
}
return true;
}
case TCKind._tk_union: {
Any myDiscriminator = orb.create_any();
Any otherDiscriminator = orb.create_any();
myDiscriminator.read_value(myStream, realType.discriminator_type());
otherDiscriminator.read_value(otherStream, realType.discriminator_type());
if ( ! myDiscriminator.equal(otherDiscriminator)) {
return false;
}
TypeCodeImpl realTypeCodeImpl = TypeCodeImpl.convertToNative(orb, realType);
int memberIndex = realTypeCodeImpl.currentUnionMemberIndex(myDiscriminator);
if (memberIndex == -1)
throw wrapper.unionDiscriminatorError() ;
if ( ! equalMember(realType.member_type(memberIndex), myStream, otherStream)) {
return false;
}
return true;
}
case TCKind._tk_sequence: {
int length = myStream.read_long();
otherStream.read_long(); // just so that the two stream are in sync
for (int i=0; i<length; i++) {
if ( ! equalMember(realType.content_type(), myStream, otherStream)) {
return false;
}
}
return true;
}
case TCKind._tk_array: {
int length = realType.member_count();
for (int i=0; i<length; i++) {
if ( ! equalMember(realType.content_type(), myStream, otherStream)) {
return false;
}
}
return true;
}
// Too complicated to handle value types the way we handle
// other complex types above. Don't try to decompose it here
// for faster comparison, just use Object.equals().
case TCKind._tk_value:
case TCKind._tk_value_box:
org.omg.CORBA_2_3.portable.InputStream mine =
(org.omg.CORBA_2_3.portable.InputStream)myStream;
org.omg.CORBA_2_3.portable.InputStream other =
(org.omg.CORBA_2_3.portable.InputStream)otherStream;
return mine.read_value().equals(other.read_value());
case TCKind._tk_alias:
// error resolving alias above
throw wrapper.errorResolvingAlias() ;
case TCKind._tk_longdouble:
throw wrapper.tkLongDoubleNotSupported() ;
default:
throw wrapper.typecodeNotSupported() ;
}
} catch (BadKind badKind) { // impossible
throw wrapper.badkindCannotOccur() ;
} catch (Bounds bounds) { // impossible
throw wrapper.boundsCannotOccur() ;
}
}
///////////////////////////////////////////////////////////////////////////
// accessors for marshaling/unmarshaling
/**
* returns an output stream that an Any value can be marshaled into.
*
* @result the OutputStream to marshal value of Any into
*/
public org.omg.CORBA.portable.OutputStream create_output_stream()
{
//debug.log ("create_output_stream");
final ORB finalorb = this.orb;
return AccessController.doPrivileged(new PrivilegedAction<AnyOutputStream>() {
@Override
public AnyOutputStream run() {
return new AnyOutputStream(finalorb);
}
});
}
/**
* returns an input stream that an Any value can be marshaled out of.
*
* @result the InputStream to marshal value of Any out of.
*/
public org.omg.CORBA.portable.InputStream create_input_stream()
{
//
// We create a new InputStream so that multiple threads can call here
// and read the streams in parallel without thread safety problems.
//
//debug.log ("create_input_stream");
if (AnyImpl.isStreamed[realType().kind().value()]) {
return stream.dup();
} else {
OutputStream os = (OutputStream)orb.create_output_stream();
TCUtility.marshalIn(os, realType(), value, object);
return os.create_input_stream();
}
}
///////////////////////////////////////////////////////////////////////////
// marshaling/unmarshaling routines
//
// If the InputStream is a CDRInputStream then we can copy the bytes
// since it is in our format and does not have alignment issues.
//
public void read_value(org.omg.CORBA.portable.InputStream in, TypeCode tc)
{
//debug.log ("read_value");
//
// Assume that someone isn't going to think they can keep reading
// from this stream after calling us. That would be likely for
// an IIOPInputStream but if it is an AnyInputStream then they
// presumably obtained it via our create_output_stream() so they could
// write the contents of an IDL data type to it and then call
// create_input_stream() for us to read it. This is how Helper classes
// typically implement the insert() method.
// We should probably document this behavior in the 1.1 revision
// task force.
//
typeCode = TypeCodeImpl.convertToNative(orb, tc);
int kind = realType().kind().value();
if (kind >= isStreamed.length) {
throw wrapper.invalidIsstreamedTckind( CompletionStatus.COMPLETED_MAYBE,
new Integer(kind)) ;
}
if (AnyImpl.isStreamed[kind]) {
if ( in instanceof AnyInputStream ) {
// could only have been created here
stream = (CDRInputStream)in;
} else {
org.omg.CORBA_2_3.portable.OutputStream out =
(org.omg.CORBA_2_3.portable.OutputStream)orb.create_output_stream();
typeCode.copy((org.omg.CORBA_2_3.portable.InputStream)in, out);
stream = (CDRInputStream)out.create_input_stream();
}
} else {
java.lang.Object[] objholder = new java.lang.Object[1];
objholder[0] = object;
long[] longholder = new long[1];
TCUtility.unmarshalIn(in, realType(), longholder, objholder);
value = longholder[0];
object = objholder[0];
stream = null;
}
isInitialized = true;
}
//
// We could optimize this by noticing whether the target stream
// has ever had anything marshaled on it that required an
// alignment of greater than 4 (was write_double() ever called on it).
// If not, then we can just do a byte array copy without having to
// drive the remarshaling through typecode interpretation.
//
public void write_value(OutputStream out)
{
//debug.log ("write_value");
if (AnyImpl.isStreamed[realType().kind().value()]) {
typeCode.copy(stream.dup(), out);
} else {
// _REVISIT_ check isInitialized whether all we write is TypeCode!
TCUtility.marshalIn(out, realType(), value, object);
}
}
/**
* takes a streamable and inserts its reference into the any
*
* @param s the streamable to insert
*/
public void insert_Streamable(Streamable s)
{
//debug.log ("insert_Streamable");
typeCode = TypeCodeImpl.convertToNative(orb, s._type());
object = s;
isInitialized = true;
}
public Streamable extract_Streamable()
{
//debug.log( "extract_Streamable" ) ;
return (Streamable)object;
}
///////////////////////////////////////////////////////////////////////////
// insertion/extraction/replacement for all basic types
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_short(short s)
{
//debug.log ("insert_short");
typeCode = orb.get_primitive_tc(TCKind._tk_short);
value = s;
isInitialized = true;
}
private String getTCKindName( int tc )
{
if ((tc >= 0) && (tc < TypeCodeImpl.kindNames.length))
return TypeCodeImpl.kindNames[tc] ;
else
return "UNKNOWN(" + tc + ")" ;
}
private void checkExtractBadOperation( int expected )
{
if (!isInitialized)
throw wrapper.extractNotInitialized() ;
int tc = realType().kind().value() ;
if (tc != expected) {
String tcName = getTCKindName( tc ) ;
String expectedName = getTCKindName( expected ) ;
throw wrapper.extractWrongType( expectedName, tcName ) ;
}
}
private void checkExtractBadOperationList( int[] expected )
{
if (!isInitialized)
throw wrapper.extractNotInitialized() ;
int tc = realType().kind().value() ;
for (int ctr=0; ctr<expected.length; ctr++)
if (tc == expected[ctr])
return ;
List list = new ArrayList() ;
for (int ctr=0; ctr<expected.length; ctr++)
list.add( getTCKindName( expected[ctr] ) ) ;
String tcName = getTCKindName( tc ) ;
throw wrapper.extractWrongTypeList( list, tcName ) ;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public short extract_short()
{
//debug.log ("extract_short");
checkExtractBadOperation( TCKind._tk_short ) ;
return (short)value;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_long(int l)
{
//debug.log ("insert_long");
// A long value is applicable to enums as well, so don't erase the enum type code
// in case it was initialized that way before.
int kind = realType().kind().value();
if (kind != TCKind._tk_long && kind != TCKind._tk_enum) {
typeCode = orb.get_primitive_tc(TCKind._tk_long);
}
value = l;
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public int extract_long()
{
//debug.log ("extract_long");
checkExtractBadOperationList( new int[] { TCKind._tk_long, TCKind._tk_enum } ) ;
return (int)value;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_ushort(short s)
{
//debug.log ("insert_ushort");
typeCode = orb.get_primitive_tc(TCKind._tk_ushort);
value = s;
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public short extract_ushort()
{
//debug.log ("extract_ushort");
checkExtractBadOperation( TCKind._tk_ushort ) ;
return (short)value;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_ulong(int l)
{
//debug.log ("insert_ulong");
typeCode = orb.get_primitive_tc(TCKind._tk_ulong);
value = l;
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public int extract_ulong()
{
//debug.log ("extract_ulong");
checkExtractBadOperation( TCKind._tk_ulong ) ;
return (int)value;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_float(float f)
{
//debug.log ("insert_float");
typeCode = orb.get_primitive_tc(TCKind._tk_float);
value = Float.floatToIntBits(f);
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public float extract_float()
{
//debug.log ("extract_float");
checkExtractBadOperation( TCKind._tk_float ) ;
return Float.intBitsToFloat((int)value);
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_double(double d)
{
//debug.log ("insert_double");
typeCode = orb.get_primitive_tc(TCKind._tk_double);
value = Double.doubleToLongBits(d);
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public double extract_double()
{
//debug.log ("extract_double");
checkExtractBadOperation( TCKind._tk_double ) ;
return Double.longBitsToDouble(value);
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_longlong(long l)
{
//debug.log ("insert_longlong");
typeCode = orb.get_primitive_tc(TCKind._tk_longlong);
value = l;
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public long extract_longlong()
{
//debug.log ("extract_longlong");
checkExtractBadOperation( TCKind._tk_longlong ) ;
return value;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_ulonglong(long l)
{
//debug.log ("insert_ulonglong");
typeCode = orb.get_primitive_tc(TCKind._tk_ulonglong);
value = l;
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public long extract_ulonglong()
{
//debug.log ("extract_ulonglong");
checkExtractBadOperation( TCKind._tk_ulonglong ) ;
return value;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_boolean(boolean b)
{
//debug.log ("insert_boolean");
typeCode = orb.get_primitive_tc(TCKind._tk_boolean);
value = (b)? 1:0;
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public boolean extract_boolean()
{
//debug.log ("extract_boolean");
checkExtractBadOperation( TCKind._tk_boolean ) ;
return (value == 0)? false: true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_char(char c)
{
//debug.log ("insert_char");
typeCode = orb.get_primitive_tc(TCKind._tk_char);
value = c;
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public char extract_char()
{
//debug.log ("extract_char");
checkExtractBadOperation( TCKind._tk_char ) ;
return (char)value;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_wchar(char c)
{
//debug.log ("insert_wchar");
typeCode = orb.get_primitive_tc(TCKind._tk_wchar);
value = c;
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public char extract_wchar()
{
//debug.log ("extract_wchar");
checkExtractBadOperation( TCKind._tk_wchar ) ;
return (char)value;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_octet(byte b)
{
//debug.log ("insert_octet");
typeCode = orb.get_primitive_tc(TCKind._tk_octet);
value = b;
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public byte extract_octet()
{
//debug.log ("extract_octet");
checkExtractBadOperation( TCKind._tk_octet ) ;
return (byte)value;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_string(String s)
{
//debug.log ("insert_string");
// Make sure type code information for bounded strings is not erased
if (typeCode.kind() == TCKind.tk_string) {
int length = 0;
try {
length = typeCode.length();
} catch (BadKind bad) {
throw wrapper.badkindCannotOccur() ;
}
// Check if bounded strings length is not exceeded
if (length != 0 && s != null && s.length() > length) {
throw wrapper.badStringBounds( new Integer(s.length()),
new Integer(length) ) ;
}
} else {
typeCode = orb.get_primitive_tc(TCKind._tk_string);
}
object = s;
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public String extract_string()
{
//debug.log ("extract_string");
checkExtractBadOperation( TCKind._tk_string ) ;
return (String)object;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_wstring(String s)
{
//debug.log ("insert_wstring");
// Make sure type code information for bounded strings is not erased
if (typeCode.kind() == TCKind.tk_wstring) {
int length = 0;
try {
length = typeCode.length();
} catch (BadKind bad) {
throw wrapper.badkindCannotOccur() ;
}
// Check if bounded strings length is not exceeded
if (length != 0 && s != null && s.length() > length) {
throw wrapper.badStringBounds( new Integer(s.length()),
new Integer(length) ) ;
}
} else {
typeCode = orb.get_primitive_tc(TCKind._tk_wstring);
}
object = s;
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public String extract_wstring()
{
//debug.log ("extract_wstring");
checkExtractBadOperation( TCKind._tk_wstring ) ;
return (String)object;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_any(Any a)
{
//debug.log ("insert_any");
typeCode = orb.get_primitive_tc(TCKind._tk_any);
object = a;
stream = null;
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public Any extract_any()
{
//debug.log ("extract_any");
checkExtractBadOperation( TCKind._tk_any ) ;
return (Any)object;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_Object(org.omg.CORBA.Object o)
{
//debug.log ("insert_Object");
if ( o == null ) {
typeCode = orb.get_primitive_tc(TCKind._tk_objref);
} else {
if (StubAdapter.isStub(o)) {
String[] ids = StubAdapter.getTypeIds( o ) ;
typeCode = new TypeCodeImpl(orb, TCKind._tk_objref, ids[0], "");
} else {
throw wrapper.badInsertobjParam(
CompletionStatus.COMPLETED_MAYBE, o.getClass().getName() ) ;
}
}
object = o;
isInitialized = true;
}
/**
* A variant of the insertion operation that takes a typecode
* argument as well.
*/
public void insert_Object(org.omg.CORBA.Object o, TypeCode tc)
{
//debug.log ("insert_Object2");
try {
if ( tc.id().equals("IDL:omg.org/CORBA/Object:1.0") || o._is_a(tc.id()) )
{
typeCode = TypeCodeImpl.convertToNative(orb, tc);
object = o;
}
else {
throw wrapper.insertObjectIncompatible() ;
}
} catch ( Exception ex ) {
throw wrapper.insertObjectFailed(ex) ;
}
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public org.omg.CORBA.Object extract_Object()
{
//debug.log ("extract_Object");
if (!isInitialized)
throw wrapper.extractNotInitialized() ;
// Check if the object contained here is of the type in typeCode
org.omg.CORBA.Object obj = null;
try {
obj = (org.omg.CORBA.Object) object;
if (typeCode.id().equals("IDL:omg.org/CORBA/Object:1.0") || obj._is_a(typeCode.id())) {
return obj;
} else {
throw wrapper.extractObjectIncompatible() ;
}
} catch ( Exception ex ) {
throw wrapper.extractObjectFailed(ex);
}
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public void insert_TypeCode(TypeCode tc)
{
//debug.log ("insert_TypeCode");
typeCode = orb.get_primitive_tc(TCKind._tk_TypeCode);
object = tc;
isInitialized = true;
}
/**
* See the description of the <a href="#anyOps">general Any operations.</a>
*/
public TypeCode extract_TypeCode()
{
//debug.log ("extract_TypeCode");
checkExtractBadOperation( TCKind._tk_TypeCode ) ;
return (TypeCode)object;
}
/**
* @deprecated
*/
@Deprecated
public void insert_Principal(Principal p)
{
typeCode = orb.get_primitive_tc(TCKind._tk_Principal);
object = p;
isInitialized = true;
}
/**
* @deprecated
*/
@Deprecated
public Principal extract_Principal()
{
checkExtractBadOperation( TCKind._tk_Principal ) ;
return (Principal)object;
}
/**
* Note that the Serializable really should be an IDLEntity of
* some kind. It shouldn't just be an RMI-IIOP type. Currently,
* we accept and will produce RMI repIds with the latest
* calculations if given a non-IDLEntity Serializable.
*/
public Serializable extract_Value()
{
//debug.log ("extract_Value");
checkExtractBadOperationList( new int[] { TCKind._tk_value,
TCKind._tk_value_box, TCKind._tk_abstract_interface } ) ;
return (Serializable)object;
}
public void insert_Value(Serializable v)
{
//debug.log ("insert_Value");
object = v;
TypeCode tc;
if ( v == null ) {
tc = orb.get_primitive_tc (TCKind.tk_value);
} else {
// See note in getPrimitiveTypeCodeForClass. We
// have to use the latest type code fixes in this
// case since there is no way to know what ORB will
// actually send this Any. In RMI-IIOP, when using
// Util.writeAny, we can do the versioning correctly,
// and use the insert_Value(Serializable, TypeCode)
// method.
//
// The ORB singleton uses the latest version.
tc = createTypeCodeForClass (v.getClass(), (ORB)ORB.init());
}
typeCode = TypeCodeImpl.convertToNative(orb, tc);
isInitialized = true;
}
public void insert_Value(Serializable v, org.omg.CORBA.TypeCode t)
{
//debug.log ("insert_Value2");
object = v;
typeCode = TypeCodeImpl.convertToNative(orb, t);
isInitialized = true;
}
public void insert_fixed(java.math.BigDecimal value) {
typeCode = TypeCodeImpl.convertToNative(orb,
orb.create_fixed_tc(TypeCodeImpl.digits(value), TypeCodeImpl.scale(value)));
object = value;
isInitialized = true;
}
public void insert_fixed(java.math.BigDecimal value, org.omg.CORBA.TypeCode type)
{
try {
if (TypeCodeImpl.digits(value) > type.fixed_digits() ||
TypeCodeImpl.scale(value) > type.fixed_scale())
{
throw wrapper.fixedNotMatch() ;
}
} catch (org.omg.CORBA.TypeCodePackage.BadKind bk) {
// type isn't even of kind fixed
throw wrapper.fixedBadTypecode( bk ) ;
}
typeCode = TypeCodeImpl.convertToNative(orb, type);
object = value;
isInitialized = true;
}
public java.math.BigDecimal extract_fixed() {
checkExtractBadOperation( TCKind._tk_fixed ) ;
return (BigDecimal)object;
}
/**
* Utility method for insert_Value and Util.writeAny.
*
* The ORB passed in should have the desired ORBVersion. It
* is used to generate the type codes.
*/
public TypeCode createTypeCodeForClass (java.lang.Class c, ORB tcORB)
{
// Look in the cache first
TypeCodeImpl classTC = tcORB.getTypeCodeForClass(c);
if (classTC != null)
return classTC;
// All cases need to be able to create repository IDs.
//
// See bug 4391648 for more info about the tcORB in this
// case.
RepositoryIdStrings repStrs
= RepositoryIdFactory.getRepIdStringsFactory();
// Assertion: c instanceof Serializable?
if ( c.isArray() ) {
// Arrays - may recurse for multi-dimensional arrays
Class componentClass = c.getComponentType();
TypeCode embeddedType;
if ( componentClass.isPrimitive() ) {
embeddedType = getPrimitiveTypeCodeForClass(componentClass,
tcORB);
} else {
embeddedType = createTypeCodeForClass (componentClass,
tcORB);
}
TypeCode t = tcORB.create_sequence_tc (0, embeddedType);
String id = repStrs.createForJavaType(c);
return tcORB.create_value_box_tc (id, "Sequence", t);
} else if ( c == java.lang.String.class ) {
// Strings
TypeCode t = tcORB.create_string_tc (0);
String id = repStrs.createForJavaType(c);
return tcORB.create_value_box_tc (id, "StringValue", t);
}
// Anything else
// We know that this is a TypeCodeImpl since it is our ORB
classTC = (TypeCodeImpl)ValueUtility.createTypeCodeForClass(
tcORB, c, ORBUtility.createValueHandler());
// Intruct classTC to store its buffer
classTC.setCaching(true);
// Update the cache
tcORB.setTypeCodeForClass(c, classTC);
return classTC;
}
/**
* It looks like this was copied from io.ValueUtility at some
* point.
*
* It's used by createTypeCodeForClass. The tcORB passed in
* should have the desired ORB version, and is used to
* create the type codes.
*/
private TypeCode getPrimitiveTypeCodeForClass (Class c, ORB tcORB)
{
//debug.log ("getPrimitiveTypeCodeForClass");
if (c == Integer.TYPE) {
return tcORB.get_primitive_tc (TCKind.tk_long);
} else if (c == Byte.TYPE) {
return tcORB.get_primitive_tc (TCKind.tk_octet);
} else if (c == Long.TYPE) {
return tcORB.get_primitive_tc (TCKind.tk_longlong);
} else if (c == Float.TYPE) {
return tcORB.get_primitive_tc (TCKind.tk_float);
} else if (c == Double.TYPE) {
return tcORB.get_primitive_tc (TCKind.tk_double);
} else if (c == Short.TYPE) {
return tcORB.get_primitive_tc (TCKind.tk_short);
} else if (c == Character.TYPE) {
// For Merlin or later JDKs, or for foreign ORBs,
// we correctly say that a Java char maps to a
// CORBA wchar. For backwards compatibility
// with our older ORBs, we say it maps to a
// CORBA char. This is only used in RMI-IIOP
// in our javax.rmi.CORBA.Util delegate's
// writeAny method. In Java IDL, there's no way
// to know the ORB version that the Any will be
// sent out with -- it could be different than
// the one used to create the Any -- so we use the
// most recent version (see insert_Value).
if (ORBVersionFactory.getFOREIGN().compareTo(tcORB.getORBVersion()) == 0 ||
ORBVersionFactory.getNEWER().compareTo(tcORB.getORBVersion()) <= 0)
return tcORB.get_primitive_tc(TCKind.tk_wchar);
else
return tcORB.get_primitive_tc(TCKind.tk_char);
} else if (c == Boolean.TYPE) {
return tcORB.get_primitive_tc (TCKind.tk_boolean);
} else {
// _REVISIT_ Not sure if this is right.
return tcORB.get_primitive_tc (TCKind.tk_any);
}
}
// 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
public Any extractAny(TypeCode memberType, ORB orb) {
Any returnValue = orb.create_any();
OutputStream out = returnValue.create_output_stream();
TypeCodeImpl.convertToNative(orb, memberType).copy((InputStream)stream, out);
returnValue.read_value(out.create_input_stream(), memberType);
return returnValue;
}
// This method could very well be moved into TypeCodeImpl or a common utility class,
// but is has to be in this package.
static public Any extractAnyFromStream(TypeCode memberType, InputStream input, ORB orb) {
Any returnValue = orb.create_any();
OutputStream out = returnValue.create_output_stream();
TypeCodeImpl.convertToNative(orb, memberType).copy(input, out);
returnValue.read_value(out.create_input_stream(), memberType);
return returnValue;
}
// There is no other way for DynAnys to find out whether the Any is initialized.
public boolean isInitialized() {
return isInitialized;
}
}