RequestManager

Package: MachII.framework
Manages request functionality for the framework.
Method Summary
public RequestManager init(AppManager appManager)

Initializes the manager.

public string buildUrl(string moduleName, string eventName, [any urlParameters=""], [string urlBase="#getDefaultUrlBase()#"])

Builds a framework specific url.

private void cleanupPersistEventStorage()

Cleanups the persist event data storage.

public void configure()

Configures nothing.

private string createPersistId()

Creates a persistId for use.

private string createTimestamp()

Creates a timestamp for use.

private AppManager getAppManager()
private string getDefaultUrlBase()
private string getEventParameter()
private numeric getMaxEvents()
private string getModuleDelimiter()
private string getPairDelimiter()
private string getParameterPrecedence()
private string getParseSes()
private struct getPersistEventStorage()

Helper function to get the event data store for persists.

private PropertyManager getPropertyManager()
private string getQueryStringDelimiter()
private string getRedirectPersistParameter()
private string getRedirectPersistScope()
public RequestHandler getRequestHandler()

Returns a new or cached instance of a RequestHandler.

private string getSeriesDelimiter()
private Utils getUtils()
private struct parseBuildUrlParameters(any urlParameters)

Parses the build url parameters into a useable form.

public struct parseSesParameters(string pathInfo)

Parse SES parameters.

public struct readPersistEventData(struct eventArgs)

Gets a persisted event by id if found in event args.

public string savePersistEventData(struct eventArgs)

Saves persisted event data and returns the persistId.

private void setAppManager(AppManager appManager)
private void setDefaultUrlBase(string defaultUrlBase)
private void setEventParameter(string eventParameter)
private void setMaxEvents(numeric maxEvents)
private void setModuleDelimiter(string moduleDelimiter)
private void setPairDelimiter(string pairDelimiter)
private void setParameterPrecedence(string parameterPrecedence)
private void setParseSes(string parseSes)
private void setQueryStringDelimiter(string queryStringDelimiter)
private void setRedirectPersistParameter(string redirectPersistParameter)
private void setRedirectPersistScope(string redirectPersistScope)
private void setSeriesDelimiter(string seriesDelimiter)
Method Detail
buildUrl

public string buildUrl( string moduleName, string eventName, [any urlParameters=""], [string urlBase="#getDefaultUrlBase()#"] )

Builds a framework specific url.

Parameters:
string moduleName
string eventName
[any urlParameters=""]
[string urlBase="#getDefaultUrlBase()#"]

Code:

	<cffunction name="buildUrl" access="public" returntype="string" output="false"
		hint="Builds a framework specific url.">
		<cfargument name="moduleName" type="string" required="true"
			hint="Name of the module to build the url with." />
		<cfargument name="eventName" type="string" required="true"
			hint="Name of the event to build the url with." />
		<cfargument name="urlParameters" type="any" required="false" default=""
			hint="Name/value pairs (urlArg1=value1|urlArg2=value2) to build the url with or a struct of data." />
		<cfargument name="urlBase" type="string" required="false" default="#getDefaultUrlBase()#"
			hint="Base of the url. Defaults to the value of the urlBase property." />
		
		<cfset var builtUrl = "" />
		<cfset var queryString = "" />
		<cfset var params = parseBuildUrlParameters(arguments.urlParameters) />
		<cfset var value = "" />
		<cfset var i = "" />

		
		<cfif Len(arguments.moduleName) AND Len(arguments.eventName)>
			<cfset queryString = queryString & getEventParameter() & getPairDelimiter() & arguments.moduleName & getModuleDelimiter() & arguments.eventName />
		<cfelseif NOT Len(arguments.moduleName) AND Len(arguments.eventName)>
			<cfset queryString = queryString & getEventParameter() & getPairDelimiter()& arguments.eventName />
		</cfif>
		
		
		<cfloop collection="#params#" item="i">
			<cfif IsSimpleValue(params[i])>
				
				<cfif getParseSes()>
					<cfset params[i] = Replace(params[i], ";", "U_03B", "all") />
				</cfif>
				<cfset queryString = queryString & getSeriesDelimiter() & i & getPairDelimiter() & URLEncodedFormat(params[i]) />
			</cfif>
		</cfloop>
		
		
		<cfif Len(queryString)>
			<cfset builtUrl = arguments.urlBase & getQueryStringDelimiter() & queryString />
			<cfif getSeriesDelimiter() NEQ "&">
				<cfset builtUrl = builtUrl & getSeriesDelimiter() />
			</cfif>
		<cfelse>
			<cfset builtUrl = arguments.urlBase />
		</cfif>
		
		<cfreturn builtUrl />
	</cffunction> 

