| 1 | <!---
|
|---|
| 2 | Copyright 2006-2007 TeraTech, Inc. http://teratech.com/
|
|---|
| 3 |
|
|---|
| 4 | Licensed under the Apache License, Version 2.0 (the "License");
|
|---|
| 5 | you may not use this file except in compliance with the License.
|
|---|
| 6 | You may obtain a copy of the License at
|
|---|
| 7 |
|
|---|
| 8 | http://www.apache.org/licenses/LICENSE-2.0
|
|---|
| 9 |
|
|---|
| 10 | Unless required by applicable law or agreed to in writing, software
|
|---|
| 11 | distributed under the License is distributed on an "AS IS" BASIS,
|
|---|
| 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|---|
| 13 | See the License for the specific language governing permissions and
|
|---|
| 14 | limitations under the License.
|
|---|
| 15 | --->
|
|---|
| 16 | <cfcomponent output="false" hint="I am the Fusebox application object, formerly the application.fusebox data structure.">
|
|---|
| 17 |
|
|---|
| 18 | <cfscript>
|
|---|
| 19 | // initialize the fusebox (available to be read by developers but not to be written to)
|
|---|
| 20 | this.isFullyLoaded = false;
|
|---|
| 21 | this.circuits = structNew();
|
|---|
| 22 | this.classes = structNew();
|
|---|
| 23 | this.lexicons = structNew();
|
|---|
| 24 | this.plugins = structNew();
|
|---|
| 25 | this.pluginphases = structNew();
|
|---|
| 26 | this.nonFatalExceptionPrefix = "INFORMATION (can be ignored): ";
|
|---|
| 27 |
|
|---|
| 28 | // this always has to be overridden:
|
|---|
| 29 | this.defaultFuseaction = "";
|
|---|
| 30 |
|
|---|
| 31 | this.precedenceFormOrURL = "form";
|
|---|
| 32 | this.fuseactionVariable = "fuseaction";
|
|---|
| 33 |
|
|---|
| 34 | // these are all ignored:
|
|---|
| 35 | this.parseWithComments = false;
|
|---|
| 36 | this.ignoreBadGrammar = true;
|
|---|
| 37 | this.allowLexicon = true;
|
|---|
| 38 | this.useAssertions = true;
|
|---|
| 39 |
|
|---|
| 40 | // FB55: this is implemented now:
|
|---|
| 41 | this.conditionalParse = false;
|
|---|
| 42 |
|
|---|
| 43 | this.password = "";
|
|---|
| 44 | this.mode = "production";
|
|---|
| 45 | this.scriptLanguage = "cfmx";
|
|---|
| 46 | this.scriptFileDelimiter = "cfm";
|
|---|
| 47 | this.maskedFileDelimiters = "htm,cfm,cfml,php,php4,asp,aspx";
|
|---|
| 48 | this.characterEncoding = "utf-8";
|
|---|
| 49 | // this is ignored:
|
|---|
| 50 | this.parseWithIndentation = this.parseWithComments;
|
|---|
| 51 | this.strictMode = false;
|
|---|
| 52 | this.allowImplicitFusebox = false;
|
|---|
| 53 | this.allowImplicitCircuits = false;
|
|---|
| 54 | this.debug = false;
|
|---|
| 55 | </cfscript>
|
|---|
| 56 |
|
|---|
| 57 | <cffunction name="init" returntype="fuseboxApplication" access="public" output="false"
|
|---|
| 58 | hint="I am the constructor.">
|
|---|
| 59 | <cfargument name="appKey" type="string" required="true"
|
|---|
| 60 | hint="I am FUSEBOX_APPLICATION_KEY." />
|
|---|
| 61 | <cfargument name="appPath" type="string" required="true"
|
|---|
| 62 | hint="I am FUSEBOX_APPLICATION_PATH." />
|
|---|
| 63 | <cfargument name="myFusebox" type="myFusebox" required="true"
|
|---|
| 64 | hint="I am the myFusebox data structure." />
|
|---|
| 65 | <cfargument name="callerPath" type="string" required="true"
|
|---|
| 66 | hint="I am FUSEBOX_CALLER_PATH." />
|
|---|
| 67 | <cfargument name="appParameters" type="struct" required="true"
|
|---|
| 68 | hint="I am FUSEBOX_PARAMETERS." />
|
|---|
| 69 |
|
|---|
| 70 | <cfset var myVersion = "5.5.1" />
|
|---|
| 71 | <!--- <cfset var myVersion = "5.5.0.#REReplace('$LastChangedRevision:683 $','[^0-9]','','all')#" /> --->
|
|---|
| 72 |
|
|---|
| 73 | <cfset variables.factory = createObject("component","fuseboxFactory").init() />
|
|---|
| 74 | <cfset variables.fuseboxLexicon = variables.factory.getBuiltinLexicon() />
|
|---|
| 75 | <cfset variables.customAttributes = structNew() />
|
|---|
| 76 |
|
|---|
| 77 | <cfset variables.fuseboxFileExtension = "" />
|
|---|
| 78 |
|
|---|
| 79 | <cfset variables.fuseboxVersion = myVersion />
|
|---|
| 80 |
|
|---|
| 81 | <cfset variables.appKey = arguments.appKey />
|
|---|
| 82 | <cfset this.webrootdirectory = replace(getDirectoryFromPath(getBaseTemplatePath()),"\","/","all") />
|
|---|
| 83 | <cfset variables.coreRoot = replace(getDirectoryFromPath(getCurrentTemplatePath()),"\","/","all") />
|
|---|
| 84 |
|
|---|
| 85 | <cfset this.approotdirectory = getCanonicalPath(normalizePartialPath(arguments.callerPath) & normalizePartialPath(arguments.appPath)) />
|
|---|
| 86 |
|
|---|
| 87 | <!--- this works on all platforms: --->
|
|---|
| 88 | <cfset this.osdelimiter = "/" />
|
|---|
| 89 |
|
|---|
| 90 | <cfset this.coreToAppRootPath = relativePath(variables.coreRoot,this.approotdirectory) />
|
|---|
| 91 | <cfset this.appRootPathToCore = relativePath(this.approotdirectory,variables.coreRoot) />
|
|---|
| 92 | <cfset this.coreToWebRootPath = relativePath(variables.coreRoot,this.webrootdirectory) />
|
|---|
| 93 | <cfset this.WebRootPathToCore = relativePath(this.webrootdirectory,variables.coreRoot) />
|
|---|
| 94 |
|
|---|
| 95 | <cfset this.parsePath = "parsed/" />
|
|---|
| 96 | <cfset this.parseRootPath = "../" />
|
|---|
| 97 | <cfset this.pluginsPath = "plugins/" />
|
|---|
| 98 | <cfset this.lexiconPath = "lexicon/" />
|
|---|
| 99 | <cfset this.errortemplatesPath = "errortemplates/" />
|
|---|
| 100 |
|
|---|
| 101 | <!--- new in Fusebox 5.1: --->
|
|---|
| 102 | <cfset this.self = CGI.SCRIPT_NAME />
|
|---|
| 103 | <cfset this.queryStringStart = "?" />
|
|---|
| 104 | <cfset this.queryStringSeparator = "&" />
|
|---|
| 105 | <cfset this.queryStringEqual = "=" />
|
|---|
| 106 |
|
|---|
| 107 | <cfset this.circuits = structNew() />
|
|---|
| 108 | <cfset reload(arguments.appKey,arguments.appPath,arguments.myFusebox,arguments.appParameters) />
|
|---|
| 109 |
|
|---|
| 110 | <cfif this.strictMode>
|
|---|
| 111 | <!--- rootdirectory was deprecated in Fusebox 5 so we no longer set it it strict mode: --->
|
|---|
| 112 | <cfset structDelete(this,"rootdirectory") />
|
|---|
| 113 | <cfelse>
|
|---|
| 114 | <!--- for FB4.0 compatibility: --->
|
|---|
| 115 | <cfset this.rootdirectory = this.approotdirectory />
|
|---|
| 116 | </cfif>
|
|---|
| 117 |
|
|---|
| 118 | <cfreturn this />
|
|---|
| 119 |
|
|---|
| 120 | </cffunction>
|
|---|
| 121 |
|
|---|
| 122 | <cffunction name="reload" returntype="void" access="public" output="false"
|
|---|
| 123 | hint="I (re)load the fusebox.xml file into memory and (re)load all of the application components referenced by that.">
|
|---|
| 124 | <cfargument name="appKey" type="string" required="true"
|
|---|
| 125 | hint="I am FUSEBOX_APPLICATION_KEY." />
|
|---|
| 126 | <cfargument name="appPath" type="string" required="true"
|
|---|
| 127 | hint="I am FUSEBOX_APPLICATION_PATH." />
|
|---|
| 128 | <cfargument name="myFusebox" type="myFusebox" required="true"
|
|---|
| 129 | hint="I am the myFusebox data structure." />
|
|---|
| 130 | <cfargument name="appParameters" type="struct" required="true"
|
|---|
| 131 | hint="I am FUSEBOX_PARAMETERS." />
|
|---|
| 132 |
|
|---|
| 133 | <cfset var fbFile = "fusebox.xml.cfm" />
|
|---|
| 134 | <cfset var fbFileAlt = "fusebox.xml" />
|
|---|
| 135 | <cfset var fbFileExists = false />
|
|---|
| 136 | <cfset var fbXML = "" />
|
|---|
| 137 | <cfset var fbCode = "" />
|
|---|
| 138 | <cfset var encodings = 0 />
|
|---|
| 139 | <cfset var needToLoad = true />
|
|---|
| 140 | <cfset var fuseboxFiles = 0 />
|
|---|
| 141 | <cfset var p = "" />
|
|---|
| 142 |
|
|---|
| 143 | <!--- FB55: cache of parsed file signatures --->
|
|---|
| 144 | <cfset variables.parsedFileCache = structNew() />
|
|---|
| 145 |
|
|---|
| 146 | <!--- FB55: can override fusebox.xml parameters programmatically --->
|
|---|
| 147 | <!--- this sets up the defaults for the reload - prior to actually reading parameters --->
|
|---|
| 148 | <cfloop collection="#arguments.appParameters#" item="p">
|
|---|
| 149 | <cfset this[p] = arguments.appParameters[p] />
|
|---|
| 150 | </cfloop>
|
|---|
| 151 | <cfif structKeyExists(this,"allowImplicitFusebox") and this.allowImplicitFusebox>
|
|---|
| 152 | <cfset this.allowImplicitCircuits = true />
|
|---|
| 153 | </cfif>
|
|---|
| 154 |
|
|---|
| 155 | <!---
|
|---|
| 156 | since we need to check the file, regardless of whether we load it,
|
|---|
| 157 | we might as well do the test up front and perform the strict check
|
|---|
| 158 | that just one version exists (ticket 135)
|
|---|
| 159 | --->
|
|---|
| 160 | <cfset fbFileExists = fileExists(this.approotdirectory & fbFile) />
|
|---|
| 161 | <cfif fbFileExists>
|
|---|
| 162 | <cfif this.strictMode and fileExists(this.approotdirectory & fbFileAlt)>
|
|---|
| 163 | <cfthrow type="fusebox.multipleFuseboxXML"
|
|---|
| 164 | message="Both 'fusebox.xml' and 'fusebox.xml.cfm' exist"
|
|---|
| 165 | detail="'fusebox.xml.cfm' will be used but 'fusebox.xml' also exists in '#this.approotdirectory#." />
|
|---|
| 166 | </cfif>
|
|---|
| 167 | <cfelse>
|
|---|
| 168 | <cfset fbFile = fbFileAlt />
|
|---|
| 169 | <cfset fbFileExists = fileExists(this.approotdirectory & fbFile) />
|
|---|
| 170 | </cfif>
|
|---|
| 171 |
|
|---|
| 172 | <cfif structKeyExists(this,"timestamp")>
|
|---|
| 173 | <cfif fbFileExists>
|
|---|
| 174 | <!--- we only check the time stamp if the file exists --->
|
|---|
| 175 | <cfset needToLoad = fileModificationDate(this.approotdirectory & fbFile) gt parseDateTime(this.timestamp) />
|
|---|
| 176 | <cfelse>
|
|---|
| 177 | <!---
|
|---|
| 178 | if we loaded the application and there is no fusebox.xml file,
|
|---|
| 179 | then we must have loaded an implicit fusebox.xml file so there
|
|---|
| 180 | is no need to reload it again because an implicit file can't change!
|
|---|
| 181 | --->
|
|---|
| 182 | <cfset needToLoad = false />
|
|---|
| 183 | </cfif>
|
|---|
| 184 | </cfif>
|
|---|
| 185 |
|
|---|
| 186 | <cfif needToLoad>
|
|---|
| 187 |
|
|---|
| 188 | <cfif this.debug>
|
|---|
| 189 | <cfset arguments.myFusebox.trace("Compiler","Loading fusebox.xml file") />
|
|---|
| 190 | </cfif>
|
|---|
| 191 |
|
|---|
| 192 | <!--- attempt to load fusebox.xml(.cfm): --->
|
|---|
| 193 | <cfif fbFileExists>
|
|---|
| 194 | <cftry>
|
|---|
| 195 |
|
|---|
| 196 | <cffile action="read" file="#this.approotdirectory##fbFile#"
|
|---|
| 197 | variable="fbXML"
|
|---|
| 198 | charset="#this.characterEncoding#" />
|
|---|
| 199 |
|
|---|
| 200 | <cfset variables.fuseboxFileExtension = listLast(fbFile,".") />
|
|---|
| 201 | <cfset fbXML = this.approotdirectory & fbFile />
|
|---|
| 202 | <cfcatch type="security">
|
|---|
| 203 | <!--- cffile denied by sandbox security --->
|
|---|
| 204 | <cfthrow type="fusebox.security"
|
|---|
| 205 | message="security error reading fusebox.xml"
|
|---|
| 206 | detail="The file '#fbFile#' in the directory #this.approotdirectory# could not be read because sandbox security has disabled the cffile tag."
|
|---|
| 207 | extendedinfo="#cfcatch.detail#" />
|
|---|
| 208 | </cfcatch>
|
|---|
| 209 |
|
|---|
| 210 | <cfcatch type="any">
|
|---|
| 211 | <!--- the file exists but we cannot read it --->
|
|---|
| 212 | <cfthrow type="fusebox.missingFuseboxXML"
|
|---|
| 213 | message="missing fusebox.xml"
|
|---|
| 214 | detail="The file '#fbFile#' in the directory #this.approotdirectory# could not be read."
|
|---|
| 215 | extendedinfo="#cfcatch.detail#" />
|
|---|
| 216 | </cfcatch>
|
|---|
| 217 |
|
|---|
| 218 | </cftry>
|
|---|
| 219 |
|
|---|
| 220 | <cfelse>
|
|---|
| 221 |
|
|---|
| 222 | <cfif this.allowImplicitFusebox>
|
|---|
| 223 |
|
|---|
| 224 | <cfif this.debug>
|
|---|
| 225 | <cfset arguments.myFusebox.trace("Compiler","Implicit fusebox.xml(.cfm) identified") />
|
|---|
| 226 | </cfif>
|
|---|
| 227 | <cfset fbXML = "<fusebox/>" />
|
|---|
| 228 | <!--- if the fusebox.xml file is missing there are no circuit declarations: --->
|
|---|
| 229 | <cfset this.allowImplicitCircuits = true />
|
|---|
| 230 |
|
|---|
| 231 | <cfelse>
|
|---|
| 232 |
|
|---|
| 233 | <cfthrow type="fusebox.missingFuseboxXML"
|
|---|
| 234 | message="missing fusebox.xml"
|
|---|
| 235 | detail="The file '#fbFile#' could not be found in the directory #this.approotdirectory#." />
|
|---|
| 236 |
|
|---|
| 237 | </cfif>
|
|---|
| 238 |
|
|---|
| 239 | </cfif>
|
|---|
| 240 |
|
|---|
| 241 | <cftry>
|
|---|
| 242 |
|
|---|
| 243 | <cfset fbCode = xmlParse(fbXML) />
|
|---|
| 244 |
|
|---|
| 245 | <!--- see if we need to re-read based on the encoding being different to our default --->
|
|---|
| 246 | <cfset encodings = xmlSearch(fbCode,"/fusebox/parameters/parameter[@name='characterEncoding']") />
|
|---|
| 247 | <cfif arrayLen(encodings) eq 1 and structKeyExists(encodings[1].xmlAttributes,"value")>
|
|---|
| 248 | <cfif encodings[1].xmlAttributes.value is not this.characterEncoding>
|
|---|
| 249 | <cfset this.characterEncoding = encodings[1].xmlAttributes.value />
|
|---|
| 250 | <!--- now re-read the file in case anything is changed in that new encoding --->
|
|---|
| 251 | <cffile action="read" file="#this.approotdirectory##fbFile#"
|
|---|
| 252 | variable="fbXML"
|
|---|
| 253 | charset="#this.characterEncoding#" />
|
|---|
| 254 | <cfset fbCode = xmlParse(fbXML) />
|
|---|
| 255 | </cfif>
|
|---|
| 256 | </cfif>
|
|---|
| 257 |
|
|---|
| 258 | <cfcatch type="any">
|
|---|
| 259 | <cfthrow type="fusebox.fuseboxXMLError"
|
|---|
| 260 | message="Error reading fusebox.xml"
|
|---|
| 261 | detail="A problem was encountered while reading the #fbFile# file. This is usually caused by unmatched XML tags (a <tag> without a </tag> or without use of the <tag/> short-cut.)"
|
|---|
| 262 | extendedinfo="#cfcatch.detail#" />
|
|---|
| 263 | </cfcatch>
|
|---|
| 264 |
|
|---|
| 265 | </cftry>
|
|---|
| 266 |
|
|---|
| 267 | <cfif fbCode.xmlRoot.xmlName is not "fusebox">
|
|---|
| 268 | <cfthrow type="fusebox.badGrammar.badFuseboxFile"
|
|---|
| 269 | detail="Fusebox file does contain 'fusebox' XML"
|
|---|
| 270 | message="Fusebox file #fbFile# does not contain 'fusebox' as the root XML node." />
|
|---|
| 271 | </cfif>
|
|---|
| 272 |
|
|---|
| 273 | <cfset loadParameters(fbCode) />
|
|---|
| 274 |
|
|---|
| 275 | <!--- FB55: can override fusebox.xml parameters programmatically --->
|
|---|
| 276 | <cfloop collection="#arguments.appParameters#" item="p">
|
|---|
| 277 | <cfset this[p] = arguments.appParameters[p] />
|
|---|
| 278 | </cfloop>
|
|---|
| 279 | <cfif structKeyExists(this,"allowImplicitFusebox") and this.allowImplicitFusebox>
|
|---|
| 280 | <cfset this.allowImplicitCircuits = true />
|
|---|
| 281 | </cfif>
|
|---|
| 282 |
|
|---|
| 283 | <!---
|
|---|
| 284 | if the user overrides certain path variables, we need to normalize them:
|
|---|
| 285 | - this.parsePath (reset parseRootPath)
|
|---|
| 286 | - this.pluginsPath
|
|---|
| 287 | - this.lexiconPath
|
|---|
| 288 | - this.errortemplatesPath
|
|---|
| 289 | normalizing means changing all \ to / and appending / if not present
|
|---|
| 290 | --->
|
|---|
| 291 | <cfset this.parsePath = normalizePartialPath(this.parsePath) />
|
|---|
| 292 | <cfset this.parseRootPath = relativePath(expandFuseboxPath(this.parsePath),getApplicationRoot()) />
|
|---|
| 293 | <cfset this.pluginsPath = normalizePartialPath(this.pluginsPath) />
|
|---|
| 294 | <cfset this.lexiconPath = normalizePartialPath(this.lexiconPath) />
|
|---|
| 295 | <cfset this.errortemplatesPath = normalizePartialPath(this.errortemplatesPath) />
|
|---|
| 296 |
|
|---|
| 297 | <!--- Fusebox 5.1: default this.myself: --->
|
|---|
| 298 | <cfif not structKeyExists(this,"myself")>
|
|---|
| 299 | <cfset this.myself = getDefaultMyself(this.self) />
|
|---|
| 300 | </cfif>
|
|---|
| 301 |
|
|---|
| 302 | <cfset loadLexicons(fbCode) />
|
|---|
| 303 | <cfset loadClasses(fbCode) />
|
|---|
| 304 | <cfset loadPlugins(fbCode) />
|
|---|
| 305 | <cfset loadGlobalPreAndPostProcess(fbCode) />
|
|---|
| 306 | <!--- save fusebox.xml DOM internally for (re-)loading circuits --->
|
|---|
| 307 | <cfset variables.fbCode = fbCode />
|
|---|
| 308 | <cfset variables.fbFile = fbFile />
|
|---|
| 309 | <cfset this.timestamp = now() />
|
|---|
| 310 | </cfif>
|
|---|
| 311 |
|
|---|
| 312 | <!--- to track circuit loads on this request --->
|
|---|
| 313 | <cfparam name="request.__fusebox.CircuitsLoaded" default="#structNew()#" />
|
|---|
| 314 | <cfset loadCircuits(variables.fbCode,arguments.myFusebox) />
|
|---|
| 315 |
|
|---|
| 316 | <!--- FB5: fusebox.loadclean will delete all the parsed files --->
|
|---|
| 317 | <cfif arguments.myFusebox.parameters.clean>
|
|---|
| 318 | <cfset deleteParsedFiles() />
|
|---|
| 319 | </cfif>
|
|---|
| 320 |
|
|---|
| 321 | <!--- application data available to developers via getApplicationData() method: --->
|
|---|
| 322 | <cfset variables.data = structNew() />
|
|---|
| 323 |
|
|---|
| 324 | <cfset this.isFullyLoaded = true />
|
|---|
| 325 | <cfset this.applicationStarted = false />
|
|---|
| 326 | <cfset this.dateLastLoaded = now() />
|
|---|
| 327 |
|
|---|
| 328 | <!---
|
|---|
| 329 | The following documented parts of application.fusebox are not supported in Fusebox 5:
|
|---|
| 330 | - application.fusebox.xml
|
|---|
| 331 | - application.fusebox.globalfuseactions.*
|
|---|
| 332 | - application.fusebox.circuits.*.xml
|
|---|
| 333 | - application.fusebox.circuits.preFuseaction.*
|
|---|
| 334 | - application.fusebox.circuits.postFuseaction.*
|
|---|
| 335 | - application.fusebox.circuits.*.fuseactions.*.xml
|
|---|
| 336 | --->
|
|---|
| 337 |
|
|---|
| 338 | </cffunction>
|
|---|
| 339 |
|
|---|
| 340 | <cffunction name="getPluginsPath" returntype="string" access="public" output="false"
|
|---|
| 341 | hint="I am a convenience method to return the location of the plugins.">
|
|---|
| 342 |
|
|---|
| 343 | <cfreturn this.pluginsPath />
|
|---|
| 344 |
|
|---|
| 345 | </cffunction>
|
|---|
| 346 |
|
|---|
| 347 | <!--- FB55: exposes this directly in myFusebox for convenience --->
|
|---|
| 348 | <cffunction name="getApplicationData" returntype="struct" access="public" output="false"
|
|---|
| 349 | hint="I return a reference to the application data cache. This is a new concept in Fusebox 5.">
|
|---|
| 350 |
|
|---|
| 351 | <cfreturn variables.data />
|
|---|
| 352 |
|
|---|
| 353 | </cffunction>
|
|---|
| 354 |
|
|---|
| 355 | <cffunction name="getApplicationRoot" returntype="any" access="public" output="false"
|
|---|
| 356 | hint="I am a convenience method to return the full application root directory path.">
|
|---|
| 357 |
|
|---|
| 358 | <cfreturn this.approotdirectory />
|
|---|
| 359 |
|
|---|
| 360 | </cffunction>
|
|---|
| 361 |
|
|---|
| 362 | <cffunction name="expandFuseboxPath" returntype="any" access="public" output="false"
|
|---|
| 363 | hint="I expand a path in the context of a Fusebox application.">
|
|---|
| 364 | <cfargument name="partialPath" type="any" required="true"
|
|---|
| 365 | hint="I am the partial path to expand. If I do not begin with a /, prepend the Fusebox application root." />
|
|---|
| 366 |
|
|---|
| 367 | <cfif left(arguments.partialPath,1) is "/">
|
|---|
| 368 | <!--- absolute path, i.e., root-relative or mapped --->
|
|---|
| 369 | <cfreturn replace(expandPath(arguments.partialPath),"\","/","all") />
|
|---|
| 370 | <cfelse>
|
|---|
| 371 | <!--- relative, i.e., relative to the Fusebox application root --->
|
|---|
| 372 | <cfreturn getApplicationRoot() & arguments.partialPath />
|
|---|
| 373 | </cfif>
|
|---|
| 374 |
|
|---|
| 375 | </cffunction>
|
|---|
| 376 |
|
|---|
| 377 | <cffunction name="getFuseboxXMLFilename" returntype="string" access="public" output="false"
|
|---|
| 378 | hint="I return the actual name of the fusebox.xml(.cfm) file.">
|
|---|
| 379 |
|
|---|
| 380 | <cfreturn variables.fbFile />
|
|---|
| 381 |
|
|---|
| 382 | </cffunction>
|
|---|
| 383 |
|
|---|
| 384 | <cffunction name="getCoreToAppRootPath" returntype="any" access="public" output="false"
|
|---|
| 385 | hint="I am a convenience method to return the relative path from the core files to the application root.">
|
|---|
| 386 |
|
|---|
| 387 | <cfreturn this.coreToAppRootPath />
|
|---|
| 388 |
|
|---|
| 389 | </cffunction>
|
|---|
| 390 |
|
|---|
| 391 | <cffunction name="compileAll" returntype="void" access="public" output="false"
|
|---|
| 392 | hint="I compile all the public fuseactions in the application.">
|
|---|
| 393 | <cfargument name="myFusebox" type="myFusebox" required="true"
|
|---|
| 394 | hint="I am the myFusebox data structure." />
|
|---|
| 395 |
|
|---|
| 396 | <cfset var c = 0 />
|
|---|
| 397 | <cfset var a = 0 />
|
|---|
| 398 | <cfset var f = 0 />
|
|---|
| 399 |
|
|---|
| 400 | <cfloop collection="#this.circuits#" item="c">
|
|---|
| 401 | <cfset a = this.circuits[c].getFuseactions() />
|
|---|
| 402 | <cfloop collection="#a#" item="f">
|
|---|
| 403 | <cfif a[f].access is "public">
|
|---|
| 404 | <cfset compileRequest(c & "." & f,arguments.myFusebox) />
|
|---|
| 405 | </cfif>
|
|---|
| 406 | </cfloop>
|
|---|
| 407 | </cfloop>
|
|---|
| 408 |
|
|---|
| 409 | </cffunction>
|
|---|
| 410 |
|
|---|
| 411 | <cffunction name="compileRequest" returntype="struct" access="public" output="false"
|
|---|
| 412 | hint="I compile a specific (public) fuseaction as an external request.">
|
|---|
| 413 | <cfargument name="circuitFuseaction" type="string" required="true"
|
|---|
| 414 | hint="I am the full name of the requested fuseaction (circuit.fuseaction)." />
|
|---|
| 415 | <cfargument name="myFusebox" type="myFusebox" required="true"
|
|---|
| 416 | hint="I am the myFusebox data structure." />
|
|---|
| 417 |
|
|---|
| 418 | <cfset var myVersion = getVersion() />
|
|---|
| 419 | <cfset var circuit = "" />
|
|---|
| 420 | <cfset var fuseaction = listLast(arguments.circuitFuseaction,".") />
|
|---|
| 421 | <cfset var i = 0 />
|
|---|
| 422 | <cfset var n = 0 />
|
|---|
| 423 | <cfset var needRethrow = true />
|
|---|
| 424 | <cfset var needTryOnFuseaction = false />
|
|---|
| 425 | <cfset var parsedName = "#lCase(arguments.circuitFuseaction)#.cfm" />
|
|---|
| 426 | <cfset var parsedFile = "#this.parsePath##parsedName#" />
|
|---|
| 427 | <cfset var fullParsedFile = "#this.expandFuseboxPath(this.parsePath)##parsedName#" />
|
|---|
| 428 | <cfset var result = structNew() />
|
|---|
| 429 | <cfset var writer = 0 />
|
|---|
| 430 |
|
|---|
| 431 | <!--- to track reloads on this request --->
|
|---|
| 432 | <cfparam name="request.__fusebox.CircuitsLoaded" default="#structNew()#" />
|
|---|
| 433 | <cfparam name="request.__fusebox.fuseactionsDone" default="#structNew()#" />
|
|---|
| 434 |
|
|---|
| 435 | <!--- note that in Fusebox 5, these are really all the same set of files --->
|
|---|
| 436 | <cfset arguments.myFusebox.version.loader = myVersion />
|
|---|
| 437 | <cfset arguments.myFusebox.version.parser = myVersion />
|
|---|
| 438 | <cfset arguments.myFusebox.version.transformer = myVersion />
|
|---|
| 439 | <!--- legacy test from FB41 although it's a bit pointless --->
|
|---|
| 440 | <cfif myFusebox.version.runtime neq myFusebox.version.loader>
|
|---|
| 441 | <cfthrow type="fusebox.versionMismatchException"
|
|---|
| 442 | message="The loader is not the same version as the runtime" />
|
|---|
| 443 | </cfif>
|
|---|
| 444 |
|
|---|
| 445 | <!--- validate format of the fuseaction: --->
|
|---|
| 446 | <cfif listLen(arguments.circuitFuseaction,".") lt 2>
|
|---|
| 447 | <cfthrow type="fusebox.malformedFuseaction"
|
|---|
| 448 | message="malformed Fuseaction"
|
|---|
| 449 | detail="You specified a malformed Fuseaction of #arguments.circuitFuseaction#. A fully qualified Fuseaction must be in the form [Circuit].[Fuseaction]." />
|
|---|
| 450 | </cfif>
|
|---|
| 451 |
|
|---|
| 452 | <cfset circuit = left(arguments.circuitFuseaction,len(arguments.circuitFuseaction)-len(fuseaction)-1) />
|
|---|
| 453 |
|
|---|
| 454 | <!--- set up myFusebox values for this request: --->
|
|---|
| 455 | <cfset arguments.myFusebox.originalCircuit = circuit />
|
|---|
| 456 | <cfset arguments.myFusebox.originalFuseaction = fuseaction />
|
|---|
| 457 | <cfloop collection="#this.plugins#" item="i">
|
|---|
| 458 | <cfset arguments.myFusebox.plugins[i] = structNew() />
|
|---|
| 459 | </cfloop>
|
|---|
| 460 |
|
|---|
| 461 | <!--- ticket 293 - prevent dynamic do() from executing until prerequisites complete --->
|
|---|
| 462 | <cfset request.__fusebox.dynamicDoOK = true />
|
|---|
| 463 |
|
|---|
| 464 | <!--- check access on request - if the circuit/fuseaction doesn't exist we trap it later --->
|
|---|
| 465 | <cfif structKeyExists(this.circuits,circuit) and
|
|---|
| 466 | structKeyExists(this.circuits[circuit].fuseactions,fuseaction) and
|
|---|
| 467 | this.circuits[circuit].fuseactions[fuseaction].getAccess() is not "public">
|
|---|
| 468 | <cfthrow type="fusebox.invalidAccessModifier"
|
|---|
| 469 | message="Invalid Access Modifier"
|
|---|
| 470 | detail="You tried to access #circuit#.#fuseaction# which does not have access modifier of public. A Fuseaction which is to be accessed from anywhere outside the application (such as called via an URL, or a FORM, or as a web service) must have an access modifier of public or if unspecified at least inherit such a modifier from its circuit.">
|
|---|
| 471 | </cfif>
|
|---|
| 472 |
|
|---|
| 473 | <cfif not fileExists(fullParsedFile) or arguments.myFusebox.parameters.parse>
|
|---|
| 474 | <cflock name="#fullParsedFile#" type="exclusive" timeout="300">
|
|---|
| 475 | <cfif not fileExists(fullParsedFile) or arguments.myFusebox.parameters.parse>
|
|---|
| 476 | <cfset request.__fusebox.SuppressPlugins = false />
|
|---|
| 477 | <cfset writer = createObject("component","fuseboxWriter").init(this,arguments.myFusebox) />
|
|---|
| 478 | <cfset writer.open(parsedName) />
|
|---|
| 479 | <cfset writer.rawPrintln("<!--- circuit: #circuit# --->") />
|
|---|
| 480 | <cfset writer.rawPrintln("<!--- fuseaction: #fuseaction# --->") />
|
|---|
| 481 | <cfset writer.rawPrintln("<cftry>") />
|
|---|
| 482 | <cfset writer.setCircuit(circuit) />
|
|---|
| 483 | <cfset writer.setFuseaction(fuseaction) />
|
|---|
| 484 | <cfif variables.hasProcess["appinit"]>
|
|---|
| 485 | <cfset writer.setPhase("appinit") />
|
|---|
| 486 | <cfset writer.println("<cfif myFusebox.applicationStart or") />
|
|---|
| 487 | <cfset writer.println(' not myFusebox.getApplication().applicationStarted>') />
|
|---|
| 488 | <cfset writer.println(' <cflock name="##application.ApplicationName##_fusebox_##FUSEBOX_APPLICATION_KEY##_appinit" type="exclusive" timeout="30">') />
|
|---|
| 489 | <cfset writer.println(' <cfif not myFusebox.getApplication().applicationStarted>') />
|
|---|
| 490 | <cfset request.__fusebox.SuppressPlugins = true />
|
|---|
| 491 | <cfset variables.process["appinit"].compile(writer) />
|
|---|
| 492 | <cfset writer.println(' <cfset myFusebox.getApplication().applicationStarted = true />') />
|
|---|
| 493 | <cfset writer.println(' </cfif>') />
|
|---|
| 494 | <cfset writer.println(' </cflock>') />
|
|---|
| 495 | <cfset writer.println('</cfif>') />
|
|---|
| 496 | </cfif>
|
|---|
| 497 | <cfset request.__fusebox.SuppressPlugins = false />
|
|---|
| 498 | <cfif structKeyExists(this.pluginPhases,"preProcess")>
|
|---|
| 499 | <cfset n = arrayLen(this.pluginPhases["preProcess"]) />
|
|---|
| 500 | <cfloop from="1" to="#n#" index="i">
|
|---|
| 501 | <cfset this.pluginPhases["preProcess"][i].compile(writer) />
|
|---|
| 502 | </cfloop>
|
|---|
| 503 | </cfif>
|
|---|
| 504 | <cfset writer.setPhase("preprocessFuseactions") />
|
|---|
| 505 | <cfif variables.hasProcess["preprocess"]>
|
|---|
| 506 | <cfset variables.process["preprocess"].compile(writer) />
|
|---|
| 507 | </cfif>
|
|---|
| 508 | <cfif structKeyExists(this.pluginPhases,"fuseactionException") and
|
|---|
| 509 | arrayLen(this.pluginPhases["fuseactionException"]) gt 0 and
|
|---|
| 510 | not request.__fusebox.SuppressPlugins>
|
|---|
| 511 | <cfset needTryOnFuseaction = true />
|
|---|
| 512 | <cfset writer.rawPrintln("<cftry>") />
|
|---|
| 513 | </cfif>
|
|---|
| 514 | <cfif structKeyExists(this.pluginPhases,"preFuseaction")>
|
|---|
| 515 | <cfset n = arrayLen(this.pluginPhases["preFuseaction"]) />
|
|---|
| 516 | <cfloop from="1" to="#n#" index="i">
|
|---|
| 517 | <cfset this.pluginPhases["preFuseaction"][i].compile(writer) />
|
|---|
| 518 | </cfloop>
|
|---|
| 519 | </cfif>
|
|---|
| 520 | <cfset writer.setPhase("requestedFuseaction") />
|
|---|
| 521 | <cfset compile(writer,circuit,fuseaction,true) />
|
|---|
| 522 | <cfif structKeyExists(this.pluginPhases,"postFuseaction")>
|
|---|
| 523 | <cfset n = arrayLen(this.pluginPhases["postFuseaction"]) />
|
|---|
| 524 | <cfloop from="1" to="#n#" index="i">
|
|---|
| 525 | <cfset this.pluginPhases["postFuseaction"][i].compile(writer) />
|
|---|
| 526 | </cfloop>
|
|---|
| 527 | </cfif>
|
|---|
| 528 | <cfif needTryOnFuseaction>
|
|---|
| 529 | <cfset n = arrayLen(this.pluginPhases["fuseactionException"]) />
|
|---|
| 530 | <cfloop from="1" to="#n#" index="i">
|
|---|
| 531 | <cfset this.pluginPhases["fuseactionException"][i].compile(writer) />
|
|---|
| 532 | </cfloop>
|
|---|
| 533 | <cfset writer.rawPrintln("</cftry>") />
|
|---|
| 534 | </cfif>
|
|---|
| 535 | <cfset writer.setPhase("postprocessFuseactions") />
|
|---|
| 536 | <cfif variables.hasProcess["postprocess"]>
|
|---|
| 537 | <cfset variables.process["postprocess"].compile(writer) />
|
|---|
| 538 | </cfif>
|
|---|
| 539 | <cfif structKeyExists(this.pluginPhases,"postProcess")>
|
|---|
| 540 | <cfset n = arrayLen(this.pluginPhases["postProcess"]) />
|
|---|
| 541 | <cfloop from="1" to="#n#" index="i">
|
|---|
| 542 | <cfset this.pluginPhases["postProcess"][i].compile(writer) />
|
|---|
| 543 | </cfloop>
|
|---|
| 544 | </cfif>
|
|---|
| 545 | <cfif structKeyExists(this.pluginPhases,"processError") and
|
|---|
| 546 | not request.__fusebox.SuppressPlugins>
|
|---|
| 547 | <cfset n = arrayLen(this.pluginPhases["processError"]) />
|
|---|
| 548 | <cfloop from="1" to="#n#" index="i">
|
|---|
| 549 | <cfset needRethrow = false />
|
|---|
| 550 | <cfset this.pluginPhases["processError"][i].compile(writer) />
|
|---|
| 551 | </cfloop>
|
|---|
| 552 | </cfif>
|
|---|
| 553 | <cfif needRethrow>
|
|---|
| 554 | <cfset writer.rawPrintln('<' & 'cfcatch><' & 'cfrethrow><' & '/cfcatch>') />
|
|---|
| 555 | </cfif>
|
|---|
| 556 | <cfset writer.rawPrintln("</cftry>") />
|
|---|
| 557 | <cfset writer.close(variables.parsedFileCache) />
|
|---|
| 558 | </cfif>
|
|---|
| 559 | </cflock>
|
|---|
| 560 | </cfif>
|
|---|
| 561 |
|
|---|
| 562 | <cfset result.parsedName = parsedName />
|
|---|
| 563 | <cfif left(parsedFile,1) is "/">
|
|---|
| 564 | <cfset result.parsedFile = parsedFile />
|
|---|
| 565 | <cfelse>
|
|---|
| 566 | <cfset result.parsedFile = this.getCoreToAppRootPath() & parsedFile />
|
|---|
| 567 | </cfif>
|
|---|
| 568 | <cfset result.lockName = fullParsedFile />
|
|---|
| 569 |
|
|---|
| 570 | <cfreturn result />
|
|---|
| 571 |
|
|---|
| 572 | </cffunction>
|
|---|
| 573 |
|
|---|
| 574 | <cffunction name="do" returntype="string" access="public" output="true"
|
|---|
| 575 | hint="I compile and execute a specific fuseaction.">
|
|---|
| 576 | <cfargument name="circuitFuseaction" type="string" required="true"
|
|---|
| 577 | hint="I am the full name of the requested fuseaction (circuit.fuseaction)." />
|
|---|
| 578 | <cfargument name="myFusebox" type="myFusebox" required="true"
|
|---|
| 579 | hint="I am the myFusebox data structure." />
|
|---|
| 580 | <cfargument name="returnOutput" type="boolean" required="true"
|
|---|
| 581 | hint="I indicate whether to display output (false) or return the output (true)." />
|
|---|
| 582 |
|
|---|
| 583 | <cfset var parsedFileInfo = 0 />
|
|---|
| 584 | <cfset var output = "" />
|
|---|
| 585 | <cfset var circuit = "" />
|
|---|
| 586 | <cfset var fuseaction = "" />
|
|---|
| 587 |
|
|---|
| 588 | <!--- ticket 293 - prevent dynamic do() from executing until prerequisites complete --->
|
|---|
| 589 | <cfif not structKeyExists(request,"__fusebox") or
|
|---|
| 590 | not structKeyExists(request.__fusebox,"dynamicDoOK") or
|
|---|
| 591 | not request.__fusebox.dynamicDoOK>
|
|---|
| 592 | <cfif structKeyExists(arguments.myFusebox,"originalCircuit") and
|
|---|
| 593 | structKeyExists(arguments.myFusebox,"originalFuseaction")>
|
|---|
| 594 | <cfset output = output & " while executing " & arguments.myFusebox.originalCircuit &
|
|---|
| 595 | "." & arguments.myFusebox.originalFuseaction />
|
|---|
| 596 | </cfif>
|
|---|
| 597 | <cfthrow type="fusebox.dynamicDoNotAllowed" message="dynamic 'do' not allowed"
|
|---|
| 598 | detail="This request did not reach the state where dynamic 'do' is possible#output#." />
|
|---|
| 599 | </cfif>
|
|---|
| 600 |
|
|---|
| 601 | <!--- allow for abbreviated circuitFuseaction form: --->
|
|---|
| 602 | <cfif listLen(arguments.circuitFuseaction,".") lt 2>
|
|---|
| 603 | <cfset arguments.circuitFuseaction = arguments.myFusebox.thisCircuit & "." & arguments.circuitFuseaction />
|
|---|
| 604 | <cfelse>
|
|---|
| 605 | <cfset circuit = listFirst(arguments.circuitFuseaction,".") />
|
|---|
| 606 | <cfif circuit is not arguments.myFusebox.thisCircuit>
|
|---|
| 607 | <!--- different circuit, check access is not private (implicit fuseactions cannot be private) --->
|
|---|
| 608 | <cfset fuseaction = listRest(arguments.circuitFuseaction,".") />
|
|---|
| 609 | <cfif structKeyExists(this.circuits,circuit) and
|
|---|
| 610 | structKeyExists(this.circuits[circuit].fuseactions,fuseaction) and
|
|---|
| 611 | this.circuits[circuit].fuseactions[fuseaction].getAccess() is "private">
|
|---|
| 612 | <cfthrow type="fusebox.invalidAccessModifier"
|
|---|
| 613 | message="invalid access modifier"
|
|---|
| 614 | detail="The fuseaction '#circuit#.#fuseaction#' has an access modifier of private and can only be called from within its own circuit. Use an access modifier of internal or public to make it available outside its immediate circuit." />
|
|---|
| 615 | </cfif>
|
|---|
| 616 | </cfif>
|
|---|
| 617 | </cfif>
|
|---|
| 618 |
|
|---|
| 619 | <cfset parsedFileInfo = compileDynamicDo(arguments.circuitFuseaction,arguments.myFusebox) />
|
|---|
| 620 |
|
|---|
| 621 | <cfif this.debug>
|
|---|
| 622 | <cfset arguments.myFusebox.trace("Runtime","<do action=""#arguments.circuitFuseaction#""/> -- dynamic") />
|
|---|
| 623 | </cfif>
|
|---|
| 624 | <cfinvoke component="fuseboxExecutionContext" method="__executeDynamicDo" returnvariable="output"
|
|---|
| 625 | parsedFileInfo="#parsedFileInfo#" myFusebox="#arguments.myFusebox#" returnOutput="#arguments.returnOutput#" />
|
|---|
| 626 |
|
|---|
| 627 | <cfreturn output />
|
|---|
| 628 |
|
|---|
| 629 | </cffunction>
|
|---|
| 630 |
|
|---|
| 631 | <cffunction name="compileDynamicDo" returntype="struct" access="private" output="false"
|
|---|
| 632 | hint="I compile a specific fuseaction as a dynamic request.">
|
|---|
| 633 | <cfargument name="circuitFuseaction" type="string" required="true"
|
|---|
| 634 | hint="I am the full name of the requested fuseaction (circuit.fuseaction)." />
|
|---|
| 635 | <cfargument name="myFusebox" type="myFusebox" required="true"
|
|---|
| 636 | hint="I am the myFusebox data structure." />
|
|---|
| 637 |
|
|---|
| 638 | <cfset var circuit = "" />
|
|---|
| 639 | <cfset var fuseaction = listLast(arguments.circuitFuseaction,".") />
|
|---|
| 640 | <cfset var i = 0 />
|
|---|
| 641 | <cfset var n = 0 />
|
|---|
| 642 | <cfset var needTryOnFuseaction = false />
|
|---|
| 643 | <cfset var parsedName = "do.#lCase(arguments.circuitFuseaction)#.cfm" />
|
|---|
| 644 | <cfset var parsedFile = "#this.parsePath##parsedName#" />
|
|---|
| 645 | <cfset var fullParsedFile = "#this.expandFuseboxPath(this.parsePath)##parsedName#" />
|
|---|
| 646 | <cfset var result = structNew() />
|
|---|
| 647 | <cfset var writer = 0 />
|
|---|
| 648 |
|
|---|
| 649 | <!--- validate format of the fuseaction: --->
|
|---|
| 650 | <cfif listLen(arguments.circuitFuseaction,".") lt 2>
|
|---|
| 651 | <cfthrow type="fusebox.malformedFuseaction"
|
|---|
| 652 | message="malformed Fuseaction"
|
|---|
| 653 | detail="You specified a malformed Fuseaction of #arguments.circuitFuseaction#. A fully qualified Fuseaction must be in the form [Circuit].[Fuseaction]." />
|
|---|
| 654 | </cfif>
|
|---|
| 655 |
|
|---|
| 656 | <cfset circuit = left(arguments.circuitFuseaction,len(arguments.circuitFuseaction)-len(fuseaction)-1) />
|
|---|
| 657 |
|
|---|
| 658 | <cfif not fileExists(fullParsedFile) or arguments.myFusebox.parameters.parse>
|
|---|
| 659 | <cflock name="#fullParsedFile#" type="exclusive" timeout="300">
|
|---|
| 660 | <cfif not fileExists(fullParsedFile) or arguments.myFusebox.parameters.parse>
|
|---|
| 661 | <cfset writer = createObject("component","fuseboxWriter").init(this,arguments.myFusebox) />
|
|---|
| 662 | <cfset writer.open(parsedName) />
|
|---|
| 663 | <cfset writer.rawPrintln("<!--- circuit: #circuit# --->") />
|
|---|
| 664 | <cfset writer.rawPrintln("<!--- fuseaction: #fuseaction# --->") />
|
|---|
| 665 | <cfset writer.setCircuit(circuit) />
|
|---|
| 666 | <cfset writer.setFuseaction(fuseaction) />
|
|---|
| 667 | <cfif structKeyExists(this.pluginPhases,"fuseactionException") and
|
|---|
| 668 | arrayLen(this.pluginPhases["fuseactionException"]) gt 0 and
|
|---|
| 669 | not request.__fusebox.SuppressPlugins>
|
|---|
| 670 | <cfset needTryOnFuseaction = true />
|
|---|
| 671 | <cfset writer.rawPrintln("<cftry>") />
|
|---|
| 672 | </cfif>
|
|---|
| 673 | <cfif structKeyExists(this.pluginPhases,"preFuseaction")>
|
|---|
| 674 | <cfset n = arrayLen(this.pluginPhases["preFuseaction"]) />
|
|---|
| 675 | <cfloop from="1" to="#n#" index="i">
|
|---|
| 676 | <cfset this.pluginPhases["preFuseaction"][i].compile(writer) />
|
|---|
| 677 | </cfloop>
|
|---|
| 678 | </cfif>
|
|---|
| 679 | <cfset writer.setPhase("requestedFuseaction") />
|
|---|
| 680 | <cfset compile(writer,circuit,fuseaction) />
|
|---|
| 681 | <cfif structKeyExists(this.pluginPhases,"postFuseaction")>
|
|---|
| 682 | <cfset n = arrayLen(this.pluginPhases["postFuseaction"]) />
|
|---|
| 683 | <cfloop from="1" to="#n#" index="i">
|
|---|
| 684 | <cfset this.pluginPhases["postFuseaction"][i].compile(writer) />
|
|---|
| 685 | </cfloop>
|
|---|
| 686 | </cfif>
|
|---|
| 687 | <cfif needTryOnFuseaction>
|
|---|
| 688 | <cfset n = arrayLen(this.pluginPhases["fuseactionException"]) />
|
|---|
| 689 | <cfloop from="1" to="#n#" index="i">
|
|---|
| 690 | <cfset this.pluginPhases["fuseactionException"][i].compile(writer) />
|
|---|
| 691 | </cfloop>
|
|---|
| 692 | <cfset writer.rawPrintln("</cftry>") />
|
|---|
| 693 | </cfif>
|
|---|
| 694 | <cfset writer.close(variables.parsedFileCache) />
|
|---|
| 695 | </cfif>
|
|---|
| 696 | </cflock>
|
|---|
| 697 | </cfif>
|
|---|
| 698 |
|
|---|
| 699 | <cfset result.parsedName = parsedName />
|
|---|
| 700 | <cfif left(parsedFile,1) is "/">
|
|---|
| 701 | <cfset result.parsedFile = parsedFile />
|
|---|
| 702 | <cfelse>
|
|---|
| 703 | <cfset result.parsedFile = this.getCoreToAppRootPath() & parsedFile />
|
|---|
| 704 | </cfif>
|
|---|
| 705 | <cfset result.lockName = fullParsedFile />
|
|---|
| 706 |
|
|---|
| 707 | <cfreturn result />
|
|---|
| 708 |
|
|---|
| 709 | </cffunction>
|
|---|
| 710 |
|
|---|
| 711 | <cffunction name="compile" returntype="void" access="public" output="false"
|
|---|
| 712 | hint="I compile a specific fuseaction during a request (such as for a 'do' verb).">
|
|---|
| 713 | <cfargument name="writer" type="any" required="false"
|
|---|
| 714 | hint="I am the parsed file writer object. I am required but it's faster to specify that I am not required." />
|
|---|
| 715 | <cfargument name="circuit" type="any" required="false"
|
|---|
| 716 | hint="I am the circuit name. I am required but it's faster to specify that I am not required." />
|
|---|
| 717 | <cfargument name="fuseaction" type="any" required="false"
|
|---|
| 718 | hint="I am the fuseaction name, within the specified circuit." />
|
|---|
| 719 | <cfargument name="topLevel" type="boolean" default="false"
|
|---|
| 720 | hint="I specify whether or not this is a top-level (public) request." />
|
|---|
| 721 |
|
|---|
| 722 | <cfset var c = "" />
|
|---|
| 723 |
|
|---|
| 724 | <cfif not structKeyExists(this.circuits,arguments.circuit)>
|
|---|
| 725 | <cfif this.allowImplicitCircuits>
|
|---|
| 726 | <!--- FB55: attempt to create an implicit circuit --->
|
|---|
| 727 | <cfset this.circuits[arguments.circuit] =
|
|---|
| 728 | createObject("component","fuseboxImplicitCircuit")
|
|---|
| 729 | .init(this,arguments.circuit,arguments.writer.getMyFusebox()) />
|
|---|
| 730 | <!--- still need to check access here! --->
|
|---|
| 731 | <cfif arguments.writer.getMyFusebox().thisCircuit is not arguments.circuit and
|
|---|
| 732 | structKeyExists(this.circuits[circuit].fuseactions,arguments.fuseaction) and
|
|---|
| 733 | this.circuits[circuit].fuseactions[fuseaction].getAccess() is "private">
|
|---|
| 734 | <cfthrow type="fusebox.invalidAccessModifier"
|
|---|
| 735 | message="invalid access modifier"
|
|---|
| 736 | detail="The fuseaction '#arguments.circuit#.#arguments.fuseaction#' has an access modifier of private and can only be called from within its own circuit. Use an access modifier of internal or public to make it available outside its immediate circuit." />
|
|---|
| 737 | </cfif>
|
|---|
| 738 | <cfelse>
|
|---|
| 739 | <cfthrow type="fusebox.undefinedCircuit"
|
|---|
| 740 | message="undefined Circuit"
|
|---|
| 741 | detail="You specified a Circuit of #arguments.circuit# which is not defined." />
|
|---|
| 742 | </cfif>
|
|---|
| 743 | </cfif>
|
|---|
| 744 | <!--- FB5: development-circuit-load only reloads the requested circuit --->
|
|---|
| 745 | <cfif this.mode is "development-circuit-load">
|
|---|
| 746 | <!--- FB5: ensure we only reload each circuit once per request --->
|
|---|
| 747 | <cfif not structKeyExists(request.__fusebox.CircuitsLoaded,arguments.circuit)>
|
|---|
| 748 | <cfset request.__fusebox.CircuitsLoaded[arguments.circuit] = true />
|
|---|
| 749 | <cfset this.circuits[arguments.circuit].reload(arguments.writer.getMyFusebox()) />
|
|---|
| 750 | </cfif>
|
|---|
| 751 | </cfif>
|
|---|
| 752 |
|
|---|
| 753 | <cfset c = arguments.writer.setCircuit(arguments.circuit) />
|
|---|
| 754 | <cfset this.circuits[arguments.circuit]
|
|---|
| 755 | .compile(arguments.writer,arguments.fuseaction,arguments.topLevel) />
|
|---|
| 756 | <cfset arguments.writer.setCircuit(c) />
|
|---|
| 757 |
|
|---|
| 758 | </cffunction>
|
|---|
| 759 |
|
|---|
| 760 | <cffunction name="handleFuseboxException" returntype="boolean" access="public" output="true"
|
|---|
| 761 | hint="I attempt to handle a Fusebox exception by looking for a handler file in the errortemplates/ directory. I return true if I handle the exception, else I return false.">
|
|---|
| 762 | <cfargument name="cfcatch" type="any" required="true"
|
|---|
| 763 | hint="I am the original cfcatch structure from the exception that fusebox5.cfm caught." />
|
|---|
| 764 | <cfargument name="attributes" type="struct" required="true"
|
|---|
| 765 | hint="I am the attributes 'scope'." />
|
|---|
| 766 | <cfargument name="myFusebox" type="any" required="true"
|
|---|
| 767 | hint="I am the myFusebox object." />
|
|---|
| 768 | <cfargument name="appKey" type="string" required="true"
|
|---|
| 769 | hint="I am the application key object." />
|
|---|
| 770 |
|
|---|
| 771 | <cfset var __handled = false />
|
|---|
| 772 | <cfset var __type = arguments.cfcatch.type />
|
|---|
| 773 | <cfset var __ext = "." & this.scriptFileDelimiter />
|
|---|
| 774 | <cfset var __errorFile = this.errortemplatesPath & __type & __ext />
|
|---|
| 775 | <cfset var __handlerExists = fileExists(expandFuseboxPath(__errorFile)) />
|
|---|
| 776 | <cfset var FUSEBOX_APPLICATION_KEY = arguments.appKey />
|
|---|
| 777 |
|
|---|
| 778 | <cfloop condition="not __handlerExists and len(__type) gt 0">
|
|---|
| 779 | <cfset __type = listDeleteAt(__type,listLen(__type,"."),".") />
|
|---|
| 780 | <cfset __errorFile = this.errortemplatesPath & __type & __ext />
|
|---|
| 781 | <cfset __handlerExists = fileExists(expandFuseboxPath(__errorFile)) />
|
|---|
| 782 | </cfloop>
|
|---|
| 783 | <cfif __handlerExists>
|
|---|
| 784 | <cfif left(__errorFile,1) is "/">
|
|---|
| 785 | <cfinclude template="#__errorFile#" />
|
|---|
| 786 | <cfelse>
|
|---|
| 787 | <cfinclude template="#getCoreToAppRootPath()##__errorFile#" />
|
|---|
| 788 | </cfif>
|
|---|
| 789 | <cfset __handled = true />
|
|---|
| 790 | </cfif>
|
|---|
| 791 |
|
|---|
| 792 | <cfreturn __handled />
|
|---|
| 793 |
|
|---|
| 794 | </cffunction>
|
|---|
| 795 |
|
|---|
| 796 | <cffunction name="getFuseactionFactory" returntype="any" access="public" output="false"
|
|---|
| 797 | hint="I return the factory object that makes fuseaction objects for the framework.">
|
|---|
| 798 |
|
|---|
| 799 | <cfreturn variables.factory />
|
|---|
| 800 |
|
|---|
| 801 | </cffunction>
|
|---|
| 802 |
|
|---|
| 803 | <cffunction name="getClassDefinition" returntype="struct" access="public" output="false"
|
|---|
| 804 | hint="I return the class declaration for a given class. I throw an exception if the class has no declaration.">
|
|---|
| 805 | <cfargument name="className" type="string" required="true"
|
|---|
| 806 | hint="I am the name of the class whose declaration should be returned." />
|
|---|
| 807 |
|
|---|
| 808 | <cfreturn this.classes[arguments.className] />
|
|---|
| 809 |
|
|---|
| 810 | </cffunction>
|
|---|
| 811 |
|
|---|
| 812 | <cffunction name="getLexiconDefinition" returntype="any" access="public" output="false"
|
|---|
| 813 | hint="I return the lexicon definition for a given namespace. I return either the internal Fusebox lexicon or a declared (Fusebox 4.1 style) lexicon.">
|
|---|
| 814 | <cfargument name="namespace" type="any" required="false"
|
|---|
| 815 | hint="I am the namespace of the lexicon whose definition should be returned. I am required but it's faster to specify that I am not required." />
|
|---|
| 816 |
|
|---|
| 817 | <cfif arguments.namespace is variables.fuseboxLexicon.namespace>
|
|---|
| 818 | <cfreturn variables.fuseboxLexicon />
|
|---|
| 819 | <cfelse>
|
|---|
| 820 | <cfreturn variables.fb41Lexicons[arguments.namespace] />
|
|---|
| 821 | </cfif>
|
|---|
| 822 |
|
|---|
| 823 | </cffunction>
|
|---|
| 824 |
|
|---|
| 825 | <cffunction name="getVersion" returntype="string" access="public" output="false"
|
|---|
| 826 | hint="I return the version of this Fusebox 5 object. This is the preferred way to obtain the version in Fusebox 5.">
|
|---|
| 827 |
|
|---|
| 828 | <cfreturn variables.fuseboxVersion />
|
|---|
| 829 |
|
|---|
| 830 | </cffunction>
|
|---|
| 831 |
|
|---|
| 832 | <cffunction name="getAlias" returntype="any" access="public" output="false"
|
|---|
| 833 | hint="I return the fake circuit alias for the application.">
|
|---|
| 834 |
|
|---|
| 835 | <cfreturn "$fusebox" />
|
|---|
| 836 |
|
|---|
| 837 | </cffunction>
|
|---|
| 838 |
|
|---|
| 839 | <cffunction name="getApplication" returntype="any" access="public" output="false"
|
|---|
| 840 | hint="I return the fusebox application object.">
|
|---|
| 841 |
|
|---|
| 842 | <cfreturn this />
|
|---|
| 843 |
|
|---|
| 844 | </cffunction>
|
|---|
| 845 |
|
|---|
| 846 | <cffunction name="getCustomAttributes" returntype="struct" access="public" output="false"
|
|---|
| 847 | hint="I return any custom attributes for the specified namespace prefix.">
|
|---|
| 848 | <cfargument name="ns" type="string" required="true"
|
|---|
| 849 | hint="I am the namespace for which to return custom attributes." />
|
|---|
| 850 |
|
|---|
| 851 | <cfif structKeyExists(variables.customAttributes,arguments.ns)>
|
|---|
| 852 | <!--- we structCopy() this so folks can't poke values back into the metadata! --->
|
|---|
| 853 | <cfreturn structCopy(variables.customAttributes[arguments.ns]) />
|
|---|
| 854 | <cfelse>
|
|---|
| 855 | <cfreturn structNew() />
|
|---|
| 856 | </cfif>
|
|---|
| 857 |
|
|---|
| 858 | </cffunction>
|
|---|
| 859 |
|
|---|
| 860 | <cffunction name="getFuseboxFileExtension" returntype="string" access="public" output="false"
|
|---|
| 861 | hint="I return the fusebox.xml file extension: either xml or cfm.">
|
|---|
| 862 |
|
|---|
| 863 | <cfreturn variables.fuseboxFileExtension />
|
|---|
| 864 |
|
|---|
| 865 | </cffunction>
|
|---|
| 866 |
|
|---|
| 867 | <cffunction name="deleteParsedFiles" returntype="void" access="private" output="false"
|
|---|
| 868 | hint="I delete all the script files in the parsed/ directory.">
|
|---|
| 869 |
|
|---|
| 870 | <cfset var fileQuery = 0 />
|
|---|
| 871 | <cfset var parseDir = expandFuseboxPath(this.parsePath) />
|
|---|
| 872 |
|
|---|
| 873 | <cftry>
|
|---|
| 874 | <cfdirectory action="list" directory="#parseDir#"
|
|---|
| 875 | filter="*.#this.scriptFileDelimiter#" name="fileQuery" />
|
|---|
| 876 | <cfloop query="fileQuery">
|
|---|
| 877 | <cffile action="delete" file="#parseDir##fileQuery.name#" />
|
|---|
| 878 | </cfloop>
|
|---|
| 879 | <cfcatch />
|
|---|
| 880 | </cftry>
|
|---|
| 881 |
|
|---|
| 882 | </cffunction>
|
|---|
| 883 |
|
|---|
| 884 | <cffunction name="loadCircuits" returntype="void" access="private" output="false"
|
|---|
| 885 | hint="I (re)load all the circuits in an application.">
|
|---|
| 886 | <cfargument name="fbCode" type="any" required="true"
|
|---|
| 887 | hint="I am the parsed XML representation of the fusebox.xml file." />
|
|---|
| 888 | <cfargument name="myFusebox" type="myFusebox" required="true"
|
|---|
| 889 | hint="I am the myFusebox data structure." />
|
|---|
| 890 |
|
|---|
| 891 | <cfset var definedCircuits = xmlSearch(arguments.fbCode,"/fusebox/circuits/circuit") />
|
|---|