Skip to content

Commit 50c605c

Browse files
Siedlerchrkopporsubhramit
authored
Add progess output for consisteny check (#13181)
* Add progess output for consisteny check Fixes #12487 * better handling of not present * checkstyle * fix test * Revert some intellij formatting changes * Update ArgumentProcessorTest.java --------- Co-authored-by: Oliver Kopp <[email protected]> Co-authored-by: Subhramit Basu <[email protected]>
1 parent 3e1a4f4 commit 50c605c

File tree

9 files changed

+70
-39
lines changed

9 files changed

+70
-39
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
3131
- We renamed the "Body Text" CSL bibliography header format name to "Text body" as per internal LibreOffice conventions. [#13074](https://github.com/JabRef/jabref/pull/13074)
3232
- We moved the "Modify bibliography title" option from the CSL styles tab of the Select Style dialog to the OpenOffice/LibreOffice side panel and renamed it to "Bibliography properties". [#13074](https://github.com/JabRef/jabref/pull/13074)
3333
- We changed path output display to show the relative path with respect to library path in context of library properties. [#13031](https://github.com/JabRef/jabref/issues/13031)
34+
- We added a progress dialog to the "Check consistency" action and progress output to the corresponding cli command. [#12487](https://github.com/JabRef/jabref/issues/12487)
3435

3536
### Fixed
3637

jabgui/src/main/java/org/jabref/gui/consistency/ConsistencyCheckAction.java

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package org.jabref.gui.consistency;
22

33
import java.util.List;
4+
import java.util.Optional;
45
import java.util.function.Supplier;
56

7+
import javafx.concurrent.Task;
8+
69
import org.jabref.gui.DialogService;
710
import org.jabref.gui.LibraryTab;
811
import org.jabref.gui.StateManager;
@@ -11,7 +14,6 @@
1114
import org.jabref.gui.util.UiTaskExecutor;
1215
import org.jabref.logic.l10n.Localization;
1316
import org.jabref.logic.quality.consistency.BibliographyConsistencyCheck;
14-
import org.jabref.logic.util.BackgroundTask;
1517
import org.jabref.model.database.BibDatabaseContext;
1618
import org.jabref.model.entry.BibEntry;
1719
import org.jabref.model.entry.BibEntryTypesManager;
@@ -45,22 +47,39 @@ public ConsistencyCheckAction(Supplier<LibraryTab> tabSupplier,
4547

4648
@Override
4749
public void execute() {
48-
BackgroundTask.wrap(() -> {
49-
BibDatabaseContext databaseContext = stateManager.getActiveDatabase()
50-
.orElseThrow(() -> new NullPointerException("Database null"));
51-
List<BibEntry> entries = databaseContext.getDatabase().getEntries();
50+
Task<BibliographyConsistencyCheck.Result> task = new Task<>() {
51+
@Override
52+
public BibliographyConsistencyCheck.Result call() throws Exception {
53+
54+
Optional<BibDatabaseContext> databaseContext = stateManager.getActiveDatabase();
55+
if (databaseContext.isEmpty()) {
56+
throw new IllegalStateException((Localization.lang("No library present")));
57+
}
58+
List<BibEntry> entries = databaseContext.get().getEntries();
5259

53-
BibliographyConsistencyCheck consistencyCheck = new BibliographyConsistencyCheck();
54-
return consistencyCheck.check(entries);
55-
}).onSuccess(result -> {
56-
if (result.entryTypeToResultMap().isEmpty()) {
60+
BibliographyConsistencyCheck consistencyCheck = new BibliographyConsistencyCheck();
61+
return consistencyCheck.check(entries, (count, total) ->
62+
UiTaskExecutor.runInJavaFXThread(() -> {
63+
updateProgress(count, total);
64+
updateMessage(Localization.lang("%0/%1 entry types", count + 1, total));
65+
}));
66+
}
67+
};
68+
69+
task.setOnFailed(_ -> dialogService.showErrorDialogAndWait(Localization.lang("Consistency check failed."), task.getException()));
70+
task.setOnSucceeded(_ -> {
71+
if (task.getValue().entryTypeToResultMap().isEmpty()) {
5772
dialogService.notify(Localization.lang("No problems found."));
5873
} else {
5974
dialogService.showCustomDialogAndWait(
60-
new ConsistencyCheckDialog(tabSupplier.get(), dialogService, preferences, entryTypesManager, result));
75+
new ConsistencyCheckDialog(tabSupplier.get(), dialogService, preferences, entryTypesManager, task.getValue()));
6176
}
62-
}).onFailure(exception ->
63-
dialogService.showErrorDialogAndWait(Localization.lang("Consistency check failed."), exception)
64-
).executeWith(taskExecutor);
77+
});
78+
taskExecutor.execute(task);
79+
80+
dialogService.showProgressDialogAndWait(
81+
Localization.lang("Check consistency"),
82+
Localization.lang("Checking consistency..."),
83+
task);
6584
}
6685
}

jabkit/src/main/java/org/jabref/cli/CheckConsistency.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ public void run() {
6565
List<BibEntry> entries = databaseContext.getDatabase().getEntries();
6666

6767
BibliographyConsistencyCheck consistencyCheck = new BibliographyConsistencyCheck();
68-
BibliographyConsistencyCheck.Result result = consistencyCheck.check(entries);
68+
BibliographyConsistencyCheck.Result result = consistencyCheck.check(entries, (count, total) -> {
69+
System.out.println(Localization.lang("Checking consistency for entry type %0 of %1", count + 1, total));
70+
});
6971

7072
Writer writer = new OutputStreamWriter(System.out);
7173
BibliographyConsistencyCheckResultWriter checkResultWriter;

jabkit/src/test/java/org/jabref/cli/ArgumentProcessorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ void checkConsistencyPorcelain() throws URISyntaxException {
165165
commandLine.execute(args.toArray(String[]::new));
166166

167167
String output = outContent.toString();
168-
assertEquals("", output);
168+
assertEquals("Checking consistency for entry type 1 of 1\n", output);
169169

170170
System.setOut(System.out);
171171
}

jablib/src/main/java/org/jabref/logic/quality/consistency/BibliographyConsistencyCheck.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.util.Map;
99
import java.util.SequencedCollection;
1010
import java.util.Set;
11+
import java.util.function.BiConsumer;
1112

1213
import org.jabref.logic.bibtex.comparator.BibEntryByCitationKeyComparator;
1314
import org.jabref.logic.bibtex.comparator.BibEntryByFieldsComparator;
@@ -35,7 +36,7 @@ public record EntryTypeResult(Collection<Field> fields, SequencedCollection<BibE
3536
*
3637
* @implNote This class does not implement {@link org.jabref.logic.integrity.DatabaseChecker}, because it returns a list of {@link org.jabref.logic.integrity.IntegrityMessage}, which are too fine-grained.
3738
*/
38-
public Result check(List<BibEntry> entries) {
39+
public Result check(List<BibEntry> entries, BiConsumer<Integer, Integer> entriesGroupingProgress) {
3940
// collects fields existing in any entry, scoped by entry type
4041
Map<EntryType, Set<Field>> entryTypeToFieldsInAnyEntryMap = new HashMap<>();
4142
// collects fields existing in all entries, scoped by entry type
@@ -47,14 +48,18 @@ public Result check(List<BibEntry> entries) {
4748

4849
Map<EntryType, EntryTypeResult> resultMap = new HashMap<>();
4950

50-
entryTypeToFieldsInAnyEntryMap.forEach((entryType, fields) -> {
51+
int counter = 0;
52+
for (Map.Entry<EntryType, Set<Field>> mapEntry : entryTypeToFieldsInAnyEntryMap.entrySet()) {
53+
entriesGroupingProgress.accept(counter++, entryTypeToFieldsInAnyEntryMap.size());
54+
EntryType entryType = mapEntry.getKey();
55+
Set<Field> fields = mapEntry.getValue();
5156
Set<Field> commonFields = entryTypeToFieldsInAllEntriesMap.get(entryType);
5257
assert commonFields != null;
5358
Set<Field> uniqueFields = new HashSet<>(fields);
5459
uniqueFields.removeAll(commonFields);
5560

5661
if (uniqueFields.isEmpty()) {
57-
return;
62+
continue;
5863
}
5964

6065
List<Comparator<BibEntry>> comparators = List.of(
@@ -69,13 +74,13 @@ public Result check(List<BibEntry> entries) {
6974
.toList();
7075

7176
resultMap.put(entryType, new EntryTypeResult(uniqueFields, differingEntries));
72-
});
77+
}
7378

7479
return new Result(resultMap);
7580
}
7681

7782
private static void collectEntriesIntoMaps(List<BibEntry> entries, Map<EntryType, Set<Field>> entryTypeToFieldsInAnyEntryMap, Map<EntryType, Set<Field>> entryTypeToFieldsInAllEntriesMap, Map<EntryType, Set<BibEntry>> entryTypeToEntriesMap) {
78-
entries.forEach(entry -> {
83+
for (BibEntry entry : entries) {
7984
EntryType entryType = entry.getType();
8085

8186
Set<Field> fieldsInAnyEntry = entryTypeToFieldsInAnyEntryMap.computeIfAbsent(entryType, k -> new HashSet<>());
@@ -86,6 +91,6 @@ private static void collectEntriesIntoMaps(List<BibEntry> entries, Map<EntryType
8691

8792
Set<BibEntry> entriesOfType = entryTypeToEntriesMap.computeIfAbsent(entryType, k -> new HashSet<>());
8893
entriesOfType.add(entry);
89-
});
94+
}
9095
}
9196
}

jablib/src/main/resources/l10n/JabRef_en.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,8 +1022,12 @@ field\ is\ absent=field is absent
10221022

10231023
Consistency\ check\ completed=Consistency check completed
10241024

1025+
%0/%1\ entry\ types=%0/%1 entry types
1026+
Checking\ consistency\ for\ entry\ type\ %0\ of\ %1=Checking consistency for entry type %0 of %1
1027+
10251028
Check\ consistency=Check consistency
10261029
Consistency\ check\ failed.=Consistency check failed.
1030+
Checking\ consistency...=Checking consistency...
10271031

10281032
Meaning=Meaning
10291033
Symbol=Symbol

jablib/src/test/java/org/jabref/logic/quality/consistency/BibliographyConsistencyCheckResultCsvWriterTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
class BibliographyConsistencyCheckResultCsvWriterTest {
2828

29-
private BibtexImporter importer = new BibtexImporter(mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS), new DummyFileUpdateMonitor());
29+
private final BibtexImporter importer = new BibtexImporter(mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS), new DummyFileUpdateMonitor());
3030

3131
@Test
3232
void checkSimpleLibrary(@TempDir Path tempDir) throws IOException {
@@ -36,7 +36,7 @@ void checkSimpleLibrary(@TempDir Path tempDir) throws IOException {
3636
BibEntry second = new BibEntry(StandardEntryType.Article, "second")
3737
.withField(StandardField.AUTHOR, "Author One")
3838
.withField(StandardField.PUBLISHER, "publisher");
39-
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second));
39+
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second), (_, _) -> { });
4040

4141
Path csvFile = tempDir.resolve("checkSimpleLibrary-result.csv");
4242
try (Writer writer = new OutputStreamWriter(Files.newOutputStream(csvFile));
@@ -60,7 +60,7 @@ void checkDifferentOutputSymbols(@TempDir Path tempDir) throws IOException {
6060
.withField(customField, "custom"); // unknown
6161
BibEntry second = new BibEntry(StandardEntryType.Article, "second")
6262
.withField(StandardField.AUTHOR, "Author One");
63-
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second));
63+
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second), (_, _) -> { });
6464

6565
Path csvFile = tempDir.resolve("checkDifferentOutputSymbols-result.csv");
6666
try (Writer writer = new OutputStreamWriter(Files.newOutputStream(csvFile));
@@ -95,7 +95,7 @@ void checkComplexLibrary(@TempDir Path tempDir) throws IOException {
9595
.withField(StandardField.AUTHOR, "Author One")
9696
.withField(StandardField.YEAR, "2024");
9797

98-
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second, third, fourth, fifth));
98+
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second, third, fourth, fifth), (_, _) -> { });
9999

100100
Path csvFile = tempDir.resolve("checkSimpleLibrary-result.csv");
101101
try (Writer writer = new OutputStreamWriter(Files.newOutputStream(csvFile));
@@ -119,7 +119,7 @@ void checkLibraryWithoutIssues(@TempDir Path tempDir) throws IOException {
119119
BibEntry second = new BibEntry(StandardEntryType.Article, "second")
120120
.withField(StandardField.AUTHOR, "Author One")
121121
.withField(StandardField.PAGES, "some pages");
122-
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second));
122+
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second), (_, _) -> { });
123123

124124
Path csvFile = tempDir.resolve("checkLibraryWithoutIssues-result.csv");
125125
try (Writer writer = new OutputStreamWriter(Files.newOutputStream(csvFile));
@@ -137,7 +137,7 @@ void checkManualInput() throws IOException {
137137
Path file = Path.of("C:\\TEMP\\JabRef\\biblio-anon.bib");
138138
Path csvFile = file.resolveSibling("biblio-cited.csv");
139139
BibDatabaseContext databaseContext = importer.importDatabase(file).getDatabaseContext();
140-
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(databaseContext.getEntries());
140+
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(databaseContext.getEntries(), (_, _) -> { });
141141
try (Writer writer = new OutputStreamWriter(Files.newOutputStream(csvFile));
142142
BibliographyConsistencyCheckResultCsvWriter paperConsistencyCheckResultCsvWriter = new BibliographyConsistencyCheckResultCsvWriter(result, writer, true)) {
143143
paperConsistencyCheckResultCsvWriter.writeFindings();

jablib/src/test/java/org/jabref/logic/quality/consistency/BibliographyConsistencyCheckResultTxtWriterTest.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import static org.mockito.Mockito.mock;
2626

2727
class BibliographyConsistencyCheckResultTxtWriterTest {
28-
private BibtexImporter importer = new BibtexImporter(mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS), new DummyFileUpdateMonitor());
28+
private final BibtexImporter importer = new BibtexImporter(mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS), new DummyFileUpdateMonitor());
2929

3030
@Test
3131
void checkSimpleLibrary(@TempDir Path tempDir) throws IOException {
@@ -35,7 +35,7 @@ void checkSimpleLibrary(@TempDir Path tempDir) throws IOException {
3535
BibEntry second = new BibEntry(StandardEntryType.Article, "second")
3636
.withField(StandardField.AUTHOR, "Author One")
3737
.withField(StandardField.PUBLISHER, "publisher");
38-
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second));
38+
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second), (_, _) -> { });
3939

4040
Path txtFile = tempDir.resolve("checkSimpleLibrary-result.txt");
4141
try (Writer writer = new OutputStreamWriter(Files.newOutputStream(txtFile));
@@ -69,7 +69,7 @@ void checkDifferentOutputSymbols(@TempDir Path tempDir) throws IOException {
6969
.withField(customField, "custom"); // unknown
7070
BibEntry second = new BibEntry(StandardEntryType.Article, "second")
7171
.withField(StandardField.AUTHOR, "Author One");
72-
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second));
72+
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second), (_, _) -> { });
7373

