| 1 | <cfsilent> |
|---|
| 2 | <!--- |
|---|
| 3 | Fusebox Software License |
|---|
| 4 | Version 1.0 |
|---|
| 5 | |
|---|
| 6 | Copyright (c) 2003, 2004, 2005 The Fusebox Corporation. All rights reserved. |
|---|
| 7 | |
|---|
| 8 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
|---|
| 9 | |
|---|
| 10 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
|---|
| 11 | |
|---|
| 12 | 2. Redistributions in binary form or otherwise encrypted form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
|---|
| 13 | |
|---|
| 14 | 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: |
|---|
| 15 | |
|---|
| 16 | "This product includes software developed by the Fusebox Corporation (http://www.fusebox.org/)." |
|---|
| 17 | |
|---|
| 18 | Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. |
|---|
| 19 | |
|---|
| 20 | 4. The names "Fusebox" and "Fusebox Corporation" must not be used to endorse or promote products derived from this software without prior written (non-electronic) permission. For written permission, please contact fusebox@fusebox.org. |
|---|
| 21 | |
|---|
| 22 | 5. Products derived from this software may not be called "Fusebox", nor may "Fusebox" appear in their name, without prior written (non-electronic) permission of the Fusebox Corporation. For written permission, please contact fusebox@fusebox.org. |
|---|
| 23 | |
|---|
| 24 | If one or more of the above conditions are violated, then this license is immediately revoked and can be re-instated only upon prior written authorization of the Fusebox Corporation. |
|---|
| 25 | |
|---|
| 26 | THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FUSEBOX CORPORATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|---|
| 27 | |
|---|
| 28 | ------------------------------------------------------------------------------- |
|---|
| 29 | |
|---|
| 30 | This software consists of voluntary contributions made by many individuals on behalf of the Fusebox Corporation. For more information on Fusebox, please see <http://www.fusebox.org/>. |
|---|
| 31 | |
|---|
| 32 | ---> |
|---|
| 33 | |
|---|
| 34 | <!--- which version of the loader is this? ---> |
|---|
| 35 | <cfset myFusebox.version.loader = "4.1.0" /> |
|---|
| 36 | |
|---|
| 37 | <cfif myFusebox.version.runtime NEQ myFusebox.version.loader> |
|---|
| 38 | <cfthrow type="fusebox.versionMismatchException" |
|---|
| 39 | message="The loader is not the same version as the runtime" /> |
|---|
| 40 | </cfif> |
|---|
| 41 | |
|---|
| 42 | <cflock scope="application" timeout="10" type="EXCLUSIVE"> |
|---|
| 43 | |
|---|
| 44 | <cfif NOT structKeyExists(variables, "fb_canonicalPath")> |
|---|
| 45 | <cfinclude template="udf_canonicalpath.cfm" /> |
|---|
| 46 | </cfif> |
|---|
| 47 | <cfscript> |
|---|
| 48 | // initialize the application.fusebox (available to be read by developers but not to be written to) |
|---|
| 49 | fb_.application.fusebox = structNew(); |
|---|
| 50 | fb_.application.fusebox.isFullyLoaded = false; |
|---|
| 51 | fb_.application.fusebox.circuits = structNew(); |
|---|
| 52 | fb_.application.fusebox.classes = structNew(); |
|---|
| 53 | fb_.application.fusebox.lexicons = structNew(); |
|---|
| 54 | fb_.application.fusebox.plugins = structNew(); |
|---|
| 55 | fb_.application.fusebox.pluginphases = structNew(); |
|---|
| 56 | |
|---|
| 57 | // compute the current directory. This is the same as the |
|---|
| 58 | // fb_.rootdir variable that gets used later, but this variable is needed |
|---|
| 59 | // for ALL requests, not just for the loader. |
|---|
| 60 | fb_.application.fusebox.webrootdirectory = getDirectoryFromPath(getBaseTemplatePath()); |
|---|
| 61 | fb_.application.fusebox.approotdirectory = fb_canonicalPath(fb_.application.fusebox.webrootdirectory & fb_.appPath, fb_.osdelimiter); |
|---|
| 62 | // for 4.0 compatibility |
|---|
| 63 | fb_.application.fusebox.rootdirectory = fb_.application.fusebox.approotdirectory; |
|---|
| 64 | // the file separator for the platform |
|---|
| 65 | fb_.application.fusebox.osdelimiter = fb_.osdelimiter; |
|---|
| 66 | </cfscript> |
|---|
| 67 | |
|---|
| 68 | <!--- compute the relative path from the core files back to the application dir ---> |
|---|
| 69 | <cfif NOT structKeyExists(variables, "fb_relativeFilePath")> |
|---|
| 70 | <cfinclude template="udf_relativefilepath.cfm" /> |
|---|
| 71 | </cfif> |
|---|
| 72 | <cfscript> |
|---|
| 73 | // this is needed for FB_APP_PATH values that contain '../' on BlueDragon |
|---|
| 74 | fb_.currTmplPath = fb_canonicalPath(getCurrentTemplatePath(), fb_.osdelimiter); |
|---|
| 75 | |
|---|
| 76 | fb_.application.fusebox.CoreToAppRootPath = GetDirectoryFromPath(fb_relativeFilePath(fb_.currTmplPath, fb_canonicalPath("#fb_.application.fusebox.approotdirectory#dummy.file", fb_.osdelimiter))); |
|---|
| 77 | fb_.application.fusebox.AppRootToCorePath = GetDirectoryFromPath(fb_relativeFilePath(fb_canonicalPath("#fb_.application.fusebox.approotdirectory#dummy.file", fb_.osdelimiter), fb_.currTmplPath)); |
|---|
| 78 | fb_.application.fusebox.CoreToWebRootPath = GetDirectoryFromPath(fb_relativeFilePath(fb_.currTmplPath, fb_canonicalPath("#fb_.application.fusebox.webrootdirectory#dummy.file", fb_.osdelimiter))); |
|---|
| 79 | fb_.application.fusebox.WebRootToCorePath = GetDirectoryFromPath(fb_relativeFilePath(fb_canonicalPath("#fb_.application.fusebox.webrootdirectory#dummy.file", fb_.osdelimiter), fb_.currTmplPath)); |
|---|
| 80 | // location of parsed files |
|---|
| 81 | fb_.application.fusebox.parsePath = "parsed" & fb_.application.fusebox.osdelimiter; |
|---|
| 82 | |
|---|
| 83 | // location of plugins |
|---|
| 84 | fb_.application.fusebox.pluginsPath = "plugins" & fb_.application.fusebox.osdelimiter; |
|---|
| 85 | |
|---|
| 86 | // location of lexicon |
|---|
| 87 | fb_.application.fusebox.lexiconPath = "lexicon" & fb_.application.fusebox.osdelimiter; |
|---|
| 88 | |
|---|
| 89 | // location of error templates |
|---|
| 90 | fb_.application.fusebox.errortemplatesPath = "errortemplates" & fb_.application.fusebox.osdelimiter; |
|---|
| 91 | |
|---|
| 92 | </cfscript> |
|---|
| 93 | |
|---|
| 94 | <!--- make sure the "parsed" and "plugins" directorys exist ---> |
|---|
| 95 | <cflock name="#fb_.application.fusebox.approotdirectory#" timeout="30" type="Exclusive"> |
|---|
| 96 | <cftry> |
|---|
| 97 | <cfdirectory action="create" directory="#fb_.application.fusebox.approotdirectory#parsed" mode="777"> |
|---|
| 98 | <cfcatch><!--- do nothing ---></cfcatch> |
|---|
| 99 | </cftry> |
|---|
| 100 | <cftry> |
|---|
| 101 | <cfdirectory action="create" directory="#fb_.application.fusebox.approotdirectory#plugins" mode="777"> |
|---|
| 102 | <cfcatch><!--- do nothing ---></cfcatch> |
|---|
| 103 | </cftry> |
|---|
| 104 | </cflock> |
|---|
| 105 | |
|---|
| 106 | <!--- now that we've got all the paths we need, see if everything is up to date and abort the loading process ---> |
|---|
| 107 | <!---<cftrace category="core" text="beginning abort load check" />---> |
|---|
| 108 | <cftry> |
|---|
| 109 | <!--- if we're production, do the full load ---> |
|---|
| 110 | <cfif application.fusebox.mode NEQ "development"> |
|---|
| 111 | <cfthrow type="fusebox.forceLoadException.production" |
|---|
| 112 | message="If we're in production mode, we must really want the load to happen" /> |
|---|
| 113 | </cfif> |
|---|
| 114 | |
|---|
| 115 | <!--- the user requested a full load ---> |
|---|
| 116 | <cfif myFusebox.parameters.userProvidedLoadParameter AND attributes["fusebox.load"]> |
|---|
| 117 | <cfthrow type="fusebox.forceLoadException.userRequestedLoad" |
|---|
| 118 | message="The user requested a full load." /> |
|---|
| 119 | </cfif> |
|---|
| 120 | |
|---|
| 121 | <!--- we started a load, but it wasn't completed ---> |
|---|
| 122 | <cfif NOT isDefined("application.fusebox.isFullyLoaded") OR NOT application.fusebox.isFullyLoaded> |
|---|
| 123 | <cfthrow type="fusebox.forceLoadException.partialLoad" |
|---|
| 124 | message="The loading process was left incomplete" /> |
|---|
| 125 | </cfif> |
|---|
| 126 | |
|---|
| 127 | <!--- the app root has changed, meaning all the XML has changed ---> |
|---|
| 128 | <cfif isDefined("application.fusebox.approotdirectory") AND application.fusebox.approotdirectory NEQ fb_.application.fusebox.approotdirectory> |
|---|
| 129 | <cfthrow type="fusebox.forceLoadException.newAppRoot" |
|---|
| 130 | message="The application root directory has changed." /> |
|---|
| 131 | </cfif> |
|---|
| 132 | |
|---|
| 133 | <!--- check if fusebox.xml has been touched since it was last loaded ---> |
|---|
| 134 | <cfdirectory action="list" |
|---|
| 135 | directory="#fb_.application.fusebox.approotdirectory#" |
|---|
| 136 | name="fb_.dirlist" |
|---|
| 137 | filter="fusebox.xml*" /> |
|---|
| 138 | <cfif fb_.dirlist.recordCount NEQ 1> |
|---|
| 139 | <cfthrow type="fusebox.forceLoadException.noFuseboxXml" |
|---|
| 140 | message="Couldn't reliably locate fusebox.xml" |
|---|
| 141 | detail="Either fusebox.xml isn't located where it should be, or you have two files with names matching the expression fusebox.xml*" /> |
|---|
| 142 | </cfif> |
|---|
| 143 | <cfif parseDateTime(fb_.dirlist.datelastmodified) GT parseDateTime(application.fusebox.timestamp)> |
|---|
| 144 | <cfthrow type="fusebox.forceLoadException.fuseboxXmlIsNewer" |
|---|
| 145 | message="fusebox.xml is newer than it's in-memory cache." /> |
|---|
| 146 | </cfif> |
|---|
| 147 | |
|---|
| 148 | <!--- loop over the circuits and see if any have been touched since they were last loaded ---> |
|---|
| 149 | <cfloop collection="#application.fusebox.circuits#" item="fb_.i"> |
|---|
| 150 | <cfdirectory action="list" |
|---|
| 151 | directory="#fb_.application.fusebox.approotdirectory##application.fusebox.circuits[fb_.i].path#" |
|---|
| 152 | name="fb_.dirlist" |
|---|
| 153 | filter="circuit.xml*" /> |
|---|
| 154 | <cfif fb_.dirlist.recordCount NEQ 1> |
|---|
| 155 | <cfthrow type="fusebox.forceLoadException.noCircuitXml" |
|---|
| 156 | message="Couldn't reliably locate #fb_.i#/circuit.xml" |
|---|
| 157 | detail="Either circuit.xml isn't located where it should be in the #fb_.i# circuit, or you have two files with names matching the expression circuit.xml*" /> |
|---|
| 158 | </cfif> |
|---|
| 159 | <cfif parseDateTime(fb_.dirlist.datelastmodified) GT parseDateTime(application.fusebox.circuits[fb_.i].timestamp)> |
|---|
| 160 | <cfthrow type="fusebox.forceLoadException.circuitXmlIsNewer" |
|---|
| 161 | message="#fb_.i#/circuit.xml is newer than it's in-memory cache." /> |
|---|
| 162 | </cfif> |
|---|
| 163 | </cfloop> |
|---|
| 164 | |
|---|
| 165 | <!--- check the core files and see if any are newer than the last load ---> |
|---|
| 166 | <cfdirectory action="list" |
|---|
| 167 | directory="#getDirectoryFromPath(getCurrentTemplatePath())#" |
|---|
| 168 | name="fb_.dirlist" /> |
|---|
| 169 | <cfloop query="fb_.dirlist"> |
|---|
| 170 | <cfif type EQ "file" AND parseDateTime(datelastmodified) GT parseDateTime(application.fusebox.dateLastLoaded)> |
|---|
| 171 | <cfthrow type="fusebox.forceLoadException.coreFileIsNewer" |
|---|
| 172 | message="The #name# core is newer than the in-memory cache." /> |
|---|
| 173 | </cfif> |
|---|
| 174 | </cfloop> |
|---|
| 175 | |
|---|
| 176 | <!--- if we've gotten this far, the in-memory cache is up to date, so abort the the load ---> |
|---|
| 177 | <cfthrow type="fusebox.LoadUnneeded" |
|---|
| 178 | message="The full XML load is unneeded because the in-memory copy is fully up to date" /> |
|---|
| 179 | |
|---|
| 180 | <cfcatch type="fusebox.LoadUnneeded"> |
|---|
| 181 | <cfrethrow /> |
|---|
| 182 | </cfcatch> |
|---|
| 183 | <cfcatch type="fusebox.forceLoadException"> |
|---|
| 184 | <!--- a test of up-to-dateness failed ---> |
|---|
| 185 | </cfcatch> |
|---|
| 186 | <cfcatch type="any"> |
|---|
| 187 | <!--- something unknown happened ---> |
|---|
| 188 | </cfcatch> |
|---|
| 189 | </cftry> |
|---|
| 190 | <!---<cftrace category="core" text="abort load check completed unsuccessfully - continuing full load" />---> |
|---|
| 191 | |
|---|
| 192 | <cfscript> |
|---|
| 193 | // an interim write to the application.fusebox structure so we have the minimum needed in case there's a problem with the XML files |
|---|
| 194 | application.fusebox = duplicate(fb_.application.fusebox); |
|---|
| 195 | </cfscript> |
|---|
| 196 | |
|---|
| 197 | <!--- read the fusebox.xml file ---> |
|---|
| 198 | <cfif FileExists("#fb_.application.fusebox.approotdirectory#fusebox.xml.cfm")> |
|---|
| 199 | <cfset fb_.fuseboxXMLfile = "fusebox.xml.cfm"> |
|---|
| 200 | <cfelse> |
|---|
| 201 | <cfset fb_.fuseboxXMLfile = "fusebox.xml"> |
|---|
| 202 | </cfif> |
|---|
| 203 | <cftry> |
|---|
| 204 | <cffile |
|---|
| 205 | action="READ" |
|---|
| 206 | file="#fb_.application.fusebox.approotdirectory##fb_.fuseboxXMLfile#" |
|---|
| 207 | variable="fb_.FuseboxXMLcode"> |
|---|
| 208 | <cfcatch type="application"> |
|---|
| 209 | <cfthrow type="fusebox.missingFuseboxXML" message="missing fusebox.xml" detail="The file '#fb_.fuseboxXMLfile#' could not be found."> |
|---|
| 210 | </cfcatch> |
|---|
| 211 | </cftry> |
|---|
| 212 | <cftry> |
|---|
| 213 | <cfset fb_.application.fusebox.xml = xmlParse(trim(fb_.FuseboxXMLcode))> |
|---|
| 214 | <cfcatch type="any"> |
|---|
| 215 | <cfthrow type="fusebox.fuseboxXMLError" message="Error reading fusebox.xml" detail="A problem was encountered while reading the #fb_.fuseboxXMLfile# file. This is usually caused by unmatched XML tags (a <tag> without a </tag> or without use of the <tag/> short-cut.)"> |
|---|
| 216 | </cfcatch> |
|---|
| 217 | </cftry> |
|---|
| 218 | |
|---|
| 219 | |
|---|
| 220 | <cfscript> |
|---|
| 221 | // pull out the character encoding |
|---|
| 222 | fb_.xnParameters = XMLsearch(fb_.application.fusebox.xml, "//parameters/parameter[@name='characterEncoding']"); |
|---|
| 223 | if (arrayLen(fb_.xnParameters) AND structKeyExists(fb_.xnParameters[1].xmlAttributes, "value")) { |
|---|
| 224 | fb_.application.fusebox.characterEncoding = fb_.xnParameters[1].xmlAttributes['value']; |
|---|
| 225 | } |
|---|
| 226 | else { |
|---|
| 227 | fb_.application.fusebox.characterEncoding = "UTF-8"; |
|---|
| 228 | } |
|---|
| 229 | </cfscript> |
|---|
| 230 | |
|---|
| 231 | <!--- now reload the fusebox.xml file using the known characterEncoding in case anything else in it requires some special encoding ---> |
|---|
| 232 | <cftry> |
|---|
| 233 | <cffile |
|---|
| 234 | action="READ" |
|---|
| 235 | file="#fb_.application.fusebox.approotdirectory##fb_.fuseboxXMLfile#" |
|---|
| 236 | variable="fb_.FuseboxXMLcode" |
|---|
| 237 | charset="#fb_.application.fusebox.characterEncoding#"> |
|---|
| 238 | <cfcatch type="application"> |
|---|
| 239 | <cfthrow type="fusebox.missingFuseboxXML" message="missing fusebox.xml" detail="The file '#fb_.fuseboxXMLfile#' could not be found."> |
|---|
| 240 | </cfcatch> |
|---|
| 241 | </cftry> |
|---|
| 242 | <cftry> |
|---|
| 243 | <cfset fb_.application.fusebox.xml = xmlParse(trim(fb_.FuseboxXMLcode))> |
|---|
| 244 | <cfcatch type="any"> |
|---|
| 245 | <cfthrow type="fusebox.fuseboxXMLError" message="Error reading fusebox.xml" detail="A problem was encountered while reading the #fb_.fuseboxXMLfile# file. This is usually caused by unmatched XML tags (a <tag> without a </tag> or without use of the <tag/> short-cut.)"> |
|---|
| 246 | </cfcatch> |
|---|
| 247 | </cftry> |
|---|
| 248 | |
|---|
| 249 | <cfscript> |
|---|
| 250 | // make sure the fusebox.xml file has a namespace declared |
|---|
| 251 | //fb_.namespace = ' xmlns="http://www.fusebox.org/"'; |
|---|
| 252 | //if (FindNoCase('fusebox', fb_.FuseboxXMLcode) AND NOT FindNoCase(' xmlns=', fb_.FuseboxXMLcode) ) { |
|---|
| 253 | //fb_.FuseboxXMLcode = insert(fb_.namespace, fb_.FuseboxXMLcode, FindNoCase('fusebox', fb_.FuseboxXMLcode)+Len('fusebox')-1 ); |
|---|
| 254 | //} |
|---|
| 255 | fb_.application.fusebox.xml = xmlParse(trim(fb_.FuseboxXMLcode)); |
|---|
| 256 | // give this memory structure a timestamp |
|---|
| 257 | fb_.application.fusebox.timestamp = Now(); |
|---|
| 258 | |
|---|
| 259 | // parse the "application.fusebox" fusebox parameters properties |
|---|
| 260 | fb_.xnParameters = XMLsearch(fb_.application.fusebox.xml, "//parameters/parameter"); |
|---|
| 261 | for (fb_.i = 1; fb_.i LTE arrayLen(fb_.xnParameters); fb_.i = fb_.i + 1) { |
|---|
| 262 | fb_.application.fusebox[fb_.xnParameters[fb_.i].xmlAttributes['name']] = fb_.xnParameters[fb_.i].xmlAttributes['value']; |
|---|
| 263 | } |
|---|
| 264 | </cfscript> |
|---|
| 265 | <cfparam name="fb_.application.fusebox.precedenceFormOrUrl" default="form"> |
|---|
| 266 | <cfparam name="fb_.application.fusebox.defaultFuseaction" default=""> |
|---|
| 267 | <cfparam name="fb_.application.fusebox.fuseactionVariable" default="fuseaction"> |
|---|
| 268 | <cfparam name="fb_.application.fusebox.parseWithComments" default="false"> |
|---|
| 269 | <cfparam name="fb_.application.fusebox.ignoreBadGrammar" default="true"> |
|---|
| 270 | <cfparam name="fb_.application.fusebox.allowLexicon" default="true"> |
|---|
| 271 | <cfparam name="fb_.application.fusebox.useAssertions" default="true"> |
|---|
| 272 | <cfparam name="fb_.application.fusebox.conditionalParse" default="false"> |
|---|
| 273 | |
|---|
| 274 | <cfparam name="fb_.application.fusebox.password" default=""> |
|---|
| 275 | <cfparam name="fb_.application.fusebox.mode" default="production"> |
|---|
| 276 | <cfparam name="fb_.application.fusebox.scriptlanguage" default="cfmx"> |
|---|
| 277 | <cfparam name="fb_.application.fusebox.scriptFileDelimiter" default="cfm"> |
|---|
| 278 | <cfparam name="fb_.application.fusebox.maskedFileDelimiters" default="htm,cfm,cfml,php,php4,asp,aspx"> |
|---|
| 279 | <cfparam name="fb_.application.fusebox.parseWithIndentation" default="#fb_.application.fusebox.parseWithComments#"> |
|---|
| 280 | |
|---|
| 281 | <cfscript> |
|---|
| 282 | //parse the global fuseactions, both preprocess and postprocess |
|---|
| 283 | fb_.xnPreprocessFA = XMLsearch(fb_.application.fusebox.xml, "//globalfuseactions/preprocess"); |
|---|
| 284 | fb_.xnPostprocessFA = XMLsearch(fb_.application.fusebox.xml, "//globalfuseactions/postprocess"); |
|---|
| 285 | fb_.application.fusebox.globalfuseactions.preprocess.xml = fb_.xnPreprocessFA[1]; |
|---|
| 286 | fb_.application.fusebox.globalfuseactions.postprocess.xml = fb_.xnPostprocessFA[1]; |
|---|
| 287 | </cfscript> |
|---|
| 288 | |
|---|
| 289 | <cfscript> |
|---|
| 290 | // parse the class definitions |
|---|
| 291 | fb_.xnClasses = XMLsearch(fb_.application.fusebox.xml, "//classes/class"); |
|---|
| 292 | |
|---|
| 293 | for (fb_.i = 1; fb_.i LTE arrayLen(fb_.xnClasses); fb_.i = fb_.i + 1) { |
|---|
| 294 | |
|---|
| 295 | fb_.alias = fb_.xnClasses[fb_.i].xmlAttributes['alias']; |
|---|
| 296 | fb_.type = fb_.xnClasses[fb_.i].xmlAttributes['type']; |
|---|
| 297 | fb_.classpath = fb_.xnClasses[fb_.i].xmlAttributes['classpath']; |
|---|
| 298 | |
|---|
| 299 | if (StructKeyExists(fb_.xnClasses[fb_.i].xmlAttributes, 'constructor') AND Len(fb_.xnClasses[fb_.i].xmlAttributes.constructor)) { |
|---|
| 300 | fb_.constructor = fb_.xnClasses[fb_.i].xmlAttributes['constructor']; |
|---|
| 301 | } else { |
|---|
| 302 | fb_.constructor = ''; |
|---|
| 303 | } |
|---|
| 304 | fb_.application.fusebox.classes[fb_.alias] = structNew(); |
|---|
| 305 | |
|---|
| 306 | fb_.application.fusebox.classes[fb_.alias]['classpath'] = fb_.classpath; |
|---|
| 307 | fb_.application.fusebox.classes[fb_.alias]['type'] = fb_.type; |
|---|
| 308 | fb_.application.fusebox.classes[fb_.alias]['constructor'] = fb_.constructor; |
|---|
| 309 | } |
|---|
| 310 | </cfscript> |
|---|
| 311 | <cfscript> |
|---|
| 312 | // parse the lexicon definitions |
|---|
| 313 | fb_.xnLexicons = XMLsearch(fb_.application.fusebox.xml, "//lexicons/lexicon"); |
|---|
| 314 | fb_.namespace = ' xmlns="http://www.fusebox.org/"'; |
|---|
| 315 | for (fb_.i = 1; fb_.i LTE arrayLen(fb_.xnLexicons); fb_.i = fb_.i + 1) { |
|---|
| 316 | |
|---|
| 317 | fb_.xmlns = fb_.xnLexicons[fb_.i].xmlAttributes['namespace']; |
|---|
| 318 | fb_.path = fb_.xnLexicons[fb_.i].xmlAttributes['path']; |
|---|
| 319 | |
|---|
| 320 | fb_.application.fusebox.lexicons[fb_.xmlns] = structNew(); |
|---|
| 321 | fb_.application.fusebox.lexicons[fb_.xmlns]['path'] = fb_.path; |
|---|
| 322 | fb_.namespace = fb_.namespace & ' xmlns:#fb_.xmlns#="lexicon/#fb_.path#"'; |
|---|
| 323 | } |
|---|
| 324 | </cfscript> |
|---|
| 325 | <cfscript> |
|---|
| 326 | // an interim write to the application.fusebox structure |
|---|
| 327 | application.fusebox = duplicate(fb_.application.fusebox); |
|---|
| 328 | </cfscript> |
|---|
| 329 | |
|---|
| 330 | |
|---|
| 331 | <!--- parse the circuit definitions ---> |
|---|
| 332 | <cfset fb_.xnCircuits = XMLsearch(fb_.application.fusebox.xml, "//circuits/circuit") > |
|---|
| 333 | <cfloop from="1" to="#arrayLen(fb_.xnCircuits)#" index="fb_.i"> |
|---|
| 334 | <cfscript> |
|---|
| 335 | // if no attribute for path then insert it as empty string |
|---|
| 336 | if (NOT StructKeyExists(fb_.xnCircuits[fb_.i].xmlAttributes, 'path')) { |
|---|
| 337 | StructInsert(fb_.xnCircuits[fb_.i].xmlAttributes, 'path', ''); |
|---|
| 338 | } |
|---|
| 339 | // if no attribute for parent then insert it as empty string |
|---|
| 340 | if (NOT StructKeyExists(fb_.xnCircuits[fb_.i].xmlAttributes, 'parent')) { |
|---|
| 341 | StructInsert(fb_.xnCircuits[fb_.i].xmlAttributes, 'parent', ''); |
|---|
| 342 | } |
|---|
| 343 | |
|---|
| 344 | fb_.path = fb_.xnCircuits[fb_.i].xmlAttributes['path']; |
|---|
| 345 | fb_.parent = fb_.xnCircuits[fb_.i].xmlAttributes['parent']; |
|---|
| 346 | fb_.alias = fb_.xnCircuits[fb_.i].xmlAttributes['alias']; |
|---|
| 347 | fb_.application.fusebox.circuits[fb_.alias] = structNew(); |
|---|
| 348 | |
|---|
| 349 | fb_.application.fusebox.circuits[fb_.alias]['path'] = fb_.path; |
|---|
| 350 | fb_.application.fusebox.circuits[fb_.alias]['parent'] = fb_.parent; |
|---|
| 351 | |
|---|
| 352 | fb_.rootpath = ""; |
|---|
| 353 | fb_.rootdir = GetDirectoryFromPath(GetCurrentTemplatePath()); |
|---|
| 354 | |
|---|
| 355 | fb_.aDirs = ListToArray(fb_.path,"/"); |
|---|
| 356 | for (fb_.j = 1; fb_.j LTE arrayLen(fb_.aDirs); fb_.j = fb_.j + 1) { |
|---|
| 357 | if (fb_.aDirs[fb_.j] EQ "..") { |
|---|
| 358 | fb_.rootpath = listPrepend(fb_.rootpath, ListLast(fb_.rootdir, "/"), "/"); |
|---|
| 359 | fb_.rootdir = ListDeleteAt(fb_.rootdir, ListLen(fb_.rootdir), "\/"); |
|---|
| 360 | } |
|---|
| 361 | else { |
|---|
| 362 | fb_.rootpath = listPrepend(fb_.rootpath, "..", "/"); |
|---|
| 363 | } |
|---|
| 364 | } |
|---|
| 365 | if (Len(fb_.rootpath)) { |
|---|
| 366 | fb_.rootpath = fb_.rootpath & "/"; |
|---|
| 367 | } |
|---|
| 368 | fb_.application.fusebox.circuits[fb_.alias]['rootpath'] = fb_.rootpath; |
|---|
| 369 | </cfscript> |
|---|
| 370 | |
|---|
| 371 | <cfif FileExists("#fb_.application.fusebox.approotdirectory##REreplace(fb_.application.fusebox.circuits[fb_.alias]['path'], '\\/', fb_.application.fusebox.osdelimiter, 'all')#circuit.xml.cfm")> |
|---|
| 372 | <cfset fb_.circuitXMLfile = "circuit.xml.cfm"> |
|---|
| 373 | <cfelse> |
|---|
| 374 | <cfset fb_.circuitXMLfile = "circuit.xml"> |
|---|
| 375 | </cfif> |
|---|
| 376 | |
|---|
| 377 | <cftry> |
|---|
| 378 | <cffile |
|---|
| 379 | action="READ" |
|---|
| 380 | file="#fb_.application.fusebox.approotdirectory##REreplace(fb_.application.fusebox.circuits[fb_.alias]['path'], '\\/', fb_.application.fusebox.osdelimiter, 'all')##fb_.circuitXMLfile#" |
|---|
| 381 | variable="fb_.CircuitXML" |
|---|
| 382 | charset="#fb_.application.fusebox.characterEncoding#"> |
|---|
| 383 | |
|---|
| 384 | <cfcatch type="application"> |
|---|
| 385 | <cfthrow type="fusebox.missingCircuitXML" message="missing circuit.xml" detail="The circuit xml file, #fb_.circuitXMLfile#, for circuit #fb_.alias# could not be found."> |
|---|
| 386 | </cfcatch> |
|---|
| 387 | </cftry> |
|---|
| 388 | <cftry> |
|---|
| 389 | <cfscript> |
|---|
| 390 | // make sure the circuit.xml file has a namespace declared |
|---|
| 391 | //if (FindNoCase('circuit', fb_.CircuitXML) AND NOT FindNoCase(' xmlns=', fb_.CircuitXML) ) { |
|---|
| 392 | //fb_.CircuitXML = insert(fb_.namespace, fb_.CircuitXML, FindNoCase('circuit', fb_.CircuitXML)+Len('circuit')-1 ); |
|---|
| 393 | //} |
|---|
| 394 | fb_.application.fusebox.circuits[fb_.alias].xml = xmlParse(trim(fb_.CircuitXML)); |
|---|
| 395 | fb_.application.fusebox.circuits[fb_.alias].timestamp = now(); |
|---|
| 396 | </cfscript> |
|---|
| 397 | |
|---|
| 398 | <cfcatch type="any"> |
|---|
| 399 | <cfthrow type="fusebox.circuitXMLError" message="Error reading circuit.xml" detail="A problem was encountered while reading the circuit file #fb_.circuitXMLfile# for circuit #fb_.alias#. This is usually caused by unmatched XML tag-pairs. Close all XML tags explicitly or use the / (slash) short-cut."> |
|---|
| 400 | </cfcatch> |
|---|
| 401 | </cftry> |
|---|
| 402 | |
|---|
| 403 | </cfloop> |
|---|
| 404 | |
|---|
| 405 | <cfscript> |
|---|
| 406 | // an interim write to the application.fusebox structure |
|---|
| 407 | application.fusebox = duplicate(fb_.application.fusebox); |
|---|
| 408 | </cfscript> |
|---|
| 409 | |
|---|
| 410 | <cfscript> |
|---|
| 411 | // loop over all circuits to determine each circuit's "circuitTrace" |
|---|
| 412 | for (fb_.aCircuit in fb_.application.fusebox.circuits) { |
|---|
| 413 | fb_.application.fusebox.circuits[fb_.aCircuit]['circuitTrace'] = arrayNew(1); |
|---|
| 414 | arrayAppend(fb_.application.fusebox.circuits[fb_.aCircuit]['circuitTrace'], fb_.aCircuit); |
|---|
| 415 | fb_.thisCircuit = fb_.application.fusebox.circuits[fb_.aCircuit]['parent']; |
|---|
| 416 | while (len(trim(fb_.thisCircuit))) { |
|---|
| 417 | arrayAppend(fb_.application.fusebox.circuits[fb_.aCircuit]['circuitTrace'], fb_.thisCircuit); |
|---|
| 418 | fb_.thisCircuit = fb_.application.fusebox.circuits[fb_.thisCircuit]['parent']; |
|---|
| 419 | } |
|---|
| 420 | } |
|---|
| 421 | |
|---|
| 422 | // loop over all circuits to determine its attributes and its fuseactions |
|---|
| 423 | for (fb_.aCircuit in fb_.application.fusebox.circuits) { |
|---|
| 424 | fb_.xnCircuit = xmlSearch(fb_.application.fusebox.circuits[fb_.aCircuit]['xml'], "//circuit"); |
|---|
| 425 | |
|---|
| 426 | // determine the circuit's access modifier |
|---|
| 427 | if (structKeyExists(fb_.xnCircuit[1].xmlAttributes, 'access')) { |
|---|
| 428 | fb_.application.fusebox.circuits[fb_.aCircuit]['access'] = fb_.xnCircuit[1].xmlAttributes['access']; |
|---|
| 429 | } |
|---|
| 430 | else { |
|---|
| 431 | // by default, a circuit's access modifier is "internal" (accessible anywhere from inside the app but not from outside) |
|---|
| 432 | // note: this is important since any of a circuit's fuseactions who do not have an access modifier will inherit the access modifier of its circuit |
|---|
| 433 | fb_.application.fusebox.circuits[fb_.aCircuit]['access'] = "internal"; |
|---|
| 434 | } |
|---|
| 435 | |
|---|
| 436 | // determine the circuit's permissions |
|---|
| 437 | if (structKeyExists(fb_.xnCircuit[1].xmlAttributes, 'permissions')) { |
|---|
| 438 | fb_.application.fusebox.circuits[fb_.aCircuit]['permissions'] = fb_.xnCircuit[1].xmlAttributes['permissions']; |
|---|
| 439 | } |
|---|
| 440 | else { |
|---|
| 441 | fb_.application.fusebox.circuits[fb_.aCircuit]['permissions'] = ""; |
|---|
| 442 | } |
|---|
| 443 | |
|---|
| 444 | // determine all the circuit's fuseactions, prefuseactions, and postfuseactions |
|---|
| 445 | fb_.application.fusebox.circuits[fb_.aCircuit].fuseactions = structNew(); |
|---|
| 446 | fb_.application.fusebox.circuits[fb_.aCircuit].prefuseaction = structNew(); |
|---|
| 447 | fb_.application.fusebox.circuits[fb_.aCircuit].postfuseaction = structNew(); |
|---|
| 448 | |
|---|
| 449 | fb_.application.fusebox.circuits[fb_.aCircuit].prefuseaction.xml = arrayNew(1); |
|---|
| 450 | fb_.application.fusebox.circuits[fb_.aCircuit].postfuseaction.xml = arrayNew(1); |
|---|
| 451 | |
|---|
| 452 | fb_.application.fusebox.circuits[fb_.aCircuit].prefuseaction.callsuper = false; |
|---|
| 453 | fb_.application.fusebox.circuits[fb_.aCircuit].postfuseaction.callsuper = false; |
|---|
| 454 | |
|---|
| 455 | for (fb_.i = 1; fb_.i LTE arrayLen(fb_.xnCircuit[1].xmlChildren); fb_.i = fb_.i + 1) { |
|---|
| 456 | /* the fuseactions */ |
|---|
| 457 | if (fb_.xnCircuit[1].xmlChildren[fb_.i].xmlName EQ "fuseaction") { |
|---|
| 458 | fb_.name = fb_.xnCircuit[1].xmlChildren[fb_.i].xmlAttributes['name']; |
|---|
| 459 | fb_.application.fusebox.circuits[fb_.aCircuit].fuseactions[fb_.name] = structNew(); |
|---|
| 460 | fb_.application.fusebox.circuits[fb_.aCircuit].fuseactions[fb_.name].xml = fb_.xnCircuit[1].xmlChildren[fb_.i]; |
|---|
| 461 | |
|---|
| 462 | // determine the fuseaction's access modifier |
|---|
| 463 | if (structKeyExists(fb_.xnCircuit[1].xmlChildren[fb_.i].xmlAttributes, 'access')) { |
|---|
| 464 | fb_.application.fusebox.circuits[fb_.aCircuit].fuseactions[fb_.name].access = fb_.xnCircuit[1].xmlChildren[fb_.i].xmlAttributes.access; |
|---|
| 465 | } |
|---|
| 466 | else { |
|---|
| 467 | // by default, a fuseaction has no access modifier then it inherits that of its parent |
|---|
| 468 | fb_.application.fusebox.circuits[fb_.aCircuit].fuseactions[fb_.name].access = fb_.application.fusebox.circuits[fb_.aCircuit].access; |
|---|
| 469 | } |
|---|
| 470 | |
|---|
| 471 | // determine the fuseaction's permissions |
|---|
| 472 | if (structKeyExists(fb_.xnCircuit[1].xmlChildren[fb_.i].xmlAttributes, 'permissions')) { |
|---|
| 473 | fb_.application.fusebox.circuits[fb_.aCircuit].fuseactions[fb_.name].permissions = fb_.xnCircuit[1].xmlChildren[fb_.i].xmlAttributes.permissions; |
|---|
| 474 | } |
|---|
| 475 | else { |
|---|
| 476 | // by default, a fuseaction's permissions is the empty string |
|---|
| 477 | fb_.application.fusebox.circuits[fb_.aCircuit].fuseactions[fb_.name].permissions = ""; |
|---|
| 478 | } |
|---|
| 479 | } |
|---|
| 480 | /* the prefuseactions */ |
|---|
| 481 | else if (fb_.xnCircuit[1].xmlChildren[fb_.i].xmlName EQ "prefuseaction") { |
|---|
| 482 | if (arrayLen(fb_.xnCircuit[1].xmlChildren[fb_.i].xmlChildren)) { |
|---|
| 483 | fb_.application.fusebox.circuits[fb_.aCircuit].prefuseaction.xml = fb_.xnCircuit[1].xmlChildren[fb_.i]; |
|---|
| 484 | } |
|---|
| 485 | if ((StructKeyExists(fb_.xnCircuit[1].xmlChildren[fb_.i].xmlAttributes, 'callsuper')) AND |
|---|
| 486 | (fb_.xnCircuit[1].xmlChildren[fb_.i].xmlAttributes.callsuper EQ "true")){ |
|---|
| 487 | fb_.application.fusebox.circuits[fb_.aCircuit].prefuseaction.callsuper = true; |
|---|
| 488 | } |
|---|
| 489 | } |
|---|
| 490 | /* the postfuseactions */ |
|---|
| 491 | else if (fb_.xnCircuit[1].xmlChildren[fb_.i].xmlName EQ "postfuseaction") { |
|---|
| 492 | if (arrayLen(fb_.xnCircuit[1].xmlChildren[fb_.i].xmlChildren)) { |
|---|
| 493 | fb_.application.fusebox.circuits[fb_.aCircuit].postfuseaction.xml = fb_.xnCircuit[1].xmlChildren[fb_.i]; |
|---|
| 494 | } |
|---|
| 495 | if ((StructKeyExists(fb_.xnCircuit[1].xmlChildren[fb_.i].xmlAttributes, 'callsuper')) AND |
|---|
| 496 | (fb_.xnCircuit[1].xmlChildren[fb_.i].xmlAttributes.callsuper EQ "true")) { |
|---|
| 497 | fb_.application.fusebox.circuits[fb_.aCircuit].postfuseaction.callsuper = true; |
|---|
| 498 | } |
|---|
| 499 | } |
|---|
| 500 | } |
|---|
| 501 | } |
|---|
| 502 | |
|---|
| 503 | /* determine application.fusebox.parseRootPath, the inverse path of application.fusebox.parsePath */ |
|---|
| 504 | fb_.application.fusebox.parseRootPath = ""; |
|---|
| 505 | fb_.rootdir = Replace(GetDirectoryFromPath(getCurrentTemplatePath()), '\', fb_.application.fusebox.osdelimiter, 'all'); |
|---|
| 506 | fb_.aDirs = ListToArray(fb_.application.fusebox.parsePath,fb_.application.fusebox.osdelimiter); |
|---|
| 507 | for (fb_.i = 1; fb_.i LTE arrayLen(fb_.aDirs); fb_.i = fb_.i + 1) { |
|---|
| 508 | if (fb_.aDirs[fb_.i] EQ "..") { |
|---|
| 509 | fb_.application.fusebox.parseRootPath = listPrepend(fb_.application.fusebox.parseRootPath, ListLast(fb_.rootdir, fb_.application.fusebox.osdelimiter), fb_.application.fusebox.osdelimiter); |
|---|
| 510 | fb_.rootdir = ListDeleteAt(fb_.rootdir, ListLen(fb_.rootdir), fb_.application.fusebox.osdelimiter); |
|---|
| 511 | } |
|---|
| 512 | else { |
|---|
| 513 | fb_.application.fusebox.parseRootPath = listPrepend(fb_.application.fusebox.parseRootPath, "..", fb_.application.fusebox.osdelimiter); |
|---|
| 514 | } |
|---|
| 515 | } |
|---|
| 516 | |
|---|
| 517 | if (Len(fb_.application.fusebox.parseRootPath)) { |
|---|
| 518 | fb_.application.fusebox.parseRootPath = fb_.application.fusebox.parseRootPath & fb_.application.fusebox.osdelimiter; |
|---|
| 519 | } |
|---|
| 520 | |
|---|
| 521 | /* parse the plugins |
|---|
| 522 | sometimes we'll need to refer to the plugins by Name and sometimes by Phase |
|---|
| 523 | */ |
|---|
| 524 | fb_.xnPluginPhases = XMLsearch(fb_.application.fusebox.xml, "//plugins/phase"); |
|---|
| 525 | |
|---|
| 526 | // loop over all the plugin phases |
|---|
| 527 | for (fb_.i = 1; fb_.i LTE arrayLen(fb_.xnPluginPhases); fb_.i = fb_.i + 1) { |
|---|
| 528 | fb_.phase = fb_.xnPluginPhases[fb_.i].xmlAttributes['name']; |
|---|
| 529 | fb_.application.fusebox.pluginphases[fb_.phase] = arrayNew(1); |
|---|
| 530 | fb_.xnPlugins = xmlSearch(fb_.application.fusebox.xml, "//plugins/phase[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='#lcase(fb_.phase)#']/plugin"); |
|---|
| 531 | |
|---|
| 532 | // loop over all the plugins for a given phase |
|---|
| 533 | for (fb_.j = 1; fb_.j LTE arrayLen(fb_.xnPlugins); fb_.j = fb_.j + 1) { |
|---|
| 534 | fb_.name = fb_.xnPlugins[fb_.j].xmlAttributes['name']; |
|---|
| 535 | fb_.template = fb_.xnPlugins[fb_.j].xmlAttributes['template']; |
|---|
| 536 | fb_.path = fb_.application.fusebox.pluginsPath; |
|---|
| 537 | if (structKeyExists(fb_.xnPlugins[fb_.j].xmlAttributes, 'path')) { |
|---|
| 538 | fb_.path = fb_.path & fb_.xnPlugins[fb_.j].xmlAttributes['path']; |
|---|
| 539 | } |
|---|
| 540 | |
|---|
| 541 | if (NOT structKeyExists(fb_.application.fusebox.plugins, fb_.name)) { |
|---|
| 542 | fb_.application.fusebox.plugins[fb_.name] = structNew(); |
|---|
| 543 | } |
|---|
| 544 | fb_.application.fusebox.plugins[fb_.name][fb_.phase] = structNew(); |
|---|
| 545 | |
|---|
| 546 | fb_.rootpath = ""; |
|---|
| 547 | fb_.rootdir = getDirectoryFromPath(getCurrentTemplatePath()); |
|---|
| 548 | fb_.aDirs = ListToArray(fb_.path,"/"); |
|---|
| 549 | for (fb_.k = 1; fb_.k LTE arrayLen(fb_.aDirs); fb_.k = fb_.k + 1) { |
|---|
| 550 | if (fb_.aDirs[fb_.k] EQ "..") { |
|---|
| 551 | fb_.rootpath = listPrepend(fb_.rootpath, ListLast(fb_.rootdir, "/"), "/"); |
|---|
| 552 | fb_.rootdir = listDeleteAt(fb_.rootdir, ListLen(fb_.rootdir), "/"); |
|---|
| 553 | } |
|---|
| 554 | else { |
|---|
| 555 | fb_.rootpath = listPrepend(fb_.rootpath, "..", "/"); |
|---|
| 556 | } |
|---|
| 557 | } |
|---|
| 558 | |
|---|
| 559 | if (Len(fb_.rootpath)) { |
|---|
| 560 | fb_.rootpath = fb_.rootpath & "/"; |
|---|
| 561 | } |
|---|
| 562 | fb_.application.fusebox.plugins[fb_.name][fb_.phase].path = fb_.path; |
|---|
| 563 | fb_.application.fusebox.plugins[fb_.name][fb_.phase].template = fb_.template; |
|---|
| 564 | fb_.application.fusebox.plugins[fb_.name][fb_.phase].rootpath = fb_.rootpath; |
|---|
| 565 | |
|---|
| 566 | fb_.application.fusebox.pluginphases[fb_.phase][fb_.j] = structNew(); |
|---|
| 567 | fb_.application.fusebox.pluginphases[fb_.phase][fb_.j].name = fb_.name; |
|---|
| 568 | fb_.application.fusebox.pluginphases[fb_.phase][fb_.j].path = fb_.path; |
|---|
| 569 | fb_.application.fusebox.pluginphases[fb_.phase][fb_.j].template = fb_.template; |
|---|
| 570 | fb_.application.fusebox.pluginphases[fb_.phase][fb_.j].rootpath = fb_.rootpath; |
|---|
| 571 | fb_.application.fusebox.pluginphases[fb_.phase][fb_.j].parameters = fb_.xnPlugins[fb_.j].xmlChildren; |
|---|
| 572 | } |
|---|
| 573 | } |
|---|
| 574 | </cfscript> |
|---|
| 575 | |
|---|
| 576 | <cfscript> |
|---|
| 577 | fb_.application.fusebox.dateLastLoaded = now(); |
|---|
| 578 | fb_.application.fusebox.isFullyLoaded = true; |
|---|
| 579 | |
|---|
| 580 | // now, finally, copy the entire fb_.application.fusebox structure to the application.fusebox structure |
|---|
| 581 | application.fusebox = duplicate(fb_.application.fusebox); |
|---|
| 582 | </cfscript> |
|---|
| 583 | |
|---|
| 584 | </cflock> |
|---|
| 585 | </cfsilent> |
|---|