Last active
March 11, 2019 08:20
-
-
Save cfmitrah/6aecb8b398968680267dadba9afcd044 to your computer and use it in GitHub Desktop.
Demo Lucee Event Gateway - Driver Component
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfcomponent output="no"> | |
<cfset variables.logFileName = "demoLogGateway" /> | |
<cfset variables.state="stopped" /> | |
<cffunction name="init" access="public" output="no" returntype="void"> | |
<cfargument name="id" required="false" type="string"> | |
<cfargument name="config" required="false" type="struct"> | |
<cfargument name="listener" required="false" type="component"> | |
<cfset variables.id=id> | |
<cfset variables.config=config> | |
<cfset variables.listener=listener> | |
</cffunction> | |
<cffunction name="start" access="public" output="no" returntype="void"> | |
<cfset var sleepStep = iif(variables.config.interval lt 500, 'variables.config.interval', de(500)) /> | |
<cfset var i=-1 /> | |
<cfwhile variables.state EQ "stopping"> | |
<!--- Loop & wait for 10 ms, until gateway is running ---> | |
<cfset sleep(10)> | |
</cfwhile> | |
<cfset variables.state="running"> | |
<cfset variables._filter = cleanExtensions(variables.config.extensions) /> | |
<cfset logDetails("start", "information")> | |
<cfset var funcNames={add:config.addFunction, change:config.changeFunction, delete:config.deleteFunction}> | |
<!--- check if the directory actually exists ---> | |
<cfif not DirectoryExists(variables.config.directory)> | |
<cfset logDetails("Directory [#variables.config.directory#] does not exist or is not a directory", "error")> | |
</cfif> | |
<cfif not StructKeyExists(variables.config,"recurse")> | |
<cfset variables.config.recurse=false> | |
</cfif> | |
<cfset var files=loadFiles(variables.config.directory, variables.config.recurse, variables._filter) /> | |
<!--- first execution ---> | |
<cfwhile variables.state EQ "running"> | |
<cfset var coll=compareFiles(files,funcNames,config.directory, config.recurse, variables._filter)> | |
<cfset files=coll.data> | |
<cfset var name=""> | |
<cfset var funcName=""> | |
<cfloop collection="#coll.diff#" item="name"> | |
<cfset funcName=coll.diff[name].action> | |
<cfif len(funcName)> | |
<!--- calling listener methods ---> | |
<cfset logDetails("change:::#funcName#:::#name#:::start", "information")> | |
<cfset variables.listener[funcName](coll.diff[name])> | |
<cfset logDetails("change:::#funcName#:::#name#:::done", "information")> | |
</cfif> | |
</cfloop> | |
<cfif variables.state NEQ "running"> | |
<cfbreak /> | |
</cfif> | |
<!--- sleep untill the next run, but cut it into half seconds, so we can stop the gateway ---> | |
<cfloop from="#sleepStep#" to="#variables.config.interval#" step="#sleepStep#" index="i"> | |
<cfset sleep(sleepStep) /> | |
<cfif variables.state neq "running"> | |
<cfbreak /> | |
</cfif> | |
</cfloop> | |
<!--- some extra sleeping if ---> | |
<cfif variables.config.interval mod sleepStep and variables.state eq "running"> | |
<cfset sleep((variables.config.interval mod sleepStep)) /> | |
</cfif> | |
</cfwhile> | |
<cfset variables.state="stopped" /> | |
</cffunction> | |
<cffunction name="loadFiles" access="private" output="no" returntype="struct" hints="Loads the current details of available files"> | |
<cfargument name="directory" type="string" required="yes"> | |
<cfargument name="recurse" type="boolean" required="no" default="#false#"> | |
<cfargument name="fileFilter" type="string" required="no" default="*" /> | |
<cfset var dir = getFiles(arguments.directory, arguments.recurse, arguments.fileFilter) /> | |
<cfset var sct={} /> | |
<cfloop query="dir"> | |
<cfset sct[dir.directory&server.separator.file&dir.name] = createElement(dir) /> | |
</cfloop> | |
<cfreturn sct /> | |
</cffunction> | |
<cffunction name="getFiles" access="private" output="no" returntype="query" hints="List all files in the specified directory with applied filters"> | |
<cfargument name="directory" type="string" required="yes"> | |
<cfargument name="recurse" type="boolean" required="no" default="false" /> | |
<cfargument name="fileFilter" type="string" required="no" default="*" /> | |
<cfset var qDir = "" /> | |
<cfdirectory directory="#arguments.directory#" action="list" name="qDir" type="file" | |
filter="#arguments.fileFilter#" recurse="#arguments.recurse#" /> | |
<cfreturn qDir /> | |
</cffunction> | |
<cffunction name="compareFiles" access="private" output="no" returntype="struct"> | |
<cfargument name="last" type="struct" required="yes"> | |
<cfargument name="funcNames" type="struct" required="yes"> | |
<cfargument name="directory" type="string" required="yes"> | |
<cfargument name="recurse" type="boolean" required="no" default="false" /> | |
<cfargument name="fileFilter" type="string" required="no" default="*" /> | |
<cfset var dir = getFiles(arguments.directory, arguments.recurse, arguments.fileFilter) /> | |
<cfset var sct={}> | |
<cfset var diff={}> | |
<cfset var name=""> | |
<cfset var tmp=""> | |
<!--- check for new and changed files ---> | |
<cfloop query="dir"> | |
<cfset name=dir.directory&server.separator.file&dir.name> | |
<!--- populate the struct with all currently found files/directories ---> | |
<cfset sct[name]=createElement(dir)> | |
<!--- file existed already ---> | |
<cfif StructKeyExists(arguments.last,name)> | |
<!--- date last modified has changed? ---> | |
<cfif dir.dateLastModified NEQ arguments.last[name].dateLastModified> | |
<cfset tmp = createElement(dir)> | |
<cfset tmp.action = arguments.funcNames.change> | |
<cfset diff[name] = tmp> | |
</cfif> | |
<!--- new file ---> | |
<cfelse> | |
<cfset tmp=createElement(dir)> | |
<cfset tmp.action=funcNames.add> | |
<cfset diff[name]=tmp> | |
</cfif> | |
</cfloop> | |
<!--- check if files are deleted ---> | |
<cfloop collection="#last#" item="name"> | |
<cfif not StructKeyExists(sct,name)> | |
<cfset last[name].action=funcNames.delete> | |
<cfset diff[name]=last[name]> | |
</cfif> | |
</cfloop> | |
<cfreturn {data:sct,diff:diff}> | |
</cffunction> | |
<cffunction name="createElement" access="private" output="no" returntype="struct"> | |
<cfargument name="dir" type="query" required="yes"> | |
<cfreturn {dateLastModified:dir.dateLastModified, size:dir.size, name:dir.name, directory:dir.directory,id:variables.id}> | |
</cffunction> | |
<cffunction name="stop" access="public" output="no" returntype="void"> | |
<cfset logDetails("stop", "information")> | |
<cfset variables.state="stopping"> | |
</cffunction> | |
<cffunction name="restart" access="public" output="no" returntype="void"> | |
<cfif state EQ "running"><cfset stop()></cfif> | |
<cfset start()> | |
</cffunction> | |
<cffunction name="getState" access="public" output="no" returntype="string"> | |
<cfreturn variables.state /> | |
</cffunction> | |
<cffunction name="sendMessage" access="public" output="no" returntype="string"> | |
<cfargument name="data" required="true" type="struct"> | |
<cfset variables.listener.checkChange(arguments.data)> | |
<cfreturn true> | |
</cffunction> | |
<cffunction name="cleanExtensions" access="private" output="no" returntype="string"> | |
<cfargument name="extensions" required="true" type="string"> | |
<!--- replace the commas and optional trailing spaces with pipes ("|"), because that's the delimiter cfdirectory works with. ---> | |
<cfreturn rereplace(trim(arguments.extensions), " *, *", "|", "all") /> | |
</cffunction> | |
<cffunction name="_handleError" returntype="void" access="private" output="no"> | |
<cfargument name="catchData" required="yes" /> | |
<cfargument name="functionName" type="string" required="no" default="unknown" /> | |
<cfset logDetails("Function #arguments.functionName#: #arguments.catchData.message# #arguments.catchData.detail#", "error")> | |
</cffunction> | |
<cffunction name="logDetails" returntype="void" access="private" output="no"> | |
<cfargument name="content" required="yes" type="string" /> | |
<cfargument name="type" required="yes" type="string" /> | |
<cflog text="#arguments.content#" type="#arguments.type#" file="#variables.logFileName#" /> | |
</cffunction> | |
</cfcomponent> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment