1 // 2 // Copyright (c) ZeroC, Inc. All rights reserved. 3 // 4 5 package IceInternal; 6 7 public class OutgoingAsync extends ProxyOutgoingAsyncBase 8 { check(Ice.AsyncResult r, Ice.ObjectPrx prx, String operation)9 public static OutgoingAsync check(Ice.AsyncResult r, Ice.ObjectPrx prx, String operation) 10 { 11 ProxyOutgoingAsyncBase.checkImpl(r, prx, operation); 12 try 13 { 14 return (OutgoingAsync)r; 15 } 16 catch(ClassCastException ex) 17 { 18 throw new IllegalArgumentException("Incorrect AsyncResult object for end_" + operation + " method"); 19 } 20 } 21 OutgoingAsync(Ice.ObjectPrx prx, String operation, CallbackBase cb)22 public OutgoingAsync(Ice.ObjectPrx prx, String operation, CallbackBase cb) 23 { 24 super((Ice.ObjectPrxHelperBase)prx, operation, cb); 25 _encoding = Protocol.getCompatibleEncoding(_proxy._getReference().getEncoding()); 26 _is = null; 27 } 28 OutgoingAsync(Ice.ObjectPrx prx, String operation, CallbackBase cb, Ice.InputStream is, Ice.OutputStream os)29 public OutgoingAsync(Ice.ObjectPrx prx, String operation, CallbackBase cb, Ice.InputStream is, Ice.OutputStream os) 30 { 31 super((Ice.ObjectPrxHelperBase)prx, operation, cb, os); 32 _encoding = Protocol.getCompatibleEncoding(_proxy._getReference().getEncoding()); 33 _is = is; 34 } 35 prepare(String operation, Ice.OperationMode mode, java.util.Map<String, String> ctx, boolean explicitCtx, boolean synchronous)36 public void prepare(String operation, Ice.OperationMode mode, java.util.Map<String, String> ctx, 37 boolean explicitCtx, boolean synchronous) 38 { 39 Protocol.checkSupportedProtocol(Protocol.getCompatibleProtocol(_proxy._getReference().getProtocol())); 40 41 _mode = mode; 42 _synchronous = synchronous; 43 44 if(explicitCtx && ctx == null) 45 { 46 ctx = _emptyContext; 47 } 48 _observer = ObserverHelper.get(_proxy, operation, ctx); 49 50 switch(_proxy._getReference().getMode()) 51 { 52 case Reference.ModeTwoway: 53 case Reference.ModeOneway: 54 case Reference.ModeDatagram: 55 { 56 _os.writeBlob(IceInternal.Protocol.requestHdr); 57 break; 58 } 59 60 case Reference.ModeBatchOneway: 61 case Reference.ModeBatchDatagram: 62 { 63 _proxy._getBatchRequestQueue().prepareBatchRequest(_os); 64 break; 65 } 66 } 67 68 Reference ref = _proxy._getReference(); 69 70 ref.getIdentity().ice_writeMembers(_os); 71 72 // 73 // For compatibility with the old FacetPath. 74 // 75 String facet = ref.getFacet(); 76 if(facet == null || facet.length() == 0) 77 { 78 _os.writeStringSeq(null); 79 } 80 else 81 { 82 String[] facetPath = { facet }; 83 _os.writeStringSeq(facetPath); 84 } 85 86 _os.writeString(operation); 87 88 _os.writeByte((byte) mode.value()); 89 90 if(ctx != null) 91 { 92 // 93 // Explicit context 94 // 95 Ice.ContextHelper.write(_os, ctx); 96 } 97 else 98 { 99 // 100 // Implicit context 101 // 102 Ice.ImplicitContextI implicitContext = ref.getInstance().getImplicitContext(); 103 java.util.Map<String, String> prxContext = ref.getContext(); 104 105 if(implicitContext == null) 106 { 107 Ice.ContextHelper.write(_os, prxContext); 108 } 109 else 110 { 111 implicitContext.write(prxContext, _os); 112 } 113 } 114 } 115 116 @Override sent()117 public boolean sent() 118 { 119 return sent(!_proxy.ice_isTwoway()); // done = true if not a two-way proxy (no response expected) 120 } 121 122 @Override invokeRemote(Ice.ConnectionI connection, boolean compress, boolean response)123 public int invokeRemote(Ice.ConnectionI connection, boolean compress, boolean response) throws RetryException 124 { 125 _cachedConnection = connection; 126 return connection.sendAsyncRequest(this, compress, response, 0); 127 } 128 129 @Override invokeCollocated(CollocatedRequestHandler handler)130 public int invokeCollocated(CollocatedRequestHandler handler) 131 { 132 // The stream cannot be cached if the proxy is not a twoway or there is an invocation timeout set. 133 if(!_proxy.ice_isTwoway() || _proxy._getReference().getInvocationTimeout() > 0) 134 { 135 // Disable caching by marking the streams as cached! 136 _state |= StateCachedBuffers; 137 } 138 return handler.invokeAsyncRequest(this, 0, _synchronous); 139 } 140 141 @Override abort(Ice.Exception ex)142 public void abort(Ice.Exception ex) 143 { 144 int mode = _proxy._getReference().getMode(); 145 if(mode == Reference.ModeBatchOneway || mode == Reference.ModeBatchDatagram) 146 { 147 // 148 // If we didn't finish a batch oneway or datagram request, we 149 // must notify the connection about that we give up ownership 150 // of the batch stream. 151 // 152 _proxy._getBatchRequestQueue().abortBatchRequest(_os); 153 } 154 155 super.abort(ex); 156 } 157 invoke()158 public void invoke() 159 { 160 int mode = _proxy._getReference().getMode(); 161 if(mode == Reference.ModeBatchOneway || mode == Reference.ModeBatchDatagram) 162 { 163 // 164 // NOTE: we don't call sent/completed callbacks for batch AMI requests 165 // 166 _sentSynchronously = true; 167 _proxy._getBatchRequestQueue().finishBatchRequest(_os, _proxy, getOperation()); 168 finished(true, false); 169 } 170 else 171 { 172 // 173 // NOTE: invokeImpl doesn't throw so this can be called from the 174 // try block with the catch block calling abort() in case of an 175 // exception. 176 // 177 invokeImpl(true); // userThread = true 178 } 179 } 180 181 @Override completed(Ice.InputStream is)182 public final boolean completed(Ice.InputStream is) 183 { 184 // 185 // NOTE: this method is called from ConnectionI.parseMessage 186 // with the connection locked. Therefore, it must not invoke 187 // any user callbacks. 188 // 189 190 assert(_proxy.ice_isTwoway()); // Can only be called for twoways. 191 192 if(_childObserver != null) 193 { 194 _childObserver.reply(is.size() - Protocol.headerSize - 4); 195 _childObserver.detach(); 196 _childObserver = null; 197 } 198 199 byte replyStatus; 200 try 201 { 202 // _is can already be initialized if the invocation is retried 203 if(_is == null) 204 { 205 _is = new Ice.InputStream(_instance, IceInternal.Protocol.currentProtocolEncoding); 206 } 207 _is.swap(is); 208 replyStatus = _is.readByte(); 209 210 switch(replyStatus) 211 { 212 case ReplyStatus.replyOK: 213 { 214 break; 215 } 216 217 case ReplyStatus.replyUserException: 218 { 219 if(_observer != null) 220 { 221 _observer.userException(); 222 } 223 break; 224 } 225 226 case ReplyStatus.replyObjectNotExist: 227 case ReplyStatus.replyFacetNotExist: 228 case ReplyStatus.replyOperationNotExist: 229 { 230 Ice.Identity id = new Ice.Identity(); 231 id.ice_readMembers(_is); 232 233 // 234 // For compatibility with the old FacetPath. 235 // 236 String[] facetPath = _is.readStringSeq(); 237 String facet; 238 if(facetPath.length > 0) 239 { 240 if(facetPath.length > 1) 241 { 242 throw new Ice.MarshalException(); 243 } 244 facet = facetPath[0]; 245 } 246 else 247 { 248 facet = ""; 249 } 250 251 String operation = _is.readString(); 252 253 Ice.RequestFailedException ex = null; 254 switch(replyStatus) 255 { 256 case ReplyStatus.replyObjectNotExist: 257 { 258 ex = new Ice.ObjectNotExistException(); 259 break; 260 } 261 262 case ReplyStatus.replyFacetNotExist: 263 { 264 ex = new Ice.FacetNotExistException(); 265 break; 266 } 267 268 case ReplyStatus.replyOperationNotExist: 269 { 270 ex = new Ice.OperationNotExistException(); 271 break; 272 } 273 274 default: 275 { 276 assert(false); 277 break; 278 } 279 } 280 281 ex.id = id; 282 ex.facet = facet; 283 ex.operation = operation; 284 throw ex; 285 } 286 287 case ReplyStatus.replyUnknownException: 288 case ReplyStatus.replyUnknownLocalException: 289 case ReplyStatus.replyUnknownUserException: 290 { 291 String unknown = _is.readString(); 292 293 Ice.UnknownException ex = null; 294 switch(replyStatus) 295 { 296 case ReplyStatus.replyUnknownException: 297 { 298 ex = new Ice.UnknownException(); 299 break; 300 } 301 302 case ReplyStatus.replyUnknownLocalException: 303 { 304 ex = new Ice.UnknownLocalException(); 305 break; 306 } 307 308 case ReplyStatus.replyUnknownUserException: 309 { 310 ex = new Ice.UnknownUserException(); 311 break; 312 } 313 314 default: 315 { 316 assert(false); 317 break; 318 } 319 } 320 321 ex.unknown = unknown; 322 throw ex; 323 } 324 325 default: 326 { 327 throw new Ice.UnknownReplyStatusException(); 328 } 329 } 330 331 return finished(replyStatus == ReplyStatus.replyOK, true); 332 } 333 catch(Ice.Exception ex) 334 { 335 return completed(ex); 336 } 337 } 338 startWriteParams(Ice.FormatType format)339 public Ice.OutputStream startWriteParams(Ice.FormatType format) 340 { 341 _os.startEncapsulation(_encoding, format); 342 return _os; 343 } 344 endWriteParams()345 public void endWriteParams() 346 { 347 _os.endEncapsulation(); 348 } 349 writeEmptyParams()350 public void writeEmptyParams() 351 { 352 _os.writeEmptyEncapsulation(_encoding); 353 } 354 writeParamEncaps(byte[] encaps)355 public void writeParamEncaps(byte[] encaps) 356 { 357 if(encaps == null || encaps.length == 0) 358 { 359 _os.writeEmptyEncapsulation(_encoding); 360 } 361 else 362 { 363 _os.writeEncapsulation(encaps); 364 } 365 } 366 startReadParams()367 public Ice.InputStream startReadParams() 368 { 369 _is.startEncapsulation(); 370 return _is; 371 } 372 endReadParams()373 public void endReadParams() 374 { 375 _is.endEncapsulation(); 376 } 377 readEmptyParams()378 public void readEmptyParams() 379 { 380 _is.skipEmptyEncapsulation(); 381 } 382 readParamEncaps()383 public byte[] readParamEncaps() 384 { 385 return _is.readEncapsulation(null); 386 } 387 throwUserException()388 public final void throwUserException() 389 throws Ice.UserException 390 { 391 try 392 { 393 _is.startEncapsulation(); 394 _is.throwException(null); 395 } 396 catch(Ice.UserException ex) 397 { 398 _is.endEncapsulation(); 399 throw ex; 400 } 401 } 402 403 @Override cacheMessageBuffers()404 public void cacheMessageBuffers() 405 { 406 if(_proxy._getReference().getInstance().cacheMessageBuffers() > 0) 407 { 408 synchronized(this) 409 { 410 if((_state & StateCachedBuffers) > 0) 411 { 412 return; 413 } 414 _state |= StateCachedBuffers; 415 } 416 417 if(_is != null) 418 { 419 _is.reset(); 420 } 421 _os.reset(); 422 423 _proxy.cacheMessageBuffers(_is, _os); 424 425 _is = null; 426 _os = null; 427 } 428 } 429 430 final private Ice.EncodingVersion _encoding; 431 private Ice.InputStream _is; 432 433 // 434 // If true this AMI request is being used for a generated synchronous invocation. 435 // 436 private boolean _synchronous; 437 438 private static final java.util.Map<String, String> _emptyContext = new java.util.HashMap<String, String>(); 439 } 440