Terser cloneInto doesn't work for contained resources (#4467)
* Add fix * Add docs
This commit is contained in:
parent
69f64269cf
commit
8c287f0269
|
@ -197,7 +197,8 @@ public class FhirTerser {
|
|||
|
||||
for (BaseRuntimeChildDefinition nextChild : children)
|
||||
for (IBase nextValue : nextChild.getAccessor().getValues(theSource)) {
|
||||
String elementName = nextChild.getChildNameByDatatype(nextValue.getClass());
|
||||
Class<? extends IBase> valueType = nextValue.getClass();
|
||||
String elementName = nextChild.getChildNameByDatatype(valueType);
|
||||
BaseRuntimeChildDefinition targetChild = targetDef.getChildByName(elementName);
|
||||
if (targetChild == null) {
|
||||
if (theIgnoreMissingFields) {
|
||||
|
@ -206,10 +207,24 @@ public class FhirTerser {
|
|||
throw new DataFormatException(Msg.code(1789) + "Type " + theTarget.getClass().getName() + " does not have a child with name " + elementName);
|
||||
}
|
||||
|
||||
BaseRuntimeElementDefinition<?> element = myContext.getElementDefinition(nextValue.getClass());
|
||||
BaseRuntimeElementDefinition<?> element = myContext.getElementDefinition(valueType);
|
||||
Object instanceConstructorArg = targetChild.getInstanceConstructorArguments();
|
||||
IBase target;
|
||||
if (instanceConstructorArg != null) {
|
||||
if (element == null && BaseContainedDt.class.isAssignableFrom(valueType)) {
|
||||
/*
|
||||
* This is a hack for DSTU2 - The way we did contained resources in
|
||||
* the DSTU2 model was weird, since the element isn't actually a FHIR type.
|
||||
* This is fixed in DSTU3+ so this hack only applies there.
|
||||
*/
|
||||
BaseContainedDt containedTarget = (BaseContainedDt) ReflectionUtil.newInstance(valueType);
|
||||
BaseContainedDt containedSource = (BaseContainedDt) nextValue;
|
||||
for (IResource next : containedSource.getContainedResources()) {
|
||||
List containedResources = containedTarget.getContainedResources();
|
||||
containedResources.add(next);
|
||||
}
|
||||
targetChild.getMutator().addValue(theTarget, containedTarget);
|
||||
continue;
|
||||
} else if (instanceConstructorArg != null) {
|
||||
target = element.newInstance(instanceConstructorArg);
|
||||
} else {
|
||||
target = element.newInstance();
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
type: fix
|
||||
issue: 4467
|
||||
title: "The FhirTerser#clone method failed to clone resources when contained resources were
|
||||
present in the source resource. This has been fixed."
|
|
@ -19,10 +19,13 @@ import ca.uhn.fhir.parser.DataFormatException;
|
|||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
import org.hl7.fhir.instance.model.api.IBaseExtension;
|
||||
import org.hl7.fhir.instance.model.api.IBaseReference;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
@ -30,6 +33,7 @@ import java.util.List;
|
|||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
@ -41,7 +45,8 @@ import static org.mockito.Mockito.when;
|
|||
|
||||
public class FhirTerserDstu2Test {
|
||||
|
||||
private static FhirContext ourCtx = FhirContext.forDstu2();
|
||||
private static FhirContext ourCtx = FhirContext.forDstu2Cached();
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(FhirTerserDstu2Test.class);
|
||||
|
||||
@Test
|
||||
public void testCloneIntoComposite() {
|
||||
|
@ -54,6 +59,27 @@ public class FhirTerserDstu2Test {
|
|||
assertEquals("CODE", target.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloneResource() {
|
||||
Organization org = new Organization();
|
||||
org.setName("Contained Org Name");
|
||||
Patient patient = new Patient();
|
||||
patient.setActive(true);
|
||||
patient.getManagingOrganization().setResource(org);
|
||||
|
||||
// Re-encode
|
||||
String string = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||
ourLog.info("Encoded: {}", string);
|
||||
patient = ourCtx.newJsonParser().parseResource(Patient.class, string);
|
||||
|
||||
Patient clonedPatient = ourCtx.newTerser().clone(patient);
|
||||
assertEquals(true, clonedPatient.getActive().booleanValue());
|
||||
string = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(clonedPatient);
|
||||
ourLog.info("Encoded: {}", string);
|
||||
assertThat(string, containsString("\"contained\""));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCloneIntoCompositeMismatchedFields() {
|
||||
QuantityDt source = new QuantityDt();
|
||||
|
|
Loading…
Reference in New Issue