1. /*
  2. * @(#)RequestImpl.java 1.90 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.ARG_IN;
  18. import org.omg.CORBA.ARG_OUT;
  19. import org.omg.CORBA.ARG_INOUT;
  20. import org.omg.CORBA.Context;
  21. import org.omg.CORBA.ContextList;
  22. import org.omg.CORBA.Environment;
  23. import org.omg.CORBA.ExceptionList;
  24. import org.omg.CORBA.NVList;
  25. import org.omg.CORBA.NamedValue;
  26. import org.omg.CORBA.Request;
  27. import org.omg.CORBA.SystemException;
  28. import org.omg.CORBA.TCKind;
  29. import org.omg.CORBA.TypeCode;
  30. import org.omg.CORBA.TypeCodePackage.BadKind;
  31. import org.omg.CORBA.UnknownUserException;
  32. import org.omg.CORBA.Bounds;
  33. import org.omg.CORBA.UNKNOWN;
  34. import org.omg.CORBA.INTERNAL;
  35. import org.omg.CORBA.NO_IMPLEMENT;
  36. import org.omg.CORBA.CompletionStatus;
  37. import org.omg.CORBA.WrongTransaction;
  38. import org.omg.CORBA.portable.ApplicationException ;
  39. import org.omg.CORBA.portable.RemarshalException ;
  40. import org.omg.CORBA.portable.InputStream ;
  41. import org.omg.CORBA.portable.OutputStream ;
  42. import com.sun.corba.se.spi.orb.ORB;
  43. import com.sun.corba.se.spi.presentation.rmi.StubAdapter;
  44. import com.sun.corba.se.spi.logging.CORBALogDomains;
  45. import com.sun.corba.se.impl.logging.ORBUtilSystemException;
  46. import com.sun.corba.se.impl.corba.AsynchInvoke;
  47. public class RequestImpl
  48. extends Request
  49. {
  50. ///////////////////////////////////////////////////////////////////////////
  51. // data members
  52. protected org.omg.CORBA.Object _target;
  53. protected String _opName;
  54. protected NVList _arguments;
  55. protected ExceptionList _exceptions;
  56. private NamedValue _result;
  57. protected Environment _env;
  58. private Context _ctx;
  59. private ContextList _ctxList;
  60. protected ORB _orb;
  61. private ORBUtilSystemException _wrapper;
  62. // invocation-specific stuff
  63. protected boolean _isOneWay = false;
  64. private int[] _paramCodes;
  65. private long[] _paramLongs;
  66. private java.lang.Object[] _paramObjects;
  67. // support for deferred invocations.
  68. // protected instead of private since it needs to be set by the
  69. // thread object doing the asynchronous invocation.
  70. protected boolean gotResponse = false;
  71. ///////////////////////////////////////////////////////////////////////////
  72. // constructor
  73. // REVISIT - used to be protected. Now public so it can be
  74. // accessed from xgiop.
  75. public RequestImpl (ORB orb,
  76. org.omg.CORBA.Object targetObject,
  77. Context ctx,
  78. String operationName,
  79. NVList argumentList,
  80. NamedValue resultContainer,
  81. ExceptionList exceptionList,
  82. ContextList ctxList)
  83. {
  84. // initialize the orb
  85. _orb = orb;
  86. _wrapper = ORBUtilSystemException.get( orb,
  87. CORBALogDomains.OA_INVOCATION ) ;
  88. // initialize target, context and operation name
  89. _target = targetObject;
  90. _ctx = ctx;
  91. _opName = operationName;
  92. // initialize argument list if not passed in
  93. if (argumentList == null)
  94. _arguments = new NVListImpl(_orb);
  95. else
  96. _arguments = argumentList;
  97. // set result container.
  98. _result = resultContainer;
  99. // initialize exception list if not passed in
  100. if (exceptionList == null)
  101. _exceptions = new ExceptionListImpl();
  102. else
  103. _exceptions = exceptionList;
  104. // initialize context list if not passed in
  105. if (ctxList == null)
  106. _ctxList = new ContextListImpl(_orb);
  107. else
  108. _ctxList = ctxList;
  109. // initialize environment
  110. _env = new EnvironmentImpl();
  111. }
  112. public org.omg.CORBA.Object target()
  113. {
  114. return _target;
  115. }
  116. public String operation()
  117. {
  118. return _opName;
  119. }
  120. public NVList arguments()
  121. {
  122. return _arguments;
  123. }
  124. public NamedValue result()
  125. {
  126. return _result;
  127. }
  128. public Environment env()
  129. {
  130. return _env;
  131. }
  132. public ExceptionList exceptions()
  133. {
  134. return _exceptions;
  135. }
  136. public ContextList contexts()
  137. {
  138. return _ctxList;
  139. }
  140. public synchronized Context ctx()
  141. {
  142. if (_ctx == null)
  143. _ctx = new ContextImpl(_orb);
  144. return _ctx;
  145. }
  146. public synchronized void ctx(Context newCtx)
  147. {
  148. _ctx = newCtx;
  149. }
  150. public synchronized Any add_in_arg()
  151. {
  152. return _arguments.add(org.omg.CORBA.ARG_IN.value).value();
  153. }
  154. public synchronized Any add_named_in_arg(String name)
  155. {
  156. return _arguments.add_item(name, org.omg.CORBA.ARG_IN.value).value();
  157. }
  158. public synchronized Any add_inout_arg()
  159. {
  160. return _arguments.add(org.omg.CORBA.ARG_INOUT.value).value();
  161. }
  162. public synchronized Any add_named_inout_arg(String name)
  163. {
  164. return _arguments.add_item(name, org.omg.CORBA.ARG_INOUT.value).value();
  165. }
  166. public synchronized Any add_out_arg()
  167. {
  168. return _arguments.add(org.omg.CORBA.ARG_OUT.value).value();
  169. }
  170. public synchronized Any add_named_out_arg(String name)
  171. {
  172. return _arguments.add_item(name, org.omg.CORBA.ARG_OUT.value).value();
  173. }
  174. public synchronized void set_return_type(TypeCode tc)
  175. {
  176. if (_result == null)
  177. _result = new NamedValueImpl(_orb);
  178. _result.value().type(tc);
  179. }
  180. public synchronized Any return_value()
  181. {
  182. if (_result == null)
  183. _result = new NamedValueImpl(_orb);
  184. return _result.value();
  185. }
  186. public synchronized void add_exception(TypeCode exceptionType)
  187. {
  188. _exceptions.add(exceptionType);
  189. }
  190. public synchronized void invoke()
  191. {
  192. doInvocation();
  193. }
  194. public synchronized void send_oneway()
  195. {
  196. _isOneWay = true;
  197. doInvocation();
  198. }
  199. public synchronized void send_deferred()
  200. {
  201. AsynchInvoke invokeObject = new AsynchInvoke(_orb, this, false);
  202. new Thread(invokeObject).start();
  203. }
  204. public synchronized boolean poll_response()
  205. {
  206. // this method has to be synchronized even though it seems
  207. // "readonly" since the thread object doing the asynchronous
  208. // invocation can potentially update this variable in parallel.
  209. // updates are currently simply synchronized againt the request
  210. // object.
  211. return gotResponse;
  212. }
  213. public synchronized void get_response()
  214. throws org.omg.CORBA.WrongTransaction
  215. {
  216. while (gotResponse == false) {
  217. // release the lock. wait to be notified by the thread that is
  218. // doing the asynchronous invocation.
  219. try {
  220. wait();
  221. }
  222. catch (InterruptedException e) {}
  223. }
  224. }
  225. ///////////////////////////////////////////////////////////////////////////
  226. // private helper methods
  227. /*
  228. * The doInvocation operation is where the real mechanics of
  229. * performing the request invocation is done.
  230. */
  231. protected void doInvocation()
  232. {
  233. org.omg.CORBA.portable.Delegate delegate = StubAdapter.getDelegate(
  234. _target ) ;
  235. // Initiate Client Portable Interceptors. Inform the PIHandler that
  236. // this is a DII request so that it knows to ignore the second
  237. // inevitable call to initiateClientPIRequest in createRequest.
  238. // Also, save the RequestImpl object for later use.
  239. _orb.getPIHandler().initiateClientPIRequest( true );
  240. _orb.getPIHandler().setClientPIInfo( this );
  241. InputStream $in = null;
  242. try {
  243. OutputStream $out = delegate.request(null, _opName, !_isOneWay);
  244. // Marshal args
  245. try {
  246. for (int i=0; i<_arguments.count() ; i++) {
  247. NamedValue nv = _arguments.item(i);
  248. switch (nv.flags()) {
  249. case ARG_IN.value:
  250. nv.value().write_value($out);
  251. break;
  252. case ARG_OUT.value:
  253. break;
  254. case ARG_INOUT.value:
  255. nv.value().write_value($out);
  256. break;
  257. }
  258. }
  259. } catch ( org.omg.CORBA.Bounds ex ) {
  260. throw _wrapper.boundsErrorInDiiRequest( ex ) ;
  261. }
  262. $in = delegate.invoke(null, $out);
  263. } catch (ApplicationException e) {
  264. // REVISIT - minor code.
  265. // This is already handled in subcontract.
  266. // REVISIT - uncomment.
  267. //throw new INTERNAL();
  268. } catch (RemarshalException e) {
  269. doInvocation();
  270. } catch( SystemException ex ) {
  271. _env.exception(ex);
  272. // NOTE: The exception should not be thrown.
  273. // However, JDK 1.4 and earlier threw the exception,
  274. // so we keep the behavior to be compatible.
  275. throw ex;
  276. } finally {
  277. delegate.releaseReply(null, $in);
  278. }
  279. }
  280. // REVISIT - make protected after development - so xgiop can get it.
  281. public void unmarshalReply(InputStream is)
  282. {
  283. // First unmarshal the return value if it is not void
  284. if ( _result != null ) {
  285. Any returnAny = _result.value();
  286. TypeCode returnType = returnAny.type();
  287. if ( returnType.kind().value() != TCKind._tk_void )
  288. returnAny.read_value(is, returnType);
  289. }
  290. // Now unmarshal the out/inout args
  291. try {
  292. for ( int i=0; i<_arguments.count() ; i++) {
  293. NamedValue nv = _arguments.item(i);
  294. switch( nv.flags() ) {
  295. case ARG_IN.value:
  296. break;
  297. case ARG_OUT.value:
  298. case ARG_INOUT.value:
  299. Any any = nv.value();
  300. any.read_value(is, any.type());
  301. break;
  302. }
  303. }
  304. }
  305. catch ( org.omg.CORBA.Bounds ex ) {
  306. // Cannot happen since we only iterate till _arguments.count()
  307. }
  308. }
  309. }