This commit is contained in:
msyu
2024-10-23 11:17:42 +03:00
commit ab5c944862
380 changed files with 55823 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+57
View File
@@ -0,0 +1,57 @@
<cfcomponent output="false" hint="a helper class to decode input data">
<!--- the most basic of input handlers, available in all APIs --->
<cffunction name="getFromForm" output="false" taffy:mime="application/x-www-form-urlencoded" hint="get data from form post">
<cfargument name="body" hint="the textual request body" />
<cfset var response = {} />
<cfset var pairs = listToArray(arguments.body, "&") />
<cfset var pair = "" />
<cfset var kv = [] />
<cfset var ix = 0 />
<cfset var k = "" />
<cfset var v = "" />
<cfif not find('=', arguments.body)>
<cfset throwError(400, "You've indicated that you're sending form-encoded data but it doesn't appear to be valid. Aborting request.") />
</cfif>
<cfloop from="1" to="#arrayLen(pairs)#" index="ix">
<cfset pair = pairs[ix] />
<cfset kv = listToArray(pair, "=", true) />
<cfset k = kv[1] />
<cfset v = urlDecode( kv[2] ) />
<cfif structKeyExists( response, k )>
<cfset response[k] = listAppend(response[k], v)>
<cfelse>
<cfset response[k] = v>
</cfif>
</cfloop>
<cfreturn response />
</cffunction>
<!--- ============================ --->
<!--- Helpers --->
<!--- ============================ --->
<cffunction name="throwError" access="private" output="false" returntype="void">
<cfargument name="statusCode" type="numeric" default="500" />
<cfargument name="msg" type="string" required="true" hint="message to return to api consumer" />
<cfargument name="headers" type="struct" required="false" default="#structNew()#" />
<cfcontent reset="true" />
<cfset addHeaders(arguments.headers) />
<cfheader statuscode="#arguments.statusCode#" statustext="#arguments.msg#" />
<cfabort />
</cffunction>
<cffunction name="addHeaders" access="private" output="false" returntype="void">
<cfargument name="headers" type="struct" required="true" />
<cfset var h = '' />
<cfif !structIsEmpty(arguments.headers)>
<cfloop list="#structKeyList(arguments.headers)#" index="h">
<cfheader name="#h#" value="#arguments.headers[h]#" />
</cfloop>
</cfif>
</cffunction>
</cfcomponent>
+199
View File
@@ -0,0 +1,199 @@
<cfcomponent output="false" hint="a helper class to represent easily serializable data">
<cfset variables.data = "" />
<cfset variables.fileName = "" />
<cfset variables.fileMime = "" />
<cfset variables.statusCode = 200 />
<cfset variables.statusText = "OK" />
<cfset variables.miscHeaders = StructNew() />
<cfset variables.deleteFile = false />
<!--- 1= textual, 2= filename, 3= file data --->
<cfset variables.type = 1 />
<cfset variables.types = StructNew() />
<cfset variables.types[1] = "textual" />
<cfset variables.types[2] = "filename" />
<cfset variables.types[3] = "filedata" />
<cfset variables.types[4] = "imagedata" />
<cfset variables.statusTexts = StructNew() />
<cfset variables.statusTexts[100] = "Continue" />
<cfset variables.statusTexts[101] = "Switching Protocols" />
<cfset variables.statusTexts[102] = "Processing" />
<cfset variables.statusTexts[200] = "OK" />
<cfset variables.statusTexts[201] = "Created" />
<cfset variables.statusTexts[202] = "Accepted" />
<cfset variables.statusTexts[203] = "Non-authoritative Information" />
<cfset variables.statusTexts[204] = "No Content" />
<cfset variables.statusTexts[205] = "Reset Content" />
<cfset variables.statusTexts[206] = "Partial Content" />
<cfset variables.statusTexts[207] = "Multi-Status" />
<cfset variables.statusTexts[208] = "Already Reported" />
<cfset variables.statusTexts[226] = "IM Used" />
<cfset variables.statusTexts[300] = "Multiple Choices" />
<cfset variables.statusTexts[301] = "Moved Permanently" />
<cfset variables.statusTexts[302] = "Found" />
<cfset variables.statusTexts[303] = "See Other" />
<cfset variables.statusTexts[304] = "Not Modified" />
<cfset variables.statusTexts[305] = "Use Proxy" />
<cfset variables.statusTexts[307] = "Temporary Redirect" />
<cfset variables.statusTexts[308] = "Permanent Redirect" />
<cfset variables.statusTexts[400] = "Bad Request" />
<cfset variables.statusTexts[401] = "Unauthorized" />
<cfset variables.statusTexts[402] = "Payment Required" />
<cfset variables.statusTexts[403] = "Forbidden" />
<cfset variables.statusTexts[404] = "Not Found" />
<cfset variables.statusTexts[405] = "Method Not Allowed" />
<cfset variables.statusTexts[406] = "Not Acceptable" />
<cfset variables.statusTexts[407] = "Proxy Authentication Required" />
<cfset variables.statusTexts[408] = "Request Timeout" />
<cfset variables.statusTexts[409] = "Conflict" />
<cfset variables.statusTexts[410] = "Gone" />
<cfset variables.statusTexts[411] = "Length Required" />
<cfset variables.statusTexts[412] = "Precondition Failed" />
<cfset variables.statusTexts[413] = "Payload Too Large" />
<cfset variables.statusTexts[414] = "Request-URI Too Long" />
<cfset variables.statusTexts[415] = "Unsupported Media Type" />
<cfset variables.statusTexts[416] = "Requested Range Not Satisfiable" />
<cfset variables.statusTexts[417] = "Expectation Failed" />
<cfset variables.statusTexts[418] = "I'm a teapot" />
<cfset variables.statusTexts[421] = "Misdirected Request" />
<cfset variables.statusTexts[422] = "Unprocessable Entity" />
<cfset variables.statusTexts[423] = "Locked" />
<cfset variables.statusTexts[424] = "Failed Dependency" />
<cfset variables.statusTexts[426] = "Upgrade Required" />
<cfset variables.statusTexts[428] = "Precondition Required" />
<cfset variables.statusTexts[429] = "Too Many Requests" />
<cfset variables.statusTexts[431] = "Request Header Fields Too Large" />
<cfset variables.statusTexts[444] = "Connection Closed Without Response" />
<cfset variables.statusTexts[451] = "Unavailable For Legal Reasons" />
<cfset variables.statusTexts[499] = "Client Closed Request" />
<cfset variables.statusTexts[500] = "Internal Server Error" />
<cfset variables.statusTexts[501] = "Not Implemented" />
<cfset variables.statusTexts[502] = "Bad Gateway" />
<cfset variables.statusTexts[503] = "Service Unavailable" />
<cfset variables.statusTexts[504] = "Gateway Timeout" />
<cfset variables.statusTexts[505] = "HTTP Version Not Supported" />
<cfset variables.statusTexts[506] = "Variant Also Negotiates" />
<cfset variables.statusTexts[507] = "Insufficient Storage" />
<cfset variables.statusTexts[508] = "Loop Detected" />
<cfset variables.statusTexts[510] = "Not Extended" />
<cfset variables.statusTexts[511] = "Network Authentication Required" />
<cfset variables.statusTexts[599] = "Network Connect Timeout Error" />
<cffunction name="getType" acces="public" output="false">
<cfreturn variables.types[variables.type] />
</cffunction>
<cffunction name="setData" access="public" output="false" hint="setter for the data to be returned">
<cfargument name="data" required="true" hint="the simple or complex data that you want to return to the api consumer" />
<cfset variables.type = 1 />
<cfset variables.data = arguments.data />
<cfreturn this />
</cffunction>
<cffunction name="getData" access="public" output="false" hint="mostly for testability, returns the native data embedded in the representation instance">
<cfreturn variables.data />
</cffunction>
<cffunction name="noData" access="public" output="false" hint="returns empty representation instance">
<cfif application._taffy.settings.noDataSends204NoContent>
<cfreturn this.noContent() />
<cfelse>
<cfreturn this />
</cfif>
</cffunction>
<cffunction name="noContent" access="public" output="false" hint="returns empty representation instance">
<!--- According to issue #365 https://github.com/atuttle/Taffy/issues/365
noContent() returns with HTTP status code 204 and Content-Type as text/plain (omitting this header is difficult and maybe not recommanded)
noData() is kept 'as is' for backward compatibility with existing implementations
--->
<cfreturn this.withStatus(204).withHeaders({"Content-Type"="text/plain"}) />
</cffunction>
<cffunction name="setFileName" access="public" output="false" hint="Pass in a file-name (fully qualified, e.g. c:\temp\img.jpg) to have Taffy stream this file back to the client">
<cfargument name="file" type="string" required="true" />
<cfset variables.type = 2 />
<cfset variables.fileName = arguments.file />
<cfreturn this />
</cffunction>
<cffunction name="getFileName" access="public" output="false">
<cfreturn variables.fileName />
</cffunction>
<cffunction name="setFileData" access="public" output="false" hint="Pass in file data (eg a generated PDF object) - NOT a Filename! - to have Taffy stream the content back to the client">
<cfargument name="data" required="true" />
<cfset variables.type = 3 />
<cfset variables.fileData = arguments.data />
<cfreturn this />
</cffunction>
<cffunction name="getFileData" access="public" output="false">
<cfreturn variables.fileData />
</cffunction>
<cffunction name="setImageData" access="public" output="false" hint="Pass in image data (eg a generated image object) - NOT a Filename! - to have Taffy stream the content back to the client">
<cfargument name="data" required="true" />
<cfset variables.type = 4 />
<cfif not isBinary(arguments.data)>
<cfset arguments.data = toBinary(toBase64(arguments.data)) />
</cfif>
<cfset variables.fileData = arguments.data />
<cfreturn this />
</cffunction>
<cffunction name="getImageData" access="public" output="false">
<cfreturn getFileData() />
</cffunction>
<cffunction name="withMime" access="public" output="false" hint="Use this method in conjunction with streamFile and streamBinary in your resources to set the mime type of the file being returned. Ex: return streamFile('kittens/cuteness.jpg').withMime('image/jpeg');">
<cfargument name="mime" type="string" required="true" />
<cfset variables.fileMime = arguments.mime />
<cfreturn this />
</cffunction>
<cffunction name="getFileMime" access="public" output="false">
<cfreturn variables.fileMime />
</cffunction>
<cffunction name="withStatus" access="public" output="false" hint="used to set the http response code for the response">
<cfargument name="statusCode" type="numeric" required="true" hint="eg 200" />
<cfargument name="statusText" type="string" required="false" default="" />
<cfset variables.statusCode = arguments.statusCode />
<cfif len(arguments.statusText)>
<cfset variables.statusText = arguments.statusText />
<cfelseif StructKeyExists(variables.statusTexts, arguments.statusCode)>
<cfset variables.statusText = variables.statusTexts[arguments.statusCode] />
</cfif>
<cfreturn this />
</cffunction>
<cffunction name="getStatus" access="public" output="false" returnType="numeric">
<cfreturn variables.statusCode />
</cffunction>
<cffunction name="getStatusText" access="public" output="false" returnType="string">
<cfreturn variables.statusText />
</cffunction>
<cffunction name="withHeaders" access="public" output="false" hint="used to set custom headers for the response">
<cfargument name="headerStruct" type="struct" required="true" />
<cfset variables.miscHeaders = arguments.headerStruct />
<cfreturn this />
</cffunction>
<cffunction name="getHeaders" access="public" output="false" returntype="Struct">
<cfreturn variables.miscHeaders />
</cffunction>
<cffunction name="andDelete" access="public" output="false" hint="used to delete the streamed file">
<cfargument name="doDeleteFile" type="boolean" required="true" />
<cfset variables.deleteFile = arguments.doDeleteFile />
<cfreturn this />
</cffunction>
<cffunction name="getDeleteFile" access="public" output="false" returntype="boolean">
<cfreturn variables.deleteFile />
</cffunction>
</cfcomponent>
+202
View File
@@ -0,0 +1,202 @@
<cfcomponent output="false">
<cfscript>
//bean cache
this.beans = structNew();
this.transients = structNew();
//functionality
</cfscript>
<cffunction name="init" output="false">
<cfargument name="externalBeanFactory">
<cfscript>
if (structKeyExists(arguments, "externalBeanFactory")) {
this.externalBeanFactory = arguments.externalBeanFactory;
}
return this;
</cfscript>
</cffunction>
<cfscript>
// Proxy to beanExists to provide similar interface to ColdSpring
function containsBean(beanName){
return beanExists(arguments.beanName);
}
function transientExists(beanName){
return structKeyExists(this.transients, arguments.beanName);
}
function getBean(beanName){
var b = 0;
var meta = 0;
if (beanExists(arguments.beanName, false, false)){
return this.beans[arguments.beanName];
}else if (transientExists(arguments.beanName)){
b = createObject('component', this.transients[arguments.beanName]);
meta = getMetadata(b);
_recurse_ResolveDependencies(b, meta);
return b;
}else if (externalBeanExists(arguments.beanName)){
return this.externalBeanFactory.getBean(arguments.beanName);
}else{
throwError(message="Bean name '#arguments.beanName#' not found.", type="Taffy.Factory.BeanNotFound");
}
}
function getBeanList(){
var combined = structKeyList(this.beans);
var trans = structKeyList(this.transients);
if (len(combined) and len(trans)){
combined = combined & ",";
}
combined = combined & trans;
return combined;
}
</cfscript>
<cffunction name="beanExists" output="false">
<cfargument required="true" name="beanName">
<cfargument name="includeTransients" default="true">
<cfargument name="includeExternal" default="false">
<cfscript>
return structKeyExists(this.beans, arguments.beanName) or (arguments.includeTransients and transientExists(arguments.beanName)) or
(arguments.includeExternal and externalBeanExists(arguments.beanName));
</cfscript>
</cffunction>
<cffunction name="externalBeanExists" access="private" output="false" returnType="boolean">
<cfargument required="true" name="beanName">
<cfscript>
return structKeyExists(this, "externalBeanFactory") and this.externalBeanFactory.containsBean(arguments.beanName);
</cfscript>
</cffunction>
<cffunction name="loadBeansFromPath" access="public" output="false" returnType="void">
<cfargument name="beanPath" type="string" required="true" hint="Absolute path to folder containing beans" />
<cfargument name="resourcesPath" type="string" default="resources" />
<cfargument name="resourcesBasePath" type="string" default="" />
<cfargument name="isFullReload" type="boolean" default="false" />
<cfargument name="taffyRef" type="any" required="false" default="#structNew()#" />
<cfset var local = StructNew() />
<!--- cache all of the beans --->
<cfif isFullReload>
<cfset this.beans = structNew() />
<cfset arguments.taffyRef.status.skippedResources = arrayNew(1) /> <!--- empty out the array on factory reloads --->
<cfset arguments.taffyRef.beanList = "" />
</cfif>
<!--- if the folder doesn't exist, do nothing --->
<cfif not directoryExists(arguments.beanPath)>
<cfreturn />
</cfif>
<!--- get list of beans to load --->
<cfdirectory action="list" directory="#arguments.beanPath#" filter="*.cfc" name="local.beanQuery" recurse="true" />
<cfloop query="local.beanQuery">
<cfset local.beanName = filePathToBeanName(local.beanQuery.directory, local.beanquery.name, arguments.resourcesBasePath) />
<cfset local.beanPath = filePathToBeanPath(local.beanQuery.directory, local.beanquery.name, arguments.resourcesPath, arguments.resourcesBasePath) />
<cftry>
<cfset local.objBean = createObject("component", local.beanPath) />
<cfif isInstanceOf(local.objBean, "taffy.core.baseSerializer")>
<cfset this.transients[local.beanName] = local.beanPath />
<cfelse>
<cfset this.beans[local.beanName] = local.objBean />
</cfif>
<cfcatch>
<!--- skip cfc's with errors, but save info about them for display in the dashboard --->
<cfset local.err = structNew() />
<cfset local.err.resource = local.beanName />
<cfset local.err.exception = cfcatch />
<cfset arrayAppend(arguments.taffyRef.status.skippedResources, local.err) />
</cfcatch>
</cftry>
</cfloop>
<!--- resolve dependencies --->
<cfloop list="#structKeyList(this.beans)#" index="local.b">
<cfset local.bean = this.beans[local.b] />
<cfset local.beanMeta = getMetadata(local.bean) />
<cfset _recurse_ResolveDependencies(local.bean, local.beanMeta) />
</cfloop>
</cffunction>
<cffunction name="filePathToBeanPath" access="private">
<cfargument name="path" />
<cfargument name="filename" />
<cfargument name="resourcesPath" />
<cfargument name="resourcesBasePath" />
<cfset var beanPath = "" />
<cfif len(resourcesBasePath) eq 0>
<cfset arguments.resourcesBasePath = "!@$%^&*()" />
</cfif>
<cfset beanPath =
resourcesPath
&
"."
&
replaceList(
replace(path, resourcesBasePath, ""),
"/,\",
".,."
)
&
"."
&
replace(
filename,
".cfc",
""
)
/>
<cfset beanPath = replace(beanPath, "..", ".", "ALL") />
<cfif left(beanPath, 1) eq ".">
<cfset beanPath = right(beanPath, len(beanPath)-1) />
</cfif>
<cfreturn beanPath />
</cffunction>
<cffunction name="filePathToBeanName" access="private">
<cfargument name="path" />
<cfargument name="filename" />
<cfargument name="basepath" />
<cfif len(basepath) eq 0>
<cfset arguments.basePath = "!@$%^&*()" />
</cfif>
<cfreturn
replaceList(
replace(path, basepath, ""),
"/,\",
","
)
& replace(
filename,
".cfc",
""
)
/>
</cffunction>
<cffunction name="_recurse_ResolveDependencies" access="private">
<cfargument name="bean" required="true" />
<cfargument name="metaData" type="struct" required="true" />
<cfset var local = structNew() />
<cfif structKeyExists(arguments.metaData, "functions") and isArray(arguments.metaData.functions)>
<cfloop from="1" to="#arrayLen(arguments.metaData.functions)#" index="local.f">
<cfset local.fname = arguments.metaData.functions[local.f].name />
<cfif len(local.fname) gt 3>
<cfset local.propName = right(local.fname, len(local.fname)-3) />
<cfif left(local.fname, 3) eq "set" and beanExists(local.propName, true, true)>
<cfset evaluate("arguments.bean.#local.fname#(getBean('#local.propName#'))") />
</cfif>
</cfif>
</cfloop>
</cfif>
<cfif structKeyExists(arguments.metaData, "properties") and isArray(arguments.metaData.properties)>
<cfloop from="1" to="#arrayLen(arguments.metaData.properties)#" index="local.p">
<cfset local.propName = arguments.metaData.properties[local.p].name />
<cfif beanExists(local.propName, true, true)>
<cfset arguments.bean[local.propName] = getBean(local.propName) />
</cfif>
</cfloop>
</cfif>
<cfif structKeyExists(arguments.metaData, "extends") and isStruct(arguments.metaData.extends)>
<cfset _recurse_ResolveDependencies(arguments.bean, arguments.metaData.extends) />
</cfif>
</cffunction>
<!--- proxy function for CF8 compatibility --->
<cffunction name="throwError">
<cfthrow attributecollection="#arguments#" />
</cffunction>
</cfcomponent>
+21
View File
@@ -0,0 +1,21 @@
<cfcomponent extends="taffy.core.baseDeserializer">
<cffunction name="getFromJson" output="false" taffy:mime="application/json,text/json" hint="get data from json">
<cfargument name="body" hint="the textual request body" />
<cfset var data = 0 />
<cfset var response = {} />
<cfif not isJson(arguments.body)>
<cfset throwError(msg="Input JSON is not well formed", statusCode="400") />
</cfif>
<cfset data = deserializeJSON(arguments.body) />
<cfif not isStruct(data)>
<cfset response['_body'] = data />
<cfelse>
<cfset response = data />
</cfif>
<cfreturn response />
</cffunction>
</cfcomponent>
+12
View File
@@ -0,0 +1,12 @@
<cfcomponent extends="taffy.core.baseSerializer" output="false" hint="Serializer that uses CFML server's json serialization functionality to return json data">
<cffunction
name="getAsJson"
output="false"
taffy:mime="application/json;text/json"
taffy:default="true"
hint="serializes data as JSON">
<cfreturn rereplace(replace(serializeJSON(variables.data), chr(2), '', 'ALL'), '"\\u0002', '"', 'ALL') />
</cffunction>
</cfcomponent>
+141
View File
@@ -0,0 +1,141 @@
<cfcomponent hint="base class for taffy REST components">
<cffunction name="forceString">
<cfargument name="data" required="true" hint="the data that is being forced to serialize as a string" />
<cfreturn chr(2) & arguments.data />
</cffunction>
<cfset variables.encode = structNew() />
<cfset variables.encode.string = forceString />
<!--- helper functions --->
<cffunction name="representationOf" access="public" output="false" hint="returns an object capable of serializing the data in a variety of formats">
<cfargument name="data" required="true" hint="any simple or complex data that should be returned for the request" />
<cfreturn getRepInstance().setData(arguments.data) />
</cffunction>
<cffunction name="rep" access="public" output="false" hint="alias for representationOf">
<cfargument name="data" required="true" />
<cfreturn representationOf(arguments.data) />
</cffunction>
<cffunction name="noData" access="private" output="false" hint="use this function to return only headers to the consumer, no data">
<cfreturn getRepInstance().noData() />
</cffunction>
<cffunction name="noContent" access="private" output="false" hint="use this function to return only headers to the consumer, no data">
<cfreturn getRepInstance().noContent() />
</cffunction>
<cffunction name="streamFile" access="private" output="false" hint="Use this function to specify a file name (eg c:\tmp\kitten.jpg) to be streamed to the client. When you use this method it is *required* that you also use .withMime() to specify the mime type.">
<cfargument name="fileName" required="true" hint="fully qualified file path (eg c:\tmp\kitten.jpg)" />
<cfreturn getRepInstance().setFileName(arguments.fileName) />
</cffunction>
<cffunction name="streamBinary" access="private" output="false" hint="Use this function to stream binary data, like a generated PDF object, to the client. When you use this method it is *required* that you also use .withMime() to specify the mime type.">
<cfargument name="binaryData" required="true" hint="binary file data (eg a PDF object) that you want to return to the client" />
<cfreturn getRepInstance().setFileData(arguments.binaryData) />
</cffunction>
<cffunction name="streamImage" access="private" output="false" hint="Use this function to stream binary data, like a generated PDF object, to the client. When you use this method it is *required* that you also use .withMime() to specify the mime type.">
<cfargument name="binaryData" required="true" hint="binary file data (eg a PDF object or image data) that you want to return to the client" />
<cfreturn getRepInstance().setImageData(arguments.binaryData) />
</cffunction>
<cffunction name="saveLog">
<cfargument name="exception" />
<cfset logger = createObject("component", application._taffy.settings.exceptionLogAdapter).init(
application._taffy.settings.exceptionLogAdapterConfig
) />
<cfset logger.saveLog(exception) />
</cffunction>
<cffunction name="queryToArray" access="private" returntype="array" output="false">
<cfargument name="q" type="query" required="yes" />
<cfargument name="cb" type="any" required="no" />
<cfscript>
var local = {};
if (structKeyExists(server, "railo") or structKeyExists(server, "lucee")) {
local.Columns = listToArray(arguments.q.getColumnList(false));
}
else {
local.Columns = arguments.q.getMetaData().getColumnLabels();
}
local.QueryArray = ArrayNew(1);
for (local.RowIndex = 1; local.RowIndex <= arguments.q.RecordCount; local.RowIndex++){
local.Row = {};
local.numCols = ArrayLen( local.Columns );
for (local.ColumnIndex = 1; local.ColumnIndex <= local.numCols; local.ColumnIndex++){
local.ColumnName = local.Columns[ local.ColumnIndex ];
if( local.ColumnName NEQ "" ) {
local.Row[ local.ColumnName ] = arguments.q[ local.ColumnName ][ local.RowIndex ];
}
}
if ( structKeyExists( arguments, "cb" ) ) {
local.Row = cb( local.Row );
}
ArrayAppend( local.QueryArray, local.Row );
}
return( local.QueryArray );
</cfscript>
</cffunction>
<cffunction name="queryToStruct" access="private" returntype="struct" output="false">
<cfargument name="q" type="query" required="yes" />
<cfargument name="cb" type="any" required="no" />
<cfset var local = {} />
<cfif q.recordcount gt 1>
<cfthrow message="Unable to convert query resultset with more than one record to a simple struct, use queryToArray() instead" />
</cfif>
<cfscript>
if (structKeyExists(server, "railo") or structKeyExists(server, "lucee")) {
local.Columns = listToArray(arguments.q.getColumnList(false));
}
else {
local.Columns = arguments.q.getMetaData().getColumnLabels();
}
local.QueryStruct = {};
local.numCols = ArrayLen( local.Columns );
for (local.ColumnIndex = 1; local.ColumnIndex <= local.numCols; local.ColumnIndex++){
local.ColumnName = local.Columns[ local.ColumnIndex ];
if( local.ColumnName NEQ "" ) {
if ( structKeyExists( arguments, "cb" ) ) {
local.QueryStruct[ local.ColumnName ] = cb( local.ColumnName, arguments.q[ local.ColumnName ][1] );
} else {
local.QueryStruct[ local.ColumnName ] = arguments.q[ local.ColumnName ][1];
}
}
}
return( local.QueryStruct );
</cfscript>
</cffunction>
<!---
function that gets the representation class instance
-- if the argument is blank, we use the default from taffy settings
-- if the argument is a beanName, the bean is returned from the factory;
-- otherwise it is assumed to be a cfc path and that cfc instance is returned
--->
<cffunction name="getRepInstance" access="private" output="false">
<cfargument name="repClass" type="string" default="" />
<cfif repClass eq "">
<!--- recursion not the most efficient path here, but it's damn readable --->
<cfreturn getRepInstance(application._taffy.settings.serializer) />
<cfelseif application._taffy.factory.containsBean(arguments.repClass)>
<cfreturn application._taffy.factory.getBean(arguments.repClass) />
<cfelse>
<cfreturn createObject("component", arguments.repClass) />
</cfif>
</cffunction>
<cffunction name="addDebugData" access="package" output="false">
<cfargument name="data" type="any" />
<cfset request.debugData = arguments.data />
</cffunction>
</cfcomponent>