Skip to content

Commit

Permalink
Code improvement of PdfImporter
Browse files Browse the repository at this point in the history
 * Make use of XMPUtil.hasMetadata
 * try-with-resources
  • Loading branch information
koppor committed Mar 12, 2016
1 parent ae0621c commit ad2a9cd
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 95 deletions.
68 changes: 47 additions & 21 deletions src/main/java/net/sf/jabref/logic/xmp/XMPUtil.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2003-2015 JabRef contributors.
/* Copyright (C) 2003-2016 JabRef contributors.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
Expand All @@ -17,6 +17,9 @@

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.*;

import javax.xml.transform.TransformerException;
Expand All @@ -30,6 +33,9 @@
import net.sf.jabref.model.entry.*;
import net.sf.jabref.bibtex.BibEntryWriter;
import net.sf.jabref.model.database.BibDatabase;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jempbox.impl.DateConverter;
import org.apache.jempbox.impl.XMLUtil;
import org.apache.jempbox.xmp.XMPMetadata;
Expand All @@ -43,15 +49,17 @@
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.apache.pdfbox.pdmodel.common.PDMetadata;
import org.w3c.dom.Document;

/**
* XMPUtils provide support for reading and writing BibTex data as XMP-Metadata
* in PDF-documents.
*
* @author Christopher Oezbek <oezi@oezi.de>
*/
public class XMPUtil {

private static final Log LOGGER = LogFactory.getLog(XMPUtil.class);


/**
* Convenience method for readXMP(File).
*
Expand Down Expand Up @@ -105,9 +113,11 @@ public static void writeXMP(String filename, BibEntry entry,
* than remove a lock or cancel the operation.
*/
public static List<BibEntry> readXMP(File file) throws IOException {
List<BibEntry> res = Collections.EMPTY_LIST;
try (FileInputStream is = new FileInputStream(file)) {
return XMPUtil.readXMP(is);
res = XMPUtil.readXMP(is);
}
return res;
}

/**
Expand All @@ -120,6 +130,8 @@ public static List<BibEntry> readXMP(File file) throws IOException {
* @throws IOException
* Throws an IOException if the file cannot be read, so the user
* than remove a lock or cancel the operation.
*
* @return list of BibEntries retrieved from the stream. May be empty, but never null
*/
public static List<BibEntry> readXMP(InputStream inputStream)
throws IOException {
Expand All @@ -128,32 +140,29 @@ public static List<BibEntry> readXMP(InputStream inputStream)

try (PDDocument document = PDDocument.load(inputStream)) {
if (document.isEncrypted()) {
throw new EncryptionNotSupportedException(
"Error: Cannot read metadata from encrypted document.");
throw new EncryptionNotSupportedException("Error: Cannot read metadata from encrypted document.");
}

XMPMetadata meta = XMPUtil.getXMPMetadata(document);

// If we did not find any XMP metadata, search for non XMP metadata
if (meta != null) {

List<XMPSchema> schemas = meta
.getSchemasByNamespaceURI(XMPSchemaBibtex.NAMESPACE);
List<XMPSchema> schemas = meta.getSchemasByNamespaceURI(XMPSchemaBibtex.NAMESPACE);

for (XMPSchema schema : schemas) {
XMPSchemaBibtex bib = (XMPSchemaBibtex) schema;

BibEntry entry = bib.getBibtexEntry();
if(entry.getType() == null) {
if (entry.getType() == null) {
entry.setType("misc");
}
result.add(entry);
}

// If we did not find anything have a look if a Dublin Core exists
if (result.isEmpty()) {
schemas = meta
.getSchemasByNamespaceURI(XMPSchemaDublinCore.NAMESPACE);
schemas = meta.getSchemasByNamespaceURI(XMPSchemaDublinCore.NAMESPACE);
for (XMPSchema schema : schemas) {
XMPSchemaDublinCore dc = (XMPSchemaDublinCore) schema;

Expand All @@ -169,20 +178,15 @@ public static List<BibEntry> readXMP(InputStream inputStream)
}
}
if (result.isEmpty()) {
Optional<BibEntry> entry = XMPUtil
.getBibtexEntryFromDocumentInformation(document
.getDocumentInformation());

PDDocumentInformation documentInformation = document.getDocumentInformation();
Optional<BibEntry> entry = XMPUtil.getBibtexEntryFromDocumentInformation(documentInformation);
if (entry.isPresent()) {
if (entry.get().getType() == null) {
entry.get().setType("misc");
}
result.add(entry.get());
}
}
}

// return null, if no metadata was found
// return empty list, if no metadata was found
if (result.isEmpty()) {
return Collections.emptyList();
}
Expand Down Expand Up @@ -515,6 +519,9 @@ private static XMPMetadata readRawXMP(InputStream inputStream) throws IOExceptio
}
}

/**
* @return null if no metadata has been found
*/
private static XMPMetadata getXMPMetadata(PDDocument document) throws IOException {
PDDocumentCatalog catalog = document.getDocumentCatalog();
PDMetadata metaRaw = catalog.getMetadata();
Expand All @@ -523,8 +530,11 @@ private static XMPMetadata getXMPMetadata(PDDocument document) throws IOExceptio
return null;
}

XMPMetadata meta = new XMPMetadata(XMLUtil.parse(metaRaw
.createInputStream()));
Document parseResult;
try (InputStream is = metaRaw.createInputStream()) {
parseResult = XMLUtil.parse(is);
}
XMPMetadata meta = new XMPMetadata(parseResult);
meta.addXMLNSMapping(XMPSchemaBibtex.NAMESPACE, XMPSchemaBibtex.class);
return meta;
}
Expand Down Expand Up @@ -1232,6 +1242,18 @@ public static void main(String[] args) throws IOException,
}
}

