| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // Licensed to the Apache Software Foundation (ASF) under one or more |
| // contributor license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright ownership. |
| // The ASF licenses this file to You under the Apache License, Version 2.0 |
| // (the "License"); you may not use this file except in compliance with |
| // the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| package mx.rpc |
| { |
| |
| import mx.core.mx_internal; |
| import mx.messaging.Producer; |
| import mx.messaging.messages.AcknowledgeMessage; |
| import mx.messaging.messages.AsyncMessage; |
| import mx.messaging.messages.ErrorMessage; |
| import mx.messaging.messages.IMessage; |
| import mx.messaging.events.MessageEvent; |
| import mx.messaging.events.MessageFaultEvent; |
| |
| use namespace mx_internal; |
| |
| /** |
| * The AsyncRequest class provides an abstraction of messaging for RPC call invocation. |
| * An AsyncRequest allows multiple requests to be made on a remote destination |
| * and will call back to the responder specified within the request when |
| * the remote request is completed. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public class AsyncRequest extends mx.messaging.Producer |
| { |
| //-------------------------------------------------------------------------- |
| // |
| // Constructor |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Constructs a new asynchronous request. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function AsyncRequest() |
| { |
| super(); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Public Methods |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Delegates to the results to responder |
| * @param ack Message acknowlegdement of message previously sent |
| * @param msg Message that was recieved the acknowledgement |
| * @private |
| */ |
| override public function acknowledge(ack:AcknowledgeMessage, msg:IMessage):void |
| { |
| var error:Boolean = ack.headers[AcknowledgeMessage.ERROR_HINT_HEADER]; |
| // super will clean the error hint from the message |
| super.acknowledge(ack, msg); |
| // if acknowledge is *not* for a message that caused an error |
| // dispatch a result event |
| if (!error) |
| { |
| var act:String = ack.correlationId; |
| var resp:IResponder = IResponder(_pendingRequests[act]); |
| if (resp) |
| { |
| delete _pendingRequests[act]; |
| resp.result(MessageEvent.createEvent(MessageEvent.RESULT, ack)); |
| } |
| } |
| } |
| |
| /** |
| * Delegates to the fault to responder |
| * @param error message. |
| * The error codes and information are contained in the |
| * <code>headers</code> property |
| * @param msg Message original message that caused the fault. |
| * @private |
| */ |
| override public function fault(errMsg:ErrorMessage, msg:IMessage):void |
| { |
| super.fault(errMsg, msg); |
| |
| if (_ignoreFault) |
| return; |
| |
| // This used to use the errMsg.correlationId here but |
| // if the server fails to deserialize the message (like if |
| // the body references a non-existent server class) |
| // it cannot supply a correlationId to the error message. |
| var act:String = msg.messageId; |
| var resp:IResponder = IResponder(_pendingRequests[act]); |
| if (resp) |
| { |
| delete _pendingRequests[act]; |
| resp.fault(MessageFaultEvent.createEvent(errMsg)); |
| } |
| } |
| |
| /** |
| * Returns <code>true</code> if there are any pending requests for the passed in message. |
| * |
| * @param msg The message for which the existence of pending requests is checked. |
| * |
| * @return Returns <code>true</code> if there are any pending requests for the |
| * passed in message; otherwise, returns <code>false</code>. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function hasPendingRequestForMessage(msg:IMessage):Boolean |
| { |
| var act:String = msg.messageId; |
| return _pendingRequests[act]; |
| } |
| |
| |
| /** |
| * Dispatches the asynchronous request and stores the responder to call |
| * later. |
| * |
| * @param msg The message to be sent asynchronously. |
| * |
| * @param responder The responder to be called later. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function invoke(msg:IMessage, responder:IResponder):void |
| { |
| _pendingRequests[msg.messageId] = responder; |
| send(msg); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Variables |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * manages a list of all pending requests. each request must implement |
| * IResponder |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| private var _pendingRequests:Object = {}; |
| } |
| } |