PageRenderTime 169ms CodeModel.GetById 11ms RepoModel.GetById 5ms app.codeStats 0ms

/Source/Modules/Testing/iCognition/Network/RemoteResource.as

http://icog.googlecode.com/
ActionScript | 392 lines | 285 code | 59 blank | 48 comment | 38 complexity | 1c687fce8c4c195cb4579c3762f0914b MD5 | raw file
  1. package iCognition.Network
  2. {
  3. import flash.display.Loader;
  4. import flash.events.Event;
  5. import flash.events.HTTPStatusEvent;
  6. import flash.events.IOErrorEvent;
  7. import flash.events.ProgressEvent;
  8. import flash.net.URLLoader;
  9. import flash.net.URLRequest;
  10. import flash.system.ApplicationDomain;
  11. import flash.system.LoaderContext;
  12. import flash.system.Security;
  13. import iCognition.Errors.BadArgumentError;
  14. import iCognition.Errors.ErrorManager;
  15. import iCognition.Errors.FileNotFoundError;
  16. import iCognition.Events.RemoteResourceEvent;
  17. import iCognition.Geometry.Size;
  18. import iCognition.iCogObject;
  19. import iCognition.Utilities.Log;
  20. import iCognition.Utilities.StringUtils;
  21. public class RemoteResource extends iCogObject
  22. {
  23. protected var __status:Object=new Object();
  24. protected var __file:*=null;
  25. protected var __options:Object=new Object();
  26. protected var __url:String="";
  27. protected var __requestURL:String="";
  28. protected var __sandboxed:Boolean=false;
  29. public function RemoteResource(_url:String="",options:Object=null)
  30. {
  31. if (_url && _url.length)
  32. url=_url;
  33. if (options)
  34. __options=options;
  35. __status={
  36. downloaded:false,
  37. bytesTotal:0,
  38. bytesLoaded:0
  39. };
  40. //Check if we need to enable auto-binary mode
  41. if (__options.binary==null)
  42. {
  43. var tempURL=url.toLowerCase();
  44. if (StringUtils.endsWith(tempURL,".swf") ||
  45. StringUtils.endsWith(tempURL,".png") ||
  46. StringUtils.endsWith(tempURL,".jpg") ||
  47. StringUtils.endsWith(tempURL,".gif") )
  48. __options.binary=false;
  49. else
  50. __options.binary=true;
  51. }
  52. var event_dispatcher:Object=null;
  53. //Decide whether we need to use a Loader or a URLLoader object
  54. if (__options.binary)
  55. {
  56. __file=new URLLoader();
  57. event_dispatcher=__file;
  58. }
  59. else
  60. {
  61. __file=new Loader();
  62. event_dispatcher=__file.contentLoaderInfo;
  63. addChild(__file);
  64. }
  65. //Add common event listeners
  66. event_dispatcher.addEventListener(HTTPStatusEvent.HTTP_STATUS, __httpStatus);
  67. event_dispatcher.addEventListener(IOErrorEvent.IO_ERROR, __error);
  68. event_dispatcher.addEventListener(ProgressEvent.PROGRESS, __progress);
  69. event_dispatcher.addEventListener(Event.COMPLETE,__complete);
  70. }
  71. public static function normalizeURL(u:String):String
  72. {
  73. //Do nothing to absolute URIs that start with http: or https:
  74. if (u.match(new RegExp("^https?:","i")))
  75. return u;
  76. //Split the URL into path and query
  77. var splitPath:Array=u.split('?',1);
  78. var relativePath:String=splitPath[0];
  79. var query:String="";
  80. if (splitPath[1])
  81. query=splitPath[1];
  82. //normalize a relative URL
  83. var fromRoot:Boolean=false;
  84. //Does it start with a '/'?
  85. if (StringUtils.trim(relativePath).charAt(0)=='/')
  86. fromRoot=true;
  87. //Split the relative path
  88. var path:Array=relativePath.split('/');
  89. var i:int=0;
  90. //Loop over each element.
  91. while (i<path.length)
  92. {
  93. var dir=StringUtils.trim(path[i]);
  94. //Delete empty elements
  95. if (!dir.length)
  96. {
  97. path.splice(i,1);
  98. continue;
  99. }
  100. //Found a reference to the parent
  101. if (dir=='..')
  102. {
  103. //Move up only the previous wasn't purposefully left in
  104. if ((i>0) && (path[i-1]!=".."))
  105. {
  106. path.splice(i-1,2);
  107. i--;
  108. continue;
  109. }
  110. //otherwise, there is nowhere else to move,
  111. //so we can just delete the redundant '..',
  112. //unless the path is relative to the current file (not root)
  113. //in which case we should let the server resolve any '..'
  114. if (fromRoot)
  115. {
  116. path.splice(i,1);
  117. continue;
  118. }
  119. }
  120. i++;
  121. }
  122. var result:String=path.join('/');
  123. //Was it relative to the root? if yes, restore the slash
  124. if (fromRoot)
  125. result='/'+result;
  126. //Restore the query part
  127. if (query.length)
  128. result+='?'+query;
  129. return result;
  130. }
  131. public function download():void
  132. {
  133. if (!file)
  134. throw new BadArgumentError("RemoteResource property 'file' cannot be null.",this, "download");
  135. if (file is Loader)
  136. {
  137. var lc:LoaderContext;
  138. //Using method B here.
  139. //http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e07.html
  140. if (__sandboxed)
  141. lc=new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain));
  142. else
  143. lc=new LoaderContext(false, ApplicationDomain.currentDomain);
  144. file.load(new URLRequest(requestURL),lc);
  145. }
  146. else
  147. file.load(new URLRequest(requestURL));
  148. }
  149. public function get data():*
  150. {
  151. if (!this.file)
  152. return null
  153. if (this.file is URLLoader)
  154. return this.file.data;
  155. if (this.file is Loader)
  156. return this.file.content;
  157. }
  158. //Public properties
  159. public function get url():String
  160. {
  161. return __url;
  162. }
  163. public function get requestURL():String
  164. {
  165. return __requestURL;
  166. }
  167. public function set url(newValue:String):void
  168. {
  169. if (!newValue)
  170. throw new BadArgumentError("RemoteResource URL cannot be null.", this, "set url");
  171. __url=newValue;
  172. if ((__url.indexOf("http://")!=0) && (BaseURL))
  173. __requestURL=BaseURL+__url;
  174. else
  175. __requestURL=__url;
  176. //Normalize the URL (Flash Player 9 throws Security Sandbox Violation errors if the path
  177. //contains '..'
  178. __requestURL=normalizeURL(__requestURL);
  179. }
  180. public function get status():Object
  181. {
  182. return __status;
  183. }
  184. public function get file():*
  185. {
  186. return __file;
  187. }
  188. public function get sandboxed():Boolean
  189. {
  190. return __sandboxed;
  191. }
  192. public function set sandboxed(newValue:Boolean):void
  193. {
  194. //Takes care of both 'false' and 'null' values
  195. if (!newValue)
  196. __sandboxed=false;
  197. else
  198. __sandboxed=true;
  199. }
  200. /**
  201. * Resource HTTPStatus Event handler
  202. * @callback
  203. */
  204. private function __httpStatus(e:HTTPStatusEvent):void
  205. {
  206. try
  207. {
  208. this.status.httpCode=e.status;
  209. }
  210. catch (e:*)
  211. {
  212. ErrorManager.error(e,this);
  213. }
  214. }
  215. /**
  216. * Resource ProgressEvent.PROGRESS handler
  217. * @callback
  218. */
  219. private function __progress(e:ProgressEvent):void
  220. {
  221. try
  222. {
  223. if (!e.target)
  224. {
  225. Log.warning("Unable to access target of event "+e.type,this);
  226. return;
  227. }
  228. //Store these values
  229. this.status.bytesLoaded=e.bytesLoaded;
  230. this.status.bytesTotal=e.bytesTotal;
  231. }
  232. catch (e:*)
  233. {
  234. ErrorManager.fatal(e,this);
  235. }
  236. }
  237. /**
  238. * Resource IOErrorEvent.IO_ERROR handler
  239. * @callback
  240. */
  241. private function __error(e:IOErrorEvent):void
  242. {
  243. try
  244. {
  245. if (!this.status)
  246. {
  247. Log.warning("Unable to access the 'status' property of the RemoteResource target for event "+e.type+".",this);
  248. return;
  249. }
  250. this.status.downloaded=false;
  251. this.status.error=new FileNotFoundError(this,e.text,this, "__error", new Error(e.text));
  252. //Forward the error
  253. if (this.hasEventListener(RemoteResourceEvent.ERROR))
  254. dispatchEvent(new RemoteResourceEvent(this,RemoteResourceEvent.ERROR,"File not found: "+requestURL));
  255. else
  256. Log.extra("[RemoteResource::__error] Not dispatching RemoteResourceEvent.ERROR because there are no handlers attached.");
  257. }
  258. catch (e:*)
  259. {
  260. //ErrorManager.fatal(e,this);
  261. }
  262. }
  263. /**
  264. * Resource Event.COMPLETE handler
  265. * @callback
  266. */
  267. private function __complete(e:Event)
  268. {
  269. try
  270. {
  271. if (!this.status)
  272. {
  273. Log.warning("Unable to access the 'status' property for event "+e.type+".",this);
  274. return;
  275. }
  276. //Mark the resource as downloaded
  277. this.status.downloaded=true;
  278. this.status.error=null;
  279. //Dispatch resource complete event
  280. if (this.hasEventListener(RemoteResourceEvent.COMPLETE))
  281. dispatchEvent(new RemoteResourceEvent(this, RemoteResourceEvent.COMPLETE));
  282. else
  283. Log.extra("[RemoteResource::__complete] Warning: Cannot dispatch event: no event handler registered for "+RemoteResourceEvent.COMPLETE);
  284. }
  285. catch(e:*)
  286. {
  287. ErrorManager.fatal(e,this);
  288. }
  289. }
  290. public function onError(method:Function)
  291. {
  292. addEventListener(RemoteResourceEvent.ERROR, method);
  293. }
  294. public function onProgress(method:Function)
  295. {
  296. addEventListener(RemoteResourceEvent.PROGRESS, method);
  297. }
  298. public function onComplete(method:Function)
  299. {
  300. addEventListener(RemoteResourceEvent.COMPLETE,method);
  301. }
  302. //Is the file attachable to the stage?
  303. public function canAttach():Boolean
  304. {
  305. if ((this.file) && (this.file is Loader))
  306. return true;
  307. return false;
  308. }
  309. //Has the file been downloaded in binary mode?
  310. public function isBinary():Boolean
  311. {
  312. if ((__options) && (__options.binary!==null) && (__options.binary===true))
  313. return true;
  314. return false;
  315. }
  316. //Returns the width of the resource or null on Error
  317. public function get size():Size
  318. {
  319. var result:Size=null;
  320. try
  321. {
  322. if (!__file)
  323. return null;
  324. result=new Size(__file.contentLoaderInfo.width,__file.contentLoaderInfo.height);
  325. }
  326. catch(e:*)
  327. {
  328. Log.error(e);
  329. }
  330. return result;
  331. }
  332. }
  333. }