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 manage the creation of and writing to the parsed files.">
17 18 <cffunction name="init" returntype="any" access="public" output="false"
19 hint="I am the constructor.">
20 <cfargument name="fbApp" type="any" required="false"
21 hint="I am the fusebox application object. I am required but it's faster to specify that I am not required." />
22 <cfargument name="myFusebox" type="any" required="false"
23 hint="I am the myFusebox data structure. I am required but it's faster to specify that I am not required." />
24 25 <cfset variables.fuseboxApplication = arguments.fbApp />
26 <cfset variables.myFusebox = arguments.myFusebox />
27 <cfset variables.parsedDir = variables.fuseboxApplication.expandFuseboxPath(variables.fuseboxApplication.parsePath) />
28 <cfset variables.phase = "" />
29 <cfset variables.circuit = "" />
30 <cfset variables.fuseaction = "" />
31 <cfset variables.newline = chr(13) & chr(10) />
32 33 <cfif not directoryExists(variables.parsedDir)>
34 <cflock name="#variables.parsedDir#" type="exclusive" timeout="30">
35 <cfif not directoryExists(variables.parsedDir)>
36 <cftry>
37 <cfdirectory action="create" directory="#variables.parsedDir#" mode="777" />
38 <cfcatch type="any">
39 <cfthrow type="fusebox.missingParsedDirException"
40 message="The 'parsed' directory in the application root directory is missing, and could not be created"
41 detail="You must manually create this directory, and ensure that CF has the ability to write and change files within the directory."
42 extendedinfo="#cfcatch.detail#" />
43 </cfcatch>
44 </cftry>
45 </cfif>
46 </cflock>
47 </cfif>
48 49 <cfset reset() />
50 51 <cfreturn this />
52 53 </cffunction>
54 55 <cffunction name="getMyFusebox" returntype="any" access="public" output="false">
56 57 <cfreturn variables.myFusebox />
58 59 </cffunction>
60 61 <cffunction name="reset" returntype="void" access="public" output="false"
62 hint="I reset the phase, circuit and fuseaction as well as initializing the file content object.">
63 64 <cfset variables.lastPhase = "" />
65 <cfset variables.lastCircuit = "" />
66 <cfset variables.lastFuseaction = "" />
67 <!--- watch out for hosts that have createObject("java") disabled - this will be slow but it will work --->
68 <cftry>
69 <cfset variables.content = createObject("java","java.lang.StringBuffer").init() />
70 <cfcatch type="any">
71 <cfset variables.content = createObject("component","FakeStringBuffer").init() />
72 </cfcatch>
73 </cftry>
74 75 </cffunction>
76 77 <cffunction name="open" returntype="void" access="public" output="false"
78 hint="I 'open' the parsed file. In fact I just setup the writing process. The file is only created when this writer object is 'closed'.">
79 <cfargument name="filename" type="string" required="true"
80 hint="I am the name of the parsed file to be created." />
81 82 <cfset variables.filename = arguments.filename />
83 <cfset reset() />
84 <cfset rawPrintln('<cfsetting enablecfoutputonly="true" />') />
85 <cfset rawPrintln('<cfprocessingdirective pageencoding="#variables.fuseboxApplication.characterEncoding#" />') />
86 87 </cffunction>
88 89 <cffunction name="close" returntype="void" access="public" output="false"
90 hint="I 'close' the parsed file and write it to disk.">
91 <cfargument name="parsedFileCache" type="struct" required="true"
92 hint="I am a cache of parsed file text hash values." />
93 94 <cfset var parsedText = variables.content.toString() />
95 <cfset var parsedHash = hash(parsedText) />
96 97 <cfif variables.fuseboxApplication.conditionalParse>
98 <cfif fileExists(variables.parsedDir & "/" & variables.filename) and
99 structKeyExists(arguments.parsedFileCache,variables.filename) and
100 parsedHash is arguments.parsedFileCache[variables.filename]>
101 <cfif variables.fuseboxApplication.debug>
102 <cfset getMyFusebox().trace("Compiler","Parsed file '#variables.filename#' is unchanged and was not overwritten") />
103 </cfif>
104 <cfreturn />
105 <cfelse>
106 <cfif variables.fuseboxApplication.debug>
107 <cfset getMyFusebox().trace("Compiler","Parsed file '#variables.filename#' changed or did not exist") />
108 </cfif>
109 </cfif>
110 </cfif>
111 <cfset arguments.parsedFileCache[variables.filename] = parsedHash />
112 113 <cfset rawPrintln('<cfsetting enablecfoutputonly="false" />') />
114 <cftry>
115 <cffile action="write" file="#variables.parsedDir#/#variables.filename#"
116 output="#parsedText#"
117 charset="#variables.fuseboxApplication.characterEncoding#" />
118 <cfcatch type="any">
119 <cfthrow type="fusebox.errorWritingParsedFile"
120 message="An Error during write of Parsed File or Parsing Directory not found."
121 detail="Attempting to write the parsed file '#variables.filename#' threw an error. This can also occur if the parsed file directory cannot be found."
122 extendedinfo="#cfcatch.detail#" />
123 </cfcatch>
124 </cftry>
125 126 </cffunction>
127 128 <cffunction name="setPhase" returntype="any" access="public" output="false"
129 hint="I remember the currently executing plugin phase.">
130 <cfargument name="phase" type="any" required="false"
131 hint="I am the name of the current phase. I am required but it's faster to specify that I am not required." />
132 133 <cfset var p = variables.phase />
134 135 <cfset variables.phase = arguments.phase />
136 137 <cfreturn p />
138 139 </cffunction>
140 141 <cffunction name="setCircuit" returntype="any" access="public" output="false"
142 hint="I remember the currently executing circuit alias.">
143 <cfargument name="circuit" type="any" required="false"
144 hint="I am the name of the current circuit. I am required but it's faster to specify that I am not required." />
145 146 <cfset var c = variables.circuit />
147 148 <cfset variables.circuit = arguments.circuit />
149 150 <cfreturn c />
151 152 </cffunction>
153 154 <cffunction name="setFuseaction" returntype="any" access="public" output="false"
155 hint="I remember the currently executing fuseaction name.">
156 <cfargument name="fuseaction" type="any" required="false"
157 hint="I am the name of the current fuseaction. I am required but it's faster to specify that I am not required." />
158 159 <cfset var f = variables.fuseaction />
160 161 <cfset variables.fuseaction = arguments.fuseaction />
162 163 <cfreturn f />
164 165 </cffunction>
166 167 <cffunction name="print" returntype="void" access="public" output="false"
168 hint="I print a string to the parsed file. I set the phase, circuit and fuseaction variables if necessary in the myFusebox structure.">
169 <cfargument name="text" type="any" required="false"
170 hint="I am the string to be printed. I am required but it's faster to specify that I am not required." />
171 172 <cfif variables.lastPhase is not variables.phase>
173 <cfset rawPrintln('<cfset myFusebox.thisPhase = "#variables.phase#">') />
174 <cfset variables.lastPhase = variables.phase />
175 </cfif>
176 <cfif variables.lastCircuit is not variables.circuit>
177 <cfset rawPrintln('<cfset myFusebox.thisCircuit = "#variables.circuit#">') />
178 <cfset variables.lastCircuit = variables.circuit />
179 </cfif>
180 <cfif variables.lastFuseaction is not variables.fuseaction>
181 <cfset rawPrintln('<cfset myFusebox.thisFuseaction = "#variables.fuseaction#">') />
182 <cfset variables.lastFuseaction = variables.fuseaction />
183 </cfif>
184 <cfset variables.content.append(arguments.text) />
185 186 </cffunction>
187 188 <cffunction name="println" returntype="void" access="public" output="false"
189 hint="I print a string to the parsed file, followed by a newline. I set the phase, circuit and fuseaction variables if necessary in the myFusebox structure.">
190 <cfargument name="text" type="any" required="false"
191 hint="I am the string to be printed. I am required but it's faster to specify that I am not required." />
192 193 <cfset print(arguments.text) />
194 <cfset variables.content.append(variables.newline) />
195 196 </cffunction>
197 198 <cffunction name="rawPrint" returntype="void" access="public" output="false"
199 hint="I print a string to the parsed file, without setting any variables.">
200 <cfargument name="text" type="any" required="false"
201 hint="I am the string to be printed. I am required but it's faster to specify that I am not required." />
202 203 <cfset variables.content.append(arguments.text) />
204 205 </cffunction>
206 207 <cffunction name="rawPrintln" returntype="void" access="public" output="false"
208 hint="I print a string to the parsed file, followed by a newline, without setting any variables.">
209 <cfargument name="text" type="any" required="false"
210 hint="I am the string to be printed. I am required but it's faster to specify that I am not required." />
211 212 <cfset variables.content.append(arguments.text).append(variables.newline) />
213 214 </cffunction>
215 216</cfcomponent>