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