Skip to content

Commit

Permalink
[WIP] Refactored around the FileAnnotationCache. (#2557)
Browse files Browse the repository at this point in the history
* Refactored quite much around the FileAnnotationCache. The Cache now works as intended, i.e., fully automatically instead of manual maintenance.

* Reverted an incorrect renaming.

* Reverted an incorrect renaming to the original

* Fixed wrong locale message

* fixing @koppor's remarks

* fixed imports, consitent naming

* minor change
  • Loading branch information
LinusDietz authored and tobiasdiez committed Feb 21, 2017
1 parent 43e6138 commit 41d1551
Show file tree
Hide file tree
Showing 8 changed files with 330 additions and 287 deletions.
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;
}
}

0 comments on commit 41d1551

Please sign in to comment.