From 6f49c3034ba80629281f2f399b50bc7b7159fbc0 Mon Sep 17 00:00:00 2001 From: Lucas Freund <127773292+Luggas4you@users.noreply.github.com> Date: Sat, 9 Sep 2023 17:10:02 +0200 Subject: [PATCH 01/12] Create PDF WIP --- .../jabref/logic/exporter/XmpPdfExporter.java | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java b/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java index f6ece8646c2..d12615680b7 100644 --- a/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java +++ b/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java @@ -1,15 +1,18 @@ package org.jabref.logic.exporter; -import java.nio.file.Path; -import java.util.List; -import java.util.Objects; + import java.io.IOException; + import java.nio.file.Path; + import java.util.List; + import java.util.Objects; -import org.jabref.logic.l10n.Localization; -import org.jabref.logic.util.StandardFileType; -import org.jabref.logic.xmp.XmpPreferences; -import org.jabref.logic.xmp.XmpUtilWriter; -import org.jabref.model.database.BibDatabaseContext; -import org.jabref.model.entry.BibEntry; + import org.jabref.logic.l10n.Localization; + import org.jabref.logic.util.StandardFileType; + import org.jabref.logic.xmp.XmpPreferences; + import org.jabref.logic.xmp.XmpUtilWriter; + import org.jabref.model.database.BibDatabaseContext; + import org.jabref.model.entry.BibEntry; + + import org.apache.pdfbox.pdmodel.PDDocument; public class XmpPdfExporter extends Exporter { @@ -26,8 +29,22 @@ public void export(BibDatabaseContext databaseContext, Path pdfFile, List Date: Sun, 10 Sep 2023 21:59:06 +0200 Subject: [PATCH 02/12] Create PDF WIP --- .../jabref/logic/exporter/XmpPdfExporter.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java b/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java index d12615680b7..3907601b95f 100644 --- a/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java +++ b/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java @@ -13,6 +13,8 @@ import org.jabref.model.entry.BibEntry; import org.apache.pdfbox.pdmodel.PDDocument; + import org.apache.pdfbox.pdmodel.PDPage; + import org.apache.pdfbox.pdmodel.PDPageContentStream; public class XmpPdfExporter extends Exporter { @@ -29,20 +31,26 @@ public void export(BibDatabaseContext databaseContext, Path pdfFile, List Date: Fri, 15 Sep 2023 16:28:43 +0200 Subject: [PATCH 03/12] Create PDF WIP --- .../jabref/logic/exporter/XmpPdfExporter.java | 65 ++++++++++--------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java b/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java index 3907601b95f..1318fc01a62 100644 --- a/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java +++ b/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java @@ -1,20 +1,23 @@ package org.jabref.logic.exporter; - import java.io.IOException; - import java.nio.file.Path; - import java.util.List; - import java.util.Objects; - - import org.jabref.logic.l10n.Localization; - import org.jabref.logic.util.StandardFileType; - import org.jabref.logic.xmp.XmpPreferences; - import org.jabref.logic.xmp.XmpUtilWriter; - import org.jabref.model.database.BibDatabaseContext; - import org.jabref.model.entry.BibEntry; - - import org.apache.pdfbox.pdmodel.PDDocument; - import org.apache.pdfbox.pdmodel.PDPage; - import org.apache.pdfbox.pdmodel.PDPageContentStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Objects; + +import org.jabref.logic.l10n.Localization; +import org.jabref.logic.util.StandardFileType; +import org.jabref.logic.xmp.XmpPreferences; +import org.jabref.logic.xmp.XmpUtilWriter; +import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.entry.BibEntry; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.font.PDType1Font; +import org.apache.pdfbox.pdmodel.font.Standard14Fonts; public class XmpPdfExporter extends Exporter { @@ -36,23 +39,23 @@ public void export(BibDatabaseContext databaseContext, Path pdfFile, List Date: Sat, 23 Sep 2023 22:33:01 +0200 Subject: [PATCH 04/12] Add @Test to XmpPdfExporterTest WIP --- .../logic/exporter/XmpPdfExporterTest.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java b/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java index 3e07fd1f085..5839e46bed2 100644 --- a/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java +++ b/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java @@ -1,7 +1,11 @@ package org.jabref.logic.exporter; +import java.io.File; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import java.util.Collections; import java.util.List; import java.util.stream.Stream; @@ -19,15 +23,22 @@ import org.jabref.model.entry.types.StandardEntryType; import org.jabref.preferences.FilePreferences; +import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.font.PDType1Font; +import org.apache.pdfbox.pdmodel.font.Standard14Fonts; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -123,6 +134,9 @@ void unsuccessfulExportToAllFilesOfEntry(BibEntry bibEntryWithValidPdfFileLink) assertFalse(exporter.exportToAllFilesOfEntry(databaseContext, filePreferences, bibEntryWithValidPdfFileLink, List.of(olly2018), abbreviationRepository)); } + + + public static Stream provideBibEntriesWithValidPdfFileLinks() { return Stream.of(Arguments.of(olly2018)); } @@ -143,6 +157,41 @@ void unsuccessfulExportToFileByPath(Path path) throws Exception { assertFalse(exporter.exportToFileByPath(databaseContext, filePreferences, path, abbreviationRepository)); } + @Test + public void testRoundtripExportImport() { + Path originalFilePath = Path.of("original.pdf"); + Path exportedFilePath = Path.of("exported.pdf"); + + try { + try (PDDocument document = new PDDocument()) { + PDPage page = new PDPage(); + document.addPage(page); + + try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) { + contentStream.beginText(); + contentStream.newLineAtOffset(25, 500); + contentStream.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA), 12); + contentStream.showText("This PDF was created by JabRef. It demonstrates the embedding of BibTeX data in PDF files. Please open the file attachments view of your PDF viewer to see the attached files. Note that the normal usage is to embed the BibTeX data in an existing PDF."); + contentStream.endText(); + } + document.save(originalFilePath.toString()); + } + exporter.exportToFileByPath(databaseContext, filePreferences, originalFilePath, abbreviationRepository); + + Files.copy(Paths.get(originalFilePath.toString()), Paths.get(exportedFilePath.toString()), StandardCopyOption.REPLACE_EXISTING); + + try (PDDocument importedDocument = Loader.loadPDF(new File(exportedFilePath.toString()))) { + assertNotNull(importedDocument, "The imported document should not be null"); + assertEquals(1, importedDocument.getNumberOfPages()); + } + } catch (IOException e) { + e.printStackTrace(); + } catch ( + Exception e) { + throw new RuntimeException(e); + } + } + public static Stream providePathsToValidPDFs() { return Stream.of(Arguments.of(tempDir.resolve("existing.pdf").toAbsolutePath())); } From 58dcf13c81077643a09e4a9b637c18bd789cff92 Mon Sep 17 00:00:00 2001 From: Lucas Freund <127773292+Luggas4you@users.noreply.github.com> Date: Sun, 24 Sep 2023 18:48:15 +0200 Subject: [PATCH 05/12] Add Importer to XmpPdfExporterTest --- .../logic/exporter/XmpPdfExporterTest.java | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java b/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java index 5839e46bed2..afc910c0740 100644 --- a/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java +++ b/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java @@ -1,17 +1,18 @@ package org.jabref.logic.exporter; -import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.Collections; import java.util.List; import java.util.stream.Stream; import javafx.beans.property.SimpleObjectProperty; +import javafx.collections.FXCollections; +import org.jabref.logic.importer.ImportFormatPreferences; +import org.jabref.logic.importer.fileformat.PdfEmbeddedBibFileImporter; import org.jabref.logic.journals.JournalAbbreviationRepository; import org.jabref.logic.xmp.XmpPreferences; import org.jabref.model.database.BibDatabase; @@ -23,7 +24,6 @@ import org.jabref.model.entry.types.StandardEntryType; import org.jabref.preferences.FilePreferences; -import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; @@ -35,6 +35,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.Answers; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -52,6 +53,7 @@ class XmpPdfExporterTest { private static BibEntry vapnik2000 = new BibEntry(StandardEntryType.Article); private XmpPdfExporter exporter; + private PdfEmbeddedBibFileImporter importer; private BibDatabaseContext databaseContext; private JournalAbbreviationRepository abbreviationRepository; @@ -113,6 +115,10 @@ void setUp() throws IOException { XmpPreferences xmpPreferences = new XmpPreferences(false, Collections.emptySet(), new SimpleObjectProperty<>(',')); exporter = new XmpPdfExporter(xmpPreferences); + ImportFormatPreferences importFormatPreferences = mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS); + when(importFormatPreferences.fieldPreferences().getNonWrappableFields()).thenReturn(FXCollections.emptyObservableList()); + importer = new PdfEmbeddedBibFileImporter(importFormatPreferences); + databaseContext = new BibDatabaseContext(); BibDatabase dataBase = databaseContext.getDatabase(); @@ -159,6 +165,7 @@ void unsuccessfulExportToFileByPath(Path path) throws Exception { @Test public void testRoundtripExportImport() { + Path originalFilePath = Path.of("original.pdf"); Path exportedFilePath = Path.of("exported.pdf"); @@ -176,14 +183,16 @@ public void testRoundtripExportImport() { } document.save(originalFilePath.toString()); } + exporter.exportToFileByPath(databaseContext, filePreferences, originalFilePath, abbreviationRepository); - Files.copy(Paths.get(originalFilePath.toString()), Paths.get(exportedFilePath.toString()), StandardCopyOption.REPLACE_EXISTING); + Files.copy(originalFilePath, exportedFilePath, StandardCopyOption.REPLACE_EXISTING); + + List importedDocument = importer.importDatabase(exportedFilePath).getDatabase().getEntries(); + + assertNotNull(importedDocument, "The imported document should not be null"); + assertEquals(Collections.singletonList(originalFilePath), importedDocument); - try (PDDocument importedDocument = Loader.loadPDF(new File(exportedFilePath.toString()))) { - assertNotNull(importedDocument, "The imported document should not be null"); - assertEquals(1, importedDocument.getNumberOfPages()); - } } catch (IOException e) { e.printStackTrace(); } catch ( From 2b5838f64008e7ef645253d16b8a98a4ca75fc90 Mon Sep 17 00:00:00 2001 From: Lucas Freund <127773292+Luggas4you@users.noreply.github.com> Date: Sun, 24 Sep 2023 21:06:40 +0200 Subject: [PATCH 06/12] WIP --- .../org/jabref/logic/exporter/XmpPdfExporterTest.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java b/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java index afc910c0740..46ba4f1ddc9 100644 --- a/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java +++ b/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java @@ -15,6 +15,7 @@ import org.jabref.logic.importer.fileformat.PdfEmbeddedBibFileImporter; import org.jabref.logic.journals.JournalAbbreviationRepository; import org.jabref.logic.xmp.XmpPreferences; +import org.jabref.logic.xmp.XmpUtilWriter; import org.jabref.model.database.BibDatabase; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; @@ -39,7 +40,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -54,6 +54,7 @@ class XmpPdfExporterTest { private XmpPdfExporter exporter; private PdfEmbeddedBibFileImporter importer; + private XmpPreferences xmpPreferences; private BibDatabaseContext databaseContext; private JournalAbbreviationRepository abbreviationRepository; @@ -112,7 +113,7 @@ void setUp() throws IOException { when(filePreferences.getUserAndHost()).thenReturn(tempDir.toAbsolutePath().toString()); when(filePreferences.shouldStoreFilesRelativeToBibFile()).thenReturn(false); - XmpPreferences xmpPreferences = new XmpPreferences(false, Collections.emptySet(), new SimpleObjectProperty<>(',')); + xmpPreferences = new XmpPreferences(false, Collections.emptySet(), new SimpleObjectProperty<>(',')); exporter = new XmpPdfExporter(xmpPreferences); ImportFormatPreferences importFormatPreferences = mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS); @@ -166,8 +167,8 @@ void unsuccessfulExportToFileByPath(Path path) throws Exception { @Test public void testRoundtripExportImport() { - Path originalFilePath = Path.of("original.pdf"); - Path exportedFilePath = Path.of("exported.pdf"); + Path originalFilePath = tempDir.resolve("original.pdf").toAbsolutePath(); + Path exportedFilePath = tempDir.resolve("exported.pdf").toAbsolutePath(); try { try (PDDocument document = new PDDocument()) { @@ -183,6 +184,7 @@ public void testRoundtripExportImport() { } document.save(originalFilePath.toString()); } + new XmpUtilWriter(xmpPreferences).writeXmp(originalFilePath, databaseContext.getEntries(), databaseContext.getDatabase()); exporter.exportToFileByPath(databaseContext, filePreferences, originalFilePath, abbreviationRepository); @@ -190,7 +192,6 @@ public void testRoundtripExportImport() { List importedDocument = importer.importDatabase(exportedFilePath).getDatabase().getEntries(); - assertNotNull(importedDocument, "The imported document should not be null"); assertEquals(Collections.singletonList(originalFilePath), importedDocument); } catch (IOException e) { From 648301e5d50f820a0facc6e0061b1ae020b64347 Mon Sep 17 00:00:00 2001 From: Lucas Freund <127773292+Luggas4you@users.noreply.github.com> Date: Sun, 24 Sep 2023 21:41:30 +0200 Subject: [PATCH 07/12] Fix testRoundtripExportImport --- .../logic/exporter/XmpPdfExporterTest.java | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java b/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java index 46ba4f1ddc9..edab2df7cef 100644 --- a/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java +++ b/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java @@ -1,9 +1,7 @@ package org.jabref.logic.exporter; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.StandardCopyOption; import java.util.Collections; import java.util.List; import java.util.stream.Stream; @@ -12,7 +10,7 @@ import javafx.collections.FXCollections; import org.jabref.logic.importer.ImportFormatPreferences; -import org.jabref.logic.importer.fileformat.PdfEmbeddedBibFileImporter; +import org.jabref.logic.importer.fileformat.PdfXmpImporter; import org.jabref.logic.journals.JournalAbbreviationRepository; import org.jabref.logic.xmp.XmpPreferences; import org.jabref.logic.xmp.XmpUtilWriter; @@ -53,7 +51,7 @@ class XmpPdfExporterTest { private static BibEntry vapnik2000 = new BibEntry(StandardEntryType.Article); private XmpPdfExporter exporter; - private PdfEmbeddedBibFileImporter importer; + private PdfXmpImporter importer; private XmpPreferences xmpPreferences; private BibDatabaseContext databaseContext; @@ -118,7 +116,7 @@ void setUp() throws IOException { ImportFormatPreferences importFormatPreferences = mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS); when(importFormatPreferences.fieldPreferences().getNonWrappableFields()).thenReturn(FXCollections.emptyObservableList()); - importer = new PdfEmbeddedBibFileImporter(importFormatPreferences); + importer = new PdfXmpImporter(xmpPreferences); databaseContext = new BibDatabaseContext(); BibDatabase dataBase = databaseContext.getDatabase(); @@ -168,7 +166,6 @@ void unsuccessfulExportToFileByPath(Path path) throws Exception { public void testRoundtripExportImport() { Path originalFilePath = tempDir.resolve("original.pdf").toAbsolutePath(); - Path exportedFilePath = tempDir.resolve("exported.pdf").toAbsolutePath(); try { try (PDDocument document = new PDDocument()) { @@ -186,13 +183,9 @@ public void testRoundtripExportImport() { } new XmpUtilWriter(xmpPreferences).writeXmp(originalFilePath, databaseContext.getEntries(), databaseContext.getDatabase()); - exporter.exportToFileByPath(databaseContext, filePreferences, originalFilePath, abbreviationRepository); + List importedEntries = importer.importDatabase(originalFilePath).getDatabase().getEntries(); - Files.copy(originalFilePath, exportedFilePath, StandardCopyOption.REPLACE_EXISTING); - - List importedDocument = importer.importDatabase(exportedFilePath).getDatabase().getEntries(); - - assertEquals(Collections.singletonList(originalFilePath), importedDocument); + assertEquals(databaseContext.getEntries(), importedEntries); } catch (IOException e) { e.printStackTrace(); From 78fbb406abfd1d2b14ec794352289aeca759f102 Mon Sep 17 00:00:00 2001 From: Lucas Freund <127773292+Luggas4you@users.noreply.github.com> Date: Sun, 24 Sep 2023 22:23:10 +0200 Subject: [PATCH 08/12] Finish testRoundtripExportImport --- .../logic/exporter/XmpPdfExporterTest.java | 57 ++++++++++--------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java b/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java index edab2df7cef..7181c0b842a 100644 --- a/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java +++ b/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java @@ -9,6 +9,8 @@ import javafx.beans.property.SimpleObjectProperty; import javafx.collections.FXCollections; +import org.jabref.logic.cleanup.FieldFormatterCleanup; +import org.jabref.logic.formatter.bibtexfields.NormalizeNamesFormatter; import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.logic.importer.fileformat.PdfXmpImporter; import org.jabref.logic.journals.JournalAbbreviationRepository; @@ -96,7 +98,7 @@ private static void initBibEntries() throws IOException { vapnik2000.setCitationKey("vapnik2000"); vapnik2000.setField(StandardField.TITLE, "The Nature of Statistical Learning Theory"); vapnik2000.setField(StandardField.PUBLISHER, "Springer Science + Business Media"); - vapnik2000.setField(StandardField.AUTHOR, "Vladimir N. Vapnik"); + vapnik2000.setField(StandardField.AUTHOR, "Vapnik, Vladimir N."); vapnik2000.setField(StandardField.DOI, "10.1007/978-1-4757-3264-1"); vapnik2000.setField(StandardField.OWNER, "Ich"); } @@ -139,9 +141,6 @@ void unsuccessfulExportToAllFilesOfEntry(BibEntry bibEntryWithValidPdfFileLink) assertFalse(exporter.exportToAllFilesOfEntry(databaseContext, filePreferences, bibEntryWithValidPdfFileLink, List.of(olly2018), abbreviationRepository)); } - - - public static Stream provideBibEntriesWithValidPdfFileLinks() { return Stream.of(Arguments.of(olly2018)); } @@ -163,36 +162,34 @@ void unsuccessfulExportToFileByPath(Path path) throws Exception { } @Test - public void testRoundtripExportImport() { + public void testRoundtripExportImport() throws Exception { Path originalFilePath = tempDir.resolve("original.pdf").toAbsolutePath(); - try { - try (PDDocument document = new PDDocument()) { - PDPage page = new PDPage(); - document.addPage(page); - - try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) { - contentStream.beginText(); - contentStream.newLineAtOffset(25, 500); - contentStream.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA), 12); - contentStream.showText("This PDF was created by JabRef. It demonstrates the embedding of BibTeX data in PDF files. Please open the file attachments view of your PDF viewer to see the attached files. Note that the normal usage is to embed the BibTeX data in an existing PDF."); - contentStream.endText(); - } - document.save(originalFilePath.toString()); - } - new XmpUtilWriter(xmpPreferences).writeXmp(originalFilePath, databaseContext.getEntries(), databaseContext.getDatabase()); + try (PDDocument document = new PDDocument()) { + PDPage page = new PDPage(); + document.addPage(page); - List importedEntries = importer.importDatabase(originalFilePath).getDatabase().getEntries(); + try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) { + contentStream.beginText(); + contentStream.newLineAtOffset(25, 500); + contentStream.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA), 12); + contentStream.showText("This PDF was created by JabRef. It demonstrates the embedding of BibTeX data in PDF files. Please open the file attachments view of your PDF viewer to see the attached files. Note that the normal usage is to embed the BibTeX data in an existing PDF."); + contentStream.endText(); + } + document.save(originalFilePath.toString()); + } + new XmpUtilWriter(xmpPreferences).writeXmp(originalFilePath, databaseContext.getEntries(), databaseContext.getDatabase()); - assertEquals(databaseContext.getEntries(), importedEntries); + List importedEntries = importer.importDatabase(originalFilePath).getDatabase().getEntries(); + importedEntries.forEach(bibEntry -> new FieldFormatterCleanup(StandardField.AUTHOR, new NormalizeNamesFormatter()).cleanup(bibEntry)); - } catch (IOException e) { - e.printStackTrace(); - } catch ( - Exception e) { - throw new RuntimeException(e); + List expectedEntries = databaseContext.getEntries(); + for (BibEntry entry : expectedEntries) { + entry.clearField(StandardField.FILE); + entry.addFile(createDefaultLinkedFile("", "original.pdf", tempDir)); } + assertEquals(expectedEntries, importedEntries); } public static Stream providePathsToValidPDFs() { @@ -208,12 +205,16 @@ public static Stream providePathsToInvalidPDFs() throws IOException { } private static LinkedFile createDefaultLinkedFile(String fileName, Path tempDir) throws IOException { + return createDefaultLinkedFile("A linked pdf", fileName, tempDir); + } + + private static LinkedFile createDefaultLinkedFile(String description, String fileName, Path tempDir) throws IOException { Path pdfFile = tempDir.resolve(fileName); try (PDDocument pdf = new PDDocument()) { pdf.addPage(new PDPage()); pdf.save(pdfFile.toAbsolutePath().toString()); } - return new LinkedFile("A linked pdf", pdfFile, "PDF"); + return new LinkedFile(description, pdfFile, "PDF"); } } From 91370eaabdec0a7cc207f7db21eb74b4fe63bb6a Mon Sep 17 00:00:00 2001 From: Lucas Freund <127773292+Luggas4you@users.noreply.github.com> Date: Sat, 30 Sep 2023 16:38:34 +0200 Subject: [PATCH 09/12] Add @AfterEach to XmpPdfExporterTest.java --- .../jabref/logic/exporter/XmpPdfExporterTest.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java b/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java index 7181c0b842a..c8cabc4ec2c 100644 --- a/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java +++ b/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java @@ -30,6 +30,7 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.pdfbox.pdmodel.font.Standard14Fonts; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -129,6 +130,17 @@ void setUp() throws IOException { dataBase.insertEntry(vapnik2000); } + @AfterEach + void reset() throws IOException { + List expectedEntries = databaseContext.getEntries(); + for (BibEntry entry : expectedEntries) { + entry.clearField(StandardField.FILE); + } + LinkedFile linkedFile = createDefaultLinkedFile("existing.pdf", tempDir); + olly2018.setFiles(List.of(linkedFile)); + toral2006.setFiles(List.of(new LinkedFile("non-existing", "path/to/nowhere.pdf", "PDF"))); + } + @ParameterizedTest @MethodSource("provideBibEntriesWithValidPdfFileLinks") void successfulExportToAllFilesOfEntry(BibEntry bibEntryWithValidPdfFileLink) throws Exception { @@ -205,7 +217,7 @@ public static Stream providePathsToInvalidPDFs() throws IOException { } private static LinkedFile createDefaultLinkedFile(String fileName, Path tempDir) throws IOException { - return createDefaultLinkedFile("A linked pdf", fileName, tempDir); + return createDefaultLinkedFile("", fileName, tempDir); } private static LinkedFile createDefaultLinkedFile(String description, String fileName, Path tempDir) throws IOException { From b32f000888fce3669ebaff48c69c85090aa751cf Mon Sep 17 00:00:00 2001 From: Lucas Freund <127773292+Luggas4you@users.noreply.github.com> Date: Sat, 30 Sep 2023 17:20:26 +0200 Subject: [PATCH 10/12] Change @Test to @ParameterizedTest --- .../logic/exporter/XmpPdfExporterTest.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java b/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java index c8cabc4ec2c..995103fa865 100644 --- a/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java +++ b/src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java @@ -32,7 +32,6 @@ import org.apache.pdfbox.pdmodel.font.Standard14Fonts; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -173,11 +172,9 @@ void unsuccessfulExportToFileByPath(Path path) throws Exception { assertFalse(exporter.exportToFileByPath(databaseContext, filePreferences, path, abbreviationRepository)); } - @Test - public void testRoundtripExportImport() throws Exception { - - Path originalFilePath = tempDir.resolve("original.pdf").toAbsolutePath(); - + @ParameterizedTest + @MethodSource("providePathToNewPDFs") + public void testRoundtripExportImport(Path path) throws Exception { try (PDDocument document = new PDDocument()) { PDPage page = new PDPage(); document.addPage(page); @@ -189,21 +186,25 @@ public void testRoundtripExportImport() throws Exception { contentStream.showText("This PDF was created by JabRef. It demonstrates the embedding of BibTeX data in PDF files. Please open the file attachments view of your PDF viewer to see the attached files. Note that the normal usage is to embed the BibTeX data in an existing PDF."); contentStream.endText(); } - document.save(originalFilePath.toString()); + document.save(path.toString()); } - new XmpUtilWriter(xmpPreferences).writeXmp(originalFilePath, databaseContext.getEntries(), databaseContext.getDatabase()); + new XmpUtilWriter(xmpPreferences).writeXmp(path, databaseContext.getEntries(), databaseContext.getDatabase()); - List importedEntries = importer.importDatabase(originalFilePath).getDatabase().getEntries(); + List importedEntries = importer.importDatabase(path).getDatabase().getEntries(); importedEntries.forEach(bibEntry -> new FieldFormatterCleanup(StandardField.AUTHOR, new NormalizeNamesFormatter()).cleanup(bibEntry)); List expectedEntries = databaseContext.getEntries(); for (BibEntry entry : expectedEntries) { entry.clearField(StandardField.FILE); - entry.addFile(createDefaultLinkedFile("", "original.pdf", tempDir)); + entry.addFile(createDefaultLinkedFile("original.pdf", tempDir)); } assertEquals(expectedEntries, importedEntries); } + public static Stream providePathToNewPDFs() { + return Stream.of(Arguments.of(tempDir.resolve("original.pdf").toAbsolutePath())); + } + public static Stream providePathsToValidPDFs() { return Stream.of(Arguments.of(tempDir.resolve("existing.pdf").toAbsolutePath())); } @@ -227,6 +228,6 @@ private static LinkedFile createDefaultLinkedFile(String description, String fil pdf.save(pdfFile.toAbsolutePath().toString()); } - return new LinkedFile(description, pdfFile, "PDF"); + return new LinkedFile("", pdfFile, "PDF"); } } From 1a3c47b3fa312a25451297c4785ed923279c7173 Mon Sep 17 00:00:00 2001 From: Lucas Freund <127773292+Luggas4you@users.noreply.github.com> Date: Sat, 30 Sep 2023 17:45:20 +0200 Subject: [PATCH 11/12] Delete IllegalArgumentException in XmpPdfExporter.java --- src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java b/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java index 1318fc01a62..357f01018ce 100644 --- a/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java +++ b/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java @@ -36,9 +36,6 @@ public void export(BibDatabaseContext databaseContext, Path pdfFile, List Date: Tue, 3 Oct 2023 14:31:47 +0200 Subject: [PATCH 12/12] add changelog and change message --- CHANGELOG.md | 2 ++ src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java | 2 +- src/test/java/org/jabref/logic/exporter/XmpPdfExporterTest.java | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 155e23266c1..b78c3cda0c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv - The export formats `listrefs`, `tablerefs`, `tablerefsabsbib`, now use the ISO date format in the footer [#10383](https://github.com/JabRef/jabref/pull/10383). - When searching for an identifier in the "Web search", the title of the search window is now "Identifier-based Web Search". [#10391](https://github.com/JabRef/jabref/pull/10391) - The ampersand checker now skips verbatim fields (`file`, `url`, ...). [#10419](https://github.com/JabRef/jabref/pull/10419) +- If no existing document is selected for exporting "XMP annotated pdf" JabRef will now create a new PDF file with a sample text and the metadata. [#10102](https://github.com/JabRef/jabref/issues/10102) ### Fixed @@ -38,6 +39,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv - We fixed an issue where it was possible to create a group with no name or with a group separator inside the name [#9776](https://github.com/JabRef/jabref/issues/9776) - Biblatex's `journaltitle` is now also respected for showing the journal information. [#10397](https://github.com/JabRef/jabref/issues/10397) - JabRef does not hang anymore when exporting via CLI. [#10380](https://github.com/JabRef/jabref/issues/10380) +- We fixed an issue where exporting "XMP annotated pdf" without selecting an existing document would produce an exception. [#10102](https://github.com/JabRef/jabref/issues/10102) ### Removed diff --git a/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java b/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java index 357f01018ce..21e671b7d4c 100644 --- a/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java +++ b/src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java @@ -45,7 +45,7 @@ public void export(BibDatabaseContext databaseContext, Path pdfFile, List