/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 ĠMark . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġres aver . gui Ċ Ċ import Ġmu . K Log gable Ċ import Ġmu . K Logger Ċ import Ġjava . awt . event . Window Adapter Ċ import Ġjava . awt . event . Window Event Ċ import Ġjava . io . IOException Ċ import Ġjava . nio . file .* Ċ import Ġjavax . swing . JOptionPane Ċ import Ġjavax . swing . Swing Worker Ċ Ċ /** Ċ Ġ* Ċ Ġ* Ġ@ author ĠMark Ċ Ġ*/ Ċ class ĠWatch er ( window : ĠSave Window ?, Ġwor rier : Ġess . pap yr us . W or rier ?) Ġ{ ĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġstart ( new Watch Dir : ĠPath ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire (!( new Watch Dir Ġ!= Ġnull Ġ&& Ġ! Configurator . valid Dir ( new Watch Dir ))) Ġ{ Ġ" Invalid Ġwatch Ġdirectory ." Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ(! isRunning Ġ|| Ġwatch Dir Ġ!= Ġnew Watch Dir ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstop () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwatch Dir Ġ= Ġnew Watch Dir ĊĠĠĠĠĠĠĠĠĠĠĠ Ġworker Ġ= ĠWatch Worker () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġworker !!. execute () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġresume () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( isRunning ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġworker Ġ= ĠWatch Worker () ĊĠĠĠĠĠĠĠ Ġworker !!. execute () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġstop () Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ( isRunning ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġworker !!. cancel ( true ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġworker Ġ= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġis Running : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġworker Ġ!= Ġnull Ġ&& Ġ! worker !!. is Done ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ author ĠMark ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinternal Ġinner Ġclass ĠWatch Worker Ġ: ĠSw ing Worker < Path ?, ĠDouble ?> () Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return Ġ@ throws ĠException ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Synchron ized ĊĠĠĠĠĠĠĠ Ġ@ Throws ( Exception :: class ) ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġdo In Background (): ĠPath ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġwatch Directories : ĠList < Path > Ġ= Ġif Ġ( null Ġ!= Ġwatch Dir ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( watch Dir !! ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlist : ĠMutable List < Path > Ġ= ĠArrayList () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( VALUE Ġin Ġres aver . Game . VALUES ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsave Directory Ġ= ĠConfigurator . get Save Directory ( VALUE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Files . exists ( save Directory )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlist . add ( save Directory ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlist ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠFS Ġ= ĠFileSystem s . getDefault () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFS . new Watch Service (). use Ġ{ ĠW ATCH SERVICE Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠREG KEYS : ĠMutable Map < Watch Key , ĠPath > Ġ= ĠHashMap () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( dir Ġin Ġwatch Directories ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info {" WATCH ER : Ġinitializing Ġfor Ġ$ dir "} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠREG KEYS [ dir . register ( WATCH SERVICE , ĠStandard Watch Event Kinds . ENTRY _ CREATE )] Ġ= Ġdir ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠEVENT KEY Ġ= ĠW ATCH SERVICE . take () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// final ĠWatch Key ĠEVENT KEY Ġ= ĠW ATCH SERVICE . poll ( 1 , ĠTimeUnit . SECONDS ); ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( EVENT KEY Ġ== Ġnull Ġ|| Ġ! EVENT KEY . isValid ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info {" INVALID ĠEVENT KEY "} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( event Ġin ĠEVENT KEY . poll Events ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( event . kind () Ġ=== ĠStandard Watch Event Kinds . OVER FLOW ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info {" WATCH ER ĠOVER FLOW "} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠNAME Ġ= Ġ( event Ġas ĠWatch Event < Path ?> ). context () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠFULL Ġ= ĠREG KEYS [ EVENT KEY ] !!. resolve ( NAME !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Files . exists ( FULL ) Ġ&& ĠMATCH ER . matches ( FULL )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info {" WATCH ER : ĠTrying Ġto Ġopen Ġ$ FULL ." } ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġi Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( i Ġ< Ġ 5 0 Ġ&& Ġ! Files . is Readable ( FULL )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info {" Waiting Ġfor Ġ$ FULL Ġto Ġbe Ġreadable ." } ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// this . wait ( 2 5 0 , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġi ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Configurator . validate Save game ( FULL )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠOP ENER Ġ= ĠOp ener ( WINDOW , ĠFULL , ĠW OR RI ER , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOP ENER . execute () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info {" WATCH ER : ĠInvalid Ġfile Ġ$ FULL ." } ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! EVENT KEY . reset ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠInterruptedException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info {" Watcher Service Ġinterrupted ." } ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠClosed Watch ServiceException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info {" Watcher Service Ġinterrupted ." } ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠMSG Ġ= Ġ" Error .\ n ${ ex . message }" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠJOptionPane . showMessageDialog ( WINDOW , ĠMSG , Ġ" Watch ĠError ", ĠJOptionPane . ERROR _ MESSAGE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info ( ex ) Ġ{" Watcher ĠError ." Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġwatch Dir ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval ĠWINDO W : ĠSave Window Ġ= Ġwindow !! ĊĠĠĠ Ġprivate Ġval ĠW OR RI ER : Ġess . pap yr us . W or rier Ġ= Ġwor rier !! ĊĠĠĠ Ġprivate Ġvar Ġworker : ĠWatch Worker ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġwatch Dir : ĠPath ? Ġ= Ġnull ĊĊĠĠĠ Ġcompanion Ġobject : K Log gable Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠMATCH ER Ġ= ĠFileSystem s . getDefault (). getPath Matcher (" glob :** .{ fos , ess }") ĊĠĠĠĠĠĠĠ Ġoverride Ġval Ġlogger : ĠK Logger ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget () Ġ= Ġlogger () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġwindow ĊĠĠĠĠ Ġ* Ġ@ param Ġwor rier ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ ĠWINDO W . add WindowListener ( object Ġ: ĠWindow Adapter () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġwindow Closing ( e : ĠWindow Event ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstop () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} Ċ }