1. /*
  2. * @(#)ServerRequestImpl.java 1.80 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.corba.se.internal.iiop;
  8. import org.omg.CORBA.SystemException;
  9. import org.omg.CORBA.portable.UnknownException;
  10. import org.omg.CORBA.UNKNOWN;
  11. import org.omg.CORBA.INTERNAL;
  12. import org.omg.CORBA.CompletionStatus;
  13. import com.sun.corba.se.internal.core.ServerRequest;
  14. import com.sun.corba.se.internal.core.ServiceContext;
  15. import com.sun.corba.se.internal.core.DuplicateServiceContext;
  16. import com.sun.corba.se.internal.core.SendingContextServiceContext;
  17. import com.sun.corba.se.internal.core.ORBVersionServiceContext;
  18. import com.sun.corba.se.internal.core.ORBVersionFactory;
  19. import com.sun.corba.se.internal.core.UEInfoServiceContext;
  20. import com.sun.corba.se.internal.core.ServiceContexts;
  21. import com.sun.corba.se.internal.core.ServerResponse;
  22. import com.sun.corba.se.internal.core.IOR;
  23. import com.sun.corba.se.internal.core.MarshalOutputStream;
  24. import com.sun.corba.se.internal.ior.ObjectKey;
  25. import com.sun.corba.se.internal.orbutil.ORBUtility;
  26. import com.sun.corba.se.internal.core.ORBVersion;
  27. import com.sun.corba.se.internal.iiop.messages.MessageBase;
  28. import com.sun.corba.se.internal.iiop.messages.ReplyMessage;
  29. import com.sun.corba.se.internal.iiop.messages.RequestMessage;
  30. public class ServerRequestImpl extends IIOPInputStream implements ServerRequest
  31. {
  32. private void dprint( String msg )
  33. {
  34. ORBUtility.dprint( this, msg ) ;
  35. }
  36. org.omg.CORBA.portable.OutputStream replyStream;
  37. org.omg.CORBA.portable.OutputStream exceptionReplyStream;
  38. public static final int UNKNOWN_EXCEPTION_INFO_ID = 9;
  39. protected ServerRequestImpl(Connection c, byte[] buf, RequestMessage header)
  40. throws java.io.IOException
  41. {
  42. super(c, buf, header);
  43. com.sun.corba.se.internal.corba.ORB theOrb = (com.sun.corba.se.internal.corba.ORB)orb() ;
  44. if (theOrb.subcontractDebugFlag)
  45. dprint( "Constructing ServerRequestImpl object" ) ;
  46. this.request = header;
  47. }
  48. protected ServerRequestImpl()
  49. throws java.io.IOException
  50. {
  51. }
  52. public int getRequestId() {
  53. return request.getRequestId();
  54. }
  55. public boolean isOneWay() {
  56. return !request.isResponseExpected();
  57. }
  58. public ServiceContexts getServiceContexts() {
  59. return request.getServiceContexts();
  60. }
  61. public String getOperationName() {
  62. return request.getOperation();
  63. }
  64. public ObjectKey getObjectKey() {
  65. return request.getObjectKey();
  66. }
  67. public ServerResponse createResponse(ServiceContexts svc)
  68. {
  69. return new ServerResponseImpl(this,
  70. getServiceContextsForReply(getConnection(),
  71. svc));
  72. }
  73. public org.omg.CORBA.portable.OutputStream createReply() {
  74. if ( replyStream == null ) {
  75. replyStream =
  76. (org.omg.CORBA.portable.OutputStream)
  77. createResponse(null);
  78. }
  79. return replyStream;
  80. }
  81. public org.omg.CORBA.portable.OutputStream createExceptionReply() {
  82. if ( exceptionReplyStream == null ) {
  83. exceptionReplyStream =
  84. (org.omg.CORBA.portable.OutputStream)
  85. createUserExceptionResponse(null);
  86. }
  87. return exceptionReplyStream;
  88. }
  89. public ServerResponse createUserExceptionResponse(ServiceContexts svc) {
  90. return new ServerResponseImpl((ServerRequestImpl)this,
  91. getServiceContextsForReply(getConnection(),
  92. svc),
  93. true);
  94. }
  95. /**
  96. * Create a response that represents an unknown exception.
  97. *
  98. */
  99. public ServerResponse createUnknownExceptionResponse(
  100. UnknownException ex
  101. )
  102. {
  103. ServiceContexts contexts = null;
  104. SystemException sys = new UNKNOWN( 0,
  105. CompletionStatus.COMPLETED_MAYBE);
  106. try {
  107. contexts = new ServiceContexts( (com.sun.corba.se.internal.corba.ORB)orb() );
  108. UEInfoServiceContext uei = new UEInfoServiceContext(sys);
  109. contexts.put( uei ) ;
  110. } catch (DuplicateServiceContext d) {
  111. // can't happen
  112. }
  113. return createSystemExceptionResponse(sys,contexts);
  114. }
  115. public ServerResponse createSystemExceptionResponse(
  116. SystemException ex, ServiceContexts svc)
  117. {
  118. // It is possible that fragments of response have already been
  119. // sent. Then an error may occur (e.g. marshaling error like
  120. // non serializable object). In that case it is too late
  121. // to send the exception. We just return the existing fragmented
  122. // stream here. This will cause an incomplete last fragment
  123. // to be sent. Then the other side will get a marshaling error
  124. // when attempting to unmarshal.
  125. IIOPOutputStream existingOutputStream =
  126. ((IIOPConnection)getConnection())
  127. .getIdToFragmentedOutputStreamEntry(request.getRequestId());
  128. if (existingOutputStream != null) {
  129. return (ServerResponse) existingOutputStream;
  130. }
  131. // Only do this if interceptors have been initialized on this request
  132. // and have not completed their lifecycle (otherwise the info stack
  133. // may be empty or have a different request's entry on top).
  134. if (executePIInResponseConstructor()) {
  135. // Inform Portable Interceptors of the SystemException. This is
  136. // required to be done here because the ending interception point
  137. // is called in the ServerResponseImpl constructor called below
  138. // but we do not currently write the SystemException into the
  139. // response until after the ending point is called.
  140. ORB orb = (ORB)orb();
  141. orb.setServerPIInfo( ex );
  142. }
  143. if (orb() != null && ((ORB)orb()).subcontractDebugFlag && ex != null)
  144. ORBUtility.dprint(this, "Sending SystemException:", ex);
  145. ServerResponseImpl response =
  146. new ServerResponseImpl((ServerRequestImpl)this,
  147. getServiceContextsForReply(getConnection(),
  148. svc),
  149. false);
  150. ORBUtility.writeSystemException(ex, response);
  151. return response;
  152. }
  153. public ServerResponse createLocationForward(
  154. IOR ior, ServiceContexts svc)
  155. {
  156. ReplyMessage reply
  157. = MessageBase.createReply((ORB) orb(),
  158. request.getGIOPVersion(),
  159. request.getRequestId(),
  160. ReplyMessage.LOCATION_FORWARD,
  161. getServiceContextsForReply(getConnection(),
  162. svc),
  163. ior);
  164. ServerResponseImpl response = new ServerResponseImpl(this, reply, ior);
  165. return response;
  166. }
  167. protected RequestMessage request;
  168. /**
  169. * Check to see if request is local.
  170. */
  171. public boolean isLocal(){
  172. return false;
  173. }
  174. /**
  175. * Returns ServiceContexts for reply. If the contexts parameter is null,
  176. * it creates a new ServiceContexts instance with the code base (first
  177. * time only) and ORB version contexts. Otherwise, it tries to add these
  178. * to the instance given, and returns that instance.
  179. */
  180. private ServiceContexts getServiceContextsForReply(Connection c,
  181. ServiceContexts contexts)
  182. {
  183. com.sun.corba.se.internal.corba.ORB theOrb
  184. = (com.sun.corba.se.internal.corba.ORB)orb() ;
  185. if (theOrb.subcontractDebugFlag)
  186. dprint( "getServiceContextsReply called with connection " + c ) ;
  187. if (contexts == null)
  188. contexts = new ServiceContexts( theOrb ) ;
  189. // NOTE : We only want to send the runtime context the first time
  190. if (c != null && !c.isPostInitialContexts()) {
  191. c.setPostInitialContexts();
  192. SendingContextServiceContext scsc =
  193. new SendingContextServiceContext(theOrb.getServantIOR()) ;
  194. try {
  195. contexts.put( scsc ) ;
  196. if (theOrb.subcontractDebugFlag)
  197. dprint( "Added SendingContextServiceContext" ) ;
  198. } catch (DuplicateServiceContext dsc) {
  199. // Ignore
  200. }
  201. }
  202. // send ORBVersion servicecontext as part of the Reply
  203. ORBVersionServiceContext ovsc
  204. = new ORBVersionServiceContext(ORBVersionFactory.getORBVersion());
  205. try {
  206. contexts.put( ovsc ) ;
  207. if (theOrb.subcontractDebugFlag)
  208. dprint("Added ORB version service context");
  209. } catch (DuplicateServiceContext dsc) {
  210. // Ignore
  211. }
  212. return contexts;
  213. }
  214. private boolean _executeReturnServantInResponseConstructor = false;
  215. public boolean executeReturnServantInResponseConstructor()
  216. {
  217. return _executeReturnServantInResponseConstructor;
  218. }
  219. public void setExecuteReturnServantInResponseConstructor(boolean b)
  220. {
  221. _executeReturnServantInResponseConstructor = b;
  222. }
  223. private boolean _executeRemoveThreadInfoInResponseConstructor = false;
  224. public boolean executeRemoveThreadInfoInResponseConstructor()
  225. {
  226. return _executeRemoveThreadInfoInResponseConstructor;
  227. }
  228. public void setExecuteRemoveThreadInfoInResponseConstructor(boolean b)
  229. {
  230. _executeRemoveThreadInfoInResponseConstructor = b;
  231. }
  232. private boolean _executePIInResponseConstructor = false;
  233. public boolean executePIInResponseConstructor() {
  234. return _executePIInResponseConstructor;
  235. }
  236. public void setExecutePIInResponseConstructor( boolean b ) {
  237. _executePIInResponseConstructor = b;
  238. }
  239. }