Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,15 @@ private static Set<Field> filterExcludedFields(Collection<Field> fields) {
/// Filters the given entries to those that violate consistency:
///
/// - Fields not set (but set in other entries of the same type)
/// - Required fields not set
///
///
/// Additionally, the entries are sorted
@VisibleForTesting
List<BibEntry> filterAndSortEntriesWithFieldDifferences(Set<BibEntry> entries, Set<Field> differingFields, Set<Field> requiredFields) {
List<BibEntry> filterAndSortEntriesWithFieldDifferences(Set<BibEntry> entries, Set<Field> differingFields) {
return entries.stream()
.filter(entry ->
// This removes entries that have all differing fields set (could be confusing to the user)
!Collections.disjoint(entry.getFields(), differingFields)
// This ensures that all entries with missing required fields are included
|| !entry.getFields().containsAll(requiredFields))
!Collections.disjoint(entry.getFields(), differingFields))
.sorted(new FieldComparatorStack<>(List.of(
new BibEntryByCitationKeyComparator(),
new BibEntryByFieldsComparator()
Expand All @@ -95,7 +93,7 @@ public record EntryTypeResult(Collection<Field> fields, SequencedCollection<BibE
* Checks the consistency of the given entries by looking at the present and absent fields.
* <p>
* Computation takes place grouped by each entryType.
* Computes the fields set in all entries. In case entries of the same type has more fields defined, it is output.
* Computes the fields set in all entries. In case entries of the same type have more fields defined, they are output.
* <p>
* This class <em>does not</em> check whether all required fields are present or if the fields are valid for the entry type.
* That result can a) be retrieved by using the JabRef UI and b) by checking the CSV output of {@link BibliographyConsistencyCheckResultCsvWriter#writeFindings}
Expand Down Expand Up @@ -138,20 +136,14 @@ public Result check(BibDatabaseContext bibContext, BiConsumer<Integer, Integer>
.filter(def -> def.getType().equals(entryType))
.findFirst();

Set<Field> requiredFields = typeDefOpt.map(typeDef ->
typeDef.getRequiredFields().stream()
.flatMap(orFields -> orFields.getFields().stream())
.collect(Collectors.toSet())
).orElse(Set.of());

Set<BibEntry> entries = entryTypeToEntriesMap.get(entryType);
assert entries != null;
if (entries == null || entries.size() <= 1 || differingFields.isEmpty()) {
// entries.size == 1 can happen if there is only one entry for one type. (E.g., only one `@Book` entry)
continue;
}

List<BibEntry> sortedEntries = filterAndSortEntriesWithFieldDifferences(entries, differingFields, requiredFields);
List<BibEntry> sortedEntries = filterAndSortEntriesWithFieldDifferences(entries, differingFields);
if (!sortedEntries.isEmpty()) {
resultMap.put(entryType, new EntryTypeResult(differingFields, sortedEntries));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,19 @@
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.database.BibDatabaseMode;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.BibEntryType;
import org.jabref.model.entry.BibEntryTypeBuilder;
import org.jabref.model.entry.BibEntryTypesManager;
import org.jabref.model.entry.field.BibField;
import org.jabref.model.entry.field.Field;
import org.jabref.model.entry.field.FieldPriority;
import org.jabref.model.entry.field.SpecialField;
import org.jabref.model.entry.field.StandardField;
import org.jabref.model.entry.field.UnknownField;
import org.jabref.model.entry.field.UserSpecificCommentField;
import org.jabref.model.entry.types.EntryType;
import org.jabref.model.entry.types.StandardEntryType;
import org.jabref.model.entry.types.UnknownEntryType;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
Expand All @@ -23,6 +30,8 @@

class BibliographyConsistencyCheckTest {

private static final EntryType CUSTOM_TYPE = new UnknownEntryType("customType");

@Test
void checkSimpleLibrary(@TempDir Path tempDir) {
BibEntry first = new BibEntry(StandardEntryType.Article, "first")
Expand Down Expand Up @@ -232,14 +241,14 @@ void checkFieldEntriesWithFieldDifferences() {
StandardField.TITLE,
StandardField.PAGES,
new UnknownField("customField"),
StandardField.PUBLISHER
StandardField.PUBLISHER,
StandardField.PDF
);
List<BibEntry> result = new BibliographyConsistencyCheck().filterAndSortEntriesWithFieldDifferences(
Set.of(entry1, entry2, entry3, entry4, entry5),
differingFields,
Set.of(StandardField.AUTHOR, StandardField.TITLE, StandardField.PAGES, StandardField.PDF));
differingFields);

assertEquals(List.of(entry1, entry2, entry3, entry4, entry5), result);
assertEquals(List.of(entry1, entry3, entry4, entry5), result);
}

@Test
Expand Down Expand Up @@ -279,4 +288,31 @@ void checkComplexLibraryWithAdditionalEntry(@TempDir Path tempDir) {
));
assertEquals(expectedResult, actualResult);
}

@Test
void checkCustomEntryTypes() {

BibEntry first = new BibEntry(StandardEntryType.Article, "first")
.withField(StandardField.AUTHOR, "Author One")
.withField(StandardField.PAGES, "some pages");
BibEntry second = new BibEntry(StandardEntryType.Article, "second")
.withField(StandardField.AUTHOR, "Author One")
.withField(StandardField.PUBLISHER, "publisher");
BibDatabase database = new BibDatabase(List.of(first, second));
BibDatabaseContext bibContext = new BibDatabaseContext(database);
bibContext.setMode(BibDatabaseMode.BIBTEX);

BibEntryTypesManager entryTypesManager = new BibEntryTypesManager();
BibEntryType customEntryType = new BibEntryType(CUSTOM_TYPE,
List.of(new BibField(StandardField.AUTHOR, FieldPriority.IMPORTANT), new BibField(StandardField.ABSTRACT, FieldPriority.IMPORTANT)),
Set.of());
entryTypesManager.addCustomOrModifiedType(customEntryType, bibContext.getMode());

BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(bibContext, (count, total) -> {
});

BibliographyConsistencyCheck.EntryTypeResult entryTypeResult = new BibliographyConsistencyCheck.EntryTypeResult(Set.of(StandardField.PAGES, StandardField.PUBLISHER), List.of(first, second));
BibliographyConsistencyCheck.Result expected = new BibliographyConsistencyCheck.Result(Map.of(StandardEntryType.Article, entryTypeResult));
assertEquals(expected, result);
}
}
Loading