Created
November 5, 2009 21:16
-
-
Save ruckus/227407 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfcomponent output="yes"> | |
<!--- Take an object and a struct as input. Traverse through the object's meta-data and | |
find all methods and if the datastruct contains a key which matches that method name (with "set" prepended) | |
then call that method using the struct key value. | |
This is a convenient way to quickly populate an object/bean by calling all of its | |
setters. | |
---> | |
<cffunction name="populateBean" returntype="any" output="yes"> | |
<cfargument name="object" type="any"> | |
<cfargument name="datastruct" type="any"> | |
<cfset var md = StructNew()> | |
<cfset var functionSeen = structNew()> | |
<cfset var functionIx = 0> | |
<cfset var functionName = ''> | |
<cfset var setterName = 0> | |
<cfset var function = ""> | |
<cfset var value = ""> | |
<cfif NOT IsObject(object)> | |
<cfthrow message="BeanUtil.populateBean()::NOT AN OBJECT!" /> | |
</cfif> | |
<cfset md = getMetaData(object)> | |
<!--- This nested looping is necessary because we need to examine all methods that this object | |
has, including methods it has inherited. Inherited methods exist in sub-structs so we need to extract and examine | |
those. In addition, we need to maintain a list of visited methods and check this so as to not call a base method | |
that we have already seen and called (possibly seriously polluting an objects interior data). | |
----> | |
<cfloop condition="structKeyExists(md,'extends')"> | |
<cfif structKeyExists(md,'functions')> | |
<!--- now we'll loop through the target's methods and search for matching methods ---> | |
<cfloop from="1" to="#arraylen(md.functions)#" index="functionIx"> | |
<cfset function = md.functions[functionIx]> | |
<cfset functionName = function.name> | |
<cfif not structKeyExists(functionSeen,functionName)> | |
<cfset functionSeen[functionName] = true> | |
<!--- Look for a match in our struct ---> | |
<cfif len(functionName) gt 3 and | |
left(functionName,3) is "set" and | |
arrayLen(md.functions[functionIx].parameters) eq 1> | |
<cfset setterName = right(functionName,len(functionName)-3)> | |
<cfif StructKeyExists(datastruct, setterName)> | |
<!--- massage the value into the correct type that the setter method is expecting, if the type | |
information is set on the function definition ---> | |
<cfset value = StructFind(datastruct, setterName)> | |
<cfscript> | |
if(StructKeyExists(function, 'parameters')) { | |
if(ArrayLen(function.parameters) == 1) { | |
if(function.parameters[1].type == 'numeric') { | |
value = Val(value); | |
} | |
if(function.parameters[1].type == 'string') { | |
value = Trim(value); | |
} | |
} | |
} | |
</cfscript> | |
<cfinvoke component="#object#" | |
method="set#setterName#"> | |
<cfinvokeargument name="#md.functions[functionIx].parameters[1].name#" | |
value="#value#"/> | |
</cfinvoke> | |
</cfif> | |
</cfif> | |
</cfif> | |
</cfloop> | |
</cfif> | |
<cfset md = md.extends /> | |
</cfloop> | |
<cfreturn object /> | |
</cffunction> | |
</cfcomponent> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment