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