root/coldbox/trunk/src/system/controller.cfc @ 815

Revision 815, 19.2 kB (checked in by lmajano, 6 years ago)

Ticket #213
updates to use coldbox.xml.cfm and config.xml.cfm

Line 
1<!-----------------------------------------------------------------------
2********************************************************************************
3Copyright 2005-2007 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
4www.coldboxframework.com | www.luismajano.com | www.ortussolutions.com
5********************************************************************************
6
7Author                  : Luis Majano
8Date                    : September 23, 2005
9Description             : This is the main ColdBox front Controller.
10----------------------------------------------------------------------->
11<cfcomponent name="controller" hint="This is the ColdBox Front Controller." output="false">
12
13<!------------------------------------------- CONSTRUCTOR ------------------------------------------->
14
15        <cfscript>
16                variables.instance = structnew();
17                variables.instance.ColdboxInitiated = false;
18                variables.instance.ConfigSettings = structnew();
19                variables.instance.ColdboxSettings = structnew();
20                variables.instance.AppStartHandlerFired = false;
21                variables.instance.AppHash = "";
22                //Services & Managers
23                variables.instance.ColdboxOCM = structNew();
24                variables.instance.DebuggerService = structNew();
25                variables.instance.RequestService = structNew();
26        </cfscript>
27
28        <cffunction name="init" returntype="any" access="Public" hint="I am the constructor" output="false">
29                <cfscript>
30                        //Set the App hash
31                        instance.AppHash = hash(createUUID() & getTickCount());
32                        //Create & init ColdBox Services
33                        instance.ColdboxOCM = CreateObject("component","cache.cacheManager").init(this);
34                        instance.RequestService = CreateObject("component","services.requestService").init(this);
35                        instance.DebuggerService = CreateObject("component","services.debuggerService").init(this);
36                        //Return instance
37                        return this;
38                </cfscript>
39        </cffunction>
40
41<!------------------------------------------- PUBLIC ------------------------------------------->
42
43        <!--- Getters / Setters Services & Managers --->
44        <cffunction name="getColdboxOCM" access="public" output="false" returntype="any" hint="Get ColdboxOCM">
45                <cfreturn instance.ColdboxOCM/>
46        </cffunction>
47        <cffunction name="getRequestService" access="public" output="false" returntype="any" hint="Get RequestService">
48                <cfreturn instance.RequestService/>
49        </cffunction>
50        <cffunction name="getDebuggerService" access="public" output="false" returntype="any" hint="Get DebuggerService">
51                <cfreturn instance.DebuggerService/>
52        </cffunction>
53
54        <!--- Getter & Setter Internal Structures --->
55        <cffunction name="getConfigSettings" access="public" returntype="struct" output="false" hint="I retrieve the Config Settings Structure by Reference">
56                <cfreturn instance.ConfigSettings>
57        </cffunction>
58        <cffunction name="setConfigSettings" access="public" output="false" returntype="void" hint="Set ConfigSettings">
59                <cfargument name="ConfigSettings" type="struct" required="true"/>
60                <cfset instance.ConfigSettings = arguments.ConfigSettings/>
61        </cffunction>
62        <cffunction name="getColdboxSettings" access="public" returntype="struct" output="false" hint="I retrieve the ColdBox Settings Structure by Reference">
63                <cfreturn instance.ColdboxSettings>
64        </cffunction>
65        <cffunction name="setColdboxSettings" access="public" output="false" returntype="void" hint="Set ColdboxSettings">
66                <cfargument name="ColdboxSettings" type="struct" required="true"/>
67                <cfset instance.ColdboxSettings = arguments.ColdboxSettings/>
68        </cffunction>
69
70        <!--- Accessor ColdBox Initiation Flag --->
71        <cffunction name="getColdboxInitiated" access="public" output="false" returntype="boolean" hint="Get ColdboxInitiated">
72                <cfreturn instance.ColdboxInitiated/>
73        </cffunction>
74        <cffunction name="setColdboxInitiated" access="public" output="false" returntype="void" hint="Set ColdboxInitiated">
75                <cfargument name="ColdboxInitiated" type="boolean" required="true"/>
76                <cfset instance.ColdboxInitiated = arguments.ColdboxInitiated/>
77        </cffunction>
78
79        <!--- App hash Get --->
80        <cffunction name="getAppHash" access="public" output="false" returntype="string" hint="Get AppHash">
81                <cfreturn instance.AppHash/>
82        </cffunction>
83       
84        <!--- Accessor/Mutator App Start Handler Fired --->
85        <cffunction name="setAppStartHandlerFired" access="public" output="false" returntype="void" hint="Set AppStartHandlerFired">
86                <cfargument name="AppStartHandlerFired" type="boolean" required="true"/>
87                <cfset instance.AppStartHandlerFired = arguments.AppStartHandlerFired/>
88        </cffunction>
89        <cffunction name="getAppStartHandlerFired" access="public" output="false" returntype="boolean" hint="Get AppStartHandlerFired">
90                <cfreturn instance.AppStartHandlerFired/>
91        </cffunction>
92
93        <!--- Config Structures Accessors/Mutators --->
94        <cffunction name="getSettingStructure" hint="Compatability & Utility Method. By default I retrieve the Config Settings. You can change this by using the FWSetting flag." access="public" returntype="struct" output="false">
95                <!--- ************************************************************* --->
96                <cfargument name="FWSetting"    type="boolean"   required="false"  hint="Boolean Flag. If true, it will retrieve from the fwSettingsStruct else the configStruct. Default is false." default="false">
97                <cfargument name="DeepCopyFlag" hint="Default is false. True, creates a deep copy of the structure." type="boolean" required="no" default="false">
98                <!--- ************************************************************* --->
99                <cfscript>
100                if (arguments.FWSetting){
101                        if (arguments.DeepCopyFlag)
102                                return duplicate(instance.ColdboxSettings);
103                        else
104                                return instance.ColdboxSettings;
105                }
106                else{
107                        if (arguments.DeepCopyFlag)
108                                return duplicate(instance.ConfigSettings);
109                        else
110                                return instance.ConfigSettings;
111                }
112                </cfscript>
113        </cffunction>
114        <cffunction name="getSetting" hint="I get a setting from the FW Config structures. Use the FWSetting boolean argument to retrieve from the fwSettingsStruct." access="public" returntype="any" output="false">
115                <cfargument name="name"             type="string"       hint="Name of the setting key to retrieve"  >
116                <cfargument name="FWSetting"    type="boolean"          required="false"  hint="Boolean Flag. If true, it will retrieve from the fwSettingsStruct else from the configStruct. Default is false." default="false">
117                <!--- ************************************************************* --->
118                <cfscript>
119                if ( arguments.FWSetting and settingExists(arguments.name,true) )
120                        return Evaluate("instance.ColdboxSettings.#arguments.name#");
121                else if ( settingExists(arguments.name) )
122                         return Evaluate("instance.ConfigSettings.#arguments.name#");
123                else
124                        throw("The setting #arguments.name# does not exist.","FWSetting flag is #arguments.FWSetting#","Framework.SettingNotFoundException");
125                </cfscript>
126        </cffunction>
127        <cffunction name="settingExists" returntype="boolean" access="Public"   hint="I Check if a value exists in the configstruct or the fwsettingsStruct." output="false">
128                <cfargument name="name" hint="Name of the setting to find." type="string">
129                <cfargument name="FWSetting"    type="boolean"   required="false"  hint="Boolean Flag. If true, it will retrieve from the fwSettingsStruct else from the configStruct. Default is false." default="false">
130                <!--- ************************************************************* --->
131                <cfscript>
132                if (arguments.FWSetting){
133                        return isDefined("instance.ColdboxSettings.#arguments.name#");
134                }
135                else{
136                        return isDefined("instance.ConfigSettings.#arguments.name#");
137                }
138                </cfscript>
139        </cffunction>
140        <cffunction name="setSetting" access="Public" returntype="void" hint="I set a Global Coldbox setting variable in the configstruct, if it exists it will be overrided. This only sets in the ConfigStruct" output="false">
141                <cfargument name="name"  type="string"   hint="The name of the setting" >
142                <cfargument name="value" type="any"      hint="The value of the setting (Can be simple or complex)">
143                <!--- ************************************************************* --->
144                <cfscript>
145                "instance.ConfigSettings.#arguments.name#" = arguments.value;
146                </cfscript>
147        </cffunction>
148
149        <!--- Service Locator --->
150        <cffunction name="getService" access="public" output="false" returntype="any" hint="Internal ColdBox Service Locator.">
151                <cfargument name="service" type="string" required="true" hint="The service/manager to create.">
152                <cfscript>
153                //Some services get loaded as singleton's, other are just created as needed
154                var servicePath = "";
155                switch(arguments.service){
156                        //Loader
157                        case "loader":
158                                servicePath = "services.loaderService";
159                                break;
160                        case "exception":
161                                servicePath = "services.exceptionService";
162                                break;
163                        //Default Case
164                        default:
165                                throw("Invalid Service detected","service:#arguments.service#","Framework.ServiceNotDefinedException");
166                }
167                return CreateObject("component",servicePath).init(this);
168                </cfscript>
169        </cffunction>
170
171        <!--- Plugin Factories --->
172        <cffunction name="getMyPlugin" access="Public" returntype="any" hint="I am the Custom Plugin cfc object factory." output="false">
173                <cfargument name="plugin"               type="string" hint="The Custom Plugin object's name to instantiate" >
174                <cfreturn getPlugin(arguments.plugin,true)>
175        </cffunction>
176        <cffunction name="getPlugin" access="Public" returntype="any" hint="I am the Plugin cfc object factory." output="true">
177                <cfargument name="plugin"               type="string"  hint="The Plugin object's name to instantiate" >
178                <cfargument name="customPlugin" type="boolean" required="false" default="false" hint="Used internally to create custom plugins.">
179                <cfargument name="newInstance"  type="boolean" required="false" default="false" hint="If true, it will create and return a new plugin. No caching or persistance.">
180                <!--- ************************************************************* --->
181                <cfset var oPlugin = "">
182                <cfset var MetaData = structNew()>
183                <cfset var objTimeout = "">
184                <cfset var pluginKey = "plugin_" & arguments.plugin>
185                <cfset var pluginPath = "coldbox.system.plugins.#trim(arguments.plugin)#">
186
187                <!--- Custom Plugin Test --->
188                <cfif arguments.customPlugin>
189                        <cfset pluginKey = "custom_plugin_" & arguments.plugin>
190                        <cfset pluginPath = "#getSetting("MyPluginsLocation")#.#trim(arguments.plugin)#">
191                </cfif>
192
193                <!--- Check FOr New Instance --->
194                <cfif arguments.newInstance>
195                        <!--- Object not found, proceed to create and verify --->
196                        <cfset oPlugin = CreateObject("component", pluginPath).init(this)>
197                <cfelse>
198                        <!--- Lookup in Cache --->
199                        <cfif instance.ColdboxOCM.lookup(pluginKey)>
200                                <cfset oPlugin = instance.ColdboxOCM.get(pluginKey)>
201                        <cfelse>
202                                <!--- Object not found, proceed to create and verify --->
203                                <cfset oPlugin = CreateObject("component", pluginPath).init(this)>
204                                <!--- Get Object's MetaData --->
205                                <cfset MetaData = getMetaData(oPlugin)>
206                                <!--- Test for caching parameters --->
207                                <cfif structKeyExists(MetaData, "cache") and isBoolean(MetaData["cache"]) and MetaData["cache"]>
208                                        <cfif structKeyExists(MetaData,"cachetimeout") >
209                                                <cfset objTimeout = MetaData["cachetimeout"]>
210                                        </cfif>
211                                        <cfset instance.ColdboxOCM.set(pluginKey,oPlugin,objTimeout)>
212                                </cfif>
213                        </cfif>
214                </cfif>
215
216                <!--- Return Plugin --->
217                <cfreturn oPlugin>
218        </cffunction>
219
220        <!--- Event Context Methods --->
221        <cffunction name="setNextEvent" access="Public" returntype="void" hint="I Set the next event to run and relocate the browser to that event."  output="false">
222                <cfargument name="event"                        hint="The name of the event to run."                    type="string" required="No" default="#getSetting("DefaultEvent")#" >
223                <cfargument name="queryString"          hint="The query string to append, if needed."   type="string" required="No" default="" >
224                <cfargument name="addToken"                     hint="Wether to add the tokens or not. Default is false" type="boolean" required="false" default="false"        >
225                <!--- ************************************************************* --->
226                <cfset var EventName = getSetting("EventName")>
227                <cfset var frontController = listlast(cgi.script_name,"/")>
228               
229                <!--- Cleanup Event --->
230                <cfif len(trim(arguments.event)) eq 0>
231                        <cfset arguments.event = getSetting("DefaultEvent")>
232                </cfif>
233               
234                <!--- Check if query String needs appending --->
235                <cfif len(trim(arguments.queryString)) eq 0>
236                        <cflocation url="#frontController#?#EventName#=#arguments.event#" addtoken="#arguments.addToken#">
237                <cfelse>
238                        <cflocation url="#frontController#?#EventName#=#arguments.event#&#arguments.queryString#" addtoken="#arguments.addToken#">
239                </cfif>
240        </cffunction>
241
242        <!--- Event Service Locator Factory --->
243        <cffunction name="runEvent" returntype="void" access="Public" hint="I am an event handler runnable factory. If no event is passed in then it will run the default event from the config file.">
244                <cfargument name="event"         hint="The event to run. If no current event is set, use the default event from the config.xml" type="string" required="false" default="">
245                <cfargument name="prepostExempt" hint="If true, pre/post handlers will not be fired." type="boolean" required="false" default="false">
246                <!--- ************************************************************* --->
247                <cfset var oEventHandler = "">
248                <cfset var oEventBean = "">
249                <cfset var objTimeout = "">
250                <cfset var MetaData = "">
251                <cfset var ExecutingHandler = "">
252                <cfset var ExecutingMethod = "">
253                <cfset var RequestContext = instance.RequestService.getContext()>
254                <cfset var EventName = getSetting("EventName")>
255
256                <!--- Default Event Set --->
257                <cfif arguments.event eq "">
258                        <cfset arguments.event = RequestContext.getValue(EventName)>
259                </cfif>
260
261                        <!--- Validate and Get registered handler --->
262                        <cfset oEventBean = getRegisteredHandler(arguments.event)>
263                        <!--- Set Executing Parameters --->
264                        <cfset ExecutingHandler = oEventBean.getRunnable()>
265                        <cfset ExecutingMethod = oEventBean.getMethod()>
266
267                        <!--- Check if using handler caching --->
268                        <cfif getSetting("HandlerCaching")>
269
270                                <!--- Lookup in Cache --->
271                                <cfif instance.ColdboxOCM.lookup("handler_" & ExecutingHandler)>
272                                        <cfset oEventHandler = instance.ColdboxOCM.get("handler_" & ExecutingHandler)>
273                                <cfelse>
274                                        <cfset oEventHandler = CreateObject("component",ExecutingHandler).init(this)>
275                                        <!--- Get Object MetaData --->
276                                        <cfset MetaData = getMetaData(oEventHandler)>
277                                        <!--- By Default, handlers with no cache flag are set to true --->
278                                        <cfif not structKeyExists(MetaData,"cache")>
279                                                <cfset MetaData.cache = true>
280                                        </cfif>
281                                        <cfif isBoolean(MetaData["cache"]) and MetaData["cache"]>
282                                                <cfif structKeyExists(MetaData,"cachetimeout") >
283                                                        <cfset objTimeout = MetaData["cachetimeout"]>
284                                                </cfif>
285                                                <!--- Set the Runnable Object --->
286                                                <cfset instance.ColdboxOCM.set("handler_" & ExecutingHandler,oEventHandler,objTimeout)>
287                                        </cfif>
288                                </cfif>
289                        <cfelse>
290                                <!--- Create Runnable Object --->
291                                <cfset oEventHandler = CreateObject("component",ExecutingHandler).init(this)>
292                        </cfif>
293
294                        <!--- Verify Event Method Exists --->
295                        <cfif not structKeyExists(oEventHandler,ExecutingMethod)>
296                                <!--- Invalid Event Detected, log it --->
297                                <cfset getPlugin("logger").logEntry("error","Invalid Event detected: #ExecutingHandler#.#ExecutingMethod#")>
298                                <cfif getSetting("onInvalidEvent") neq "">
299                                        <!--- Test for invalid Event Error --->
300                                        <cfif compareNoCase(getSetting("onInvalidEvent"),arguments.event) eq 0>
301                                                <cfthrow type="Framework.onInValidEventSettingException" message="An invalid event has been detected: #RequestContext.getValue("invalidevent","")# and the onInvalidEvent setting is also invalid: #getSetting("onInvalidEvent")#. Please check your settings.">
302                                        </cfif>
303                                        <!--- Relocate to Invalid Event --->
304                                        <cfset setNextEvent(getSetting("onInvalidEvent"),"invalidevent=#ExecutingHandler#.#ExecutingMethod#")>
305                                <cfelse>
306                                        <cfthrow type="Framework.InvalidEventException" message="An invalid event has been detected: #ExecutingHandler#.#ExecutingMethod#. This event does not exist in the specified handler controller.">
307                                </cfif>
308                        </cfif>
309
310                        <!--- PreHandler Execution --->
311                        <cfif not arguments.prepostExempt and structKeyExists(oEventHandler,"preHandler")>
312                                <cfmodule template="includes/timer.cfm" timertag="invoking runEvent [preHandler] for #arguments.event#">
313                                <cfset oEventHandler.preHandler(RequestContext)>
314                                </cfmodule>
315                        </cfif>
316
317                        <!--- Start Timer --->
318                        <cfmodule template="includes/timer.cfm" timertag="invoking runEvent [#arguments.event#]">
319                                <!--- Execute the Event --->
320                                <cfinvoke component="#oEventHandler#" method="#ExecutingMethod#">
321                                        <cfinvokeargument name="event" value="#RequestContext#">
322                                </cfinvoke>
323                        </cfmodule>
324
325                        <!--- PostHandler Execution --->
326                        <cfif not arguments.prepostExempt and structKeyExists(oEventHandler,"postHandler")>
327                                <cfmodule template="includes/timer.cfm" timertag="invoking runEvent [postHandler] for #arguments.event#">
328                                <cfset oEventHandler.postHandler(RequestContext)>
329                                </cfmodule>
330                        </cfif>
331
332        </cffunction>
333
334        <cffunction name="throw" access="public" hint="Facade for cfthrow" output="false">
335                <!--- ************************************************************* --->
336                <cfargument name="message"      type="string"   required="yes">
337                <cfargument name="detail"       type="string"   required="no" default="">
338                <cfargument name="type"         type="string"   required="no" default="Framework">
339                <!--- ************************************************************* --->
340                <cfthrow type="#arguments.type#" message="#arguments.message#"  detail="#arguments.detail#">
341        </cffunction>
342
343<!------------------------------------------- PRIVATE ------------------------------------------->
344
345        <cffunction name="getRegisteredHandler" access="private" hint="I get a registered handler and method according to passed event from the registeredHandlers setting." returntype="coldbox.system.beans.eventhandlerBean"  output="false">
346                <!--- ************************************************************* --->
347                <cfargument name="event" hint="The event to check and get." type="string" required="true">
348                <!--- ************************************************************* --->
349                <cfscript>
350                var handlerIndex = 0;
351                var HandlerReceived = "";
352                var MethodReceived = "";
353                var handlersList = getSetting("RegisteredHandlers");
354                var onInvalidEvent = getSetting("onInvalidEvent");
355                var HandlerBean = CreateObject("component","coldbox.system.beans.eventhandlerBean").init(getSetting("HandlersInvocationPath"));
356                //Rip the method
357                HandlerReceived = getPlugin("fileUtilities").ripExtension(arguments.event);
358                MethodReceived = listLast(arguments.event,".");
359
360                //Check Registration
361                handlerIndex = listFindNoCase(handlersList, HandlerReceived);
362
363                //Check for registration results
364                if ( handlerIndex ){
365                        HandlerBean.setHandler(listgetAt(handlersList,handlerIndex));
366                        HandlerBean.setMethod(MethodReceived);
367                }
368                else if ( onInvalidEvent neq "" ){
369                                //Check if the invalid event is the same as the current event
370                                if ( CompareNoCase(onInvalidEvent,arguments.event) eq 0){
371                                        throw("The invalid event handler: #onInvalidEvent# is also invalid. Please check your settings","","Framework.InvalidEventHandlerException");
372                                }
373                                else{
374                                        //Log Invalid Event
375                                        getPlugin("logger").logEntry("error","Invalid Event detected: #HandlerReceived#.#MethodReceived#");
376                                        //Override Event
377                                        HandlerBean.setHandler(getPlugin("fileUtilities").ripExtension(onInvalidEvent));
378                                        HandlerBean.setMethod(listLast(onInvalidEvent,"."));
379                                }
380                        }
381                else{
382                        throw("The event handler: #arguments.event# is not valid registered event.","","Framework.EventHandlerNotRegisteredException");
383                }
384                return HandlerBean;
385                </cfscript>
386        </cffunction>
387
388</cfcomponent>
Note: See TracBrowser for help on using the browser.