diff --git a/src/main/java/org/jabref/logic/externalfiles/ExternalFilesContentImporter.java b/src/main/java/org/jabref/logic/externalfiles/ExternalFilesContentImporter.java index 7a868577c42..bd2bcf0582f 100644 --- a/src/main/java/org/jabref/logic/externalfiles/ExternalFilesContentImporter.java +++ b/src/main/java/org/jabref/logic/externalfiles/ExternalFilesContentImporter.java @@ -20,11 +20,7 @@ public ExternalFilesContentImporter(ImportFormatPreferences importFormatPreferen } public ParserResult importPDFContent(Path file, BibDatabaseContext context, FilePreferences filePreferences) { - try { - return new PdfMergeMetadataImporter(importFormatPreferences).importDatabase(file, context, filePreferences); - } catch (IOException e) { - return ParserResult.fromError(e); - } + return new PdfMergeMetadataImporter(importFormatPreferences).importDatabase(file, context, filePreferences); } public ParserResult importFromBibFile(Path bibFile, FileUpdateMonitor fileUpdateMonitor) throws IOException { diff --git a/src/main/java/org/jabref/logic/importer/fileformat/PdfMergeMetadataImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/PdfMergeMetadataImporter.java index ba8eefa3ab4..6e862b171ba 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/PdfMergeMetadataImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/PdfMergeMetadataImporter.java @@ -4,7 +4,6 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Stream; @@ -26,7 +25,6 @@ import org.jabref.logic.importer.fileformat.pdf.PdfXmpImporter; import org.jabref.logic.importer.util.FileFieldParser; import org.jabref.logic.l10n.Localization; -import org.jabref.logic.util.StandardFileType; import org.jabref.logic.util.io.FileUtil; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; @@ -76,8 +74,8 @@ public PdfMergeMetadataImporter(ImportFormatPreferences importFormatPreferences) * 2. Run {@link PdfImporter}s, and store extracted candidates in the list. */ @Override - public List importDatabase(Path filePath, PDDocument document) throws IOException, ParseException { - List extractedCandidates = extractCandidatesFromPdf(filePath, document); + public List importDatabase(Path fullPath, PDDocument document) throws IOException, ParseException { + List extractedCandidates = extractCandidatesFromPdf(fullPath, document); if (extractedCandidates.isEmpty()) { return List.of(); } @@ -87,12 +85,24 @@ public List importDatabase(Path filePath, PDDocument document) throws Stream allCandidates = Stream.concat(fetchedCandidates.stream(), extractedCandidates.stream()); BibEntry entry = mergeCandidates(allCandidates); - // We use the absolute path here as we do not know the context where this import will be used. - // The caller is responsible for making the path relative if necessary. - entry.addFile(new LinkedFile("", filePath, StandardFileType.PDF.getName())); return List.of(entry); } + /** + * Enhanced {@link PdfImporter#importDatabase(Path)} method that relativizes paths of PDF files (if turned on in the preferences). + */ + public ParserResult importDatabase(Path filePath, BibDatabaseContext bibDatabaseContext, FilePreferences filePreferences) { + ParserResult parserResult = importDatabase(filePath); + + if (filePreferences.shouldStoreFilesRelativeToBibFile() && bibDatabaseContext.getDatabasePath().isPresent()) { + Path storePath = bibDatabaseContext.getDatabasePath().get().getParent().relativize(filePath); + parserResult.getDatabase().getEntries().forEach(entry -> + entry.addFile(new LinkedFile("", storePath, StandardField.PDF.getName()))); + } + + return parserResult; + } + private List extractCandidatesFromPdf(Path filePath, PDDocument document) { List candidates = new ArrayList<>(); @@ -186,13 +196,6 @@ private static BibEntry mergeCandidates(Stream candidates) { return entry; } - public ParserResult importDatabase(Path filePath, BibDatabaseContext context, FilePreferences filePreferences) throws IOException { - Objects.requireNonNull(context); - Objects.requireNonNull(filePreferences); - - return importDatabase(filePath); - } - @Override public String getId() { return "pdfMerged"; diff --git a/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfContentImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfContentImporter.java index 292fbc62b14..bdf9a56b496 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfContentImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfContentImporter.java @@ -185,7 +185,7 @@ private String streamlineTitle(String title) { return removeNonLettersAtEnd(title); } - public List importDatabase(Path filePath, PDDocument document) throws IOException { + public List importDatabase(Path fullPath, PDDocument document) throws IOException { List result = new ArrayList<>(1); String firstPageContents = PdfUtils.getFirstPageContents(document); Optional titleByFontSize = extractTitleFromDocument(document); diff --git a/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfEmbeddedBibFileImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfEmbeddedBibFileImporter.java index a071bc98bef..18c2bb6a890 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfEmbeddedBibFileImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfEmbeddedBibFileImporter.java @@ -38,7 +38,7 @@ public PdfEmbeddedBibFileImporter(ImportFormatPreferences importFormatPreference * Extraction of embedded files in pdfs adapted from: * ... */ - public List importDatabase(Path filePath, PDDocument document) throws IOException, ParseException { + public List importDatabase(Path fullPath, PDDocument document) throws IOException, ParseException { List allParsedEntries = new ArrayList<>(); PDDocumentNameDictionary nameDictionary = document.getDocumentCatalog().getNames(); if (nameDictionary != null) { diff --git a/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfGrobidImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfGrobidImporter.java index fbcdbda830c..3579bd36ee0 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfGrobidImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfGrobidImporter.java @@ -25,8 +25,8 @@ public PdfGrobidImporter(ImportFormatPreferences importFormatPreferences) { this.importFormatPreferences = importFormatPreferences; } - public List importDatabase(Path filePath, PDDocument document) throws IOException, ParseException { - return grobidService.processPDF(filePath, importFormatPreferences); + public List importDatabase(Path fullPath, PDDocument document) throws IOException, ParseException { + return grobidService.processPDF(fullPath, importFormatPreferences); } @Override diff --git a/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfImporter.java index 32f0489737b..e1260139313 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfImporter.java @@ -31,7 +31,14 @@ * {@link PdfImporter#importDatabase(Path)} or {@link PdfMergeMetadataImporter}. */ public abstract class PdfImporter extends Importer { - public abstract List importDatabase(Path filePath, PDDocument document) throws IOException, ParseException; + /** + * Abstract method that inheritors should define. + *

+ * It contains two arguments: `fullPath`, which you can use to read file again for other properties + * (like XMP metadata); and `document`, which is a parsed PDF file. Many importers parse PDF files, + * so it was decided to parse it only once and provide the parsed data structure as an argument. + */ + public abstract List importDatabase(Path fullPath, PDDocument document) throws IOException, ParseException; @Override public boolean isRecognizedFormat(BufferedReader input) throws IOException { diff --git a/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfVerbatimBibtexImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfVerbatimBibtexImporter.java index d883f51805a..fd00104bf49 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfVerbatimBibtexImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfVerbatimBibtexImporter.java @@ -24,7 +24,7 @@ public PdfVerbatimBibtexImporter(ImportFormatPreferences importFormatPreferences this.importFormatPreferences = importFormatPreferences; } - public List importDatabase(Path filePath, PDDocument document) throws IOException, ParseException { + public List importDatabase(Path fullPath, PDDocument document) throws IOException, ParseException { List result; String firstPageContents = PdfUtils.getFirstPageContents(document); BibtexParser parser = new BibtexParser(importFormatPreferences); diff --git a/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfXmpImporter.java b/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfXmpImporter.java index 93eefa4e8d3..c0fc31d99fa 100644 --- a/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfXmpImporter.java +++ b/src/main/java/org/jabref/logic/importer/fileformat/pdf/PdfXmpImporter.java @@ -22,8 +22,8 @@ public PdfXmpImporter(XmpPreferences xmpPreferences) { this.xmpPreferences = xmpPreferences; } - public List importDatabase(Path filePath, PDDocument document) throws IOException { - return new XmpUtilReader().readXmp(filePath, xmpPreferences); + public List importDatabase(Path fullPath, PDDocument document) throws IOException { + return new XmpUtilReader().readXmp(fullPath, xmpPreferences); } @Override diff --git a/src/test/java/org/jabref/logic/importer/fileformat/pdf/PdfMergeMetadataImporterTest.java b/src/test/java/org/jabref/logic/importer/fileformat/pdf/PdfMergeMetadataImporterTest.java index 3e55db53d47..f5f7880aaba 100644 --- a/src/test/java/org/jabref/logic/importer/fileformat/pdf/PdfMergeMetadataImporterTest.java +++ b/src/test/java/org/jabref/logic/importer/fileformat/pdf/PdfMergeMetadataImporterTest.java @@ -90,22 +90,22 @@ void importWorksAsExpected() throws Exception { @Test void importRelativizesFilePath() throws Exception { - // Initialize database and preferences - FilePreferences preferences = mock(FilePreferences.class); - BibDatabaseContext database = new BibDatabaseContext(); - - // Initialize file and working directory Path file = Path.of(PdfMergeMetadataImporter.class.getResource("/pdfs/minimal.pdf").toURI()); Path directory = Path.of(PdfMergeMetadataImporter.class.getResource("/pdfs/").toURI()); - preferences.setWorkingDirectory(directory); - List result = importer.importDatabase(file, database, preferences).getDatabase().getEntries(); + FilePreferences filePreferences = mock(FilePreferences.class); + when(filePreferences.shouldStoreFilesRelativeToBibFile()).thenReturn(true); + + BibDatabaseContext database = new BibDatabaseContext(); + database.setDatabasePath(directory.resolve("db.bib")); + + List result = importer.importDatabase(file, database, filePreferences).getDatabase().getEntries(); BibEntry expected = new BibEntry(StandardEntryType.InProceedings) .withField(StandardField.AUTHOR, "1 ") .withField(StandardField.TITLE, "Hello World") // Expecting relative path - .withField(StandardField.FILE, ":minimal.pdf:PDF"); + .withField(StandardField.FILE, ":minimal.pdf:pdf"); assertEquals(List.of(expected), result); }