From 451074f25d545abfdd84a5214d2f8c81b8e81fbe Mon Sep 17 00:00:00 2001 From: stuart mcneill Date: Mon, 10 Mar 2025 21:32:40 +0000 Subject: [PATCH 1/3] modified date validator to convert any date value=1 to a default date - 1970-01-01 --- .../mappings/from/hl7/XmlToFhirMapper.java | 24 ++++++++++++++++++- .../from/hl7/XmlToFhirMapperTest.java | 5 ++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/docker/service/src/main/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapper.java b/docker/service/src/main/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapper.java index b7a75225d..54c5cc8af 100644 --- a/docker/service/src/main/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapper.java +++ b/docker/service/src/main/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapper.java @@ -1,6 +1,8 @@ package uk.nhs.adaptors.scr.mappings.from.hl7; import lombok.SneakyThrows; + +import org.hibernate.validator.internal.util.logging.LoggerFactory; import org.hl7.fhir.r4.model.BaseDateTimeType; import org.hl7.fhir.r4.model.DateTimeType; import org.hl7.fhir.r4.model.InstantType; @@ -13,6 +15,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.Date; import java.util.List; import java.util.TimeZone; @@ -23,6 +26,10 @@ import static ca.uhn.fhir.model.api.TemporalPrecisionEnum.MILLI; import static java.lang.Integer.parseInt; +import java.lang.System.Logger; +import java.lang.System.Logger.Level; + + public interface XmlToFhirMapper { // List of known date/time formats which may be present in HL7 based SCR. String DATE_TIME_SECONDS_PATTERN = "yyyyMMddHHmmss"; @@ -34,9 +41,16 @@ public interface XmlToFhirMapper { String SNOMED_SYSTEM = "http://snomed.info/sct"; String TIMEZONE = "Europe/London"; + // private static Logger logger() { + // final class LogHolder { + // private static final Logger LOGGER = LoggerFactory.getLogger(XmlToFhirMapper.class); + // } + // return LogHolder.LOGGER; + // } + List map(Node document); - /** + /** * Takes a date, and parses it into a BaseDateTimeObject. * Dates may be received in partial format, e.g. YYYY, YYYY-mm, which are invalid, but we still need to preserve * them as-is for clinical safety. Due to limitations on the third party FHIR parser code, we instead allocate a @@ -61,6 +75,8 @@ static T parseDate(String date, Class clazz) { int monthPrecision = 2; int yearPrecision = 1; + Date defaultDate; + defaultDate = new Date(0); if (isValidDate(date, DATE_TIME_SECONDS_PATTERN)) { LocalDateTime parsed = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(DATE_TIME_SECONDS_PATTERN)); @@ -106,6 +122,11 @@ static T parseDate(String date, Class clazz) { baseDateTimeType.setTimeZone(TimeZone.getTimeZone(TIMEZONE)); baseDateTimeType.setYear(parseInt(date) + 1); baseDateTimeType.setMillis(yearPrecision); + } else if (date.equals("1")) { + baseDateTimeType.setTimeZone(TimeZone.getTimeZone(TIMEZONE)); + baseDateTimeType.setValue(defaultDate); + // logger().log(Level.ERROR, "Invalid date value:1 updated"); + } else { throw new ScrBaseException("Unsupported date format: " + date); } @@ -141,4 +162,5 @@ static void setDatePart(BaseDateTimeType baseDateTimeType, int dayOfMonth, int m baseDateTimeType.setMonth(monthValue - 1); baseDateTimeType.setYear(year); } + } diff --git a/docker/service/src/test/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapperTest.java b/docker/service/src/test/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapperTest.java index cb1ffdae2..43094cd01 100644 --- a/docker/service/src/test/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapperTest.java +++ b/docker/service/src/test/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapperTest.java @@ -37,6 +37,11 @@ public void When_ParsingDate_Expect_CorrectDateFormat() { date = parseDate("2023", InstantType.class); assertThat(date.getValueAsString()).isEqualTo("2023"); + // FLAGSAPI-806 + date = parseDate("1", InstantType.class); + // System.out.println(date.getValueAsString()); + assertThat(date.getValueAsString()).isEqualTo("1970-01-01T01:00:00.000+01:00"); + assertThrows(ScrBaseException.class, () -> { parseDate("-2023", InstantType.class); }); From 0ff28e5b911079d6a10d429e154085fb1e0b34ae Mon Sep 17 00:00:00 2001 From: stuart mcneill Date: Mon, 17 Mar 2025 16:15:36 +0000 Subject: [PATCH 2/3] changes following review from steve and alex --- .../mappings/from/hl7/XmlToFhirMapper.java | 30 ++++++------------- .../from/hl7/XmlToFhirMapperTest.java | 3 +- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/docker/service/src/main/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapper.java b/docker/service/src/main/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapper.java index 54c5cc8af..d238a1ff1 100644 --- a/docker/service/src/main/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapper.java +++ b/docker/service/src/main/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapper.java @@ -1,8 +1,7 @@ package uk.nhs.adaptors.scr.mappings.from.hl7; import lombok.SneakyThrows; - -import org.hibernate.validator.internal.util.logging.LoggerFactory; +import org.slf4j.LoggerFactory; import org.hl7.fhir.r4.model.BaseDateTimeType; import org.hl7.fhir.r4.model.DateTimeType; import org.hl7.fhir.r4.model.InstantType; @@ -15,7 +14,6 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.Date; import java.util.List; import java.util.TimeZone; @@ -26,10 +24,6 @@ import static ca.uhn.fhir.model.api.TemporalPrecisionEnum.MILLI; import static java.lang.Integer.parseInt; -import java.lang.System.Logger; -import java.lang.System.Logger.Level; - - public interface XmlToFhirMapper { // List of known date/time formats which may be present in HL7 based SCR. String DATE_TIME_SECONDS_PATTERN = "yyyyMMddHHmmss"; @@ -41,16 +35,9 @@ public interface XmlToFhirMapper { String SNOMED_SYSTEM = "http://snomed.info/sct"; String TIMEZONE = "Europe/London"; - // private static Logger logger() { - // final class LogHolder { - // private static final Logger LOGGER = LoggerFactory.getLogger(XmlToFhirMapper.class); - // } - // return LogHolder.LOGGER; - // } - List map(Node document); - /** + /** * Takes a date, and parses it into a BaseDateTimeObject. * Dates may be received in partial format, e.g. YYYY, YYYY-mm, which are invalid, but we still need to preserve * them as-is for clinical safety. Due to limitations on the third party FHIR parser code, we instead allocate a @@ -75,8 +62,6 @@ static T parseDate(String date, Class clazz) { int monthPrecision = 2; int yearPrecision = 1; - Date defaultDate; - defaultDate = new Date(0); if (isValidDate(date, DATE_TIME_SECONDS_PATTERN)) { LocalDateTime parsed = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(DATE_TIME_SECONDS_PATTERN)); @@ -123,10 +108,14 @@ static T parseDate(String date, Class clazz) { baseDateTimeType.setYear(parseInt(date) + 1); baseDateTimeType.setMillis(yearPrecision); } else if (date.equals("1")) { + date = "19700101"; + LocalDate parsed = LocalDate.parse(date, DateTimeFormatter.ofPattern(DATE_PATTERN)); + baseDateTimeType.setPrecision(DAY); baseDateTimeType.setTimeZone(TimeZone.getTimeZone(TIMEZONE)); - baseDateTimeType.setValue(defaultDate); - // logger().log(Level.ERROR, "Invalid date value:1 updated"); - + setDatePart(baseDateTimeType, parsed.getDayOfMonth(), parsed.getMonthValue(), parsed.getYear()); + baseDateTimeType.setMillis(dayPrecision); + org.slf4j.Logger logger = LoggerFactory.getLogger(XmlToFhirMapper.class); + logger.error("Invalid date value:1 updated"); } else { throw new ScrBaseException("Unsupported date format: " + date); } @@ -162,5 +151,4 @@ static void setDatePart(BaseDateTimeType baseDateTimeType, int dayOfMonth, int m baseDateTimeType.setMonth(monthValue - 1); baseDateTimeType.setYear(year); } - } diff --git a/docker/service/src/test/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapperTest.java b/docker/service/src/test/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapperTest.java index 43094cd01..a8e9adddb 100644 --- a/docker/service/src/test/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapperTest.java +++ b/docker/service/src/test/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapperTest.java @@ -39,8 +39,7 @@ public void When_ParsingDate_Expect_CorrectDateFormat() { // FLAGSAPI-806 date = parseDate("1", InstantType.class); - // System.out.println(date.getValueAsString()); - assertThat(date.getValueAsString()).isEqualTo("1970-01-01T01:00:00.000+01:00"); + assertThat(date.getValueAsString()).isEqualTo("1970-01-01"); assertThrows(ScrBaseException.class, () -> { parseDate("-2023", InstantType.class); From 843b23f8eafcce8d659f23c00c0379afdca8e2fc Mon Sep 17 00:00:00 2001 From: stuart mcneill Date: Tue, 18 Mar 2025 13:30:18 +0000 Subject: [PATCH 3/3] FLAGSAPI-806 removed trailing spaces --- .../nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapperTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/service/src/test/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapperTest.java b/docker/service/src/test/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapperTest.java index a8e9adddb..091b971a3 100644 --- a/docker/service/src/test/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapperTest.java +++ b/docker/service/src/test/java/uk/nhs/adaptors/scr/mappings/from/hl7/XmlToFhirMapperTest.java @@ -37,7 +37,7 @@ public void When_ParsingDate_Expect_CorrectDateFormat() { date = parseDate("2023", InstantType.class); assertThat(date.getValueAsString()).isEqualTo("2023"); - // FLAGSAPI-806 + // FLAGSAPI-806 date = parseDate("1", InstantType.class); assertThat(date.getValueAsString()).isEqualTo("1970-01-01");