-
Notifications
You must be signed in to change notification settings - Fork 28
/
fuseboxNoXmlCircuit.cfc
339 lines (260 loc) · 14.2 KB
/
fuseboxNoXmlCircuit.cfc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
<!---
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--->
<cfcomponent hint="I represent any circuit that does not use XML." output="false">
<cfset variables.originalPath = "" />
<cffunction name="init" returntype="any" access="public" output="false"
hint="I am the constructor.">
<cfargument name="fbApp" type="fuseboxApplication" required="true"
hint="I am the fusebox application object." />
<cfargument name="alias" type="string" required="true"
hint="I am the circuit alias." />
<cfargument name="myFusebox" type="myFusebox" required="true"
hint="I am the myFusebox data structure." />
<cfargument name="path" type="string" required="false" default="#variables.originalPath#"
hint="I am the path to the No XML ciruit." />
<cfset var traditionalCircuit = false />
<cfset var circuitPrefix = "" />
<cfset var circuitSearchPath =
"controller/#arguments.alias#,model/#arguments.alias#,view/#arguments.alias#," &
"#arguments.alias#/controller,#arguments.alias#/model,#arguments.alias#/view," &
"#arguments.alias#" />
<cfset variables.fuseboxApplication = arguments.fbApp />
<cfset variables.alias = arguments.alias />
<cfset variables.appPath = variables.fuseboxApplication.getApplicationRoot() />
<cfset variables.fuseboxLexicon = variables.fuseboxApplication.getFuseactionFactory().getBuiltinLexicon() />
<!--- ensure we don't reload this in the same request --->
<cfset request.__fusebox.CircuitsLoaded[variables.alias] = true />
<!---
look for traditional circuit in MVC/alias or alias/MVC or just alias directories:
--->
<cfloop index="circuitPrefix" list="#circuitSearchPath#">
<cfset traditionalCircuit =
fileExists(variables.appPath & circuitPrefix & "/circuit.xml.cfm") or
fileExists(variables.appPath & circuitPrefix & "/circuit.xml") />
<cfif traditionalCircuit>
<cfbreak />
</cfif>
</cfloop>
<!---
if we found a traditional circuit that simply wasn't declared,
return a regular Fusebox 5.x style circuit object:
--->
<cfif traditionalCircuit>
<cfif variables.fuseboxApplication.debug>
<cfset arguments.myFusebox.trace("Compiler","Implicit #circuitPrefix#/circuit.xml(.cfm) identified") />
</cfif>
<cfreturn createObject("component","fuseboxCircuit")
.init(variables.fuseboxApplication,
getAlias(),
circuitPrefix,
"",
arguments.myFusebox,
true) />
</cfif>
<!---
now we're off into convention over configuration territory...
--->
<cfset reload(arguments.myFusebox, arguments.path) />
<cfreturn this />
</cffunction>
<cffunction name="reload" returntype="any" access="public" output="false"
hint="I reload the circuit file and build the in-memory structures from it.">
<cfargument name="myFusebox" type="myFusebox" required="true"
hint="I am the myFusebox data structure." />
<cfargument name="path" type="string" required="false" default="#originalPath#"
hint="I am the path to the No XML ciruit." />
<cfset variables.fuseactionIsMethod = false />
<cfset variables.originalPath = arguments.path />
<cfset variables.fullPath = variables.appPath & variables.originalPath />
<cfset variables.relativePath = variables.fuseboxApplication.relativePath(variables.appPath,variables.fullPath) />
<!--- if the CFC actually exists, see if we can figure out if it exists in a sensible place --->
<cfif right(variables.fullPath, 4) EQ ".cfc" AND fileExists(variables.fullPath)>
<cfset variables.dottedPath = variables.fuseboxApplication.locateCfc(variables.fullPath) />
<cfif variables.dottedPath is not "">
<cfset variables.fuseactionIsMethod = true />
<cfif variables.fuseboxApplication.debug>
<cfset arguments.myFusebox.trace("Compiler","Loading No XML component-as-circuit #variables.fullPath# identified") />
</cfif>
</cfif>
<cfelseif directoryExists(variables.fullPath)>
<cfif variables.fuseboxApplication.debug>
<cfset arguments.myFusebox.trace("Compiler","Loading No XML diretory-as-circuit #variables.fullPath# identified") />
</cfif>
<cfelse>
<cfthrow type="fusebox.undefinedCircuit"
message="undefined Circuit"
detail="You specified a Circuit of #getAlias()# which is not found in #variables.fullPath#." />
</cfif>
<!--- TODO: added access level to Fusebox.xml or read annotation --->
<cfset this.access = "public" />
<!--- we don't know what fuseactions an implicit circuit has --->
<cfset this.fuseactions = structNew() />
<cfset this.parent = "" />
<cfset this.permissions = "" />
<cfset this.path = variables.relativePath />
<cfset this.rootPath = variables.fuseboxApplication.relativePath(variables.fullPath,variables.appPath) />
<cfset this.timestamp = now() />
<cfreturn this />
</cffunction>
<cffunction name="compile" returntype="void" access="public" output="false"
hint="I compile a given fuseaction within this circuit.">
<cfargument name="writer" type="any" required="false"
hint="I am the parsed file writer object. I am required but it's faster to specify that I am not required." />
<cfargument name="fuseaction" type="any" required="false"
hint="I am the name of the fuseaction to compile. I am required but it's faster to specify that I am not required." />
<cfargument name="topLevel" type="boolean" default="false"
hint="I specify whether or not this is a top-level (public) request." />
<cfset var f = arguments.writer.setFuseaction(arguments.fuseaction) />
<cfif arguments.fuseaction is "prefuseaction" or arguments.fuseaction is "postfuseaction">
<cfthrow type="fusebox.undefinedFuseaction"
message="undefined Fuseaction"
detail="You specified a Fuseaction of #arguments.fuseaction# which is uncallable in Circuit #getAlias()#." />
</cfif>
<!--- prefuseaction is handled internally to the circuit mechanism --->
<cfif not structKeyExists(this.fuseactions,arguments.fuseaction)>
<cfif variables.fuseactionIsMethod>
<cfset this.fuseactions[arguments.fuseaction] =
createObject("component","fuseboxControllerMethod")
.init(this,variables.dottedPath,arguments.fuseaction,true) />
<cfelse>
<!--- attempt to find the fuseaction as a file in the circuit directory --->
<cfif fileExists(variables.fullPath & arguments.fuseaction & ".xml")>
<!--- fuseaction.xml fragment --->
<cfthrow type="fusebox.NotImplemented"
message="undefined Fuseaction"
detail="You specified a Fuseaction of #arguments.fuseaction# which is not defined in Circuit #getAlias()#." />
<cfelseif fileExists(variables.fullPath & arguments.fuseaction & ".cfc")>
<!--- fuseaction.cfc (call do() on this) --->
<cfset variables.dottedPath = getApplication().locateCfc(variables.fullPath & arguments.fuseaction & ".cfc") />
<cfif variables.dottedPath is not "">
<cfset this.fuseactions[arguments.fuseaction] =
createObject("component","fuseboxControllerMethod")
.init(this,variables.dottedPath,arguments.fuseaction,false) />
<cfelse>
<cfthrow type="fusebox.undefinedFuseaction"
message="undefined Fuseaction"
detail="You specified a Fuseaction of #arguments.fuseaction# which is not defined in Circuit #getAlias()#." />
</cfif>
<cfelseif fileExists(variables.fullPath & arguments.fuseaction & ".cfm")>
<!--- fuseaction.cfm (i.e., a fuse) --->
<cfset this.fuseactions[arguments.fuseaction] =
createObject("component","fuseboxImplicitFuseaction")
.init(this,arguments.fuseaction) />
<cfelse>
<cfset writer.getMyFusebox().trace("Compiler","Could not find:" & variables.fullPath & arguments.fuseaction & ".cfm") />
<cfthrow type="fusebox.undefinedFuseaction"
message="undefined Fuseaction"
detail="You specified a Fuseaction of #arguments.fuseaction# which is not defined in Circuit #getAlias()#." />
</cfif>
</cfif>
</cfif>
<cfif arguments.topLevel>
<cfif this.access is not "public">
<cfthrow type="fusebox.invalidAccessModifier"
message="Invalid Access Modifier"
detail="You tried to access #getAlias()#.#arguments.fuseaction# which does not have access modifier of public. A Fuseaction which is to be accessed from anywhere outside the application (such as called via an URL, or a FORM, or as a web service) must have an access modifier of public or if unspecified at least inherit such a modifier from its circuit." />
</cfif>
</cfif>
<cfset this.fuseactions[arguments.fuseaction].compile(arguments.writer) />
<!--- postfuseaction is handled internally to the circuit mechanism --->
<cfset arguments.writer.setFuseaction(f) />
</cffunction>
<cffunction name="compilePreOrPostFuseaction" returntype="void" access="public" output="false"
hint="I compile the pre/post-fuseaction for a circuit.">
<cfargument name="writer" type="any" required="false"
hint="I am the parsed file writer object. I am required but it's faster to specify that I am not required." />
<cfargument name="preOrPost" type="string" required="false"
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." />
<!--- implicit circuits do not have pre/post fuseactions so this is a no-op --->
</cffunction>
<cffunction name="buildCircuitTrace" returntype="void" access="public" output="false"
hint="I build the 'circuit trace' structure - the array of parents. Required for Fusebox 4.1 compatibility.">
<cfset this.circuitTrace = arrayNew(1) />
<cfset arrayAppend(this.circuitTrace,getAlias()) />
</cffunction>
<cffunction name="getOriginalPath" returntype="string" access="public" output="false"
hint="I return the original relative path specified in the circuit declaration.">
<cfreturn variables.originalPath />
</cffunction>
<cffunction name="getCircuitRoot" returntype="string" access="public" output="false"
hint="I return the full file system path to the circuit directory.">
<cfreturn variables.fullPath />
</cffunction>
<cffunction name="getCircuitXMLFilename" returntype="string" access="public" output="false"
hint="I return the actual name of the circuit XML file: circuit.xml or circuit.xml.cfm.">
<!--- there is no XML file for an implicit circuit --->
<cfreturn "" />
</cffunction>
<cffunction name="getOriginalPathIsRelative" returntype="string" access="public" output="false"
hint="I return true if this circuit's declaration used a relative path.">
<!--- original path is relative by definition --->
<cfreturn true />
</cffunction>
<cffunction name="getParentName" returntype="string" access="public" output="false"
hint="I return the name (alias) of this circuit's parent.">
<cfreturn this.parent />
</cffunction>
<cffunction name="hasParent" returntype="boolean" access="public" output="false"
hint="I return true if this circuit has a parent, otherwise I return false.">
<cfreturn getParentName() is not "" />
</cffunction>
<cffunction name="getParent" returntype="any" access="public" output="false"
hint="I return this circuit's parent circuit object. I throw an exception if hasParent() returns false.">
<!---
note that this will throw an exception if the circuit has no parent
code should call hasParent() first
--->
<cfreturn variables.fuseboxApplication.circuits[getParentName()] />
</cffunction>
<cffunction name="getPermissions" returntype="string" access="public" output="false"
hint="I return the aggregated permissions for this circuit.">
<cfargument name="useCircuitTrace" type="boolean" default="false"
hint="I indicate whether or not to inherit the parent circuit's permissions if this circuit has no permissions specified." />
<cfreturn this.permissions />
</cffunction>
<cffunction name="getRelativePath" returntype="string" access="public" output="false"
hint="I return the normalized relative path from the application root to this circuit's directory.">
<cfreturn variables.relativePath />
</cffunction>
<cffunction name="getFuseactions" returntype="struct" access="public" output="false"
hint="I return the structure containing the definitions of the fuseactions within this circuit.">
<cfreturn this.fuseactions />
</cffunction>
<cffunction name="getLexiconDefinition" returntype="any" access="public" output="false"
hint="I return the definition of the specified lexicon.">
<cfargument name="namespace" type="any" required="false"
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." />
<cfif arguments.namespace is variables.fuseboxLexicon.namespace>
<cfreturn variables.fuseboxLexicon />
<!--- else we return nothing because this is an illegal call --->
</cfif>
</cffunction>
<cffunction name="getAccess" returntype="any" access="public" output="false"
hint="I return the access specified for this circuit.">
<cfreturn this.access />
</cffunction>
<cffunction name="getAlias" returntype="any" access="public" output="false"
hint="I return the circuit alias.">
<cfreturn variables.alias />
</cffunction>
<cffunction name="getApplication" returntype="any" access="public" output="false"
hint="I return the fusebox application object.">
<cfreturn variables.fuseboxApplication />
</cffunction>
<cffunction name="getCustomAttributes" returntype="struct" access="public" output="false"
hint="I return any custom attributes for the specified namespace prefix.">
<cfargument name="ns" type="string" required="true"
hint="I am the namespace for which to return custom attributes." />
<!--- implicit circuits have no custom attributes --->
<cfreturn structNew() />
</cffunction>
</cfcomponent>