/* * Copyright (c) 2000, 2004, 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.protocol.giopmsgheaders; import java.io.IOException; import java.lang.Class; import java.lang.reflect.Constructor; import java.nio.ByteBuffer; import java.util.Iterator; import org.omg.CORBA.CompletionStatus; import org.omg.CORBA.INTERNAL; import org.omg.CORBA.MARSHAL; import org.omg.CORBA.Principal; import org.omg.CORBA.SystemException; import org.omg.IOP.TaggedProfile; import com.sun.corba.se.pept.transport.ByteBufferPool; import com.sun.corba.se.spi.ior.ObjectKey; import com.sun.corba.se.spi.ior.ObjectId; import com.sun.corba.se.spi.ior.IOR; import com.sun.corba.se.spi.ior.ObjectKeyFactory; import com.sun.corba.se.spi.ior.iiop.IIOPProfile; import com.sun.corba.se.spi.ior.iiop.IIOPFactories; import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate ; import com.sun.corba.se.spi.ior.iiop.GIOPVersion; import com.sun.corba.se.spi.ior.iiop.RequestPartitioningComponent; import com.sun.corba.se.spi.logging.CORBALogDomains ; import com.sun.corba.se.spi.orb.ORB; import com.sun.corba.se.spi.transport.CorbaConnection; import com.sun.corba.se.spi.transport.ReadTimeouts; import com.sun.corba.se.spi.servicecontext.ServiceContexts; import com.sun.corba.se.impl.encoding.ByteBufferWithInfo; import com.sun.corba.se.impl.encoding.CDRInputStream_1_0; import com.sun.corba.se.impl.logging.ORBUtilSystemException ; import com.sun.corba.se.impl.orbutil.ORBUtility; import com.sun.corba.se.impl.orbutil.ORBConstants; import com.sun.corba.se.impl.orbutil.ORBClassLoader; import com.sun.corba.se.impl.protocol.AddressingDispositionException; /** * This class acts as the base class for the various GIOP message types. This * also serves as a factory to create various message types. We currently * support GIOP 1.0, 1.1 and 1.2 message types. * * @author Ram Jeyaraman 05/14/2000 */ public abstract class MessageBase implements Message{ // This is only used when the giopDebug flag is // turned on. public byte[] giopHeader; private ByteBuffer byteBuffer; private int threadPoolToUse; // (encodingVersion == 0x00) implies CDR encoding, // (encodingVersion > 0x00) implies Java serialization version. byte encodingVersion = (byte) Message.CDR_ENC_VERSION; private static ORBUtilSystemException wrapper = ORBUtilSystemException.get( CORBALogDomains.RPC_PROTOCOL ) ; // Static methods public static String typeToString(int type) { return typeToString((byte)type); } public static String typeToString(byte type) { String result = type + "/"; switch (type) { case GIOPRequest : result += "GIOPRequest"; break; case GIOPReply : result += "GIOPReply"; break; case GIOPCancelRequest : result += "GIOPCancelRequest"; break; case GIOPLocateRequest : result += "GIOPLocateRequest"; break; case GIOPLocateReply : result += "GIOPLocateReply"; break; case GIOPCloseConnection : result += "GIOPCloseConnection"; break; case GIOPMessageError : result += "GIOPMessageError"; break; case GIOPFragment : result += "GIOPFragment"; break; default : result += "Unknown"; break; } return result; } public static MessageBase readGIOPMessage(ORB orb, CorbaConnection connection) { MessageBase msg = readGIOPHeader(orb, connection); msg = (MessageBase)readGIOPBody(orb, connection, (Message)msg); return msg; } public static MessageBase readGIOPHeader(ORB orb, CorbaConnection connection) { MessageBase msg = null; ReadTimeouts readTimeouts = orb.getORBData().getTransportTCPReadTimeouts(); ByteBuffer buf = null; try { buf = connection.read(GIOPMessageHeaderLength, 0, GIOPMessageHeaderLength, readTimeouts.get_max_giop_header_time_to_wait()); } catch (IOException e) { throw wrapper.ioexceptionWhenReadingConnection(e); } if (orb.giopDebugFlag) { // Since this is executed in debug mode only the overhead of // using a View Buffer is not an issue. We'll also use a // read-only View Buffer so we don't disturb the state of // byteBuffer. dprint(".readGIOPHeader: " + typeToString(buf.get(7))); dprint(".readGIOPHeader: GIOP header is: "); ByteBuffer viewBuffer = buf.asReadOnlyBuffer(); viewBuffer.position(0).limit(GIOPMessageHeaderLength); ByteBufferWithInfo bbwi = new ByteBufferWithInfo(orb,viewBuffer); bbwi.buflen = GIOPMessageHeaderLength; CDRInputStream_1_0.printBuffer(bbwi); } // Sanity checks /* * check for magic corruption * check for version incompatibility * check if fragmentation is allowed based on mesg type. . 1.0 fragmentation disallowed; FragmentMessage is non-existent. . 1.1 only {Request, Reply} msgs maybe fragmented. . 1.2 only {Request, Reply, LocateRequest, LocateReply} msgs maybe fragmented. */ int b1, b2, b3, b4; b1 = (buf.get(0) << 24) & 0xFF000000; b2 = (buf.get(1) << 16) & 0x00FF0000; b3 = (buf.get(2) << 8) & 0x0000FF00; b4 = (buf.get(3) << 0) & 0x000000FF; int magic = (b1 | b2 | b3 | b4); if (magic != GIOPBigMagic) { // If Magic is incorrect, it is an error. // ACTION : send MessageError and close the connection. throw wrapper.giopMagicError( CompletionStatus.COMPLETED_MAYBE); } // Extract the encoding version from the request GIOP Version, // if it contains an encoding, and set GIOP version appropriately. // For Java serialization, we use GIOP Version 1.2 message format. byte requestEncodingVersion = Message.CDR_ENC_VERSION; if ((buf.get(4) == 0x0D) && (buf.get(5) <= Message.JAVA_ENC_VERSION) && (buf.get(5) > Message.CDR_ENC_VERSION) && orb.getORBData().isJavaSerializationEnabled()) { // Entering this block means the request is using Java encoding, // and the encoding version is <= this ORB's Java encoding version. requestEncodingVersion = buf.get(5); buf.put(4, (byte) 0x01); buf.put(5, (byte) 0x02); } GIOPVersion orbVersion = orb.getORBData().getGIOPVersion(); if (orb.giopDebugFlag) { dprint(".readGIOPHeader: Message GIOP version: " + buf.get(4) + '.' + buf.get(5)); dprint(".readGIOPHeader: ORB Max GIOP Version: " + orbVersion); } if ( (buf.get(4) > orbVersion.getMajor()) || ( (buf.get(4) == orbVersion.getMajor()) && (buf.get(5) > orbVersion.getMinor()) ) ) { // For requests, sending ORB should use the version info // published in the IOR or may choose to use a <= version // for requests. If the version is greater than published version, // it is an error. // For replies, the ORB should always receive a version it supports // or less, but never greater (except for MessageError) // ACTION : Send back a MessageError() with the the highest version // the server ORB supports, and close the connection. if ( buf.get(7) != GIOPMessageError ) { throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } } AreFragmentsAllowed(buf.get(4), buf.get(5), buf.get(6), buf.get(7)); // create appropriate messages types switch (buf.get(7)) { case GIOPRequest: if (orb.giopDebugFlag) { dprint(".readGIOPHeader: creating RequestMessage"); } //msg = new RequestMessage(orb.giopDebugFlag); if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 msg = new RequestMessage_1_0(orb); } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x01) ) { // 1.1 msg = new RequestMessage_1_1(orb); } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x02) ) { // 1.2 msg = new RequestMessage_1_2(orb); } else { throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } break; case GIOPLocateRequest: if (orb.giopDebugFlag) { dprint(".readGIOPHeader: creating LocateRequestMessage"); } //msg = new LocateRequestMessage(orb.giopDebugFlag); if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 msg = new LocateRequestMessage_1_0(orb); } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x01) ) { // 1.1 msg = new LocateRequestMessage_1_1(orb); } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x02) ) { // 1.2 msg = new LocateRequestMessage_1_2(orb); } else { throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } break; case GIOPCancelRequest: if (orb.giopDebugFlag) { dprint(".readGIOPHeader: creating CancelRequestMessage"); } //msg = new CancelRequestMessage(orb.giopDebugFlag); if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 msg = new CancelRequestMessage_1_0(); } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x01) ) { // 1.1 msg = new CancelRequestMessage_1_1(); } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x02) ) { // 1.2 msg = new CancelRequestMessage_1_2(); } else { throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } break; case GIOPReply: if (orb.giopDebugFlag) { dprint(".readGIOPHeader: creating ReplyMessage"); } //msg = new ReplyMessage(orb.giopDebugFlag); if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 msg = new ReplyMessage_1_0(orb); } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x01) ) { // 1.1 msg = new ReplyMessage_1_1(orb); } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x02) ) { // 1.2 msg = new ReplyMessage_1_2(orb); } else { throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } break; case GIOPLocateReply: if (orb.giopDebugFlag) { dprint(".readGIOPHeader: creating LocateReplyMessage"); } //msg = new LocateReplyMessage(orb.giopDebugFlag); if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 msg = new LocateReplyMessage_1_0(orb); } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x01) ) { // 1.1 msg = new LocateReplyMessage_1_1(orb); } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x02) ) { // 1.2 msg = new LocateReplyMessage_1_2(orb); } else { throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } break; case GIOPCloseConnection: case GIOPMessageError: if (orb.giopDebugFlag) { dprint(".readGIOPHeader: creating Message for CloseConnection or MessageError"); } // REVISIT a MessageError may contain the highest version server // can support. In such a case, a new request may be made with the // correct version or the connection be simply closed. Note the // connection may have been closed by the server. //msg = new Message(orb.giopDebugFlag); if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 msg = new Message_1_0(); } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x01) ) { // 1.1 msg = new Message_1_1(); } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x02) ) { // 1.2 msg = new Message_1_1(); } else { throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } break; case GIOPFragment: if (orb.giopDebugFlag) { dprint(".readGIOPHeader: creating FragmentMessage"); } //msg = new FragmentMessage(orb.giopDebugFlag); if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 // not possible (error checking done already) } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x01) ) { // 1.1 msg = new FragmentMessage_1_1(); } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x02) ) { // 1.2 msg = new FragmentMessage_1_2(); } else { throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } break; default: if (orb.giopDebugFlag) dprint(".readGIOPHeader: UNKNOWN MESSAGE TYPE: " + buf.get(7)); // unknown message type ? // ACTION : send MessageError and close the connection throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } // // Initialize the generic GIOP header instance variables. // if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 Message_1_0 msg10 = (Message_1_0) msg; msg10.magic = magic; msg10.GIOP_version = new GIOPVersion(buf.get(4), buf.get(5)); msg10.byte_order = (buf.get(6) == LITTLE_ENDIAN_BIT); // 'request partitioning' not supported on GIOP version 1.0 // so just use the default thread pool, 0. msg.threadPoolToUse = 0; msg10.message_type = buf.get(7); msg10.message_size = readSize(buf.get(8), buf.get(9), buf.get(10), buf.get(11), msg10.isLittleEndian()) + GIOPMessageHeaderLength; } else { // 1.1 & 1.2 Message_1_1 msg11 = (Message_1_1) msg; msg11.magic = magic; msg11.GIOP_version = new GIOPVersion(buf.get(4), buf.get(5)); msg11.flags = (byte)(buf.get(6) & TRAILING_TWO_BIT_BYTE_MASK); // IMPORTANT: For 'request partitioning', the thread pool to use // information is stored in the leading 6 bits of byte 6. // // IMPORTANT: Request partitioning is a PROPRIETARY EXTENSION !!! // // NOTE: Bitwise operators will promote a byte to an int before // performing a bitwise operation and bytes, ints, longs, etc // are signed types in Java. Thus, the need for the // THREAD_POOL_TO_USE_MASK operation. msg.threadPoolToUse = (buf.get(6) >>> 2) & THREAD_POOL_TO_USE_MASK; msg11.message_type = buf.get(7); msg11.message_size = readSize(buf.get(8), buf.get(9), buf.get(10), buf.get(11), msg11.isLittleEndian()) + GIOPMessageHeaderLength; } if (orb.giopDebugFlag) { // Since this is executed in debug mode only the overhead of // using a View Buffer is not an issue. We'll also use a // read-only View Buffer so we don't disturb the state of // byteBuffer. dprint(".readGIOPHeader: header construction complete."); // For debugging purposes, save the 12 bytes of the header ByteBuffer viewBuf = buf.asReadOnlyBuffer(); byte[] msgBuf = new byte[GIOPMessageHeaderLength]; viewBuf.position(0).limit(GIOPMessageHeaderLength); viewBuf.get(msgBuf,0,msgBuf.length); // REVISIT: is giopHeader still used? ((MessageBase)msg).giopHeader = msgBuf; } msg.setByteBuffer(buf); msg.setEncodingVersion(requestEncodingVersion); return msg; } public static Message readGIOPBody(ORB orb, CorbaConnection connection, Message msg) { ReadTimeouts readTimeouts = orb.getORBData().getTransportTCPReadTimeouts(); ByteBuffer buf = msg.getByteBuffer(); buf.position(MessageBase.GIOPMessageHeaderLength); int msgSizeMinusHeader = msg.getSize() - MessageBase.GIOPMessageHeaderLength; try { buf = connection.read(buf, GIOPMessageHeaderLength, msgSizeMinusHeader, readTimeouts.get_max_time_to_wait()); } catch (IOException e) { throw wrapper.ioexceptionWhenReadingConnection(e); } msg.setByteBuffer(buf); if (orb.giopDebugFlag) { dprint(".readGIOPBody: received message:"); ByteBuffer viewBuffer = buf.asReadOnlyBuffer(); viewBuffer.position(0).limit(msg.getSize()); ByteBufferWithInfo bbwi = new ByteBufferWithInfo(orb, viewBuffer); CDRInputStream_1_0.printBuffer(bbwi); } return msg; } private static RequestMessage createRequest( ORB orb, GIOPVersion gv, byte encodingVersion, int request_id, boolean response_expected, byte[] object_key, String operation, ServiceContexts service_contexts, Principal requesting_principal) { if (gv.equals(GIOPVersion.V1_0)) { // 1.0 return new RequestMessage_1_0(orb, service_contexts, request_id, response_expected, object_key, operation, requesting_principal); } else if (gv.equals(GIOPVersion.V1_1)) { // 1.1 return new RequestMessage_1_1(orb, service_contexts, request_id, response_expected, new byte[] { 0x00, 0x00, 0x00 }, object_key, operation, requesting_principal); } else if (gv.equals(GIOPVersion.V1_2)) { // 1.2 // Note: Currently we use response_expected flag to decide if the // call is oneway or not. Ideally, it is possible to expect a // response on a oneway call too, but we do not support it now. byte response_flags = 0x03; if (response_expected) { response_flags = 0x03; } else { response_flags = 0x00; } /* // REVISIT The following is the correct way to do it. This gives // more flexibility. if ((DII::INV_NO_RESPONSE == false) && response_expected) { response_flags = 0x03; // regular two-way } else if ((DII::INV_NO_RESPONSE == false) && !response_expected) { // this condition is not possible } else if ((DII::INV_NO_RESPONSE == true) && response_expected) { // oneway, but we need response for LocationForwards or // SystemExceptions. response_flags = 0x01; } else if ((DII::INV_NO_RESPONSE == true) && !response_expected) { // oneway, no response required response_flags = 0x00; } */ TargetAddress target = new TargetAddress(); target.object_key(object_key); RequestMessage msg = new RequestMessage_1_2(orb, request_id, response_flags, new byte[] { 0x00, 0x00, 0x00 }, target, operation, service_contexts); msg.setEncodingVersion(encodingVersion); return msg; } else { throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } } public static RequestMessage createRequest( ORB orb, GIOPVersion gv, byte encodingVersion, int request_id, boolean response_expected, IOR ior, short addrDisp, String operation, ServiceContexts service_contexts, Principal requesting_principal) { RequestMessage requestMessage = null; IIOPProfile profile = ior.getProfile(); if (addrDisp == KeyAddr.value) { // object key will be used for target addressing profile = ior.getProfile(); ObjectKey objKey = profile.getObjectKey(); byte[] object_key = objKey.getBytes(orb); requestMessage = createRequest(orb, gv, encodingVersion, request_id, response_expected, object_key, operation, service_contexts, requesting_principal); } else { if (!(gv.equals(GIOPVersion.V1_2))) { // only object_key based target addressing is allowed for // GIOP 1.0 & 1.1 throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } // Note: Currently we use response_expected flag to decide if the // call is oneway or not. Ideally, it is possible to expect a // response on a oneway call too, but we do not support it now. byte response_flags = 0x03; if (response_expected) { response_flags = 0x03; } else { response_flags = 0x00; } TargetAddress target = new TargetAddress(); if (addrDisp == ProfileAddr.value) { // iop profile will be used profile = ior.getProfile(); target.profile(profile.getIOPProfile()); } else if (addrDisp == ReferenceAddr.value) { // ior will be used IORAddressingInfo iorInfo = new IORAddressingInfo( 0, // profile index ior.getIOPIOR()); target.ior(iorInfo); } else { // invalid target addressing disposition value throw wrapper.illegalTargetAddressDisposition( CompletionStatus.COMPLETED_NO); } requestMessage = new RequestMessage_1_2(orb, request_id, response_flags, new byte[] { 0x00, 0x00, 0x00 }, target, operation, service_contexts); requestMessage.setEncodingVersion(encodingVersion); } if (gv.supportsIORIIOPProfileComponents()) { // add request partitioning thread pool to use info int poolToUse = 0; // default pool IIOPProfileTemplate temp = (IIOPProfileTemplate)profile.getTaggedProfileTemplate(); Iterator iter = temp.iteratorById(ORBConstants.TAG_REQUEST_PARTITIONING_ID); if (iter.hasNext()) { poolToUse = ((RequestPartitioningComponent)iter.next()).getRequestPartitioningId(); } if (poolToUse < ORBConstants.REQUEST_PARTITIONING_MIN_THREAD_POOL_ID || poolToUse > ORBConstants.REQUEST_PARTITIONING_MAX_THREAD_POOL_ID) { throw wrapper.invalidRequestPartitioningId(new Integer(poolToUse), new Integer(ORBConstants.REQUEST_PARTITIONING_MIN_THREAD_POOL_ID), new Integer(ORBConstants.REQUEST_PARTITIONING_MAX_THREAD_POOL_ID)); } requestMessage.setThreadPoolToUse(poolToUse); } return requestMessage; } public static ReplyMessage createReply( ORB orb, GIOPVersion gv, byte encodingVersion, int request_id, int reply_status, ServiceContexts service_contexts, IOR ior) { if (gv.equals(GIOPVersion.V1_0)) { // 1.0 return new ReplyMessage_1_0(orb, service_contexts, request_id, reply_status, ior); } else if (gv.equals(GIOPVersion.V1_1)) { // 1.1 return new ReplyMessage_1_1(orb, service_contexts, request_id, reply_status, ior); } else if (gv.equals(GIOPVersion.V1_2)) { // 1.2 ReplyMessage msg = new ReplyMessage_1_2(orb, request_id, reply_status, service_contexts, ior); msg.setEncodingVersion(encodingVersion); return msg; } else { throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } } public static LocateRequestMessage createLocateRequest( ORB orb, GIOPVersion gv, byte encodingVersion, int request_id, byte[] object_key) { if (gv.equals(GIOPVersion.V1_0)) { // 1.0 return new LocateRequestMessage_1_0(orb, request_id, object_key); } else if (gv.equals(GIOPVersion.V1_1)) { // 1.1 return new LocateRequestMessage_1_1(orb, request_id, object_key); } else if (gv.equals(GIOPVersion.V1_2)) { // 1.2 TargetAddress target = new TargetAddress(); target.object_key(object_key); LocateRequestMessage msg = new LocateRequestMessage_1_2(orb, request_id, target); msg.setEncodingVersion(encodingVersion); return msg; } else { throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } } public static LocateReplyMessage createLocateReply( ORB orb, GIOPVersion gv, byte encodingVersion, int request_id, int locate_status, IOR ior) { if (gv.equals(GIOPVersion.V1_0)) { // 1.0 return new LocateReplyMessage_1_0(orb, request_id, locate_status, ior); } else if (gv.equals(GIOPVersion.V1_1)) { // 1.1 return new LocateReplyMessage_1_1(orb, request_id, locate_status, ior); } else if (gv.equals(GIOPVersion.V1_2)) { // 1.2 LocateReplyMessage msg = new LocateReplyMessage_1_2(orb, request_id, locate_status, ior); msg.setEncodingVersion(encodingVersion); return msg; } else { throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } } public static CancelRequestMessage createCancelRequest( GIOPVersion gv, int request_id) { if (gv.equals(GIOPVersion.V1_0)) { // 1.0 return new CancelRequestMessage_1_0(request_id); } else if (gv.equals(GIOPVersion.V1_1)) { // 1.1 return new CancelRequestMessage_1_1(request_id); } else if (gv.equals(GIOPVersion.V1_2)) { // 1.2 return new CancelRequestMessage_1_2(request_id); } else { throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } } public static Message createCloseConnection(GIOPVersion gv) { if (gv.equals(GIOPVersion.V1_0)) { // 1.0 return new Message_1_0(Message.GIOPBigMagic, false, Message.GIOPCloseConnection, 0); } else if (gv.equals(GIOPVersion.V1_1)) { // 1.1 return new Message_1_1(Message.GIOPBigMagic, GIOPVersion.V1_1, FLAG_NO_FRAG_BIG_ENDIAN, Message.GIOPCloseConnection, 0); } else if (gv.equals(GIOPVersion.V1_2)) { // 1.2 return new Message_1_1(Message.GIOPBigMagic, GIOPVersion.V1_2, FLAG_NO_FRAG_BIG_ENDIAN, Message.GIOPCloseConnection, 0); } else { throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } } public static Message createMessageError(GIOPVersion gv) { if (gv.equals(GIOPVersion.V1_0)) { // 1.0 return new Message_1_0(Message.GIOPBigMagic, false, Message.GIOPMessageError, 0); } else if (gv.equals(GIOPVersion.V1_1)) { // 1.1 return new Message_1_1(Message.GIOPBigMagic, GIOPVersion.V1_1, FLAG_NO_FRAG_BIG_ENDIAN, Message.GIOPMessageError, 0); } else if (gv.equals(GIOPVersion.V1_2)) { // 1.2 return new Message_1_1(Message.GIOPBigMagic, GIOPVersion.V1_2, FLAG_NO_FRAG_BIG_ENDIAN, Message.GIOPMessageError, 0); } else { throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); } } public static FragmentMessage createFragmentMessage(GIOPVersion gv) { // This method is not currently used. // New fragment messages are always created from existing messages. // Creating a FragmentMessage from InputStream is done in // createFromStream(..) return null; } public static int getRequestId(Message msg) { switch (msg.getType()) { case GIOPRequest : return ((RequestMessage) msg).getRequestId(); case GIOPReply : return ((ReplyMessage) msg).getRequestId(); case GIOPLocateRequest : return ((LocateRequestMessage) msg).getRequestId(); case GIOPLocateReply : return ((LocateReplyMessage) msg).getRequestId(); case GIOPCancelRequest : return ((CancelRequestMessage) msg).getRequestId(); case GIOPFragment : return ((FragmentMessage) msg).getRequestId(); } throw wrapper.illegalGiopMsgType( CompletionStatus.COMPLETED_MAYBE); } /** * Set a flag in the given buffer (fragment bit, byte order bit, etc) */ public static void setFlag(ByteBuffer byteBuffer, int flag) { byte b = byteBuffer.get(6); b |= flag; byteBuffer.put(6,b); } /** * Clears a flag in the given buffer */ public static void clearFlag(byte[] buf, int flag) { buf[6] &= (0xFF ^ flag); } private static void AreFragmentsAllowed(byte major, byte minor, byte flag, byte msgType) { if ( (major == 0x01) && (minor == 0x00) ) { // 1.0 if (msgType == GIOPFragment) { throw wrapper.fragmentationDisallowed( CompletionStatus.COMPLETED_MAYBE); } } if ( (flag & MORE_FRAGMENTS_BIT) == MORE_FRAGMENTS_BIT ) { switch (msgType) { case GIOPCancelRequest : case GIOPCloseConnection : case GIOPMessageError : throw wrapper.fragmentationDisallowed( CompletionStatus.COMPLETED_MAYBE); case GIOPLocateRequest : case GIOPLocateReply : if ( (major == 0x01) && (minor == 0x01) ) { // 1.1 throw wrapper.fragmentationDisallowed( CompletionStatus.COMPLETED_MAYBE); } break; } } } /** * Construct an ObjectKey from a byte[]. * * @return ObjectKey the object key. */ static ObjectKey extractObjectKey(byte[] objKey, ORB orb) { try { if (objKey != null) { ObjectKey objectKey = orb.getObjectKeyFactory().create(objKey); if (objectKey != null) { return objectKey; } } } catch (Exception e) { // XXX log this exception } // This exception is thrown if any exceptions are raised while // extracting the object key or if the object key is empty. throw wrapper.invalidObjectKey(); } /** * Extract the object key from TargetAddress. * * @return ObjectKey the object key. */ static ObjectKey extractObjectKey(TargetAddress target, ORB orb) { short orbTargetAddrPref = orb.getORBData().getGIOPTargetAddressPreference(); short reqAddrDisp = target.discriminator(); switch (orbTargetAddrPref) { case ORBConstants.ADDR_DISP_OBJKEY : if (reqAddrDisp != KeyAddr.value) { throw new AddressingDispositionException(KeyAddr.value); } break; case ORBConstants.ADDR_DISP_PROFILE : if (reqAddrDisp != ProfileAddr.value) { throw new AddressingDispositionException(ProfileAddr.value); } break; case ORBConstants.ADDR_DISP_IOR : if (reqAddrDisp != ReferenceAddr.value) { throw new AddressingDispositionException(ReferenceAddr.value); } break; case ORBConstants.ADDR_DISP_HANDLE_ALL : break; default : throw wrapper.orbTargetAddrPreferenceInExtractObjectkeyInvalid() ; } try { switch (reqAddrDisp) { case KeyAddr.value : byte[] objKey = target.object_key(); if (objKey != null) { // AddressingDisposition::KeyAddr ObjectKey objectKey = orb.getObjectKeyFactory().create(objKey); if (objectKey != null) { return objectKey; } } break; case ProfileAddr.value : IIOPProfile iiopProfile = null; TaggedProfile profile = target.profile(); if (profile != null) { // AddressingDisposition::ProfileAddr iiopProfile = IIOPFactories.makeIIOPProfile(orb, profile); ObjectKey objectKey = iiopProfile.getObjectKey(); if (objectKey != null) { return objectKey; } } break; case ReferenceAddr.value : IORAddressingInfo iorInfo = target.ior(); if (iorInfo != null) { // AddressingDisposition::IORAddr profile = iorInfo.ior.profiles[iorInfo.selected_profile_index]; iiopProfile = IIOPFactories.makeIIOPProfile(orb, profile); ObjectKey objectKey = iiopProfile.getObjectKey(); if (objectKey != null) { return objectKey; } } break; default : // this cannot happen // There is no need for a explicit exception, since the // TargetAddressHelper.read() would have raised a BAD_OPERATION // exception by now. break; } } catch (Exception e) {} // This exception is thrown if any exceptions are raised while // extracting the object key from the TargetAddress or if all the // the valid TargetAddress::AddressingDispositions are empty. throw wrapper.invalidObjectKey() ; } private static int readSize(byte b1, byte b2, byte b3, byte b4, boolean littleEndian) { int a1, a2, a3, a4; if (!littleEndian) { a1 = (b1 << 24) & 0xFF000000; a2 = (b2 << 16) & 0x00FF0000; a3 = (b3 << 8) & 0x0000FF00; a4 = (b4 << 0) & 0x000000FF; } else { a1 = (b4 << 24) & 0xFF000000; a2 = (b3 << 16) & 0x00FF0000; a3 = (b2 << 8) & 0x0000FF00; a4 = (b1 << 0) & 0x000000FF; } return (a1 | a2 | a3 | a4); } static void nullCheck(Object obj) { if (obj == null) { throw wrapper.nullNotAllowed() ; } } static SystemException getSystemException( String exClassName, int minorCode, CompletionStatus completionStatus, String message, ORBUtilSystemException wrapper) { SystemException sysEx = null; try { Class clazz = ORBClassLoader.loadClass(exClassName); if (message == null) { sysEx = (SystemException) clazz.newInstance(); } else { Class[] types = { String.class }; Constructor constructor = clazz.getConstructor(types); Object[] args = { message }; sysEx = (SystemException)constructor.newInstance(args); } } catch (Exception someEx) { throw wrapper.badSystemExceptionInReply( CompletionStatus.COMPLETED_MAYBE, someEx ); } sysEx.minor = minorCode; sysEx.completed = completionStatus; return sysEx; } public void callback(MessageHandler handler) throws java.io.IOException { handler.handleInput(this); } public ByteBuffer getByteBuffer() { return byteBuffer; } public void setByteBuffer(ByteBuffer byteBuffer) { this.byteBuffer = byteBuffer; } public int getThreadPoolToUse() { return threadPoolToUse; } public byte getEncodingVersion() { return this.encodingVersion; } public void setEncodingVersion(byte version) { this.encodingVersion = version; } private static void dprint(String msg) { ORBUtility.dprint("MessageBase", msg); } }