7474
Path txtFile = tempDir.resolve("checkDifferentOutputSymbols-result.txt");
7575
try (Writer writer = new OutputStreamWriter(Files.newOutputStream(txtFile));
@@ -102,7 +102,7 @@ void checkVeryLongCitationKey(@TempDir Path tempDir) throws IOException {
102102
.withField(customField, "custom"); // unknown
103103
BibEntry second = new BibEntry(StandardEntryType.Article, "second")
104104
.withField(StandardField.AUTHOR, "Author One");
105-
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second));
105+
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second), (_, _) -> { });
106106

107107
Path txtFile = tempDir.resolve("checkDifferentOutputSymbols-result.txt");
108108
try (Writer writer = new OutputStreamWriter(Files.newOutputStream(txtFile));
@@ -152,7 +152,7 @@ void checkComplexLibrary(@TempDir Path tempDir) throws IOException {
152152
.withField(StandardField.AUTHOR, "Author One")
153153
.withField(StandardField.YEAR, "2024");
154154

155-
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second, third, fourth, fifth, sixth));
155+
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second, third, fourth, fifth, sixth), (_, _) -> { });
156156

157157
Path txtFile = tempDir.resolve("checkSimpleLibrary-result.txt");
158158
try (Writer writer = new OutputStreamWriter(Files.newOutputStream(txtFile));
@@ -187,7 +187,7 @@ void checkLibraryWithoutIssuesWithOutPorcelain(@TempDir Path tempDir) throws IOE
187187
BibEntry second = new BibEntry(StandardEntryType.Article, "second")
188188
.withField(StandardField.AUTHOR, "Author One")
189189
.withField(StandardField.PAGES, "some pages");
190-
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second));
190+
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second), (_, _) -> { });
191191

