I have to confess that I lied ever so slightly in that last post. I said that the service code was exactly the same as it was without using the Command metadatatag.
This isn’t strictly true – I had to write a wrapper for AsyncToken to handle the xml translation. I was hoping that I would be able to use an interceptor to intercept the result event, translate the xml and then re-dispatch the event. Jens said that this wasn’t possible though so I needed a neat and tidy way to translate the results of the async call before it made it back to the model.
I did this by wrapping the async token that I get from whatever async operation I am performing. I can then pass this token to parsley so my code can do what it likes to the result before parsley routes it to it’s destination.
AsyncTokenWrapper does just that, it extends AsyncToken and wraps another AsyncToken. When it gets a result or a fault from the original token it applies an optional function to the result or fault before passing this new ResultEvent or FaultEvent onto it’s responders.
Code Below:
package com.pricklythistle.common.service
{
import mx.core.mx_internal;
import mx.messaging.messages.IMessage;
import mx.rpc.AsyncToken;
import mx.rpc.Fault;
import mx.rpc.IResponder;
import mx.rpc.Responder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
use namespace mx_internal
public class AsyncTokenWrapper extends AsyncToken
{
//---------------------------------
//
// Constructor
//
//---------------------------------
public function AsyncTokenWrapper(
token : AsyncToken,
resultProcessingFunction : Function = null,
faultProcessingFunction : Function = null )
{
super();
_token = token;
addResponders();
this.resultProcessingFunction = resultProcessingFunction;
this.faultProcessingFunction = faultProcessingFunction;
}
//---------------------------------
//
// Private Variables
//
//---------------------------------
private var _token : AsyncToken;
//---------------------------------
//
// Properties
//
//---------------------------------
public var resultProcessingFunction : Function;
public var faultProcessingFunction : Function;
//---------------------------------
//
// Public Methods
//
//---------------------------------
private function onResult( data : Object ) : void
{
var originalResultEvent : ResultEvent = ResultEvent( data );
var result : Object = originalResultEvent.result;
if( resultProcessingFunction != null )
{
result = resultProcessingFunction( result );
}
var newResultEvent : ResultEvent = new ResultEvent(
ResultEvent.RESULT,
originalResultEvent.bubbles,
originalResultEvent.cancelable,
result,
this,
originalResultEvent.message );
applyResult( newResultEvent );
}
private function onFault( info : Object ) : void
{
var originalFaultEvent : FaultEvent = FaultEvent( info );
var fault : Fault = originalFaultEvent.fault;
if( faultProcessingFunction != null )
{
fault = faultProcessingFunction( fault ) as Fault;
}
var newFaultEvent : FaultEvent = new FaultEvent(
FaultEvent.FAULT,
originalFaultEvent.bubbles,
originalFaultEvent.cancelable,
fault,
this,
originalFaultEvent.message
);
applyFault( newFaultEvent );
}
//---------------------------------
//
// Private Functions
//
//---------------------------------
private function addResponders() : void
{
_token.addResponder(
new Responder( onResult, onFault ) );
}
}
}
Sorry for the way the code gets mashed up there but you can click on the little button top right to get it in a new window.
4 comments: