package com.maccman.activeresource { import com.adobe.webapis.URLLoaderBase; import com.maccman.activeresource.IndexedCollection; import flash.net.URLRequest; import flash.events.Event; import mx.utils.StringUtil; import com.adobe.utils.DateUtil; import com.adobe.net.DynamicURLLoader; import flash.net.URLLoader; import flash.net.URLLoaderDataFormat; import flash.net.URLRequest; import flash.net.URLRequestHeader; import flash.net.URLRequestMethod; import flash.net.URLVariables; import mx.rpc.IResponder; import mx.rpc.events.FaultEvent; import mx.rpc.AsyncToken; import mx.utils.ArrayUtil; import mx.controls.Alert; import flash.events.HTTPStatusEvent; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.events.SecurityErrorEvent; import com.adobe.net.URI; import com.maccman.net.SocketURLLoader; import com.maccman.aireo.model.AireoModelLocator; import flash.system.Security; dynamic public class ActiveResource extends URLLoaderBase { protected var _baseUrl:URI; protected var _resourceName:String; protected var _modelName:String; protected var _path:String; protected var _responder:IResponder;; protected var _username:String; protected var _password:String; protected var _current_id:Number; public static const GET:String = "GET" public static const PUT:String = "PUT" public static const POST:String = "POST" public static const DELETE:String = "DELETE" protected var _showBusyCursor:Boolean = false; public var remembrall:String; //private var loader:HTTPURLLoader; //private var loader:URLLoader; private var loader:SocketURLLoader; private static var model:AireoModelLocator = AireoModelLocator.getInstance() public function ActiveResource(baseUrl:URI, modelName:String, responder:IResponder){ this._baseUrl = baseUrl; this._modelName = modelName this._resourceName = modelName + 's'; this._responder = responder } public function set showBusyCursor(t:Boolean) { this._showBusyCursor = t; } // Should be static? public function find_all(conditions:* = null):void { getAction(null,conditions); } public function find(id:Number,conditions:* = null):void { getAction(id.toString(),conditions); } public function save(data:Object):void { data.id ? update(data) : create(data) } protected function update(data:Object):void { _current_id = data.id; putAction(data); } protected function create(data:Object):void { postAction(data); } public function destroy(id:Number):void { _current_id = id; deleteAction(id); } public function set username(user:String):void { this._username = user; } public function set password(pass:String):void { this._password = pass; } public function set resource(res:String):void { this._resourceName = res; } protected function getAction(id:String = null, conditions:* = null):void{ if(id){ connection(getActionResultHandler, GET, null, '/' + id, conditions); } else { connection(getActionResultHandler, GET, null, '/', conditions); } } protected function getActionResultHandler(event:Event):void { _responder.result(XML(event.target.data)) } protected function putAction(data:Object):void { connection(putActionResultHandler, PUT, data, '/' + data.id); } protected function putActionResultHandler(event:Event):void { find(_current_id) } protected function postAction(data:Object):void { connection(postActionResultHandler, POST, data, null); } protected function postActionResultHandler(event:Event):void { var loc:String = SocketURLLoader(event.target).responseHeaders['Location']; var num:Number = Number(loc.split('/').pop()); find(num); } protected function deleteAction(id:Number):void { connection(deleteActionResultHandler, DELETE, null, '/' + id.toString()); } protected function deleteActionResultHandler(event:Event):void { var o:Object = new Object(); o.id = _current_id; _responder.result(o); } protected function parse_conditions(con:*):String { var st:String = new String(); if (con is Array) { var r:Array = new Array(); for ( var i:Number=0 ;i < con.length; i ++){ r.push('conditions[]=' + URI.escapeChars(con[i])); } st = r.join('&') } else { st = 'conditions=' + URI.escapeChars(con) } return st; } protected function parse_data_into_string(data:Object):URLVariables { var ar:Array = new Array(); for(var i:String in data) { ar.push(this._modelName + '[' + i + ']=' + data[i]); } return new URLVariables(ar.join('&')); } protected function progressHandler(event:ProgressEvent):void { model.requestProgress = "Loaded " + Math.round((event.bytesLoaded / event.bytesTotal) * 100) + "%"; } protected function httpFaultHandler(event:HTTPStatusEvent):void { switch(event.status) { case 200: break; case 401: Alert.show( "Your session has expired, please log in again", "Session Expired" ); break; case 500: Alert.show( "Oops, Aireo has had an error, please try again in a few minutes", "Error" ); break; case 409: Alert.show( "You're trying to overright newer data, please refresh", "Stale Object Error" ); break; default: _responder.fault(event); } } protected function IOFaultHandler(event:Event):void { Alert.show( "There has been an error connecting to Aireo's servers, please make sure you're connected and try again.","Connection Error") } protected function securityFaultHandler(event:Event):void { Alert.show( "There has been a security error, please contact Aireo Support.", "Security Error" ) } protected function connection(resultHandler:Function, method:String, data:Object = null, extraUrlInfo:String = null, conditions:* = null):void { //loader = new HTTPURLLoader(); //loader = new URLLoader; loader = new SocketURLLoader(); loader.addEventListener(Event.COMPLETE, resultHandler); loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpFaultHandler) loader.addEventListener(IOErrorEvent.IO_ERROR, IOFaultHandler) loader.addEventListener(ProgressEvent.PROGRESS, progressHandler) loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityFaultHandler) //need to listen for errors var request:URLRequest = new URLRequest(); request.url = this._baseUrl.toString() + '/' + this._resourceName; if (extraUrlInfo) { request.url += extraUrlInfo; } if (data) { request.data = parse_data_into_string(data); } //else { // request.data = new Object(); //} //request.method = URLRequestMethod.POST; loader.method = method; if(_username) { var credentials:String = ""; var authHeader:URLRequestHeader = new URLRequestHeader("Authorization","Basic " + credentials); request.requestHeaders.push(authHeader); } //request.url += "?_method=" + method if (conditions) { request.url += "&" + parse_conditions(conditions) } if (remembrall) { request.requestHeaders.push(new URLRequestHeader("Cookie","remembrall=" + remembrall)); } //loader.httpUrl = new URI(this._baseUrl.toString() + '/' + this._resourceName) //loader.httpMethod = method; Security.loadPolicyFile(_baseUrl.toString() + '/crossdomain.xml'); loader.showBusyCursor = _showBusyCursor; loader.requestTimeout = 6; loader.load(request); } } }