/core/factory.cfc
ColdFusion CFScript | 202 lines | 194 code | 5 blank | 3 comment | 8 complexity | 8c44ed69fd11aca845948cb42a0009f0 MD5 | raw file
1<cfcomponent output="false"> 2 <cfscript> 3 //bean cache 4 this.beans = structNew(); 5 this.transients = structNew(); 6 //functionality 7 </cfscript> 8 9 <cffunction name="init" output="false"> 10 <cfargument name="externalBeanFactory"> 11 <cfscript> 12 if (structKeyExists(arguments, "externalBeanFactory")) { 13 this.externalBeanFactory = arguments.externalBeanFactory; 14 } 15 return this; 16 </cfscript> 17 </cffunction> 18 19 <cfscript> 20 // Proxy to beanExists to provide similar interface to ColdSpring 21 function containsBean(beanName){ 22 return beanExists(arguments.beanName); 23 } 24 function transientExists(beanName){ 25 return structKeyExists(this.transients, arguments.beanName); 26 } 27 function getBean(beanName){ 28 var b = 0; 29 var meta = 0; 30 if (beanExists(arguments.beanName, false, false)){ 31 return this.beans[arguments.beanName]; 32 }else if (transientExists(arguments.beanName)){ 33 b = createObject('component', this.transients[arguments.beanName]); 34 meta = getMetadata(b); 35 _recurse_ResolveDependencies(b, meta); 36 return b; 37 }else if (externalBeanExists(arguments.beanName)){ 38 return this.externalBeanFactory.getBean(arguments.beanName); 39 }else{ 40 throwError(message="Bean name '#arguments.beanName#' not found.", type="Taffy.Factory.BeanNotFound"); 41 } 42 } 43 function getBeanList(){ 44 var combined = structKeyList(this.beans); 45 var trans = structKeyList(this.transients); 46 if (len(combined) and len(trans)){ 47 combined = combined & ","; 48 } 49 combined = combined & trans; 50 return combined; 51 } 52 </cfscript> 53 <cffunction name="beanExists" output="false"> 54 <cfargument required="true" name="beanName"> 55 <cfargument name="includeTransients" default="true"> 56 <cfargument name="includeExternal" default="false"> 57 <cfscript> 58 return structKeyExists(this.beans, arguments.beanName) or (arguments.includeTransients and transientExists(arguments.beanName)) or 59 (arguments.includeExternal and externalBeanExists(arguments.beanName)); 60 </cfscript> 61 </cffunction> 62 <cffunction name="externalBeanExists" access="private" output="false" returnType="boolean"> 63 <cfargument required="true" name="beanName"> 64 <cfscript> 65 return structKeyExists(this, "externalBeanFactory") and this.externalBeanFactory.containsBean(arguments.beanName); 66 </cfscript> 67 </cffunction> 68 <cffunction name="loadBeansFromPath" access="public" output="false" returnType="void"> 69 <cfargument name="beanPath" type="string" required="true" hint="Absolute path to folder containing beans" /> 70 <cfargument name="resourcesPath" type="string" default="resources" /> 71 <cfargument name="resourcesBasePath" type="string" default="" /> 72 <cfargument name="isFullReload" type="boolean" default="false" /> 73 <cfargument name="taffyRef" type="any" required="false" default="#structNew()#" /> 74 <cfset var local = StructNew() /> 75 <!--- cache all of the beans ---> 76 <cfif isFullReload> 77 <cfset this.beans = structNew() /> 78 <cfset arguments.taffyRef.status.skippedResources = arrayNew(1) /> <!--- empty out the array on factory reloads ---> 79 <cfset arguments.taffyRef.beanList = "" /> 80 </cfif> 81 <!--- if the folder doesn't exist, do nothing ---> 82 <cfif not directoryExists(arguments.beanPath)> 83 <cfreturn /> 84 </cfif> 85 <!--- get list of beans to load ---> 86 <cfdirectory action="list" directory="#arguments.beanPath#" filter="*.cfc" name="local.beanQuery" recurse="true" /> 87 <cfloop query="local.beanQuery"> 88 <cfset local.beanName = filePathToBeanName(local.beanQuery.directory, local.beanquery.name, arguments.resourcesBasePath) /> 89 <cfset local.beanPath = filePathToBeanPath(local.beanQuery.directory, local.beanquery.name, arguments.resourcesPath, arguments.resourcesBasePath) /> 90 <cftry> 91 <cfset local.objBean = createObject("component", local.beanPath) /> 92 <cfif isInstanceOf(local.objBean, "taffy.core.baseSerializer")> 93 <cfset this.transients[local.beanName] = local.beanPath /> 94 <cfelse> 95 <cfset this.beans[local.beanName] = local.objBean /> 96 </cfif> 97 <cfcatch> 98 <!--- skip cfc's with errors, but save info about them for display in the dashboard ---> 99 <cfset local.err = structNew() /> 100 <cfset local.err.resource = local.beanName /> 101 <cfset local.err.exception = cfcatch /> 102 <cfset arrayAppend(arguments.taffyRef.status.skippedResources, local.err) /> 103 </cfcatch> 104 </cftry> 105 </cfloop> 106 <!--- resolve dependencies ---> 107 <cfloop list="#structKeyList(this.beans)#" index="local.b"> 108 <cfset local.bean = this.beans[local.b] /> 109 <cfset local.beanMeta = getMetadata(local.bean) /> 110 <cfset _recurse_ResolveDependencies(local.bean, local.beanMeta) /> 111 </cfloop> 112 </cffunction> 113 114 <cffunction name="filePathToBeanPath" access="private"> 115 <cfargument name="path" /> 116 <cfargument name="filename" /> 117 <cfargument name="resourcesPath" /> 118 <cfargument name="resourcesBasePath" /> 119 <cfset var beanPath = "" /> 120 <cfif len(resourcesBasePath) eq 0> 121 <cfset arguments.resourcesBasePath = "!@$%^&*()" /> 122 </cfif> 123 <cfset beanPath = 124 resourcesPath 125 & 126 "." 127 & 128 replaceList( 129 replace(path, resourcesBasePath, ""), 130 "/,\", 131 ".,." 132 ) 133 & 134 "." 135 & 136 replace( 137 filename, 138 ".cfc", 139 "" 140 ) 141 /> 142 <cfset beanPath = replace(beanPath, "..", ".", "ALL") /> 143 <cfif left(beanPath, 1) eq "."> 144 <cfset beanPath = right(beanPath, len(beanPath)-1) /> 145 </cfif> 146 <cfreturn beanPath /> 147 </cffunction> 148 149 <cffunction name="filePathToBeanName" access="private"> 150 <cfargument name="path" /> 151 <cfargument name="filename" /> 152 <cfargument name="basepath" /> 153 <cfif len(basepath) eq 0> 154 <cfset arguments.basePath = "!@$%^&*()" /> 155 </cfif> 156 <cfreturn 157 replaceList( 158 replace(path, basepath, ""), 159 "/,\", 160 "," 161 ) 162 & replace( 163 filename, 164 ".cfc", 165 "" 166 ) 167 /> 168 </cffunction> 169 170 <cffunction name="_recurse_ResolveDependencies" access="private"> 171 <cfargument name="bean" required="true" /> 172 <cfargument name="metaData" type="struct" required="true" /> 173 <cfset var local = structNew() /> 174 <cfif structKeyExists(arguments.metaData, "functions") and isArray(arguments.metaData.functions)> 175 <cfloop from="1" to="#arrayLen(arguments.metaData.functions)#" index="local.f"> 176 <cfset local.fname = arguments.metaData.functions[local.f].name /> 177 <cfif len(local.fname) gt 3> 178 <cfset local.propName = right(local.fname, len(local.fname)-3) /> 179 <cfif left(local.fname, 3) eq "set" and beanExists(local.propName, true, true)> 180 <cfset evaluate("arguments.bean.#local.fname#(getBean('#local.propName#'))") /> 181 </cfif> 182 </cfif> 183 </cfloop> 184 </cfif> 185 <cfif structKeyExists(arguments.metaData, "properties") and isArray(arguments.metaData.properties)> 186 <cfloop from="1" to="#arrayLen(arguments.metaData.properties)#" index="local.p"> 187 <cfset local.propName = arguments.metaData.properties[local.p].name /> 188 <cfif beanExists(local.propName, true, true)> 189 <cfset arguments.bean[local.propName] = getBean(local.propName) /> 190 </cfif> 191 </cfloop> 192 </cfif> 193 <cfif structKeyExists(arguments.metaData, "extends") and isStruct(arguments.metaData.extends)> 194 <cfset _recurse_ResolveDependencies(arguments.bean, arguments.metaData.extends) /> 195 </cfif> 196 </cffunction> 197 <!--- proxy function for CF8 compatibility ---> 198 <cffunction name="throwError"> 199 <cfthrow attributecollection="#arguments#" /> 200 </cffunction> 201 202</cfcomponent>