Skip to content

Commit 223b240

Browse files
Isira-Seneviratnetheimpulson
authored andcommitted
Refactor zip import/export using Path
1 parent 668af4f commit 223b240

6 files changed

Lines changed: 67 additions & 86 deletions

File tree

app/src/main/java/org/schabi/newpipe/settings/BackupRestoreSettingsFragment.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import org.schabi.newpipe.util.NavigationHelper;
3636
import org.schabi.newpipe.util.ZipHelper;
3737

38-
import java.io.File;
3938
import java.io.IOException;
4039
import java.text.SimpleDateFormat;
4140
import java.util.Date;
@@ -70,13 +69,12 @@ public void onAttach(@NonNull final Context context) {
7069
@Override
7170
public void onCreatePreferences(@Nullable final Bundle savedInstanceState,
7271
@Nullable final String rootKey) {
73-
final File homeDir = ContextCompat.getDataDir(requireContext());
74-
Objects.requireNonNull(homeDir);
75-
manager = new ImportExportManager(new BackupFileLocator(homeDir));
72+
final var dbDir = Objects.requireNonNull(ContextCompat.getDataDir(requireContext()))
73+
.toPath();
74+
manager = new ImportExportManager(new BackupFileLocator(dbDir));
7675

7776
importExportDataPathKey = getString(R.string.import_export_data_path);
7877

79-
8078
addPreferencesFromResourceRegistry();
8179

8280
final Preference importDataPreference = requirePreference(R.string.import_data);
@@ -204,9 +202,7 @@ private void importDatabase(final StoredFileHelper file, final Uri importDataUri
204202
}
205203

206204
try {
207-
if (!manager.ensureDbDirectoryExists()) {
208-
throw new IOException("Could not create databases dir");
209-
}
205+
manager.ensureDbDirectoryExists();
210206

211207
// replace the current database
212208
if (!manager.extractDb(file)) {
Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package org.schabi.newpipe.settings.export
22

3-
import java.io.File
3+
import java.nio.file.Path
4+
import kotlin.io.path.div
45

56
/**
67
* Locates specific files of NewPipe based on the home directory of the app.
78
*/
8-
class BackupFileLocator(private val homeDir: File) {
9+
class BackupFileLocator(homeDir: Path) {
910
companion object {
1011
const val FILE_NAME_DB = "newpipe.db"
1112

@@ -17,13 +18,9 @@ class BackupFileLocator(private val homeDir: File) {
1718
const val FILE_NAME_JSON_PREFS = "preferences.json"
1819
}
1920

20-
val dbDir by lazy { File(homeDir, "/databases") }
21-
22-
val db by lazy { File(dbDir, FILE_NAME_DB) }
23-
24-
val dbJournal by lazy { File(dbDir, "$FILE_NAME_DB-journal") }
25-
26-
val dbShm by lazy { File(dbDir, "$FILE_NAME_DB-shm") }
27-
28-
val dbWal by lazy { File(dbDir, "$FILE_NAME_DB-wal") }
21+
val dbDir = homeDir / "databases"
22+
val db = homeDir / FILE_NAME_DB
23+
val dbJournal = homeDir / "$FILE_NAME_DB-journal"
24+
val dbShm = dbDir / "$FILE_NAME_DB-shm"
25+
val dbWal = dbDir / "$FILE_NAME_DB-wal"
2926
}

app/src/main/java/org/schabi/newpipe/settings/export/ImportExportManager.kt

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import java.io.FileNotFoundException
99
import java.io.IOException
1010
import java.io.ObjectOutputStream
1111
import java.util.zip.ZipOutputStream
12+
import kotlin.io.path.createDirectories
13+
import kotlin.io.path.deleteExisting
1214
import org.schabi.newpipe.streams.io.SharpOutputStream
1315
import org.schabi.newpipe.streams.io.StoredFileHelper
1416
import org.schabi.newpipe.util.ZipHelper
@@ -28,11 +30,8 @@ class ImportExportManager(private val fileLocator: BackupFileLocator) {
2830
// previous file size, the file will retain part of the previous content and be corrupted
2931
ZipOutputStream(SharpOutputStream(file.openAndTruncateStream()).buffered()).use { outZip ->
3032
// add the database
31-
ZipHelper.addFileToZip(
32-
outZip,
33-
BackupFileLocator.FILE_NAME_DB,
34-
fileLocator.db.path
35-
)
33+
val name = BackupFileLocator.FILE_NAME_DB
34+
ZipHelper.addFileToZip(outZip, name, fileLocator.db)
3635

3736
// add the legacy vulnerable serialized preferences (will be removed in the future)
3837
ZipHelper.addFileToZip(
@@ -61,11 +60,10 @@ class ImportExportManager(private val fileLocator: BackupFileLocator) {
6160

6261
/**
6362
* Tries to create database directory if it does not exist.
64-
*
65-
* @return Whether the directory exists afterwards.
6663
*/
67-
fun ensureDbDirectoryExists(): Boolean {
68-
return fileLocator.dbDir.exists() || fileLocator.dbDir.mkdir()
64+
@Throws(IOException::class)
65+
fun ensureDbDirectoryExists() {
66+
fileLocator.dbDir.createDirectories()
6967
}
7068

7169
/**
@@ -75,16 +73,13 @@ class ImportExportManager(private val fileLocator: BackupFileLocator) {
7573
* @return true if the database was successfully extracted, false otherwise
7674
*/
7775
fun extractDb(file: StoredFileHelper): Boolean {
78-
val success = ZipHelper.extractFileFromZip(
79-
file,
80-
BackupFileLocator.FILE_NAME_DB,
81-
fileLocator.db.path
82-
)
76+
val name = BackupFileLocator.FILE_NAME_DB
77+
val success = ZipHelper.extractFileFromZip(file, name, fileLocator.db)
8378

8479
if (success) {
85-
fileLocator.dbJournal.delete()
86-
fileLocator.dbWal.delete()
87-
fileLocator.dbShm.delete()
80+
fileLocator.dbJournal.deleteExisting()
81+
fileLocator.dbWal.deleteExisting()
82+
fileLocator.dbShm.deleteExisting()
8883
}
8984

9085
return success

app/src/main/java/org/schabi/newpipe/util/ZipHelper.java

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
import java.io.BufferedInputStream;
77
import java.io.ByteArrayInputStream;
88
import java.io.ByteArrayOutputStream;
9-
import java.io.File;
10-
import java.io.FileInputStream;
11-
import java.io.FileOutputStream;
129
import java.io.IOException;
1310
import java.io.InputStream;
1411
import java.io.OutputStream;
12+
import java.nio.file.Files;
13+
import java.nio.file.Path;
14+
import java.nio.file.StandardCopyOption;
1515
import java.util.zip.ZipEntry;
1616
import java.util.zip.ZipInputStream;
1717
import java.util.zip.ZipOutputStream;
@@ -55,17 +55,17 @@ private ZipHelper() { }
5555

5656

5757
/**
58-
* This function helps to create zip files. Caution this will overwrite the original file.
58+
* This function helps to create zip files. Caution, this will overwrite the original file.
5959
*
6060
* @param outZip the ZipOutputStream where the data should be stored in
6161
* @param nameInZip the path of the file inside the zip
62-
* @param fileOnDisk the path of the file on the disk that should be added to zip
62+
* @param path the path of the file on the disk that should be added to zip
6363
*/
6464
public static void addFileToZip(final ZipOutputStream outZip,
6565
final String nameInZip,
66-
final String fileOnDisk) throws IOException {
67-
try (FileInputStream fi = new FileInputStream(fileOnDisk)) {
68-
addFileToZip(outZip, nameInZip, fi);
66+
final Path path) throws IOException {
67+
try (var inputStream = Files.newInputStream(path)) {
68+
addFileToZip(outZip, nameInZip, inputStream);
6969
}
7070
}
7171

@@ -113,33 +113,18 @@ public static void addFileToZip(final ZipOutputStream outZip,
113113
}
114114

115115
/**
116-
* This will extract data from ZipInputStream. Caution this will overwrite the original file.
116+
* This will extract data from ZipInputStream. Caution, this will overwrite the original file.
117117
*
118118
* @param zipFile the zip file to extract from
119119
* @param nameInZip the path of the file inside the zip
120-
* @param fileOnDisk the path of the file on the disk where the data should be extracted to
120+
* @param path the path of the file on the disk where the data should be extracted to
121121
* @return will return true if the file was found within the zip file
122122
*/
123123
public static boolean extractFileFromZip(final StoredFileHelper zipFile,
124124
final String nameInZip,
125-
final String fileOnDisk) throws IOException {
126-
return extractFileFromZip(zipFile, nameInZip, input -> {
127-
// delete old file first
128-
final File oldFile = new File(fileOnDisk);
129-
if (oldFile.exists()) {
130-
if (!oldFile.delete()) {
131-
throw new IOException("Could not delete " + fileOnDisk);
132-
}
133-
}
134-
135-
final byte[] data = new byte[BUFFER_SIZE];
136-
try (FileOutputStream outFile = new FileOutputStream(fileOnDisk)) {
137-
int count;
138-
while ((count = input.read(data)) != -1) {
139-
outFile.write(data, 0, count);
140-
}
141-
}
142-
});
125+
final Path path) throws IOException {
126+
return extractFileFromZip(zipFile, nameInZip, input ->
127+
Files.copy(input, path, StandardCopyOption.REPLACE_EXISTING));
143128
}
144129

145130
/**

app/src/test/java/org/schabi/newpipe/settings/ImportAllCombinationsTest.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package org.schabi.newpipe.settings
33
import android.content.SharedPreferences
44
import java.io.File
55
import java.io.IOException
6-
import java.nio.file.Files
6+
import kotlin.io.path.createTempFile
7+
import kotlin.io.path.exists
8+
import kotlin.io.path.fileSize
79
import org.junit.Assert
810
import org.junit.Test
911
import org.mockito.Mockito
@@ -47,10 +49,10 @@ class ImportAllCombinationsTest {
4749
BackupFileLocator::class.java,
4850
Mockito.withSettings().stubOnly()
4951
)
50-
val db = File.createTempFile("newpipe_", "")
51-
val dbJournal = File.createTempFile("newpipe_", "")
52-
val dbWal = File.createTempFile("newpipe_", "")
53-
val dbShm = File.createTempFile("newpipe_", "")
52+
val db = createTempFile("newpipe_", "")
53+
val dbJournal = createTempFile("newpipe_", "")
54+
val dbWal = createTempFile("newpipe_", "")
55+
val dbShm = createTempFile("newpipe_", "")
5456
Mockito.`when`(fileLocator.db).thenReturn(db)
5557
Mockito.`when`(fileLocator.dbJournal).thenReturn(dbJournal)
5658
Mockito.`when`(fileLocator.dbShm).thenReturn(dbShm)
@@ -62,15 +64,15 @@ class ImportAllCombinationsTest {
6264
Assert.assertFalse(dbJournal.exists())
6365
Assert.assertFalse(dbWal.exists())
6466
Assert.assertFalse(dbShm.exists())
65-
Assert.assertTrue("database file size is zero", Files.size(db.toPath()) > 0)
67+
Assert.assertTrue("database file size is zero", db.fileSize() > 0)
6668
}
6769
} else {
6870
runTest {
6971
Assert.assertFalse(ImportExportManager(fileLocator).extractDb(zip))
7072
Assert.assertTrue(dbJournal.exists())
7173
Assert.assertTrue(dbWal.exists())
7274
Assert.assertTrue(dbShm.exists())
73-
Assert.assertEquals(0, Files.size(db.toPath()))
75+
Assert.assertEquals(0, db.fileSize())
7476
}
7577
}
7678

app/src/test/java/org/schabi/newpipe/settings/ImportExportManagerTest.kt

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,14 @@ import android.content.SharedPreferences
44
import com.grack.nanojson.JsonParser
55
import java.io.File
66
import java.io.ObjectInputStream
7-
import java.nio.file.Files
87
import java.util.zip.ZipFile
8+
import kotlin.io.path.Path
9+
import kotlin.io.path.createTempDirectory
10+
import kotlin.io.path.createTempFile
11+
import kotlin.io.path.deleteIfExists
12+
import kotlin.io.path.exists
13+
import kotlin.io.path.fileSize
14+
import kotlin.io.path.inputStream
915
import org.junit.Assert.assertEquals
1016
import org.junit.Assert.assertFalse
1117
import org.junit.Assert.assertThrows
@@ -46,7 +52,7 @@ class ImportExportManagerTest {
4652

4753
@Test
4854
fun `The settings must be exported successfully in the correct format`() {
49-
val db = File(classloader.getResource("settings/newpipe.db")!!.file)
55+
val db = Path(classloader.getResource("settings/newpipe.db")!!.file)
5056
`when`(fileLocator.db).thenReturn(db)
5157

5258
val expectedPreferences = mapOf("such pref" to "much wow")
@@ -81,8 +87,8 @@ class ImportExportManagerTest {
8187

8288
@Test
8389
fun `Ensuring db directory existence must work`() {
84-
val dir = Files.createTempDirectory("newpipe_").toFile()
85-
Assume.assumeTrue(dir.delete())
90+
val dir = createTempDirectory("newpipe_")
91+
Assume.assumeTrue(dir.deleteIfExists())
8692
`when`(fileLocator.dbDir).thenReturn(dir)
8793

8894
ImportExportManager(fileLocator).ensureDbDirectoryExists()
@@ -91,7 +97,7 @@ class ImportExportManagerTest {
9197

9298
@Test
9399
fun `Ensuring db directory existence must work when the directory already exists`() {
94-
val dir = Files.createTempDirectory("newpipe_").toFile()
100+
val dir = createTempDirectory("newpipe_")
95101
`when`(fileLocator.dbDir).thenReturn(dir)
96102

97103
ImportExportManager(fileLocator).ensureDbDirectoryExists()
@@ -100,10 +106,10 @@ class ImportExportManagerTest {
100106

101107
@Test
102108
fun `The database must be extracted from the zip file`() {
103-
val db = File.createTempFile("newpipe_", "")
104-
val dbJournal = File.createTempFile("newpipe_", "")
105-
val dbWal = File.createTempFile("newpipe_", "")
106-
val dbShm = File.createTempFile("newpipe_", "")
109+
val db = createTempFile("newpipe_", "")
110+
val dbJournal = createTempFile("newpipe_", "")
111+
val dbWal = createTempFile("newpipe_", "")
112+
val dbShm = createTempFile("newpipe_", "")
107113
`when`(fileLocator.db).thenReturn(db)
108114
`when`(fileLocator.dbJournal).thenReturn(dbJournal)
109115
`when`(fileLocator.dbShm).thenReturn(dbShm)
@@ -117,15 +123,15 @@ class ImportExportManagerTest {
117123
assertFalse(dbJournal.exists())
118124
assertFalse(dbWal.exists())
119125
assertFalse(dbShm.exists())
120-
assertTrue("database file size is zero", Files.size(db.toPath()) > 0)
126+
assertTrue("database file size is zero", db.fileSize() > 0)
121127
}
122128

123129
@Test
124130
fun `Extracting the database from an empty zip must not work`() {
125-
val db = File.createTempFile("newpipe_", "")
126-
val dbJournal = File.createTempFile("newpipe_", "")
127-
val dbWal = File.createTempFile("newpipe_", "")
128-
val dbShm = File.createTempFile("newpipe_", "")
131+
val db = createTempFile("newpipe_", "")
132+
val dbJournal = createTempFile("newpipe_", "")
133+
val dbWal = createTempFile("newpipe_", "")
134+
val dbShm = createTempFile("newpipe_", "")
129135
`when`(fileLocator.db).thenReturn(db)
130136

131137
val emptyZip = File(classloader.getResource("settings/nodb_noser_nojson.zip")?.file!!)
@@ -136,7 +142,7 @@ class ImportExportManagerTest {
136142
assertTrue(dbJournal.exists())
137143
assertTrue(dbWal.exists())
138144
assertTrue(dbShm.exists())
139-
assertEquals(0, Files.size(db.toPath()))
145+
assertEquals(0, db.fileSize())
140146
}
141147

142148
@Test

0 commit comments

Comments
 (0)