package marstonstudio.lib.framework.service { import marstonstudio.lib.framework.command.IResponderCommand; import marstonstudio.lib.logging.Logger; import flash.events.Event; import flash.events.HTTPStatusEvent; import flash.events.IOErrorEvent; import flash.events.SecurityErrorEvent; import flash.net.URLLoader; import flash.net.URLRequest; import flash.net.URLRequestMethod; import flash.net.URLVariables; /** * Flash Rest Service for making calls to a Rest service. * * @author Jonathan Marston * @version 2007.07.07 * * This work is licensed under a Creative Commons Attribution NonCommercial ShareAlike 3.0 License. * @see http://creativecommons.org/licenses/by-nc-sa/3.0/ */ public class RestService { /** * Create logger reference */ private var logger:Logger; /** * Type for http GET */ public static const GET:String = "GET"; /** * Type for http POST */ public static const POST:String = "POST"; /** * Type for http PUT */ public static const PUT:String = "PUT"; /** * Type for http DELETE */ public static const DELETE:String = "DELETE"; /** * Responder for the rest service to return results to */ private var _responderCommand:IResponderCommand; /** * Rest Loader */ private var _urlLoader:URLLoader; /** * Rest Request */ private var _urlRequest:URLRequest; /** * Rest Variable */ protected var _urlVariables:URLVariables; /** * Type of REST call to make */ private var _restMethod:String; /** * Begining of url fof REST service */ private var _restPath:String; /** * End of url for REST service */ private var _restAction:String; /** * Constructor. Initialize logger. Initialize UrlLoader the root url of the rest service and the method. * Populate the urlVariables with the appropriate _method to support PUT and DELETE operations. * * @param responderCommand Command that should receive responses from the service * @param restMethod Method to use in making request GET, POST, PUT, DELETE * @param restPath Begining of address of url to use when making a request. * @param restAction Optional end of address of url to use when making a request. */ public function RestService(responderCommand:IResponderCommand, restMethod:String, restPath:String, restAction:String = ""):void { logger = Logger.buildLogger(this); logger.debug("Constructor"); this._responderCommand = responderCommand; this._restMethod = restMethod; this._restPath = restPath; this._restAction = restAction; _urlLoader = new URLLoader(); _urlLoader.addEventListener(Event.COMPLETE, _responderCommand.onResult); _urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onHttpStatus); _urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onIoError); _urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError); _urlVariables = new URLVariables(); _urlRequest = new URLRequest(); switch (_restMethod) { case GET: _urlRequest.method = URLRequestMethod.GET; break; case POST: _urlRequest.method = URLRequestMethod.POST; break; case PUT: _urlVariables._method = RestService.PUT; _urlRequest.method = URLRequestMethod.POST; break; case DELETE: _urlVariables._method = RestService.DELETE; _urlRequest.method = URLRequestMethod.POST; break; } //assign data to request _urlRequest.data = _urlVariables; } /** * Add a url variable to the service request */ public function addParameter(name:String, value:Object) { logger.debug("addParameter " + name + ": " + value.toString()); _urlVariables[name] = value.toString(); } /** * Build a rest request url and make the request */ public function load(input:Object):void { var requestAddress = _restPath + "/" + input.toString() + ".xml" + _restAction; logger.debug("load " + requestAddress); //logger.debug("variables: " + _urlVariables.toString()); _urlRequest.url = requestAddress; _urlLoader.load(_urlRequest); } /** * Handler for HttpStatus messages. * * @param eventObj HTTPStatusEvent dispatched by URLLoader */ protected function onHttpStatus(eventObj:HTTPStatusEvent):void { logger.debug("onHttpStatus " + eventObj.status.toString()); switch (eventObj.status.toString()) { case "0": //Continue break; case "100": //Continue break; case "101": //Switching Protocols break; case "200": //OK break; case "201": //Created break; case "202": //Accepted break; case "203": //Non-Authoritative Information break; case "204": //No Content break; case "205": //Reset Content break; case "206": //Partial Content break; case "300": //Multiple Choices break; case "301": //Moved Permanently break; case "302": //Found break; case "303": //See Other break; case "304": //Not Modified break; case "305": //Use Proxy break; case "307": //Temporary Redirect break; case "400": //Bad Request _responderCommand.onFault(eventObj); break; case "401": //Unauthorized _responderCommand.onFault(eventObj); break; case "402": //Payment Required _responderCommand.onFault(eventObj); break; case "403": //Forbidden _responderCommand.onFault(eventObj); break; case "404": //Not Found _responderCommand.onFault(eventObj); break; case "405": //Method Not Allowed _responderCommand.onFault(eventObj); break; case "406": //Not Acceptable _responderCommand.onFault(eventObj); break; } } /** * Handler for IO errors. * Invoke onFault to manage the failure. * * @param eventObj IOErrorEvent dispatched by URLLoader */ protected function onIoError(eventObj:IOErrorEvent):void { logger.fatal("onIoError"); _responderCommand.onFault(eventObj); } /** * Handler for security errors. * Invoke onFault to manage the failure. * * @param eventObj SecurityErrorEvent dispatched by URLLoader */ protected function onSecurityError(eventObj:SecurityErrorEvent):void { logger.fatal("onSecurityError"); _responderCommand.onFault(eventObj); } /** * Get the data from the urlLoader */ public function get data():XML { return XML(_urlLoader.data); } } }