192192
Path txtFile = tempDir.resolve("checkLibraryWithoutIssues-result.txt");
193193
try (Writer writer = new OutputStreamWriter(Files.newOutputStream(txtFile));
@@ -209,7 +209,7 @@ void checkLibraryWithoutIssuesWithPorcelain(@TempDir Path tempDir) throws IOExce
209209
BibEntry second = new BibEntry(StandardEntryType.Article, "second")
210210
.withField(StandardField.AUTHOR, "Author One")
211211
.withField(StandardField.PAGES, "some pages");
212-
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second));
212+
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(List.of(first, second), (_, _) -> { });
213213

214214
Path txtFile = tempDir.resolve("checkLibraryWithoutIssues-result.txt");
215215
try (Writer writer = new OutputStreamWriter(Files.newOutputStream(txtFile));
@@ -225,7 +225,7 @@ void checkManualInput() throws IOException {
225225
Path file = Path.of("C:\\TEMP\\JabRef\\biblio-anon.bib");
226226
Path txtFile = file.resolveSibling("biblio-cited.txt");
227227
BibDatabaseContext databaseContext = importer.importDatabase(file).getDatabaseContext();
228-
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(databaseContext.getEntries());
228+
BibliographyConsistencyCheck.Result result = new BibliographyConsistencyCheck().check(databaseContext.getEntries(), (_, _) -> { });
229229
try (Writer writer = new OutputStreamWriter(Files.newOutputStream(txtFile));
230230
BibliographyConsistencyCheckResultTxtWriter BibliographyConsistencyCheckResultTxtWriter = new BibliographyConsistencyCheckResultTxtWriter(result, writer, true)) {
231231
BibliographyConsistencyCheckResultTxtWriter.writeFindings();

0 commit comments

Comments
 (0)