| /* |
| * 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; |
| } |
| } |