Skip to content

Commit

Permalink
[CDR-1512] Fix flat parsing of ObjectVersionId (#622)
Browse files Browse the repository at this point in the history
* CDR-1512 Migrate tests to JUnit5

* CDR-1512 Reduce cognitive load of flat locatable unmarshaller
  • Loading branch information
alexlehn authored Jul 22, 2024
1 parent 69ffad0 commit 83e6b5f
Show file tree
Hide file tree
Showing 12 changed files with 485 additions and 448 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Note: version releases in the 0.x.y range may introduce breaking changes.
## [unreleased]
### Added
### Fixed
- Fix flat format parsing of `ObjectVersionId` ([622](https://github.com/ehrbase/openEHR_SDK/pull/622))

## [2.14.0]
### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,17 @@
import com.nedap.archie.rm.datavalues.DvCodedText;
import com.nedap.archie.rm.datavalues.DvText;
import com.nedap.archie.rm.support.identification.HierObjectId;
import com.nedap.archie.rm.support.identification.ObjectVersionId;
import java.util.ArrayList;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.ehrbase.openehr.sdk.serialisation.walker.Context;
import org.ehrbase.openehr.sdk.serialisation.walker.FlatHelper;
import org.ehrbase.openehr.sdk.serialisation.walker.defaultvalues.DefaultValues;
import org.ehrbase.openehr.sdk.util.rmconstants.RmConstants;
import org.ehrbase.openehr.sdk.webtemplate.model.WebTemplateNode;
import org.ehrbase.openehr.sdk.webtemplate.path.flat.FlatPathDto;

public class LocatableUnmarshalPostprocessor extends AbstractUnmarshalPostprocessor<Locatable> {
Expand All @@ -48,54 +51,16 @@ public void process(
Set<String> consumedPaths,
Context<Map<FlatPathDto, String>> context) {

if (RmConstants.ELEMENT.equals(context.getNodeDeque().peek().getRmType())
|| !context.getFlatHelper().skip(context)) {

setValue(
term + PATH_DIVIDER + "_uid",
null,
values,
s -> rmObject.setUid(new HierObjectId(s)),
String.class,
consumedPaths);

Map<Integer, Map<FlatPathDto, String>> links = extractMultiValued(term, "_link", values);

if (rmObject.getLinks() == null) {
rmObject.setLinks(new ArrayList<>());
}

rmObject.getLinks()
.addAll(links.entrySet().stream()
.map(e -> DefaultValues.createLink(e.getValue(), term + "/_link:" + e.getKey()))
.collect(Collectors.toList()));

consumeAllMatching(term + PATH_DIVIDER + "_link", values, consumedPaths, false);

Map<FlatPathDto, String> feederAuditValues = FlatHelper.filter(values, term + "/_feeder_audit", false);

if (!feederAuditValues.isEmpty()) {

rmObject.setFeederAudit(new FeederAudit());
handleRmAttribute(
term, rmObject.getFeederAudit(), feederAuditValues, consumedPaths, context, "feeder_audit");
}

Map<FlatPathDto, String> nameValues = FlatHelper.filter(values, term + "/_name", false);
if (!nameValues.isEmpty()) {
final DvText name;
boolean isDvCodedText = nameValues.keySet().stream()
.anyMatch(e -> "code".equals(e.getLast().getAttributeName())
&& "_name".equals(e.getLast().getName()));

if (isDvCodedText) {
name = new DvCodedText();
} else {
name = new DvText();
}
rmObject.setName(name);
handleRmAttribute(term, rmObject.getName(), nameValues, consumedPaths, context, "name");
}
String rmType = Optional.ofNullable(context.getNodeDeque().peek())
.map(WebTemplateNode::getRmType)
.orElse(null);

if (RmConstants.ELEMENT.equals(rmType) || !context.getFlatHelper().skip(context)) {

setUID(term, rmObject, values, consumedPaths);
setName(term, rmObject, values, consumedPaths, context);
setLinks(term, rmObject, values, consumedPaths);
setFeederAudit(term, rmObject, values, consumedPaths, context);
}
}

Expand All @@ -104,4 +69,69 @@ public void process(
public Class<Locatable> getAssociatedClass() {
return Locatable.class;
}

private void setUID(String term, Locatable rmObject, Map<FlatPathDto, String> values, Set<String> consumedPaths) {
setValue(
term + PATH_DIVIDER + "_uid",
null,
values,
value -> rmObject.setUid(
StringUtils.countMatches(value, "::") == 2
? new ObjectVersionId(value)
: new HierObjectId(value)),
String.class,
consumedPaths);
}

private void setName(
String term,
Locatable rmObject,
Map<FlatPathDto, String> values,
Set<String> consumedPaths,
Context<Map<FlatPathDto, String>> context) {

Map<FlatPathDto, String> nameValues = FlatHelper.filter(values, term + "/_name", false);
if (!nameValues.isEmpty()) {
boolean isDvCodedText = nameValues.keySet().stream().anyMatch(e -> {
FlatPathDto last = e.getLast();
return "code".equals(last.getAttributeName()) && "_name".equals(last.getName());
});

rmObject.setName(isDvCodedText ? new DvCodedText() : new DvText());
handleRmAttribute(term, rmObject.getName(), nameValues, consumedPaths, context, "name");
}
}

private void setLinks(String term, Locatable rmObject, Map<FlatPathDto, String> values, Set<String> consumedPaths) {

Map<Integer, Map<FlatPathDto, String>> links = extractMultiValued(term, "_link", values);

if (rmObject.getLinks() == null) {
rmObject.setLinks(new ArrayList<>());
}

rmObject.getLinks()
.addAll(links.entrySet().stream()
.map(e -> DefaultValues.createLink(e.getValue(), term + "/_link:" + e.getKey()))
.toList());

consumeAllMatching(term + PATH_DIVIDER + "_link", values, consumedPaths, false);
}

private void setFeederAudit(
String term,
Locatable rmObject,
Map<FlatPathDto, String> values,
Set<String> consumedPaths,
Context<Map<FlatPathDto, String>> context) {

Map<FlatPathDto, String> feederAuditValues = FlatHelper.filter(values, term + "/_feeder_audit", false);

if (!feederAuditValues.isEmpty()) {

rmObject.setFeederAudit(new FeederAudit());
handleRmAttribute(
term, rmObject.getFeederAudit(), feederAuditValues, consumedPaths, context, "feeder_audit");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@
import org.ehrbase.openehr.sdk.serialisation.xmlencoding.CanonicalXML;
import org.ehrbase.openehr.sdk.test_data.folder.FolderTestDataCanonicalJson;
import org.ehrbase.openehr.sdk.test_data.folder.FolderTestDataCanonicalXML;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

public class FolderSerializerTest {
class FolderSerializerTest {

@Test
public void marshalBasicJsonFolder() throws IOException {
void marshalBasicJsonFolder() throws IOException {

String value = IOUtils.toString(FolderTestDataCanonicalJson.SIMPLE_EMPTY_FOLDER.getStream(), UTF_8);
CanonicalJson canonicalJson = new CanonicalJson();
Expand All @@ -49,7 +49,7 @@ public void marshalBasicJsonFolder() throws IOException {
}

@Test
public void unmarshalBasicJsonFolder() throws IOException {
void unmarshalBasicJsonFolder() throws IOException {

String value = IOUtils.toString(FolderTestDataCanonicalJson.SIMPLE_EMPTY_FOLDER.getStream(), UTF_8);

Expand All @@ -60,8 +60,8 @@ public void unmarshalBasicJsonFolder() throws IOException {
}

@Test
@Ignore("Possible bug at Archie with missing XMLRootElement annotation for folders.")
public void marshalBasicXmlFolder() throws IOException {
@Disabled("Possible bug at Archie with missing XMLRootElement annotation for folders.")
void marshalBasicXmlFolder() throws IOException {

String value = IOUtils.toString(FolderTestDataCanonicalXML.SIMPLE_EMPTY_FOLDER.getStrean(), UTF_8);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,17 @@
import org.apache.commons.io.IOUtils;
import org.assertj.core.api.SoftAssertions;
import org.ehrbase.openehr.sdk.serialisation.RMDataFormat;
import org.ehrbase.openehr.sdk.serialisation.flatencoding.std.marshal.FlatJsonMarshallerTest;
import org.ehrbase.openehr.sdk.serialisation.templateprovider.TestDataTemplateProvider;
import org.ehrbase.openehr.sdk.test_data.composition.CompositionTestDataSimSDTJson;
import org.ehrbase.openehr.sdk.test_data.operationaltemplate.OperationalTemplateTestData;
import org.junit.Test;
import org.junit.jupiter.api.Test;

public class FlatJsonTest {
class FlatJsonTest {

public static final TestDataTemplateProvider templateProvider = new TestDataTemplateProvider();
private static final TestDataTemplateProvider templateProvider = new TestDataTemplateProvider();

@Test
public void roundTrip() throws IOException {
void roundTrip() throws IOException {

CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.CORONA_WITH_OTHER_PARTICIPATION;
String templateId = "Corona_Anamnese";
Expand All @@ -46,7 +45,7 @@ public void roundTrip() throws IOException {
}

@Test
public void roundTripSSIAD_PRIeSM() throws IOException {
void roundTripSSIAD_PRIeSM() throws IOException {

CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.SSIAD_PRIESM;
String templateId = testData.getTemplate().getTemplateId();
Expand All @@ -55,7 +54,7 @@ public void roundTripSSIAD_PRIeSM() throws IOException {
}

@Test
public void roundTripFeederAudit() throws IOException {
void roundTripFeederAudit() throws IOException {

CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.CORONA_WITH_FEEDER_AUDIT;
String templateId = "Corona_Anamnese";
Expand All @@ -64,7 +63,7 @@ public void roundTripFeederAudit() throws IOException {
}

@Test
public void roundTripFeederAuditRaw() throws IOException {
void roundTripFeederAuditRaw() throws IOException {

CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.CORONA_WITH_FEEDER_AUDIT_RAW;
String templateId = "Corona_Anamnese";
Expand All @@ -90,7 +89,7 @@ public void roundTripFeederAuditRaw() throws IOException {
String expected = IOUtils.toString(
CompositionTestDataSimSDTJson.CORONA_WITH_FEEDER_AUDIT.getStream(), StandardCharsets.UTF_8);

List<String> errors = FlatJsonMarshallerTest.compere(actual, expected);
List<String> errors = FlatTestHelper.compere(actual, expected);

softAssertions
.assertThat(errors)
Expand All @@ -103,7 +102,7 @@ public void roundTripFeederAuditRaw() throws IOException {
}

@Test
public void roundTripRaw() throws IOException {
void roundTripRaw() throws IOException {

CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.CORONA_WITH_RAW;
String templateId = "Corona_Anamnese";
Expand All @@ -128,7 +127,7 @@ public void roundTripRaw() throws IOException {

String expected = IOUtils.toString(CompositionTestDataSimSDTJson.CORONA.getStream(), StandardCharsets.UTF_8);

List<String> errors = FlatJsonMarshallerTest.compere(actual, expected);
List<String> errors = FlatTestHelper.compere(actual, expected);

softAssertions
.assertThat(errors)
Expand All @@ -141,7 +140,7 @@ public void roundTripRaw() throws IOException {
}

@Test
public void roundTripAction() throws IOException {
void roundTripAction() throws IOException {

CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.EREACT_COVID_MANAGEMENT;
String templateId = OperationalTemplateTestData.EREACT_COVID_MANAGEMENT.getTemplateId();
Expand All @@ -150,7 +149,7 @@ public void roundTripAction() throws IOException {
}

@Test
public void roundTripNCD() throws IOException {
void roundTripNCD() throws IOException {

CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.NCD;
String templateId = OperationalTemplateTestData.NCD.getTemplateId();
Expand Down Expand Up @@ -202,15 +201,15 @@ public void roundTripNCD() throws IOException {
}

@Test
public void roundTripVitalSigns() throws IOException {
void roundTripVitalSigns() throws IOException {
CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.VITALSIGNS;
String templateId = "EHRN Vital signs.v2";

check(templateId, testData, new String[] {}, new String[] {});
}

@Test
public void roundTripIcd() throws IOException {
void roundTripIcd() throws IOException {

CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.ADVERSE_REACTION_LIST;
String templateId = "Adverse Reaction List.v1";
Expand All @@ -219,7 +218,7 @@ public void roundTripIcd() throws IOException {
}

@Test
public void roundMultiList() throws IOException {
void roundMultiList() throws IOException {

CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.MULTI_LIST;
String templateId = OperationalTemplateTestData.MULTI_LIST.getTemplateId();
Expand All @@ -228,7 +227,7 @@ public void roundMultiList() throws IOException {
}

@Test
public void roundNameWithAnd() throws IOException {
void roundNameWithAnd() throws IOException {

CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.WORD_WITH_AND;
String templateId = OperationalTemplateTestData.WORD_WITH_AND.getTemplateId();
Expand All @@ -237,7 +236,7 @@ public void roundNameWithAnd() throws IOException {
}

@Test
public void roundTripDeterioriationAssessment() throws IOException {
void roundTripDeterioriationAssessment() throws IOException {

String templateId = "EREACT - Deterioriation assessment.v0";
CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.DETERIORIATION_ASSESSMENT;
Expand All @@ -264,7 +263,7 @@ public void roundTripDeterioriationAssessment() throws IOException {
}

@Test
public void roundTripAll() throws IOException {
void roundTripAll() throws IOException {
String templateId = "test_all_types.en.v1";
CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.ALL_TYPES;

Expand All @@ -282,7 +281,7 @@ public void roundTripAll() throws IOException {
}

@Test
public void roundTripAlt() throws IOException {
void roundTripAlt() throws IOException {

String templateId = "AlternativeEvents";
CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.ALTERNATIVE_EVENTS;
Expand All @@ -307,7 +306,7 @@ public void roundTripAlt() throws IOException {
}

@Test
public void roundTripMulti() throws IOException {
void roundTripMulti() throws IOException {

String templateId = "ehrbase_multi_occurrence.de.v1";
CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.MULTI_OCCURRENCE;
Expand All @@ -330,7 +329,7 @@ public void roundTripMulti() throws IOException {
}

@Test
public void roundTripMissingCount() throws IOException {
void roundTripMissingCount() throws IOException {
String templateId = "ehrbase_multi_occurrence.de.v1";
CompositionTestDataSimSDTJson testData = CompositionTestDataSimSDTJson.MISSING_COUNT;

Expand Down Expand Up @@ -385,7 +384,7 @@ private void check(

String expected = IOUtils.toString(testData.getStream(), StandardCharsets.UTF_8);

List<String> errors = FlatJsonMarshallerTest.compere(actual, expected);
List<String> errors = FlatTestHelper.compere(actual, expected);

softAssertions
.assertThat(errors)
Expand Down
Loading

0 comments on commit 83e6b5f

Please sign in to comment.