Last active
March 4, 2016 04:12
-
-
Save timmaybrown/7226809 to your computer and use it in GitHub Desktop.
Revisions
-
timmaybrown renamed this gist
Sep 24, 2014 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
Tim Brown created this gist
Oct 30, 2013 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,162 @@ <cfcomponent extends="model.util.jsonSerializer" singleton="true"> <cfproperty name="jsonUTIL" inject="model" /> <cffunction name="init"> <!---// let's init Mr. Nadel's serializer---> <cfset super.init()> <!--- FOR Reference: PROPERTIES THAT ARE AVAILABLE due to the SUPER.init() call above // Every key is added to the full key list. fullKeyList = {}; // These key lists determine special data serialization. booleanKeyList = {}; integerKeyList = {}; floatKeyList = {}; dateKeyList = {}; // These keys will NOT be used in serialization (ie. the key/value pairs will not be added // to the serialized output). blockedKeyList = {}; // When serializing values, ColdFusion has a tendency to convert strings to numbers if those // strings look like numbers. We will prepend the string values with this "conversion blocker" // so that we can force ColdFusion to make a string (this gets removed after serialization). START_OF_STRING = chr( 2 ); ---> <!--- PERSISTENT ENTITY SEARCH LOGIC ---> <cfset var qEntities = ""> <cfset var qModels = ""> <!--- LET's fetch our model's this be an array of persitent cfc names, but I don't want to have to update the array for every new entity I add to my model's folder ---> <cfdirectory action="list" type="file" listinfo="name" directory="#GetDirectoryFromPath( GetBaseTemplatePath() )#model\" name="qModels" /> <cfquery name="qEntities" dbtype="query"> SELECT Name FROM qModels WHERE Name NOT LIKE '%Service.cfc' AND Name NOT IN ('DummyFlash.cfc','ORMEventHandler.cfc') </cfquery> <cfset var arEntities = listToArray(valueList(qEntities.Name))> <!--- /END PERSISTENT ENTITY SEARCH LOGIC ---> <!--- UNCOMMENT IF YOU WANT TO GET ALL avail type Methods <cfset pMeths = GetComponentMetaData('jsonSerializer').functions> <cfset f = ""> <cfloop array="#pMeths#" index="p"> <cfif !listFindnoCase(f, p.name) && left(p.name, 2) EQ 'as'> <cfset f = listAppend(f, p.name)> </cfif> </cfloop> <cfdump var="#f#"><cfabort> ---> <!--- COMPONENT METADATA LOGIC ---> <cfscript> var meta = {}; var md = {}; // iteration to fetch all entity properties if the cfc is a persistent cfc for(var e=1; e <= arrayLen(arEntities); e++){ c = listFirst(arEntities[e], '.'); md = GetComponentMetaData("model.#c#"); if (structKeyExists(md,'persistent')) meta[c] = md.properties; } // now let's prep the struct of property names the value of the property names are the method name available in the serializer // eg: toInit['userID'] = 'asInteger'; // this will allow for dyanmic method invocation of the asInteger method now available from the inherited serailizer var toInit = {}; var entityName = ""; var entityProperties = []; for(entityName in meta){ entityProperties = meta[entityName]; for(var p=1; p <=arrayLen(entityProperties); p++){ toInit[entityProperties[p].name] = (structKeyExists(entityProperties[p], 'ormType')) ? getSerializeMethByORMType(entityProperties[p].ormType) : "asAny"; } } //now that the toInit structure is ready lets dynamically invoke the methods. // Thanks to Adam Cameron for this blogging about this little trick (http://cfmlblog.adamcameron.me/2012/09/functions-and-their-execution-context.html) for(propertyName in toInit) { this.theMethod = this[toInit[propertyName]]; //put a reference to the ACTUAL method into this static property name this.theMethod(key=propertyName); // now invoke the dynamic method } // now for anything else that wasn't a proper name that was custom just continue to chain calls like Mr Nadel shows in his blog post this .asInteger("adCount") .asString("partnerName") .asString("configStatus") ; </cfscript> <cfreturn this> </cffunction> <!------------------------------------------------------------------------ PUBLIC METHODS -------------------------------------------------------------------------> <!--- override Mr. Nadel's serialize method and use injected jsonUTIL service in lieu of CF's serializeJSON() ---> <cffunction name="serialize" access="public" returntype="String"> <cfargument name="input" required="true" type="any" /> <cfscript> var preparedInput = prepareInputForSerialization( input ); var serializedInput = jsonUtil.serialize(var=preparedInput, strict="true"); // At this point, we have the serialized response; but, the response contains unwanted // artifacts that were required to enforce string value integrity. Those must now be // removed, post-serialization. var sanitizedResponse = removeStartOfStringMarkers( serializedInput ); return( sanitizedResponse ); </cfscript> </cffunction> <!------------------------------------------------------------------------ PRIVATE METHODS -------------------------------------------------------------------------> <cffunction name="getSerializeMethByORMType" access="private"> <cfargument name="ormType" type="string" required="true"> <cfscript> var stORMTypes = { "big_decimal" = "asFloat" ,"binary" = "asString" ,"blob" = "asString" ,"boolean" = "asBoolean" ,"char" = "asString" ,"character" = "asString" ,"clob" = "asString" ,"date" = "asDate" ,"double" = "asFloat" ,"float" = "asFloat" ,"int" = "asInteger" ,"integer" = "asInteger" ,"long" = "asString" ,"serializable" = "asString" ,"short" = "asString" ,"string" = "asString" ,"text" = "asString" ,"timestamp" = "asDate" ,"true_false" = "asBoolean" ,"yes_no" = "asBoolean" }; return (structKeyExists(stORMTypes, ormType)) ? stORMTypes[ormType] : "asAny"; </cfscript> </cffunction> </cfcomponent>