package net.sf.jabref.imports;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import net.sf.jabref.BibtexEntry;
import net.sf.jabref.Globals;
import net.sf.jabref.JabRefPreferences;
import net.sf.jabref.OutputPrinterToNull;
import net.sf.jabref.external.ExternalFileType;
import net.sf.jabref.util.EncryptionNotSupportedException;
import net.sf.jabref.util.XMPUtil;
/**
* Uses XMPUtils to get one BibtexEntry 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 {
private static Logger logger = Logger.getLogger(EntryFromPDFCreator.class.getName());
public EntryFromPDFCreator() {
super(getPDFExternalFileType());
}
private static ExternalFileType getPDFExternalFileType(){
ExternalFileType pdfFileType = JabRefPreferences.getInstance().getExternalFileTypeByExt("pdf");
if (pdfFileType==null){
return new ExternalFileType("PDF", "pdf", "application/pdf", "evince", "pdfSmall");
}
return pdfFileType;
}
/*
* (non-Javadoc)
*
* @see net.sf.jabref.imports.EntryFromFileCreator#accept(java.io.File)
*
* Accepts all Files having as suffix ".PDF" (in ignore case mode).
*/
@Override
public boolean accept(File f) {
return f != null && f.getName().toUpperCase().endsWith(".PDF");
}
@Override
protected BibtexEntry createBibtexEntry(File pdfFile) {
if (!accept(pdfFile)) {
return null;
}
BibtexEntry entry = new BibtexEntry();
// Read pdf specific metadata
// use PdfContentImporter
PdfContentImporter pci = new PdfContentImporter();
try {
ArrayList<BibtexEntry> list = (ArrayList<BibtexEntry>) pci.importEntries(new FileInputStream(pdfFile), new OutputPrinterToNull());
// there should only be one entry in the arraylist
if(list != null && !list.isEmpty()) {
return list.iterator().next();
}
} catch (FileNotFoundException e) {
logger.log(Level.SEVERE, "File not found", e);
} catch (IOException e) {
logger.log(Level.SEVERE, "Error opening file", e);
}
return null;
/*addEntryDataFromPDDocumentInformation(pdfFile, entry);
addEntyDataFromXMP(pdfFile, entry);
if (entry.getField("title") == null) {
entry.setField("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, BibtexEntry entry) {
PDDocument document = null;
try {
document = PDDocument.load(pdfFile.getAbsoluteFile());
PDDocumentInformation pdfDocInfo = document
.getDocumentInformation();
if (pdfDocInfo!=null){
BibtexEntry entryDI = XMPUtil.getBibtexEntryFromDocumentInformation(document
.getDocumentInformation());
if (entryDI!=null){
addEntryDataToEntry(entry,entryDI);
Calendar creationDate = pdfDocInfo.getCreationDate();
if (creationDate != null) {
String date = new SimpleDateFormat("yyyy.MM.dd")
.format(creationDate.getTime());
appendToField(entry, "timestamp", date.toString());
}
if (pdfDocInfo.getCustomMetadataValue("bibtex/bibtexkey") != null){
entry.setId(pdfDocInfo
.getCustomMetadataValue("bibtex/bibtexkey"));
}
}
}
} catch (IOException e) {
// no canceling here, just no data added.
} finally {
if (document != null) {
try {
document.close();
} catch (IOException e) {
// no canceling here, just no data added.
}
}
}
}
/**
* Adds all data Found in all the entrys 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 addEntyDataFromXMP(File aFile, BibtexEntry entry) {
try {
List<BibtexEntry> entrys = XMPUtil.readXMP(aFile.getAbsoluteFile());
addEntrysToEntry(entry, entrys);
} catch (EncryptionNotSupportedException e) {
// no canceling here, just no data added.
} catch (IOException e) {
// no canceling here, just no data added.
}
}
@Override
public String getFormatName() {
return "PDF";
}
}