Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

5738: Skip alternate handling if already handled by previous step #5971

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -1359,9 +1359,17 @@ private void parseChildren(BaseJsonLikeObject theObject, ParserState<?> theState
String alternateName = keyIter.next();
if (alternateName.startsWith("_") && alternateName.length() > 1) {
BaseJsonLikeValue nextValue = theObject.get(alternateName);
String nextName = alternateName.substring(1);

if (nextValue != null) {
BaseJsonLikeValue nonAlternativeValue = theObject.get(nextName);

// Only alternate values with no corresponding "normal" value is unhandled from previous step.
if (nonAlternativeValue != null) {
continue;
}

if (nextValue.isObject()) {
String nextName = alternateName.substring(1);
if (theObject.get(nextName) == null) {
theState.enteringNewElement(null, nextName);
parseAlternates(nextValue, theState, alternateName, alternateName);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
type: fix
issue: 5971
title: "The JSON Parser failed to parse alternate names (e.g. `_family`) containing extensions if the
corresponding regular named element (e.g. `family`) was not present. Thanks to Stefan Lindström for
the pull request!"
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.hl7.fhir.dstu2016may.model.Observation.ObservationStatus;
import org.hl7.fhir.dstu2016may.model.Parameters;
import org.hl7.fhir.dstu2016may.model.Patient;
import org.hl7.fhir.dstu2016may.model.Practitioner;
import org.hl7.fhir.dstu2016may.model.PrimitiveType;
import org.hl7.fhir.dstu2016may.model.Quantity;
import org.hl7.fhir.dstu2016may.model.QuestionnaireResponse;
Expand All @@ -55,6 +56,7 @@
import org.hl7.fhir.dstu2016may.model.StringType;
import org.hl7.fhir.dstu2016may.model.UriType;
import org.hl7.fhir.dstu2016may.model.ValueSet;
import org.hl7.fhir.dstu2016may.model.codesystems.DataAbsentReason;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
Expand All @@ -63,7 +65,6 @@
import org.mockito.ArgumentCaptor;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand All @@ -78,6 +79,7 @@
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
Expand Down Expand Up @@ -1901,6 +1903,40 @@ public void testPreCommentsToFhirComments() {
assertEquals(expectedJson, patientString);
}

@Test
public void testObjectWithBothPrimitiverAndArrayAlternatives() {
String resource = "{\n" +
" \"resourceType\": \"Practitioner\",\n" +
" \"id\": \"1\",\n" +
" \"name\": [{\n" +
" \"_family\": {\n" +
" \"extension\": [{\n" +
" \"url\": \"http:https://hl7.org/fhir/StructureDefinition/data-absent-reason\",\n" +
" \"valueString\": \"masked\"\n" +
" }\n" +
" ]\n" +
" },\n" +
" \"given\": [\n" +
" null\n" +
" ],\n" +
" \"_given\": [{\n" +
" \"extension\": [{\n" +
" \"url\": \"http:https://hl7.org/fhir/StructureDefinition/data-absent-reason\",\n" +
" \"valueString\": \"masked\"\n" +
" }\n" +
" ]\n" +
" }\n" +
" ]\n" +
" }\n" +
" ]\n" +
"}\n";
Practitioner practitioner = assertDoesNotThrow(() -> ourCtx.newJsonParser().parseResource(Practitioner.class, resource));
HumanName humanName = practitioner.getName().get(0);
StringType given = humanName.getGiven().get(0);
assertTrue(given.getExtension().stream().allMatch(ext -> DataAbsentReason.MASKED.toCode().equals(ext.getValue().primitiveValue())));
assertTrue(humanName.getFamily().get(0).getExtension().stream().allMatch(ext -> DataAbsentReason.MASKED.toCode().equals(ext.getValue().primitiveValue())));
}

@AfterAll
public static void afterClassClearContext() {
TestUtil.randomizeLocaleAndTimezone();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import org.hl7.fhir.dstu3.model.Organization;
import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.dstu3.model.Practitioner;
import org.hl7.fhir.dstu3.model.PrimitiveType;
import org.hl7.fhir.dstu3.model.Quantity;
import org.hl7.fhir.dstu3.model.QuestionnaireResponse;
Expand All @@ -74,6 +75,7 @@
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.UriType;
import org.hl7.fhir.dstu3.model.ValueSet;
import org.hl7.fhir.dstu3.model.codesystems.DataAbsentReason;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
Expand Down Expand Up @@ -101,6 +103,7 @@
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
Expand Down Expand Up @@ -2548,6 +2551,41 @@ public void testPreCommentsToFhirComments() {
assertThat(patientString, is(not(containsString("fhir_comment"))));
}

@Test
public void testObjectWithBothPrimitiverAndArrayAlternatives() {
String resource = "{\n" +
" \"resourceType\": \"Practitioner\",\n" +
" \"id\": \"1\",\n" +
" \"name\": [{\n" +
" \"_family\": {\n" +
" \"extension\": [{\n" +
" \"url\": \"http:https://hl7.org/fhir/StructureDefinition/data-absent-reason\",\n" +
" \"valueString\": \"masked\"\n" +
" }\n" +
" ]\n" +
" },\n" +
" \"given\": [\n" +
" null\n" +
" ],\n" +
" \"_given\": [{\n" +
" \"extension\": [{\n" +
" \"url\": \"http:https://hl7.org/fhir/StructureDefinition/data-absent-reason\",\n" +
" \"valueString\": \"masked\"\n" +
" }\n" +
" ]\n" +
" }\n" +
" ]\n" +
" }\n" +
" ]\n" +
"}\n";
Practitioner practitioner = assertDoesNotThrow(() -> ourCtx.newJsonParser().parseResource(Practitioner.class, resource));
HumanName humanName = practitioner.getName().get(0);
StringType given = humanName.getGiven().get(0);
assertTrue(given.getExtension().stream().allMatch(ext -> DataAbsentReason.MASKED.toCode().equals(ext.getValue().primitiveValue())));
assertTrue(humanName.getFamilyElement().getExtension().stream().allMatch(ext -> DataAbsentReason.MASKED.toCode().equals(ext.getValue().primitiveValue())));
}


@AfterAll
public static void afterClassClearContext() {
TestUtil.randomizeLocaleAndTimezone();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.Type;
import org.hl7.fhir.r4.model.codesystems.DataAbsentReason;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
Expand Down Expand Up @@ -73,6 +74,7 @@
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.hamcrest.core.IsNot.not;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
Expand Down Expand Up @@ -1190,6 +1192,40 @@ public void testEncodeToString_Resource() {
assertEquals(expected, actual);
}

@Test
public void testObjectWithBothPrimitiverAndArrayAlternatives() {
String resource = "{\n" +
" \"resourceType\": \"Practitioner\",\n" +
" \"id\": \"1\",\n" +
" \"name\": [{\n" +
" \"_family\": {\n" +
" \"extension\": [{\n" +
" \"url\": \"http:https://hl7.org/fhir/StructureDefinition/data-absent-reason\",\n" +
" \"valueString\": \"masked\"\n" +
" }\n" +
" ]\n" +
" },\n" +
" \"given\": [\n" +
" null\n" +
" ],\n" +
" \"_given\": [{\n" +
" \"extension\": [{\n" +
" \"url\": \"http:https://hl7.org/fhir/StructureDefinition/data-absent-reason\",\n" +
" \"valueString\": \"masked\"\n" +
" }\n" +
" ]\n" +
" }\n" +
" ]\n" +
" }\n" +
" ]\n" +
"}\n";
Practitioner practitioner = assertDoesNotThrow(() -> ourCtx.newJsonParser().parseResource(Practitioner.class, resource));
HumanName humanName = practitioner.getNameFirstRep();
StringType given = humanName.getGiven().get(0);
assertTrue(given.getExtension().stream().allMatch(ext -> DataAbsentReason.MASKED.toCode().equals(ext.getValue().primitiveValue())));
assertTrue(humanName.getFamilyElement().getExtension().stream().allMatch(ext -> DataAbsentReason.MASKED.toCode().equals(ext.getValue().primitiveValue())));
}

@Test
public void testEncodeToString_GeneralPurposeDataType() {
HumanName name = new HumanName();
Expand Down
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,11 @@
<id>subigre</id>
<name>Renaud Subiger</name>
</developer>
<developer>
<id>stefan-lindstrom</id>
<name>Stefan Lindström</name>
<organization>Softhouse AB</organization>
</developer>
</developers>

<licenses>
Expand Down
Loading