From 2dae7d8d8b925ea3f25e1d46e83c41a1be59204f Mon Sep 17 00:00:00 2001 From: "Bartenstein, Eran [AU-AU]" Date: Tue, 16 Dec 2025 15:34:10 +1100 Subject: [PATCH 1/2] Fix broken tests that does not take daylight saving correctly in SimpleDateFormat for years below 2020 by replacing it with java.time.format.DateTimeFormatter and initialize test data in a test setup method to make sure that there's no CPU ticks between dates initializations. --- .../common/source/CswCqlFilterTest.java | 30 ++++--- .../common/source/CswFilterDelegateTest.java | 45 ++++++---- .../catalog/source/WfsFilterDelegateTest.java | 90 +++++++++++-------- .../xml/XmlInputTransformerTest.java | 35 ++++++-- 4 files changed, 131 insertions(+), 69 deletions(-) diff --git a/catalog/spatial/csw/spatial-csw-source-common/src/test/java/org/codice/ddf/spatial/ogc/csw/catalog/common/source/CswCqlFilterTest.java b/catalog/spatial/csw/spatial-csw-source-common/src/test/java/org/codice/ddf/spatial/ogc/csw/catalog/common/source/CswCqlFilterTest.java index 999fef782064..6cf3cc5131cf 100644 --- a/catalog/spatial/csw/spatial-csw-source-common/src/test/java/org/codice/ddf/spatial/ogc/csw/catalog/common/source/CswCqlFilterTest.java +++ b/catalog/spatial/csw/spatial-csw-source-common/src/test/java/org/codice/ddf/spatial/ogc/csw/catalog/common/source/CswCqlFilterTest.java @@ -21,8 +21,8 @@ import ddf.catalog.data.Metacard; import ddf.catalog.data.types.Core; import ddf.catalog.source.UnsupportedQueryException; -import java.text.ParseException; -import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -129,7 +129,7 @@ public class CswCqlFilterTest { initDefaultCswFilterDelegate( initCswSourceConfiguration(CswAxisOrder.LON_LAT, CswConstants.CSW_TYPE)); - private final Date date = getDate(); + private Date date; private final String propertyName = DEFAULT_PROPERTY_NAME; @@ -231,7 +231,7 @@ public class CswCqlFilterTest { private final String propertyIsEqualToContentType = "type" + SPACE + EQUALS + SPACE + "'myType'"; - private final String propertyIsEqualToWithDate = getPropertyIsEqualToWithDate(getDate()); + private String propertyIsEqualToWithDate; private final String propertyIsEqualToWithBoolean = DEFAULT_PROPERTY_NAME + SPACE + EQUALS + SPACE + TRUE; @@ -616,6 +616,8 @@ private static Operation getOperation() { @Before public void setup() { + date = getDate(); + propertyIsEqualToWithDate = getPropertyIsEqualToWithDate(getDate()); Hints.putSystemDefault( Hints.CRS_AUTHORITY_FACTORY, "org.geotools.referencing.factory.epsg.hsql.ThreadedHsqlEpsgFactory"); @@ -1499,15 +1501,23 @@ public void testDisjointPropertyOwsBoundingBoxPolygon() throws UnsupportedQueryE } private Date getDate() { - String dateString = "Jun 11 2002"; - SimpleDateFormat formatter = new SimpleDateFormat("MMM d yyyy"); - Date aDate = null; + final String dateString = "Jun 11 2002"; + + // Define the formatter for the input pattern + java.time.format.DateTimeFormatter formatter = + java.time.format.DateTimeFormatter.ofPattern("MMM dd yyyy", java.util.Locale.ENGLISH); + + Date date = null; + // Parse the input date-time with MST, then convert to America/Denver to ensure that + // region-specific rules are applied correctly when parsing + LocalDate localDate; try { - aDate = formatter.parse(dateString); - } catch (ParseException e) { + localDate = LocalDate.parse(dateString, formatter); + date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + } catch (Exception e) { LOGGER.error(e.getMessage(), e); } - return aDate; + return date; } private String getPropertyIsEqualToWithDate(Date aDate) { diff --git a/catalog/spatial/csw/spatial-csw-source-common/src/test/java/org/codice/ddf/spatial/ogc/csw/catalog/common/source/CswFilterDelegateTest.java b/catalog/spatial/csw/spatial-csw-source-common/src/test/java/org/codice/ddf/spatial/ogc/csw/catalog/common/source/CswFilterDelegateTest.java index 195766bcfe0e..5073f296564f 100644 --- a/catalog/spatial/csw/spatial-csw-source-common/src/test/java/org/codice/ddf/spatial/ogc/csw/catalog/common/source/CswFilterDelegateTest.java +++ b/catalog/spatial/csw/spatial-csw-source-common/src/test/java/org/codice/ddf/spatial/ogc/csw/catalog/common/source/CswFilterDelegateTest.java @@ -46,12 +46,14 @@ import java.io.IOException; import java.io.StringWriter; import java.text.ParseException; -import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; @@ -140,7 +142,7 @@ public class CswFilterDelegateTest { private static final String DISTANCE_GEO_FILTER_PROP_MAP_KEY = "distance"; - private static final Date SAMPLE_NON_ISO_8601_DATE; + private static Date sampleNonIso8601Date; // NOTE: The contents of these maps ARE mutable private static final Map POS_LIST_GEO_FILTER_PROP_MAP = new HashMap<>(); @@ -167,15 +169,6 @@ public class CswFilterDelegateTest { private static Marshaller marshaller = null; - static { - try { - SAMPLE_NON_ISO_8601_DATE = new SimpleDateFormat("MMM d yyyy").parse("Jun 11 2003"); - } catch (ParseException pe) { - LOGGER.error("Unable to instantiate SAMPLE_NON_ISO_8601_DATE", pe); - throw new RuntimeException(); - } - } - private final CswFilterDelegate cswFilterDelegateLatLon = createCswFilterDelegate( initCswSourceConfiguration(CswAxisOrder.LAT_LON, false, CswConstants.CSW_TYPE)); @@ -309,7 +302,7 @@ public class CswFilterDelegateTest { createComparisonFilterString( ComparisonOperator.PROPERTY_IS_EQUAL_TO, DEFAULT_PROPERTY_NAME, - convertDateToIso8601Format(SAMPLE_NON_ISO_8601_DATE).toString()); + convertDateToIso8601Format(sampleNonIso8601Date).toString()); private final String propertyIsEqualToXmlWithBoolean = createComparisonFilterString( @@ -778,6 +771,27 @@ public static void setupTestClass() throws JAXBException, ParseException { map.put("ogc", "http://www.opengis.net/ogc"); NamespaceContext ctx = new SimpleNamespaceContext(map); XMLUnit.setXpathNamespaceContext(ctx); + + sampleNonIso8601Date = getNonIso8601Date(); + } + + private static Date getNonIso8601Date() { + final String dateString = "Jun 11 2003"; + + java.time.format.DateTimeFormatter formatter = + java.time.format.DateTimeFormatter.ofPattern("MMM dd yyyy", Locale.ENGLISH); + + Date date = null; + // Parse the input date-time with MST, then convert to America/Denver to ensure that + // region-specific rules are applied correctly when parsing + LocalDate localDate; + try { + localDate = LocalDate.parse(dateString, formatter); + date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + } + return date; } private static FilterCapabilities getMockFilterCapabilities() { @@ -1518,11 +1532,10 @@ public void testConfigurableMetacardMappingApiso() public void testPropertyIsEqualToDateLiteral() throws JAXBException, ParseException, SAXException, IOException { - LOGGER.debug("Input date: {}", SAMPLE_NON_ISO_8601_DATE); - LOGGER.debug( - "ISO 8601 formatted date: {}", convertDateToIso8601Format(SAMPLE_NON_ISO_8601_DATE)); + LOGGER.debug("Input date: {}", sampleNonIso8601Date); + LOGGER.debug("ISO 8601 formatted date: {}", convertDateToIso8601Format(sampleNonIso8601Date)); FilterType filterType = - cswFilterDelegateLatLon.propertyIsEqualTo(propertyName, SAMPLE_NON_ISO_8601_DATE); + cswFilterDelegateLatLon.propertyIsEqualTo(propertyName, sampleNonIso8601Date); assertXMLEqual(propertyIsEqualToXmlWithNonIso8601Date, getXmlFromMarshaller(filterType)); } diff --git a/catalog/spatial/wfs/1.1.0/spatial-wfs-v1_1_0-source/src/test/java/org/codice/ddf/spatial/ogc/wfs/v110/catalog/source/WfsFilterDelegateTest.java b/catalog/spatial/wfs/1.1.0/spatial-wfs-v1_1_0-source/src/test/java/org/codice/ddf/spatial/ogc/wfs/v110/catalog/source/WfsFilterDelegateTest.java index 853a4c2522d3..8f4971a18191 100644 --- a/catalog/spatial/wfs/1.1.0/spatial-wfs-v1_1_0-source/src/test/java/org/codice/ddf/spatial/ogc/wfs/v110/catalog/source/WfsFilterDelegateTest.java +++ b/catalog/spatial/wfs/1.1.0/spatial-wfs-v1_1_0-source/src/test/java/org/codice/ddf/spatial/ogc/wfs/v110/catalog/source/WfsFilterDelegateTest.java @@ -38,11 +38,11 @@ import java.io.IOException; import java.io.StringWriter; import java.io.Writer; -import java.text.ParseException; -import java.text.SimpleDateFormat; +import java.time.LocalDate; import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.Collections; import java.util.Date; import java.util.List; import javax.xml.bind.JAXBContext; @@ -62,6 +62,7 @@ import net.opengis.gml.v_3_1_1.MultiPolygonType; import net.opengis.gml.v_3_1_1.PointType; import net.opengis.gml.v_3_1_1.PolygonType; +import org.checkerframework.checker.nullness.qual.Nullable; import org.codice.ddf.spatial.ogc.wfs.catalog.common.FeatureMetacardType; import org.codice.ddf.spatial.ogc.wfs.catalog.common.WfsConstants; import org.codice.ddf.spatial.ogc.wfs.catalog.mapper.MetacardMapper; @@ -70,6 +71,7 @@ import org.custommonkey.xmlunit.XMLUnit; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; +import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; @@ -78,6 +80,7 @@ @SuppressWarnings("FieldCanBeLocal") public class WfsFilterDelegateTest { + private static final Logger LOGGER = LoggerFactory.getLogger(WfsFilterDelegateTest.class); private static final JAXBContext JAXB_CONTEXT = initJaxbContext(); @@ -110,11 +113,9 @@ public class WfsFilterDelegateTest { private static final String NO_OP = "NoOp"; - private final Date date = getDate(); - - private final Date endDate = getEndDate(); + private Date date; - private static final Logger LOGGER = LoggerFactory.getLogger(WfsFilterDelegateTest.class); + private Date endDate; private static final String FILTER_QNAME_LOCAL_PART = "Filter"; @@ -179,7 +180,7 @@ public class WfsFilterDelegateTest { + "" + ""; - private String propertyIsEqualToXmlDate = getPropertyEqualToXmlDate(); + private String propertyIsEqualToXmlDate; private final String propertyNotEqualToXml = "" @@ -197,7 +198,7 @@ public class WfsFilterDelegateTest { + "" + ""; - private final String propertyNotEqualToXmlDate = getPropertyNotEqualToXmlDate(); + private String propertyNotEqualToXmlDate; private final String propertyNotEqualToXmlBoolean = "" @@ -233,7 +234,7 @@ public class WfsFilterDelegateTest { + "" + ""; - private final String propertyGreaterThanXmlDate = getPropertyGreaterThanXmlDate(); + private String propertyGreaterThanXmlDate; private final String propertyGreaterThanOrEqualToXmlLiteral = "" @@ -260,8 +261,7 @@ public class WfsFilterDelegateTest { + "" + ""; - private final String propertyGreaterThanOrEqualToXmlDate = - getPropertyGreaterThanOrEqualToXmlDate(); + private String propertyGreaterThanOrEqualToXmlDate; private final String propertyLessThanXmlLiteral = "" @@ -288,7 +288,7 @@ public class WfsFilterDelegateTest { + "" + ""; - private final String propertyLessThanXmlDate = getPropertyLessThanXmlDate(); + private String propertyLessThanXmlDate; private final String propertyLessThanOrEqualToXmlLiteral = "" @@ -315,7 +315,7 @@ public class WfsFilterDelegateTest { + "" + ""; - private final String propertyLessThanOrEqualToXmlDate = getPropertyLessThanOrEqualToXmlDate(); + private String propertyLessThanOrEqualToXmlDate; private final String propertyIsLikeXmlLiteral = "" @@ -404,12 +404,26 @@ public class WfsFilterDelegateTest { + "" + ""; - private final String propertyBetweenXmlDate = getPropertyBetweenXmlDate(); + private String propertyBetweenXmlDate; private FeatureMetacardType featureMetacardType = mock(FeatureMetacardType.class); private MetacardMapper metacardMapper = mock(MetacardMapper.class); + @Before + public void setup() { + // init date + date = getDate(); + endDate = getEndDate(); + propertyIsEqualToXmlDate = getPropertyEqualToXmlDate(); + propertyNotEqualToXmlDate = getPropertyNotEqualToXmlDate(); + propertyGreaterThanXmlDate = getPropertyGreaterThanXmlDate(); + propertyGreaterThanOrEqualToXmlDate = getPropertyGreaterThanOrEqualToXmlDate(); + propertyLessThanXmlDate = getPropertyLessThanXmlDate(); + propertyLessThanOrEqualToXmlDate = getPropertyLessThanOrEqualToXmlDate(); + propertyBetweenXmlDate = getPropertyBetweenXmlDate(); + } + @Test(expected = IllegalArgumentException.class) public void testWfsFilterDelegateNullFeatureMetacardType() { new WfsFilterDelegate( @@ -661,9 +675,7 @@ public void testPropertyIsNotEqualToStringMatchCase() @Test public void testPropertyIsNotEqualToDate() throws JAXBException, SAXException, IOException { WfsFilterDelegate delegate = createSinglePropertyDelegate(); - FilterType filter = delegate.propertyIsNotEqualTo(MOCK_PROPERTY, date); - assertXMLEqual(propertyNotEqualToXmlDate, marshal(filter)); } @@ -1580,7 +1592,7 @@ public void testIntersectsMultipleProperties() { public void testAllGmlPropertiesBlacklisted() { whenGeom(MOCK_GEOM, MOCK_GEOM2, false, false); - List supportedGeo = Collections.singletonList(SPATIAL_OPERATORS.INTERSECTS.getValue()); + List supportedGeo = singletonList(SPATIAL_OPERATORS.INTERSECTS.getValue()); WfsFilterDelegate delegate = new WfsFilterDelegate( featureMetacardType, @@ -2036,32 +2048,38 @@ private static JAXBContext initJaxbContext() { return jaxbContext; } - private Date getDate() { - String dateString = "Jun 11 2002"; - SimpleDateFormat formatter = new SimpleDateFormat("MMM d yyyy"); - Date date = null; - try { - date = formatter.parse(dateString); - } catch (ParseException e) { - LOGGER.error(e.getMessage(), e); - } - return date; + private static Date getEndDate() { + final String JUN_11_2002 = "Jun 11 2002"; + + return getDate(JUN_11_2002); } - private Date getEndDate() { - String dateString = "Jul 11 2002"; - SimpleDateFormat formatter = new SimpleDateFormat("MMM d yyyy"); + private static Date getDate() { + final String JUN_11_2002 = "Jun 11 2002"; + + return getDate(JUN_11_2002); + } + + private static @Nullable Date getDate(String dateString) { + // Define the formatter for the input pattern + DateTimeFormatter formatter = + DateTimeFormatter.ofPattern("MMM dd yyyy", java.util.Locale.ENGLISH); + Date date = null; + // Parse the input date-time with MST, then convert to America/Denver to ensure that + // region-specific rules are applied correctly when parsing + LocalDate localDate; try { - date = formatter.parse(dateString); - } catch (ParseException e) { + localDate = LocalDate.parse(dateString, formatter); + date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + } catch (Exception e) { LOGGER.error(e.getMessage(), e); } return date; } - private DateTime convertDateToIso8601Format(Date inputDate) { - return new DateTime(inputDate, DateTimeZone.UTC); + private String convertDateToIso8601Format(Date inputDate) { + return new DateTime(inputDate, DateTimeZone.UTC).toString(); } private String getPropertyEqualToXmlDate() { @@ -2212,7 +2230,7 @@ private WfsFilterDelegate setupFilterDelegate( when(featureMetacardType.getGmlProperties()).thenReturn(gmlProps); when(featureMetacardType.isQueryable(MOCK_GEOM)).thenReturn(true); - List supportedGeo = Collections.singletonList(spatialOpType); + List supportedGeo = singletonList(spatialOpType); return new WfsFilterDelegate( featureMetacardType, metacardMapper, diff --git a/catalog/transformer/catalog-transformer-xml/src/test/java/ddf/catalog/transform/xml/XmlInputTransformerTest.java b/catalog/transformer/catalog-transformer-xml/src/test/java/ddf/catalog/transform/xml/XmlInputTransformerTest.java index 6c5fbe40eee3..b8a55da5d4e3 100644 --- a/catalog/transformer/catalog-transformer-xml/src/test/java/ddf/catalog/transform/xml/XmlInputTransformerTest.java +++ b/catalog/transformer/catalog-transformer-xml/src/test/java/ddf/catalog/transform/xml/XmlInputTransformerTest.java @@ -31,10 +31,14 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.Serializable; import java.text.ParseException; -import java.text.SimpleDateFormat; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Base64; +import java.util.Date; import java.util.List; import org.codice.ddf.parser.xml.XmlParser; import org.junit.Before; @@ -135,9 +139,18 @@ public void testSimpleMetadata() throws IOException, CatalogTransformerException metacard.getAttribute(Metacard.METADATA).getValue().toString(), startsWith("")); - assertEquals( - (new SimpleDateFormat("MMM d, yyyy HH:mm:ss.SSS z")).parse("Dec 27, 2012 16:31:01.641 MST"), - metacard.getAttribute(Metacard.EXPIRATION).getValue()); + Date actualDate = (Date) metacard.getAttribute(Metacard.EXPIRATION).getValue(); + + // Define the formatter for the input pattern + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd, yyyy HH:mm:ss.SSS z"); + + // Parse the input date-time with MST, then convert to America/Denver to ensure that + // region-specific rules are applied correctly when parsing + ZonedDateTime mstDateTime = ZonedDateTime.parse("Dec 27, 2012 16:31:01.641 MST", formatter); + ZonedDateTime denverDateTime = mstDateTime.withZoneSameInstant(ZoneId.of("America/Denver")); + Date expectedDate = Date.from(denverDateTime.toInstant()); + + assertEquals(expectedDate, actualDate); assertEquals(DESCRIPTION, metacard.getAttribute("description").getValue()); assertEquals(POINT_OF_CONTACT, metacard.getAttribute("point-of-contact").getValue()); @@ -183,9 +196,17 @@ public void testFallbackToBasicMetacardForUnknowMetacardType() metacard.getAttribute(Metacard.METADATA).getValue().toString(), startsWith("")); - assertThat( - (new SimpleDateFormat("MMM d, yyyy HH:mm:ss.SSS z")).parse("Dec 27, 2012 16:31:01.641 MST"), - is(metacard.getAttribute(Metacard.EXPIRATION).getValue())); + // Define the formatter for the input pattern + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd, yyyy HH:mm:ss.SSS z"); + + // Parse the input date-time with MST, then convert to America/Denver to ensure that + // region-specific rules are applied correctly when parsing + ZonedDateTime mstDateTime = ZonedDateTime.parse("Dec 27, 2012 16:31:01.641 MST", formatter); + ZonedDateTime denverDateTime = mstDateTime.withZoneSameInstant(ZoneId.of("America/Denver")); + Date expectedDate = Date.from(denverDateTime.toInstant()); + + Serializable actualDate = metacard.getAttribute(Metacard.EXPIRATION).getValue(); + assertEquals(expectedDate, actualDate); assertEquals(DESCRIPTION, metacard.getAttribute("description").getValue()); assertEquals(POINT_OF_CONTACT, metacard.getAttribute("point-of-contact").getValue()); From ce3783228eb9ee1db73c0daec93abd35dc16fee0 Mon Sep 17 00:00:00 2001 From: "Bartenstein, Eran [AU-AU]" Date: Tue, 23 Dec 2025 08:02:18 +1100 Subject: [PATCH 2/2] Upgrade to latest GSon 2.13.2 including upgraded countrycode --- .../ddf/persistence/commands/StoreImportCommand.java | 2 +- pom.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/persistence/platform-persistence-commands/src/main/java/org/codice/ddf/persistence/commands/StoreImportCommand.java b/platform/persistence/platform-persistence-commands/src/main/java/org/codice/ddf/persistence/commands/StoreImportCommand.java index b10ed64203ed..caac84aa622d 100644 --- a/platform/persistence/platform-persistence-commands/src/main/java/org/codice/ddf/persistence/commands/StoreImportCommand.java +++ b/platform/persistence/platform-persistence-commands/src/main/java/org/codice/ddf/persistence/commands/StoreImportCommand.java @@ -117,7 +117,7 @@ private Map processFile(File file) { } catch (FileNotFoundException e) { console.println("File not found for import " + file.getName() + "\n"); return null; - } catch (JsonSyntaxException | JsonIOException e) { + } catch (ClassCastException | JsonSyntaxException | JsonIOException e) { console.println("Unable to parse json file. Skipping " + file.getName()); return null; } catch (IOException e) { diff --git a/pom.xml b/pom.xml index 4ab87b9b7589..85f12bc2e21c 100644 --- a/pom.xml +++ b/pom.xml @@ -180,7 +180,7 @@ 1.13.0 1.6 4.7.0 - 0.2.3 + 0.2.4 1.5.2 3.6.7 2.9.0 @@ -195,7 +195,7 @@ org.apache.geronimo.specs 1.22.0 1.1.0 - 2.11.0 + 2.13.2 33.4.0-jre 1.11 4.5.13 @@ -283,7 +283,7 @@ 3.0.5 5.4.1 5.2.2 - 4.28.2 + 4.33.0 2.3.2 0.1.10 5.7 @@ -341,7 +341,7 @@ ${jacoco.argline} 0.45.1 - 1.16.0 + 1.20.0 20240303