Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Refactored around the FileAnnotationCache. #2557

Merged
merged 9 commits into from
Feb 21, 2017
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/BasePanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ public BasePanel(JabRefFrame frame, BibDatabaseContext bibDatabaseContext) {
this.tableModel = new MainTableDataModel(getBibDatabaseContext());

citationStyleCache = new CitationStyleCache(bibDatabaseContext);
annotationCache = new FileAnnotationCache();
annotationCache = new FileAnnotationCache(bibDatabaseContext);

setupMainPanel();

Expand Down
256 changes: 140 additions & 116 deletions src/main/java/org/jabref/gui/entryeditor/EntryEditor.java

Large diffs are not rendered by default.

224 changes: 96 additions & 128 deletions src/main/java/org/jabref/gui/entryeditor/FileAnnotationTab.java

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions src/main/java/org/jabref/logic/pdf/AnnotationImporter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.jabref.logic.pdf;

import java.util.List;

import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.pdf.FileAnnotation;

public interface AnnotationImporter {

List<FileAnnotation> importAnnotations(final String path, final BibDatabaseContext context);
}
54 changes: 54 additions & 0 deletions src/main/java/org/jabref/logic/pdf/EntryAnnotationImporter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.jabref.logic.pdf;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.FieldName;
import org.jabref.model.entry.FileField;
import org.jabref.model.entry.ParsedFileField;
import org.jabref.model.pdf.FileAnnotation;


/**
* Here all PDF files attached to a BibEntry are scanned for annotations using a PdfAnnotationImporter.
*/
public class EntryAnnotationImporter {

private final BibEntry entry;

/**
* @param entry The BibEntry whose attached files are scanned for annotations.
*/
public EntryAnnotationImporter(BibEntry entry) {
this.entry = entry;
}

/**
* Filter files with a web address containing "www."
*
* @return a list of file parsed files
*/
public List<ParsedFileField> getFilteredFileList() {
return FileField.parse(this.entry.getField(FieldName.FILE).get()).stream()
.filter(parsedFileField -> parsedFileField.getLink().toLowerCase().endsWith(".pdf"))
.filter(parsedFileField -> !parsedFileField.getLink().contains("www.")).collect(Collectors.toList());
}

/**
* Reads the annotations from the files that are attached to a BibEntry.
*
* @param context The context is needed for the importer.
* @return Map from each PDF to a list of file annotations
*/
public Map<String, List<FileAnnotation>> importAnnotationsFromFiles(BibDatabaseContext context) {
Map<String, List<FileAnnotation>> annotations = new HashMap<>();
AnnotationImporter importer = new PdfAnnotationImporter();
//import annotationsOfFiles if the selected files are valid which is checked in getFilteredFileList()
this.getFilteredFileList().forEach(parsedFileField -> annotations.put(parsedFileField.getLink(), importer.importAnnotations(parsedFileField.getLink(), context)));
return annotations;
}
}
27 changes: 7 additions & 20 deletions src/main/java/org/jabref/logic/pdf/FileAnnotationCache.java
Original file line number Diff line number Diff line change
@@ -1,54 +1,41 @@
package org.jabref.logic.pdf;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutionException;

import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.pdf.FileAnnotation;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;


public class FileAnnotationCache {

//cache size in entries
private final static int CACHE_SIZE = 10;
//the inner list holds the annotations per file, the outer collection maps this to a BibEntry.
private LoadingCache<BibEntry, Map<String, List<FileAnnotation>>> annotationCache;

public FileAnnotationCache() {
public FileAnnotationCache(BibDatabaseContext context) {
annotationCache = CacheBuilder.newBuilder().maximumSize(CACHE_SIZE).build(new CacheLoader<BibEntry, Map<String, List<FileAnnotation>>>() {
@Override
public Map<String, List<FileAnnotation>> load(BibEntry notUsed) throws Exception {
// Automated reloading of entries is not supported.
return new HashMap<>();
public Map<String, List<FileAnnotation>> load(BibEntry entry) throws Exception {
return new EntryAnnotationImporter(entry).importAnnotationsFromFiles(context);
}
});
}

public void addToCache(BibEntry entry, final Map<String, List<FileAnnotation>> annotations) {
annotationCache.put(entry, annotations);
}

/**
* Note that entry becomes the most recent entry in the cache
*
* @param entry entry for which to get the annotations
* @return Map containing a list of annotations in a list for each file
*/
public Optional<Map<String, List<FileAnnotation>>> getFromCache(Optional<BibEntry> entry) {
Optional<Map<String, List<FileAnnotation>>> emptyAnnotation = Optional.empty();
try {
if (entry.isPresent() && annotationCache.get(entry.get()).size() > 0) {
return Optional.of(annotationCache.get(entry.get()));
}
} catch (ExecutionException failure) {
return emptyAnnotation;
}
return emptyAnnotation;
public Map<String, List<FileAnnotation>> getFromCache(BibEntry entry) throws ExecutionException {
return annotationCache.get(entry);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Optional;

import org.jabref.logic.util.io.FileUtil;
Expand All @@ -24,14 +25,10 @@
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import org.apache.pdfbox.util.PDFTextStripperByArea;

public class PdfAnnotationImporterImpl implements AnnotationImporterInterface {
import static org.jabref.gui.importer.actions.OpenDatabaseAction.LOGGER;

private List pdfPages;
private PDPage page;
public class PdfAnnotationImporter implements AnnotationImporter {

public PdfAnnotationImporterImpl() {

}

/**
* Imports the comments from a pdf specified by its path
Expand Down Expand Up @@ -62,12 +59,12 @@ public List<FileAnnotation> importAnnotations(final String path, final BibDataba
}

} catch (IOException e) {
e.printStackTrace();
LOGGER.error(String.format("Failed to read file %s.", path) , e);
}

pdfPages = document.getDocumentCatalog().getAllPages();
List pdfPages = document.getDocumentCatalog().getAllPages();
for (int i = 0; i < pdfPages.size(); i++) {
page = (PDPage) pdfPages.get(i);
PDPage page = (PDPage) pdfPages.get(i);
try {
for (PDAnnotation annotation : page.getAnnotations()) {

Expand All @@ -82,7 +79,10 @@ public List<FileAnnotation> importAnnotations(final String path, final BibDataba
PDFTextStripperByArea stripperByArea = new PDFTextStripperByArea();
COSArray quadsArray = (COSArray) annotation.getDictionary().getDictionaryObject(COSName.getPDFName("QuadPoints"));
String highlightedText = null;
for (int j = 1, k = 0; j <= (quadsArray.size() / 8); j++) {
for (int j = 1,
k = 0;
j <= (quadsArray.size() / 8);
j++) {

COSFloat upperLeftX = (COSFloat) quadsArray.get(k);
COSFloat upperLeftY = (COSFloat) quadsArray.get(1 + k);
Expand Down Expand Up @@ -124,14 +124,13 @@ public List<FileAnnotation> importAnnotations(final String path, final BibDataba
annotationsList.add(new FileAnnotation(annotation, i + 1));
}
}
} catch (IOException e1) {
e1.printStackTrace();
} catch (IOException e) {
LOGGER.error(String.format("Failed to read file %s.", path) , e);
}
}
try {
document.close();
} catch (IOException e) {
e.printStackTrace();
} catch (IOException ignored) {
}
return annotationsList;
}
Expand All @@ -144,7 +143,7 @@ public List<FileAnnotation> importAnnotations(final String path, final BibDataba
*/
public PDDocument importPdfFile(final String path) throws IOException {

if(path.toLowerCase().endsWith(".pdf")){
if(path.toLowerCase(Locale.ROOT).endsWith(".pdf")){
return PDDocument.load("/"+ path);
}
return null;
Expand Down
14 changes: 7 additions & 7 deletions src/main/java/org/jabref/model/pdf/FileAnnotation.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class FileAnnotation {
private FileAnnotation linkedFileAnnotation;
private final static int ABBREVIATED_ANNOTATION_NAME_LENGTH = 45;

private boolean linkedComment;
private boolean linkedAnnotation;

public FileAnnotation(final String commentId, final String author, final String date, final int page,
final String content, final String annotationType) {
Expand Down Expand Up @@ -56,8 +56,8 @@ private String abbreviateAnnotationName(final String annotationName ){
public void linkComments(FileAnnotation commentToLinkTo){
linkedFileAnnotation = commentToLinkTo;
commentToLinkTo.setLinkedFileAnnotation(this);
commentToLinkTo.setLinkedComment(true);
linkedComment = true;
commentToLinkTo.setLinkedAnnotation(true);
linkedAnnotation = true;
}

@Override
Expand Down Expand Up @@ -117,11 +117,11 @@ public String getAnnotationType() {
return annotationType;
}

public boolean hasLinkedComment() {
return linkedComment;
public boolean hasLinkedAnnotation() {
return linkedAnnotation;
}

public void setLinkedComment(boolean linkedComment) {
this.linkedComment = linkedComment;
public void setLinkedAnnotation(boolean linkedAnnotation) {
this.linkedAnnotation = linkedAnnotation;
}
}