cleanupPersistEventStorage

private void cleanupPersistEventStorage( )

Cleanups the persist event data storage.

Parameters:

Code:

	<cffunction name="cleanupPersistEventStorage" access="private" returntype="void" output="false"
		hint="Cleanups the persist event data storage.">
		
		<cfset var timestamp = createTimestamp() />
		<cfset var diffTimestamp = DateAdd("n", variables.cleanupDifference, timestamp) />
		<cfset var dataStorage = getPersistEventStorage() />
		<cfset var dataTimestampArray = "" />
		<cfset var i = "" />
		
		
		<cfif DateCompare(dataStorage.lastCleanup, diffTimestamp) EQ 1>
			<cflock name="_MachIIPersistEventStorageCleanup" type="exclusive" timeout="5" throwontimeout="false">
				<cfif DateCompare(dataStorage.lastCleanup, diffTimestamp) EQ 1>
					<cfset dataStorage.lastCleanup = timestamp />
					
					
					<cfset dataTimestampArray = StructKeyArray(dataStorage.timestamps) />
					<cfset ArraySort(dataTimestampArray, "numeric", "asc") />
					
					
					<cfloop from="1" to="#ArrayLen(dataTimestampArray)#" index="i">
						<cftry>
							<cfif DateCompare(dataTimestampArray[i], diffTimestamp) EQ 1>
								<cfset StructDelete(dataStorage.data, dataStorage.timestamps[dataTimestampArray[i]], false) />
								<cfset StructDelete(dataStorage.timestamps, dataTimestampArray[i], false) />
							<cfelse>
								<cfbreak />
							</cfif>
							<cfcatch type="any">
								
							</cfcatch>
						</cftry>
					</cfloop>
				</cfif>
			</cflock>
		</cfif>
	</cffunction> 

configure

public void configure( )

Configures nothing.

Parameters:

Code:

	<cffunction name="configure" access="public" returntype="void" output="false"
		hint="Configures nothing.">
		
	</cffunction> 

createPersistId

private string createPersistId( )

Creates a persistId for use.

Parameters:

Code:

	<cffunction name="createPersistId" access="private" returntype="string" output="false"
		hint="Creates a persistId for use.">
		<cfreturn REReplace(CreateUUID(), "[[:punct:]]", "", "ALL") />
	</cffunction> 

createTimestamp

private string createTimestamp( )

Creates a timestamp for use.

Parameters:

Code:

	<cffunction name="createTimestamp" access="private" returntype="string" output="false"
		hint="Creates a timestamp for use.">
		<cfreturn REReplace(Now(), "[ts[:punct:][:space:]]", "", "ALL") />
	</cffunction> 

getAppManager

private AppManager getAppManager( )

Parameters:

Code:

	<cffunction name="getAppManager" access="private" returntype="MachII.framework.AppManager" output="false">
		<cfreturn variables.appManager />
	</cffunction> 

getDefaultUrlBase

private string getDefaultUrlBase( )

Parameters:

Code:

	<cffunction name="getDefaultUrlBase" access="private" returntype="string" output="false">
		<cfreturn variables.defaultUrlBase />
	</cffunction> 

getEventParameter

private string getEventParameter( )

Parameters:

Code:

	<cffunction name="getEventParameter" access="private" returntype="string" output="false">
		<cfreturn variables.eventParameter />
	</cffunction> 

getMaxEvents

private numeric getMaxEvents( )

Parameters:

Code:

	<cffunction name="getMaxEvents" access="private" returntype="numeric" output="false">
		<cfreturn variables.maxEvents />
	</cffunction> 

