ConfigLoader Class for Flex 3

Do you want to use a config.xml file for your flex applications, and be able to change the values in that file without needing to recompile your flex app? I have written a couple of utility classes to help with just that.

If you create a config.xml file and stick it in your src directory and then use mx:xml to pull it in, the xml file will be compiled into the application and will not show up in your bin-debug or bin-release directories. But using this class will allow you to load and reload the configuration file at runtime. This is particularly useful when you are deploying your application to different servers in different environments.

The first file is the main class ConfigLoader:

package com.util
{
   import flash.events.Event;
   import flash.events.EventDispatcher;
   import flash.events.IEventDispatcher;
   import flash.events.IOErrorEvent;
   import flash.events.SecurityErrorEvent;
   import flash.net.URLLoader;
   import flash.net.URLLoaderDataFormat;
   import flash.net.URLRequest;

   [Event(name="complete",type="ConfigLoaderEvent")]
   [Event(name="fault",type="ConfigLoaderEvent")]
   
   public class ConfigLoader extends EventDispatcher
   {            
      private var _configXMLPath:String;
      private var _configLoaded:Boolean = false;
      private var _configXML:XML;
      
      //our favorite constructor...       
      public function ConfigLoader(configXMLPath:String, target:IEventDispatcher=null)
      {
         super(target);
         _configXMLPath = configXMLPath;
      }
   
      //here lies the meat and potatoes of this class       
      public function load () : void
      {         
         var loader:URLLoader = new URLLoader();
         loader.dataFormat = URLLoaderDataFormat.TEXT;
         loader.addEventListener(Event.COMPLETE,loadConfigXML_complete_handler);
         loader.addEventListener(IOErrorEvent.IO_ERROR,loadConfigXML_ioError_handler);
         loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,loadConfigXML_securityError_handler);
         
         //clear the config in case it has been loaded before          
         _configXML = null;
         //set that the config hasn't been loaded          
         _configLoaded = false
         
         try
         {
            trace("loading config: " + _configXMLPath);
            loader.load( new URLRequest(_configXMLPath) );
         }
         catch ( e:Error )
         {
            //trace out the error, but it will be caught below             
            trace("an error occurred loading the config file");
         }
      }
      
      public function loadConfigXML_ioError_handler ( e:IOErrorEvent ) : void
      {
         //woops, something went wrong with the transfer, create and dispatch an event letting everyone know
               
         var cle:ConfigLoaderEvent = new ConfigLoaderEvent(ConfigLoaderEvent.FAULT);
         cle.message = "I/O Error";
         dispatchEvent(cle);
      }
      
      public function loadConfigXML_securityError_handler ( e:SecurityErrorEvent ) : void
      {
         //looks like someone is trying to access something they aren't supposed to be able to see.          
         var cle:ConfigLoaderEvent = new ConfigLoaderEvent(ConfigLoaderEvent.FAULT);
         cle.message = "Security Error";
         dispatchEvent(cle);
      }
   
      private function loadConfigXML_complete_handler ( e:Event ) : void
      {
         try
         {
            //convert the text to xml             
            _configXML = new XML( e.target.data );
            
            //set the flag that the config has been loaded.             
            _configLoaded = true;
            
            //create and dispatch the complete event for a job well done.             
            var completeEvent:ConfigLoaderEvent = new ConfigLoaderEvent(ConfigLoaderEvent.COMPLETE);
            completeEvent.data = _configXML;
            dispatchEvent(completeEvent);
            trace('configLoader complete');
         }
         catch ( e:TypeError )
         {
            var faultEvent:ConfigLoaderEvent = new ConfigLoaderEvent(ConfigLoaderEvent.FAULT);
            faultEvent.message = "Could not convert config to xml, document may be malformed.";
            dispatchEvent(faultEvent);
         }
      }
      
      
      public function get configXML () : XML
      {
         return _configXML;
      }
      
      public function set configXMLPath ( value:String ) : void
      {
         _configXMLPath = value;
      }

      public function get configXMLPath () : String
      {
         return _configXMLPath;
      }
      
      public function set configLoaded ( value:Boolean ) : void
      {
         _configLoaded = value;
      }
      
      
      public function get configLoaded () : Boolean
      {
         return _configLoaded;
      }
   }
}

and a custom event for it, ConfigLoaderEvent:

package com.util
{
   import flash.events.Event;

   public class ConfigLoaderEvent extends Event
   {
      
      public static const COMPLETE:String = 'Complete';
      public static const FAULT:String = 'Fault';
      
      private var _data:XML;
      private var _message:String;
      
      public function ConfigLoaderEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
      {
         super(type, bubbles, cancelable);
      }
      
      public function set data ( value:XML ) : void
      {
         _data = value;
      }
            
      public function get data () : XML
      {
         return _data;
      }
      
      public function set message ( value:String ) : void
      {
         _message = value;
      }
      
      
      public function get message () : String
      {
         return _message;
      }


   }
}

just stick these in a com/util/ directory under source and you should be off to the races. So here is an example of how to use these classes:

import com.util.ConfigLoader;
   import com.util.ConfigLoaderEvent;
   
   [Bindable]
   public var configXML:XML;   
   
   //a variable to keep track if we are loaded or not    
   public var configLoaded:Boolean = false;
   
   //create the configloader and tell it where the config.xml file is relative to src.    
   public var configLoader:ConfigLoader = new ConfigLoader("config.xml");
   
   
   // I use the initialize event on application to set up these event handlers    
   //and load the configuration file because it does not    
   //require any UIComponents to function.    
   public function application_initialization_handler ( e:Event ) : void
   {
      //configLoader will broadcast an event on load complete or fault...       
      configLoader.addEventListener(ConfigLoaderEvent.COMPLETE,configLoader_complete_handler);
      configLoader.addEventListener(ConfigLoaderEvent.FAULT,configLoader_fault_handler);
      
      //call load() to actually load in the file and parse it.       
      configLoader.load();
   }
   
   public function configLoader_complete_handler ( e:ConfigLoaderEvent ) : void
   {
      configXML = e.data;   
      useConfig(configXML);      
   }
   
   public function configLoader_fault_handler ( e:ConfigLoaderEvent ) : void
   {
      Alert.show(e.message);
   }
   
   public function useConfig( configXML ) : void
   {
      // so here you can now use the configXML to pull out whatever values you need.       
         
   }

Now this code is a work in progress of course so make sure you look over it and understand it before using it. Hope someone finds it useful.

Comments
Comments are not allowed for this entry.
BlogCFC was created by Raymond Camden. This blog is running version 5.1.004.