/Source/Modules/Testing/iCognition/Network/RemoteResource.as
ActionScript | 392 lines | 285 code | 59 blank | 48 comment | 38 complexity | 1c687fce8c4c195cb4579c3762f0914b MD5 | raw file
- package iCognition.Network
- {
- import flash.display.Loader;
- import flash.events.Event;
- import flash.events.HTTPStatusEvent;
- import flash.events.IOErrorEvent;
- import flash.events.ProgressEvent;
- import flash.net.URLLoader;
- import flash.net.URLRequest;
- import flash.system.ApplicationDomain;
- import flash.system.LoaderContext;
- import flash.system.Security;
- import iCognition.Errors.BadArgumentError;
- import iCognition.Errors.ErrorManager;
- import iCognition.Errors.FileNotFoundError;
- import iCognition.Events.RemoteResourceEvent;
- import iCognition.Geometry.Size;
- import iCognition.iCogObject;
- import iCognition.Utilities.Log;
- import iCognition.Utilities.StringUtils;
-
- public class RemoteResource extends iCogObject
- {
- protected var __status:Object=new Object();
- protected var __file:*=null;
- protected var __options:Object=new Object();
- protected var __url:String="";
- protected var __requestURL:String="";
- protected var __sandboxed:Boolean=false;
-
- public function RemoteResource(_url:String="",options:Object=null)
- {
- if (_url && _url.length)
- url=_url;
- if (options)
- __options=options;
- __status={
- downloaded:false,
- bytesTotal:0,
- bytesLoaded:0
- };
-
- //Check if we need to enable auto-binary mode
- if (__options.binary==null)
- {
- var tempURL=url.toLowerCase();
- if (StringUtils.endsWith(tempURL,".swf") ||
- StringUtils.endsWith(tempURL,".png") ||
- StringUtils.endsWith(tempURL,".jpg") ||
- StringUtils.endsWith(tempURL,".gif") )
- __options.binary=false;
- else
- __options.binary=true;
- }
-
- var event_dispatcher:Object=null;
-
- //Decide whether we need to use a Loader or a URLLoader object
- if (__options.binary)
- {
- __file=new URLLoader();
- event_dispatcher=__file;
- }
- else
- {
- __file=new Loader();
- event_dispatcher=__file.contentLoaderInfo;
- addChild(__file);
-
- }
-
- //Add common event listeners
- event_dispatcher.addEventListener(HTTPStatusEvent.HTTP_STATUS, __httpStatus);
- event_dispatcher.addEventListener(IOErrorEvent.IO_ERROR, __error);
- event_dispatcher.addEventListener(ProgressEvent.PROGRESS, __progress);
- event_dispatcher.addEventListener(Event.COMPLETE,__complete);
- }
-
- public static function normalizeURL(u:String):String
- {
- //Do nothing to absolute URIs that start with http: or https:
- if (u.match(new RegExp("^https?:","i")))
- return u;
-
- //Split the URL into path and query
- var splitPath:Array=u.split('?',1);
- var relativePath:String=splitPath[0];
- var query:String="";
- if (splitPath[1])
- query=splitPath[1];
-
- //normalize a relative URL
- var fromRoot:Boolean=false;
-
- //Does it start with a '/'?
- if (StringUtils.trim(relativePath).charAt(0)=='/')
- fromRoot=true;
- //Split the relative path
- var path:Array=relativePath.split('/');
-
- var i:int=0;
- //Loop over each element.
- while (i<path.length)
- {
- var dir=StringUtils.trim(path[i]);
- //Delete empty elements
- if (!dir.length)
- {
- path.splice(i,1);
- continue;
- }
-
- //Found a reference to the parent
- if (dir=='..')
- {
- //Move up only the previous wasn't purposefully left in
- if ((i>0) && (path[i-1]!=".."))
- {
- path.splice(i-1,2);
- i--;
- continue;
- }
- //otherwise, there is nowhere else to move,
- //so we can just delete the redundant '..',
- //unless the path is relative to the current file (not root)
- //in which case we should let the server resolve any '..'
- if (fromRoot)
- {
- path.splice(i,1);
- continue;
- }
- }
-
- i++;
- }
- var result:String=path.join('/');
-
- //Was it relative to the root? if yes, restore the slash
- if (fromRoot)
- result='/'+result;
-
- //Restore the query part
- if (query.length)
- result+='?'+query;
-
- return result;
- }
-
- public function download():void
- {
- if (!file)
- throw new BadArgumentError("RemoteResource property 'file' cannot be null.",this, "download");
-
- if (file is Loader)
- {
- var lc:LoaderContext;
- //Using method B here.
- //http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e07.html
- if (__sandboxed)
- lc=new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain));
- else
- lc=new LoaderContext(false, ApplicationDomain.currentDomain);
-
- file.load(new URLRequest(requestURL),lc);
- }
- else
- file.load(new URLRequest(requestURL));
- }
-
- public function get data():*
- {
- if (!this.file)
- return null
-
- if (this.file is URLLoader)
- return this.file.data;
-
- if (this.file is Loader)
- return this.file.content;
- }
-
- //Public properties
- public function get url():String
- {
- return __url;
- }
-
- public function get requestURL():String
- {
- return __requestURL;
- }
-
- public function set url(newValue:String):void
- {
- if (!newValue)
- throw new BadArgumentError("RemoteResource URL cannot be null.", this, "set url");
-
- __url=newValue;
-
- if ((__url.indexOf("http://")!=0) && (BaseURL))
- __requestURL=BaseURL+__url;
- else
- __requestURL=__url;
-
- //Normalize the URL (Flash Player 9 throws Security Sandbox Violation errors if the path
- //contains '..'
- __requestURL=normalizeURL(__requestURL);
- }
-
- public function get status():Object
- {
- return __status;
- }
-
- public function get file():*
- {
- return __file;
- }
-
- public function get sandboxed():Boolean
- {
- return __sandboxed;
- }
-
- public function set sandboxed(newValue:Boolean):void
- {
- //Takes care of both 'false' and 'null' values
- if (!newValue)
- __sandboxed=false;
- else
- __sandboxed=true;
- }
- /**
- * Resource HTTPStatus Event handler
- * @callback
- */
- private function __httpStatus(e:HTTPStatusEvent):void
- {
- try
- {
- this.status.httpCode=e.status;
- }
- catch (e:*)
- {
- ErrorManager.error(e,this);
- }
- }
-
- /**
- * Resource ProgressEvent.PROGRESS handler
- * @callback
- */
- private function __progress(e:ProgressEvent):void
- {
- try
- {
- if (!e.target)
- {
- Log.warning("Unable to access target of event "+e.type,this);
- return;
- }
-
- //Store these values
- this.status.bytesLoaded=e.bytesLoaded;
- this.status.bytesTotal=e.bytesTotal;
- }
- catch (e:*)
- {
- ErrorManager.fatal(e,this);
- }
- }
-
- /**
- * Resource IOErrorEvent.IO_ERROR handler
- * @callback
- */
- private function __error(e:IOErrorEvent):void
- {
- try
- {
- if (!this.status)
- {
- Log.warning("Unable to access the 'status' property of the RemoteResource target for event "+e.type+".",this);
- return;
- }
-
- this.status.downloaded=false;
- this.status.error=new FileNotFoundError(this,e.text,this, "__error", new Error(e.text));
-
- //Forward the error
- if (this.hasEventListener(RemoteResourceEvent.ERROR))
- dispatchEvent(new RemoteResourceEvent(this,RemoteResourceEvent.ERROR,"File not found: "+requestURL));
- else
- Log.extra("[RemoteResource::__error] Not dispatching RemoteResourceEvent.ERROR because there are no handlers attached.");
- }
- catch (e:*)
- {
- //ErrorManager.fatal(e,this);
- }
- }
-
- /**
- * Resource Event.COMPLETE handler
- * @callback
- */
- private function __complete(e:Event)
- {
- try
- {
- if (!this.status)
- {
- Log.warning("Unable to access the 'status' property for event "+e.type+".",this);
- return;
- }
-
- //Mark the resource as downloaded
- this.status.downloaded=true;
- this.status.error=null;
-
- //Dispatch resource complete event
- if (this.hasEventListener(RemoteResourceEvent.COMPLETE))
- dispatchEvent(new RemoteResourceEvent(this, RemoteResourceEvent.COMPLETE));
- else
- Log.extra("[RemoteResource::__complete] Warning: Cannot dispatch event: no event handler registered for "+RemoteResourceEvent.COMPLETE);
- }
- catch(e:*)
- {
- ErrorManager.fatal(e,this);
- }
- }
-
- public function onError(method:Function)
- {
- addEventListener(RemoteResourceEvent.ERROR, method);
- }
-
- public function onProgress(method:Function)
- {
- addEventListener(RemoteResourceEvent.PROGRESS, method);
- }
-
- public function onComplete(method:Function)
- {
- addEventListener(RemoteResourceEvent.COMPLETE,method);
- }
-
- //Is the file attachable to the stage?
- public function canAttach():Boolean
- {
- if ((this.file) && (this.file is Loader))
- return true;
-
- return false;
- }
-
- //Has the file been downloaded in binary mode?
- public function isBinary():Boolean
- {
- if ((__options) && (__options.binary!==null) && (__options.binary===true))
- return true;
-
- return false;
- }
-
- //Returns the width of the resource or null on Error
- public function get size():Size
- {
- var result:Size=null;
- try
- {
- if (!__file)
- return null;
- result=new Size(__file.contentLoaderInfo.width,__file.contentLoaderInfo.height);
- }
- catch(e:*)
- {
- Log.error(e);
- }
-
- return result;
- }
- }
- }