/* Ċ Ġ* ĠLocal FileManager . kt Ċ Ġ* ĠCopyright ĠÂ© Ġ 1 9 9 3 - 2 0 2 0 , ĠThe ĠAv ail ĠFoundation , ĠLLC . Ċ Ġ* ĠAll Ġrights Ġreserved . Ċ Ġ* Ċ Ġ* ĠRedistribution Ġand Ġuse Ġin Ġsource Ġand Ġbinary Ġforms , Ġwith Ġor Ġwithout Ċ Ġ* Ġmodification , Ġare Ġpermitted Ġprovided Ġthat Ġthe Ġfollowing Ġconditions Ġare Ġmet : Ċ Ġ* Ċ Ġ* Ġ Ġ* ĠRedistributions Ġof Ġsource Ġcode Ġmust Ġretain Ġthe Ġabove Ġcopyright Ġnotice , Ġthis Ċ Ġ* ĠĠĠĠ Ġlist Ġof Ġconditions Ġand Ġthe Ġfollowing Ġdisclaimer . Ċ Ġ* Ċ Ġ* Ġ Ġ* ĠRedistributions Ġin Ġbinary Ġform Ġmust Ġreproduce Ġthe Ġabove Ġcopyright Ġnotice , Ġthis Ċ Ġ* ĠĠĠĠ Ġlist Ġof Ġconditions Ġand Ġthe Ġfollowing Ġdisclaimer Ġin Ġthe Ġdocumentation Ċ Ġ* ĠĠĠĠ Ġand / or Ġother Ġmaterials Ġprovided Ġwith Ġthe Ġdistribution . Ċ Ġ* Ċ Ġ* Ġ Ġ* ĠNeither Ġthe Ġname Ġof Ġthe Ġcopyright Ġholder Ġnor Ġthe Ġnames Ġof Ġthe Ġcontributors Ċ Ġ* ĠĠĠ Ġmay Ġbe Ġused Ġto Ġendorse Ġor Ġpromote Ġproducts Ġderived Ġfrom Ġthis Ġsoftware Ċ Ġ* ĠĠĠ Ġwithout Ġspecific Ġprior Ġwritten Ġpermission . Ċ Ġ* Ċ Ġ* ĠTHIS ĠSOFTWARE ĠIS ĠPROVIDED ĠBY ĠTHE ĠCOPYRIGHT ĠHOLDERS ĠAND ĠCONTRIBUTORS Ġ" AS ĠIS " Ċ Ġ* ĠAND ĠANY ĠEXPRESS ĠOR ĠIMPLIED ĠWARRANTIES , ĠINCLUDING , ĠBUT ĠNOT ĠLIMITED ĠTO , ĠTHE Ċ Ġ* ĠIMPLIED ĠWARRANTIES ĠOF ĠMERCHANTABILITY ĠAND ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE Ċ Ġ* ĠARE ĠDISCLAIMED . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE ĠCOPYRIGHT ĠHOLDER ĠOR ĠCONTRIBUTORS ĠBE Ċ Ġ* ĠLIABLE ĠFOR ĠANY ĠDIRECT , ĠINDIRECT , ĠINCIDENTAL , ĠSPECIAL , ĠEXEMPLARY , ĠOR Ċ Ġ* ĠCONSEQUENTIAL ĠDAMAGES Ġ( INCLUDING , ĠBUT ĠNOT ĠLIMITED ĠTO , ĠPROCUREMENT ĠOF Ċ Ġ* ĠSUBSTITUTE ĠGOODS ĠOR ĠSERVICES ; ĠLOSS ĠOF ĠUSE , ĠDATA , ĠOR ĠPROFITS ; ĠOR ĠBUSINESS Ċ Ġ* ĠINTERRUPTION ) ĠHOWEVER ĠCAUSED ĠAND ĠON ĠANY ĠTHEORY ĠOF ĠLIABILITY , ĠWHETHER ĠIN Ċ Ġ* ĠCONTRACT , ĠSTRICT ĠLIABILITY , ĠOR ĠTORT Ġ( INCLUDING ĠNEGLIGENCE ĠOR ĠOTHERWISE ) Ċ Ġ* ĠARISING ĠIN ĠANY ĠWAY ĠOUT ĠOF ĠTHE ĠUSE ĠOF ĠTHIS ĠSOFTWARE , ĠEVEN ĠIF ĠADVISED ĠOF ĠTHE Ċ Ġ* ĠPOSSIBILITY ĠOF ĠSUCH ĠDAMAGE . Ċ Ġ*/ Ċ Ċ package Ġcom . avail . server . io . files Ċ Ċ import Ġcom . avail . Avail Runtime Ċ import Ġcom . avail . server . error . Server ErrorCode Ċ import Ġjava . io . IOException Ċ import Ġjava . nio . ByteBuffer Ċ import Ġjava . nio . channels . As ynchronous File Channel Ċ import Ġjava . nio . channels . Completion Handler Ċ import Ġjava . nio . file . File AlreadyExists Exception Ċ import Ġjava . nio . file . Files Ċ import Ġjava . nio . file . Paths Ċ import Ġjava . nio . file . Standard Open Option Ċ import Ġjava . util .* Ċ Ċ /** Ċ Ġ* Ġ` Local FileManager ` Ġis Ġa Ġ[ FileManager ] Ġused Ġto Ġmanage Ġfiles Ġwhen Ġa Ġlocal Ġcopy Ċ Ġ* Ġof Ġthe ĠAv ail Server Ġis Ġrunning Ġand Ġis Ġmeant Ġto Ġinteract Ġwith Ġthe Ġhost 's Ġlocal Ċ Ġ* Ġfile Ġsystem . Ċ Ġ* Ċ Ġ* Ġ@ author ĠRichard ĠAr ri aga Ġ& lt ; rich @ avail lang . org & gt ; Ċ Ġ*/ Ċ internal Ġclass ĠLocal FileManager Ġconstructor ( runtime : ĠAv ail Runtime ) Ċ ĉ : ĠFile Manager ( runtime ) Ċ { Ċ ĉ override Ġfun Ġserver File Wrapper ( Ċĉ ĉ id : ĠUUID , Ċĉ ĉ path : ĠString ): ĠServer File Wrapper Ġ= Ċĉĉ ĉ Server File Wrapper ( Ċĉĉĉ ĉ id , Ċĉĉĉ ĉ path , Ċĉĉĉ ĉ this , Ċĉĉĉ ĉ runtime . io System (). open File ( Ċĉĉĉĉ ĉ Paths . get ( path ), Ġfile Open Options )) ĊĊ ĉ override Ġfun ĠreadFile Ġ( Ċĉ ĉ path : ĠString , Ċĉ ĉ consumer : Ġ( UUID , ĠString , ĠByteArray ) Ġ-> ĠUnit , Ċĉ ĉ failure Handler : Ġ( Server ErrorCode , ĠThrowable ?) Ġ-> ĠUnit ): ĠUUID Ċ ĉ { Ċĉ ĉ val Ġuuid : ĠUUID Ċĉ ĉ synchronized ( path To Id Map ) Ċĉ ĉ { Ċĉĉ ĉ uuid Ġ= Ġpath To Id Map . get Or Put ( path ) Ġ{ ĠUUID . randomUUID () Ġ} Ċĉĉ ĉ id To Path Map [ uuid ] Ġ= Ġpath Ċĉ ĉ } Ċĉ ĉ val Ġvalue Ġ= Ġfile Cache [ uuid ] Ċĉ ĉ execute File Task Ġ{ Ċĉĉ ĉ value . value ?. provide ( consumer , Ġfailure Handler ) Ċĉĉ ĉ ?: Ġfailure Handler ( Server ErrorCode . FILE _ NOT _ FOUND , Ġnull ) Ċĉ ĉ } Ċĉ ĉ return Ġuuid Ċ ĉ } ĊĊ ĉ override Ġfun Ġcreate File Ġ( Ċĉ ĉ path : ĠString , Ċĉ ĉ consumer : Ġ( UUID , ĠString , ĠByteArray ) Ġ-> ĠUnit , Ċĉ ĉ failure Handler : Ġ( Server ErrorCode , ĠThrowable ?) Ġ-> ĠUnit ): ĠUUID ? Ċ ĉ { Ċĉ ĉ // ĠTODO Ġshould Ġthe Ġmime Ġtype Ġbe Ġrequired ? Ċĉ ĉ // ĠTODO Ġcheck Ġto Ġsee Ġif Ġthis Ġis Ġreasonable ? Ċĉ ĉ try Ċĉ ĉ { Ċĉĉ ĉ val Ġfile Ġ= ĠAs ynchronous File Channel . open ( Ċĉĉĉ ĉ Paths . get ( path ), Ġfile Create Options , Ġfile Executor ) Ċĉĉ ĉ file . force ( false ) Ċĉĉ ĉ file . close () Ċĉĉ ĉ return ĠreadFile ( path , Ġconsumer , Ġfailure Handler ) Ċĉ ĉ } Ċĉ ĉ catch Ġ( e : ĠFile AlreadyExists Exception ) Ċĉ ĉ { Ċĉĉ ĉ failure Handler ( Server ErrorCode . FILE _ AL READY _ EXISTS , Ġe ) Ċĉ ĉ } Ċĉ ĉ catch Ġ( e : ĠIOException ) Ċĉ ĉ { Ċĉĉ ĉ failure Handler ( Server ErrorCode . IO _ EXCEPTION , Ġe ) Ċĉ ĉ } Ċĉ ĉ return Ġnull Ċ ĉ } ĊĊ ĉ override Ġfun Ġsave File Ġ( Ċĉ ĉ avail Server File : ĠAv ail Server File , Ċĉ ĉ failure Handler : Ġ( Server ErrorCode , ĠThrowable ?) Ġ-> ĠUnit ) Ċ ĉ { Ċĉ ĉ val Ġcontent Ġ= Ġavail Server File . get Save Content () Ċĉ ĉ val Ġdata Ġ= ĠByteBuffer . wrap ( content ) Ċĉ ĉ val Ġsave Time Start Ġ= ĠSystem . currentTimeMillis () Ċĉ ĉ val Ġfile Ġ= Ġruntime . io System (). open File ( Ċĉĉ ĉ Paths . get ( avail Server File . path ), Ċĉĉ ĉ Enum Set . of ( Standard Open Option . TRUNC ATE _ EXIST ING , ĠStandard Open Option . READ , ĠStandard Open Option . WRITE )) Ċĉ ĉ file . write ( Ċĉĉ ĉ data , Ċĉĉĉ 0 , Ċĉĉ ĉ null , Ċĉĉ ĉ object Ġ: ĠCompletion Handler < Int , ĠServer ErrorCode ?> Ġ{ Ċĉĉĉ ĉ override Ġfun Ġcompleted ( result : ĠInt ?, Ġattachment : ĠServer ErrorCode ?) Ċĉĉĉ ĉ { Ċĉĉĉĉ ĉ if Ġ( data . has Remaining ()) Ċĉĉĉĉ ĉ { Ċĉĉĉĉĉ ĉ save ( file , Ġdata , Ġdata . position (). to Long (), Ġfailure Handler ) Ċĉĉĉĉ ĉ } Ċĉĉĉĉ ĉ else Ċĉĉĉĉ ĉ { Ċĉĉĉĉĉ ĉ avail Server File . condition ally Clear Dirty ( save Time Start ) Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } ĊĊĉĉĉ ĉ override Ġfun Ġfailed ( exc : ĠThrowable ?, Ġattachment : ĠServer ErrorCode ?) Ċĉĉĉ ĉ { Ċĉĉĉĉ ĉ failure Handler ( attachment Ġ?: ĠServer ErrorCode . UNSPECIFIED , Ġexc ) Ċĉĉĉ ĉ } Ċĉĉ ĉ }) Ċ ĉ } ĊĊ ĉ /** Ċĉ Ġ* ĠSave Ġthe Ġdata Ġto Ġdisk Ġstarting Ġat Ġthe Ġspecified Ġwrite Ġlocation . Ċĉ Ġ* Ċĉ Ġ* Ġ@ param Ġdata Ċĉ Ġ* ĠĠ ĠThe Ġ[ ByteBuffer ] Ġto Ġsave Ġto Ġdisk Ġfor Ġthis Ġ[ Avail Server File ]. Ċĉ Ġ* Ġ@ param Ġwrite Position Ċĉ Ġ* ĠĠ ĠThe Ġposition Ġin Ġthe Ġfile Ġto Ġstart Ġwriting Ġto . Ċĉ Ġ* Ġ@ param Ġfailure Ċĉ Ġ* ĠĠ ĠA Ġfunction Ġthat Ġaccepts Ġa Ġ[ Server ErrorCode ] Ġthat Ġdescribes Ġthe Ġnature Ċĉ Ġ* ĠĠ Ġof Ġthe Ġfailure Ġand Ġan Ġoptional Ġ[ Throwable ]. Ċĉ Ġ*/ Ċ ĉ private Ġfun Ġsave Ġ( Ċĉ ĉ file : ĠAs ynchronous File Channel , Ċĉ ĉ data : ĠByteBuffer , Ċĉ ĉ write Position : ĠLong , Ċĉ ĉ failure : Ġ( Server ErrorCode , ĠThrowable ?) Ġ-> ĠUnit ) Ċ ĉ { Ċĉ ĉ file . write ( Ċĉĉ ĉ data , Ċĉĉ ĉ write Position , Ċĉĉ ĉ null , Ċ // ĉĉ ĉ Simple Completion Handler < Int , ĠServer ErrorCode ? >( Ċ // ĉĉĉ ĉ { Ġresult , Ġ_, Ġ_ Ġ-> Ċ // ĉĉĉĉ ĉ if Ġ( data . has Remaining ()) Ċ // ĉĉĉĉ ĉ { Ċ // ĉĉĉĉĉ ĉ save ( file , Ġdata , Ġdata . position (). to Long (), Ġfailure ) Ċ // ĉĉĉĉ ĉ } Ċ // ĉĉĉ ĉ }) Ċ // ĉĉ ĉ { Ġe , Ġcode , Ġ_ Ġ-> Ċ // ĉĉĉ ĉ failure ( code Ġ?: ĠServer ErrorCode . UNSPECIFIED , Ġe ) Ċ // ĉĉ ĉ }) Ċĉĉ ĉ object Ġ: ĠCompletion Handler < Int , ĠServer ErrorCode ?> Ġ{ Ċĉĉĉ ĉ override Ġfun Ġcompleted ( result : ĠInt ?, Ġattachment : ĠServer ErrorCode ?) Ċĉĉĉ ĉ { Ċĉĉĉĉ ĉ if Ġ( data . has Remaining ()) Ċĉĉĉĉ ĉ { Ċĉĉĉĉĉ ĉ save ( file , Ġdata , Ġdata . position (). to Long (), Ġfailure ) Ċĉĉĉĉ ĉ } Ċĉĉĉ ĉ } ĊĊĉĉĉ ĉ override Ġfun Ġfailed ( exc : ĠThrowable ?, Ġattachment : ĠServer ErrorCode ?) Ċĉĉĉ ĉ { Ċĉĉĉĉ ĉ failure ( attachment Ġ?: ĠServer ErrorCode . UNSPECIFIED , Ġexc ) Ċĉĉĉ ĉ } Ċĉĉ ĉ }) Ċ ĉ } ĊĊ ĉ override Ġfun Ġdelete Ġ( Ċĉ ĉ path : ĠString , Ċĉ ĉ success : Ġ( UUID ?) Ġ-> ĠUnit , Ċĉ ĉ failure : Ġ( Server ErrorCode , ĠThrowable ?) Ġ-> ĠUnit ) Ċ ĉ { Ċĉ ĉ val Ġremoved Id Ġ= Ġpath To Id Map . remove ( path )?. let Ġ{ id Ġ-> Ċĉĉ ĉ // ĠTODO Ġsend Ġnotifications Ġfile Ġdeleted ? Ċĉĉ ĉ // Ġ Ġmight Ġneed Ġto Ġtrack Ġmore Ġsession - file Ġinterest Ġinfo Ċĉĉ ĉ file Cache . remove ( id ) Ċĉĉ ĉ id To Path Map . remove ( id ) Ċĉĉ ĉ id Ċĉ ĉ } Ċĉ ĉ if Ġ(! Files . delete IfExists ( Paths . get ( path ))) Ċĉ ĉ { Ċĉĉ ĉ failure ( Server ErrorCode . FILE _ NOT _ FOUND , Ġnull ) Ċĉ ĉ } Ċĉ ĉ else Ċĉ ĉ { Ċĉĉ ĉ success ( removed Id ) Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ comp anion Ġobject Ċ ĉ { Ċĉ ĉ /** Ċĉĉ Ġ* ĠThe Ġ[ Enum Set ] Ġof Ġ[ Standard Open Option ] s Ġused Ġwhen Ġopening Ġfiles . Ċĉĉ Ġ*/ Ċĉ ĉ private Ġval Ġfile Open Options Ġ= Ċĉĉ ĉ Enum Set . of ( Standard Open Option . READ , ĠStandard Open Option . WRITE ) Ċ ĉ } Ċ }