root / framework / tags / fusebox51B1 / myFusebox.cfc

Revision 295, 12.6 kB (checked in by scorfield, 2 years ago)

Fixes #170 by creating the 5.1 beta!

  • Property svn:keywords set to LastChangedRevision
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 hint="I provide the per-request myFusebox data structure and some convenience methods.">
17        <cfscript>
18        // ticket 170 created the 5.1 beta
19        this.version.runtime     = "5.0.9.#REReplace('$LastChangedRevision$','[^0-9]','','all')#";
20         
21        this.version.loader      = "unknown";
22        this.version.transformer = "unknown";
23        this.version.parser      = "unknown";
24         
25        this.thisCircuit = "";
26        this.thisFuseaction =  "";
27        this.thisPlugin = "";
28        this.thisPhase = "";
29        this.plugins = structNew();
30        this.parameters = structNew();
31       
32        // the basic default is development-full-load mode:
33        this.parameters.load = true;
34        this.parameters.parse = true;
35        this.parameters.execute = true;
36        // FB5: new execution parameters:
37        this.parameters.clean = false;          // don't delete parsed files by default
38        this.parameters.parseall = false;       // don't compile all fuseactions by default
39         
40        this.parameters.userProvidedLoadParameter = false;
41        this.parameters.userProvidedCleanParameter = false;
42        this.parameters.userProvidedParseParameter = false;
43        this.parameters.userProvidedParseAllParameter = false;
44        this.parameters.userProvidedExecuteParameter = false;
45       
46        // stack frame for do/include parameters:
47        this.stack = structNew();
48        </cfscript>
49       
50        <cffunction name="init" returntype="myFusebox" access="public" output="false"
51                                hint="I am the constructor.">
52                <cfargument name="appKey" type="string" required="true"
53                                        hint="I am FUSEBOX_APPLICATION_KEY." />
54                <cfargument name="attributes" type="struct" required="true"
55                                        hint="I am the attributes (URL and form variables) structure." />
56               
57                <cfset var theFusebox = structNew() />
58               
59                <cfset variables.created = getTickCount() />
60                <cfset variables.log = arrayNew(1) />
61                <cfset variables.occurrence = structNew() />
62
63                <cfset variables.appKey = arguments.appKey />
64                <cfset variables.attributes = arguments.attributes />
65               
66                <!--- we can't guarantee the fusebox exists in application scope yet... --->
67                <cfif structKeyExists(application,variables.appKey)>
68                        <cfset theFusebox = application[variables.appKey] />
69                </cfif>
70               
71                <!--- default myFusebox.parameters depending on "mode" of the application set in fusebox.xml --->
72                <cfif structKeyExists(theFusebox,"mode")>
73                        <cfswitch expression="#theFusebox.mode#">
74                        <!--- FB41 backward compatibility - now deprecated --->
75                        <cfcase value="development">
76                                <cfif structKeyExists(theFusebox,"strictMode") and theFusebox.strictMode>
77                                        <!--- since we don't load fusebox.xml if we throw an exception, we must fixup the value for the next run --->
78                                        <cfset theFusebox.mode = "development-full-load" />
79                                        <cfthrow type="fusebox.badGrammar.deprecated"
80                                                        message="Deprecated feature"
81                                                        detail="'development' is a deprecated execution mode - use 'development-full-load' instead." />
82                                </cfif>
83                                <cfset this.parameters.load = true />
84                                <cfset this.parameters.parse = true />
85                                <cfset this.parameters.execute = true />
86                        </cfcase>
87                        <!--- FB5: replacement for old development mode --->
88                        <cfcase value="development-full-load">
89                                <cfset this.parameters.load = true />
90                                <cfset this.parameters.parse = true />
91                                <cfset this.parameters.execute = true />
92                        </cfcase>
93                        <!--- FB5: new option - does not load fusebox.xml and therefore does not (re-)load fuseboxApplication object --->
94                        <cfcase value="development-circuit-load">
95                                <cfset this.parameters.load = false />
96                                <cfset this.parameters.parse = true />
97                                <cfset this.parameters.execute = true />
98                        </cfcase>
99                        <cfcase value="production">
100                                <cfset this.parameters.load = false />
101                                <cfset this.parameters.parse = false />
102                                <cfset this.parameters.execute = true />
103                        </cfcase>
104                        <cfdefaultcase>
105                                <!--- since we don't load fusebox.xml if we throw an exception, we must fixup the value for the next run --->
106                                <cfset theFusebox.mode = "development-full-load" />
107                                <cfthrow type="fusebox.badGrammar.invalidParameterValue"
108                                                message="Parameter has invalid value"
109                                                detail="The parameter 'mode' must be one of 'development-full-load', 'development-circuit-load' or 'production' in the fusebox.xml file." />
110                        </cfdefaultcase>
111                        </cfswitch>
112                </cfif>
113
114                <!--- did the user pass in any special "fuseboxDOT" parameters for this request? --->
115                <!--- If so, process them --->
116                <!--- note: only if attributes.fusebox.password matches the application password --->
117                <cfif not structKeyExists(variables.attributes,"fusebox.password")>
118                        <cfset variables.attributes["fusebox.password"] = "" />
119                </cfif>
120                <cfif structKeyExists(theFusebox,"password") and
121                                theFusebox.password is variables.attributes['fusebox.password']>
122                        <!--- FB5: does a load and wipes the parsed files out --->
123                        <cfif structKeyExists(variables.attributes,'fusebox.loadclean') and isBoolean(variables.attributes['fusebox.loadclean'])>
124                                <cfset this.parameters.load = variables.attributes['fusebox.loadclean'] />
125                                <cfset this.parameters.clean = variables.attributes['fusebox.loadclean'] />
126                                <cfset this.parameters.userProvidedLoadParameter = true />
127                                <cfset this.parameters.userProvidedCleanParameter = true />
128                        </cfif>
129                        <cfif structKeyExists(variables.attributes,'fusebox.load') and isBoolean(variables.attributes['fusebox.load'])>
130                                <cfset this.parameters.load = variables.attributes['fusebox.load'] />
131                                <cfset this.parameters.userProvidedLoadParameter = true />
132                        </cfif>
133                        <cfif structKeyExists(variables.attributes,'fusebox.parseall') and isBoolean(variables.attributes['fusebox.parseall'])>
134                                <cfset this.parameters.parse = variables.attributes['fusebox.parseall'] />
135                                <cfset this.parameters.parseall = variables.attributes['fusebox.parseall'] />
136                                <cfif this.parameters.parseall>
137                                        <cfset this.parameters.load = true />
138                                </cfif>
139                                <cfset this.parameters.userProvidedParseParameter = true />
140                                <cfset this.parameters.userProvidedParseAllParameter = true />
141                        </cfif>
142                        <cfif structKeyExists(variables.attributes,'fusebox.parse') and isBoolean(variables.attributes['fusebox.parse'])>
143                                <cfset this.parameters.parse = variables.attributes['fusebox.parse'] />
144                                <cfset this.parameters.userProvidedParseParameter = true />
145                        </cfif>
146                        <cfif structKeyExists(variables.attributes,'fusebox.execute') and isBoolean(variables.attributes['fusebox.execute'])>
147                                <cfset this.parameters.execute = variables.attributes['fusebox.execute'] />
148                                <cfset this.parameters.userProvidedExecuteParameter = true />
149                        </cfif>
150                </cfif>
151               
152                <!---
153                        force a load if the runtime and core versions differ: this allows a new
154                        version to be dropped in and the framework will automatically reload!
155                        note: that we must *force* a load, by pretending this is user-provided!
156                --->
157                <cfif structKeyExists(theFusebox,"getVersion") and
158                                isCustomFunction(theFusebox.getVersion)>
159                        <cfif this.version.runtime is not theFusebox.getVersion()>
160                                <cfset this.parameters.userProvidedLoadParameter = true />
161                                <cfset this.parameters.load = true />
162                        </cfif>
163                <cfelse>
164                        <!--- hmm, doesn't look like the core is present (or it's not FB5 Alpha 2 or higher) --->
165                        <cfset this.parameters.userProvidedLoadParameter = true />
166                        <cfset this.parameters.load = true />
167                </cfif>
168
169                <!--- if the fusebox doesn't already exist we definitely want to reload --->
170                <cfif structKeyExists(theFusebox,"isFullyLoaded") and
171                                theFusebox.isFullyLoaded>
172                        <!--- if fully loaded, leave the load parameter alone --->
173                <cfelse>
174                        <cfset this.parameters.load = true />
175                </cfif>
176               
177                <cfreturn this />
178        </cffunction>
179       
180        <cffunction name="getApplication" returntype="any" access="public" output="false"
181                                hint="I am a convenience method to return the fuseboxApplication object without needing to know reference application scope or the FUSEBOX_APPLICATION_KEY variable.">
182       
183                <!---
184                        this is a bit of a hack since we're accessing application scope directly
185                        but it's probably cleaner than exposing a method to allow fuseboxApplication
186                        to inject itself back into myFusebox during compileRequest()...
187                --->
188                <cfreturn application[variables.appKey] />
189       
190        </cffunction>
191       
192        <cffunction name="getCurrentCircuit" returntype="any" access="public" output="false"
193                                hint="I am a convenience method to return the current Fusebox circuit object.">
194       
195                <cfreturn getApplication().circuits[this.thisCircuit] />
196       
197        </cffunction>
198       
199        <cffunction name="getCurrentFuseaction" returntype="any" access="public" output="false"
200                                hint="I am a convenience method to return the current fuseboxAction (fuseaction) object.">
201       
202                <cfreturn getCurrentCircuit().fuseactions[this.thisFuseaction] />
203       
204        </cffunction>
205       
206        <cffunction name="enterStackFrame" returntype="void" access="public" output="false"
207                                hint="I create a new stack frame (for scoped parameters to do/include).">
208               
209                <cfset var frame = structNew() />
210               
211                <cfset frame.__fuseboxStack = this.stack />
212                <cfset this.stack = frame />
213               
214        </cffunction>
215       
216        <cffunction name="leaveStackFrame" returntype="void" access="public" output="false"
217                                hint="I pop the last stack frame (for scoped parameters to do/include).">
218               
219                <cfset this.stack = this.stack.__fuseboxStack />
220               
221        </cffunction>
222       
223        <cffunction name="trace" returntype="void" access="public" output="false"
224                                hint="I add a line to the execution trace log.">
225                <cfargument name="type" hint="I am the type of trace (Fusebox, Compiler, Runtime are used by the framework)." />
226                <cfargument name="message" hint="I am the message to put in the execution trace." />
227               
228                <cfset addTrace(getTickCount() - variables.created,arguments.type,arguments.message) />
229               
230        </cffunction>
231
232        <cffunction name="addTrace" returntype="void" access="private" output="false"
233                                hint="I add a detailed line to the execution trace log.">
234                <cfargument name="time" hint="I am the time taken to get to this point in the request." />
235                <cfargument name="type" hint="I am the type of trace." />
236                <cfargument name="message" hint="I am the trace message." />
237                <cfargument name="occurrence" default="0" hint="I am a placeholder for part of the struct that is added to the log." />
238               
239                <cfif structKeyExists(variables.occurrence,arguments.message)>
240                        <cfset variables.occurrence[arguments.message] = 1 + variables.occurrence[arguments.message] />
241                <cfelse>
242                        <cfset variables.occurrence[arguments.message] = 1 />
243                </cfif>
244                <cfset arguments.occurrence = variables.occurrence[arguments.message] />
245                <cfset arrayAppend(variables.log,arguments) />
246               
247        </cffunction>
248       
249        <cffunction name="renderTrace" returntype="string" access="public" output="false" hint="I render the trace log as HTML.">
250               
251                <cfset var result = "" />
252                <cfset var i = 0 />
253               
254                <cfsavecontent variable="result">
255                        <br />
256                        <div style="clear:both;padding-top:10px;border-bottom:1px Solid #CCC;font-family:verdana;font-size:16px;font-weight:bold">Fusebox debugging:</div>
257                        <br />
258                        <table cellpadding="2" cellspacing="0" width="100%" style="border:1px Solid ##CCC;font-family:verdana;font-size:11pt;">
259                                <tr style="background:##EAEAEA">
260                                        <td style="border-bottom:1px Solid ##CCC;font-family:verdana;font-size:11pt;"><strong>Time</strong></td>
261                                        <td style="border-bottom:1px Solid ##CCC;font-family:verdana;font-size:11pt;"><strong>Category</strong></td>
262                                        <td style="border-bottom:1px Solid ##CCC;font-family:verdana;font-size:11pt;"><strong>Message</strong></td>
263                                        <td style="border-bottom:1px Solid ##CCC;font-family:verdana;font-size:11pt;"><strong>Count</strong></td>
264                                </tr>
265                                <cfloop index="i" from="1" to="#arrayLen(variables.log)#">
266                                        <cfoutput>
267                                                <cfif i mod 2>
268                                                        <tr style="background:##F9F9F9">
269                                                <cfelse>
270                                                        <tr style="background:##FFFFFF">
271                                                </cfif>
272                                                <td valign="top" style="font-size:10pt;border-bottom:1px Solid ##CCC;font-family:verdana;">#variables.log[i].time#ms</td>
273                                                <td valign="top" style="font-size:10pt;border-bottom:1px Solid ##CCC;font-family:verdana;">#variables.log[i].type#</td>
274                                                <td valign="top" style="font-size:10pt;border-bottom:1px Solid ##CCC;font-family:verdana;">#variables.log[i].message#</td>
275                                                <td valign="top" align="center" style="font-size:10pt;border-bottom:1px Solid ##CCC;font-family:verdana;">#variables.log[i].occurrence#</td>
276                                        </tr></cfoutput>
277                                </cfloop>
278                        </table>
279                </cfsavecontent>
280               
281                <cfreturn result />
282               
283        </cffunction>
284
285</cfcomponent>
Note: See TracBrowser for help on using the browser.