/**
* see XMPUtil.hasMetadata(InputStream is)
*/
public static boolean hasMetadata(Path p) {
try (InputStream is = Files.newInputStream(p, StandardOpenOption.READ)) {
return hasMetadata(is);
} catch (IOException e) {
LOGGER.error("XMP reading failed", e);
return false;
}
}

/**
* Will try to read XMP metadata from the given file, returning whether
* metadata was found.
Expand All @@ -1247,7 +1269,11 @@ public static boolean hasMetadata(InputStream is) {
try {
List<BibEntry> l = XMPUtil.readXMP(is);
return !l.isEmpty();
} catch (EncryptionNotSupportedException ex) {
LOGGER.info("Encryption not supported by XMPUtil");
return false;
} catch (IOException e) {
LOGGER.error("XMP reading failed", e);
return false;
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/net/sf/jabref/model/entry/BibEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public String getType() {
* Sets this entry's type.
*/
public void setType(String type) {
if(type == null) {
if (type == null) {
type = DEFAULT_TYPE;
}

Expand All @@ -120,7 +120,6 @@ public void setType(String type) {
} catch (PropertyVetoException pve) {
LOGGER.warn(pve);
}

}

/**
Expand Down
92 changes: 20 additions & 72 deletions src/main/java/net/sf/jabref/pdfimport/PdfImporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
import java.awt.Point;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand All @@ -46,7 +46,6 @@
import net.sf.jabref.gui.entryeditor.EntryEditor;
import net.sf.jabref.gui.preftabs.ImportSettingsTab;
import net.sf.jabref.gui.undo.UndoableInsertEntry;
import net.sf.jabref.gui.util.FocusRequester;
import net.sf.jabref.gui.util.PositionWindow;
import net.sf.jabref.importer.OutputPrinter;
import net.sf.jabref.importer.fileformat.PdfContentImporter;
Expand Down Expand Up @@ -143,10 +142,9 @@ private List<BibEntry> importPdfFiles(List<String> fileNames, OutputPrinter stat
List<BibEntry> res = new ArrayList<>();

for (String fileName : fileNames) {
List<BibEntry> xmpEntriesInFile = readXmpEntries(fileName);
if (!neverShow && !doNotShowAgain) {
importDialog = new ImportDialog(dropRow >= 0, fileName);
if (!hasXmpEntries(xmpEntriesInFile)) {
if (!XMPUtil.hasMetadata(Paths.get(fileName))) {
importDialog.disableXMPChoice();
}
centerRelativeToWindow(importDialog, frame);
Expand Down Expand Up @@ -226,48 +224,30 @@ private BibEntry createNewBlankEntry(String fileName) {

private void doContentImport(String fileName, List<BibEntry> res, OutputPrinter status) {
File file = new File(fileName);
InputStream in;
BibEntry entry;
try {
in = new FileInputStream(file);
} catch (FileNotFoundException e) {
// import failed -> generate default entry
LOGGER.info("Import failed", e);
entry = createNewBlankEntry(fileName);
res.add(entry);
return;
}
PdfContentImporter contentImporter = new PdfContentImporter();
List<BibEntry> localRes = null;
try {
try (InputStream in = new FileInputStream(file)) {
PdfContentImporter contentImporter = new PdfContentImporter();
List<BibEntry> localRes = null;
localRes = contentImporter.importEntries(in, status);

if ((localRes == null) || localRes.isEmpty()) {
// import failed -> generate default entry
entry = createNewBlankEntry(fileName);
res.add(entry);
return;
}

// only one entry is imported
entry = localRes.get(0);
} catch (IOException e) {
// import failed -> generate default entry
LOGGER.info("Import failed", e);
entry = createNewBlankEntry(fileName);
res.add(entry);
return;
} finally {
try {
in.close();
} catch (IOException ex) {
LOGGER.warn("Problem closing PDF", ex);
// Ignored
}
}

// import failed -> generate default entry
if ((localRes == null) || localRes.isEmpty()) {
entry = createNewBlankEntry(fileName);
res.add(entry);
return;
}

// only one entry is imported
entry = localRes.get(0);

// insert entry to database and link file

panel.database().insertEntry(entry);
panel.markBaseChanged();
LabelPatternUtil.makeLabel(panel.getBibDatabaseContext().getMetaData(), panel.database(), entry);
Expand All @@ -280,12 +260,10 @@ private void doContentImport(String fileName, List<BibEntry> res, OutputPrinter
panel.adjustSplitter();
}
res.add(entry);

}

private BibEntry createNewEntry() {

// Find out what type is wanted.
// Find out what type is desired
EntryTypeDialog etd = new EntryTypeDialog(frame);
// We want to center the dialog, to make it look nicer.
PositionWindow.placeDialog(etd, frame);
Expand Down Expand Up @@ -316,27 +294,11 @@ private BibEntry createNewEntry() {
panel.setMode(BasePanel.WILL_SHOW_EDITOR);
}

/*int row = entryTable.findEntry(be);
if (row >= 0)
// Selects the entry. The selection listener will open the editor.
if (row >= 0) {
try{
entryTable.setRowSelectionInterval(row, row);
}catch(IllegalArgumentException e){
System.out.println("RowCount: " + entryTable.getRowCount());
}
//entryTable.setActiveRow(row);
entryTable.ensureVisible(row);
}
else {
// The entry is not visible in the table, perhaps due to a filtering search
// or group selection. Show the entry editor anyway:
panel.showEntry(be);
} */
panel.showEntry(be);
panel.markBaseChanged(); // The database just changed.
new FocusRequester(panel.getEntryEditor(be));

// The database just changed.
panel.markBaseChanged();

return be;
} catch (KeyCollisionException ex) {
LOGGER.info("Key collision occurred", ex);
Expand All @@ -345,20 +307,6 @@ private BibEntry createNewEntry() {
return null;
}

private static List<BibEntry> readXmpEntries(String fileName) {
List<BibEntry> xmpEntriesInFile = null;
try {
xmpEntriesInFile = XMPUtil.readXMP(fileName);
} catch (IOException e) {
LOGGER.error("XMPUtil.readXMP failed", e);
}
return xmpEntriesInFile;
}

private static boolean hasXmpEntries(List<BibEntry> xmpEntriesInFile) {
return !((xmpEntriesInFile == null) || xmpEntriesInFile.isEmpty());
}

public MainTable getEntryTable() {
return entryTable;
}
Expand Down

0 comments on commit ad2a9cd

Please sign in to comment.