root / website / trunk / fusebox4.loader.cfmx.cfm

Revision 217, 29.9 kB (checked in by scorfield, 3 years ago)

Initial import of partial fusebox.org site just to kick off the repository.

Line 
1<cfsilent>
2<!---
3Fusebox Software License
4Version 1.0
5
6Copyright (c) 2003, 2004, 2005 The Fusebox Corporation. All rights reserved.
7
8Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
9
101. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
11
122. 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
143. 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
18Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear.
19
204. 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
225. 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
24If 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
26THIS 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
30This 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 &lt;tag&gt; without a &lt;/tag&gt; or without use of the &lt;tag/&gt; 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 &lt;tag&gt; without a &lt;/tag&gt; or without use of the &lt;tag/&gt; 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>
Note: See TracBrowser for help on using the browser.