From 1c27726055fc2bd7837efcd4e26a1189f83830b9 Mon Sep 17 00:00:00 2001 From: christian ohr Date: Tue, 21 Jul 2020 11:36:25 +0200 Subject: [PATCH] #1817: fix problem with missing resource references when extensions are used (#1848) Co-authored-by: Christian Ohr --- .../java/ca/uhn/fhir/parser/ParserState.java | 10 ++++ .../ca/uhn/fhir/parser/ExtendedPatient.java | 31 ++++++++++ .../uhn/fhir/parser/ExtendedPatientTest.java | 56 +++++++++++++++++++ .../ca/uhn/fhir/parser/ExtendedPatient.java | 31 ++++++++++ .../uhn/fhir/parser/ExtendedPatientTest.java | 56 +++++++++++++++++++ 5 files changed, 184 insertions(+) create mode 100644 hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/ExtendedPatient.java create mode 100644 hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/ExtendedPatientTest.java create mode 100644 hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/ExtendedPatient.java create mode 100644 hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/ExtendedPatientTest.java diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java index cdd8149997c..99af71de317 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java @@ -1067,9 +1067,19 @@ class ParserState { * At some point it would be good to write code which can present a view * of one type backed by another type and use that. */ + FhirTerser t = myContext.newTerser(); + + // Clean up the cached resources + myGlobalResources.remove(myInstance); + myGlobalReferences.removeAll(t.getAllPopulatedChildElementsOfType(myInstance, IBaseReference.class)); + IParser parser = myContext.newJsonParser(); String asString = parser.encodeResourceToString(myInstance); myInstance = parser.parseResource(wantedProfileType, asString); + + // Add newly created instance + myGlobalResources.add(myInstance); + myGlobalReferences.addAll(t.getAllPopulatedChildElementsOfType(myInstance, IBaseReference.class)); } } } diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/ExtendedPatient.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/ExtendedPatient.java new file mode 100644 index 00000000000..dad8b9f769e --- /dev/null +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/ExtendedPatient.java @@ -0,0 +1,31 @@ +package ca.uhn.fhir.parser; + +import ca.uhn.fhir.model.api.annotation.Child; +import ca.uhn.fhir.model.api.annotation.Extension; +import ca.uhn.fhir.model.api.annotation.ResourceDef; +import org.hl7.fhir.dstu3.model.CodeType; +import org.hl7.fhir.dstu3.model.Patient; + + +@ResourceDef( + name = "Patient", + profile = "http://acme.org//StructureDefinition/patient-with-eyes" +) +public class ExtendedPatient extends Patient { + + @Child(name = "eyeColour") + @Extension(url = "http://acme.org/#extpt", definedLocally = false, isModifier = false) + private CodeType myEyeColour; + + public CodeType getEyeColour() { + if (myEyeColour == null) { + myEyeColour = new CodeType(); + } + return myEyeColour; + } + + public void setEyeColour(CodeType theEyeColour) { + myEyeColour = theEyeColour; + } + +} diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/ExtendedPatientTest.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/ExtendedPatientTest.java new file mode 100644 index 00000000000..844b9599183 --- /dev/null +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/ExtendedPatientTest.java @@ -0,0 +1,56 @@ +package ca.uhn.fhir.parser; + +import ca.uhn.fhir.context.FhirContext; +import org.hl7.fhir.dstu3.model.Bundle; +import org.hl7.fhir.dstu3.model.CodeType; +import org.hl7.fhir.dstu3.model.Patient; +import org.hl7.fhir.dstu3.model.Reference; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; + +public class ExtendedPatientTest { + + @Test + public void testBundleReferences() { + + FhirContext fhirContext = FhirContext.forDstu3(); + fhirContext.setDefaultTypeForProfile("http://acme.org//StructureDefinition/patient-with-eyes", ExtendedPatient.class); + + ExtendedPatient homer = new ExtendedPatient(); + homer.setId("homer"); + homer.addName().setFamily("Simpson").addGiven("Homer"); + + ExtendedPatient marge = new ExtendedPatient(); + marge.setId("marge"); + marge.addName().setFamily("Simpson").addGiven("Marge"); + marge.setEyeColour(new CodeType("blue")); + marge.getLink().add(new Patient.PatientLinkComponent() + .setType(Patient.LinkType.REFER) + .setOther(new Reference("Patient/homer"))); + + Bundle bundle = new Bundle() + .addEntry(new Bundle.BundleEntryComponent() + .setFullUrl("http://acme.org/Patient/homer").setResource(homer) + .setSearch(new Bundle.BundleEntrySearchComponent() + .setMode(Bundle.SearchEntryMode.INCLUDE))) + .addEntry(new Bundle.BundleEntryComponent() + .setFullUrl("http://acme.org/Patient/marge").setResource(marge) + .setSearch(new Bundle.BundleEntrySearchComponent())); + + IParser p = fhirContext.newXmlParser().setPrettyPrint(true); + String encoded = p.encodeResourceToString(bundle); + + Bundle parsedBundle = p.parseResource(Bundle.class, encoded); + + ExtendedPatient parsedHomer = (ExtendedPatient)parsedBundle.getEntry().get(0).getResource(); + ExtendedPatient parsedMarge = (ExtendedPatient)parsedBundle.getEntry().get(1).getResource(); + + IBaseResource referencedHomer = parsedMarge.getLinkFirstRep().getOther().getResource(); + assertNotNull(referencedHomer); + assertSame(parsedHomer, referencedHomer); + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/ExtendedPatient.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/ExtendedPatient.java new file mode 100644 index 00000000000..1bdfae234f7 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/ExtendedPatient.java @@ -0,0 +1,31 @@ +package ca.uhn.fhir.parser; + +import ca.uhn.fhir.model.api.annotation.Child; +import ca.uhn.fhir.model.api.annotation.Extension; +import ca.uhn.fhir.model.api.annotation.ResourceDef; +import org.hl7.fhir.r4.model.CodeType; +import org.hl7.fhir.r4.model.Patient; + + +@ResourceDef( + name = "Patient", + profile = "http://acme.org//StructureDefinition/patient-with-eyes" +) +public class ExtendedPatient extends Patient { + + @Child(name = "eyeColour") + @Extension(url = "http://acme.org/#extpt", definedLocally = false, isModifier = false) + private CodeType myEyeColour; + + public CodeType getEyeColour() { + if (myEyeColour == null) { + myEyeColour = new CodeType(); + } + return myEyeColour; + } + + public void setEyeColour(CodeType theEyeColour) { + myEyeColour = theEyeColour; + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/ExtendedPatientTest.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/ExtendedPatientTest.java new file mode 100644 index 00000000000..0f0c42e795e --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/ExtendedPatientTest.java @@ -0,0 +1,56 @@ +package ca.uhn.fhir.parser; + +import ca.uhn.fhir.context.FhirContext; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.CodeType; +import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.Reference; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; + +public class ExtendedPatientTest { + + @Test + public void testBundleReferences() { + + FhirContext fhirContext = FhirContext.forR4(); + fhirContext.setDefaultTypeForProfile("http://acme.org//StructureDefinition/patient-with-eyes", ExtendedPatient.class); + + ExtendedPatient homer = new ExtendedPatient(); + homer.setId("homer"); + homer.addName().setFamily("Simpson").addGiven("Homer"); + + ExtendedPatient marge = new ExtendedPatient(); + marge.setId("marge"); + marge.addName().setFamily("Simpson").addGiven("Marge"); + marge.setEyeColour(new CodeType("blue")); + marge.getLink().add(new Patient.PatientLinkComponent() + .setType(Patient.LinkType.REFER) + .setOther(new Reference("Patient/homer"))); + + Bundle bundle = new Bundle() + .addEntry(new Bundle.BundleEntryComponent() + .setFullUrl("http://acme.org/Patient/homer").setResource(homer) + .setSearch(new Bundle.BundleEntrySearchComponent() + .setMode(Bundle.SearchEntryMode.INCLUDE))) + .addEntry(new Bundle.BundleEntryComponent() + .setFullUrl("http://acme.org/Patient/marge").setResource(marge) + .setSearch(new Bundle.BundleEntrySearchComponent())); + + IParser p = fhirContext.newXmlParser().setPrettyPrint(true); + String encoded = p.encodeResourceToString(bundle); + + Bundle parsedBundle = p.parseResource(Bundle.class, encoded); + + ExtendedPatient parsedHomer = (ExtendedPatient)parsedBundle.getEntry().get(0).getResource(); + ExtendedPatient parsedMarge = (ExtendedPatient)parsedBundle.getEntry().get(1).getResource(); + + IBaseResource referencedHomer = parsedMarge.getLinkFirstRep().getOther().getResource(); + assertNotNull(referencedHomer); + assertSame(parsedHomer, referencedHomer); + } + +}