MessageBase.java revision 608:7e06bf1dcb09
1/* 2 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.corba.se.impl.protocol.giopmsgheaders; 27 28import java.io.IOException; 29import java.lang.Class; 30import java.lang.reflect.Constructor; 31import java.nio.ByteBuffer; 32import java.util.Iterator; 33 34import org.omg.CORBA.CompletionStatus; 35import org.omg.CORBA.INTERNAL; 36import org.omg.CORBA.MARSHAL; 37import org.omg.CORBA.Principal; 38import org.omg.CORBA.SystemException; 39import org.omg.IOP.TaggedProfile; 40 41import com.sun.corba.se.pept.transport.ByteBufferPool; 42 43import com.sun.corba.se.spi.ior.ObjectKey; 44import com.sun.corba.se.spi.ior.ObjectId; 45import com.sun.corba.se.spi.ior.IOR; 46import com.sun.corba.se.spi.ior.ObjectKeyFactory; 47import com.sun.corba.se.spi.ior.iiop.IIOPProfile; 48import com.sun.corba.se.spi.ior.iiop.IIOPFactories; 49import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate ; 50import com.sun.corba.se.spi.ior.iiop.GIOPVersion; 51import com.sun.corba.se.spi.ior.iiop.RequestPartitioningComponent; 52import com.sun.corba.se.spi.logging.CORBALogDomains ; 53import com.sun.corba.se.spi.orb.ORB; 54import com.sun.corba.se.spi.transport.CorbaConnection; 55import com.sun.corba.se.spi.transport.ReadTimeouts; 56 57import com.sun.corba.se.spi.servicecontext.ServiceContexts; 58import com.sun.corba.se.impl.encoding.ByteBufferWithInfo; 59import com.sun.corba.se.impl.encoding.CDRInputStream_1_0; 60import com.sun.corba.se.impl.logging.ORBUtilSystemException ; 61import com.sun.corba.se.impl.orbutil.ORBUtility; 62import com.sun.corba.se.impl.orbutil.ORBConstants; 63import com.sun.corba.se.impl.protocol.AddressingDispositionException; 64 65import sun.corba.SharedSecrets; 66 67/** 68 * This class acts as the base class for the various GIOP message types. This 69 * also serves as a factory to create various message types. We currently 70 * support GIOP 1.0, 1.1 and 1.2 message types. 71 * 72 * @author Ram Jeyaraman 05/14/2000 73 */ 74 75public abstract class MessageBase implements Message{ 76 77 // This is only used when the giopDebug flag is 78 // turned on. 79 public byte[] giopHeader; 80 private ByteBuffer byteBuffer; 81 private int threadPoolToUse; 82 83 // (encodingVersion == 0x00) implies CDR encoding, 84 // (encodingVersion > 0x00) implies Java serialization version. 85 byte encodingVersion = (byte) Message.CDR_ENC_VERSION; 86 87 private static ORBUtilSystemException wrapper = 88 ORBUtilSystemException.get( CORBALogDomains.RPC_PROTOCOL ) ; 89 90 // Static methods 91 92 public static String typeToString(int type) 93 { 94 return typeToString((byte)type); 95 } 96 97 public static String typeToString(byte type) 98 { 99 String result = type + "/"; 100 switch (type) { 101 case GIOPRequest : result += "GIOPRequest"; break; 102 case GIOPReply : result += "GIOPReply"; break; 103 case GIOPCancelRequest : result += "GIOPCancelRequest"; break; 104 case GIOPLocateRequest : result += "GIOPLocateRequest"; break; 105 case GIOPLocateReply : result += "GIOPLocateReply"; break; 106 case GIOPCloseConnection : result += "GIOPCloseConnection"; break; 107 case GIOPMessageError : result += "GIOPMessageError"; break; 108 case GIOPFragment : result += "GIOPFragment"; break; 109 default : result += "Unknown"; break; 110 } 111 return result; 112 } 113 114 public static MessageBase readGIOPMessage(ORB orb, CorbaConnection connection) 115 { 116 MessageBase msg = readGIOPHeader(orb, connection); 117 msg = (MessageBase)readGIOPBody(orb, connection, (Message)msg); 118 return msg; 119 } 120 121 public static MessageBase readGIOPHeader(ORB orb, CorbaConnection connection) 122 { 123 MessageBase msg = null; 124 ReadTimeouts readTimeouts = 125 orb.getORBData().getTransportTCPReadTimeouts(); 126 127 ByteBuffer buf = null; 128 129 try { 130 buf = connection.read(GIOPMessageHeaderLength, 131 0, GIOPMessageHeaderLength, 132 readTimeouts.get_max_giop_header_time_to_wait()); 133 } catch (IOException e) { 134 throw wrapper.ioexceptionWhenReadingConnection(e); 135 } 136 137 if (orb.giopDebugFlag) { 138 // Since this is executed in debug mode only the overhead of 139 // using a View Buffer is not an issue. We'll also use a 140 // read-only View Buffer so we don't disturb the state of 141 // byteBuffer. 142 dprint(".readGIOPHeader: " + typeToString(buf.get(7))); 143 dprint(".readGIOPHeader: GIOP header is: "); 144 ByteBuffer viewBuffer = buf.asReadOnlyBuffer(); 145 viewBuffer.position(0).limit(GIOPMessageHeaderLength); 146 ByteBufferWithInfo bbwi = new ByteBufferWithInfo(orb,viewBuffer); 147 bbwi.buflen = GIOPMessageHeaderLength; 148 CDRInputStream_1_0.printBuffer(bbwi); 149 } 150 151 // Sanity checks 152 153 /* 154 * check for magic corruption 155 * check for version incompatibility 156 * check if fragmentation is allowed based on mesg type. 157 . 1.0 fragmentation disallowed; FragmentMessage is non-existent. 158 . 1.1 only {Request, Reply} msgs maybe fragmented. 159 . 1.2 only {Request, Reply, LocateRequest, LocateReply} msgs 160 maybe fragmented. 161 */ 162 163 int b1, b2, b3, b4; 164 165 b1 = (buf.get(0) << 24) & 0xFF000000; 166 b2 = (buf.get(1) << 16) & 0x00FF0000; 167 b3 = (buf.get(2) << 8) & 0x0000FF00; 168 b4 = (buf.get(3) << 0) & 0x000000FF; 169 int magic = (b1 | b2 | b3 | b4); 170 171 if (magic != GIOPBigMagic) { 172 // If Magic is incorrect, it is an error. 173 // ACTION : send MessageError and close the connection. 174 throw wrapper.giopMagicError( CompletionStatus.COMPLETED_MAYBE); 175 } 176 177 // Extract the encoding version from the request GIOP Version, 178 // if it contains an encoding, and set GIOP version appropriately. 179 // For Java serialization, we use GIOP Version 1.2 message format. 180 byte requestEncodingVersion = Message.CDR_ENC_VERSION; 181 if ((buf.get(4) == 0x0D) && 182 (buf.get(5) <= Message.JAVA_ENC_VERSION) && 183 (buf.get(5) > Message.CDR_ENC_VERSION) && 184 orb.getORBData().isJavaSerializationEnabled()) { 185 // Entering this block means the request is using Java encoding, 186 // and the encoding version is <= this ORB's Java encoding version. 187 requestEncodingVersion = buf.get(5); 188 buf.put(4, (byte) 0x01); 189 buf.put(5, (byte) 0x02); 190 } 191 192 GIOPVersion orbVersion = orb.getORBData().getGIOPVersion(); 193 194 if (orb.giopDebugFlag) { 195 dprint(".readGIOPHeader: Message GIOP version: " 196 + buf.get(4) + '.' + buf.get(5)); 197 dprint(".readGIOPHeader: ORB Max GIOP Version: " 198 + orbVersion); 199 } 200 201 if ( (buf.get(4) > orbVersion.getMajor()) || 202 ( (buf.get(4) == orbVersion.getMajor()) && (buf.get(5) > orbVersion.getMinor()) ) 203 ) { 204 // For requests, sending ORB should use the version info 205 // published in the IOR or may choose to use a <= version 206 // for requests. If the version is greater than published version, 207 // it is an error. 208 209 // For replies, the ORB should always receive a version it supports 210 // or less, but never greater (except for MessageError) 211 212 // ACTION : Send back a MessageError() with the the highest version 213 // the server ORB supports, and close the connection. 214 if ( buf.get(7) != GIOPMessageError ) { 215 throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE); 216 } 217 } 218 219 AreFragmentsAllowed(buf.get(4), buf.get(5), buf.get(6), buf.get(7)); 220 221 // create appropriate messages types 222 223 switch (buf.get(7)) { 224 225 case GIOPRequest: 226 if (orb.giopDebugFlag) { 227 dprint(".readGIOPHeader: creating RequestMessage"); 228 } 229 //msg = new RequestMessage(orb.giopDebugFlag); 230 if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 231 msg = new RequestMessage_1_0(orb); 232 } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x01) ) { // 1.1 233 msg = new RequestMessage_1_1(orb); 234 } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x02) ) { // 1.2 235 msg = new RequestMessage_1_2(orb); 236 } else { 237 throw wrapper.giopVersionError( 238 CompletionStatus.COMPLETED_MAYBE); 239 } 240 break; 241 242 case GIOPLocateRequest: 243 if (orb.giopDebugFlag) { 244 dprint(".readGIOPHeader: creating LocateRequestMessage"); 245 } 246 //msg = new LocateRequestMessage(orb.giopDebugFlag); 247 if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 248 msg = new LocateRequestMessage_1_0(orb); 249 } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x01) ) { // 1.1 250 msg = new LocateRequestMessage_1_1(orb); 251 } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x02) ) { // 1.2 252 msg = new LocateRequestMessage_1_2(orb); 253 } else { 254 throw wrapper.giopVersionError( 255 CompletionStatus.COMPLETED_MAYBE); 256 } 257 break; 258 259 case GIOPCancelRequest: 260 if (orb.giopDebugFlag) { 261 dprint(".readGIOPHeader: creating CancelRequestMessage"); 262 } 263 //msg = new CancelRequestMessage(orb.giopDebugFlag); 264 if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 265 msg = new CancelRequestMessage_1_0(); 266 } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x01) ) { // 1.1 267 msg = new CancelRequestMessage_1_1(); 268 } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x02) ) { // 1.2 269 msg = new CancelRequestMessage_1_2(); 270 } else { 271 throw wrapper.giopVersionError( 272 CompletionStatus.COMPLETED_MAYBE); 273 } 274 break; 275 276 case GIOPReply: 277 if (orb.giopDebugFlag) { 278 dprint(".readGIOPHeader: creating ReplyMessage"); 279 } 280 //msg = new ReplyMessage(orb.giopDebugFlag); 281 if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 282 msg = new ReplyMessage_1_0(orb); 283 } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x01) ) { // 1.1 284 msg = new ReplyMessage_1_1(orb); 285 } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x02) ) { // 1.2 286 msg = new ReplyMessage_1_2(orb); 287 } else { 288 throw wrapper.giopVersionError( 289 CompletionStatus.COMPLETED_MAYBE); 290 } 291 break; 292 293 case GIOPLocateReply: 294 if (orb.giopDebugFlag) { 295 dprint(".readGIOPHeader: creating LocateReplyMessage"); 296 } 297 //msg = new LocateReplyMessage(orb.giopDebugFlag); 298 if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 299 msg = new LocateReplyMessage_1_0(orb); 300 } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x01) ) { // 1.1 301 msg = new LocateReplyMessage_1_1(orb); 302 } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x02) ) { // 1.2 303 msg = new LocateReplyMessage_1_2(orb); 304 } else { 305 throw wrapper.giopVersionError( 306 CompletionStatus.COMPLETED_MAYBE); 307 } 308 break; 309 310 case GIOPCloseConnection: 311 case GIOPMessageError: 312 if (orb.giopDebugFlag) { 313 dprint(".readGIOPHeader: creating Message for CloseConnection or MessageError"); 314 } 315 // REVISIT a MessageError may contain the highest version server 316 // can support. In such a case, a new request may be made with the 317 // correct version or the connection be simply closed. Note the 318 // connection may have been closed by the server. 319 //msg = new Message(orb.giopDebugFlag); 320 if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 321 msg = new Message_1_0(); 322 } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x01) ) { // 1.1 323 msg = new Message_1_1(); 324 } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x02) ) { // 1.2 325 msg = new Message_1_1(); 326 } else { 327 throw wrapper.giopVersionError( 328 CompletionStatus.COMPLETED_MAYBE); 329 } 330 break; 331 332 case GIOPFragment: 333 if (orb.giopDebugFlag) { 334 dprint(".readGIOPHeader: creating FragmentMessage"); 335 } 336 //msg = new FragmentMessage(orb.giopDebugFlag); 337 if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 338 // not possible (error checking done already) 339 } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x01) ) { // 1.1 340 msg = new FragmentMessage_1_1(); 341 } else if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x02) ) { // 1.2 342 msg = new FragmentMessage_1_2(); 343 } else { 344 throw wrapper.giopVersionError( 345 CompletionStatus.COMPLETED_MAYBE); 346 } 347 break; 348 349 default: 350 if (orb.giopDebugFlag) 351 dprint(".readGIOPHeader: UNKNOWN MESSAGE TYPE: " 352 + buf.get(7)); 353 // unknown message type ? 354 // ACTION : send MessageError and close the connection 355 throw wrapper.giopVersionError( 356 CompletionStatus.COMPLETED_MAYBE); 357 } 358 359 // 360 // Initialize the generic GIOP header instance variables. 361 // 362 363 if ( (buf.get(4) == 0x01) && (buf.get(5) == 0x00) ) { // 1.0 364 Message_1_0 msg10 = (Message_1_0) msg; 365 msg10.magic = magic; 366 msg10.GIOP_version = new GIOPVersion(buf.get(4), buf.get(5)); 367 msg10.byte_order = (buf.get(6) == LITTLE_ENDIAN_BIT); 368 // 'request partitioning' not supported on GIOP version 1.0 369 // so just use the default thread pool, 0. 370 msg.threadPoolToUse = 0; 371 msg10.message_type = buf.get(7); 372 msg10.message_size = readSize(buf.get(8), buf.get(9), buf.get(10), buf.get(11), 373 msg10.isLittleEndian()) + 374 GIOPMessageHeaderLength; 375 } else { // 1.1 & 1.2 376 Message_1_1 msg11 = (Message_1_1) msg; 377 msg11.magic = magic; 378 msg11.GIOP_version = new GIOPVersion(buf.get(4), buf.get(5)); 379 msg11.flags = (byte)(buf.get(6) & TRAILING_TWO_BIT_BYTE_MASK); 380 // IMPORTANT: For 'request partitioning', the thread pool to use 381 // information is stored in the leading 6 bits of byte 6. 382 // 383 // IMPORTANT: Request partitioning is a PROPRIETARY EXTENSION !!! 384 // 385 // NOTE: Bitwise operators will promote a byte to an int before 386 // performing a bitwise operation and bytes, ints, longs, etc 387 // are signed types in Java. Thus, the need for the 388 // THREAD_POOL_TO_USE_MASK operation. 389 msg.threadPoolToUse = (buf.get(6) >>> 2) & THREAD_POOL_TO_USE_MASK; 390 msg11.message_type = buf.get(7); 391 msg11.message_size = 392 readSize(buf.get(8), buf.get(9), buf.get(10), buf.get(11), 393 msg11.isLittleEndian()) + GIOPMessageHeaderLength; 394 } 395 396 397 if (orb.giopDebugFlag) { 398 // Since this is executed in debug mode only the overhead of 399 // using a View Buffer is not an issue. We'll also use a 400 // read-only View Buffer so we don't disturb the state of 401 // byteBuffer. 402 dprint(".readGIOPHeader: header construction complete."); 403 404 // For debugging purposes, save the 12 bytes of the header 405 ByteBuffer viewBuf = buf.asReadOnlyBuffer(); 406 byte[] msgBuf = new byte[GIOPMessageHeaderLength]; 407 viewBuf.position(0).limit(GIOPMessageHeaderLength); 408 viewBuf.get(msgBuf,0,msgBuf.length); 409 // REVISIT: is giopHeader still used? 410 ((MessageBase)msg).giopHeader = msgBuf; 411 } 412 413 msg.setByteBuffer(buf); 414 msg.setEncodingVersion(requestEncodingVersion); 415 416 return msg; 417 } 418 419 public static Message readGIOPBody(ORB orb, 420 CorbaConnection connection, 421 Message msg) 422 { 423 ReadTimeouts readTimeouts = 424 orb.getORBData().getTransportTCPReadTimeouts(); 425 ByteBuffer buf = msg.getByteBuffer(); 426 427 buf.position(MessageBase.GIOPMessageHeaderLength); 428 int msgSizeMinusHeader = 429 msg.getSize() - MessageBase.GIOPMessageHeaderLength; 430 try { 431 buf = connection.read(buf, 432 GIOPMessageHeaderLength, msgSizeMinusHeader, 433 readTimeouts.get_max_time_to_wait()); 434 } catch (IOException e) { 435 throw wrapper.ioexceptionWhenReadingConnection(e); 436 } 437 438 msg.setByteBuffer(buf); 439 440 if (orb.giopDebugFlag) { 441 dprint(".readGIOPBody: received message:"); 442 ByteBuffer viewBuffer = buf.asReadOnlyBuffer(); 443 viewBuffer.position(0).limit(msg.getSize()); 444 ByteBufferWithInfo bbwi = new ByteBufferWithInfo(orb, viewBuffer); 445 CDRInputStream_1_0.printBuffer(bbwi); 446 } 447 448 return msg; 449 } 450 451 private static RequestMessage createRequest( 452 ORB orb, GIOPVersion gv, byte encodingVersion, int request_id, 453 boolean response_expected, byte[] object_key, String operation, 454 ServiceContexts service_contexts, Principal requesting_principal) { 455 456 if (gv.equals(GIOPVersion.V1_0)) { // 1.0 457 return new RequestMessage_1_0(orb, service_contexts, request_id, 458 response_expected, object_key, 459 operation, requesting_principal); 460 } else if (gv.equals(GIOPVersion.V1_1)) { // 1.1 461 return new RequestMessage_1_1(orb, service_contexts, request_id, 462 response_expected, new byte[] { 0x00, 0x00, 0x00 }, 463 object_key, operation, requesting_principal); 464 } else if (gv.equals(GIOPVersion.V1_2)) { // 1.2 465 // Note: Currently we use response_expected flag to decide if the 466 // call is oneway or not. Ideally, it is possible to expect a 467 // response on a oneway call too, but we do not support it now. 468 byte response_flags = 0x03; 469 if (response_expected) { 470 response_flags = 0x03; 471 } else { 472 response_flags = 0x00; 473 } 474 /* 475 // REVISIT The following is the correct way to do it. This gives 476 // more flexibility. 477 if ((DII::INV_NO_RESPONSE == false) && response_expected) { 478 response_flags = 0x03; // regular two-way 479 } else if ((DII::INV_NO_RESPONSE == false) && !response_expected) { 480 // this condition is not possible 481 } else if ((DII::INV_NO_RESPONSE == true) && response_expected) { 482 // oneway, but we need response for LocationForwards or 483 // SystemExceptions. 484 response_flags = 0x01; 485 } else if ((DII::INV_NO_RESPONSE == true) && !response_expected) { 486 // oneway, no response required 487 response_flags = 0x00; 488 } 489 */ 490 TargetAddress target = new TargetAddress(); 491 target.object_key(object_key); 492 RequestMessage msg = 493 new RequestMessage_1_2(orb, request_id, response_flags, 494 new byte[] { 0x00, 0x00, 0x00 }, 495 target, operation, service_contexts); 496 msg.setEncodingVersion(encodingVersion); 497 return msg; 498 } else { 499 throw wrapper.giopVersionError( 500 CompletionStatus.COMPLETED_MAYBE); 501 } 502 } 503 504 public static RequestMessage createRequest( 505 ORB orb, GIOPVersion gv, byte encodingVersion, int request_id, 506 boolean response_expected, IOR ior, 507 short addrDisp, String operation, 508 ServiceContexts service_contexts, Principal requesting_principal) { 509 510 RequestMessage requestMessage = null; 511 IIOPProfile profile = ior.getProfile(); 512 513 if (addrDisp == KeyAddr.value) { 514 // object key will be used for target addressing 515 profile = ior.getProfile(); 516 ObjectKey objKey = profile.getObjectKey(); 517 byte[] object_key = objKey.getBytes(orb); 518 requestMessage = 519 createRequest(orb, gv, encodingVersion, request_id, 520 response_expected, object_key, 521 operation, service_contexts, 522 requesting_principal); 523 } else { 524 525 if (!(gv.equals(GIOPVersion.V1_2))) { 526 // only object_key based target addressing is allowed for 527 // GIOP 1.0 & 1.1 528 throw wrapper.giopVersionError( 529 CompletionStatus.COMPLETED_MAYBE); 530 } 531 532 // Note: Currently we use response_expected flag to decide if the 533 // call is oneway or not. Ideally, it is possible to expect a 534 // response on a oneway call too, but we do not support it now. 535 byte response_flags = 0x03; 536 if (response_expected) { 537 response_flags = 0x03; 538 } else { 539 response_flags = 0x00; 540 } 541 542 TargetAddress target = new TargetAddress(); 543 if (addrDisp == ProfileAddr.value) { // iop profile will be used 544 profile = ior.getProfile(); 545 target.profile(profile.getIOPProfile()); 546 } else if (addrDisp == ReferenceAddr.value) { // ior will be used 547 IORAddressingInfo iorInfo = 548 new IORAddressingInfo( 0, // profile index 549 ior.getIOPIOR()); 550 target.ior(iorInfo); 551 } else { 552 // invalid target addressing disposition value 553 throw wrapper.illegalTargetAddressDisposition( 554 CompletionStatus.COMPLETED_NO); 555 } 556 557 requestMessage = 558 new RequestMessage_1_2(orb, request_id, response_flags, 559 new byte[] { 0x00, 0x00, 0x00 }, target, 560 operation, service_contexts); 561 requestMessage.setEncodingVersion(encodingVersion); 562 } 563 564 if (gv.supportsIORIIOPProfileComponents()) { 565 // add request partitioning thread pool to use info 566 int poolToUse = 0; // default pool 567 IIOPProfileTemplate temp = 568 (IIOPProfileTemplate)profile.getTaggedProfileTemplate(); 569 Iterator iter = 570 temp.iteratorById(ORBConstants.TAG_REQUEST_PARTITIONING_ID); 571 if (iter.hasNext()) { 572 poolToUse = 573 ((RequestPartitioningComponent)iter.next()).getRequestPartitioningId(); 574 } 575 576 if (poolToUse < ORBConstants.REQUEST_PARTITIONING_MIN_THREAD_POOL_ID || 577 poolToUse > ORBConstants.REQUEST_PARTITIONING_MAX_THREAD_POOL_ID) { 578 throw wrapper.invalidRequestPartitioningId(new Integer(poolToUse), 579 new Integer(ORBConstants.REQUEST_PARTITIONING_MIN_THREAD_POOL_ID), 580 new Integer(ORBConstants.REQUEST_PARTITIONING_MAX_THREAD_POOL_ID)); 581 } 582 requestMessage.setThreadPoolToUse(poolToUse); 583 } 584 585 return requestMessage; 586 } 587 588 public static ReplyMessage createReply( 589 ORB orb, GIOPVersion gv, byte encodingVersion, int request_id, 590 int reply_status, ServiceContexts service_contexts, IOR ior) { 591 592 if (gv.equals(GIOPVersion.V1_0)) { // 1.0 593 return new ReplyMessage_1_0(orb, service_contexts, request_id, 594 reply_status, ior); 595 } else if (gv.equals(GIOPVersion.V1_1)) { // 1.1 596 return new ReplyMessage_1_1(orb, service_contexts, request_id, 597 reply_status, ior); 598 } else if (gv.equals(GIOPVersion.V1_2)) { // 1.2 599 ReplyMessage msg = 600 new ReplyMessage_1_2(orb, request_id, reply_status, 601 service_contexts, ior); 602 msg.setEncodingVersion(encodingVersion); 603 return msg; 604 } else { 605 throw wrapper.giopVersionError( 606 CompletionStatus.COMPLETED_MAYBE); 607 } 608 } 609 610 public static LocateRequestMessage createLocateRequest( 611 ORB orb, GIOPVersion gv, byte encodingVersion, 612 int request_id, byte[] object_key) { 613 614 if (gv.equals(GIOPVersion.V1_0)) { // 1.0 615 return new LocateRequestMessage_1_0(orb, request_id, object_key); 616 } else if (gv.equals(GIOPVersion.V1_1)) { // 1.1 617 return new LocateRequestMessage_1_1(orb, request_id, object_key); 618 } else if (gv.equals(GIOPVersion.V1_2)) { // 1.2 619 TargetAddress target = new TargetAddress(); 620 target.object_key(object_key); 621 LocateRequestMessage msg = 622 new LocateRequestMessage_1_2(orb, request_id, target); 623 msg.setEncodingVersion(encodingVersion); 624 return msg; 625 } else { 626 throw wrapper.giopVersionError( 627 CompletionStatus.COMPLETED_MAYBE); 628 } 629 } 630 631 public static LocateReplyMessage createLocateReply( 632 ORB orb, GIOPVersion gv, byte encodingVersion, 633 int request_id, int locate_status, IOR ior) { 634 635 if (gv.equals(GIOPVersion.V1_0)) { // 1.0 636 return new LocateReplyMessage_1_0(orb, request_id, 637 locate_status, ior); 638 } else if (gv.equals(GIOPVersion.V1_1)) { // 1.1 639 return new LocateReplyMessage_1_1(orb, request_id, 640 locate_status, ior); 641 } else if (gv.equals(GIOPVersion.V1_2)) { // 1.2 642 LocateReplyMessage msg = 643 new LocateReplyMessage_1_2(orb, request_id, 644 locate_status, ior); 645 msg.setEncodingVersion(encodingVersion); 646 return msg; 647 } else { 648 throw wrapper.giopVersionError( 649 CompletionStatus.COMPLETED_MAYBE); 650 } 651 } 652 653 public static CancelRequestMessage createCancelRequest( 654 GIOPVersion gv, int request_id) { 655 656 if (gv.equals(GIOPVersion.V1_0)) { // 1.0 657 return new CancelRequestMessage_1_0(request_id); 658 } else if (gv.equals(GIOPVersion.V1_1)) { // 1.1 659 return new CancelRequestMessage_1_1(request_id); 660 } else if (gv.equals(GIOPVersion.V1_2)) { // 1.2 661 return new CancelRequestMessage_1_2(request_id); 662 } else { 663 throw wrapper.giopVersionError( 664 CompletionStatus.COMPLETED_MAYBE); 665 } 666 } 667 668 public static Message createCloseConnection(GIOPVersion gv) { 669 if (gv.equals(GIOPVersion.V1_0)) { // 1.0 670 return new Message_1_0(Message.GIOPBigMagic, false, 671 Message.GIOPCloseConnection, 0); 672 } else if (gv.equals(GIOPVersion.V1_1)) { // 1.1 673 return new Message_1_1(Message.GIOPBigMagic, GIOPVersion.V1_1, 674 FLAG_NO_FRAG_BIG_ENDIAN, 675 Message.GIOPCloseConnection, 0); 676 } else if (gv.equals(GIOPVersion.V1_2)) { // 1.2 677 return new Message_1_1(Message.GIOPBigMagic, GIOPVersion.V1_2, 678 FLAG_NO_FRAG_BIG_ENDIAN, 679 Message.GIOPCloseConnection, 0); 680 } else { 681 throw wrapper.giopVersionError( 682 CompletionStatus.COMPLETED_MAYBE); 683 } 684 } 685 686 public static Message createMessageError(GIOPVersion gv) { 687 if (gv.equals(GIOPVersion.V1_0)) { // 1.0 688 return new Message_1_0(Message.GIOPBigMagic, false, 689 Message.GIOPMessageError, 0); 690 } else if (gv.equals(GIOPVersion.V1_1)) { // 1.1 691 return new Message_1_1(Message.GIOPBigMagic, GIOPVersion.V1_1, 692 FLAG_NO_FRAG_BIG_ENDIAN, 693 Message.GIOPMessageError, 0); 694 } else if (gv.equals(GIOPVersion.V1_2)) { // 1.2 695 return new Message_1_1(Message.GIOPBigMagic, GIOPVersion.V1_2, 696 FLAG_NO_FRAG_BIG_ENDIAN, 697 Message.GIOPMessageError, 0); 698 } else { 699 throw wrapper.giopVersionError( 700 CompletionStatus.COMPLETED_MAYBE); 701 } 702 } 703 704 public static FragmentMessage createFragmentMessage(GIOPVersion gv) { 705 // This method is not currently used. 706 // New fragment messages are always created from existing messages. 707 // Creating a FragmentMessage from InputStream is done in 708 // createFromStream(..) 709 return null; 710 } 711 712 public static int getRequestId(Message msg) { 713 switch (msg.getType()) { 714 case GIOPRequest : 715 return ((RequestMessage) msg).getRequestId(); 716 case GIOPReply : 717 return ((ReplyMessage) msg).getRequestId(); 718 case GIOPLocateRequest : 719 return ((LocateRequestMessage) msg).getRequestId(); 720 case GIOPLocateReply : 721 return ((LocateReplyMessage) msg).getRequestId(); 722 case GIOPCancelRequest : 723 return ((CancelRequestMessage) msg).getRequestId(); 724 case GIOPFragment : 725 return ((FragmentMessage) msg).getRequestId(); 726 } 727 728 throw wrapper.illegalGiopMsgType( 729 CompletionStatus.COMPLETED_MAYBE); 730 } 731 732 /** 733 * Set a flag in the given buffer (fragment bit, byte order bit, etc) 734 */ 735 public static void setFlag(ByteBuffer byteBuffer, int flag) { 736 byte b = byteBuffer.get(6); 737 b |= flag; 738 byteBuffer.put(6,b); 739 } 740 741 /** 742 * Clears a flag in the given buffer 743 */ 744 public static void clearFlag(byte[] buf, int flag) { 745 buf[6] &= (0xFF ^ flag); 746 } 747 748 private static void AreFragmentsAllowed(byte major, byte minor, byte flag, 749 byte msgType) { 750 751 if ( (major == 0x01) && (minor == 0x00) ) { // 1.0 752 if (msgType == GIOPFragment) { 753 throw wrapper.fragmentationDisallowed( 754 CompletionStatus.COMPLETED_MAYBE); 755 } 756 } 757 758 if ( (flag & MORE_FRAGMENTS_BIT) == MORE_FRAGMENTS_BIT ) { 759 switch (msgType) { 760 case GIOPCancelRequest : 761 case GIOPCloseConnection : 762 case GIOPMessageError : 763 throw wrapper.fragmentationDisallowed( 764 CompletionStatus.COMPLETED_MAYBE); 765 case GIOPLocateRequest : 766 case GIOPLocateReply : 767 if ( (major == 0x01) && (minor == 0x01) ) { // 1.1 768 throw wrapper.fragmentationDisallowed( 769 CompletionStatus.COMPLETED_MAYBE); 770 } 771 break; 772 } 773 } 774 } 775 776 /** 777 * Construct an ObjectKey from a byte[]. 778 * 779 * @return ObjectKey the object key. 780 */ 781 static ObjectKey extractObjectKey(byte[] objKey, ORB orb) { 782 783 try { 784 if (objKey != null) { 785 ObjectKey objectKey = 786 orb.getObjectKeyFactory().create(objKey); 787 if (objectKey != null) { 788 return objectKey; 789 } 790 } 791 } catch (Exception e) { 792 // XXX log this exception 793 } 794 795 // This exception is thrown if any exceptions are raised while 796 // extracting the object key or if the object key is empty. 797 throw wrapper.invalidObjectKey(); 798 } 799 800 /** 801 * Extract the object key from TargetAddress. 802 * 803 * @return ObjectKey the object key. 804 */ 805 static ObjectKey extractObjectKey(TargetAddress target, ORB orb) { 806 807 short orbTargetAddrPref = orb.getORBData().getGIOPTargetAddressPreference(); 808 short reqAddrDisp = target.discriminator(); 809 810 switch (orbTargetAddrPref) { 811 case ORBConstants.ADDR_DISP_OBJKEY : 812 if (reqAddrDisp != KeyAddr.value) { 813 throw new AddressingDispositionException(KeyAddr.value); 814 } 815 break; 816 case ORBConstants.ADDR_DISP_PROFILE : 817 if (reqAddrDisp != ProfileAddr.value) { 818 throw new AddressingDispositionException(ProfileAddr.value); 819 } 820 break; 821 case ORBConstants.ADDR_DISP_IOR : 822 if (reqAddrDisp != ReferenceAddr.value) { 823 throw new AddressingDispositionException(ReferenceAddr.value); 824 } 825 break; 826 case ORBConstants.ADDR_DISP_HANDLE_ALL : 827 break; 828 default : 829 throw wrapper.orbTargetAddrPreferenceInExtractObjectkeyInvalid() ; 830 } 831 832 try { 833 switch (reqAddrDisp) { 834 case KeyAddr.value : 835 byte[] objKey = target.object_key(); 836 if (objKey != null) { // AddressingDisposition::KeyAddr 837 ObjectKey objectKey = 838 orb.getObjectKeyFactory().create(objKey); 839 if (objectKey != null) { 840 return objectKey; 841 } 842 } 843 break; 844 case ProfileAddr.value : 845 IIOPProfile iiopProfile = null; 846 TaggedProfile profile = target.profile(); 847 if (profile != null) { // AddressingDisposition::ProfileAddr 848 iiopProfile = IIOPFactories.makeIIOPProfile(orb, profile); 849 ObjectKey objectKey = iiopProfile.getObjectKey(); 850 if (objectKey != null) { 851 return objectKey; 852 } 853 } 854 break; 855 case ReferenceAddr.value : 856 IORAddressingInfo iorInfo = target.ior(); 857 if (iorInfo != null) { // AddressingDisposition::IORAddr 858 profile = iorInfo.ior.profiles[iorInfo.selected_profile_index]; 859 iiopProfile = IIOPFactories.makeIIOPProfile(orb, profile); 860 ObjectKey objectKey = iiopProfile.getObjectKey(); 861 if (objectKey != null) { 862 return objectKey; 863 } 864 } 865 break; 866 default : // this cannot happen 867 // There is no need for a explicit exception, since the 868 // TargetAddressHelper.read() would have raised a BAD_OPERATION 869 // exception by now. 870 break; 871 } 872 } catch (Exception e) {} 873 874 // This exception is thrown if any exceptions are raised while 875 // extracting the object key from the TargetAddress or if all the 876 // the valid TargetAddress::AddressingDispositions are empty. 877 throw wrapper.invalidObjectKey() ; 878 } 879 880 private static int readSize(byte b1, byte b2, byte b3, byte b4, 881 boolean littleEndian) { 882 883 int a1, a2, a3, a4; 884 885 if (!littleEndian) { 886 a1 = (b1 << 24) & 0xFF000000; 887 a2 = (b2 << 16) & 0x00FF0000; 888 a3 = (b3 << 8) & 0x0000FF00; 889 a4 = (b4 << 0) & 0x000000FF; 890 } else { 891 a1 = (b4 << 24) & 0xFF000000; 892 a2 = (b3 << 16) & 0x00FF0000; 893 a3 = (b2 << 8) & 0x0000FF00; 894 a4 = (b1 << 0) & 0x000000FF; 895 } 896 897 return (a1 | a2 | a3 | a4); 898 } 899 900 static void nullCheck(Object obj) { 901 if (obj == null) { 902 throw wrapper.nullNotAllowed() ; 903 } 904 } 905 906 static SystemException getSystemException( 907 String exClassName, int minorCode, CompletionStatus completionStatus, 908 String message, ORBUtilSystemException wrapper) 909 { 910 SystemException sysEx = null; 911 912 try { 913 Class<?> clazz = 914 SharedSecrets.getJavaCorbaAccess().loadClass(exClassName); 915 if (message == null) { 916 sysEx = (SystemException) clazz.newInstance(); 917 } else { 918 Class[] types = { String.class }; 919 Constructor constructor = clazz.getConstructor(types); 920 Object[] args = { message }; 921 sysEx = (SystemException)constructor.newInstance(args); 922 } 923 } catch (Exception someEx) { 924 throw wrapper.badSystemExceptionInReply( 925 CompletionStatus.COMPLETED_MAYBE, someEx ); 926 } 927 928 sysEx.minor = minorCode; 929 sysEx.completed = completionStatus; 930 931 return sysEx; 932 } 933 934 public void callback(MessageHandler handler) 935 throws java.io.IOException 936 { 937 handler.handleInput(this); 938 } 939 940 public ByteBuffer getByteBuffer() 941 { 942 return byteBuffer; 943 } 944 945 public void setByteBuffer(ByteBuffer byteBuffer) 946 { 947 this.byteBuffer = byteBuffer; 948 } 949 950 public int getThreadPoolToUse() 951 { 952 return threadPoolToUse; 953 } 954 955 public byte getEncodingVersion() { 956 return this.encodingVersion; 957 } 958 959 public void setEncodingVersion(byte version) { 960 this.encodingVersion = version; 961 } 962 963 private static void dprint(String msg) 964 { 965 ORBUtility.dprint("MessageBase", msg); 966 } 967} 968