root / framework / trunk / corefiles / fuseboxCircuit.cfc

Revision 756, 27.5 kB (checked in by a.haskell@…, 4 months ago)

strict mode, forgot to put in my last code change...

Line 
1<!---
2Copyright 2006-2007 TeraTech, Inc. http://teratech.com/
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15--->
16<cfcomponent output="false" hint="I represent a circuit.">
17        <cfset  circuitImplicit = false />
18       
19        <cffunction name="init" intent:returntype="fuseboxCircuit" access="public" output="false"
20                                hint="I am the constructor.">
21                <cfargument name="fbApp" type="fuseboxApplication" required="true"
22                                        hint="I am the fusebox application object." />
23                <cfargument name="alias" type="string" required="true"
24                                        hint="I am the circuit alias." />
25                <cfargument name="path" type="string" required="true"
26                                        hint="I am the path from the application root to the circuit directory." />
27                <cfargument name="parent" type="string" required="true"
28                                        hint="I am the alias of the parent circuit." />
29                <cfargument name="myFusebox" type="myFusebox" required="true"
30                                        hint="I am the myFusebox data structure." />
31                <cfargument name="relative" type="boolean" required="true"
32                                        hint="I indicate whether the path is relative or absolute (mapped)." />
33                                       
34                <cfset variables.fuseboxApplication = arguments.fbApp />
35                <cfset variables.alias = arguments.alias />
36                <cfset variables.relative = arguments.relative />
37
38                <cfset variables.fuseboxLexicon = variables.fuseboxApplication.getFuseactionFactory().getBuiltinLexicon() />
39                               
40                <cfset variables.customAttributes = structNew() />
41               
42                <cfset variables.originalPath = arguments.path />
43                <cfset this.parent = arguments.parent />
44                <cfset variables.appPath = variables.fuseboxApplication.getApplicationRoot() />
45                <cfset variables.lexicons = structNew() />
46               
47                <cfset variables.relativePath = variables.fuseboxApplication.normalizePartialPath(arguments.path) />
48                <cfset this.path = variables.relativePath />
49                <!--- ticket 139: allow absolute path names and mappings: --->
50                <cfif left(variables.relativePath,1) is "/">
51                        <cfif variables.relative>
52                                <!--- unintentional absolute path? --->
53                                <cfif variables.fuseboxApplication.strictMode>
54                                        <cfthrow type="fusebox.badGrammar.illegalPath"
55                                                        message="Circuit path is not relative"
56                                                        detail="The 'path' value '#variables.originalPath#' for circuit #getAlias()# specifies an absolute path. Did you forget to specify 'relative=""false""'?" />
57                                </cfif>
58                                <cfset variables.fullPath = variables.appPath & variables.relativePath />
59                        <cfelse>
60                                <!--- explicit absolute / mapped path: --->
61                                <cfset variables.fullPath = replace(expandPath(variables.relativePath),"\","/","all") />
62                        </cfif>
63                <cfelse>
64                        <cfif variables.relative>
65                                <cfset variables.fullPath = variables.appPath & variables.relativePath />
66                        <cfelse>
67                                <cfthrow type="fusebox.badGrammar.illegalPath"
68                                                message="Circuit path is relative"
69                                                detail="The 'path' value '#variables.originalPath#' for circuit #getAlias()# should specify an absolute path when 'relative=""false""'." />
70                        </cfif>
71                </cfif>
72               
73                <cfset variables.fullPath = variables.fuseboxApplication.getCanonicalPath(variables.fullPath) />
74
75                <!---
76                        this was not correctly normalized prior to ticket 139 but it didn't really matter
77                        until absolute paths were allowed in that ticket:
78                --->
79                <cfset variables.relativePath = variables.fuseboxApplication.relativePath(variables.appPath,variables.fullPath) />
80                <cfset this.rootPath = variables.fuseboxApplication.relativePath(variables.fullPath,variables.appPath) />
81
82                <cfset reload(arguments.myFusebox) />
83                               
84                <cfif circuitImplicit>
85                        <cfreturn createObject("component", "fuseboxNoXMLCircuit").init(arguments.fbApp, arguments.alias, arguments.myFusebox, arguments.path) />
86                <cfelse>
87                        <cfreturn this />
88                </cfif>
89        </cffunction>
90       
91        <cffunction name="reload" returntype="fuseboxCircuit" access="public" output="false"
92                                hint="I reload the circuit file and build the in-memory structures from it.">
93                <cfargument name="myFusebox" type="myFusebox" required="true"
94                                        hint="I am the myFusebox data structure." />
95
96                <cfset var circuitFile = "" />
97                <cfset var candidateCircuitFiles = "circuit.xml.cfm,circuit.xml,#variables.alias#.xml.cfm,#variables.alias#.xml" />
98                <cfset var storedCircuitPath = "" />
99                <cfset var circuitFound = false />
100                <cfset var circuitXML = "" />
101                <cfset var circuitCode = "" />
102                <cfset var needToLoad = true />
103                <cfset var circuitFiles = 0 />
104                <!---
105                        since we need to check the file, regardless of whether we load it,
106                        we might as well do the test up front and perform the strict check
107                        that just one version exists (ticket 135)
108                --->
109                <cfloop list="#candidateCircuitFiles#" index="circuitFile">
110                        <cfif fileExists(variables.fullPath & circuitFile)>
111                                <cfif NOT variables.fuseboxApplication.strictMode>
112                                        <cfif variables.fuseboxApplication.debug>
113                                                <cfset arguments.myFusebox.trace("Compiler","Circuit Found at: " & variables.fullPath & circuitFile) />
114                                        </cfif>
115                                        <cfbreak />
116                                <cfelseif NOT circuitFound>
117                                        <cfset storedCircuitPath = circuitFile />
118                                        <cfset circuitFound = true />
119                                <cfelse>
120                                        <cfthrow type="fusebox.multipleCircuitXML"
121                                                        message="Multiple candidate circuits found, this is disallowed in strict mode."
122                                                        detail="'#storedCircuitPath# and #circuitFile# found in '#variables.fullPath#." />
123                                </cfif>
124                        </cfif>
125                </cfloop>
126                <cfif variables.fuseboxApplication.strictMode>
127                        <cfset circuitFile = storedCircuitPath />
128                </cfif>
129                <cfif structKeyExists(this,"timestamp")>
130                        <!--- Java timestamp solution provided by Daniel Schmid --->
131                        <cfset needToLoad = getApplication().fileModificationDate(variables.fullPath & circuitFile) gt parseDateTime(this.timestamp) />
132                </cfif>
133
134                <cfif needToLoad>
135                        <cfif variables.fuseboxApplication.debug>
136                                <cfset arguments.myFusebox.trace("Compiler","Loading #getAlias()# circuit.xml file") />
137                        </cfif>
138
139                        <!--- attempt to load circuit.xml(.cfm): --->
140                        <cftry>
141                               
142                                <cffile action="read" file="#variables.fullPath##circuitFile#"
143                                                variable="circuitXML"
144                                                charset="#variables.fuseboxApplication.characterEncoding#" />
145                               
146                                <cfset variables.circuitPath = variables.fullPath & circuitFile />
147                                <cfset circuitXML = variables.fullPath & circuitFile />
148
149                                <cfcatch type="security">
150                                        <!--- cffile denied by sandbox security --->
151                                        <cfthrow type="fusebox.security"
152                                                        message="security error reading circuit.xml"
153                                                        detail="The circuit xml file, '#circuitFile#', for circuit #getAlias()# could not be read because sandbox security has disabled the cffile tag."
154                                                        extendedinfo="#cfcatch.detail#" />
155                                </cfcatch>                             
156
157                                <cfcatch type="any">
158                                        <cfif variables.fuseboxApplication.allowImplicitCircuits>
159                                                <cfset circuitXML = "<circuit/>" />
160                                                <cfset circuitImplicit = true />
161                                        <cfelse>
162                                                <cfthrow type="fusebox.missingCircuitXML"
163                                                                message="missing circuit.xml"
164                                                                detail="The circuit xml file, #circuitFile#, for circuit #getAlias()# could not be found in #variables.fullPath#."
165                                                                extendedinfo="#cfcatch.detail#" />
166                                        </cfif>
167                                </cfcatch>
168                               
169                        </cftry>
170<!---           
171                        this was initially implemented as part of ticket 135 but feedback on
172                        the mailing list seems to indicate people think it is too draconian
173                        a restriction, even in strict mode - and I agree! -- Sean Corfield
174                       
175                        <cfif variables.fuseboxApplication.strictMode and not circuitImplicit and
176                                        variables.fuseboxApplication.getFuseboxFileExtension() is not listLast(circuitFile,".")>
177                                <cfthrow type="fusebox.inconsistentFuseboxCircuit"
178                                                message="Inconsistent Fusebox / Circuit file extensions"
179                                                detail="The circuit xml file, #circuitFile#, in #variables.fullPath#, uses a different file extension to the application's fusebox xml file. Strict requires consistency." />
180                        </cfif>
181 --->                   
182                        <cftry>
183                               
184                                <cfset circuitCode = xmlParse(circuitXML) />
185                               
186                                <cfcatch type="any">
187                                        <cfthrow type="fusebox.circuitXMLError"
188                                                        message="Error reading circuit.xml"
189                                                        detail="A problem was encountered while reading the circuit file #circuitFile# for circuit #getAlias()#. This is usually caused by unmatched XML tag-pairs. Close all XML tags explicitly or use the / (slash) short-cut."
190                                                        extendedinfo="#cfcatch.detail#" />
191                                </cfcatch>
192                               
193                        </cftry>
194       
195                        <cfif circuitCode.xmlRoot.xmlName is not "circuit">
196                                <cfthrow type="fusebox.badGrammar.badCircuitFile"
197                                                detail="Circuit file does contain 'circuit' XML"
198                                                message="Circuit file #variables.circuitPath# does not contain 'circuit' as the root XML node." />
199                        </cfif>
200                        <cfif structKeyExists(circuitCode.xmlRoot.xmlAttributes,"access")>
201                                <cfif listFind("private,internal,public",circuitCode.xmlRoot.xmlAttributes.access) eq 0>
202                                        <cfthrow type="fusebox.badGrammar.illegalAccess"
203                                                        message="Circuit access illegal"
204                                                        detail="The 'access' value '#circuitCode.xmlRoot.xmlAttributes.access#' is illegal in Circuit #getAlias()#. 'private', 'internal' or 'public' are the only legal values." />
205                                </cfif>
206                                <cfset this.access = circuitCode.xmlRoot.xmlAttributes.access />
207                        <cfelse>
208                                <cfset this.access = "internal" />
209                        </cfif>
210                        <cfif structKeyExists(circuitCode.xmlRoot.xmlAttributes,"permissions")>
211                                <cfset this.permissions = circuitCode.xmlRoot.xmlAttributes.permissions />
212                        <cfelse>
213                                <cfset this.permissions = "" />
214                        </cfif>
215       
216                        <cfset loadLexicons(circuitCode) />             
217                        <cfset loadPreAndPostFuseactions(circuitCode) />
218                        <cfset loadFuseactions(circuitCode) />
219                        <cfset variables.circuitFile = circuitFile />
220                        <cfset this.timestamp = now() />
221                </cfif>
222               
223                <cfreturn this />
224               
225        </cffunction>
226
227        <cffunction name="compile" returntype="void" access="public" output="false"
228                                hint="I compile a given fuseaction within this circuit.">
229                <cfargument name="writer" type="any" required="false"
230                                        hint="I am the parsed file writer object. I am required but it's faster to specify that I am not required." />
231                <cfargument name="fuseaction" type="any" required="false"
232                                        hint="I am the name of the fuseaction to compile. I am required but it's faster to specify that I am not required." />
233       
234                <cfset var f = arguments.writer.setFuseaction(arguments.fuseaction) />
235
236                <cfset compilePreOrPostFuseaction(arguments.writer,"pre") />
237               
238                <cfif not structKeyExists(this.fuseactions,arguments.fuseaction)>
239                        <cfthrow type="fusebox.undefinedFuseaction"
240                                        message="undefined Fuseaction"
241                                        detail="You specified a Fuseaction of #arguments.fuseaction# which is not defined in Circuit #getAlias()#." />
242                </cfif>
243                <cfset this.fuseactions[arguments.fuseaction].compile(arguments.writer) />
244               
245                <cfset compilePreOrPostFuseaction(arguments.writer,"post") />
246
247                <cfset arguments.writer.setFuseaction(f) />
248               
249        </cffunction>
250       
251        <cffunction name="compilePreOrPostFuseaction" returntype="void" access="public" output="false"
252                                hint="I compile the pre/post-fuseaction for a circuit.">
253                <cfargument name="writer" type="any" required="false"
254                                        hint="I am the parsed file writer object. I am required but it's faster to specify that I am not required." />
255                <cfargument name="preOrPost" type="string" required="false"
256                                        hint="I am either 'pre' or 'post' to indicate whether this is a prefuseaction or a postfuseaction. I am required but it's faster to specify that I am not required." />
257       
258                <cfset var c = "" />
259
260                <cfif variables.hasAction[arguments.preOrPost]>
261                        <cfif arguments.preOrPost is "pre" and variables.callsuper["pre"] and hasParent()>
262                                <cfset getParent().compilePreOrPostFuseaction(arguments.writer,arguments.preOrPost) />
263                        </cfif>
264                        <cfset c = arguments.writer.setCircuit(getAlias()) />
265                        <cfset variables.action[arguments.preOrPost].compile(arguments.writer) />
266                        <cfset arguments.writer.setCircuit(c) />
267                        <cfif arguments.preOrPost is "post" and variables.callsuper["post"] and hasParent()>
268                                <cfset getParent().compilePreOrPostFuseaction(arguments.writer,arguments.preOrPost) />
269                        </cfif>
270                </cfif>
271       
272        </cffunction>
273       
274        <cffunction name="buildCircuitTrace" returntype="void" access="public" output="false"
275                                hint="I build the 'circuit trace' structure - the array of parents. Required for Fusebox 4.1 compatibility.">
276       
277                <cfset var c = getParentName() />
278                <cfset var seen = structNew() />
279               
280                <cfset seen[getAlias()] = true />
281                <cfset this.circuitTrace = arrayNew(1) />
282                <cfset arrayAppend(this.circuitTrace,getAlias()) />
283                <cfloop condition="c is not ''">
284                        <cfif structKeyExists(seen,c)>
285                                <cfthrow type="fusebox.badGrammar.circularParent"
286                                                message="Circular parent for Circuit"
287                                                detail="You specified a parent Circuit of #c# (for Circuit #getAlias()#) which creates a circular dependency." />
288                        </cfif>
289                        <cfset seen[c] = true />
290                        <cfif not structKeyExists(variables.fuseboxApplication.circuits,c)>
291                                <cfthrow type="fusebox.undefinedCircuit"
292                                                message="undefined Circuit"
293                                                detail="You specified a parent Circuit of #c# (for Circuit #getAlias()#) which is not defined." />
294                        </cfif>
295                        <cfset arrayAppend(this.circuitTrace,c) />
296                        <cfset c = variables.fuseboxApplication.circuits[c].getParentName() />
297                </cfloop>
298               
299        </cffunction>
300       
301        <cffunction name="getOriginalPath" returntype="string" access="public" output="false"
302                                hint="I return the original relative path specified in the circuit declaration.">
303       
304                <cfreturn variables.originalPath />
305       
306        </cffunction>
307       
308        <cffunction name="getCircuitRoot" returntype="string" access="public" output="false"
309                                hint="I return the full file system path to the circuit directory.">
310       
311                <cfreturn variables.fullPath />
312       
313        </cffunction>
314
315        <cffunction name="getCircuitXMLFilename" returntype="string" access="public" output="false"
316                                hint="I return the actual name of the circuit XML file: circuit.xml or circuit.xml.cfm.">
317       
318                <cfreturn variables.circuitFile />
319       
320        </cffunction>
321
322        <cffunction name="getOriginalPathIsRelative" returntype="string" access="public" output="false"
323                                hint="I return true if this circuit's declaration used a relative path.">
324       
325                <cfreturn variables.relative />
326       
327        </cffunction>
328
329        <cffunction name="getParentName" returntype="string" access="public" output="false"
330                                hint="I return the name (alias) of this circuit's parent.">
331       
332                <cfreturn this.parent />
333       
334        </cffunction>
335
336        <cffunction name="hasParent" returntype="boolean" access="public" output="false"
337                                hint="I return true if this circuit has a parent, otherwise I return false.">
338       
339                <cfreturn getParentName() is not "" />
340       
341        </cffunction>
342
343        <cffunction name="getParent" returntype="any" access="public" output="false"
344                                hint="I return this circuit's parent circuit object. I throw an exception if hasParent() returns false.">
345       
346                <!---
347                        note that this will throw an exception if the circuit has no parent
348                        code should call hasParent() first
349                --->
350                <cfreturn variables.fuseboxApplication.circuits[getParentName()] />
351       
352        </cffunction>
353
354        <cffunction name="getPermissions" returntype="string" access="public" output="false"
355                                hint="I return the aggregated permissions for this circuit.">
356                <cfargument name="useCircuitTrace" type="boolean" default="false"
357                                        hint="I indicate whether or not to inherit the parent circuit's permissions if this circuit has no permissions specified." />
358       
359                <cfif this.permissions is "" and arguments.useCircuitTrace and hasParent()>
360                        <cfreturn getParent().getPermissions(arguments.useCircuitTrace) />
361                <cfelse>
362                        <cfreturn this.permissions />
363                </cfif>
364       
365        </cffunction>
366       
367        <cffunction name="getRelativePath" returntype="string" access="public" output="false"
368                                hint="I return the normalized relative path from the application root to this circuit's directory.">
369       
370                <cfreturn variables.relativePath />
371       
372        </cffunction>
373       
374        <cffunction name="getFuseactions" returntype="struct" access="public" output="false"
375                                hint="I return the structure containing the definitions of the fuseactions within this circuit.">
376               
377                <cfreturn this.fuseactions />
378               
379        </cffunction>
380       
381        <cffunction name="getLexiconDefinition" returntype="any" access="public" output="false"
382                                hint="I return the definition of the specified lexicon.">
383                <cfargument name="namespace" type="any" required="false"
384                                        hint="I am the namespace whose lexicon is to be retrieved. I am required but it's faster to specify that I am not required." />
385               
386                <cfif arguments.namespace is variables.fuseboxLexicon.namespace>
387                        <cfreturn variables.fuseboxLexicon />
388                <cfelse>
389                        <cfreturn variables.lexicons[arguments.namespace] />
390                </cfif>
391
392        </cffunction>
393       
394        <cffunction name="getAccess" returntype="any" access="public" output="false"
395                                hint="I return the access specified for this circuit.">
396       
397                <cfreturn this.access />
398       
399        </cffunction>
400       
401        <cffunction name="getAlias" returntype="any" access="public" output="false"
402                                hint="I return the circuit alias.">
403       
404                <cfreturn variables.alias />
405       
406        </cffunction>
407       
408        <cffunction name="getApplication" returntype="any" access="public" output="false"
409                                hint="I return the fusebox application object.">
410       
411                <cfreturn variables.fuseboxApplication />
412       
413        </cffunction>
414       
415        <cffunction name="getCustomAttributes" returntype="struct" access="public" output="false"
416                                hint="I return any custom attributes for the specified namespace prefix.">
417                <cfargument name="ns" type="string" required="true"
418                                        hint="I am the namespace for which to return custom attributes." />
419               
420                <cfif structKeyExists(variables.customAttributes,arguments.ns)>
421                        <!--- we structCopy() this so folks can't poke values back into the metadata! --->
422                        <cfreturn structCopy(variables.customAttributes[arguments.ns]) />
423                <cfelse>
424                        <cfreturn structNew() />
425                </cfif>
426               
427        </cffunction>
428       
429        <cffunction name="loadLexicons" returntype="void" access="private" output="false"
430                                hint="I load the lexicon definitions and custom attributes out of the namespace declarations in the circuit tag.">
431                <cfargument name="circuitCode" type="any" required="true"
432                                        hint="I am the XML representation of the circuit file." />
433               
434                <cfset var attributes = circuitCode.xmlRoot.xmlAttributes />
435                <cfset var attr = "" />
436                <cfset var aLex = "" />
437                <cfset var ns = "" />
438                <cfset var strict = variables.fuseboxApplication.strictMode />
439               
440                <!--- pass 1: pull out any namespace declarations --->
441                <cfloop collection="#attributes#" item="attr">
442                        <cfif len(attr) gt 6 and left(attr,6) is "xmlns:">
443                                <!--- found a namespace declaration, pull it out: --->
444                                <cfset aLex = structNew() />
445                                <cfset aLex.namespace = listLast(attr,":") />
446                                <cfif aLex.namespace is variables.fuseboxLexicon.namespace>
447                                        <cfthrow type="fusebox.badGrammar.reservedName"
448                                                        message="Attempt to use reserved namespace"
449                                                        detail="You have attempted to declare a namespace '#aLex.namespace#' (in Circuit #getAlias()#) which is reserved by the Fusebox framework." />
450                                </cfif>
451                                <cfset attributes[attr] = variables.fuseboxApplication.normalizePartialPath(attributes[attr]) />
452                                <cfif left(attributes[attr],1) is "/">
453                                        <!--- assume mapped / root-relative path --->
454                                        <cfset aLex.path = attributes[attr] />
455                                <cfelseif left(variables.fuseboxApplication.lexiconPath,1) is "/">
456                                        <!--- assume mapped / root-relative path --->
457                                        <cfset aLex.path = variables.fuseboxApplication.lexiconPath & attributes[attr] />
458                                <cfelse>
459                                        <!--- relative paths --->
460                                        <cfset aLex.path = variables.fuseboxApplication.getCoreToAppRootPath() &
461                                                        variables.fuseboxApplication.lexiconPath & attributes[attr] />
462                                </cfif>
463                                <cfset variables.lexicons[aLex.namespace] = aLex />
464                                <cfset variables.customAttributes[aLex.namespace] = structNew() />
465                        </cfif>
466                </cfloop>
467               
468                <!--- pass 2: pull out any custom attributes --->
469                <cfloop collection="#attributes#" item="attr">
470                        <cfif listLen(attr,":") eq 2>
471                                <!--- looks like a custom attribute: --->
472                                <cfset ns = listFirst(attr,":") />
473                                <cfif ns is "xmlns">
474                                        <!--- special case - need to ignore xmlns:foo="bar" --->
475                                <cfelseif structKeyExists(variables.customAttributes,ns)>
476                                        <cfset variables.customAttributes[ns][listLast(attr,":")] = attributes[attr] />
477                                <cfelse>
478                                        <cfthrow type="fusebox.badGrammar.undeclaredNamespace"
479                                                        message="Undeclared lexicon namespace"
480                                                        detail="The lexicon prefix '#ns#' was found on a custom attribute in the <circuit> tag of Circuit #getAlias()# but no such lexicon namespace has been declared." />
481                                </cfif>
482                        <cfelseif strict and listFind("access,permissions",attr) eq 0>
483                                <cfthrow type="fusebox.badGrammar.unexpectedAttributes"
484                                                message="Unexpected attributes"
485                                                detail="Unexpected attributes were found in the 'circuit' tag of the '#getAlias()#' circuit.xml file." />
486                        </cfif>
487                </cfloop>
488                               
489        </cffunction>
490       
491        <cffunction name="loadPreAndPostFuseactions" returntype="void" access="private" output="false"
492                                hint="I load the prefuseaction and postfuseaction definitions from the circuit file.">
493                <cfargument name="circuitCode" type="any" required="true"
494                                        hint="I am the XML representation of the circuit file." />
495               
496                <cfset variables.hasAction = structNew() />
497                <cfset variables.action = structNew() />
498                <cfset variables.callsuper = structNew() />
499                <cfset loadPrePostFuseaction(arguments.circuitCode,"pre") />
500                <cfset loadPrePostFuseaction(arguments.circuitCode,"post") />
501                               
502        </cffunction>
503       
504        <cffunction name="loadPrePostFuseaction" returntype="void" access="private" output="false"
505                                hint="I load the either a prefuseaction or a postfuseaction definition from the circuit file.">
506                <cfargument name="circuitCode" type="any" required="true"
507                                        hint="I am the XML representation of the circuit file." />
508                <cfargument name="prePost" type="string" required="true"
509                                        hint="I specify whether to load a 'pre'fuseaction or a 'post'fuseaction." />
510               
511                <cfset var children = xmlSearch(arguments.circuitCode,"/circuit/#arguments.prePost#fuseaction") />
512                <cfset var i = 0 />
513                <cfset var n = arrayLen(children) />
514                <cfset var nAttrs = 0 />
515               
516                <cfif n eq 0>
517                        <cfset variables.hasAction[arguments.prePost] = false />
518                <cfelseif n eq 1>
519                        <cfset variables.hasAction[arguments.prePost] = true />
520                        <cfif structKeyExists(children[1].xmlAttributes,"callsuper")>
521                                <cfif listFind("true,false,yes,no",children[1].xmlAttributes.callsuper) eq 0>
522                                        <cfthrow type="fusebox.badGrammar.invalidAttributeValue"
523                                                        message="Attribute has invalid value"
524                                                        detail="The attribute 'callsuper' must either be ""true"" or ""false"", for a '#arguments.prePost#fuseaction' in Circuit #getAlias()#." />
525                                </cfif>
526                                <cfset nAttrs = 1 />
527                                <cfset variables.callsuper[arguments.prePost] = children[1].xmlAttributes.callsuper />
528                        <cfelse>
529                                <cfset variables.callsuper[arguments.prePost] = false />
530                        </cfif>
531                        <cfif variables.fuseboxApplication.strictMode and structCount(children[1].xmlAttributes) neq nAttrs>
532                                <cfthrow type="fusebox.badGrammar.unexpectedAttributes"
533                                                message="Unexpected attributes"
534                                                detail="Unexpected attributes found on '#arguments.prePost#fuseaction' in Circuit #getAlias()#." />
535                        </cfif>
536                        <cfset variables.action[arguments.prePost] =
537                                        createObject("component","fuseboxAction")
538                                                .init(this,
539                                                        "$#arguments.prePost#fuseaction",
540                                                                "internal",
541                                                                        children[1].xmlChildren) />
542                <cfelse>
543                        <cfthrow type="fusebox.badGrammar.nonUniqueDeclaration"
544                                        message="Declaration was not unique"
545                                        detail="More than one &lt;#arguments.prePost#fuseaction&gt; declaration was found in Circuit #getAlias()#." />
546                </cfif>
547               
548        </cffunction>
549       
550        <cffunction name="loadFuseactions" returntype="void" access="private" output="false"
551                                hint="I load all of the fuseaction definitions from the circuit file.">
552                <cfargument name="circuitCode" type="any" required="true"
553                                        hint="I am the XML representation of the circuit file." />
554               
555                <cfset var children = xmlSearch(arguments.circuitCode,"/circuit/fuseaction") />
556                <cfset var i = 0 />
557                <cfset var n = arrayLen(children) />
558                <cfset var attribs = 0 />
559                <cfset var attr = "" />
560                <cfset var ns = "" />
561                <cfset var customAttribs = 0 />
562                <cfset var access = "" />
563                <cfset var permissions = "" />
564                <cfset var strict = variables.fuseboxApplication.strictMode />
565               
566                <cfset this.fuseactions = structNew() />
567                <cfloop from="1" to="#n#" index="i">
568                        <!--- default fuseaction access to circuit access --->
569                        <cfset access = this.access />
570                        <!--- default fuseaction permissions to empty string --->
571                        <cfset permissions = "" />
572                        <cfset attribs = children[i].xmlAttributes />
573                       
574                        <cfif not structKeyExists(attribs,"name")>
575                                <cfthrow type="fusebox.badGrammar.requiredAttributeMissing"
576                                                message="Required attribute is missing"
577                                                detail="The attribute 'name' is required, for a 'fuseaction' declaration in circuit #getAlias()#." />
578                        </cfif>
579
580                        <!--- scan for custom attributes --->
581                        <cfset customAttribs = structNew() />
582                        <cfloop collection="#attribs#" item="attr">
583
584                                <cfswitch expression="#attr#">
585                                <cfcase value="name">
586                                        <cfif structKeyExists(this.fuseactions,attribs.name)>
587                                                <cfthrow type="fusebox.overloadedFuseaction"
588                                                                message="overloaded Fuseaction"
589                                                                detail="You referenced a fuseaction, #attribs.name#, which has been defined multiple times in circuit #getAlias()#. Fusebox does not allow overloaded methods." />
590                                        </cfif>
591                                </cfcase>
592                                <cfcase value="access">
593                                        <cfset access = attribs.access />
594                                        <cfif listFind("private,internal,public",access) eq 0>
595                                                <cfthrow type="fusebox.badGrammar.illegalAccess"
596                                                                message="Fuseaction access illegal"
597                                                                detail="The 'access' value '#access#' is illegal on Fuseaction #attribs.name# in Circuit #getAlias()#. 'private', 'internal' or 'public' are the only legal values." />
598                                        </cfif>
599                                </cfcase>
600                                <cfcase value="permissions">
601                                        <cfset permissions = attribs.permissions />
602                                </cfcase>
603                                <cfdefaultcase>
604                                        <cfif listLen(attr,":") eq 2>
605                                                <!--- looks like a custom attribute: --->
606                                                <cfset ns = listFirst(attr,":") />
607                                                <cfif structKeyExists(variables.customAttributes,ns)>
608                                                        <cfset customAttribs[ns][listLast(attr,":")] = attribs[attr] />
609                                                <cfelse>
610                                                        <cfthrow type="fusebox.badGrammar.undeclaredNamespace"
611                                                                        message="Undeclared lexicon namespace"
612                                                                        detail="The lexicon prefix '#ns#' was found on a custom attribute in the Fuseaction #attribs.name# in Circuit #getAlias()# but no such lexicon namespace has been declared." />
613                                                </cfif>
614       
615                                        <cfelseif strict>
616                                                <cfthrow type="fusebox.badGrammar.unexpectedAttributes"
617                                                                message="Unexpected attributes"
618                                                                detail="Unexpected attribute '#attr#' found on Fuseaction #attribs.name# in Circuit #getAlias()#." />
619                                        </cfif>
620                                </cfdefaultcase>
621                                </cfswitch>
622                        </cfloop>
623
624                        <cfset this.fuseactions[attribs.name] =
625                                        createObject("component","fuseboxAction")
626                                                .init(this,attribs.name,access,children[i].xmlChildren,false,customAttribs) />
627                        <!--- FB41 security plugin compatibility: --->
628                        <cfset this.fuseactions[attribs.name].permissions = permissions />
629                </cfloop>
630               
631        </cffunction>
632       
633</cfcomponent>
Note: See TracBrowser for help on using the browser.