1
0
mirror of https://github.com/hapifhir/hapi-fhir.git synced 2025-03-28 10:58:47 +00:00

Fixed primitive field merging

This commit is contained in:
Nick Goupinets 2021-05-20 15:48:00 -04:00
parent e359b6d823
commit 8a7fc58e91
2 changed files with 59 additions and 9 deletions
hapi-fhir-base/src/main/java/ca/uhn/fhir/util
hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/util

@ -28,9 +28,12 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.tuple.Triple;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseEnumeration;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.slf4j.Logger;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
@ -283,9 +286,10 @@ public final class TerserUtil {
*/
public static void replaceFieldsByPredicate(FhirContext theFhirContext, IBaseResource theFrom, IBaseResource theTo, Predicate<Triple<BaseRuntimeChildDefinition, IBase, IBase>> thePredicate) {
RuntimeResourceDefinition definition = theFhirContext.getResourceDefinition(theFrom);
FhirTerser terser = theFhirContext.newTerser();
for (BaseRuntimeChildDefinition childDefinition : definition.getChildrenAndExtension()) {
if (thePredicate.test(Triple.of(childDefinition, theFrom, theTo))) {
replaceField(theFrom, theTo, childDefinition);
replaceField(terser, theFrom, theTo, childDefinition);
}
}
}
@ -313,7 +317,7 @@ public final class TerserUtil {
public static void replaceField(FhirContext theFhirContext, String theFieldName, IBaseResource theFrom, IBaseResource theTo) {
RuntimeResourceDefinition definition = theFhirContext.getResourceDefinition(theFrom);
Validate.notNull(definition);
replaceField(theFrom, theTo, theFhirContext.getResourceDefinition(theFrom).getChildByName(theFieldName));
replaceField(theFhirContext.newTerser(), theFrom, theTo, theFhirContext.getResourceDefinition(theFrom).getChildByName(theFieldName));
}
/**
@ -441,11 +445,12 @@ public final class TerserUtil {
return values.get(0);
}
private static void replaceField(IBaseResource theFrom, IBaseResource theTo, BaseRuntimeChildDefinition childDefinition) {
childDefinition.getAccessor().getFirstValueOrNull(theFrom).ifPresent(v -> {
childDefinition.getMutator().setValue(theTo, v);
}
);
private static void replaceField(FhirTerser theTerser, IBaseResource theFrom, IBaseResource theTo, BaseRuntimeChildDefinition childDefinition) {
List<IBase> fromValues = childDefinition.getAccessor().getValues(theFrom);
List<IBase> toValues = childDefinition.getAccessor().getValues(theTo);
toValues.clear();
mergeFields(theTerser, theTo, childDefinition, fromValues, toValues);
}
/**
@ -532,13 +537,24 @@ public final class TerserUtil {
}
IBase newFieldValue = childDefinition.getChildByName(childDefinition.getElementName()).newInstance();
theTerser.cloneInto(theFromFieldValue, newFieldValue, true);
if (theFromFieldValue instanceof IPrimitiveType) {
Method copyMethod = getMethod(theFromFieldValue, "copy");
if (copyMethod != null) {
try {
newFieldValue = (IBase) copyMethod.invoke(theFromFieldValue, new Object[]{});
} catch (Throwable t) {
((IPrimitiveType) newFieldValue).setValueAsString(((IPrimitiveType) theFromFieldValue).getValueAsString());
}
}
} else {
theTerser.cloneInto(theFromFieldValue, newFieldValue, true);
}
try {
theToFieldValues.add(newFieldValue);
} catch (UnsupportedOperationException e) {
childDefinition.getMutator().setValue(theTo, newFieldValue);
break;
theToFieldValues = childDefinition.getAccessor().getValues(theTo);
}
}
}

@ -103,6 +103,38 @@ class TerserUtilTest {
assertEquals(p1.getName().get(0).getNameAsSingleString(), p2.getName().get(0).getNameAsSingleString());
}
@Test
void testCloneIdentifiers() {
Patient p1 = new Patient();
p1.addIdentifier(new Identifier().setSystem("uri:mi").setValue("123456"));
p1.addIdentifier(new Identifier().setSystem("uri:mdi").setValue("287351247K"));
p1.addIdentifier(new Identifier().setSystem("uri:cdns").setValue("654841918"));
p1.addIdentifier(new Identifier().setSystem("uri:ssn").setValue("855191882"));
p1.addName().setFamily("Sat").addGiven("Joe");
Patient p2 = new Patient();
TerserUtil.mergeField(ourFhirContext, ourFhirContext.newTerser(), "identifier", p1, p2);
assertEquals(4, p2.getIdentifier().size());
assertTrue(p2.getName().isEmpty());
}
@Test
void testReplaceIdentifiers() {
Patient p1 = new Patient();
p1.addIdentifier(new Identifier().setSystem("uri:mi").setValue("123456"));
p1.addIdentifier(new Identifier().setSystem("uri:mdi").setValue("287351247K"));
p1.addIdentifier(new Identifier().setSystem("uri:cdns").setValue("654841918"));
p1.addIdentifier(new Identifier().setSystem("uri:ssn").setValue("855191882"));
p1.addName().setFamily("Sat").addGiven("Joe");
Patient p2 = new Patient();
TerserUtil.replaceField(ourFhirContext, "identifier", p1, p2);
assertEquals(4, p2.getIdentifier().size());
assertTrue(p2.getName().isEmpty());
}
@Test
void testCloneWithNonPrimitves() {
Patient p1 = new Patient();
@ -314,6 +346,8 @@ class TerserUtilTest {
// expect p2 to have "Doe" and MALE after replace
assertEquals(1, p2.getName().size());
assertEquals("Doe", p2.getName().get(0).getFamily());
System.out.println(p2.getGender());
assertEquals(Enumerations.AdministrativeGender.MALE, p2.getGender());
assertEquals(dob, p2.getBirthDate());
}