PluginManager

Package: MachII.framework
Manages registered Plugins for the framework instance.
Method Summary
public PluginManager init(AppManager appManager, [any parentPluginManager=""])

Initialization function called by the framework.

public void addPlugin(string pluginName, Plugin plugin, [boolean override="false"])

Registers a plugin with the specified name.

public void configure()

Configures each of the registered Plugins.

private array findPluginPoints(Plugin plugin)

Finds the registered plugin points in a plugin.

private void gatherPluginMetaData(struct metadata, struct points)

Gathers meta data about a plugin.

public AppManager getAppManager()

Returns the AppManager instance this PluginManager belongs to.

public any getParent()

Sets the parent PluginManager instance this PluginManager belongs to. It will return empty string if no parent is defined.

public Plugin getPlugin(string pluginName)

Gets a plugin with the specified name.

public array getPluginNames()

Returns an array of plugin names.

public string getRunParent()
public void handleException(EventContext eventContext, Exception exception)

handleException() is called for each exception caught by the framework.

public boolean isPluginDefined(string pluginName)

Returns true if a Plugin is registered with the specified name. Does NOT check parent.

public void loadXml(string configXML, [boolean override="false"])

Loads xml into the manager.

public void postEvent(EventContext eventContext)

postEvent() is called for each announced Event after it has been handled.

public void postProcess(EventContext eventContext)

postProcess() is called for each new EventContext once after event processing completes.

public void postView(EventContext eventContext)

postView() is called for each announced Event after it has been handled.

public void preEvent(EventContext eventContext)

preEvent() is called for each announced Event before it is handled.

public void preProcess(EventContext eventContext)

preProcess() is called for each new EventContext once before event processing begins.

public void preView(EventContext eventContext)

preView() is called for each announced Event after it has been handled.

public void setAppManager(AppManager appManager)

Sets the AppManager instance this PluginManager belongs to.

public void setParent(PluginManager parentPluginManager)

Returns the parent PluginManager instance this PluginManager belongs to.

public void setRunParent(string runParent)
Method Detail
addPlugin

public void addPlugin( string pluginName, Plugin plugin, [boolean override="false"] )

Registers a plugin with the specified name.

Parameters:
string pluginName
Plugin plugin
[boolean override="false"]

