Sorcerer's IsleCode QueryParam Scanner / files

     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>