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