From 6cc40b134e24735df398660097d134cd802f60e9 Mon Sep 17 00:00:00 2001 From: Nick Date: Thu, 14 Jan 2021 20:35:09 -0500 Subject: [PATCH] Pre-review commit --- .../docs/server_jpa_mdm/mdm_operations.md | 9 ---- .../mdm/svc/GoldenResourceMergerSvcImpl.java | 31 +++++++---- .../jpa/mdm/svc/MdmLinkUpdaterSvcImpl.java | 7 ++- .../jpa/mdm/svc/MdmSurvivorshipSvcImpl.java | 2 + ...MdmProviderMergeGoldenResourcesR4Test.java | 10 ++-- .../provider/MdmProviderUpdateLinkR4Test.java | 51 ++++++------------- .../mdm/provider/MdmProviderDstu3Plus.java | 3 +- .../fhir/mdm/util/GoldenResourceHelper.java | 4 ++ .../java/ca/uhn/fhir/mdm/util/TerserUtil.java | 26 ++++++++++ 9 files changed, 78 insertions(+), 65 deletions(-) diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_mdm/mdm_operations.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_mdm/mdm_operations.md index 32819da2999..06f3d7fa417 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_mdm/mdm_operations.md +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_mdm/mdm_operations.md @@ -251,15 +251,6 @@ Use the `$mdm-update-link` operation to change the `matchResult` update of an md Must be either MATCH or NO_MATCH. - - resource - Resource - 0.1 - - Optional manually merged Golden Resource. All values except for the metadata, PID and identifiers will be copied from this resource, if it is present. If no value is specified, all fields from the resource pointed to by "resourceId" will be copied instead. - . - - diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/GoldenResourceMergerSvcImpl.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/GoldenResourceMergerSvcImpl.java index 1c008f1caf1..fae7c2da3d1 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/GoldenResourceMergerSvcImpl.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/GoldenResourceMergerSvcImpl.java @@ -20,17 +20,18 @@ package ca.uhn.fhir.jpa.mdm.svc; * #L% */ +import ca.uhn.fhir.jpa.dao.index.IdHelperService; +import ca.uhn.fhir.jpa.entity.MdmLink; +import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc; +import ca.uhn.fhir.mdm.api.IGoldenResourceMergerSvc; +import ca.uhn.fhir.mdm.api.IMdmLinkSvc; import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; -import ca.uhn.fhir.mdm.api.IMdmLinkSvc; -import ca.uhn.fhir.mdm.api.IGoldenResourceMergerSvc; import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.mdm.util.GoldenResourceHelper; -import ca.uhn.fhir.jpa.dao.index.IdHelperService; -import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc; -import ca.uhn.fhir.jpa.entity.MdmLink; import ca.uhn.fhir.mdm.util.MdmResourceUtil; +import ca.uhn.fhir.mdm.util.TerserUtil; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import org.hl7.fhir.instance.model.api.IAnyResource; import org.slf4j.Logger; @@ -65,16 +66,24 @@ public class GoldenResourceMergerSvcImpl implements IGoldenResourceMergerSvc { Long toGoldenResourcePid = myIdHelperService.getPidOrThrowException(theToGoldenResource); String resourceType = theMdmTransactionContext.getResourceType(); - // Merge attributes, to be determined when survivorship is solved. - myGoldenResourceHelper.mergeIndentifierFields(theFromGoldenResource, theToGoldenResource, theMdmTransactionContext); + if (theMergedResource != null ) { + if (myGoldenResourceHelper.hasIdentifier(theMergedResource)) { + throw new IllegalArgumentException("Manually merged resource can not contain identifiers"); + } + myGoldenResourceHelper.mergeIndentifierFields(theFromGoldenResource, theMergedResource, theMdmTransactionContext); + myGoldenResourceHelper.mergeIndentifierFields(theToGoldenResource, theMergedResource, theMdmTransactionContext); - IAnyResource mergeSource = ( theMergedResource == null ) ? theFromGoldenResource : theMergedResource; - myGoldenResourceHelper.mergeNonIdentiferFields(mergeSource, theToGoldenResource, theMdmTransactionContext); + theMergedResource.setId(theToGoldenResource.getId()); + theToGoldenResource = (IAnyResource) myMdmResourceDaoSvc.upsertGoldenResource(theMergedResource, resourceType).getResource(); + } else { + myGoldenResourceHelper.mergeIndentifierFields(theFromGoldenResource, theToGoldenResource, theMdmTransactionContext); + myGoldenResourceHelper.mergeNonIdentiferFields(theFromGoldenResource, theToGoldenResource, theMdmTransactionContext); + //Save changes to the golden resource + myMdmResourceDaoSvc.upsertGoldenResource(theToGoldenResource, resourceType); + } //Merge the links from the FROM to the TO resource. Clean up dangling links. mergeGoldenResourceLinks(theFromGoldenResource, theToGoldenResource, toGoldenResourcePid, theMdmTransactionContext); - //Save changes to the golden resource - myMdmResourceDaoSvc.upsertGoldenResource(theToGoldenResource, resourceType); //Create the new REDIRECT link addMergeLink(toGoldenResourcePid, fromGoldenResourcePid, resourceType); diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkUpdaterSvcImpl.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkUpdaterSvcImpl.java index 068bc6c67fb..7d49bced4e8 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkUpdaterSvcImpl.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmLinkUpdaterSvcImpl.java @@ -94,8 +94,11 @@ public class MdmLinkUpdaterSvcImpl implements IMdmLinkUpdaterSvc { mdmLink.setLinkSource(MdmLinkSourceEnum.MANUAL); myMdmLinkDaoSvc.save(mdmLink); - IAnyResource resource = (theManuallyMergedGoldenResource == null) ? theSourceResource : theManuallyMergedGoldenResource; - myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(resource, theGoldenResource, theMdmContext); + // IAnyResource resource = (theManuallyMergedGoldenResource == null) ? theSourceResource : theManuallyMergedGoldenResource; + if (theMatchResult == MdmMatchResultEnum.MATCH) { + // only apply survivorship rules in case of a match + myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theSourceResource, theGoldenResource, theMdmContext); + } myMdmResourceDaoSvc.upsertGoldenResource(theGoldenResource, theMdmContext.getResourceType()); if (theMatchResult == MdmMatchResultEnum.NO_MATCH) { diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSurvivorshipSvcImpl.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSurvivorshipSvcImpl.java index 365494ebc17..904adfc8a20 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSurvivorshipSvcImpl.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSurvivorshipSvcImpl.java @@ -34,6 +34,8 @@ public class MdmSurvivorshipSvcImpl implements IMdmSurvivorshipService { private FhirContext myFhirContext; /** + * TODO NG Update docs to tell taht we also do that in non GR merge - like linking + * * Merges two golden resources by overwriting all field values on theGoldenResource param for all REST operation methods * except MERGE_GOLDEN_RESOURCES. In case of MERGE_GOLDEN_RESOURCES, it will attempt to copy field values from * theTargetResource that do not exist in theGoldenResource. PID, indentifiers and meta values are not affected by diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderMergeGoldenResourcesR4Test.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderMergeGoldenResourcesR4Test.java index 716353c2089..0bd144b0568 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderMergeGoldenResourcesR4Test.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderMergeGoldenResourcesR4Test.java @@ -4,6 +4,7 @@ import ca.uhn.fhir.jpa.entity.MdmLink; import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; import ca.uhn.fhir.mdm.util.MdmResourceUtil; +import ca.uhn.fhir.mdm.util.TerserUtil; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import org.hl7.fhir.r4.model.Patient; @@ -95,12 +96,11 @@ public class MdmProviderMergeGoldenResourcesR4Test extends BaseProviderR4Test { @Test public void testMergeWithManualOverride() { - Patient mergedSourcePatient = (Patient) myMdmProvider.mergeGoldenResources(myFromGoldenPatientId, - myToGoldenPatientId, myFromGoldenPatient, myRequestDetails); + Patient patient = TerserUtil.clone(myFhirContext, myFromGoldenPatient); + patient.setIdElement(null); - myFromGoldenPatient = (Patient) myPatientDao.read(myFromGoldenPatient.getIdElement().toUnqualifiedVersionless()); - assertTrue(!MdmResourceUtil.isGoldenRecord(myFromGoldenPatient)); - assertTrue(MdmResourceUtil.isGoldenRecordRedirected(myFromGoldenPatient)); + Patient mergedSourcePatient = (Patient) myMdmProvider.mergeGoldenResources(myFromGoldenPatientId, + myToGoldenPatientId, patient, myRequestDetails); assertEquals(myToGoldenPatient.getIdElement(), mergedSourcePatient.getIdElement()); assertThat(mergedSourcePatient, is(sameGoldenResourceAs(myToGoldenPatient))); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderUpdateLinkR4Test.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderUpdateLinkR4Test.java index 5948a1f10b5..9f6c7d3f76c 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderUpdateLinkR4Test.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderUpdateLinkR4Test.java @@ -12,7 +12,6 @@ import org.hl7.fhir.r4.model.StringType; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import java.util.Date; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; @@ -32,7 +31,7 @@ public class MdmProviderUpdateLinkR4Test extends BaseLinkR4Test { @Test public void testUpdateLinkNoMatch() { assertLinkCount(1); - myMdmProvider.updateLink(mySourcePatientId, myPatientId, NO_MATCH_RESULT, null, myRequestDetails); + myMdmProvider.updateLink(mySourcePatientId, myPatientId, NO_MATCH_RESULT, myRequestDetails); assertLinkCount(2); List links = getPatientLinks(); @@ -46,7 +45,7 @@ public class MdmProviderUpdateLinkR4Test extends BaseLinkR4Test { @Test public void testUpdateLinkMatch() { assertLinkCount(1); - myMdmProvider.updateLink(mySourcePatientId, myPatientId, MATCH_RESULT, null, myRequestDetails); + myMdmProvider.updateLink(mySourcePatientId, myPatientId, MATCH_RESULT, myRequestDetails); assertLinkCount(1); List links = getPatientLinks(); @@ -54,34 +53,14 @@ public class MdmProviderUpdateLinkR4Test extends BaseLinkR4Test { assertEquals(MdmMatchResultEnum.MATCH, links.get(0).getMatchResult()); } - @Test - public void testUpdateLinkWithOverride() { - assertLinkCount(1); - Patient patient = new Patient(); - patient.addName().addGiven("Given"); - patient.addName().setFamily("Family"); - patient.setBirthDate(new Date()); - - Patient updatedPerson = (Patient) myMdmProvider - .updateLink(mySourcePatientId, myPatientId, MATCH_RESULT, patient, myRequestDetails); - assertLinkCount(1); - - List links = getPatientLinks(); - assertEquals(MdmLinkSourceEnum.MANUAL, links.get(0).getLinkSource()); - assertEquals(MdmMatchResultEnum.MATCH, links.get(0).getMatchResult()); - - assertEquals(patient.getNameFirstRep().getNameAsSingleString(), updatedPerson.getNameFirstRep().getNameAsSingleString()); - assertEquals(patient.getBirthDate(), updatedPerson.getBirthDate()); - } - @Test public void testUpdateLinkTwiceFailsDueToWrongVersion() { - myMdmProvider.updateLink(mySourcePatientId, myPatientId, MATCH_RESULT, null, myRequestDetails); + myMdmProvider.updateLink(mySourcePatientId, myPatientId, MATCH_RESULT, myRequestDetails); materiallyChangeGoldenPatient(); try { - myMdmProvider.updateLink(mySourcePatientId, myPatientId, NO_MATCH_RESULT, null, myRequestDetails); + myMdmProvider.updateLink(mySourcePatientId, myPatientId, NO_MATCH_RESULT, myRequestDetails); fail(); } catch (ResourceVersionConflictException e) { assertThat(e.getMessage(), matchesPattern("Requested resource Patient/\\d+/_history/1 is not the latest version. Latest version is Patient/\\d+/_history/2")); @@ -96,19 +75,19 @@ public class MdmProviderUpdateLinkR4Test extends BaseLinkR4Test { @Test public void testUpdateLinkTwiceDoesNotThrowValidationErrorWhenNoVersionIsProvided() { - myMdmProvider.updateLink(mySourcePatientId, myPatientId, MATCH_RESULT, null, myRequestDetails); - Patient patient = (Patient) myMdmProvider.updateLink(myVersionlessGodlenResourceId, myPatientId, NO_MATCH_RESULT, null, myRequestDetails); + myMdmProvider.updateLink(mySourcePatientId, myPatientId, MATCH_RESULT, myRequestDetails); + Patient patient = (Patient) myMdmProvider.updateLink(myVersionlessGodlenResourceId, myPatientId, NO_MATCH_RESULT, myRequestDetails); assertNotNull(patient); // if this wasn't allowed - a validation exception would be thrown } @Test public void testUnlinkLink() { - myMdmProvider.updateLink(mySourcePatientId, myPatientId, NO_MATCH_RESULT, null, myRequestDetails); + myMdmProvider.updateLink(mySourcePatientId, myPatientId, NO_MATCH_RESULT, myRequestDetails); materiallyChangeGoldenPatient(); try { - myMdmProvider.updateLink(mySourcePatientId, myPatientId, MATCH_RESULT, null, myRequestDetails); + myMdmProvider.updateLink(mySourcePatientId, myPatientId, MATCH_RESULT, myRequestDetails); fail(); } catch (ResourceVersionConflictException e) { assertThat(e.getMessage(), matchesPattern("Requested resource Patient/\\d+/_history/1 is not the latest version. Latest version is Patient/\\d+/_history/2")); @@ -118,7 +97,7 @@ public class MdmProviderUpdateLinkR4Test extends BaseLinkR4Test { @Test public void testUpdateIllegalResultForPossibleMatch() { try { - myMdmProvider.updateLink(mySourcePatientId, myPatientId, POSSIBLE_MATCH_RESULT, null, myRequestDetails); + myMdmProvider.updateLink(mySourcePatientId, myPatientId, POSSIBLE_MATCH_RESULT, myRequestDetails); fail(); } catch (InvalidRequestException e) { assertEquals("$mdm-update-link illegal matchResult value 'POSSIBLE_MATCH'. Must be NO_MATCH or MATCH", e.getMessage()); @@ -128,7 +107,7 @@ public class MdmProviderUpdateLinkR4Test extends BaseLinkR4Test { @Test public void testUpdateIllegalResultPD() { try { - myMdmProvider.updateLink(mySourcePatientId, myPatientId, POSSIBLE_DUPLICATE_RESULT, null, myRequestDetails); + myMdmProvider.updateLink(mySourcePatientId, myPatientId, POSSIBLE_DUPLICATE_RESULT, myRequestDetails); fail(); } catch (InvalidRequestException e) { assertEquals("$mdm-update-link illegal matchResult value 'POSSIBLE_DUPLICATE'. Must be NO_MATCH or MATCH", e.getMessage()); @@ -138,7 +117,7 @@ public class MdmProviderUpdateLinkR4Test extends BaseLinkR4Test { @Test public void testUpdateIllegalSecondArg() { try { - myMdmProvider.updateLink(myPatientId, new StringType(""), NO_MATCH_RESULT, null, myRequestDetails); + myMdmProvider.updateLink(myPatientId, new StringType(""), NO_MATCH_RESULT, myRequestDetails); fail(); } catch (InvalidRequestException e) { assertThat(e.getMessage(), endsWith(" must have form / where is the id of the resource and is the type of the resource")); @@ -148,7 +127,7 @@ public class MdmProviderUpdateLinkR4Test extends BaseLinkR4Test { @Test public void testUpdateIllegalFirstArg() { try { - myMdmProvider.updateLink(new StringType(""), myPatientId, NO_MATCH_RESULT, null, myRequestDetails); + myMdmProvider.updateLink(new StringType(""), myPatientId, NO_MATCH_RESULT, myRequestDetails); fail(); } catch (InvalidRequestException e) { assertThat(e.getMessage(), endsWith(" must have form / where is the id of the resource")); @@ -158,7 +137,7 @@ public class MdmProviderUpdateLinkR4Test extends BaseLinkR4Test { @Test public void testAttemptingToModifyANonExistentLinkFails() { try { - myMdmProvider.updateLink(mySourcePatientId, mySourcePatientId, NO_MATCH_RESULT, null, myRequestDetails); + myMdmProvider.updateLink(mySourcePatientId, mySourcePatientId, NO_MATCH_RESULT, myRequestDetails); fail(); } catch (InvalidRequestException e) { assertThat(e.getMessage(), startsWith("No link")); @@ -169,7 +148,7 @@ public class MdmProviderUpdateLinkR4Test extends BaseLinkR4Test { public void testUpdateStrangePatient() { Patient patient = createPatient(); try { - myMdmProvider.updateLink(new StringType(patient.getIdElement().getValue()), myPatientId, NO_MATCH_RESULT, null, myRequestDetails); + myMdmProvider.updateLink(new StringType(patient.getIdElement().getValue()), myPatientId, NO_MATCH_RESULT, myRequestDetails); fail(); } catch (InvalidRequestException e) { String expectedMessage = myMessageHelper.getMessageForUnmanagedResource(); @@ -183,7 +162,7 @@ public class MdmProviderUpdateLinkR4Test extends BaseLinkR4Test { patient.getMeta().addTag().setSystem(MdmConstants.SYSTEM_MDM_MANAGED).setCode(MdmConstants.CODE_NO_MDM_MANAGED); createPatient(patient); try { - myMdmProvider.updateLink(mySourcePatientId, new StringType(patient.getIdElement().getValue()), NO_MATCH_RESULT, null, myRequestDetails); + myMdmProvider.updateLink(mySourcePatientId, new StringType(patient.getIdElement().getValue()), NO_MATCH_RESULT, myRequestDetails); fail(); } catch (InvalidRequestException e) { assertEquals(myMessageHelper.getMessageForUnsupportedSourceResource(), e.getMessage()); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/MdmProviderDstu3Plus.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/MdmProviderDstu3Plus.java index c7901c12fab..56c0365a121 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/MdmProviderDstu3Plus.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/MdmProviderDstu3Plus.java @@ -159,10 +159,9 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider { public IBaseResource updateLink(@OperationParam(name = ProviderConstants.MDM_UPDATE_LINK_GOLDEN_RESOURCE_ID, min = 1, max = 1) IPrimitiveType theGoldenResourceId, @OperationParam(name = ProviderConstants.MDM_UPDATE_LINK_RESOURCE_ID, min = 1, max = 1) IPrimitiveType theResourceId, @OperationParam(name = ProviderConstants.MDM_UPDATE_LINK_MATCH_RESULT, min = 1, max = 1) IPrimitiveType theMatchResult, - @OperationParam(name = ProviderConstants.MDM_UPDATE_LINK_RESOURCE, max = 1) IAnyResource theManuallyMergedResource, ServletRequestDetails theRequestDetails) { validateUpdateLinkParameters(theGoldenResourceId, theResourceId, theMatchResult); - return myMdmControllerSvc.updateLink(theGoldenResourceId.getValueAsString(), theResourceId.getValue(), theManuallyMergedResource, + return myMdmControllerSvc.updateLink(theGoldenResourceId.getValueAsString(), theResourceId.getValue(), null, theMatchResult.getValue(), createMdmContext(theRequestDetails, MdmTransactionContext.OperationType.UPDATE_LINK, getResourceType(ProviderConstants.MDM_UPDATE_LINK_GOLDEN_RESOURCE_ID, theGoldenResourceId)) ); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java index d48467b9f24..0ffbfb91758 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java @@ -241,6 +241,10 @@ public class GoldenResourceHelper { } } + public boolean hasIdentifier(IBaseResource theResource) { + return TerserUtil.hasValues(myFhirContext, theResource, FIELD_NAME_IDENTIFIER); + } + public void mergeIndentifierFields(IBaseResource theFromGoldenResource, IBaseResource theToGoldenResource, MdmTransactionContext theMdmTransactionContext) { TerserUtil.cloneCompositeField(myFhirContext, theFromGoldenResource, theToGoldenResource, FIELD_NAME_IDENTIFIER); } diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/TerserUtil.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/TerserUtil.java index e26ddf01507..ebd022648ff 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/TerserUtil.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/TerserUtil.java @@ -89,6 +89,23 @@ public final class TerserUtil { theIdentifierDefinition.getMutator().addValue(theResourceToCloneEidInto, resourceNewIdentifier); } + /** + * Checks if the specified fields has any values + * + * @param theFhirContext Context holding resource definition + * @param theResource Resource to check if the specified field is set + * @param theFieldName name of the field to check + * @return Returns true if field exists and has any values set, and false otherwise + */ + public static boolean hasValues(FhirContext theFhirContext, IBaseResource theResource, String theFieldName) { + RuntimeResourceDefinition resourceDefinition = theFhirContext.getResourceDefinition(theResource); + BaseRuntimeChildDefinition resourceIdentifier = resourceDefinition.getChildByName(theFieldName); + if (resourceIdentifier == null) { + return false; + } + return !(resourceIdentifier.getAccessor().getValues(theResource).isEmpty()); + } + /** * Clones specified composite field (collection). Composite field values must confirm to the collections * contract. @@ -237,4 +254,13 @@ public final class TerserUtil { } } + public static T clone(FhirContext theFhirContext, T theInstance) { + RuntimeResourceDefinition definition = theFhirContext.getResourceDefinition(theInstance.getClass()); + T retVal = (T) definition.newInstance(); + + FhirTerser terser = theFhirContext.newTerser(); + terser.cloneInto(theInstance, retVal, true); + return retVal; + } + }