Skip to content

Commit 72b67ab

Browse files
Refactor zip import/export using Path
1 parent 840084d commit 72b67ab

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;
@@ -61,13 +60,12 @@ public class BackupRestoreSettingsFragment extends BasePreferenceFragment {
6160
@Override
6261
public void onCreatePreferences(@Nullable final Bundle savedInstanceState,
6362
@Nullable final String rootKey) {
64-
final File homeDir = ContextCompat.getDataDir(requireContext());
65-
Objects.requireNonNull(homeDir);
66-
manager = new ImportExportManager(new BackupFileLocator(homeDir));
63+
final var dbDir = Objects.requireNonNull(ContextCompat.getDataDir(requireContext()))
64+
.toPath();
65+
manager = new ImportExportManager(new BackupFileLocator(dbDir));
6766

6867
importExportDataPathKey = getString(R.string.import_export_data_path);
6968

70-
7169
addPreferencesFromResourceRegistry();
7270

7371
final Preference importDataPreference = requirePreference(R.string.import_data);
@@ -183,9 +181,7 @@ private void importDatabase(final StoredFileHelper file, final Uri importDataUri
183181
}
184182

185183
try {
186-
if (!manager.ensureDbDirectoryExists()) {
187-
throw new IOException("Could not create databases dir");
188-
}
184+
manager.ensureDbDirectoryExists();
189185

190186
// replace the current database
191187
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
@Deprecated(
@@ -16,13 +17,9 @@ class BackupFileLocator(private val homeDir: File) {
1617
const val FILE_NAME_JSON_PREFS = "preferences.json"
1718
}
1819

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

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
@@ -12,6 +12,8 @@ import java.io.FileNotFoundException
1212
import java.io.IOException
1313
import java.io.ObjectOutputStream
1414
import java.util.zip.ZipOutputStream
15+
import kotlin.io.path.createDirectories
16+
import kotlin.io.path.deleteExisting
1517

1618
class ImportExportManager(private val fileLocator: BackupFileLocator) {
1719
companion object {
@@ -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
@@ -10,7 +10,9 @@ import org.schabi.newpipe.streams.io.StoredFileHelper
1010
import us.shandian.giga.io.FileStream
1111
import java.io.File
1212
import java.io.IOException
13-
import java.nio.file.Files
13+
import kotlin.io.path.createTempFile
14+
import kotlin.io.path.exists
15+
import kotlin.io.path.fileSize
1416

1517
class ImportAllCombinationsTest {
1618

@@ -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
@@ -25,8 +25,14 @@ import org.schabi.newpipe.streams.io.StoredFileHelper
2525
import us.shandian.giga.io.FileStream
2626
import java.io.File
2727
import java.io.ObjectInputStream
28-
import java.nio.file.Files
2928
import java.util.zip.ZipFile
29+
import kotlin.io.path.Path
30+
import kotlin.io.path.createTempDirectory
31+
import kotlin.io.path.createTempFile
32+
import kotlin.io.path.deleteIfExists
33+
import kotlin.io.path.exists
34+
import kotlin.io.path.fileSize
35+
import kotlin.io.path.inputStream
3036

3137
@RunWith(MockitoJUnitRunner::class)
3238
class ImportExportManagerTest {
@@ -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)