<cfcomponent
output="false"
hint="Creates a more thread-safe version of any CFC.">
<cfset VARIABLES.Instance = {} />
<cfset VARIABLES.Instance.Target = "" />
<cfset VARIABLES.Instance.ID = CreateUUID() />
<cffunction
name="Init"
access="public"
returntype="any"
output="false"
hint="Returns an intialized thread-safe component.">
<cfargument
name="Target"
type="any"
required="true"
hint="The CFC intance that we want to make thread safe"
/>
<cfset VARIABLES.Instance.Target = ARGUMENTS.Target />
<cfreturn THIS />
</cffunction>
<cffunction
name="OnMissingMethod"
access="public"
returntype="any"
output="false"
hint="Wraps around the target object to make the methods thread-safe.">
<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."
/>
<cfset var LOCAL = {} />
<cflock
name="#VARIABLES.Instance.ID#-#ARGUMENTS.MissingMethodName#"
type="exclusive"
timeout="5">
<cfset LOCAL.Keys = StructKeyArray(
ARGUMENTS.MissingMethodArguments
) />
<cfif (
ArrayLen( LOCAL.Keys ) AND
IsNumeric( LOCAL.Keys[ 1 ] )
)>
<cfset LOCAL.Args = "" />
<cfloop
index="LOCAL.Index"
array="#LOCAL.Keys#">
<cfset LOCAL.Value = ARGUMENTS.MissingMethodArguments[ LOCAL.Index ] />
<cfif IsSimpleValue( LOCAL.Value )>
<cfset LOCAL.Args &= (
",""" &
LOCAL.Value &
""""
) />
<cfelse>
<cfset LOCAL.Args &= (
"," &
LOCAL.Value
) />
</cfif>
</cfloop>
<cfset LOCAL.Args = REReplace(
LOCAL.Args,
"^,",
"",
"one"
) />
<cfset LOCAL.Return = Evaluate(
"VARIABLES.Instance.Target." &
ARGUMENTS.MissingMethodName & "(" &
LOCAL.Args &
")"
) />
<cfelse>
<cfinvoke
component="#VARIABLES.Instance.Target#"
method="#ARGUMENTS.MissingMethodName#"
argumentcollection="#ARGUMENTS.MissingMethodArguments#"
returnvariable="LOCAL.Return"
/>
</cfif>
<cfreturn LOCAL.Return />
</cflock>
</cffunction>
</cfcomponent>