package Ġno . ve g ves en . saga . modules . shared . blob storage Ċ Ċ import Ġarrow . core . Either Ċ import Ġarrow . core . right Ċ import Ġarrow . core . right If NotNull Ċ import Ġno . ve g ves en . saga . modules . shared . ContentType Ċ import Ġjava . util . concurrent . Concurrent HashMap Ċ Ċ open Ġclass ĠIn Memory Blob Storage Ġ: ĠBlob Storage , ĠBlob Storage Browser Ġ{ ĊĠĠĠ Ġclass ĠFile ( val Ġbytes : ĠByteArray , Ġval Ġmetadata : ĠFile Metadata ) ĊĊĠĠĠ Ġprotected Ġval Ġfiles Ġ= ĠConcurrent HashMap < Storage Path , ĠFile >() ĊĊĠĠĠ Ġfun Ġclear Files () Ġ= Ġfiles . clear () ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġdelete File ( storage Path : ĠStorage Path ): ĠEither < Throwable , ĠBoolean > Ġ= ĊĠĠĠĠĠĠĠ Ġ( files . remove ( storage Path ) Ġ!= Ġnull ). right () ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġsave File ( ĊĠĠĠĠĠĠĠ Ġstorage Path : ĠStorage Path , ĊĠĠĠĠĠĠĠ Ġfile Content : ĠByteArray , ĊĠĠĠĠĠĠĠ ĠcontentType : ĠContentType , ĊĠĠĠĠĠĠĠ Ġoptions : ĠSave File Options ĊĠĠĠ Ġ): ĠEither < Throwable , ĠUnit > Ġ{ ĊĠĠĠĠĠĠĠ Ġfiles [ storage Path ] Ġ= ĠFile ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile Content , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile Metadata ( storage Path , ĠcontentType , Ġoptions ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġreturn ĠUnit . right () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfile Metadata ( ĊĠĠĠĠĠĠĠ Ġstorage Path : ĠStorage Path , ĊĠĠĠĠĠĠĠ ĠcontentType : ĠContentType , ĊĠĠĠĠĠĠĠ Ġoptions : ĠSave File Options ĊĠĠĠ Ġ) Ġ= ĠFile Metadata ( ĊĠĠĠĠĠĠĠ Ġstorage Path . fileName , ĊĠĠĠĠĠĠĠ ĠcontentType , ĊĠĠĠĠĠĠĠ Ġoptions . custom Time , ĊĠĠĠĠĠĠĠ Ġif Ġ( options . gzip Content ) Ġ" gzip " Ġelse Ġnull , ĊĠĠĠĠĠĠĠ Ġoptions . custom Metadata ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġsave File IfNot Existing ( ĊĠĠĠĠĠĠĠ Ġstorage Path : ĠStorage Path , ĊĠĠĠĠĠĠĠ Ġfile Content : ĠByteArray , ĊĠĠĠĠĠĠĠ ĠcontentType : ĠContentType , ĊĠĠĠĠĠĠĠ Ġoptions : ĠSave File Options ĊĠĠĠ Ġ): ĠEither < Throwable , ĠBoolean > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġshould Add Ġ= Ġ! files . containsKey ( storage Path ) ĊĠĠĠĠĠĠĠ Ġif Ġ( should Add ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfiles [ storage Path ] Ġ= ĠFile ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Content , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Metadata ( storage Path , ĠcontentType , Ġoptions ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġreturn Ġshould Add . right () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġload File ( ĊĠĠĠĠĠĠĠ Ġstorage Path : ĠStorage Path , ĊĠĠĠĠĠĠĠ Ġoptions : ĠLoad File Options ĊĠĠĠ Ġ): ĠEither < Blob Storage Error , ĠByteArray > Ġ= ĊĠĠĠĠĠĠĠ Ġfiles [ storage Path ]?. bytes . right If NotNull Ġ{ ĠBlob Storage Error . Blob NotFound ( storage Path ) Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġrewrite File ( storage Path : ĠStorage Path ): ĠEither < Blob Storage Error , ĠUnit > Ġ= ĊĠĠĠĠĠĠĠ Ġfiles [ storage Path ]. right If NotNull Ġ{ ĠBlob Storage Error . Blob NotFound ( storage Path ) Ġ}. map Ġ{ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġcheck If File Exists ( storage Path : ĠStorage Path ): ĠEither < Throwable , ĠBoolean > Ġ= ĊĠĠĠĠĠĠĠ Ġfiles . containsKey ( storage Path ). right () ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġcopy File ( from : ĠStorage Path , Ġto : ĠStorage Path ): ĠEither < Blob Storage Error , ĠStorage Path > Ġ= ĊĠĠĠĠĠĠĠ Ġfiles [ from ]. right If NotNull Ġ{ ĠBlob Storage Error . Blob NotFound ( from ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġfiles [ to ] Ġ= ĠFile ( it . bytes . clone (), Ġit . metadata ); Ġto Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġlist Files ( bucket : ĠString ): ĠEither < Throwable , ĠList < File Metadata >> Ġ= ĊĠĠĠĠĠĠĠ Ġfiles . filter Ġ{ Ġit . key . bucketName Ġ== Ġbucket Ġ}. values . map Ġ{ Ġit . metadata Ġ}. right () ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun ĠgetFile Metadata ( storage Path : ĠStorage Path ): ĠEither < Blob Storage Error , ĠFile Metadata > Ġ= ĊĠĠĠĠĠĠĠ Ġfiles [ storage Path ]?. metadata . right If NotNull Ġ{ ĠBlob Storage Error . Blob NotFound ( storage Path ) Ġ} Ċ } Ċ