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

Check duplicate DOI #6333

Merged
merged 21 commits into from
May 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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