/** Ċ Ġ* ĠCopyright Ġ 2 0 1 0 Ġ- Ġ 2 0 1 9 ĠJetBrains Ġs . r . o . Ċ Ġ* Ċ Ġ* Ġ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 Ġjet brains . ex od us . entity store Ċ Ċ import Ġjet brains . ex od us . TestUtil Ċ import Ġjet brains . ex od us . backup . Backup Bean Ċ import Ġjet brains . ex od us . backup . Backup Strategy Ċ import Ġjet brains . ex od us . backup . Virtual FileDescriptor Ċ import Ġjet brains . ex od us . core . execution . Job Ċ import Ġjet brains . ex od us . core . execution . Job Processor ExceptionHandler Ċ import Ġjet brains . ex od us . core . execution . Thread Job Processor Ċ import Ġjet brains . ex od us . util . Compress Backup Util Ċ import Ġjet brains . ex od us . util . IO Util Ċ import Ġjet brains . ex od us . util . Random Ċ import Ġjunit . framework . TestCase Ċ import Ġorg . apache . commons . compress . arch ivers . zip . Zip File Ċ import Ġjava . io . File Ċ import Ġjava . io . File OutputStream Ċ import Ġjava . io . IOException Ċ Ċ class ĠBackup Tests Ġ: ĠEntity Store TestBase () Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġneeds Implicit Txn (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( Exception :: class ) ĊĠĠĠ Ġfun Ġtest Sing ular () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstore Ġ= Ġentity Store ĊĠĠĠĠĠĠĠ Ġstore . config . max In Place Blob Size Ġ= Ġ 0 Ġ// Ġno Ġin - place Ġblobs ĊĠĠĠĠĠĠĠ Ġval Ġrandom Description Ġ= ĠarrayOf Null s < String >( 1 ) ĊĠĠĠĠĠĠĠ Ġstore . execute In Transaction Ġ{ Ġtxn Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġissue Ġ= Ġtxn . new Entity (" Issue ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrandom Description [ 0 ] Ġ= ĠMath . random (). toString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġissue . set Blob String (" description ", Ġrandom Description [ 0 ] !! ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġbackup Dir Ġ= ĠTest Util . create TempDir () ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbackup Ġ= ĠCompress Backup Util . backup ( store , Ġbackup Dir , Ġnull , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrestore Dir Ġ= ĠTest Util . create TempDir () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġextract Ent ire Zip ( backup , Ġrestore Dir ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Store Ġ= ĠPersistent Entity Stores . newInstance ( restore Dir ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Store . use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Store . execute In Readonly Transaction Ġ{ Ġtxn Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( 1 , Ġtxn . getAll (" Issue "). size ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġissue Ġ= Ġtxn . getAll (" Issue "). first ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertNotNull ( issue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( random Description [ 0 ], Ġissue !!. get Blob String (" description ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIO Util . delete Re cursively ( restore Dir ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠIO Util . delete Re cursively ( backup Dir ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( Exception :: class ) ĊĠĠĠ Ġfun Ġtest St ress () Ġ{ ĊĠĠĠĠĠĠĠ Ġdo St ress Test ( false ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( Exception :: class ) ĊĠĠĠ Ġfun Ġtest St ress With Backup Bean () Ġ{ ĊĠĠĠĠĠĠĠ Ġdo St ress Test ( true ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( Exception :: class ) ĊĠĠĠ Ġfun Ġtest Inter rupted Is Deleted () Ġ{ ĊĠĠĠĠĠĠĠ Ġtest Sing ular () ĊĠĠĠĠĠĠĠ Ġval Ġbackup Dir Ġ= ĠTest Util . create TempDir () ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstore Backup Strategy Ġ= Ġentity Store . backup Strategy ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbackup Ġ= ĠCompress Backup Util . backup ({ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject Ġ: ĠBackup Strategy () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Throws ( Exception :: class ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġbefore Backup () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstore Backup Strategy . before Backup () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġget Contents (): ĠIterable < Virtual FileDescriptor > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġstore Backup Strategy . contents ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Throws ( Exception :: class ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġafter Backup () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstore Backup Strategy . after Backup () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġis Inter rupted (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġaccept File ( file : ĠVirtual FileDescriptor ): ĠLong Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġstore Backup Strategy . accept File ( file ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}, Ġbackup Dir , Ġnull , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertFalse ( backup . exists ()) ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠIO Util . delete Re cursively ( backup Dir ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( Exception :: class ) ĊĠĠĠ Ġfun Ġdo St ress Test ( use Backup Bean : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstore Ġ= Ġentity Store ĊĠĠĠĠĠĠĠ Ġstore . config . max In Place Blob Size Ġ= Ġ 0 Ġ// Ġno Ġin - place Ġblobs ĊĠĠĠĠĠĠĠ Ġval Ġissue Count Ġ= Ġ 1 0 0 0 ĊĠĠĠĠĠĠĠ Ġstore . execute In Transaction Ġ{ Ġtxn Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġissue Count ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġissue Ġ= Ġtxn . new Entity (" Issue ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġissue . set Blob String (" description ", ĠMath . random (). toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġrnd Ġ= ĠRandom () ĊĠĠĠĠĠĠĠ Ġval Ġfinish Ġ= Ġboolean ArrayOf ( false ) ĊĠĠĠĠĠĠĠ Ġval Ġbackground Changes Ġ= Ġint ArrayOf ( 0 ) ĊĠĠĠĠĠĠĠ Ġval Ġthread Count Ġ= Ġ 4 ĊĠĠĠĠĠĠĠ Ġval Ġthreads Ġ= ĠarrayOf Null s < Thread Job Processor >( thread Count ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġthreads . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthreads [ i ] Ġ= ĠThread Job Processor (" Backup Test ĠJob ĠProcessor Ġ$ i "). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstart () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexception Handler Ġ= ĠJob Processor ExceptionHandler Ġ{ Ġ_, Ġ_, Ġt Ġ-> Ġprintln ( t . toString ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġqueue ( object Ġ: ĠJob () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Throws ( Throwable :: class ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġexecute () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ(! finish [ 0 ]) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstore . execute In Transaction Ġ{ Ġtxn Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġissue Ġ= Ġtxn . getAll (" Issue "). skip ( rnd . nextInt ( issue Count Ġ- Ġ 1 )). first ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTestCase . assertNotNull ( issue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġissue !!. set Blob String (" description ", ĠMath . random (). toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprint ("\ r " Ġ+ Ġ++ background Changes [ 0 ]) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠThread . sleep ( 1 0 0 0 ) ĊĠĠĠĠĠĠĠ Ġval Ġbackup Dir Ġ= ĠTest Util . create TempDir () ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbackup Ġ= ĠCompress Backup Util . backup ( if Ġ( use Backup Bean ) ĠBackup Bean ( store ) Ġelse Ġstore , Ġbackup Dir , Ġnull , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfinish [ 0 ] Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrestore Dir Ġ= ĠTest Util . create TempDir () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġextract Ent ire Zip ( backup , Ġrestore Dir ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Store Ġ= ĠPersistent Entity Stores . newInstance ( restore Dir ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Store . use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast Used Blob Handle Ġ= Ġlong ArrayOf (- 1 L ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Store . execute In Readonly Transaction Ġ{ Ġt Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtxn Ġ= Ġt Ġas ĠPersistent Store Transaction ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTestCase . assertEquals ( issue Count . to Long (), Ġtxn . getAll (" Issue "). size ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Used Blob Handle [ 0 ] Ġ= Ġnew Store . get Sequence ( txn , ĠPersistent Entity Store Impl . BLOB _ HAND LES _ SEQUENCE ). load Value ( txn ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( issue Ġin Ġtxn . getAll (" Issue ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdescription Ġ= Ġissue . get Blob String (" description ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTestCase . assertNotNull ( description ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTestCase . assertFalse ( description !!. isEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġblob Vault Ġ= Ġnew Store . blob Vault . source Vault Ġas ĠFileSystem Blob Vault ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( fd Ġin Ġblob Vault . backup Strategy . contents ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( fd Ġas ĠBackup Strategy . FileDescriptor ). file ?. let Ġ{ Ġfile Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( file . isFile Ġ&& Ġfile . name Ġ!= ĠFileSystem Blob Vault Old . VERSION _ FILE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTestCase . assertTrue ("" Ġ+ Ġblob Vault . get Blob Handle By File ( file ) Ġ+ Ġ" Ġ> Ġ" Ġ+ Ġlast Used Blob Handle [ 0 ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblob Vault . get Blob Handle By File ( file ) Ġ<= Ġlast Used Blob Handle [ 0 ]) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIO Util . delete Re cursively ( restore Dir ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠIO Util . delete Re cursively ( backup Dir ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfor Ġ( thread Ġin Ġthreads ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthread ?. finish () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠĠĠĠĠ Ġfun Ġextract Ent ire Zip ( zip : ĠFile , Ġrestore Dir : ĠFile ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠZip File ( zip ). use Ġ{ Ġzip File Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġzip Entries Ġ= Ġzip File . entries ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( zip Entries . hasMore Elements ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġzip Entry Ġ= Ġzip Entries . nextElement () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentry File Ġ= ĠFile ( restore Dir , Ġzip Entry . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( zip Entry . isDirectory ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry File . mkdir s () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry File . parent File . mkdir s () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFileOutputStream ( entry File ). use Ġ{ Ġtarget Ġ-> Ġzip File . getInputStream ( zip Entry ). use Ġ{ Ġ` in ` Ġ-> ĠIO Util . copy Streams (` in `, Ġtarget , ĠIO Util . BUFFER _ ALLOC ATOR ) Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ } Ċ