getModuleDelimiter

private string getModuleDelimiter( )

Parameters:

Code:

	<cffunction name="getModuleDelimiter" access="private" returntype="string" output="false">
		<cfreturn variables.moduleDelimiter />
	</cffunction> 

getPairDelimiter

private string getPairDelimiter( )

Parameters:

Code:

	<cffunction name="getPairDelimiter" access="private" returntype="string" output="false">
		<cfreturn variables.pairDelimiter />
	</cffunction> 

getParameterPrecedence

private string getParameterPrecedence( )

Parameters:

Code:

	<cffunction name="getParameterPrecedence" access="private" returntype="string" output="false">
		<cfreturn variables.parameterPrecedence />
	</cffunction> 

getParseSes

private string getParseSes( )

Parameters:

Code:

	<cffunction name="getParseSes" access="private" returntype="string" output="false">
		<cfreturn variables.parseSes />
	</cffunction> 

getPersistEventStorage

private struct getPersistEventStorage( )

Helper function to get the event data store for persists.

Parameters:

Code:

	<cffunction name="getPersistEventStorage" access="private" returntype="struct" output="false"
		hint="Helper function to get the event data store for persists.">
		
		<cfset var scope = "" />
		
		
		<cfif getRedirectPersistScope() EQ "application">
			<cfset scope = StructGet("application") />
		<cfelseif  getRedirectPersistScope() EQ "session">
			<cfset scope = StructGet("session") />
		<cfelseif getRedirectPersistScope() EQ "server">
			<cfset scope = StructGet("server") />
		<cfelse>
			<cfthrow type="MachII.framework.UnsupportedRedirectPersistScope"
				message="You can only use session, application or server scopes." />
		</cfif>
		
		
		<cfif NOT StructKeyExists(scope, "_MachIIPersistEventStorage")>
			<cflock name="_MachIIPersistEventStorageCreate" type="exclusive" timeout="5" throwontimeout="false">
				<cfif NOT StructKeyExists(scope, "_MachIIPersistEventStorage")>
					<cfset scope._MachIIPersistEventStorage = StructNew() />
					<cfset scope._MachIIPersistEventStorage.data = StructNew() />
					<cfset scope._MachIIPersistEventStorage.timestamps = StructNew() />
					<cfset scope._MachIIPersistEventStorage.lastCleanup = createTimestamp() />
				</cfif>
			</cflock>
		</cfif>
		
		<cfreturn scope._MachIIPersistEventStorage />		
	</cffunction> 

getPropertyManager

private PropertyManager getPropertyManager( )

Parameters:

Code:

	<cffunction name="getPropertyManager" access="private" returntype="MachII.framework.PropertyManager" output="false">
		<cfreturn getAppManager().getPropertyManager() />
	</cffunction> 

getQueryStringDelimiter

private string getQueryStringDelimiter( )

Parameters:

Code:

	<cffunction name="getQueryStringDelimiter" access="private" returntype="string" output="false">
		<cfreturn variables.queryStringDelimiter />
	</cffunction> 

getRedirectPersistParameter

private string getRedirectPersistParameter( )

Parameters:

Code:

	<cffunction name="getRedirectPersistParameter" access="private" returntype="string" output="false">
		<cfreturn variables.redirectPersistParameter />
	</cffunction> 

getRedirectPersistScope

private string getRedirectPersistScope( )

Parameters:

Code:

	<cffunction name="getRedirectPersistScope" access="private" returntype="string" output="false">
		<cfreturn variables.redirectPersistScope />
	</cffunction> 

getRequestHandler

public RequestHandler getRequestHandler( )

Returns a new or cached instance of a RequestHandler.

Parameters:

Code:

	<cffunction name="getRequestHandler" access="public" returntype="MachII.framework.RequestHandler" output="false"
		hint="Returns a new or cached instance of a RequestHandler.">
		
		<cfset var appKey = getAppManager().getAppLoader().getAppKey() />
		
		<cfif NOT StructKeyExists(request, "_MachIIRequestHandler_" & appKey)>
			<cfset request["_MachIIRequestHandler_" & appKey] = 
					CreateObject("component", "MachII.framework.RequestHandler").init(getAppManager(), getEventParameter(), getParameterPrecedence(), getModuleDelimiter(), getMaxEvents()) />
		</cfif>
		
		<cfreturn request["_MachIIRequestHandler_" & appKey]  />
	</cffunction> 

