- qpscanner/fusebox5/fuseboxPlugin.cfc
- v0.7.3.1
- 10 KB
- 231
1<!---
2Copyright 2006-2007 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 plugin declaration.">
17
18 <cffunction name="init" returntype="fuseboxPlugin" access="public" output="false"
19 hint="I am the constructor.">
20 <cfargument name="phase" type="string" required="true"
21 hint="I am the phase with which this plugin is associated." />
22 <cfargument name="pluginXML" type="any" required="true"
23 hint="I am the XML representation of this plugin's declaration." />
24 <cfargument name="fbApp" type="fuseboxApplication" required="true"
25 hint="I am the fusebox application object." />
26 <cfargument name="lexicons" type="struct" required="true"
27 hint="I am the lexicons declared in the fusebox.xml file that are available as custom attributes." />
28
29 <cfset var i = 0 />
30 <cfset var n = arrayLen(arguments.pluginXML.xmlChildren) />
31 <cfset var attr = 0 />
32 <cfset var ns = "" />
33 <cfset var verbChildren = arrayNew(1) />
34 <cfset var factory = arguments.fbApp.getFuseactionFactory() />
35 <cfset var ext = "." & arguments.fbApp.scriptFileDelimiter />
36
37 <cfif arguments.pluginXML.xmlName is "plugin">
38
39 <cfif not structKeyExists(arguments.pluginXML.xmlAttributes,"name")>
40 <cfthrow type="fusebox.badGrammar.requiredAttributeMissing"
41 message="Required attribute is missing"
42 detail="The attribute 'name' is required, for a '#arguments.phase#' plugin declaration in fusebox.xml." />
43 </cfif>
44
45 <cfset variables.name = arguments.pluginXML.xmlAttributes.name />
46 <cfset variables.fuseboxApplication = arguments.fbApp />
47 <cfset variables.customAttribs = structNew() />
48
49 <cfif not structKeyExists(arguments.pluginXML.xmlAttributes,"template")>
50 <cfthrow type="fusebox.badGrammar.requiredAttributeMissing"
51 message="Required attribute is missing"
52 detail="The attribute 'template' is required, for the '#getName()#' plugin declaration in fusebox.xml." />
53 </cfif>
54
55 <cfset variables.phase = arguments.phase />
56
57 <cfset this.path = arguments.fbApp.getPluginsPath() />
58
59 <cfif structKeyExists(arguments.pluginXML.xmlAttributes,"path")>
60 <cfif left(arguments.pluginXML.xmlAttributes.path,1) is "/">
61 <!--- path is absolute, ignore normal plugins path --->
62 <cfset this.path = arguments.fbApp.normalizePartialPath(arguments.pluginXML.xmlAttributes.path) />
63 <cfelse>
64 <cfset this.path = this.path & arguments.fbApp.normalizePartialPath(arguments.pluginXML.xmlAttributes.path) />
65 </cfif>
66 </cfif>
67
68 <!--- look for any valid custom attributes --->
69 <cfloop collection="#arguments.pluginXML.xmlAttributes#" item="attr">
70 <cfswitch expression="#attr#">
71
72 <cfcase value="name,template,path">
73 <!--- already processed --->
74 </cfcase>
75
76 <cfdefaultcase>
77
78 <cfif listLen(attr,":") eq 2>
79 <!--- looks like a custom attribute: --->
80 <cfset ns = listFirst(attr,":") />
81 <cfif structKeyExists(arguments.lexicons,ns)>
82 <cfset customAttribs[ns][listLast(attr,":")] = arguments.pluginXML.xmlAttributes[attr] />
83 <cfelse>
84 <cfthrow type="fusebox.badGrammar.undeclaredNamespace"
85 message="Undeclared lexicon namespace"
86 detail="The lexicon prefix '#ns#' was found on a custom attribute in the '#getName()#' plugin declaration in fusebox.xml but no such lexicon namespace has been declared." />
87 </cfif>
88
89 <cfelseif arguments.fbApp.strictMode>
90 <cfthrow type="fusebox.badGrammar.unexpectedAttributes"
91 message="Unexpected attributes"
92 detail="Unexpected attribute '#attr#' found in the '#getName()#' plugin declaration in fusebox.xml." />
93 </cfif>
94
95 </cfdefaultcase>
96
97 </cfswitch>
98 </cfloop>
99
100 <cfset variables.template = arguments.pluginXML.xmlAttributes.template />
101 <cfif len(variables.template) lt 4 or right(variables.template,4) is not ext>
102 <cfset variables.template = variables.template & ext />
103 </cfif>
104 <cfif left(this.path,1) is "/">
105 <cfset this.rootpath =
106 arguments.fbApp.relativePath(arguments.fbApp.expandFuseboxPath(this.path),arguments.fbApp.getApplicationRoot()) />
107 <cfelse>
108 <cfset this.rootpath =
109 arguments.fbApp.relativePath(arguments.fbApp.getApplicationRoot() &
110 this.path,arguments.fbApp.getApplicationRoot()) />
111 </cfif>
112
113 <cfset this.rootpath = arguments.fbApp.getCanonicalPath(this.rootpath) />
114
115 <cfset variables.parameters = arguments.pluginXML.xmlChildren />
116 <cfset variables.paramVerbs = structNew() />
117 <cfloop from="1" to="#n#" index="i">
118
119 <cfif variables.parameters[i].xmlName is not "parameter">
120 <cfthrow type="fusebox.badGrammar.illegalDeclaration"
121 message="Parameter expected in plugin declaration"
122 detail="A 'plugin' declaration contained '#variables.parameters[i].xmlName#' but only 'parameter' is allowed, in fusebox.xml." />
123 </cfif>
124 <cfif not structKeyExists(variables.parameters[i].xmlAttributes,"name")>
125 <cfthrow type="fusebox.badGrammar.requiredAttributeMissing"
126 message="Required attribute is missing"
127 detail="The attribute 'name' is required, for a 'parameter' to the '#getName()#' plugin declaration in fusebox.xml." />
128 </cfif>
129
130 <cfif not structKeyExists(variables.parameters[i].xmlAttributes,"value")>
131 <cfthrow type="fusebox.badGrammar.requiredAttributeMissing"
132 message="Required attribute is missing"
133 detail="The attribute 'value' is required, for a 'parameter' to the '#getName()#' plugin declaration in fusebox.xml." />
134 </cfif>
135
136 <cfif arguments.fbApp.strictMode and structCount(variables.parameters[i].xmlAttributes) neq 2>
137 <cfthrow type="fusebox.badGrammar.unexpectedAttributes"
138 message="Unexpected attributes"
139 detail="Unexpected attributes were found in the '#variables.parameters[i].xmlAttributes.name#' parameter of the '#getName()#' plugin declaration in fusebox.xml." />
140 </cfif>
141
142 <cfset attr = structNew() />
143 <cfset attr.name = "myFusebox.plugins.#getName()#.parameters." & variables.parameters[i].xmlAttributes.name />
144 <cfset attr.value = variables.parameters[i].xmlAttributes.value />
145 <cfset variables.paramVerbs[i] = factory.create("set",this,attr,verbChildren) />
146
147 </cfloop>
148 <cfelse>
149 <cfthrow type="fusebox.badGrammar.illegalDeclaration"
150 message="Illegal declaration"
151 detail="The XML entity '#arguments.pluginXML.xmlName#' was found where a plugin declaration was expected in fusebox.xml." />
152 </cfif>
153
154 <cfreturn this />
155
156 </cffunction>
157
158 <cffunction name="compile" returntype="void" access="public" output="false"
159 hint="I compile this plugin object.">
160 <cfargument name="writer" type="any" required="false"
161 hint="I am the parsed file writer object. I am required but it's faster to specify that I am not required." />
162
163 <cfset var i = 0 />
164 <cfset var n = structCount(variables.paramVerbs) />
165 <cfset var file = "" />
166 <cfset var p = "" />
167
168 <cfif request.__fusebox.SuppressPlugins>
169 <cfreturn />
170 </cfif>
171 <cfswitch expression="#variables.phase#">
172 <cfcase value="processError,fuseactionException">
173 <cfif left(this.path,1) is "/">
174 <cffile action="read" file="#variables.fuseboxApplication.expandFuseboxPath(this.path)##variables.template#"
175 variable="file"
176 charset="#variables.fuseboxApplication.characterEncoding#" />
177 <cfelse>
178 <cffile action="read" file="#variables.fuseboxApplication.getApplicationRoot()##this.path##variables.template#"
179 variable="file"
180 charset="#variables.fuseboxApplication.characterEncoding#" />
181 </cfif>
182 <cfset arguments.writer.rawPrintln(file) />
183 </cfcase>
184 <cfdefaultcase>
185 <cfloop from="1" to="#n#" index="i">
186 <cfset variables.paramVerbs[i].compile(arguments.writer) />
187 </cfloop>
188 <cfset p = arguments.writer.setPhase(variables.phase) />
189 <cfset arguments.writer.println('<cfset myFusebox.thisPlugin = "#getName()#"/>') />
190 <cfset arguments.writer.print('<' & 'cfoutput><' & 'cfinclude template=') />
191 <cfif left(this.path,1) is "/">
192 <cfset arguments.writer.print('"#this.path##variables.template#"') />
193 <cfelse>
194 <cfset arguments.writer.print('"#variables.fuseboxApplication.parseRootPath##this.path##variables.template#"') />
195 </cfif>
196 <cfset arguments.writer.println('/><' & '/cfoutput>') />
197 <cfset arguments.writer.setPhase(p) />
198 </cfdefaultcase>
199 </cfswitch>
200
201 </cffunction>
202
203 <cffunction name="getName" returntype="string" access="public" output="false"
204 hint="I return the name of the plugin.">
205
206 <cfreturn variables.name />
207
208 </cffunction>
209
210 <cffunction name="getCircuit" returntype="any" access="public" output="false"
211 hint="I return the enclosing application object. This is an edge case to allow code that works with fuseactions to work with plugins too.">
212
213 <cfreturn variables.fuseboxApplication />
214
215 </cffunction>
216
217 <cffunction name="getCustomAttributes" returntype="struct" access="public" output="false"
218 hint="I return the custom (namespace-qualified) attributes for this plugin tag.">
219 <cfargument name="ns" type="string" required="true"
220 hint="I am the namespace prefix whose attributes should be returned." />
221
222 <cfif structKeyExists(variables.customAttribs,arguments.ns)>
223 <!--- we structCopy() this so folks can't poke values back into the metadata! --->
224 <cfreturn structCopy(variables.customAttribs[arguments.ns]) />
225 <cfelse>
226 <cfreturn structNew() />
227 </cfif>
228
229 </cffunction>
230
231</cfcomponent>