Merge pull request #2668 from hapifhir/2667_terserutil_merge_empty_fields
Fixed primitive field merging
This commit is contained in:
commit
cc734613a8
|
@ -28,9 +28,12 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.apache.commons.lang3.tuple.Triple;
|
import org.apache.commons.lang3.tuple.Triple;
|
||||||
import org.hl7.fhir.instance.model.api.IBase;
|
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.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
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) {
|
public static void replaceFieldsByPredicate(FhirContext theFhirContext, IBaseResource theFrom, IBaseResource theTo, Predicate<Triple<BaseRuntimeChildDefinition, IBase, IBase>> thePredicate) {
|
||||||
RuntimeResourceDefinition definition = theFhirContext.getResourceDefinition(theFrom);
|
RuntimeResourceDefinition definition = theFhirContext.getResourceDefinition(theFrom);
|
||||||
|
FhirTerser terser = theFhirContext.newTerser();
|
||||||
for (BaseRuntimeChildDefinition childDefinition : definition.getChildrenAndExtension()) {
|
for (BaseRuntimeChildDefinition childDefinition : definition.getChildrenAndExtension()) {
|
||||||
if (thePredicate.test(Triple.of(childDefinition, theFrom, theTo))) {
|
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) {
|
public static void replaceField(FhirContext theFhirContext, String theFieldName, IBaseResource theFrom, IBaseResource theTo) {
|
||||||
RuntimeResourceDefinition definition = theFhirContext.getResourceDefinition(theFrom);
|
RuntimeResourceDefinition definition = theFhirContext.getResourceDefinition(theFrom);
|
||||||
Validate.notNull(definition);
|
Validate.notNull(definition);
|
||||||
replaceField(theFrom, theTo, theFhirContext.getResourceDefinition(theFrom).getChildByName(theFieldName));
|
replaceField(theFhirContext.newTerser(), theFrom, theTo, theFhirContext.getResourceDefinition(theFrom).getChildByName(theFieldName));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -325,7 +329,7 @@ public final class TerserUtil {
|
||||||
*/
|
*/
|
||||||
public static void clearField(FhirContext theFhirContext, String theFieldName, IBaseResource theResource) {
|
public static void clearField(FhirContext theFhirContext, String theFieldName, IBaseResource theResource) {
|
||||||
BaseRuntimeChildDefinition childDefinition = getBaseRuntimeChildDefinition(theFhirContext, theFieldName, theResource);
|
BaseRuntimeChildDefinition childDefinition = getBaseRuntimeChildDefinition(theFhirContext, theFieldName, theResource);
|
||||||
childDefinition.getAccessor().getValues(theResource).clear();
|
clear(childDefinition.getAccessor().getValues(theResource));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -339,7 +343,7 @@ public final class TerserUtil {
|
||||||
BaseRuntimeElementDefinition definition = theFhirContext.getElementDefinition(theBase.getClass());
|
BaseRuntimeElementDefinition definition = theFhirContext.getElementDefinition(theBase.getClass());
|
||||||
BaseRuntimeChildDefinition childDefinition = definition.getChildByName(theFieldName);
|
BaseRuntimeChildDefinition childDefinition = definition.getChildByName(theFieldName);
|
||||||
Validate.notNull(childDefinition);
|
Validate.notNull(childDefinition);
|
||||||
childDefinition.getAccessor().getValues(theBase).clear();
|
clear(childDefinition.getAccessor().getValues(theBase));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -441,11 +445,12 @@ public final class TerserUtil {
|
||||||
return values.get(0);
|
return values.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void replaceField(IBaseResource theFrom, IBaseResource theTo, BaseRuntimeChildDefinition childDefinition) {
|
private static void replaceField(FhirTerser theTerser, IBaseResource theFrom, IBaseResource theTo, BaseRuntimeChildDefinition childDefinition) {
|
||||||
childDefinition.getAccessor().getFirstValueOrNull(theFrom).ifPresent(v -> {
|
List<IBase> fromValues = childDefinition.getAccessor().getValues(theFrom);
|
||||||
childDefinition.getMutator().setValue(theTo, v);
|
List<IBase> toValues = childDefinition.getAccessor().getValues(theTo);
|
||||||
}
|
clear(toValues);
|
||||||
);
|
|
||||||
|
mergeFields(theTerser, theTo, childDefinition, fromValues, toValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -532,13 +537,24 @@ public final class TerserUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
IBase newFieldValue = childDefinition.getChildByName(childDefinition.getElementName()).newInstance();
|
IBase newFieldValue = childDefinition.getChildByName(childDefinition.getElementName()).newInstance();
|
||||||
theTerser.cloneInto(theFromFieldValue, newFieldValue, true);
|
if (theFromFieldValue instanceof IPrimitiveType) {
|
||||||
|
try {
|
||||||
|
Method copyMethod = getMethod(theFromFieldValue, "copy");
|
||||||
|
if (copyMethod != null) {
|
||||||
|
newFieldValue = (IBase) copyMethod.invoke(theFromFieldValue, new Object[]{});
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
((IPrimitiveType) newFieldValue).setValueAsString(((IPrimitiveType) theFromFieldValue).getValueAsString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
theTerser.cloneInto(theFromFieldValue, newFieldValue, true);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
theToFieldValues.add(newFieldValue);
|
theToFieldValues.add(newFieldValue);
|
||||||
} catch (UnsupportedOperationException e) {
|
} catch (UnsupportedOperationException e) {
|
||||||
childDefinition.getMutator().setValue(theTo, newFieldValue);
|
childDefinition.getMutator().setValue(theTo, newFieldValue);
|
||||||
break;
|
theToFieldValues = childDefinition.getAccessor().getValues(theTo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -615,4 +631,16 @@ public final class TerserUtil {
|
||||||
return (T) def.newInstance(theConstructorParam);
|
return (T) def.newInstance(theConstructorParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void clear(List<IBase> values) {
|
||||||
|
if (values == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
values.clear();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
ourLog.debug("Unable to clear values " + String.valueOf(values), t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,38 @@ class TerserUtilTest {
|
||||||
assertEquals(p1.getName().get(0).getNameAsSingleString(), p2.getName().get(0).getNameAsSingleString());
|
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
|
@Test
|
||||||
void testCloneWithNonPrimitves() {
|
void testCloneWithNonPrimitves() {
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
|
@ -314,6 +346,7 @@ class TerserUtilTest {
|
||||||
// expect p2 to have "Doe" and MALE after replace
|
// expect p2 to have "Doe" and MALE after replace
|
||||||
assertEquals(1, p2.getName().size());
|
assertEquals(1, p2.getName().size());
|
||||||
assertEquals("Doe", p2.getName().get(0).getFamily());
|
assertEquals("Doe", p2.getName().get(0).getFamily());
|
||||||
|
|
||||||
assertEquals(Enumerations.AdministrativeGender.MALE, p2.getGender());
|
assertEquals(Enumerations.AdministrativeGender.MALE, p2.getGender());
|
||||||
assertEquals(dob, p2.getBirthDate());
|
assertEquals(dob, p2.getBirthDate());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue