1. /*
  2. * @(#)ReplyMessage_1_2.java 1.23 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 org.omg.CORBA.INTERNAL;
  9. import org.omg.CORBA.SystemException;
  10. import org.omg.CORBA.CompletionStatus;
  11. import com.sun.corba.se.spi.ior.IOR;
  12. import com.sun.corba.se.spi.ior.IORFactories ;
  13. import com.sun.corba.se.spi.orb.ORB;
  14. import com.sun.corba.se.spi.servicecontext.ServiceContexts;
  15. import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
  16. import com.sun.corba.se.impl.encoding.CDRInputStream;
  17. import com.sun.corba.se.impl.encoding.CDROutputStream;
  18. import com.sun.corba.se.impl.encoding.CDRInputStream_1_2;
  19. import com.sun.corba.se.impl.encoding.CDROutputStream_1_2;
  20. import com.sun.corba.se.impl.orbutil.ORBUtility;
  21. import com.sun.corba.se.impl.orbutil.ORBConstants;
  22. import com.sun.corba.se.spi.logging.CORBALogDomains ;
  23. import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
  24. /**
  25. * This implements the GIOP 1.2 Reply header.
  26. *
  27. * @author Ram Jeyaraman 05/14/2000
  28. * @version 1.0
  29. */
  30. public final class ReplyMessage_1_2 extends Message_1_2
  31. implements ReplyMessage {
  32. // Instance variables
  33. private ORB orb = null;
  34. private ORBUtilSystemException wrapper = null ;
  35. private int reply_status = (int) 0;
  36. private ServiceContexts service_contexts = null;
  37. private IOR ior = null;
  38. private String exClassName = null;
  39. private int minorCode = (int) 0;
  40. private CompletionStatus completionStatus = null;
  41. private short addrDisposition = KeyAddr.value; // default;
  42. // Constructors
  43. ReplyMessage_1_2(ORB orb) {
  44. this.orb = orb;
  45. this.wrapper = ORBUtilSystemException.get( orb,
  46. CORBALogDomains.RPC_PROTOCOL ) ;
  47. }
  48. ReplyMessage_1_2(ORB orb, int _request_id, int _reply_status,
  49. ServiceContexts _service_contexts, IOR _ior) {
  50. super(Message.GIOPBigMagic, GIOPVersion.V1_2, FLAG_NO_FRAG_BIG_ENDIAN,
  51. Message.GIOPReply, 0);
  52. this.orb = orb;
  53. this.wrapper = ORBUtilSystemException.get( orb,
  54. CORBALogDomains.RPC_PROTOCOL ) ;
  55. request_id = _request_id;
  56. reply_status = _reply_status;
  57. service_contexts = _service_contexts;
  58. ior = _ior;
  59. }
  60. // Accessor methods
  61. public int getRequestId() {
  62. return this.request_id;
  63. }
  64. public int getReplyStatus() {
  65. return this.reply_status;
  66. }
  67. public short getAddrDisposition() {
  68. return this.addrDisposition;
  69. }
  70. public ServiceContexts getServiceContexts() {
  71. return this.service_contexts;
  72. }
  73. public void setServiceContexts( ServiceContexts sc ) {
  74. this.service_contexts = sc;
  75. }
  76. public SystemException getSystemException(String message) {
  77. return MessageBase.getSystemException(
  78. exClassName, minorCode, completionStatus, message, wrapper);
  79. }
  80. public IOR getIOR() {
  81. return this.ior;
  82. }
  83. public void setIOR( IOR ior ) {
  84. this.ior = ior;
  85. }
  86. // IO methods
  87. public void read(org.omg.CORBA.portable.InputStream istream) {
  88. super.read(istream);
  89. this.request_id = istream.read_ulong();
  90. this.reply_status = istream.read_long();
  91. isValidReplyStatus(this.reply_status); // raises exception on error
  92. this.service_contexts
  93. = new ServiceContexts((org.omg.CORBA_2_3.portable.InputStream) istream);
  94. // CORBA formal 00-11-0 15.4.2.2 GIOP 1.2 body must be
  95. // aligned on an 8 octet boundary.
  96. // Ensures that the first read operation called from the stub code,
  97. // during body deconstruction, would skip the header padding, that was
  98. // inserted to ensure that the body was aligned on an 8-octet boundary.
  99. ((CDRInputStream)istream).setHeaderPadding(true);
  100. // The code below reads the reply body in some cases
  101. // SYSTEM_EXCEPTION & LOCATION_FORWARD & LOCATION_FORWARD_PERM &
  102. // NEEDS_ADDRESSING_MODE
  103. if (this.reply_status == SYSTEM_EXCEPTION) {
  104. String reposId = istream.read_string();
  105. this.exClassName = ORBUtility.classNameOf(reposId);
  106. this.minorCode = istream.read_long();
  107. int status = istream.read_long();
  108. switch (status) {
  109. case CompletionStatus._COMPLETED_YES:
  110. this.completionStatus = CompletionStatus.COMPLETED_YES;
  111. break;
  112. case CompletionStatus._COMPLETED_NO:
  113. this.completionStatus = CompletionStatus.COMPLETED_NO;
  114. break;
  115. case CompletionStatus._COMPLETED_MAYBE:
  116. this.completionStatus = CompletionStatus.COMPLETED_MAYBE;
  117. break;
  118. default:
  119. throw wrapper.badCompletionStatusInReply(
  120. CompletionStatus.COMPLETED_MAYBE, new Integer(status) );
  121. }
  122. } else if (this.reply_status == USER_EXCEPTION) {
  123. // do nothing. The client stub will read the exception from body.
  124. } else if ( (this.reply_status == LOCATION_FORWARD) ||
  125. (this.reply_status == LOCATION_FORWARD_PERM) ){
  126. CDRInputStream cdr = (CDRInputStream) istream;
  127. this.ior = IORFactories.makeIOR( cdr ) ;
  128. } else if (this.reply_status == NEEDS_ADDRESSING_MODE) {
  129. // read GIOP::AddressingDisposition from body and resend the
  130. // original request using the requested addressing mode. The
  131. // resending is transparent to the client program.
  132. this.addrDisposition = AddressingDispositionHelper.read(istream);
  133. }
  134. }
  135. // Note, this writes only the header information. SystemException or
  136. // IOR or GIOP::AddressingDisposition may be written afterwards into the
  137. // reply mesg body.
  138. public void write(org.omg.CORBA.portable.OutputStream ostream) {
  139. super.write(ostream);
  140. ostream.write_ulong(this.request_id);
  141. ostream.write_long(this.reply_status);
  142. if (this.service_contexts != null) {
  143. service_contexts.write(
  144. (org.omg.CORBA_2_3.portable.OutputStream) ostream,
  145. GIOPVersion.V1_2);
  146. } else {
  147. ServiceContexts.writeNullServiceContext(
  148. (org.omg.CORBA_2_3.portable.OutputStream) ostream);
  149. }
  150. // CORBA formal 00-11-0 15.4.2.2 GIOP 1.2 body must be
  151. // aligned on an 8 octet boundary.
  152. // Ensures that the first write operation called from the stub code,
  153. // during body construction, would insert a header padding, such that
  154. // the body is aligned on an 8-octet boundary.
  155. ((CDROutputStream)ostream).setHeaderPadding(true);
  156. }
  157. // Static methods
  158. public static void isValidReplyStatus(int replyStatus) {
  159. switch (replyStatus) {
  160. case NO_EXCEPTION :
  161. case USER_EXCEPTION :
  162. case SYSTEM_EXCEPTION :
  163. case LOCATION_FORWARD :
  164. case LOCATION_FORWARD_PERM :
  165. case NEEDS_ADDRESSING_MODE :
  166. break;
  167. default :
  168. ORBUtilSystemException localWrapper = ORBUtilSystemException.get(
  169. CORBALogDomains.RPC_PROTOCOL ) ;
  170. throw localWrapper.illegalReplyStatus( CompletionStatus.COMPLETED_MAYBE);
  171. }
  172. }
  173. public void callback(MessageHandler handler)
  174. throws java.io.IOException
  175. {
  176. handler.handleInput(this);
  177. }
  178. } // class ReplyMessage_1_2