Learning ColdFusion 8: OnMissingMethod() Event Handler

<cfcomponent
	output="false"
	hint="This is a crude ColdFusion-based decorator for the java.lang.String object.">
 
	<!---
		Run the pseudo constructor to set up data
		structures and default values.
	--->
 
	<!---
		Create a target object. This is the Java String
		that the outside world is going to be "aiming"
		for with their actions. I am casting to string here
		just to ensure that we definitely have a string.
	--->
	<cfset VARIABLES.Target = JavaCast( "string", "" ) />
 
 
	<cffunction
		name="Init"
		access="public"
		returntype="any"
		output="false"
		hint="Initializes the string wrapper.">
 
		<!--- Define arguments. --->
		<cfargument
			name="Value"
			type="string"
			required="false"
			default=""
			/>
 
		<!--- Set the default value. --->
		<cfset VARIABLES.Target = ARGUMENTS.Value />
 
		<!--- Return This scope. --->
		<cfreturn THIS />
	</cffunction>
 
 
	<cffunction
		name="Contains"
		access="public"
		returntype="numeric"
		output="false"
		hint="Tests to see if the given regular experssion exists somewhere in the target string.">
 
		<!--- Define arguments. --->
		<cfargument
			name="RegEx"
			type="string"
			required="true"
			/>
 
		<!--- Return the REFind() on the string. --->
		<cfreturn REFind( ARGUMENTS.RegEx, VARIABLES.Target ) />
	</cffunction>
 
 
	<cffunction
		name="Get"
		access="public"
		returntype="string"
		output="false"
		hint="Gets the internal string value.">
 
		<!--- Return the string value. --->
		<cfreturn VARIABLES.Target />
	</cffunction>
 
 
	<cffunction
		name="OnMissingMethod"
		access="public"
		returntype="any"
		output="false"
		hint="Handles missing method exceptions.">
 
		<!--- Define arguments. --->
		<cfargument
			name="MissingMethodName"
			type="string"
			required="true"
			hint="The name of the missing method."
			/>
 
		<cfargument
			name="MissingMethodArguments"
			type="struct"
			required="true"
			hint="The arguments that were passed to the missing method. This might be a named argument set or a numerically indexed set."
			/>
 
		<!--- Define the local scope. --->
		<cfset var LOCAL = {} />
 
		<!--- Get the array of argument keys. --->
		<cfset LOCAL.Keys = StructKeyArray(
			ARGUMENTS.MissingMethodArguments
			) />
 
 
		<!--- Check to see if there are any arguments. --->
		<cfif NOT ArrayLen( LOCAL.Keys )>
 
			<!--- Just return the method invocation. --->
			<cfreturn Evaluate(
				"VARIABLES.Target.#ARGUMENTS.MissingMethodName#()"
				) />
 
		<!---
			If we have arguments, we might have indexed
			or numeric. Since this CFC wraps around a Java
			object, they should all be numbered, but I will
			check anyway.
		--->
		<cfelseif IsNumeric( LOCAL.Keys[ 1 ] )>
 
			<!---
				We are going to have to build up the arguments
				string used in the evaluation.
			--->
			<cfset LOCAL.Args = "" />
 
			<!--- Loop over the keys. --->
			<cfloop
				index="LOCAL.KeyIndex"
				from="1"
				to="#ArrayLen( LOCAL.Keys )#"
				step="1">
 
				<!--- Build up the ORDERED parameter. --->
				<cfset LOCAL.Args &= (
					IIF(
						(LOCAL.KeyIndex GT 1),
						DE( "," ),
						DE( "" )
						) &
					"ARGUMENTS.MissingMethodArguments[ #LOCAL.KeyIndex# ]"
					) />
 
			</cfloop>
 
			<!---
				Return the evaluated method with the passed
				in, ordered arguments.
			--->
			<cfreturn Evaluate(
				"VARIABLES.Target.#ARGUMENTS.MissingMethodName#(" &
				LOCAL.Args &
				")"
				) />
 
		<!--- We have arguments, but they are named. --->
		<cfelse>
 
			<!---
				We are going to have to build up the arguments
				string used in the evaluation.
			--->
			<cfset LOCAL.Args = "" />
 
			<!--- Loop over the keys. --->
			<cfloop
				index="LOCAL.KeyIndex"
				from="1"
				to="#ArrayLen( LOCAL.Keys )#"
				step="1">
 
				<!--- Build up the NAMED parameter. --->
				<cfset LOCAL.Args &= (
					IIF(
						(LOCAL.KeyIndex GT 1),
						DE( "," ),
						DE( "" )
						) &
					"#LOCAL.Keys[ LOCAL.KeyIndex ]#=" &
					"ARGUMENTS.MissingMethodArguments[ #LOCAL.KeyIndex# ]"
					) />
 
			</cfloop>
 
 
			<!---
				Return the evaluated method with the passed
				in, ordered arguments.
			--->
			<cfreturn Evaluate(
				"VARIABLES.Target.#ARGUMENTS.MissingMethodName#(" &
				LOCAL.Args &
				")"
				) />
 
		</cfif>
 
		<!--- Return out. --->
		<cfreturn ARGUMENTS.MissingMethodName />
	</cffunction>
 
 
	<cffunction
		name="Set"
		access="public"
		returntype="any"
		output="false"
		hint="Sets the internal string value and return a pointer to the wrapper.">
 
		<!--- Define arguments. --->
		<cfargument
			name="Value"
			type="string"
			required="false"
			default=""
			/>
 
		<!--- Set the target value. --->
		<cfset VARIABLES.Target = ARGUMENTS.Value />
 
		<!--- Return This scope. --->
		<cfreturn THIS />
	</cffunction>
 
</cfcomponent>

For Cut-and-Paste