Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backupmanager: Include check for TimeStamp at .bak files #9089

Merged
merged 1 commit into from
Aug 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 33 additions & 13 deletions src/main/java/org/jabref/logic/autosaveandbackup/BackupManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.FileTime;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -117,26 +118,45 @@ public static void shutdown(BibDatabaseContext bibDatabaseContext) {

/**
* Checks whether a backup file exists for the given database file. If it exists, it is checked whether it is
* different from the original.
* newer and different from the original.
*
* @param originalPath Path to the file a backup should be checked for. Example: jabref.bib.
*
* @return <code>true</code> if backup file exists AND differs from originalPath. <code>false</code> is the
* "default" return value in the good case. In the case of an exception <code>true</code> is returned to ensure that
* the user checks the output.
*/
public static boolean backupFileDiffers(Path originalPath) {
Optional<Path> backupPath = getLatestBackupPath(originalPath);
if (backupPath.isEmpty()) {
return false;
}

try {
return Files.mismatch(originalPath, backupPath.get()) != -1L;
} catch (IOException e) {
LOGGER.debug("Could not compare original file and backup file.", e);
// User has to investigate in this case
return true;
}
return getLatestBackupPath(originalPath).map(latestBackupPath -> {
FileTime latestBackupFileLastModifiedTime;
try {
latestBackupFileLastModifiedTime = Files.getLastModifiedTime(latestBackupPath);
} catch (IOException e) {
LOGGER.debug("Could not get timestamp of backup file {}", latestBackupPath, e);
// If we cannot get the timestamp, we do show any warning
return false;
}
FileTime currentFileLastModifiedTime;
try {
currentFileLastModifiedTime = Files.getLastModifiedTime(originalPath);
} catch (IOException e) {
LOGGER.debug("Could not get timestamp of current file file {}", originalPath, e);
// If we cannot get the timestamp, we do show any warning
return false;
}
if (latestBackupFileLastModifiedTime.compareTo(currentFileLastModifiedTime) <= 0) {
// Backup is older than current file
// We treat the backup as non-different (even if it could differ)
return false;
}
try {
return Files.mismatch(originalPath, latestBackupPath) != -1L;
} catch (IOException e) {
LOGGER.debug("Could not compare original file and backup file.", e);
// User has to investigate in this case
return true;
}
}).orElse(false);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.FileTime;

import org.jabref.logic.util.BackupFileType;
import org.jabref.logic.util.io.BackupFileUtil;
Expand Down Expand Up @@ -54,24 +55,50 @@ public void backupFileDiffers() throws Exception {

@Test
public void correctBackupFileDeterminedForMultipleBakFiles() throws Exception {
// Prepare test: Create backup files on "right" path
Path noChangesBib = Path.of(BackupManagerTest.class.getResource("no-changes.bib").toURI());
Path noChangesBibBak = Path.of(BackupManagerTest.class.getResource("no-changes.bib.bak").toURI());

// Prepare test: Create backup files on "right" path
// most recent file does not have any changes
Path source = Path.of(BackupManagerTest.class.getResource("no-changes.bib.bak").toURI());
Path target = BackupFileUtil.getPathForNewBackupFileAndCreateDirectory(Path.of(BackupManagerTest.class.getResource("no-changes.bib").toURI()), BackupFileType.BACKUP);
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
Path target = BackupFileUtil.getPathForNewBackupFileAndCreateDirectory(noChangesBib, BackupFileType.BACKUP);
Files.copy(noChangesBibBak, target, StandardCopyOption.REPLACE_EXISTING);

// create "older" .bak files containing changes
for (int i = 0; i < 10; i++) {
source = Path.of(BackupManagerTest.class.getResource("changes.bib").toURI());
Path changesBibBak = Path.of(BackupManagerTest.class.getResource("changes.bib").toURI());
Path directory = BackupFileUtil.getAppDataBackupDir();
String timeSuffix = "2020-02-03--00.00.0" + Integer.toString(i);
String fileName = BackupFileUtil.getUniqueFilePrefix(Path.of(BackupManagerTest.class.getResource("no-changes.bib").toURI())) + "--no-changes.bib--" + timeSuffix + ".bak";
String fileName = BackupFileUtil.getUniqueFilePrefix(noChangesBib) + "--no-changes.bib--" + timeSuffix + ".bak";
target = directory.resolve(fileName);
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
Files.copy(changesBibBak, target, StandardCopyOption.REPLACE_EXISTING);
}

Path originalFile = Path.of(BackupManagerTest.class.getResource("no-changes.bib").toURI());
Path originalFile = noChangesBib;
assertFalse(BackupManager.backupFileDiffers(originalFile));
}

@Test
public void bakFileWithNewerTimeStampLeadsToDiff() throws Exception {
Path changesBib = Path.of(BackupManagerTest.class.getResource("changes.bib").toURI());
Path changesBibBak = Path.of(BackupManagerTest.class.getResource("changes.bib.bak").toURI());

Path target = BackupFileUtil.getPathForNewBackupFileAndCreateDirectory(changesBib, BackupFileType.BACKUP);
Files.copy(changesBibBak, target, StandardCopyOption.REPLACE_EXISTING);

assertTrue(BackupManager.backupFileDiffers(changesBib));
}

@Test
public void bakFileWithOlderTimeStampDoesNotLeadToDiff() throws Exception {
Path changesBib = Path.of(BackupManagerTest.class.getResource("changes.bib").toURI());
Path changesBibBak = Path.of(BackupManagerTest.class.getResource("changes.bib.bak").toURI());

Path target = BackupFileUtil.getPathForNewBackupFileAndCreateDirectory(changesBib, BackupFileType.BACKUP);
Files.copy(changesBibBak, target, StandardCopyOption.REPLACE_EXISTING);

// Make .bak file very old
Files.setLastModifiedTime(target, FileTime.fromMillis(0));

assertFalse(BackupManager.backupFileDiffers(changesBib));
}
}