Code:

	<cffunction name="addPlugin" access="public" returntype="void" output="false"
		hint="Registers a plugin with the specified name.">
		<cfargument name="pluginName" type="string" required="true" />
		<cfargument name="plugin" type="MachII.framework.Plugin" required="true" />
		<cfargument name="override" type="boolean" required="false" default="false" />

		<cfset var i = 0 />
		<cfset var pointName = 0 />
		<cfset var temp = "" />
		<cfset var pluginRegisteredPoints = findPluginPoints(arguments.plugin) />

		<cfif NOT arguments.override AND isPluginDefined(arguments.pluginName)>
			<cfthrow type="MachII.framework.PluginAlreadyDefined"
				message="A Plugin with name '#arguments.pluginName#' is already registered." />
		<cfelseif arguments.override AND isPluginDefined(arguments.pluginName)>
			<cfset variables.plugins[arguments.pluginName] = arguments.plugin />
			<cfset variables.pluginArray[variables.pluginArrayPosition[arguments.pluginName]] = arguments.plugin />

			
			<cfloop from="1" to="#ArrayLen(pluginRegisteredPoints)#" index="i">
				<cfset pointName = pluginRegisteredPoints[i] />
				<cfif StructKeyExists(variables, pointName & "Plugins")>
					<cfif ListFindNoCase(variables[pointName & "PluginsPosition"], arguments.pluginName)>
						<cfset variables[pointName & "Plugins"][ListFindNoCase(variables[pointName & "PluginsPosition"], arguments.pluginName)] = arguments.plugin />
					<cfelse>
						<cfset ArrayInsertAt(variables[pointName & "Plugins"], variables.pluginArrayPosition[arguments.pluginName], arguments.plugin) />
						<cfif ListLen(variables[pointName & "PluginsPosition"]) GT 1>
							<cfset variables[pointName & "PluginsPosition"] = ListInsertAt(variables[pointName & "PluginsPosition"], variables.pluginArrayPosition[arguments.pluginName], arguments.pluginName) />
						<cfelse>
							<cfset variables[pointName & "PluginsPosition"] = ListAppend(variables[pointName & "PluginsPosition"], variables.pluginArrayPosition[arguments.pluginName]) />
						</cfif>
					</cfif>
					<cfset temp = ListAppend(temp, pointName) />
				</cfif>
			</cfloop>

			
			<cfloop from="1" to="#ArrayLen(variables.pluginPointArray)#" index="i">
				<cfset pointName = variables.pluginPointArray[i] />
				<cfif ListFindNoCase(variables[pointName & "PluginsPosition"], arguments.pluginName) AND NOT ListFindNoCase(temp, pointName)>
					<cfset ArrayDeleteAt(variables[pointName & "Plugins"], ListFindNoCase(variables[pointName & "PluginsPosition"], arguments.pluginName)) />
					<cfset ListDeleteAt(variables[pointName & "PluginsPosition"], ListFindNoCase(variables[pointName & "PluginsPosition"], arguments.pluginName)) />
				</cfif>
			</cfloop>
		<cfelse>
			<cfset variables.plugins[arguments.pluginName] = arguments.plugin />

			<cfset variables.nPlugins = variables.nPlugins + 1 />
			<cfset variables.pluginArray[variables.nPlugins] = arguments.plugin />
			<cfset variables.pluginArrayPosition[arguments.pluginName] = variables.nPlugins />

			
			<cfloop from="1" to="#ArrayLen(pluginRegisteredPoints)#" index="i">
				<cfset pointName = pluginRegisteredPoints[i] />
				<cfif StructKeyExists(variables, pointName & "Plugins")>
					<cfset ArrayAppend(variables[pointName & "Plugins"], arguments.plugin) />
					<cfset variables[pointName & "PluginsPosition"] = ListAppend(variables[pointName & "PluginsPosition"], arguments.pluginName) />
				</cfif>
			</cfloop>
		</cfif>
	</cffunction> 

configure

public void configure( )

Configures each of the registered Plugins.

Parameters:

Code:

	<cffunction name="configure" access="public" returntype="void"
		hint="Configures each of the registered Plugins.">
		<cfset var aPlugin = 0 />
		<cfset var i = 0 />

		<cfloop from="1" to="#variables.nPlugins#" index="i">
			<cfset aPlugin = variables.pluginArray[i] />
			<cfset aPlugin.configure() />
		</cfloop>
	</cffunction> 

findPluginPoints

private array findPluginPoints( Plugin plugin )

Finds the registered plugin points in a plugin.

Parameters:
Plugin plugin

Code:

	<cffunction name="findPluginPoints" access="private" returntype="array" output="false"
		hint="Finds the registered plugin points in a plugin.">
		<cfargument name="plugin" type="MachII.framework.Plugin" required="true" />

		<cfset var md = GetMetaData(arguments.plugin) />
		<cfset var points = StructNew() />

		
		<cfset gatherPluginMetaData(md, points) />

		<cfreturn StructKeyArray(points) />
	</cffunction> 

gatherPluginMetaData

private void gatherPluginMetaData( struct metadata, struct points )

Gathers meta data about a plugin.

Parameters:
struct metadata
struct points

