package org.jabref.gui.importer;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import org.jabref.Globals;
import org.jabref.JabRefGUI;
import org.jabref.gui.IconTheme;
import org.jabref.gui.externalfiletype.ExternalFileType;
import org.jabref.gui.externalfiletype.ExternalFileTypes;
import org.jabref.logic.xmp.XMPUtil;
import org.jabref.model.entry.BibEntry;
import org.jabref.pdfimport.PdfImporter;
import org.jabref.pdfimport.PdfImporter.ImportPdfFilesResult;
import org.jabref.preferences.JabRefPreferences;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
/**
* Uses XMPUtils to get one BibEntry for a PDF-File.
* Also imports the non-XMP Data (PDDocument-Information) using XMPUtil.getBibtexEntryFromDocumentInformation.
* If data from more than one entry is read by XMPUtil then this entys are merged into one.
* @author Dan
* @version 12.11.2008 | 22:12:48
*
*/
public class EntryFromPDFCreator extends EntryFromFileCreator {
public EntryFromPDFCreator() {
super(EntryFromPDFCreator.getPDFExternalFileType());
}
private static ExternalFileType getPDFExternalFileType() {
Optional<ExternalFileType> pdfFileType = ExternalFileTypes.getInstance().getExternalFileTypeByExt("pdf");
if (!pdfFileType.isPresent()) {
return new ExternalFileType("PDF", "pdf", "application/pdf", "evince", "pdfSmall", IconTheme.JabRefIcon.PDF_FILE.getSmallIcon());
}
return pdfFileType.get();
}
/**
* Accepts all Files having as suffix ".PDF" (in ignore case mode).
*/
@Override
public boolean accept(File f) {
return (f != null) && f.getName().toUpperCase(Locale.ROOT).endsWith(".PDF");
}
@Override
protected Optional<BibEntry> createBibtexEntry(File pdfFile) {
if (!accept(pdfFile)) {
return Optional.empty();
}
PdfImporter pi = new PdfImporter(JabRefGUI.getMainFrame(), JabRefGUI.getMainFrame().getCurrentBasePanel(), JabRefGUI.getMainFrame().getCurrentBasePanel().getMainTable(), -1);
ImportPdfFilesResult res = pi.importPdfFiles(Collections.singletonList(pdfFile.toString()));
if (res.getEntries().size() == 1) {
return Optional.of(res.getEntries().get(0));
} else {
return Optional.empty();
}
/*addEntryDataFromPDDocumentInformation(pdfFile, entry);
addEntryDataFromXMP(pdfFile, entry);
if (entry.getField(FieldName.TITLE) == null) {
entry.setField(FieldName.TITLE, pdfFile.getName());
}
return entry;*/
}
/** Adds entry data read from the PDDocument information of the file.
* @param pdfFile
* @param entry
*/
private void addEntryDataFromPDDocumentInformation(File pdfFile, BibEntry entry) {
try (PDDocument document = PDDocument.load(pdfFile.getAbsoluteFile())) {
PDDocumentInformation pdfDocInfo = document
.getDocumentInformation();
if (pdfDocInfo != null) {
Optional<BibEntry> entryDI = XMPUtil
.getBibtexEntryFromDocumentInformation(document
.getDocumentInformation());
if (entryDI.isPresent()) {
addEntryDataToEntry(entry, entryDI.get());
Calendar creationDate = pdfDocInfo.getCreationDate();
if (creationDate != null) {
// default time stamp follows ISO-8601. Reason: https://xkcd.com/1179/
String date = LocalDate.of(Calendar.YEAR, Calendar.MONTH + 1, Calendar.DAY_OF_MONTH)
.format(DateTimeFormatter.ISO_LOCAL_DATE);
appendToField(entry, Globals.prefs.get(JabRefPreferences.TIME_STAMP_FIELD), date);
}
if (pdfDocInfo.getCustomMetadataValue("bibtex/bibtexkey") != null) {
entry.setId(pdfDocInfo
.getCustomMetadataValue("bibtex/bibtexkey"));
}
}
}
} catch (IOException e) {
// no canceling here, just no data added.
}
}
/**
* Adds all data Found in all the entries of this XMP file to the given
* entry. This was implemented without having much knowledge of the XMP
* format.
*
* @param aFile
* @param entry
*/
private void addEntryDataFromXMP(File aFile, BibEntry entry) {
try {
List<BibEntry> entrys = XMPUtil.readXMP(aFile.getAbsoluteFile(), Globals.prefs.getXMPPreferences());
addEntrysToEntry(entry, entrys);
} catch (IOException e) {
// no canceling here, just no data added.
}
}
@Override
public String getFormatName() {
return "PDF";
}
}