root/coldbox/trunk/system/plugins/methodInjector.cfc @ 1772

Revision 1772, 9.4 kB (checked in by lmajano, 5 years ago)

Happy weekend!!!

Line 
1<!-----------------------------------------------------------------------
2********************************************************************************
3Copyright 2005-2008 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
4www.coldboxframework.com | www.luismajano.com | www.ortussolutions.com
5********************************************************************************
6
7Author     :    Luis Majano
8Date        :   10/31/2007
9Description :
10        This is a method injector based on the work by Mark Mandel.
11----------------------------------------------------------------------->
12<cfcomponent name="methodInjector"
13                         hint="Method Injector plugin. It provides a nice way to mixin and remove methods from cfc's"
14                         extends="coldbox.system.plugin"
15                         output="false"
16                         cache="true">
17
18<!------------------------------------------- CONSTRUCTOR ------------------------------------------->
19
20        <cffunction name="init" access="public" returntype="methodInjector" output="false" hint="Constructor">
21                <!--- ************************************************************* --->
22                <cfargument name="controller" type="any" required="true">
23                <!--- ************************************************************* --->
24                <cfscript>
25                        super.init(arguments.controller);
26                       
27                        /* Plugin Properties */
28                        setPluginName("Method Injector");
29                        setPluginVersion("1.0");
30                        setPluginDescription("A way to inject and remove methods from cfc's");
31                       
32                        /* Our mixins Struct */
33                        instance.mixins = StructNew();
34                       
35                        /* Place our methods on the mixins struct */
36                        instance.mixins["removeMixin"]                          = variables.removeMixin;
37                        instance.mixins["injectMixin"]                          = variables.injectMixin;
38                        instance.mixins["invokerMixin"]                         = variables.invokerMixin;
39                        instance.mixins["injectPropertyMixin"]          = variables.injectPropertyMixin;
40                        instance.mixins["removePropertyMixin"]          = variables.removePropertyMixin;
41                        instance.mixins["populatePropertyMixin"]        = variables.populatePropertyMixin;
42                       
43                        /* Remove mixin methods */
44                        stop(this);
45                       
46                        return this;
47                </cfscript>
48        </cffunction>
49
50<!------------------------------------------- PUBLIC METHODS ------------------------------------------->
51
52        <!--- Start Method Injection on a CFC --->
53        <cffunction name="start" hint="start method injection set. Injects: injectMixin,removeMixin,invokerMixin,injectPropertyMixin,removePropertyMixin" access="public" returntype="void" output="false">
54                <!--- ************************************************************* --->
55                <cfargument name="CFC" hint="The cfc to inject the method into" type="any" required="Yes">
56                <!--- ************************************************************* --->
57                <cfset var udf = 0>
58               
59                <cflock name="plugin.methodInjector.#getmetadata(arguments.cfc).name#" type="exclusive" timeout="5" throwontimeout="true">
60                        <cfscript>
61                                /* Inject Mixins methods */
62                                for( udf in instance.mixins ){
63                                        arguments.CFC[udf] = instance.mixins[udf];
64                                }
65                        </cfscript>
66                </cflock>               
67        </cffunction>
68       
69        <!--- Stop the injection, do cleanup --->
70        <cffunction name="stop" hint="stop injection block. Removes mixed in methods." access="public" returntype="void" output="false">
71                <!--- ************************************************************* --->
72                <cfargument name="CFC" hint="The cfc to inject the method into" type="any" required="Yes">
73                <!--- ************************************************************* --->
74                <cfset var udf = 0>
75               
76                <cflock name="plugin.methodInjector.#getmetadata(arguments.cfc).name#" type="exclusive" timeout="5" throwontimeout="true">
77                        <cfscript>
78                                /* Remove Mixin Methods */
79                                for( udf in instance.mixins ){
80                                        arguments.CFC[udf] = instance.mixins[udf];
81                                        StructDelete(arguments.CFC, udf);
82                                }
83                        </cfscript>
84                </cflock>
85        </cffunction>
86       
87        <!--- ColdBox Controller Accessor/Mutators used to mixing --->
88        <cffunction name="getcontroller" access="public" output="false" returntype="any" hint="Get controller: coldbox.system.controller">
89                <cfreturn variables.controller/>
90        </cffunction>
91        <cffunction name="setcontroller" access="public" output="false" returntype="void" hint="Set controller">
92                <cfargument name="controller" type="any" required="true" hint="coldbox.system.controller"/>
93                <cfset variables.controller = arguments.controller/>
94        </cffunction>
95
96<!------------------------------------------- PRIVATE ------------------------------------------->
97
98        <!--- mixin --->
99        <cffunction name="injectMixin" hint="injects a method into the CFC scope" access="public" returntype="void" output="false">
100                <!--- ************************************************************* --->
101                <cfargument name="UDF" hint="UDF to be checked" type="any" required="Yes">
102                <!--- ************************************************************* --->
103                <cfscript>
104                        var metadata = getMetaData(arguments.UDF);
105                       
106                        /* Check for metadata Access */
107                        if( not structKeyExists(metadata, "access") ){
108                                metadata.access = "public";
109                        }
110                       
111                        /* Place UDF on the variables Scope */
112                        variables[metadata.name] = arguments.UDF;
113       
114                        if(metadata.access neq "private"){
115                                /* Place UDF on the this public scope */
116                                this[metaData.name] = arguments.UDF;
117                        }
118                </cfscript>
119        </cffunction>
120       
121        <!--- mixin --->
122        <cffunction name="populatePropertyMixin" hint="Populates a property if it exists" access="public" returntype="void" output="false">
123                <!--- ************************************************************* --->
124                <cfargument name="propertyName"         type="string"   required="true" hint="The name of the property to inject."/>
125                <cfargument name="propertyValue"        type="any"              required="true" hint="The value of the property to inject"/>
126                <cfargument name="scope"                        type="string"   required="false" default="variables" hint="The scope to which inject the property to."/>
127                <!--- ************************************************************* --->
128                <cfscript>
129                        /* Validate Property */
130                        if( structKeyExists(evaluate(arguments.scope),arguments.propertyName) ){
131                                /* Populate Property */
132                                "#arguments.scope#.#arguments.propertyName#" = arguments.propertyValue;
133                        }                       
134                </cfscript>
135        </cffunction>
136       
137        <!--- mixin --->
138        <cffunction name="injectPropertyMixin" hint="injects a property into the passed scope" access="public" returntype="void" output="false">
139                <!--- ************************************************************* --->
140                <cfargument name="propertyName"         type="string"   required="true" hint="The name of the property to inject."/>
141                <cfargument name="propertyValue"        type="any"              required="true" hint="The value of the property to inject"/>
142                <cfargument name="scope"                        type="string"   required="false" default="variables" hint="The scope to which inject the property to."/>
143                <!--- ************************************************************* --->
144                <cfscript>
145                        /* Inject Property */
146                        "#arguments.scope#.#arguments.propertyName#" = arguments.propertyValue;
147                </cfscript>
148        </cffunction>
149       
150        <!--- Remove Mixin --->
151        <cffunction name="removeMixin" hint="removes a method in a CFC" access="public" returntype="void" output="false">
152                <!--- ************************************************************* --->
153                <cfargument name="UDFName" hint="Name of the UDF to be removed" type="string" required="Yes">
154                <!--- ************************************************************* --->
155                <cfscript>
156                        StructDelete(this, arguments.udfName);
157                        StructDelete(variables, arguments.udfName);
158                </cfscript>
159        </cffunction>
160       
161        <!--- Remove Mixin --->
162        <cffunction name="removePropertyMixin" hint="removes a property from the cfc used." access="public" returntype="void" output="false">
163                <!--- ************************************************************* --->
164                <cfargument name="propertyName"         type="string"   required="true" hint="The name of the property to remove."/>
165                <cfargument name="scope"                        type="string"   required="false" default="variables" hint="The scope to which inject the property to."/>
166                <!--- ************************************************************* --->
167                <cfscript>
168                        structDelete(evaluate(arguments.scope),arguments.propertyName);
169                </cfscript>
170        </cffunction>
171       
172        <!--- Invoker Mixin --->
173        <cffunction name="invokerMixin" hint="calls private/packaged/public methods" access="public" returntype="any" output="false">
174                <!--- ************************************************************* --->
175                <cfargument name="method"                type="string" required="Yes" hint="Name of the private method to call">
176                <cfargument name="argCollection" type="struct" required="No"  hint="Can be called with an argument collection struct">
177                <cfargument name="argList"               type="string" required="No"  hint="Can be called with an argument list, for simple values only: ex: 'plugin=logger,number=1'">
178                <!--- ************************************************************* --->
179                <cfset var results = "">
180                <cfset var key = "">
181               
182                <!--- Determine type of invocation --->
183                <cfif structKeyExists(arguments,"argCollection")>
184                        <cfinvoke method="#arguments.method#"
185                                          returnvariable="results"
186                                          argumentcollection="#arguments.argCollection#" />
187                <cfelseif structKeyExists(arguments, "argList")>
188                        <cfinvoke method="#arguments.method#"
189                                          returnvariable="results">
190                                <cfloop list="#argList#" index="key">
191                                        <cfinvokeargument name="#listFirst(key,'=')#" value="#listLast(key,'=')#">
192                                </cfloop>
193                        </cfinvoke>
194                <cfelse>
195                        <cfinvoke method="#arguments.method#"
196                                          returnvariable="results" />
197                </cfif>
198               
199                <!--- Return results if Found --->
200                <cfif isDefined("results")>
201                        <cfreturn results>
202                </cfif>
203        </cffunction>
204
205</cfcomponent>
Note: See TracBrowser for help on using the browser.