Code:

	<cffunction name="gatherPluginMetaData" access="private" returntype="void" output="false"
		hint="Gathers meta data about a plugin.">
		<cfargument name="metadata" type="struct" required="true" />
		<cfargument name="points" type="struct" required="true" />

		<cfset var i = 0 />

		<cfif StructKeyExists(arguments.metadata, "functions")>
			<cfloop from="1" to="#ArrayLen(arguments.metadata.functions)#" index="i">
				<cfset StructInsert(arguments.points, arguments.metadata.functions[i].name, 1, true) />
			</cfloop>
		</cfif>

		<cfif StructKeyExists(arguments.metadata, "extends") and arguments.metadata.extends.name neq "MachII.framework.Plugin">
			<cfset gatherPluginMetaData(arguments.metadata.extends, arguments.points) />
		</cfif>
	</cffunction> 

getAppManager

public AppManager getAppManager( )

Returns the AppManager instance this PluginManager belongs to.

Parameters:

Code:

	<cffunction name="getAppManager" access="public" returntype="MachII.framework.AppManager" output="false"
		hint="Returns the AppManager instance this PluginManager belongs to.">
		<cfreturn variables.appManager />
	</cffunction> 

getParent

public any getParent( )

Sets the parent PluginManager instance this PluginManager belongs to. It will return empty string if no parent is defined.

Parameters:

Code:

	<cffunction name="getParent" access="public" returntype="any" output="false"
		hint="Sets the parent PluginManager instance this PluginManager belongs to. It will return empty string if no parent is defined.">
		<cfreturn variables.parentPluginManager />
	</cffunction> 

getPlugin

public Plugin getPlugin( string pluginName )

Gets a plugin with the specified name.

Parameters:
string pluginName

Code:

	<cffunction name="getPlugin" access="public" returntype="MachII.framework.Plugin" output="false"
		hint="Gets a plugin with the specified name.">
		<cfargument name="pluginName" type="string" required="true" />

		<cfif isPluginDefined(arguments.pluginName)>
			<cfreturn variables.plugins[arguments.pluginName] />
		<cfelseif isObject(getParent()) AND getParent().isPluginDefined(arguments.pluginName)>
			<cfreturn getParent().getPlugin(arguments.pluginName) />
		<cfelse>
			<cfthrow type="MachII.framework.PluginNotDefined"
				message="Plugin with name '#arguments.pluginName#' is not defined." />
		</cfif>
	</cffunction> 

getPluginNames

public array getPluginNames( )

Returns an array of plugin names.

Parameters:

Code:

	<cffunction name="getPluginNames" access="public" returntype="array" output="false"
		hint="Returns an array of plugin names.">
		<cfreturn StructKeyArray(variables.plugins) />
	</cffunction> 

getRunParent

public string getRunParent( )

Parameters:

Code:

	<cffunction name="getRunParent" access="public" returntype="string" output="false">
		<cfreturn variables.runParent />
	</cffunction> 

handleException

public void handleException( EventContext eventContext, Exception exception )

handleException() is called for each exception caught by the framework.

Parameters:
EventContext eventContext
Exception exception

Code:

	<cffunction name="handleException" access="public" returntype="void" output="true"
		hint="handleException() is called for each exception caught by the framework.">
		<cfargument name="eventContext" type="MachII.framework.EventContext" required="true"
			hint="The EventContext under which the exception was thrown/caught." />
		<cfargument name="exception" type="MachII.util.Exception" required="true"
			hint="The Exception object." />

		<cfset var i = 0 />

		<cfif getRunParent() eq "before">
			<cfif isObject(getParent())>
				<cfset getParent().handleException(arguments.eventContext, arguments.exception) />
			</cfif>
		</cfif>

		<cfloop from="1" to="#ArrayLen(variables.handleExceptionPlugins)#" index="i">
			<cfset variables.handleExceptionPlugins[i].handleException(arguments.eventContext, arguments.exception) />
		</cfloop>

		<cfif getRunParent() eq "after" OR getRunParent() eq "">
			<cfif isObject(getParent())>
				<cfset getParent().handleException(arguments.eventContext, arguments.exception) />
			</cfif>
		</cfif>
	</cffunction> 

init

public PluginManager init( AppManager appManager, [any parentPluginManager=""] )

