1. /*
  2. * @(#)ServerRequestImpl.java 1.73 04/04/07
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * Licensed Materials - Property of IBM
  9. * RMI-IIOP v1.0
  10. * Copyright IBM Corp. 1998 1999 All Rights Reserved
  11. *
  12. * US Government Users Restricted Rights - Use, duplication or
  13. * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  14. */
  15. package com.sun.corba.se.impl.corba;
  16. import org.omg.CORBA.Any;
  17. import org.omg.CORBA.Context;
  18. import org.omg.CORBA.NamedValue;
  19. import org.omg.CORBA.NVList;
  20. import org.omg.CORBA.TypeCode;
  21. import org.omg.CORBA.TCKind;
  22. import org.omg.CORBA.ServerRequest;
  23. import org.omg.CORBA.Bounds;
  24. import org.omg.CORBA.portable.InputStream;
  25. import org.omg.CORBA.portable.OutputStream;
  26. import org.omg.CORBA.CompletionStatus;
  27. import com.sun.corba.se.spi.orb.ORB ;
  28. import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
  29. import com.sun.corba.se.spi.logging.CORBALogDomains ;
  30. import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
  31. public class ServerRequestImpl extends ServerRequest {
  32. ///////////////////////////////////////////////////////////////////////////
  33. // data members
  34. private ORB _orb = null;
  35. private ORBUtilSystemException _wrapper = null;
  36. private String _opName = null;
  37. private NVList _arguments = null;
  38. private Context _ctx = null;
  39. private InputStream _ins = null;
  40. // booleans to check for various operation invocation restrictions
  41. private boolean _paramsCalled = false;
  42. private boolean _resultSet = false;
  43. private boolean _exceptionSet = false;
  44. private Any _resultAny = null;
  45. private Any _exception = null;
  46. public ServerRequestImpl (CorbaMessageMediator req, ORB orb) {
  47. _opName = req.getOperationName();
  48. _ins = (InputStream)req.getInputObject();
  49. _ctx = null; // if we support contexts, this would
  50. // presumably also be available on
  51. // the server invocation
  52. _orb = orb;
  53. _wrapper = ORBUtilSystemException.get( orb,
  54. CORBALogDomains.OA_INVOCATION ) ;
  55. }
  56. public String operation() {
  57. return _opName;
  58. }
  59. public void arguments(NVList args)
  60. {
  61. if (_paramsCalled)
  62. throw _wrapper.argumentsCalledMultiple() ;
  63. if (_exceptionSet)
  64. throw _wrapper.argumentsCalledAfterException() ;
  65. if (args == null )
  66. throw _wrapper.argumentsCalledNullArgs() ;
  67. _paramsCalled = true;
  68. NamedValue arg = null;
  69. for (int i=0; i < args.count() ; i++) {
  70. try {
  71. arg = args.item(i);
  72. } catch (Bounds e) {
  73. throw _wrapper.boundsCannotOccur(e) ;
  74. }
  75. try {
  76. if ((arg.flags() == org.omg.CORBA.ARG_IN.value) ||
  77. (arg.flags() == org.omg.CORBA.ARG_INOUT.value)) {
  78. // unmarshal the value into the Any
  79. arg.value().read_value(_ins, arg.value().type());
  80. }
  81. } catch ( Exception ex ) {
  82. throw _wrapper.badArgumentsNvlist( ex ) ;
  83. }
  84. }
  85. // hang on to the NVList for marshaling the result
  86. _arguments = args;
  87. _orb.getPIHandler().setServerPIInfo( _arguments );
  88. _orb.getPIHandler().invokeServerPIIntermediatePoint();
  89. }
  90. public void set_result(Any res) {
  91. // check for invocation restrictions
  92. if (!_paramsCalled)
  93. throw _wrapper.argumentsNotCalled() ;
  94. if (_resultSet)
  95. throw _wrapper.setResultCalledMultiple() ;
  96. if (_exceptionSet)
  97. throw _wrapper.setResultAfterException() ;
  98. if ( res == null )
  99. throw _wrapper.setResultCalledNullArgs() ;
  100. _resultAny = res;
  101. _resultSet = true;
  102. // Notify portable interceptors of the result so that
  103. // ServerRequestInfo.result() functions as desired.
  104. _orb.getPIHandler().setServerPIInfo( _resultAny );
  105. // actual marshaling of the reply msg header and params takes place
  106. // after the DSI returns control to the ORB.
  107. }
  108. public void set_exception(Any exc)
  109. {
  110. // except can be called by the DIR at any time (CORBA 2.2 section 6.3).
  111. if ( exc == null )
  112. throw _wrapper.setExceptionCalledNullArgs() ;
  113. // Ensure that the Any contains a SystemException or a
  114. // UserException. If the UserException is not a declared exception,
  115. // the client will get an UNKNOWN exception.
  116. TCKind kind = exc.type().kind();
  117. if ( kind != TCKind.tk_except )
  118. throw _wrapper.setExceptionCalledBadType() ;
  119. _exception = exc;
  120. // Inform Portable interceptors of the exception that was set
  121. // so sending_exception can return the right value.
  122. _orb.getPIHandler().setServerPIExceptionInfo( _exception );
  123. // The user can only call arguments once and not at all after
  124. // set_exception. (internal flags ensure this). However, the user
  125. // can call set_exception multiple times. Therefore, we only
  126. // invoke receive_request the first time set_exception is
  127. // called (if they haven't already called arguments).
  128. if( !_exceptionSet && !_paramsCalled ) {
  129. // We need to invoke intermediate points here.
  130. _orb.getPIHandler().invokeServerPIIntermediatePoint();
  131. }
  132. _exceptionSet = true;
  133. // actual marshaling of the reply msg header and exception takes place
  134. // after the DSI returns control to the ORB.
  135. }
  136. /** This is called from the ORB after the DynamicImplementation.invoke
  137. * returns. Here we set the result if result() has not already been called.
  138. * @return the exception if there is one (then ORB will not call
  139. * marshalReplyParams()) otherwise return null.
  140. */
  141. public Any checkResultCalled()
  142. {
  143. // Two things to be checked (CORBA 2.2 spec, section 6.3):
  144. // 1. Unless it calls set_exception(), the DIR must call arguments()
  145. // exactly once, even if the operation signature contains
  146. // no parameters.
  147. // 2. Unless set_exception() is called, if the invoked operation has a
  148. // non-void result type, set_result() must be called exactly once
  149. // before the DIR returns.
  150. if ( _paramsCalled && _resultSet ) // normal invocation return
  151. return null;
  152. else if ( _paramsCalled && !_resultSet && !_exceptionSet ) {
  153. try {
  154. // Neither a result nor an exception has been set.
  155. // Assume that the return type is void. If this is not so,
  156. // the client will throw a MARSHAL exception while
  157. // unmarshaling the return value.
  158. TypeCode result_tc = _orb.get_primitive_tc(
  159. org.omg.CORBA.TCKind.tk_void);
  160. _resultAny = _orb.create_any();
  161. _resultAny.type(result_tc);
  162. _resultSet = true;
  163. return null;
  164. } catch ( Exception ex ) {
  165. throw _wrapper.dsiResultException(
  166. CompletionStatus.COMPLETED_MAYBE, ex ) ;
  167. }
  168. } else if ( _exceptionSet )
  169. return _exception;
  170. else {
  171. throw _wrapper.dsimethodNotcalled(
  172. CompletionStatus.COMPLETED_MAYBE ) ;
  173. }
  174. }
  175. /** This is called from the ORB after the DynamicImplementation.invoke
  176. * returns. Here we marshal the return value and inout/out params.
  177. */
  178. public void marshalReplyParams(OutputStream os)
  179. {
  180. // marshal the operation return value
  181. _resultAny.write_value(os);
  182. // marshal the inouts/outs
  183. NamedValue arg = null;
  184. for (int i=0; i < _arguments.count() ; i++) {
  185. try {
  186. arg = _arguments.item(i);
  187. } catch (Bounds e) {}
  188. if ((arg.flags() == org.omg.CORBA.ARG_OUT.value) ||
  189. (arg.flags() == org.omg.CORBA.ARG_INOUT.value)) {
  190. arg.value().write_value(os);
  191. }
  192. }
  193. }
  194. public Context ctx()
  195. {
  196. if ( !_paramsCalled || _resultSet || _exceptionSet )
  197. throw _wrapper.contextCalledOutOfOrder() ;
  198. throw _wrapper.contextNotImplemented() ;
  199. }
  200. }