getSeriesDelimiter

private string getSeriesDelimiter( )

Parameters:

Code:

	<cffunction name="getSeriesDelimiter" access="private" returntype="string" output="false">
		<cfreturn variables.seriesDelimiter />
	</cffunction> 

getUtils

private Utils getUtils( )

Parameters:

Code:

	<cffunction name="getUtils" access="private" returntype="MachII.util.Utils" output="false">
		<cfreturn getAppManager().getUtils() />
	</cffunction> 

init

public RequestManager init( AppManager appManager )

Initializes the manager.

Parameters:
AppManager appManager

Code:

	<cffunction name="init" access="public" returntype="RequestManager" output="false"
		hint="Initializes the manager.">
		<cfargument name="appManager" type="MachII.framework.AppManager" required="true" />

		<cfset var urlDelimiters = "" />	
		
		<cfset setAppManager(arguments.appManager) />

		
		<cfset urlDelimiters = getPropertyManager().getProperty("urlDelimiters") />	
		<cfset setRedirectPersistParameter(getPropertyManager().getProperty("redirectPersistParameter")) />
		<cfset setRedirectPersistScope(getPropertyManager().getProperty("redirectPersistScope")) />
		<cfset setDefaultUrlBase(getPropertyManager().getProperty("urlBase")) />
		<cfset setEventParameter(getPropertyManager().getProperty("eventParameter")) />
		<cfset setParameterPrecedence(getPropertyManager().getProperty("parameterPrecedence")) />
		<cfset setParseSES(getPropertyManager().getProperty("urlParseSES")) />
		<cfset setModuleDelimiter(getPropertyManager().getProperty("moduleDelimiter")) />
		<cfset setMaxEvents(getPropertyManager().getProperty("maxEvents")) />
		
		
		<cfset setQueryStringDelimiter(ListGetAt(urlDelimiters, 1, "|")) />
		<cfset setSeriesDelimiter(ListGetAt(urlDelimiters, 2, "|")) />
		<cfset setPairDelimiter(ListGetAt(urlDelimiters, 3, "|")) />

		<cfreturn this />
	</cffunction> 

parseBuildUrlParameters

private struct parseBuildUrlParameters( any urlParameters )

Parses the build url parameters into a useable form.

Parameters:
any urlParameters

Code:

	<cffunction name="parseBuildUrlParameters" access="private" returntype="struct" output="false"
		hint="Parses the build url parameters into a useable form.">
		<cfargument name="urlParameters" type="any" required="true"
			hint="Takes string of name/value pairs or a struct.">
		
		<cfset var params = StructNew() />
		<cfset var temp = "" />
		<cfset var i = "" />
		
		<cfif IsSimpleValue(arguments.urlParameters)>
			<cfloop list="#arguments.urlParameters#" index="i" delimiters="|">
				<cfif ListLen(i, "=") EQ 2>
					<cfset temp = ListLast(i, "=") />
				<cfelse>
					<cfset temp = "" />
				</cfif>
				<cfset params[ListFirst(i, "=")] = temp />
			</cfloop>
		<cfelseif IsStruct(arguments.urlParameters)>
			<cfset params = arguments.urlParameters />
		<cfelse>
			<cfthrow
				type="MachII.framework.urlParametersInvalidType"
				message="BuildUrl()'s urlParameters attribute takes a list or struct."/>
		</cfif>
		
		<cfreturn params />
	</cffunction> 

parseSesParameters

public struct parseSesParameters( string pathInfo )

Parse SES parameters.

Parameters:
string pathInfo