Initialization function called by the framework.

Parameters:
AppManager appManager
[any parentPluginManager=""]

Code:

	<cffunction name="init" access="public" returntype="PluginManager" output="false"
		hint="Initialization function called by the framework.">
		<cfargument name="appManager" type="MachII.framework.AppManager" required="true" />
		<cfargument name="parentPluginManager" type="any" required="false" default=""
			hint="Optional argument for a parent plugin manager. If there isn't one default to empty string." />

		<cfset setAppManager(arguments.appManager) />
		<cfset variables.utils = getAppManager().getUtils() />

		<cfif isObject(arguments.parentPluginManager)>
			<cfset setParent(arguments.parentPluginManager) />
		</cfif>

		<cfreturn this />
	</cffunction> 

isPluginDefined

public boolean isPluginDefined( string pluginName )

Returns true if a Plugin is registered with the specified name. Does NOT check parent.

Parameters:
string pluginName

Code:

	<cffunction name="isPluginDefined" access="public" returntype="boolean" output="false"
		hint="Returns true if a Plugin is registered with the specified name. Does NOT check parent.">
		<cfargument name="pluginName" type="string" required="true" />
		<cfreturn StructKeyExists(variables.plugins, arguments.pluginName) />
	</cffunction> 

loadXml

public void loadXml( string configXML, [boolean override="false"] )

Loads xml into the manager.

Parameters:
string configXML
[boolean override="false"]

Code:

	<cffunction name="loadXml" access="public" returntype="void" output="false"
		hint="Loads xml into the manager.">
		<cfargument name="configXML" type="string" required="true" />
		<cfargument name="override" type="boolean" required="false" default="false" />

		<cfset var pluginNodes = 0 />
		<cfset var paramNodes = 0 />
		<cfset var paramName = 0 />
		<cfset var paramValue = 0 />
		<cfset var plugin = 0 />
		<cfset var pluginName = 0 />
		<cfset var pluginType = 0 />
		<cfset var pluginParams = 0 />
		<cfset var i = 0 />
		<cfset var j = 0 />

		
		<cfif NOT arguments.override>
			<cfset pluginNodes = XMLSearch(arguments.configXML, "mach-ii/plugins/plugin") />
		<cfelse>
			<cfset pluginNodes = XMLSearch(arguments.configXML, ".//plugins") />
			<cfif arrayLen(pluginNodes) gt 0 AND structKeyExists(pluginNodes[1].xmlAttributes, "runParent")>
				<cfset setRunParent(pluginNodes[1].xmlAttributes["runParent"]) />
			</cfif>
			<cfset pluginNodes = XMLSearch(arguments.configXML, ".//plugins/plugin") />
		</cfif>
		<cfloop index="i" from="1" to="#ArrayLen(pluginNodes)#">
			<cfset pluginName = pluginNodes[i].XmlAttributes["name"] />
			<cfset pluginType = pluginNodes[i].XmlAttributes["type"] />

			
			<cfset pluginParams = StructNew() />

			
			<cfif StructKeyExists(pluginNodes[i], "parameters")>
				<cfset paramNodes = pluginNodes[i].parameters.xmlChildren />
				<cfloop from="1" to="#ArrayLen(paramNodes)#" index="j">
					<cfset paramName = paramNodes[j].XmlAttributes["name"] />
					<cftry>
						<cfset paramValue = variables.utils.recurseComplexValues(paramNodes[j]) />
						<cfcatch type="any">
							<cfthrow type="MachII.framework.InvalidParameterXml"
								message="Xml parsing error for the parameter named '#paramName#' for plugin '#pluginName#' in module '#getAppManager().getModuleName()#'." />
						</cfcatch>
					</cftry>
					<cfset pluginParams[paramName] = paramValue />
				</cfloop>
			</cfif>

			<cfset plugin = CreateObject("component", pluginType).init(getAppManager(), pluginParams) />
			<cfset addPlugin(pluginName, plugin, arguments.override) />
		</cfloop>
	</cffunction> 

