diff --git a/CHANGELOG.md b/CHANGELOG.md index 149ea8d8bc7..1cbf79c286c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We fixed an issue where opening a library from the recent libraries menu was not possible. [#5939](https://github.com/JabRef/jabref/issues/5939) - We fixed an issue with inconsistent capitalization of file extensions when downloading files [#6115](https://github.com/JabRef/jabref/issues/6115) - We fixed the display of language and encoding in the preferences dialog. [#6130](https://github.com/JabRef/jabref/pull/6130) - +- We fixed an issue where search full-text documents downloaded files with same name, overwriting existing files. [#6174](https://github.com/JabRef/jabref/pull/6174) ### Removed - We removed the obsolete `External programs / Open PDF` section in the preferences, as the default application to open PDFs is now set in the `Manage external file types` dialog. [#6130](https://github.com/JabRef/jabref/pull/6130) diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java index d52a24b9f95..e57513db0b7 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java +++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java @@ -38,6 +38,7 @@ import org.jabref.logic.externalfiles.LinkedFileHandler; import org.jabref.logic.l10n.Localization; import org.jabref.logic.net.URLDownload; +import org.jabref.logic.util.io.FileNameUniqueness; import org.jabref.logic.xmp.XmpPreferences; import org.jabref.logic.xmp.XmpUtilWriter; import org.jabref.model.database.BibDatabaseContext; @@ -419,6 +420,7 @@ public BackgroundTask prepareDownloadTask(Path targetDirectory, URLDownloa String suggestedTypeName = externalFileType.getName(); linkedFile.setFileType(suggestedTypeName); String suggestedName = linkedFileHandler.getSuggestedFileName(externalFileType.getExtension()); + suggestedName = FileNameUniqueness.getNonOverWritingFileName(targetDirectory, suggestedName); return targetDirectory.resolve(suggestedName); }) .then(destination -> new FileDownloadTask(urlDownload.getSource(), destination)) diff --git a/src/main/java/org/jabref/logic/util/io/FileNameUniqueness.java b/src/main/java/org/jabref/logic/util/io/FileNameUniqueness.java new file mode 100644 index 00000000000..595530d0944 --- /dev/null +++ b/src/main/java/org/jabref/logic/util/io/FileNameUniqueness.java @@ -0,0 +1,49 @@ +package org.jabref.logic.util.io; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Optional; + +public class FileNameUniqueness { + + /** + * Returns an absolute path to a file which does not match with any existing file names + * + * @param targetDirectory The directory in which file name should be unique + * @param fileName Suggested name for the file + * @return a file-name such that it does not match any existing files in targetDirectory. + * */ + public static String getNonOverWritingFileName(Path targetDirectory, String fileName) { +// String absoluteName = targetDirectory.resolve(fileName) +// .toString(); + + Optional extensionOptional = FileUtil.getFileExtension(fileName); + + // the suffix include the '.' , if extension is present Eg: ".pdf" + String extensionSuffix; + String fileNameWithoutExtension; + + if (extensionOptional.isPresent()) { + extensionSuffix = '.' + extensionOptional.get(); + fileNameWithoutExtension = fileName.substring(0, fileName.lastIndexOf('.')); + } + else { + extensionSuffix = ""; + fileNameWithoutExtension = fileName; + } + +// Path absolutePath = Paths.get(absoluteName); + String newFileName = fileName; + + int counter = 1; + while ( Files.exists( + targetDirectory.resolve(newFileName)) + ) { + newFileName = fileNameWithoutExtension + + " (" + counter + ")" + + extensionSuffix; + counter++; + } + return newFileName; + } +} diff --git a/src/test/java/org/jabref/logic/util/io/FileNameUniquenessTest.java b/src/test/java/org/jabref/logic/util/io/FileNameUniquenessTest.java new file mode 100644 index 00000000000..29f6f73cf6a --- /dev/null +++ b/src/test/java/org/jabref/logic/util/io/FileNameUniquenessTest.java @@ -0,0 +1,57 @@ +package org.jabref.logic.util.io; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + + +public class FileNameUniquenessTest { + + @TempDir + protected Path tempDir; + + @Test + public void testGetNonOverWritingFileNameReturnsSameName(@TempDir Path tempDirectory) throws IOException { + + assertFalse( + Files.exists(tempDirectory.resolve("sameFile.txt")) + ); + + String outputFileName = FileNameUniqueness.getNonOverWritingFileName(tempDirectory, "sameFile.txt"); + assertEquals("sameFile.txt", outputFileName); + + } + + @Test + public void testGetNonOverWritingFileNameReturnsUniqueNameOver1Conflict() throws IOException { + Path dummyFilePath1 = tempDir.resolve("differentFile.txt"); + + Files.createFile(dummyFilePath1); + + String outputFileName = FileNameUniqueness.getNonOverWritingFileName(tempDir, "differentFile.txt"); + assertEquals("differentFile (1).txt", outputFileName); + + Files.delete(dummyFilePath1); + } + + @Test + public void testGetNonOverWritingFileNameReturnsUniqueNameOverNConflicts() throws IOException { + Path dummyFilePath1 = tempDir.resolve("manyfiles.txt"); + Path dummyFilePath2 = tempDir.resolve("manyfiles (1).txt"); + + Files.createFile(dummyFilePath1); + Files.createFile(dummyFilePath2); + + String outputFileName = FileNameUniqueness.getNonOverWritingFileName(tempDir, "manyfiles.txt"); + assertEquals("manyfiles (2).txt", outputFileName); + + Files.delete(dummyFilePath1); + Files.delete(dummyFilePath2); + } +}