Skip to content

Commit 577bbb6

Browse files
HoussemNasriHoussem Nasrisubhramitkoppor
authored
Fix NoSuchElementException in ThreeWayMerge dialog (#13838)
* Fix NoSuchElementException in ThreeWayMerge dialog * Add changelog * Reset static fields visibility to private in YearChecker * Fix typo * Update CHANGELOG.md Co-authored-by: Subhramit Basu <[email protected]> * Use primitive type * rewriteRun --------- Co-authored-by: Houssem Nasri <[email protected]> Co-authored-by: Subhramit Basu <[email protected]> Co-authored-by: Oliver Kopp <[email protected]>
1 parent 015370b commit 577bbb6

File tree

4 files changed

+64
-20
lines changed

4 files changed

+64
-20
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
126126
- We fixed an issue where "Copy to" was enabled even if no other library was opened. [#13280](https://github.com/JabRef/jabref/pull/13280)
127127
- We fixed an issue where the groups were still displayed after closing all libraries. [#13382](https://github.com/JabRef/jabref/issues/13382)
128128
- Enhanced field selection logic in the Merge Entries dialog when fetching from DOI to prefer valid years and entry types. [#12549](https://github.com/JabRef/jabref/issues/12549)
129+
- We fixed an issue where opening the Three Way Merge dialog would throw an exception when year field contains an invalid year value. [#13673](https://github.com/JabRef/jabref/issues/13673)
129130
- We improved consistency in the Add Buttons. [#13791](https://github.com/JabRef/jabref/pull/13791)
130131
- We fixed an issue where theme or font size are not respected for all dialogs [#13558](https://github.com/JabRef/jabref/issues/13558)
131132
- We removed unnecessary spacing and margin in the AutomaticFieldEditor. [#13792](https://github.com/JabRef/jabref/pull/13792)

jabgui/src/test/java/org/jabref/gui/mergeentries/FieldRowViewModelTest.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,14 +224,23 @@ void newYearShouldBeSelectedForYearsWithLargeValueGap() {
224224
}
225225

226226
@Test
227-
void yearInRangeShouldBeSelected() {
227+
void selectRightYearWhenInRange() {
228228
BibEntry leftEntry = new BibEntry().withField(StandardField.YEAR, "1700");
229229
BibEntry rightEntry = new BibEntry().withField(StandardField.YEAR, "2000");
230230
FieldRowViewModel yearField = new FieldRowViewModel(StandardField.YEAR, leftEntry, rightEntry, mergedEntry, fieldMergerFactory);
231231
yearField.autoSelectBetterValue();
232232
assertEquals(FieldRowViewModel.Selection.RIGHT, yearField.getSelection());
233233
}
234234

235+
@Test
236+
void selectLeftYearWhenInRange() {
237+
BibEntry leftEntry = new BibEntry().withField(StandardField.YEAR, "2005");
238+
BibEntry rightEntry = new BibEntry().withField(StandardField.YEAR, "1700");
239+
FieldRowViewModel yearField = new FieldRowViewModel(StandardField.YEAR, leftEntry, rightEntry, mergedEntry, fieldMergerFactory);
240+
yearField.autoSelectBetterValue();
241+
assertEquals(FieldRowViewModel.Selection.LEFT, yearField.getSelection());
242+
}
243+
235244
public FieldRowViewModel createViewModelForField(Field field) {
236245
return new FieldRowViewModel(field, leftEntry, rightEntry, mergedEntry, fieldMergerFactory);
237246
}

jablib/src/main/java/org/jabref/logic/bibtex/comparator/YearFieldValuePlausibilityComparator.java

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.util.regex.Pattern;
77

88
import org.jabref.logic.integrity.YearChecker;
9+
import org.jabref.model.strings.StringUtil;
910

1011
public class YearFieldValuePlausibilityComparator extends FieldValuePlausibilityComparator {
1112

@@ -21,28 +22,50 @@ public class YearFieldValuePlausibilityComparator extends FieldValuePlausibility
2122

2223
@Override
2324
public ComparisonResult compare(String leftValue, String rightValue) {
24-
YearChecker checker = new YearChecker();
25+
boolean isLeftBlank = StringUtil.isBlank(leftValue);
26+
boolean isRightBlank = StringUtil.isBlank(rightValue);
27+
if (isLeftBlank && !isRightBlank) {
28+
return ComparisonResult.RIGHT_BETTER;
29+
} else if (isRightBlank && !isLeftBlank) {
30+
return ComparisonResult.LEFT_BETTER;
31+
} else if (isLeftBlank && isRightBlank) {
32+
return ComparisonResult.UNDETERMINED;
33+
}
2534

26-
boolean leftValid = checker.checkValue(leftValue).isEmpty();
35+
// left and right values are not blank.
2736

28-
if (leftValid) {
29-
Optional<Integer> leftYear = extractYear(leftValue);
30-
Optional<Integer> rightYear = extractYear(rightValue);
37+
boolean leftValueCorrectlyFormatted = YearChecker.isValueCorrectlyFormatted(leftValue);
38+
boolean rightValueCorrectlyFormatted = YearChecker.isValueCorrectlyFormatted(rightValue);
39+
if (leftValueCorrectlyFormatted && !rightValueCorrectlyFormatted) {
40+
return ComparisonResult.LEFT_BETTER;
41+
} else if (rightValueCorrectlyFormatted && !leftValueCorrectlyFormatted) {
42+
return ComparisonResult.RIGHT_BETTER;
43+
} else if (!leftValueCorrectlyFormatted && !rightValueCorrectlyFormatted) {
44+
return ComparisonResult.UNDETERMINED;
45+
}
3146

32-
boolean leftYearInRange = (leftYear.get() >= 1800) && (leftYear.get() <= Year.now().getValue() + 2);
47+
// left and right values are correctly formatted.
3348

34-
if (leftYearInRange) {
35-
int diff = Math.abs(leftYear.get() - rightYear.get());
36-
if (diff > 10) {
37-
return rightYear.get() > leftYear.get()
38-
? ComparisonResult.RIGHT_BETTER
39-
: ComparisonResult.LEFT_BETTER;
40-
}
41-
return ComparisonResult.UNDETERMINED; // years are close, undetermined
42-
}
49+
int leftYear = extractYear(leftValue).get();
50+
int rightYear = extractYear(rightValue).get();
51+
boolean leftYearInRange = (leftYear >= 1800) && (leftYear <= Year.now().getValue() + 2);
52+
boolean rightYearInRange = (rightYear >= 1800) && (rightYear <= Year.now().getValue() + 2);
53+
if (leftYearInRange && !rightYearInRange) {
54+
return ComparisonResult.LEFT_BETTER;
55+
} else if (rightYearInRange && !leftYearInRange) {
4356
return ComparisonResult.RIGHT_BETTER;
44-
}
45-
return ComparisonResult.RIGHT_BETTER;
57+
} else if (!leftYearInRange && !rightYearInRange) {
58+
return ComparisonResult.UNDETERMINED;
59+
}
60+
61+
int diff = Math.abs(leftYear - rightYear);
62+
if (diff > 10) {
63+
return rightYear > leftYear
64+
? ComparisonResult.RIGHT_BETTER
65+
: ComparisonResult.LEFT_BETTER;
66+
}
67+
68+
return ComparisonResult.UNDETERMINED; // years are close, undetermined
4669
}
4770

4871
/**

jablib/src/main/java/org/jabref/logic/integrity/YearChecker.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99

1010
public class YearChecker implements ValueChecker {
1111

12-
private static final Predicate<String> CONTAINS_FOUR_DIGIT = Pattern.compile("([^0-9]|^)[0-9]{4}([^0-9]|$)")
13-
.asPredicate();
12+
private static final Predicate<String> CONTAINS_FOUR_DIGIT = Pattern.compile("([^0-9]|^)[0-9]{4}([^0-9]|$)").asPredicate();
1413
private static final Predicate<String> ENDS_WITH_FOUR_DIGIT = Pattern.compile("[0-9]{4}$").asPredicate();
1514
private static final String PUNCTUATION_MARKS = "[(){},.;!?<>%&$]";
1615

@@ -37,4 +36,16 @@ public Optional<String> checkValue(String value) {
3736

3837
return Optional.empty();
3938
}
39+
40+
public static boolean isValueCorrectlyFormatted(String value) {
41+
if (StringUtil.isBlank(value)) {
42+
return false;
43+
}
44+
45+
if (!CONTAINS_FOUR_DIGIT.test(value.trim())) {
46+
return false;
47+
}
48+
49+
return ENDS_WITH_FOUR_DIGIT.test(value.replaceAll(PUNCTUATION_MARKS, ""));
50+
}
4051
}

0 commit comments

Comments
 (0)