postEvent

public void postEvent( EventContext eventContext )

postEvent() is called for each announced Event after it has been handled.

Parameters:
EventContext eventContext

Code:

	<cffunction name="postEvent" access="public" returntype="void" output="true"
		hint="postEvent() is called for each announced Event after it has been handled.">
		<cfargument name="eventContext" type="MachII.framework.EventContext" required="true"
			hint="The EventContext the Event occurred in. Call arguments.eventContext.getCurrentEvent() to access the Event." />

		<cfset var i = 0 />

		<cfif getRunParent() eq "before">
			<cfif isObject(getParent())>
				<cfset getParent().postEvent(arguments.eventContext) />
			</cfif>
		</cfif>

		<cfloop from="1" to="#ArrayLen(variables.postEventPlugins)#" index="i">
			<cfset variables.postEventPlugins[i].postEvent(arguments.eventContext) />
		</cfloop>

		<cfif getRunParent() eq "after" OR getRunParent() eq "">
			<cfif isObject(getParent())>
				<cfset getParent().postEvent(arguments.eventContext) />
			</cfif>
		</cfif>
	</cffunction> 

postProcess

public void postProcess( EventContext eventContext )

postProcess() is called for each new EventContext once after event processing completes.

Parameters:
EventContext eventContext

Code:

	<cffunction name="postProcess" access="public" returntype="void" output="true"
		hint="postProcess() is called for each new EventContext once after event processing completes.">
		<cfargument name="eventContext" type="MachII.framework.EventContext" required="true"
			hint="The EventContext of the processing." />

		<cfset var i = 0 />

		<cfif getRunParent() eq "before">
			<cfif isObject(getParent())>
				<cfset getParent().postProcess(arguments.eventContext) />
			</cfif>
		</cfif>

		<cfloop from="1" to="#ArrayLen(variables.postProcessPlugins)#" index="i">
			<cfset variables.postProcessPlugins[i].postProcess(arguments.eventContext) />
		</cfloop>

		<cfif getRunParent() eq "after" OR getRunParent() eq "">
			<cfif isObject(getParent())>
				<cfset getParent().postProcess(arguments.eventContext) />
			</cfif>
		</cfif>
	</cffunction> 

postView

public void postView( EventContext eventContext )

postView() is called for each announced Event after it has been handled.

Parameters:
EventContext eventContext

Code:

	<cffunction name="postView" access="public" returntype="void" output="true"
		hint="postView() is called for each announced Event after it has been handled.">
		<cfargument name="eventContext" type="MachII.framework.EventContext" required="true"
			hint="The EventContext of the processing." />

		<cfset var i = 0 />

		<cfif getRunParent() eq "before">
			<cfif isObject(getParent())>
				<cfset getParent().postView(arguments.eventContext) />
			</cfif>
		</cfif>

		<cfloop from="1" to="#ArrayLen(variables.postViewPlugins)#" index="i">
			<cfset variables.postViewPlugins[i].postView(arguments.eventContext) />
		</cfloop>

		<cfif getRunParent() eq "after" OR getRunParent() eq "">
			<cfif isObject(getParent())>
				<cfset getParent().postView(arguments.eventContext) />
			</cfif>
		</cfif>
	</cffunction> 

preEvent

public void preEvent( EventContext eventContext )

preEvent() is called for each announced Event before it is handled.

Parameters:
EventContext eventContext

