Compound Theory

v2.0

Categories

  1. Transfer
  2. ColdFusion
  3. JRuby
  4. Java
  5. ColdSpring
  6. Squabble
  7. JavaLoader
  8. ColdDoc
  9. 2ddu
  10. AsyncHTTP
  11. OO Analysis and Design
  12. Flex
  13. Railo
  14. XML / XSL
  15. Hibernate
  16. ColdFusion Builder
  17. Fall
  18. Ubuntu
  19. XHTML / CSS
  20. Eclipse
  21. Git
  22. Oracle Database
  23. Usability / UI Design
  24. webDU
  25. cf.Objective()
  26. LWJGL
  27. cf.Objective(ANZ)
  28. Captcha
  29. MAX
  30. Melbourne CFUG
  31. Martial Arts
  32. Random Things
  33. Conduit

Recent Posts

Projects

Recent Comments

20 December 2004 01:43 PM

Crazy Fun with CFCs and Functions: StructToBean()

This totally defeats all purposes of OO encapsulation, and a variety of other principles, but it was a fun time to play around with.

Basically, i wanted to see if I could turn a Struct into a Bean object on the fly. Strangely enough, it was pretty simple considering the flexibility you have with functions and CFCs.

The code works out like follows:

<cfscript>
 //helper functions
 function identityHashCode(object)
 {
  var system = createObject("java", "java.lang.System");
  return system.identityHashCode(arguments.object);
 }

 function setInstance(instance)
 {
  variables.instance = arguments.instance;
 }
</cfscript>

<cffunction name="structToObject" hint="Converts a structure to a object with getters and setters" access="public" returntype="WEB-INF.cftags.component" output="false">
 <cfargument name="inputStruct" hint="Struct to convert" type="struct" required="Yes">

 <cfscript>
  var obj = createObject("component", "WEB-INF.cftags.component");
  var lKeys = StructKeyList(arguments.inputStruct);
  var hash = identityHashCode(arguments.inputStruct);
  var key = "";  var path = GetDirectoryFromPath(CGI.PATH_TRANSLATED);
  var nl = chr(10) & chr(13);
  var buffer = createObject("java", "java.lang.StringBuffer").init("<cfscript>#nl#");

  //move variable scope to inside the CFC
  obj.setInstance = setInstance;
  obj.setInstance(arguments.inputStruct);
  StructDelete(obj, "setInstance");
 </cfscript>

 <cfloop list="#lKeys#" index="key">
  <!--- write out the function to get and set --->
  <cfscript>
   buffer.append("function get#key#() { return instance.#key#; }#nl#");
   buffer.append("function set#key#(#key#) { instance.#key# = arguments.#key#; }#nl#");
  </cfscript>
 </cfloop>
 <cfscript>
  buffer.append("</cfscript>");
 </cfscript>
 
 <!--- make the file - use the hash to ensure uniqueness --->
 <cffile action="write" file="#path##hash#.functions" output="#buffer.toString()#">
 <!--- import the file --->
 <cfinclude template="#hash#.functions"> 
 <!--- delete the file --->  
 <cffile action="delete" file="#path##hash#.functions">
 
 <!---  add it to the object --->
 <cfloop list="#lKeys#" index="key">
  <cfscript>
   obj["get#key#"] = variables["get#key#"];
   obj["set#key#"] = variables["set#key#"];
  </cfscript>
 </cfloop>  
 <cfreturn obj>

</cffunction>

To test this out:

<!--- test code --->

<cfscript>
myStruct = StructNew();
myStruct.fred = "Fred";

obj = structToObject(myStruct);
</cfscript>

<cfoutput>
#obj.getFred()#
<hr>

<cfscript>
obj.setFred("blue");
</cfscript>

#obj.getFred()#
</cfoutput>



Essentially this function:,

  1. Creates a basic CFC (WEB-INF.cftags.component is the base CFC for all CFCs),
  2. Adds the 'setInstance()' function to the CFC, and sets the Struct to the instance data of the CFC with it,
  3. Removes 'setInstance()' function from the CFC,
  4. The function loops through the Struct Keys,
  5. It writes a series of getter and setter functions to an external file,
  6. Imports in the file, placing these functions into the variables scope,
  7. Deletes the file (cleanup!)
  8. Adds all these functions to the CFC,
  9. Returns the CFC.

And look at that, we have created a CFC at run time! Totally defeats some core OO concepts, but it was interesting to note that you can do it.



Comments

No comments have been entered for this post.

Add Comment