Code:

	<cffunction name="parseSesParameters" access="public" returntype="struct" output="false"
		hint="Parse SES parameters.">
		<cfargument name="pathInfo" type="string" required="true" />
		
		<cfset var names = "" />
		<cfset var value = "" />
		<cfset var params = StructNew() />
		<cfset var i = "" />

		
		<cfif getParseSes() AND Len(arguments.pathInfo) GT 1>
			
			
			<cfset arguments.pathInfo = Mid(arguments.pathInfo, 2, Len(arguments.pathInfo)) />
			
			<cfif Right(arguments.pathInfo, 1) IS getSeriesDelimiter()>
				<cfset arguments.pathInfo = Mid(arguments.pathInfo, 1, Len(arguments.pathInfo) - 1) />
			</cfif>
			
			
			<cfset arguments.pathInfo = Replace(arguments.pathInfo, "U_03B", ";", "all") />
			
			<cfif getSeriesDelimiter() EQ getPairDelimiter()>
			
				<cfset names = ListToArray(getUtils().listFix(arguments.pathInfo, getSeriesDelimiter(), "_-_NULL_-_"), getSeriesDelimiter()) />
				
				<cfloop from="1" to="#ArrayLen(names)#" index="i" step="2">
					<cfif i + 1 LTE ArrayLen(names) AND names[i+1] NEQ "_-_NULL_-_">
						<cfset value = names[i+1] />
					<cfelse>
						<cfset value = "" />
					</cfif>
					<cfset params[names[i]] = value />
				</cfloop>
			<cfelse>
				
				<cfset names = ListToArray(arguments.pathInfo, getSeriesDelimiter()) />
				
				<cfloop from="1" to="#ArrayLen(names)#" index="i">
					<cfif ListLen(names[i], getPairDelimiter()) EQ 2>
						<cfset value = ListGetAt(names[i], 2, getPairDelimiter()) />
					<cfelse>
						<cfset value = "" />
					</cfif>
					<cfset params[ListGetAt(names[i], 1, getPairDelimiter())] =  value />
				</cfloop>
			</cfif>
		</cfif>
		
		<cfreturn params />
	</cffunction> 

readPersistEventData

public struct readPersistEventData( struct eventArgs )

Gets a persisted event by id if found in event args.

Parameters:
struct eventArgs

Code:

	<cffunction name="readPersistEventData" access="public" returntype="struct" output="false"
		hint="Gets a persisted event by id if found in event args.">
		<cfargument name="eventArgs" type="struct" required="true" />
		
		<cfset var persistId = "" />
		<cfset var persistedData = StructNew() />
		<cfset var dataStorage = "" />
		
		
		<cfif StructKeyExists(arguments.eventArgs, getRedirectPersistParameter())>
			<cfset persistId = arguments.eventArgs[getRedirectPersistParameter()] />
			<cfset dataStorage = getPersistEventStorage() />
			
			
			<cfif StructKeyExists(dataStorage.data, persistId)>
				<cftry>
					
					<cfset persistedData = dataStorage.data[persistId]>
					<cfset StructDelete(dataStorage.data, persistId, false) />
					<cfcatch type="any">
						
					</cfcatch>
				</cftry>
			</cfif>
		</cfif>
		
		<cfreturn persistedData />
	</cffunction> 

savePersistEventData

public string savePersistEventData( struct eventArgs )

Saves persisted event data and returns the persistId.

Parameters:
struct eventArgs

Code:

	<cffunction name="savePersistEventData" access="public" returntype="string" output="false"
		hint="Saves persisted event data and returns the persistId.">
		<cfargument name="eventArgs" type="struct" required="true" />
		
		<cfset var persistId = createPersistId() />
		<cfset var timestamp = createTimestamp() />
		<cfset var dataStorage = getPersistEventStorage() />
		
		
		<cfset cleanupPersistEventStorage() />
		
		
		<cfset dataStorage.data[persistId] = arguments.eventArgs />
		<cfset dataStorage.timestamps[timestamp] = persistId />
		
		<cfreturn persistId />
	</cffunction> 

setAppManager

private void setAppManager( AppManager appManager )

Parameters:
AppManager appManager

Code:

	<cffunction name="setAppManager" access="private" returntype="void" output="false">
		<cfargument name="appManager" type="MachII.framework.AppManager" required="true" />
		<cfset variables.appManager = arguments.appManager />
	</cffunction> 