Code:

	<cffunction name="preEvent" access="public" returntype="void" output="true"
		hint="preEvent() is called for each announced Event before it is handled.">
		<cfargument name="eventContext" type="MachII.framework.EventContext" required="true"
			hint="The EventContext the Event occurred in. Call arguments.eventContext.getCurrentEvent() to access the Event." />

		<cfset var i = 0 />

		<cfif getRunParent() eq "before">
			<cfif isObject(getParent())>
				<cfset getParent().preEvent(arguments.eventContext) />
			</cfif>
		</cfif>

		<cfloop from="1" to="#ArrayLen(variables.preEventPlugins)#" index="i">
			<cfset variables.preEventPlugins[i].preEvent(arguments.eventContext) />
		</cfloop>

		<cfif getRunParent() eq "after" OR getRunParent() eq "">
			<cfif isObject(getParent())>
				<cfset getParent().preEvent(arguments.eventContext) />
			</cfif>
		</cfif>
	</cffunction> 

preProcess

public void preProcess( EventContext eventContext )

preProcess() is called for each new EventContext once before event processing begins.

Parameters:
EventContext eventContext

Code:

	<cffunction name="preProcess" access="public" returntype="void" output="true"
		hint="preProcess() is called for each new EventContext once before event processing begins.">
		<cfargument name="eventContext" type="MachII.framework.EventContext" required="true"
			hint="The EventContext of the processing." />

		<cfset var i = 0 />

		<cfif getRunParent() eq "before">
			<cfif isObject(getParent())>
				<cfset getParent().preProcess(arguments.eventContext) />
			</cfif>
		</cfif>

		<cfloop from="1" to="#ArrayLen(variables.preProcessPlugins)#" index="i">
			<cfset variables.preProcessPlugins[i].preProcess(arguments.eventContext) />
		</cfloop>

		<cfif getRunParent() eq "after" OR getRunParent() eq "">
			<cfif isObject(getParent())>
				<cfset getParent().preProcess(arguments.eventContext) />
			</cfif>
		</cfif>
	</cffunction> 

preView

public void preView( EventContext eventContext )

preView() is called for each announced Event after it has been handled.

Parameters:
EventContext eventContext

Code:

	<cffunction name="preView" access="public" returntype="void" output="true"
		hint="preView() is called for each announced Event after it has been handled.">
		<cfargument name="eventContext" type="MachII.framework.EventContext" required="true"
			hint="The EventContext of the processing." />

		<cfset var i = 0 />

		<cfif getRunParent() eq "before">
			<cfif isObject(getParent())>
				<cfset getParent().preView(arguments.eventContext) />
			</cfif>
		</cfif>

		<cfloop from="1" to="#ArrayLen(variables.preViewPlugins)#" index="i">
			<cfset variables.preViewPlugins[i].preView(arguments.eventContext) />
		</cfloop>

		<cfif getRunParent() eq "after" OR getRunParent() eq "">
			<cfif isObject(getParent())>
				<cfset getParent().preView(arguments.eventContext) />
			</cfif>
		</cfif>
	</cffunction> 

setAppManager

public void setAppManager( AppManager appManager )

Sets the AppManager instance this PluginManager belongs to.

Parameters:
AppManager appManager

Code:

	<cffunction name="setAppManager" access="public" returntype="void" output="false"
		hint="Sets the AppManager instance this PluginManager belongs to.">
		<cfargument name="appManager" type="MachII.framework.AppManager" required="true" />
		<cfset variables.appManager = arguments.appManager />
	</cffunction> 

setParent

public void setParent( PluginManager parentPluginManager )

Returns the parent PluginManager instance this PluginManager belongs to.

Parameters:
PluginManager parentPluginManager

Code:

	<cffunction name="setParent" access="public" returntype="void" output="false"
		hint="Returns the parent PluginManager instance this PluginManager belongs to.">
		<cfargument name="parentPluginManager" type="MachII.framework.PluginManager" required="true" />
		<cfset variables.parentPluginManager = arguments.parentPluginManager />
	</cffunction> 

setRunParent

public void setRunParent( string runParent )

Parameters:
string runParent

Code:

	<cffunction name="setRunParent" access="public" returntype="void" output="false">
		<cfargument name="runParent" type="string" required="true" />
		<cfset variables.runParent = arguments.runParent />
	</cffunction>