Skip to content

Commit

Permalink
Check duplicate DOI (#6333)
Browse files Browse the repository at this point in the history
Co-authored-by: Jonas Moosmann <j.moosmann@gmx.de>
Co-authored-by: Stefan Kolb <stefan-kolb@web.de>
Co-authored-by: Stefan Kufer <stefan.kufer@diva-e.com>
  • Loading branch information
4 people authored May 15, 2020
1 parent 4b40cce commit 7bfbe44
Show file tree
Hide file tree
Showing 27 changed files with 172 additions and 92 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve
- We added support for basic markdown in custom formatted previews [#6194](https://github.com/JabRef/jabref/issues/6194)
- We now show the number of items found and selected to import in the online search dialog. [#6248](https://github.com/JabRef/jabref/pull/6248)
- We created a new install screen for macOS. [#5759](https://github.com/JabRef/jabref/issues/5759)
- We added a new integrity check for duplicate DOIs. [koppor#339](https://github.com/koppor/jabref/issues/339)
- We implemented an option to download fulltext files while importing. [#6381](https://github.com/JabRef/jabref/pull/6381)
- We added a progress-indicator showing the average progress of background tasks to the toolbar. Clicking it reveals a pop-over with a list of running background tasks. [6443](https://github.com/JabRef/jabref/pull/6443)
- We fixed the bug when strike the delete key in the text field. [#6421](https://github.com/JabRef/jabref/issues/6421)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ protected List<IntegrityMessage> call() {
List<IntegrityMessage> result = new ArrayList<>();

ObservableList<BibEntry> entries = database.getDatabase().getEntries();
result.addAll(check.checkDatabase(database.getDatabase()));
for (int i = 0; i < entries.size(); i++) {
if (isCancelled()) {
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@
import java.util.List;
import java.util.Map;

import org.jabref.logic.integrity.IntegrityCheck.Checker;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.Field;

import com.google.common.base.CharMatcher;

public class ASCIICharacterChecker implements Checker {
public class ASCIICharacterChecker implements EntryChecker {

/**
* Detect any non ASCII encoded characters, e.g., umlauts or unicode in the fields
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,19 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jabref.logic.integrity.IntegrityCheck.Checker;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.Field;
import org.jabref.model.entry.field.FieldProperty;

public class BibStringChecker implements Checker {
/**
* Checks, if there is an even number of unescaped #
*/
public class BibStringChecker implements EntryChecker {

// Detect # if it doesn't have a \ in front of it or if it starts the string
private static final Pattern UNESCAPED_HASH = Pattern.compile("(?<!\\\\)#|^#");

/**
* Checks, if there is an even number of unescaped #
*/
@Override
public List<IntegrityMessage> check(BibEntry entry) {
List<IntegrityMessage> results = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.util.Collections;
import java.util.List;

import org.jabref.logic.integrity.IntegrityCheck.Checker;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.InternalField;
Expand All @@ -12,7 +11,7 @@
/**
* BibTeX mode only checker
*/
public class BibTeXEntryTypeChecker implements Checker {
public class BibTeXEntryTypeChecker implements EntryChecker {
/**
* Will check if the current library uses any entry types from another mode.
* For example it will warn the user if he uses entry types defined for Biblatex inside a BibTeX library.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import java.util.List;
import java.util.Optional;

import org.jabref.logic.integrity.IntegrityCheck.Checker;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.InternalField;
Expand All @@ -14,14 +13,14 @@
/**
* Currently only checks the key if there is an author, year, and title present.
*/
public class BibtexKeyChecker implements Checker {
public class BibtexKeyChecker implements EntryChecker {

@Override
public List<IntegrityMessage> check(BibEntry entry) {
Optional<String> author = entry.getField(StandardField.AUTHOR);
Optional<String> title = entry.getField(StandardField.TITLE);
Optional<String> year = entry.getField(StandardField.YEAR);
if (!author.isPresent() || !title.isPresent() || !year.isPresent()) {
if (author.isEmpty() || title.isEmpty() || year.isEmpty()) {
return Collections.emptyList();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
import java.util.Objects;
import java.util.Optional;

import org.jabref.logic.integrity.IntegrityCheck.Checker;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabase;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.StandardField;

public class BibtexKeyDuplicationChecker implements Checker {
public class BibtexKeyDuplicationChecker implements EntryChecker {

private final BibDatabase database;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@

import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator;
import org.jabref.logic.bibtexkeypattern.BibtexKeyPatternPreferences;
import org.jabref.logic.integrity.IntegrityCheck.Checker;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.InternalField;

public class BibtexkeyDeviationChecker implements Checker {
public class BibtexkeyDeviationChecker implements EntryChecker {

private final BibDatabaseContext bibDatabaseContext;
private final BibtexKeyPatternPreferences bibtexKeyPatternPreferences;
Expand All @@ -26,7 +25,7 @@ public BibtexkeyDeviationChecker(BibDatabaseContext bibDatabaseContext, BibtexKe
@Override
public List<IntegrityMessage> check(BibEntry entry) {
Optional<String> valuekey = entry.getCiteKeyOptional();
if (!valuekey.isPresent()) {
if (valuekey.isEmpty()) {
return Collections.emptyList();
}

Expand Down
10 changes: 10 additions & 0 deletions src/main/java/org/jabref/logic/integrity/DatabaseChecker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.jabref.logic.integrity;

import java.util.List;

import org.jabref.model.database.BibDatabase;

@FunctionalInterface
public interface DatabaseChecker {
List<IntegrityMessage> check(BibDatabase database);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.jabref.logic.integrity;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javafx.collections.ObservableList;

import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabase;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.StandardField;
import org.jabref.model.entry.identifier.DOI;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;

public class DoiDuplicationChecker implements DatabaseChecker {

@Override
public List<IntegrityMessage> check(BibDatabase database) {
ObservableList<BibEntry> bibEntries = database.getEntries();
BiMap<DOI, List<BibEntry>> duplicateMap = HashBiMap.create(bibEntries.size());
for (BibEntry bibEntry : bibEntries) {
bibEntry.getDOI().ifPresent(doi ->
duplicateMap.computeIfAbsent(doi, absentDoi -> new ArrayList<>()).add(bibEntry));
}

return duplicateMap.inverse().keySet().stream()
.filter(list -> list.size() > 1)
.flatMap(list -> list.stream())
.map(item -> new IntegrityMessage(Localization.lang("Same DOI used in multiple entries"), item, StandardField.DOI))
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
import org.jabref.model.entry.identifier.DOI;
import org.jabref.model.strings.StringUtil;

public class DOIValidityChecker implements ValueChecker {

public class DoiValidityChecker implements ValueChecker {
@Override
public Optional<String> checkValue(String value) {
if (StringUtil.isBlank(value)) {
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/org/jabref/logic/integrity/EntryChecker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.jabref.logic.integrity;

import java.util.List;

import org.jabref.model.entry.BibEntry;

@FunctionalInterface
public interface EntryChecker {
List<IntegrityMessage> check(BibEntry entry);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@
import java.util.Objects;
import java.util.Set;

import org.jabref.logic.integrity.IntegrityCheck.Checker;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabase;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.Field;
import org.jabref.model.entry.field.FieldProperty;

public class EntryLinkChecker implements Checker {
public class EntryLinkChecker implements EntryChecker {

private final BibDatabase database;

Expand All @@ -28,14 +27,14 @@ public List<IntegrityMessage> check(BibEntry entry) {
for (Entry<Field, String> field : entry.getFieldMap().entrySet()) {
Set<FieldProperty> properties = field.getKey().getProperties();
if (properties.contains(FieldProperty.SINGLE_ENTRY_LINK)) {
if (!database.getEntryByKey(field.getValue()).isPresent()) {
if (database.getEntryByKey(field.getValue()).isEmpty()) {
result.add(new IntegrityMessage(Localization.lang("Referenced BibTeX key does not exist"), entry,
field.getKey()));
}
} else if (properties.contains(FieldProperty.MULTIPLE_ENTRY_LINK)) {
List<String> keys = new ArrayList<>(Arrays.asList(field.getValue().split(",")));
for (String key : keys) {
if (!database.getEntryByKey(key).isPresent()) {
if (database.getEntryByKey(key).isEmpty()) {
result.add(new IntegrityMessage(
Localization.lang("Referenced BibTeX key does not exist") + ": " + key, entry,
field.getKey()));
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/jabref/logic/integrity/FieldChecker.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import org.jabref.model.entry.field.Field;
import org.jabref.model.util.OptionalUtil;

public class FieldChecker implements IntegrityCheck.Checker {
public class FieldChecker implements EntryChecker {
protected final Field field;
private final ValueChecker checker;

Expand All @@ -21,7 +21,7 @@ public FieldChecker(Field field, ValueChecker checker) {
@Override
public List<IntegrityMessage> check(BibEntry entry) {
Optional<String> value = entry.getField(field);
if (!value.isPresent()) {
if (value.isEmpty()) {
return Collections.emptyList();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ private static Multimap<Field, ValueChecker> getAllMap(BibDatabaseContext databa
fieldCheckers.put(StandardField.BOOKTITLE, new BooktitleChecker());
fieldCheckers.put(StandardField.TITLE, new BracketChecker());
fieldCheckers.put(StandardField.TITLE, new TitleChecker(databaseContext));
fieldCheckers.put(StandardField.DOI, new DOIValidityChecker());
fieldCheckers.put(StandardField.DOI, new DoiValidityChecker());
fieldCheckers.put(StandardField.EDITION, new EditionChecker(databaseContext, allowIntegerEdition));
fieldCheckers.put(StandardField.FILE, new FileChecker(databaseContext, filePreferences));
fieldCheckers.put(StandardField.HOWPUBLISHED, new HowPublishedChecker(databaseContext));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,18 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jabref.logic.integrity.IntegrityCheck.Checker;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.Field;
import org.jabref.model.entry.field.FieldProperty;

public class HTMLCharacterChecker implements Checker {
// Detect any HTML encoded character,
/**
* Checks, if there are any HTML encoded characters in nonverbatim fields.
*/
public class HTMLCharacterChecker implements EntryChecker {
// Detect any HTML encoded character
private static final Pattern HTML_CHARACTER_PATTERN = Pattern.compile("&[#\\p{Alnum}]+;");

/**
* Checks, if there are any HTML encoded characters in nonverbatim fields.
*/
@Override
public List<IntegrityMessage> check(BibEntry entry) {
List<IntegrityMessage> results = new ArrayList<>();
Expand Down
Loading

0 comments on commit 7bfbe44

Please sign in to comment.