setDefaultUrlBase

private void setDefaultUrlBase( string defaultUrlBase )

Parameters:
string defaultUrlBase

Code:

	<cffunction name="setDefaultUrlBase" access="private" returntype="void" output="false">
		<cfargument name="defaultUrlBase" type="string" required="true" />
		<cfset variables.defaultUrlBase = arguments.defaultUrlBase />
	</cffunction> 

setEventParameter

private void setEventParameter( string eventParameter )

Parameters:
string eventParameter

Code:

	<cffunction name="setEventParameter" access="private" returntype="void" output="false">
		<cfargument name="eventParameter" type="string" required="true" />
		<cfset variables.eventParameter = arguments.eventParameter />
	</cffunction> 

setMaxEvents

private void setMaxEvents( numeric maxEvents )

Parameters:
numeric maxEvents

Code:

	<cffunction name="setMaxEvents" access="private" returntype="void" output="false">
		<cfargument name="maxEvents" required="true" type="numeric" />
		<cfset variables.maxEvents = arguments.maxEvents />
	</cffunction> 

setModuleDelimiter

private void setModuleDelimiter( string moduleDelimiter )

Parameters:
string moduleDelimiter

Code:

	<cffunction name="setModuleDelimiter" access="private" returntype="void" output="false">
		<cfargument name="moduleDelimiter" type="string" required="true" />
		<cfset variables.moduleDelimiter = arguments.moduleDelimiter />
	</cffunction> 

setPairDelimiter

private void setPairDelimiter( string pairDelimiter )

Parameters:
string pairDelimiter

Code:

	<cffunction name="setPairDelimiter" access="private" returntype="void" output="false">
		<cfargument name="pairDelimiter" type="string" required="true" />
		<cfset variables.pairDelimiter = arguments.pairDelimiter />
	</cffunction> 

setParameterPrecedence

private void setParameterPrecedence( string parameterPrecedence )

Parameters:
string parameterPrecedence

Code:

	<cffunction name="setParameterPrecedence" access="private" returntype="void" output="false">
		<cfargument name="parameterPrecedence" type="string" required="true" />
		<cfset variables.parameterPrecedence = arguments.parameterPrecedence />
	</cffunction> 

setParseSes

private void setParseSes( string parseSes )

Parameters:
string parseSes

Code:

	<cffunction name="setParseSes" access="private" returntype="void" output="false">
		<cfargument name="parseSes" type="string" required="true" />
		<cfset variables.parseSes = arguments.parseSes />
	</cffunction> 

setQueryStringDelimiter

private void setQueryStringDelimiter( string queryStringDelimiter )

Parameters:
string queryStringDelimiter

Code:

	<cffunction name="setQueryStringDelimiter" access="private" returntype="void" output="false">
		<cfargument name="queryStringDelimiter" type="string" required="true" />
		<cfset variables.queryStringDelimiter = arguments.queryStringDelimiter />
	</cffunction> 

setRedirectPersistParameter

private void setRedirectPersistParameter( string redirectPersistParameter )

Parameters:
string redirectPersistParameter

Code:

	<cffunction name="setRedirectPersistParameter" access="private" returntype="void" output="false">
		<cfargument name="redirectPersistParameter" type="string" required="true" />
		<cfset variables.redirectPersistParameter = arguments.redirectPersistParameter />
	</cffunction> 

setRedirectPersistScope

private void setRedirectPersistScope( string redirectPersistScope )

Parameters:
string redirectPersistScope

Code:

	<cffunction name="setRedirectPersistScope" access="private" returntype="void" output="false">
		<cfargument name="redirectPersistScope" type="string" required="true" />
		<cfset variables.redirectPersistScope = arguments.redirectPersistScope />
	</cffunction> 

setSeriesDelimiter

private void setSeriesDelimiter( string seriesDelimiter )

Parameters:
string seriesDelimiter

Code:

	<cffunction name="setSeriesDelimiter" access="private" returntype="void" output="false">
		<cfargument name="seriesDelimiter" type="string" required="true" />
		<cfset variables.seriesDelimiter = arguments.seriesDelimiter />
	</cffunction>