From a79442f46f1f25eca9cdc8dbb706d658a41fabb7 Mon Sep 17 00:00:00 2001 From: Andrei Bastun Date: Mon, 9 Sep 2024 20:34:06 +0200 Subject: [PATCH] CXF-9054 do not use Date and SimpleDateFormat when parsing LocalDate, use the appropriate DateTimeFormatter --- .../ext/search/AbstractSearchConditionParser.java | 2 +- .../org/apache/cxf/jaxrs/ext/search/SearchUtils.java | 8 ++++++++ .../cxf/jaxrs/ext/search/fiql/FiqlParserTest.java | 10 ++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractSearchConditionParser.java b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractSearchConditionParser.java index ca531c9818b..defd06bb8a6 100644 --- a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractSearchConditionParser.java +++ b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractSearchConditionParser.java @@ -343,7 +343,7 @@ private Temporal convertToTemporal(Class valueType, String v if (LocalTime.class.isAssignableFrom(valueType)) { return LocalTime.parse(value); } else if (LocalDate.class.isAssignableFrom(valueType)) { - return LocalDate.from(convertToDefaultDate(value).toInstant().atZone(ZoneId.systemDefault())); + return LocalDate.parse(value, SearchUtils.getLocalDateFormat(contextProperties)); } else if (LocalDateTime.class.isAssignableFrom(valueType)) { return convertTo(value, SearchUtils.DEFAULT_DATETIME_FORMAT, Boolean.FALSE, LocalDateTime::parse); } else if (OffsetTime.class.isAssignableFrom(valueType)) { diff --git a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java index 2110ab11a97..c2a6cda13c2 100644 --- a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java +++ b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java @@ -20,9 +20,11 @@ import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; @@ -47,6 +49,7 @@ public final class SearchUtils { public static final String SEARCH_VISITOR_PROPERTY = "search.visitor"; public static final String DECODE_QUERY_VALUES = "search.decode.values"; public static final String ESCAPE_UNDERSCORE_CHAR = "search.escape.underscore.char"; + private static final Map FORMATTER_CACHE = new ConcurrentHashMap<>(); private static final Logger LOG = LogUtils.getL7dLogger(SearchUtils.class); @@ -88,6 +91,11 @@ public static Date dateFromStringWithContextProperties(String value) { return dateFromStringWithDefaultFormats(value); } + public static DateTimeFormatter getLocalDateFormat(Map properties) { + String format = properties.getOrDefault(DATE_FORMAT_PROPERTY, DEFAULT_DATE_FORMAT); + return FORMATTER_CACHE.computeIfAbsent(format, DateTimeFormatter::ofPattern); + } + public static SimpleDateFormat getDateFormatOrDefault(Map properties, String pattern) { return getDateFormatOrDefault(properties.get(DATE_FORMAT_PROPERTY), pattern); } diff --git a/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParserTest.java b/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParserTest.java index 7778b48897b..ec80f00f35a 100644 --- a/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParserTest.java +++ b/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParserTest.java @@ -224,6 +224,16 @@ public void testParseLocalDateWithDefaultFormat() throws SearchParseException, P assertFalse(filter.isMet(new Condition(null, 123, null, LocalDate.parse("2010-03-12", df)))); } + @Test + public void testParseOldLocalDateWithDefaultFormat() throws SearchParseException { + DateTimeFormatter df = DateTimeFormatter.ofPattern(SearchUtils.DEFAULT_DATE_FORMAT); + SearchCondition filter = parser.parse("localDate==1893-04-02"); + assertTrue(filter.isMet(new Condition("whatever", 15, null, LocalDate.parse("1893-04-02", df)))); + + filter = parser.parse("localDate==1893-04-01"); + assertTrue(filter.isMet(new Condition("whatever", 15, null, LocalDate.parse("1893-04-01", df)))); + } + @Test public void testParseInstantWithDefaultFormat() throws SearchParseException, ParseException { SearchCondition filter = parser.parse("instant=le=2010-03-11");