permit XML file nesting in map_features.xml
authorRichard Fairhurst <richard@systemed.net>
Sun, 9 Jan 2011 16:50:08 +0000 (16:50 +0000)
committerRichard Fairhurst <richard@systemed.net>
Sun, 9 Jan 2011 16:50:08 +0000 (16:50 +0000)
net/systemeD/halcyon/NestedXMLLoader.as [new file with mode: 0644]
net/systemeD/potlatch2/mapfeatures/MapFeatures.as

diff --git a/net/systemeD/halcyon/NestedXMLLoader.as b/net/systemeD/halcyon/NestedXMLLoader.as
new file mode 100644 (file)
index 0000000..51e9ec0
--- /dev/null
@@ -0,0 +1,81 @@
+package net.systemeD.halcyon {
+
+       /** A class permitting you to load XML files containing 'include' elements (for example,
+       *   <include file="cuisine.xml" />, which will be automatically replaced with the contents of the file.
+       *
+       *   Typical usage:
+       *
+       *               xmlLoader=new NestedXMLLoader();
+       *               xmlLoader.addEventListener(Event.COMPLETE, onFeatureLoad);
+       *               xmlLoader.load("root.xml");
+       *
+       *       onFeatureLoad can then access the XML via event.target.xml.
+       */
+
+       import flash.events.*;
+    import flash.net.URLLoader;
+    import flash.net.URLRequest;
+
+       public class NestedXMLLoader extends EventDispatcher {
+               public var xml:XML = null;
+               private var url:String;
+               private var count:int;
+
+               public function NestedXMLLoader() {
+               }
+               
+               public function load(url:String):void {
+                       this.url=url;
+                       var request:URLRequest=new URLRequest(url+"?d="+Math.random());
+                       var loader:URLLoader = new URLLoader();
+                       loader.addEventListener(Event.COMPLETE, fileLoaded);
+                       loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, fileError);
+                       loader.addEventListener(IOErrorEvent.IO_ERROR, fileError);
+                       loader.load(request);
+               }
+               
+               private function fileLoaded(event:Event):void {
+                       count=0;
+                       xml = new XML(URLLoader(event.target).data);
+                       for each (var inc:XML in xml.descendants('include')) {
+                               replaceXML(inc);
+                               count++;
+                       }
+                       if (count==0) { fireComplete(); }
+               }
+
+               private function replaceXML(inc:XML):void {
+                       var xmlLoader:NestedXMLLoader=new NestedXMLLoader();
+                       var includeElement:XML=inc;
+                       xmlLoader.addEventListener(Event.COMPLETE, function(event:Event):void {
+                               includeElement.parent().replace(findChildIndex(includeElement),event.target.xml);
+                               decreaseCount();
+                       });
+                       xmlLoader.load(inc.@file+"?d="+Math.random());
+               }
+
+               private function findChildIndex(child:XML):int {
+                       var i:uint=0;
+                       for each (var sibling:XML in child.parent().children()) {
+                               if (sibling==child) return i;
+                               i++;
+                       }
+                       return -1;
+               }
+
+               private function fileError(event:Event):void {
+                       // just fire a complete event so we don't get an error dialogue
+                       fireComplete();
+               }
+               
+               private function decreaseCount():void {
+                       count--; if (count>0) return;
+                       fireComplete();
+               }
+               
+               private function fireComplete():void {
+                       var event:Event=new Event(Event.COMPLETE);
+                       dispatchEvent(event);
+               }
+       }
+}
index 424a3733d61e45cad9d8c095fb37acea42e52f9c..14d55c112555b492acf7a904ca423ccf2330e18c 100644 (file)
@@ -11,7 +11,7 @@ package net.systemeD.potlatch2.mapfeatures {
        import mx.controls.DataGrid;
 
     import net.systemeD.halcyon.connection.*;
-       import net.systemeD.halcyon.DebugURLRequest;
+       import net.systemeD.halcyon.NestedXMLLoader;
 
     /** All the information about all available map features that can be selected by the user or matched against entities in the map.
     * The list of map features is populated from an XML file the first time the MapFeatures instance is accessed.
@@ -39,10 +39,9 @@ package net.systemeD.potlatch2.mapfeatures {
 
         /** Loads list of map features from XML file which it first retrieves. */
         protected function loadFeatures():void {
-            var request:DebugURLRequest = new DebugURLRequest("map_features.xml");
-            var loader:URLLoader = new URLLoader();
-            loader.addEventListener(Event.COMPLETE, onFeatureLoad);
-            loader.load(request.request);
+            var xmlLoader:NestedXMLLoader = new NestedXMLLoader();
+            xmlLoader.addEventListener(Event.COMPLETE, onFeatureLoad);
+            xmlLoader.load("map_features.xml");
         }
 
         /** The loaded source XML file itself. */
@@ -54,7 +53,7 @@ package net.systemeD.potlatch2.mapfeatures {
         private function onFeatureLoad(event:Event):void {
                        var f:Feature;
 
-            xml = new XML(URLLoader(event.target).data);
+            xml = NestedXMLLoader(event.target).xml;
             _features = [];
             _tags = { relation:{}, way:{}, node:{} };