root / framework / tags / fusebox550 / fuseboxCircuit.cfc

Revision 535, 26.1 kB (checked in by scorfield, 1 year ago)

Fixes #75 by implementing conditionalParse!

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