root / framework / tags / fusebox51B1 / fuseboxCircuit.cfc

Revision 294, 26.0 kB (checked in by scorfield, 2 years ago)

Fixes #163 by creating a centralized function to canonicalize a path that actually does it correctly!

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