00001
00005 import mx.data.components.WebServiceConnector;
00006 import gugga.events.EventDispatcher;
00007 import mx.utils.Delegate;
00008
00009 import gugga.collections.HashTable;
00010 import gugga.common.EventDescriptor;
00011 import gugga.common.IEventDispatcher;
00012 import gugga.data.SOAPCallData;
00013 import gugga.logging.Logger;
00014 import gugga.logging.publishers.SOSPublisher;
00015 import gugga.utils.DelayedCallTimeout;
00016 import gugga.utils.Listener;
00017 import gugga.utils.ObjectCloner;
00018 import gugga.utils.DebugUtils;
00019
00020 class gugga.data.DataManager extends EventDispatcher implements IEventDispatcher
00021 {
00022 private var mMethodConnectors : HashTable;
00023 private var mMethodCallQueues : HashTable;
00024 private var mMethodsExecuting : HashTable;
00025
00026 private var mWSDLURL : String;
00027 public function get WSDLURL() : String { return mWSDLURL; }
00028 public function set WSDLURL(aValue:String) : Void
00029 {
00030 mWSDLURL = aValue;
00031
00032 for(var key:String in mMethodConnectors)
00033 {
00034 var connector:WebServiceConnector = WebServiceConnector(mMethodConnectors[key]);
00035 connector.WSDLURL = mWSDLURL;
00036 }
00037 }
00038
00039 public function DataManager()
00040 {
00041 mMethodConnectors = new HashTable();
00042 mMethodCallQueues = new HashTable();
00043 mMethodsExecuting = new HashTable();
00044 }
00045
00046 public function callMethod(aMethodName:String, aArguments:Object, aResultDelegate:Function, aAdditionalDelegateData:Object)
00047 {
00048 callMethodAdvanced(aMethodName, aArguments, aResultDelegate, null, aAdditionalDelegateData);
00049 }
00050
00051 public function callMethodAdvanced(aMethodName:String, aArguments:Object,
00052 aResultDelegate:Function, aFaultDelegate:Function, aAdditionalDelegateData:Object)
00053 {
00054 if(!mMethodConnectors[aMethodName])
00055 {
00056 registerMethod(aMethodName);
00057 }
00058
00059 var callData : SOAPCallData = new SOAPCallData();
00060
00061 callData.MethodName = aMethodName;
00062 callData.Arguments = aArguments;
00063 callData.ResultDelegate = aResultDelegate;
00064 callData.FaultDelegate = aFaultDelegate;
00065 callData.AdditionalDelegateData = aAdditionalDelegateData;
00066
00067 var callQueue : Array = mMethodCallQueues[aMethodName];
00068 callQueue.push(callData);
00069
00070 if(!mMethodsExecuting[aMethodName])
00071 {
00072 triggerNextPendingCall(aMethodName);
00073 }
00074 }
00075
00076 private function registerMethod(aMethodName:String, aOnResultDelegate:Function) : WebServiceConnector
00077 {
00078 var connector : WebServiceConnector = new WebServiceConnector();
00079 connector.WSDLURL = mWSDLURL;
00080 connector.operation = aMethodName;
00081
00082 Listener.createMergingListener(new EventDescriptor(IEventDispatcher(connector), "result"),
00083 Delegate.create(this, onConnectorResult), {methodName: aMethodName});
00084
00085 Listener.createMergingListener(new EventDescriptor(IEventDispatcher(connector), "status"),
00086 Delegate.create(this, onConnectorStatus), {methodName: aMethodName});
00087
00088 mMethodConnectors[aMethodName] = connector;
00089 mMethodCallQueues[aMethodName] = new Array();
00090
00091 return connector;
00092 }
00093
00094 private function triggerNextPendingCall(aMethodName:String)
00095 {
00096 var callQueue : Array = mMethodCallQueues[aMethodName];
00097
00098 if(callQueue[0])
00099 {
00100 var currentCall : SOAPCallData = SOAPCallData(callQueue[0]);
00101 var methodName : String = currentCall.MethodName;
00102 var connector : WebServiceConnector = WebServiceConnector(mMethodConnectors[methodName]);
00103
00104 mMethodsExecuting[methodName] = true;
00105
00106 connector.params = currentCall.Arguments;
00107 connector.trigger();
00108 }
00109 }
00110
00111 private function onConnectorStatus(ev)
00112 {
00113 if(ev.code != "StatusChange")
00114 {
00115 var methodName : String = ev.methodName;
00116 var callQueue : Array = mMethodCallQueues[methodName];
00117
00118
00119 var currentCall : SOAPCallData = SOAPCallData(callQueue.shift());
00120 var faultDelegate : Function = currentCall.FaultDelegate;
00121
00122 var statusCode : String = ev.code;
00123 var faultCode : String = ev.code;
00124 var faultString : String = ev.code;
00125 var faultDetail : String = ev.detail;
00126
00127 faultDelegate(statusCode, faultCode, faultString, faultDetail, currentCall.AdditionalDelegateData);
00128
00129 var logMessage : String = SOSPublisher.getFoldedMessagePackage(
00130 "WebServiceConnector for '" + methodName + "' failed: " + statusCode,
00131 "fault code: " + faultCode + "\n" +
00132 "fault string: " + faultString + "\n" +
00133 "fault detail: " + faultDetail
00134 );
00135
00136 Logger.logWarning(logMessage, this);
00137 }
00138 }
00139
00140 private function onConnectorResult(ev)
00141 {
00142 var callQueue : Array = mMethodCallQueues[ev.methodName];
00143
00144
00145 var currentCall : SOAPCallData = SOAPCallData(callQueue.shift());
00146
00147 var methodName : String = currentCall.MethodName;
00148 var resultDelegate : Function = currentCall.ResultDelegate;
00149 var connector : WebServiceConnector = WebServiceConnector(mMethodConnectors[methodName]);
00150
00151 resultDelegate(connector.results, currentCall.AdditionalDelegateData);
00152
00157 var delayedCallTimeout : DelayedCallTimeout =
00158 new DelayedCallTimeout(10, this, this.triggerNextPendingCallDelayed, methodName);
00159 }
00160
00161 private function triggerNextPendingCallDelayed(aMethodName : String) : Void
00162 {
00163 mMethodsExecuting[aMethodName] = false;
00164 triggerNextPendingCall(aMethodName);
00165 }
00166
00167 public static function getSealedObjectArrayFromResult(aResultObject:Object, aType:Function):Array
00168 {
00169 var objectArray : Array = new Array();
00170
00171 for (var i : Number = 0; i < aResultObject.length; i++)
00172 {
00173 var obj : Object = getSealedObjectFromResult(aResultObject[i], aType);
00174 objectArray.push(obj);
00175 }
00176
00177 return objectArray;
00178 }
00179
00180 public static function getSealedObjectFromResult(aResultObject:Object, aType : Function):Object
00181 {
00182 var obj : Object = new aType();
00183
00184 ObjectCloner.copyProperties(obj, aResultObject);
00185
00186 return obj;
00187 }
00188 }