RequestImpl.java revision 667:d0315150c39d
1/* 2 * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25/* 26 * Licensed Materials - Property of IBM 27 * RMI-IIOP v1.0 28 * Copyright IBM Corp. 1998 1999 All Rights Reserved 29 * 30 */ 31 32package com.sun.corba.se.impl.corba; 33 34 35import org.omg.CORBA.Any; 36import org.omg.CORBA.ARG_IN; 37import org.omg.CORBA.ARG_OUT; 38import org.omg.CORBA.ARG_INOUT; 39import org.omg.CORBA.Context; 40import org.omg.CORBA.ContextList; 41import org.omg.CORBA.Environment; 42import org.omg.CORBA.ExceptionList; 43import org.omg.CORBA.NVList; 44import org.omg.CORBA.NamedValue; 45import org.omg.CORBA.Request; 46import org.omg.CORBA.SystemException; 47import org.omg.CORBA.TCKind; 48import org.omg.CORBA.TypeCode; 49import org.omg.CORBA.TypeCodePackage.BadKind; 50import org.omg.CORBA.UnknownUserException; 51import org.omg.CORBA.Bounds; 52import org.omg.CORBA.UNKNOWN; 53import org.omg.CORBA.INTERNAL; 54import org.omg.CORBA.NO_IMPLEMENT; 55import org.omg.CORBA.CompletionStatus; 56import org.omg.CORBA.WrongTransaction; 57 58import org.omg.CORBA.portable.ApplicationException ; 59import org.omg.CORBA.portable.RemarshalException ; 60import org.omg.CORBA.portable.InputStream ; 61import org.omg.CORBA.portable.OutputStream ; 62 63import com.sun.corba.se.spi.orb.ORB; 64import com.sun.corba.se.spi.presentation.rmi.StubAdapter; 65import com.sun.corba.se.spi.logging.CORBALogDomains; 66import com.sun.corba.se.impl.logging.ORBUtilSystemException; 67import com.sun.corba.se.impl.corba.AsynchInvoke; 68import com.sun.corba.se.impl.transport.ManagedLocalsThread; 69 70public class RequestImpl 71 extends Request 72{ 73 /////////////////////////////////////////////////////////////////////////// 74 // data members 75 76 protected org.omg.CORBA.Object _target; 77 protected String _opName; 78 protected NVList _arguments; 79 protected ExceptionList _exceptions; 80 private NamedValue _result; 81 protected Environment _env; 82 private Context _ctx; 83 private ContextList _ctxList; 84 protected ORB _orb; 85 private ORBUtilSystemException _wrapper; 86 87 // invocation-specific stuff 88 protected boolean _isOneWay = false; 89 private int[] _paramCodes; 90 private long[] _paramLongs; 91 private java.lang.Object[] _paramObjects; 92 93 // support for deferred invocations. 94 // protected instead of private since it needs to be set by the 95 // thread object doing the asynchronous invocation. 96 protected boolean gotResponse = false; 97 98 /////////////////////////////////////////////////////////////////////////// 99 // constructor 100 101 // REVISIT - used to be protected. Now public so it can be 102 // accessed from xgiop. 103 public RequestImpl (ORB orb, 104 org.omg.CORBA.Object targetObject, 105 Context ctx, 106 String operationName, 107 NVList argumentList, 108 NamedValue resultContainer, 109 ExceptionList exceptionList, 110 ContextList ctxList) 111 { 112 113 // initialize the orb 114 _orb = orb; 115 _wrapper = ORBUtilSystemException.get( orb, 116 CORBALogDomains.OA_INVOCATION ) ; 117 118 // initialize target, context and operation name 119 _target = targetObject; 120 _ctx = ctx; 121 _opName = operationName; 122 123 // initialize argument list if not passed in 124 if (argumentList == null) 125 _arguments = new NVListImpl(_orb); 126 else 127 _arguments = argumentList; 128 129 // set result container. 130 _result = resultContainer; 131 132 // initialize exception list if not passed in 133 if (exceptionList == null) 134 _exceptions = new ExceptionListImpl(); 135 else 136 _exceptions = exceptionList; 137 138 // initialize context list if not passed in 139 if (ctxList == null) 140 _ctxList = new ContextListImpl(_orb); 141 else 142 _ctxList = ctxList; 143 144 // initialize environment 145 _env = new EnvironmentImpl(); 146 147 } 148 149 public org.omg.CORBA.Object target() 150 { 151 return _target; 152 } 153 154 public String operation() 155 { 156 return _opName; 157 } 158 159 public NVList arguments() 160 { 161 return _arguments; 162 } 163 164 public NamedValue result() 165 { 166 return _result; 167 } 168 169 public Environment env() 170 { 171 return _env; 172 } 173 174 public ExceptionList exceptions() 175 { 176 return _exceptions; 177 } 178 179 public ContextList contexts() 180 { 181 return _ctxList; 182 } 183 184 public synchronized Context ctx() 185 { 186 if (_ctx == null) 187 _ctx = new ContextImpl(_orb); 188 return _ctx; 189 } 190 191 public synchronized void ctx(Context newCtx) 192 { 193 _ctx = newCtx; 194 } 195 196 public synchronized Any add_in_arg() 197 { 198 return _arguments.add(org.omg.CORBA.ARG_IN.value).value(); 199 } 200 201 public synchronized Any add_named_in_arg(String name) 202 { 203 return _arguments.add_item(name, org.omg.CORBA.ARG_IN.value).value(); 204 } 205 206 public synchronized Any add_inout_arg() 207 { 208 return _arguments.add(org.omg.CORBA.ARG_INOUT.value).value(); 209 } 210 211 public synchronized Any add_named_inout_arg(String name) 212 { 213 return _arguments.add_item(name, org.omg.CORBA.ARG_INOUT.value).value(); 214 } 215 216 public synchronized Any add_out_arg() 217 { 218 return _arguments.add(org.omg.CORBA.ARG_OUT.value).value(); 219 } 220 221 public synchronized Any add_named_out_arg(String name) 222 { 223 return _arguments.add_item(name, org.omg.CORBA.ARG_OUT.value).value(); 224 } 225 226 public synchronized void set_return_type(TypeCode tc) 227 { 228 if (_result == null) 229 _result = new NamedValueImpl(_orb); 230 _result.value().type(tc); 231 } 232 233 public synchronized Any return_value() 234 { 235 if (_result == null) 236 _result = new NamedValueImpl(_orb); 237 return _result.value(); 238 } 239 240 public synchronized void add_exception(TypeCode exceptionType) 241 { 242 _exceptions.add(exceptionType); 243 } 244 245 public synchronized void invoke() 246 { 247 doInvocation(); 248 } 249 250 public synchronized void send_oneway() 251 { 252 _isOneWay = true; 253 doInvocation(); 254 } 255 256 public synchronized void send_deferred() 257 { 258 AsynchInvoke invokeObject = new AsynchInvoke(_orb, this, false); 259 new ManagedLocalsThread(invokeObject).start(); 260 } 261 262 public synchronized boolean poll_response() 263 { 264 // this method has to be synchronized even though it seems 265 // "readonly" since the thread object doing the asynchronous 266 // invocation can potentially update this variable in parallel. 267 // updates are currently simply synchronized againt the request 268 // object. 269 return gotResponse; 270 } 271 272 public synchronized void get_response() 273 throws org.omg.CORBA.WrongTransaction 274 { 275 while (gotResponse == false) { 276 // release the lock. wait to be notified by the thread that is 277 // doing the asynchronous invocation. 278 try { 279 wait(); 280 } 281 catch (InterruptedException e) {} 282 } 283 } 284 285 /////////////////////////////////////////////////////////////////////////// 286 // private helper methods 287 288 /* 289 * The doInvocation operation is where the real mechanics of 290 * performing the request invocation is done. 291 */ 292 protected void doInvocation() 293 { 294 org.omg.CORBA.portable.Delegate delegate = StubAdapter.getDelegate( 295 _target ) ; 296 297 // Initiate Client Portable Interceptors. Inform the PIHandler that 298 // this is a DII request so that it knows to ignore the second 299 // inevitable call to initiateClientPIRequest in createRequest. 300 // Also, save the RequestImpl object for later use. 301 _orb.getPIHandler().initiateClientPIRequest( true ); 302 _orb.getPIHandler().setClientPIInfo( this ); 303 304 InputStream $in = null; 305 try { 306 OutputStream $out = delegate.request(null, _opName, !_isOneWay); 307 // Marshal args 308 try { 309 for (int i=0; i<_arguments.count() ; i++) { 310 NamedValue nv = _arguments.item(i); 311 switch (nv.flags()) { 312 case ARG_IN.value: 313 nv.value().write_value($out); 314 break; 315 case ARG_OUT.value: 316 break; 317 case ARG_INOUT.value: 318 nv.value().write_value($out); 319 break; 320 } 321 } 322 } catch ( org.omg.CORBA.Bounds ex ) { 323 throw _wrapper.boundsErrorInDiiRequest( ex ) ; 324 } 325 326 $in = delegate.invoke(null, $out); 327 } catch (ApplicationException e) { 328 // REVISIT - minor code. 329 // This is already handled in subcontract. 330 // REVISIT - uncomment. 331 //throw new INTERNAL(); 332 } catch (RemarshalException e) { 333 doInvocation(); 334 } catch( SystemException ex ) { 335 _env.exception(ex); 336 // NOTE: The exception should not be thrown. 337 // However, JDK 1.4 and earlier threw the exception, 338 // so we keep the behavior to be compatible. 339 throw ex; 340 } finally { 341 delegate.releaseReply(null, $in); 342 } 343 } 344 345 // REVISIT - make protected after development - so xgiop can get it. 346 public void unmarshalReply(InputStream is) 347 { 348 // First unmarshal the return value if it is not void 349 if ( _result != null ) { 350 Any returnAny = _result.value(); 351 TypeCode returnType = returnAny.type(); 352 if ( returnType.kind().value() != TCKind._tk_void ) 353 returnAny.read_value(is, returnType); 354 } 355 356 // Now unmarshal the out/inout args 357 try { 358 for ( int i=0; i<_arguments.count() ; i++) { 359 NamedValue nv = _arguments.item(i); 360 switch( nv.flags() ) { 361 case ARG_IN.value: 362 break; 363 case ARG_OUT.value: 364 case ARG_INOUT.value: 365 Any any = nv.value(); 366 any.read_value(is, any.type()); 367 break; 368 } 369 } 370 } 371 catch ( org.omg.CORBA.Bounds ex ) { 372 // Cannot happen since we only iterate till _arguments.count() 373 } 374 } 375} 376