From bd8f8c3f2274c54d25568e906ab2dd0dbb87f076 Mon Sep 17 00:00:00 2001 From: Xianghao Wang Date: Wed, 26 Oct 2022 20:55:57 +1100 Subject: [PATCH 1/9] Update TemporalAccessorPicker.java: return null if the date is not in format --- .../org/jabref/gui/util/component/TemporalAccessorPicker.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java b/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java index f2aecc17947..4d59e81b389 100644 --- a/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java +++ b/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java @@ -76,6 +76,7 @@ private static LocalDate getDate(TemporalAccessor temporalAccessor) { private static LocalDate getLocalDate(TemporalAccessor dateTime) { // Try to get as much information from the temporal accessor + if (dateTime == null) return null; LocalDate date = dateTime.query(TemporalQueries.localDate()); if (date != null) { return date; @@ -139,7 +140,7 @@ public LocalDate fromString(String value) { TemporalAccessor dateTime = getStringConverter().fromString(value); temporalAccessorValue.set(dateTime); - return getLocalDate(dateTime); + return dateTime == null ? null : getLocalDate(dateTime); } } } From 51c60b9803f6f27c2f411d22a1ea670c4d9d6667 Mon Sep 17 00:00:00 2001 From: Xianghao Wang Date: Thu, 27 Oct 2022 00:38:41 +1100 Subject: [PATCH 2/9] Revert "Update TemporalAccessorPicker.java: return null if the date is not in format" This reverts commit bd8f8c3f2274c54d25568e906ab2dd0dbb87f076. --- .../org/jabref/gui/util/component/TemporalAccessorPicker.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java b/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java index 4d59e81b389..f2aecc17947 100644 --- a/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java +++ b/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java @@ -76,7 +76,6 @@ private static LocalDate getDate(TemporalAccessor temporalAccessor) { private static LocalDate getLocalDate(TemporalAccessor dateTime) { // Try to get as much information from the temporal accessor - if (dateTime == null) return null; LocalDate date = dateTime.query(TemporalQueries.localDate()); if (date != null) { return date; @@ -140,7 +139,7 @@ public LocalDate fromString(String value) { TemporalAccessor dateTime = getStringConverter().fromString(value); temporalAccessorValue.set(dateTime); - return dateTime == null ? null : getLocalDate(dateTime); + return getLocalDate(dateTime); } } } From a0353c146d4f4cf419711ebd1e88f420e1441462 Mon Sep 17 00:00:00 2001 From: Xianghao Wang Date: Thu, 27 Oct 2022 03:29:24 +1100 Subject: [PATCH 3/9] Added preferences to DateEditor for enabling validator and added preferences to the calling of DataEditor in FieldEditors --- src/main/java/org/jabref/gui/fieldeditors/DateEditor.java | 5 ++++- src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/gui/fieldeditors/DateEditor.java b/src/main/java/org/jabref/gui/fieldeditors/DateEditor.java index cd8ad8785ca..b57eab4e6a6 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/DateEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/DateEditor.java @@ -13,13 +13,14 @@ import org.jabref.model.entry.field.Field; import com.airhacks.afterburner.views.ViewLoader; +import org.jabref.preferences.PreferencesService; public class DateEditor extends HBox implements FieldEditorFX { @FXML private DateEditorViewModel viewModel; @FXML private TemporalAccessorPicker datePicker; - public DateEditor(Field field, DateTimeFormatter dateFormatter, SuggestionProvider suggestionProvider, FieldCheckers fieldCheckers) { + public DateEditor(Field field, DateTimeFormatter dateFormatter, SuggestionProvider suggestionProvider, FieldCheckers fieldCheckers, PreferencesService preferences) { this.viewModel = new DateEditorViewModel(field, suggestionProvider, dateFormatter, fieldCheckers); ViewLoader.view(this) @@ -28,6 +29,8 @@ public DateEditor(Field field, DateTimeFormatter dateFormatter, SuggestionProvid datePicker.setStringConverter(viewModel.getDateToStringConverter()); datePicker.getEditor().textProperty().bindBidirectional(viewModel.textProperty()); + + new EditorValidator(preferences).configureValidation(viewModel.getFieldValidator().getValidationStatus(), datePicker.getEditor()); } public DateEditorViewModel getViewModel() { diff --git a/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java b/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java index e038c6ba05f..6db3dac9412 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java +++ b/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java @@ -55,9 +55,9 @@ public static FieldEditorFX getForField(final Field field, boolean isMultiLine = FieldFactory.isMultiLineField(field, preferences.getFieldContentParserPreferences().getNonWrappableFields()); if (preferences.getTimestampPreferences().getTimestampField().equals(field)) { - return new DateEditor(field, DateTimeFormatter.ofPattern(preferences.getTimestampPreferences().getTimestampFormat()), suggestionProvider, fieldCheckers); + return new DateEditor(field, DateTimeFormatter.ofPattern(preferences.getTimestampPreferences().getTimestampFormat()), suggestionProvider, fieldCheckers, preferences); } else if (fieldProperties.contains(FieldProperty.DATE)) { - return new DateEditor(field, DateTimeFormatter.ofPattern("[uuuu][-MM][-dd]"), suggestionProvider, fieldCheckers); + return new DateEditor(field, DateTimeFormatter.ofPattern("[uuuu][-MM][-dd]"), suggestionProvider, fieldCheckers, preferences); } else if (fieldProperties.contains(FieldProperty.EXTERNAL)) { return new UrlEditor(field, dialogService, suggestionProvider, fieldCheckers, preferences); } else if (fieldProperties.contains(FieldProperty.JOURNAL_NAME)) { From 087ccbccf47625bb3b1dc1bbba90915c6a7fdcff Mon Sep 17 00:00:00 2001 From: Xianghao Wang Date: Thu, 27 Oct 2022 03:46:29 +1100 Subject: [PATCH 4/9] Hold content if date is invalid --- .../gui/util/component/TemporalAccessorPicker.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java b/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java index f2aecc17947..5bb4c245309 100644 --- a/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java +++ b/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java @@ -75,6 +75,11 @@ private static LocalDate getDate(TemporalAccessor temporalAccessor) { } private static LocalDate getLocalDate(TemporalAccessor dateTime) { + // Return null when dateTime is null pointer + if (dateTime == null) { + return null; + } + // Try to get as much information from the temporal accessor LocalDate date = dateTime.query(TemporalQueries.localDate()); if (date != null) { @@ -127,7 +132,7 @@ private class InternalConverter extends StringConverter { @Override public String toString(LocalDate object) { TemporalAccessor value = getTemporalAccessorValue(); - return (value != null) ? getStringConverter().toString(value) : ""; + return (value != null) ? getStringConverter().toString(value) : getEditor().getText(); } @Override @@ -139,7 +144,7 @@ public LocalDate fromString(String value) { TemporalAccessor dateTime = getStringConverter().fromString(value); temporalAccessorValue.set(dateTime); - return getLocalDate(dateTime); + return (dateTime != null) ? getLocalDate(dateTime) : null; } } } From 8bf5ba0e953475c5f9f0896d322f084d6616a999 Mon Sep 17 00:00:00 2001 From: Xianghao Wang Date: Thu, 27 Oct 2022 16:27:29 +1100 Subject: [PATCH 5/9] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab7b83bcc57..eccfa09f720 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,6 +74,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We fixed an issue where hitting enter on the search field within the preferences dialog closed the dialog. [koppor#630](https://github.com/koppor/jabref/issues/630) - We fixed a typo within a connection error message. [koppor#625](https://github.com/koppor/jabref/issues/625) - We fixed an issue where the 'close dialog' key binding was not closing the Preferences dialog. [#8888](https://github.com/jabref/jabref/issues/8888) +- We fixed an issue where editing entry's "date" field in library mode "biblatex" causes an uncaught exception. [#8747][https://github.com/JabRef/jabref/issues/8747] ### Removed From 4df4077657d4bc40a0a4dd3db32153cb90b1d961 Mon Sep 17 00:00:00 2001 From: Xianghao Wang Date: Thu, 27 Oct 2022 16:41:01 +1100 Subject: [PATCH 6/9] Add comments to TemporalAccessorPicker.java --- .../jabref/gui/util/component/TemporalAccessorPicker.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java b/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java index 5bb4c245309..8274b84a4d0 100644 --- a/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java +++ b/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java @@ -132,6 +132,8 @@ private class InternalConverter extends StringConverter { @Override public String toString(LocalDate object) { TemporalAccessor value = getTemporalAccessorValue(); + + // Keeps the original text when it is an invalid date return (value != null) ? getStringConverter().toString(value) : getEditor().getText(); } @@ -144,7 +146,8 @@ public LocalDate fromString(String value) { TemporalAccessor dateTime = getStringConverter().fromString(value); temporalAccessorValue.set(dateTime); - return (dateTime != null) ? getLocalDate(dateTime) : null; + + return getLocalDate(dateTime); } } } From 998d435a81264d2b7f84494e8609342154cdf78d Mon Sep 17 00:00:00 2001 From: Xianghao Wang Date: Sat, 29 Oct 2022 16:39:19 +1100 Subject: [PATCH 7/9] Integrate JabRef's Date to the defaultl string converter of TemporalAccessorPicker --- .../gui/util/component/TemporalAccessorPicker.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java b/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java index 8274b84a4d0..6c39e4f3015 100644 --- a/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java +++ b/src/main/java/org/jabref/gui/util/component/TemporalAccessorPicker.java @@ -7,6 +7,7 @@ import java.time.Year; import java.time.YearMonth; import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalQueries; import java.util.Objects; @@ -21,6 +22,8 @@ import org.jabref.gui.fieldeditors.TextInputControlBehavior; import org.jabref.gui.fieldeditors.contextmenu.EditorContextAction; import org.jabref.gui.util.BindingsHelper; +import org.jabref.model.entry.Date; +import org.jabref.model.strings.StringUtil; /** * A date picker with configurable datetime format where both date and time can be changed via the text field and the @@ -106,7 +109,16 @@ public String toString(TemporalAccessor value) { @Override public TemporalAccessor fromString(String value) { - return LocalDateTime.parse(value, defaultFormatter); + if (StringUtil.isNotBlank(value)) { + try { + return defaultFormatter.parse(value); + } catch ( + DateTimeParseException exception) { + return Date.parse(value).map(Date::toTemporalAccessor).orElse(null); + } + } else { + return null; + } } }; return Objects.requireNonNullElseGet(stringConverterProperty().get(), () -> newConverter); From b59a325a4c218b89e0a9d588a9836fd2f1e8e3f3 Mon Sep 17 00:00:00 2001 From: Xianghao Wang Date: Sat, 29 Oct 2022 16:49:12 +1100 Subject: [PATCH 8/9] Make Exception handles more --- .../java/org/jabref/gui/fieldeditors/DateEditorViewModel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/fieldeditors/DateEditorViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/DateEditorViewModel.java index de7bdeb7583..784abc2d6ad 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/DateEditorViewModel.java +++ b/src/main/java/org/jabref/gui/fieldeditors/DateEditorViewModel.java @@ -36,7 +36,7 @@ public TemporalAccessor fromString(String string) { if (StringUtil.isNotBlank(string)) { try { return dateFormatter.parse(string); - } catch (DateTimeParseException exception) { + } catch (Exception exception) { // We accept all kinds of dates (not just in the format specified) return Date.parse(string).map(Date::toTemporalAccessor).orElse(null); } From b9babecaeb2a9b7cb0d2ffd3a3cf57c03a91146f Mon Sep 17 00:00:00 2001 From: Xianghao Wang Date: Sun, 30 Oct 2022 20:55:55 +1100 Subject: [PATCH 9/9] Fix style --- src/main/java/org/jabref/gui/fieldeditors/DateEditor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/fieldeditors/DateEditor.java b/src/main/java/org/jabref/gui/fieldeditors/DateEditor.java index b57eab4e6a6..8c25cdc1a97 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/DateEditor.java +++ b/src/main/java/org/jabref/gui/fieldeditors/DateEditor.java @@ -11,9 +11,9 @@ import org.jabref.logic.integrity.FieldCheckers; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.field.Field; +import org.jabref.preferences.PreferencesService; import com.airhacks.afterburner.views.ViewLoader; -import org.jabref.preferences.PreferencesService; public class DateEditor extends HBox implements FieldEditorFX {