mirror of
https://github.com/hapifhir/hapi-fhir.git
synced 2025-02-20 11:55:17 +00:00
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 (BaseRuntimeChildDefinition nextChild : children)
|
||||||
for (IBase nextValue : nextChild.getAccessor().getValues(theSource)) {
|
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);
|
BaseRuntimeChildDefinition targetChild = targetDef.getChildByName(elementName);
|
||||||
if (targetChild == null) {
|
if (targetChild == null) {
|
||||||
if (theIgnoreMissingFields) {
|
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);
|
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();
|
Object instanceConstructorArg = targetChild.getInstanceConstructorArguments();
|
||||||
IBase target;
|
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);
|
target = element.newInstance(instanceConstructorArg);
|
||||||
} else {
|
} else {
|
||||||
target = element.newInstance();
|
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.IBase;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseExtension;
|
import org.hl7.fhir.instance.model.api.IBaseExtension;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseReference;
|
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.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
@ -30,6 +33,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
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.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
@ -41,7 +45,8 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
public class FhirTerserDstu2Test {
|
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
|
@Test
|
||||||
public void testCloneIntoComposite() {
|
public void testCloneIntoComposite() {
|
||||||
@ -54,6 +59,27 @@ public class FhirTerserDstu2Test {
|
|||||||
assertEquals("CODE", target.getCode());
|
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
|
@Test
|
||||||
public void testCloneIntoCompositeMismatchedFields() {
|
public void testCloneIntoCompositeMismatchedFields() {
|
||||||
QuantityDt source = new QuantityDt();
|
QuantityDt source = new QuantityDt();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user