package Ġcom . ts are v . fi ot cher . d flt . track ers Ċ Ċ import Ġcom . ts are v . fi ot cher . api . F iot cher Exception Ċ import Ġcom . ts are v . fi ot cher . api . Initial Events B unch Ċ import Ġcom . ts are v . fi ot cher . d flt . Br ake Ċ import Ġcom . ts are v . fi ot cher . d flt . is P ushed Ċ import Ġcom . ts are v . fi ot cher . d flt . push Ċ import Ġcom . ts are v . fi ot cher . internal . Event With Exception Ċ import Ġcom . ts are v . fi ot cher . internal . as Success Ċ import Ġcom . ts are v . fi ot cher . internal . pool . Tracker Ċ import Ġjava . io . File Ċ import Ġjava . util . concurrent .* Ċ import Ġjava . util . concurrent . atomic . Atomic Long Ċ Ċ /** Ċ Ġ* ĠSimple Ġplain Ġfile Ġtracker Ġimplementation Ġthat Ġiter atively Ġchecks Ċ Ġ* Ġfile Ġchange Ġtime . Ċ Ġ*/ Ċ class ĠNa ive File Tracker ( ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠMinimum Ġtime Ġof Ġone Ġwatch Ġiteration Ġin Ġmilliseconds . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġiteration Min Millis : ĠLong Ġ= Ġ 4 0 , ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIf Ġnested Ġdirectories Ġshould Ġbe Ġprocessed . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġrecursive : ĠBoolean Ġ= Ġtrue , ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAn Ġamount Ġof Ġtime Ġto Ġbelieve , Ġthat Ġfile Ġis Ġchanged . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġdoes Change Threshold Millis : ĠLong Ġ= Ġ 1 0 , ĊĊĠĠĠ Ġ) Ġ: ĠTracker < File >() Ġ{ ĊĊĠĠĠ Ġdata Ġclass ĠSt amp With Directory Flag ( val Ġstamp : ĠAtomic Long , Ġval Ġis Directory : ĠBoolean ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAlready Ġdiscovered Ġfiles Ġwith Ġtheir Ġtimestamp . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġdiscovered : ĠConcurrent HashMap < File , ĠSt amp With Directory Flag > Ġ= ĠConcurrent HashMap () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSend Ġevent Ġclosure . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġsend Event : Ġ( Event With Exception < Initial Events B unch < File >>) Ġ-> ĠUnit ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThread Ġthat Ġruns Ġthis Ġtracker . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġtracker Thread : ĠThread ? Ġ= Ġnull ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIf Ġthis Ġtracker Ġis Ġforced Ġto Ġstop . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Volatile ĊĠĠĠ Ġprivate Ġvar Ġis For ced Ġ= Ġfalse ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠStop Ġbr ake . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġval Ġstop Br ake Ġ= ĠBr ake < Unit >() ĊĊĠĠĠ Ġoverride Ġfun Ġdo Init ( ĊĠĠĠĠĠĠĠ Ġexecutor : ĠExecutor , ĊĠĠĠĠĠĠĠ Ġsend Event : Ġ( Event With Exception < Initial Events B unch < File >>) Ġ-> ĠUnit ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! resource Bundle . exists () Ġ|| Ġ! resource Bundle . isDirectory ) Ġthrow ĠF iot cher Exception ("$ resource Bundle Ġis Ġnot Ġa Ġdirectory .") ĊĠĠĠĠĠĠĠ Ġdiscovered [ resource Bundle ] Ġ= ĠSt amp With Directory Flag ( Atomic Long ( 0 ), Ġtrue ) ĊĠĠĠĠĠĠĠ Ġthis . send Event Ġ= Ġsend Event ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġrun () Ġ{ ĊĠĠĠĠĠĠĠ Ġtracker Thread Ġ= ĠThread . currentThread () ĊĠĠĠĠĠĠĠ Ġouter @ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFix Ġis Stopped Ġstate Ġto Ġallow Ġlast Ġgrace ful Ġwatch Ġiteration . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġis Stopped Fixed Ġ= Ġis Stopped ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdiscovered Copy Ġ= Ġdiscovered . entries . sorted By Ġ{ Ġit . key . absolute Path Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġiteration Min Finish Time Ġ= ĠSystem . currentTimeMillis () Ġ+ Ġiteration Min Millis ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( file , Ġstamp ) Ġin Ġdiscovered Copy ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck Ġis Ġforced Ġstate . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is For ced ) Ġbreak @ outer ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWatch Ġall Ġcommon Ġfiles . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck File ( file ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck Ġis Ġforced Ġstate . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is For ced ) Ġbreak @ outer ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWatch Ġall Ġdirectory Ġcontents . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( stamp . isDirectory ) Ġcheck Directory ( file ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Stopped Fixed Ġ|| Ġtracker Thread ?. is Inter rupted Ġ== Ġtrue ) Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremaining Ġ= Ġiteration Min Finish Time Ġ- ĠSystem . currentTimeMillis () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( remaining Ġ>= Ġ 0 ) ĠThread . sleep ( remaining ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( cause : ĠInterruptedException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . stop ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠComplete Ġbr ake Ġhandler . ĊĠĠĠĠĠĠĠ Ġstop Br ake . push (). complete ( Unit ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCheck Ġif Ġfile Ġis Ġupdated Ġsince Ġlast Ġwatch . ĊĠĠĠĠ Ġ* ĠIf Ġfile Ġis Ġremoved , Ġso Ġit Ġis Ġremoved Ġfrom Ġdiscovered . ĊĠĠĠĠ Ġ* ĠIf Ġfile Ġis Ġdiscovered Ġat Ġfirst Ġtime , Ġso Ġit Ġis Ġadded Ġto Ġ[ dis covered ] Ġmap . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġcheck File ( file : ĠFile ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! file . exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdiscovered . remove ( file ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdir Stamp Ġ= Ġdiscovered . compute If Absent ( file ) Ġ{ ĠSt amp With Directory Flag ( Atomic Long ( 0 ), Ġfile . isDirectory ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast Modified Ġ= Ġfile . lastModified () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnow Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast W atched Ġ= Ġdir Stamp . stamp . update AndGet Ġ{ Ġprevious Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( previous Ġ+ Ġdoes Change Threshold Millis Ġ< Ġlast Modified ) Ġnow Ġelse Ġprevious ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( last W atched Ġ== Ġnow ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! dir Stamp . isDirectory Ġ&& Ġ! is For ced ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠEx ists Ġcheck Ġmust Ġbe Ġthe Ġlast , Ġsince Ġfile Ġcan Ġbe Ġdeleted Ġand ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdespite Ġthis Ġhave Ġmodified Ġtime . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( file . exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Event ( Initial Events B unch ( listOf ( file )). as Success ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCheck Ġfor Ġdirectory Ġcontents . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġcheck Directory ( file : ĠFile ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! file . isDirectory ) Ġreturn ĊĠĠĠĠĠĠĠ Ġelse Ġif Ġ( file Ġ!== Ġresource Bundle Ġ&& Ġ! recursive ) Ġreturn ĊĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinner Files Ġ= Ġfile . list Files () Ġ?: Ġempty Array () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( inner File Ġin Ġinner Files ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck Ġis Ġforced Ġstate . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is For ced ) Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck File ( inner File ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠStop Ġprocessing . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġdo Stop ( force : ĠBoolean , Ġexception : ĠThrowable ?) Ġ= Ġstop Br ake . push Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( force ) Ġtracker Thread ?. interrupt () ĊĠĠĠĠĠĠĠ Ġis For ced Ġ= Ġforce ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġval Ġis Stopped Ġget () Ġ= Ġstop Br ake . is P ushed Ċ }