Skip to content

Commit

Permalink
fix dv_date_time format (#330)
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanspiska authored Mar 1, 2022
1 parent badd09f commit 8940c46
Show file tree
Hide file tree
Showing 8 changed files with 395 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,53 @@
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.nedap.archie.rm.datavalues.quantity.datetime.DvDateTime;
import com.nedap.archie.rm.datavalues.quantity.datetime.DvTemporal;
import org.apache.commons.collections4.CollectionUtils;

import java.io.IOException;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DecimalStyle;
import java.time.temporal.ChronoField;

import static com.nedap.archie.datetime.DateTimeSerializerFormatters.ISO_8601_DATE;
import static com.nedap.archie.datetime.DateTimeSerializerFormatters.ISO_8601_TIME;



/**
* custom serializer for DvDateTime instance with dot delimiter instead of comma
*/
public class DateTimeSerializer extends JsonSerializer<DvDateTime> {

public static final DateTimeFormatter ISO_8601_DATE_TIME = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(ISO_8601_DATE)
.appendLiteral('T')
.append(ISO_8601_TIME)
.toFormatter()
.withDecimalStyle(DecimalStyle.STANDARD.withDecimalSeparator('.'));
static final DateTimeFormatter ISO_8601_TIME =
(new DateTimeFormatterBuilder())
.parseCaseInsensitive()
.appendValue(ChronoField.HOUR_OF_DAY, 2)
.optionalStart()
.appendLiteral(':')
.appendValue(ChronoField.MINUTE_OF_HOUR, 2)
.optionalStart()
.appendLiteral(':')
.appendValue(ChronoField.SECOND_OF_MINUTE, 2)
.optionalStart()
.appendFraction(ChronoField.NANO_OF_SECOND, 3, 9, true)
.optionalEnd()
.optionalEnd()
.optionalEnd()
.optionalStart()
.appendOffsetId()
.optionalEnd()
.toFormatter()
.withDecimalStyle(DecimalStyle.STANDARD.withDecimalSeparator('.'));

public static final DateTimeFormatter ISO_8601_DATE_TIME =
new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(ISO_8601_DATE)
.appendLiteral('T')
.append(ISO_8601_TIME)
.toFormatter()
.withDecimalStyle(DecimalStyle.STANDARD.withDecimalSeparator('.'));

@Override
public void serialize(DvDateTime dvDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
Expand All @@ -68,26 +93,31 @@ private void toJson(JsonGenerator jsonGenerator, DvDateTime dvDateTime) throws I
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("_type", "DV_DATE_TIME");
jsonGenerator.writeStringField("value", ISO_8601_DATE_TIME.format(dvDateTime.getValue()));
if (dvDateTime.getNormalStatus() != null) {
writeDvTemporal(jsonGenerator, dvDateTime, mapper);
jsonGenerator.writeEndObject();
}

static void writeDvTemporal(
JsonGenerator jsonGenerator, DvTemporal dvTemporal, ObjectMapper mapper) throws IOException {
if (dvTemporal.getNormalStatus() != null) {
jsonGenerator.writeFieldName("normal_status");
jsonGenerator.writeRawValue(mapper.writeValueAsString(dvDateTime.getNormalStatus()));
jsonGenerator.writeRawValue(mapper.writeValueAsString(dvTemporal.getNormalStatus()));
}
if (dvDateTime.getNormalRange() != null) {
if (dvTemporal.getNormalRange() != null) {
jsonGenerator.writeFieldName("normal_range");
jsonGenerator.writeRawValue(mapper.writeValueAsString(dvDateTime.getNormalRange()));
jsonGenerator.writeRawValue(mapper.writeValueAsString(dvTemporal.getNormalRange()));
}
if (!CollectionUtils.isEmpty(dvDateTime.getOtherReferenceRanges())) {
if (!CollectionUtils.isEmpty(dvTemporal.getOtherReferenceRanges())) {
jsonGenerator.writeFieldName("other_reference_ranges");
jsonGenerator.writeRawValue(mapper.writeValueAsString(dvDateTime.getOtherReferenceRanges()));
jsonGenerator.writeRawValue(mapper.writeValueAsString(dvTemporal.getOtherReferenceRanges()));
}
if (dvDateTime.getMagnitudeStatus() != null) {
if (dvTemporal.getMagnitudeStatus() != null) {
jsonGenerator.writeFieldName("magnitude_status");
jsonGenerator.writeRawValue(mapper.writeValueAsString(dvDateTime.getMagnitudeStatus()));
jsonGenerator.writeRawValue(mapper.writeValueAsString(dvTemporal.getMagnitudeStatus()));
}
if (dvDateTime.getNormalStatus() != null) {
if (dvTemporal.getNormalStatus() != null) {
jsonGenerator.writeFieldName("accuracy");
jsonGenerator.writeRawValue(mapper.writeValueAsString(dvDateTime.getAccuracy()));
jsonGenerator.writeRawValue(mapper.writeValueAsString(dvTemporal.getAccuracy()));
}
jsonGenerator.writeEndObject();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.nedap.archie.rm.datavalues.quantity.datetime.DvDate;
import com.nedap.archie.rm.datavalues.quantity.datetime.DvDateTime;
import com.nedap.archie.rm.datavalues.quantity.datetime.DvDuration;
import com.nedap.archie.rm.datavalues.quantity.datetime.DvTime;
import com.nedap.archie.rm.ehr.Ehr;
import com.nedap.archie.rm.support.identification.HierObjectId;
import com.nedap.archie.rm.support.identification.ObjectId;
Expand Down Expand Up @@ -96,6 +97,29 @@ public void MarshalEmptyDvText() {
"{\n" + " \"_type\" : \"DV_TEXT\",\n" + " \"value\" : \"\"\n" + "}");
}

@Test
public void MarshalDvDateTimeWithZero() {
DvDateTime dvDateTime = new DvDateTime("2022-02-25T10:55:41.400Z");
CanonicalJson cut = new CanonicalJson();
String actual = cut.marshal(dvDateTime);
assertThat(actual)
.isEqualToIgnoringWhitespace(
"{\n"
+ " \"_type\" : \"DV_DATE_TIME\",\n"
+ " \"value\" : \"2022-02-25T10:55:41.400Z\"\n"
+ "}");
}

@Test
public void MarshalDvTimeWithZero() {
DvTime dvTime = new DvTime("10:55:41.400Z");
CanonicalJson cut = new CanonicalJson();
String actual = cut.marshal(dvTime);
assertThat(actual)
.isEqualToIgnoringWhitespace(
"{\n" + " \"_type\" : \"DV_TIME\",\n" + " \"value\" : \"10:55:41.400Z\"\n" + "}");
}

@Test
public void MarshalEmptyContent() {
ItemTree itemTree = new ItemTree();
Expand Down
8 changes: 4 additions & 4 deletions serialisation_conformance_test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,17 @@
<include>EmptynessTestOverwrite</include>
<include>EthersBuilderTestOverwrite</include>
<include>DurationTest</include>
<include>EndTimeTest</include>
<include>EndTimeTestOverwrite</include>
<include>FeederAuditTestOverwritten</include>
<include>FixedValueTestOverwrite</include>
<include>HistoryOriginTest</include>
<include>HistoryOriginTestOverwrite</include>
<include>InfinnityTestOverwrite</include>
<include>InstructionActionTestOverwrite</include>
<include>IntervalEventTest</include>
<include>IspekBuilderTestOverwrite</include>
<include>IsmTransitionTest</include>
<include>LinksTest</include>
<include>LocationTest</include>
<include>LocationTestOverwrite</include>
<include>LongValueJsonTest</include>
<include>MediaTypeExampleTest</include>
<include>NamedElementsTest</include>
Expand All @@ -86,7 +86,7 @@
<include>SettersTestOverwrite</include>
<include>StatusesTestOverwrite</include>
<include>TermMappingTestOverwritten</include>
<include>TimeZoneTest</include>
<include>TimeZoneTestOverwrite</include>
<include>UidTest</include>
<include>WebTemplateContentTest.java</include>
<include>WorkflowIdTestOverwrite</include>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2022 Stefan Spiska (Vitasystems GmbH) and Hannover Medical School
*
* This file is part of Project EHRbase
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.ehrbase.conformance_test.extern.tests;

import care.better.platform.web.template.EndTimeTest;
import com.google.common.collect.ImmutableMap;
import com.nedap.archie.rm.composition.Composition;
import com.nedap.archie.rm.composition.Observation;
import com.nedap.archie.rm.composition.Section;
import org.ehrbase.serialisation.RMDataFormat;
import org.ehrbase.serialisation.flatencoding.FlatFormat;
import org.junit.Test;

import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;
import static org.ehrbase.conformance_test.extern.Helper.getFlatJson;
import static org.ehrbase.conformance_test.extern.tests.StatusesTestOverwrite.OBJECT_MAPPER;

public class EndTimeTestOverwrite extends EndTimeTest {

@Override
@Test
public void endTimeTest() throws Exception {
String template = this.getFileContent("/res/Demo Vitals.opt");
OffsetDateTime dateTime =
ZonedDateTime.of(2015, 1, 1, 10, 31, 16, 0, ZoneId.systemDefault()).toOffsetDateTime();
Map<Object, Object> flatComposition =
ImmutableMap.builder()
.put("ctx/language", "sl")
.put("ctx/territory", "SI")
.put("ctx/composer_name", "Composer")
.put("ctx/id_scheme", "ispek")
.put("ctx/id_namespace", "ispek")
.put("ctx/end_time", "2016-01-01T12:30:30Z")
.put(
"vitals/vitals/haemoglobin_a1c/history_origin",
DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(dateTime))
.put("vitals/vitals/haemoglobin_a1c/any_event/test_status|terminology", "local")
.put("vitals/vitals/haemoglobin_a1c/any_event/test_status|code", "at0037")
.build();

RMDataFormat flatJson = getFlatJson(template, FlatFormat.SIM_SDT);
Composition composition = flatJson.unmarshal(OBJECT_MAPPER.writeValueAsString(flatComposition));

Observation observation =
(Observation) ((Section) composition.getContent().get(0)).getItems().get(0);

assertThat(observation.getData().getOrigin().getValue()).isEqualTo(dateTime);
assertThat(composition.getContext().getEndTime().getValue())
.hasToString("2016-01-01T12:30:30Z");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,60 @@

import care.better.platform.web.template.FeederAuditTest;
import care.better.platform.web.template.extension.WebTemplateTestExtension;
import com.nedap.archie.rm.archetyped.FeederAudit;
import com.nedap.archie.rm.composition.Composition;
import org.assertj.core.api.Assertions;
import org.ehrbase.conformance_test.extern.CompositionValidatorImp;
import org.ehrbase.serialisation.RMDataFormat;
import org.ehrbase.serialisation.flatencoding.FlatFormat;
import org.ehrbase.serialisation.jsonencoding.CanonicalJson;
import org.junit.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import static org.assertj.core.api.Assertions.assertThat;
import static org.ehrbase.conformance_test.extern.Helper.getFlatJson;

@ExtendWith({WebTemplateTestExtension.class})
public class FeederAuditTestOverwritten extends FeederAuditTest {

@Override
/* test proprietary stuff from better */
public void structuredWithGenericFields() throws Exception {}

@Override
@Test
public void feederAuditBroken() throws Exception {

String flatComposition =
this.getFileContent("/res/gel_data.json")
// topography is single valued in the template
.replace(
"gel_cancer_diagnosis/problem_diagnosis:3/cancer_diagnosis/topography:78",
"gel_cancer_diagnosis/problem_diagnosis:3/cancer_diagnosis/topography")
.replace(
"gel_cancer_diagnosis/problem_diagnosis:5/cancer_diagnosis/topography:137",
"gel_cancer_diagnosis/problem_diagnosis:5/cancer_diagnosis/topography")
.replace(
"gel_cancer_diagnosis/problem_diagnosis:1/cancer_diagnosis/topography:19",
"gel_cancer_diagnosis/problem_diagnosis:1/cancer_diagnosis/topography");

String template = this.getFileContent("/res/GEL Cancer diagnosis input.opt");

RMDataFormat flatJson = getFlatJson(template, FlatFormat.SIM_SDT);
Composition composition = flatJson.unmarshal(flatComposition);

Assertions.assertThat(
new CompositionValidatorImp()
.validate(template, new CanonicalJson().marshal(composition)))
.isEmpty();

FeederAudit feederAudit = composition.getContent().get(0).getFeederAudit();

assertThat(feederAudit).isNotNull();

assertThat(feederAudit.getOriginatingSystemAudit().getSystemId()).isEqualTo("infoflex");

assertThat(feederAudit.getOriginatingSystemAudit().getTime().getValue())
.hasToString("2018-01-01T03:00Z");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2022 Stefan Spiska (Vitasystems GmbH) and Hannover Medical School
*
* This file is part of Project EHRbase
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.ehrbase.conformance_test.extern.tests;

import care.better.platform.web.template.HistoryOriginTest;
import com.google.common.collect.ImmutableMap;
import com.nedap.archie.rm.composition.Composition;
import com.nedap.archie.rm.composition.Observation;
import com.nedap.archie.rm.composition.Section;
import org.ehrbase.serialisation.RMDataFormat;
import org.ehrbase.serialisation.flatencoding.FlatFormat;
import org.junit.Test;

import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;
import static org.ehrbase.conformance_test.extern.Helper.getFlatJson;
import static org.ehrbase.conformance_test.extern.tests.StatusesTestOverwrite.OBJECT_MAPPER;

public class HistoryOriginTestOverwrite extends HistoryOriginTest {

@Override
@Test
public void historyOrigin() throws Exception {
String template = this.getFileContent("/res/Demo Vitals.opt");
OffsetDateTime dateTime =
ZonedDateTime.of(2015, 1, 1, 10, 31, 16, 0, ZoneId.systemDefault()).toOffsetDateTime();
Map<Object, Object> flatComposition =
ImmutableMap.builder()
.put("ctx/language", "sl")
.put("ctx/territory", "SI")
.put("ctx/composer_name", "Composer")
.put("ctx/id_scheme", "ispek")
.put("ctx/id_namespace", "ispek")
.put(
"vitals/vitals/haemoglobin_a1c/history_origin",
DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(dateTime))
.put("vitals/vitals/haemoglobin_a1c/any_event/test_status|terminology", "local")
.put("vitals/vitals/haemoglobin_a1c/any_event/test_status|code", "at0037")
.build();

RMDataFormat flatJson = getFlatJson(template, FlatFormat.SIM_SDT);
Composition composition = flatJson.unmarshal(OBJECT_MAPPER.writeValueAsString(flatComposition));

Observation observation =
(Observation) ((Section) composition.getContent().get(0)).getItems().get(0);

assertThat(observation.getData().getOrigin().getValue()).isEqualTo(dateTime);
}
}
Loading

0 comments on commit 8940c46

Please sign in to comment.