Merge pull request #7 from jetthe/3791
[potlatch2.git] / net / systemeD / halcyon / NestedXMLLoader.as
1 package net.systemeD.halcyon {
2
3         /** A class permitting you to load XML files containing 'include' elements (for example,
4         *   <include file="cuisine.xml" />, which will be automatically replaced with the contents of the file.
5         *
6         *   Typical usage:
7         *
8         *               xmlLoader=new NestedXMLLoader();
9         *               xmlLoader.addEventListener(Event.COMPLETE, onFeatureLoad);
10         *               xmlLoader.load("root.xml");
11         *
12         *       onFeatureLoad can then access the XML via event.target.xml.
13         */
14
15         import flash.events.*;
16     import flash.net.URLLoader;
17     import flash.net.URLRequest;
18
19         public class NestedXMLLoader extends EventDispatcher {
20                 public var xml:XML = null;
21                 private var url:String;
22                 private var count:int;
23
24                 public function NestedXMLLoader() {
25                 }
26                 
27                 public function load(url:String):void {
28                         this.url=url;
29                         var request:URLRequest=new URLRequest(url+"?d="+Math.random());
30                         var loader:URLLoader = new URLLoader();
31                         loader.addEventListener(Event.COMPLETE, fileLoaded);
32                         loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, fileError);
33                         loader.addEventListener(IOErrorEvent.IO_ERROR, fileError);
34                         loader.load(request);
35                 }
36                 
37                 private function fileLoaded(event:Event):void {
38                         count=0;
39                         xml = new XML(URLLoader(event.target).data);
40                         for each (var inc:XML in xml.descendants('include')) {
41                                 replaceXML(inc);
42                                 count++;
43                         }
44                         if (count==0) { fireComplete(); }
45                 }
46
47                 private function replaceXML(inc:XML):void {
48                         var xmlLoader:NestedXMLLoader=new NestedXMLLoader();
49                         var includeElement:XML=inc;
50                         xmlLoader.addEventListener(Event.COMPLETE, function(event:Event):void {
51                                 includeElement.parent().replace(findChildIndex(includeElement),event.target.xml);
52                                 decreaseCount();
53                         });
54                         xmlLoader.load(inc.@file+"?d="+Math.random());
55                 }
56
57                 private function findChildIndex(child:XML):int {
58                         var i:uint=0;
59                         for each (var sibling:XML in child.parent().children()) {
60                                 if (sibling==child) return i;
61                                 i++;
62                         }
63                         return -1;
64                 }
65
66                 private function fileError(event:Event):void {
67                         // just fire a complete event so we don't get an error dialogue
68                         fireComplete();
69                 }
70                 
71                 private function decreaseCount():void {
72                         count--; if (count>0) return;
73                         fireComplete();
74                 }
75                 
76                 private function fireComplete():void {
77                         var event:Event=new Event(Event.COMPLETE);
78                         dispatchEvent(event);
79                 }
80         }
81 }