I wanted to be able to create a userPreference package, a product package, and order package, etc that I could then easily merge together into the main app.
so this is what I want.
package examples.cairngorm { import com.squaredi.frameworks.cairngorm.FrontControllerPlugin; public class MainFC extends FrontControllerPlugin { public function MainFC() { super("main"); addController(new PlugInFC()); } } }
package examples.cairngorm { import com.squaredi.frameworks.cairngorm.FrontControllerPlugin; public class PlugInFC extends FrontControllerPlugin { public function PlugInFC(id:String=null) { super("plugin"); addCommand(MyCoolThingEvent.EVENT, MyCoolThingCommand); } } }
So here is the class that I created to do that.
FrontControllerPlugIn.as
package com.squaredi.frameworks.cairngorm { import com.adobe.cairngorm.CairngormError; import com.adobe.cairngorm.CairngormMessageCodes; import com.adobe.cairngorm.commands.ICommand; import com.adobe.cairngorm.control.CairngormEvent; import com.adobe.cairngorm.control.CairngormEventDispatcher; import com.adobe.cairngorm.control.FrontController; import flash.events.EventDispatcher; import flash.utils.Dictionary; import mx.logging.ILogger; import mx.logging.Log; import mx.utils.ObjectUtil; /** * This file is not likely to be edited. Please extend it for the various projects * * It also has the ability to add other Controllers into itself to make a plugin type architecture via the addController method * * As a plugin type architecture, there are use cases when a developer of a subcomponent or subproject might have a default implementation for and event * (like show an alert for isolation testing), and know that the real implementation needs to be different. * * They should add the command via the addCommandToOverride method * * */ public class FrontControllerPlugin extends FrontController { protected static var logger:ILogger = Log.getLogger("com.squaredi.frameworks.cairngorm.FrontControllerPlugin") private var pluginControllers:Array /*FrontControllerPlugin*/ = new Array(); private var cmdToPluginMap:Dictionary = new Dictionary(true); protected var overrideCommands:Dictionary = new Dictionary(true); private var id:String public function FrontControllerPlugin(id:String = null) { super(); this.id = id; if (Log.isInfo()) { logger.info("FrontControllerPlugin constructor: " + this.toString()); } } /** * Adds all of the event command pairs already assocated with another frontController * This will throw an error if there are duplicated event names. * The expection to this is that if the duplicated event name is intended to be override * * @param p * */ public function addController(p:FrontControllerPlugin):void { /* 1) Recurse through all subcontrollers 2) Add only new controllers 3) Registger commands and deregister from added controllers */ //Do subcontrollers if (p.pluginControllers.length >0) { //Register sub controllers first var len:int = pluginControllers.length; for (var i:int = 0; i < len; i++) { addController(p.pluginControllers[i]); } } //Find new Controllers if (findPlugin(p) < 0) { //Have not registered the controller yet pluginControllers.push(p); //Copy Override Items for (var clz:String in p.overrideCommands) { overrideCommands[clz] = p.overrideCommands[clz]; } //Copy the commands in and remove them from the plugin var localcommands:Dictionary = p.commands; for (var cmd:String in localcommands) { //Make sure not to add commands twice either cmdToPluginMap[cmd] = p //Make sure to map the command before it gets added addCommand(cmd,localcommands[cmd],true); p.removeCommand(cmd); } } else { if (Log.isInfo()){logger.info(p.toString() + " has already been added");} } } protected function findPlugin(p:FrontControllerPlugin):int { var rtn:int = -1; var len:int = pluginControllers.length; for (var i:int = 0; i < len; i++) { if (pluginControllers[i].toString() == p.toString()) { rtn = i; break; } } return rtn; } /** * * Overrides the super class to allow for an error message that includes which plugin the conflict already exists in * * @param commandName * @param commandRef * @param useWeakReference * */ public override function addCommand(commandName:String, commandRef:Class, useWeakReference:Boolean=true):void { //Add usefull infomation for the alert var pluginRef:FrontControllerPlugin = cmdToPluginMap[commandName]; var pluginName:String = this.toString(); if (pluginRef != null) { pluginName = pluginRef.toString(); cmdToPluginMap[commandName] = this; } var commandReference:Class = commands[ commandName ] if( commandReference != null) { //Verify that the command is not in the override list var overrideCommandReference:Class = overrideCommands[ commandName ] if (overrideCommandReference == null) { throw new Error( "Command already registered for " + commandName +" in " + pluginName); } else { //We are indeed overriding a command if (Log.isInfo()) { logger.info(this.toString + " overriding a command")}; //lets remove the old reference and add the new overrideCommands[ commandName ] = null; delete overrideCommands[ commandName ]; cmdToPluginMap[commandName] = this; } } commands[ commandName ] = commandRef; CairngormEventDispatcher.getInstance().addEventListener( commandName, executeCommand, false, 0, useWeakReference ); } /** * * As a plugin type architecture, there are use cases when a developer of a subcomponent or subproject might have a default implementation for and event * (like show an alert for isolation testing), and know that the real implementation needs to be different. * * Adding command via this method will throw an error if this frontController gets added to another one AND the command is not redefined in the new one * * */ public function addCommandToOverride(commandName:String, commandRef:Class, useWeakReference:Boolean=true):void { var commandReference:Class = overrideCommands[ commandName ] if( commandReference != null) { var pluginRef:FrontControllerPlugin = cmdToPluginMap[commandName]; var pluginName:String = this.toString(); if (pluginRef != null) { pluginName = pluginRef.toString(); cmdToPluginMap[commandName] = this; } throw new Error( "Command already registered for override " + commandName +" in " + pluginName); } overrideCommands[ commandName ] = commandRef; addCommand(commandName, commandRef, useWeakReference); } protected function checkForOverrideCommands():void { //Copy Override Items var needsToBeOverridden:Array = new Array(); for (var clz:String in overrideCommands) { needsToBeOverridden.push(clz); } if (needsToBeOverridden.length >0) { throw new Error (this.toString() + " needs to override the following events: " + needsToBeOverridden.toString()); } } internal function forceCheckForOverrideCommands():void { checkForOverrideCommands(); } /** * * Creates the command and temporarily adds it to the context so that we get dependancy injection * * */ override protected function executeCommand( event : CairngormEvent ) : void { var commandToInitialise : Class = getCommand( event.type ); var commandToExecute : ICommand = new commandToInitialise(); if (Log.isInfo()) {logger.info("EVENT:" + event.type);} commandToExecute.execute( event ); } internal function getCommandForTesting(commandName:String):Class { try { var cmd:Class = getCommand(commandName) } catch (e:Error) { //Ignore Cairngorm Errors for testing } return cmd; } /** * * Returns the className for debugging purposes * * @return * */ public function toString():String { var classInfo:Object = ObjectUtil.getClassInfo(this); return classInfo.name + " (" + id + ")" } } }
No comments:
Post a Comment