Added empty matcher

This commit is contained in:
Nick 2021-01-21 17:42:28 -05:00
parent ed5727d795
commit cdda12ef8e
7 changed files with 115 additions and 3 deletions

View File

@ -84,6 +84,10 @@ public class MdmFieldMatchJson implements IModelJson {
return myMatcher;
}
public boolean isMatcherSupportingEmptyFields() {
return (getMatcher() == null) ? false : getMatcher().isMatchingEmptyFields();
}
public MdmFieldMatchJson setMatcher(MdmMatcherJson theMatcher) {
myMatcher = theMatcher;
return this;

View File

@ -66,6 +66,10 @@ public class MdmMatcherJson implements IModelJson {
return this;
}
public boolean isMatchingEmptyFields() {
return myAlgorithm.isMatchingEmptyFields();
}
public boolean match(FhirContext theFhirContext, IBase theLeftValue, IBase theRightValue) {
return myAlgorithm.match(theFhirContext, theLeftValue, theRightValue, myExact, myIdentifierSystem);
}

View File

@ -0,0 +1,20 @@
package ca.uhn.fhir.mdm.rules.matcher;
import ca.uhn.fhir.context.FhirContext;
import org.hl7.fhir.instance.model.api.IBase;
public class EmptyFieldMatcher implements IMdmFieldMatcher {
public EmptyFieldMatcher() {
}
@Override
public boolean matches(FhirContext theFhirContext, IBase theLeftBase, IBase theRightBase, boolean theExact, String theIdentifierSystem) {
for (IBase b : new IBase[] {theLeftBase, theRightBase}) {
if (b != null && !b.isEmpty()) {
return false;
}
}
return true;
}
}

View File

@ -48,7 +48,9 @@ public enum MdmMatcherEnum {
NAME_ANY_ORDER(new NameMatcher(MdmNameMatchModeEnum.ANY_ORDER)),
NAME_FIRST_AND_LAST(new NameMatcher(MdmNameMatchModeEnum.FIRST_AND_LAST)),
IDENTIFIER(new IdentifierMatcher());
IDENTIFIER(new IdentifierMatcher()),
EMPTY_FIELD(new EmptyFieldMatcher());
private final IMdmFieldMatcher myMdmFieldMatcher;
@ -69,4 +71,14 @@ public enum MdmMatcherEnum {
public boolean match(FhirContext theFhirContext, IBase theLeftBase, IBase theRightBase, boolean theExact, String theIdentifierSystem) {
return myMdmFieldMatcher.matches(theFhirContext, theLeftBase, theRightBase, theExact, theIdentifierSystem);
}
/**
* Checks if this matcher supports checks on empty fields
*
* @return
* Returns true of this matcher supports empty fields and false otherwise
*/
public boolean isMatchingEmptyFields() {
return this == EMPTY_FIELD;
}
}

View File

@ -58,7 +58,7 @@ public class MdmResourceFieldMatcher {
/**
* Compares two {@link IBaseResource}s and determines if they match, using the algorithm defined in this object's
* {@link MdmFieldMatchJson}.
*
* <p>
* In this implementation, it determines whether a given field matches between two resources. Internally this is evaluated using FhirPath. If any of the elements of theLeftResource
* match any of the elements of theRightResource, will return true. Otherwise, false.
*
@ -80,12 +80,19 @@ public class MdmResourceFieldMatcher {
@SuppressWarnings("rawtypes")
private MdmMatchEvaluation match(List<IBase> theLeftValues, List<IBase> theRightValues) {
MdmMatchEvaluation retval = new MdmMatchEvaluation(false, 0.0);
boolean isMatchingEmptyFieldValues = (theLeftValues.isEmpty() && theRightValues.isEmpty());
if (isMatchingEmptyFieldValues && myMdmFieldMatchJson.isMatcherSupportingEmptyFields()) {
return match((IBase) null, (IBase) null);
}
for (IBase leftValue : theLeftValues) {
for (IBase rightValue : theRightValues) {
MdmMatchEvaluation nextMatch = match(leftValue, rightValue);
retval = MdmMatchEvaluation.max(retval, nextMatch);
}
}
return retval;
}

View File

@ -0,0 +1,32 @@
package ca.uhn.fhir.mdm.rules.matcher;
import ca.uhn.fhir.mdm.rules.json.MdmFieldMatchJson;
import ca.uhn.fhir.mdm.rules.json.MdmMatcherJson;
import ca.uhn.fhir.model.primitive.StringDt;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class EmptyFieldMatcherTest extends BaseMatcherR4Test {
@Test
public void testEmptyFieldMatch() {
StringDt left = new StringDt("other value");
StringDt leftEmpty = new StringDt("");
StringDt rightEmpty = new StringDt("");
StringDt right = new StringDt("a value");
MdmMatcherJson matcher = new MdmMatcherJson().setAlgorithm(MdmMatcherEnum.EMPTY_FIELD);
MdmFieldMatchJson fieldMatch = new MdmFieldMatchJson().setMatcher(matcher);
assertTrue(fieldMatch.match(ourFhirContext, null, null).match);
assertTrue(fieldMatch.match(ourFhirContext, null, rightEmpty).match);
assertTrue(fieldMatch.match(ourFhirContext, leftEmpty, null).match);
assertTrue(fieldMatch.match(ourFhirContext, leftEmpty, rightEmpty).match);
assertFalse(fieldMatch.match(ourFhirContext, null, right).match);
assertFalse(fieldMatch.match(ourFhirContext, left, null).match);
assertFalse(fieldMatch.match(ourFhirContext, left, right).match);
}
}

View File

@ -1,7 +1,10 @@
package ca.uhn.fhir.mdm.rules.svc;
import ca.uhn.fhir.mdm.rules.json.MdmFieldMatchJson;
import ca.uhn.fhir.mdm.rules.json.MdmMatcherJson;
import ca.uhn.fhir.mdm.rules.json.MdmRulesJson;
import ca.uhn.fhir.mdm.rules.json.MdmSimilarityJson;
import ca.uhn.fhir.mdm.rules.matcher.MdmMatcherEnum;
import ca.uhn.fhir.mdm.rules.similarity.MdmSimilarityEnum;
import ca.uhn.fhir.parser.DataFormatException;
import org.hl7.fhir.r4.model.Encounter;
@ -9,6 +12,8 @@ import org.hl7.fhir.r4.model.Patient;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.StringStartsWith.startsWith;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ -31,6 +36,34 @@ public class MdmResourceFieldMatcherR4Test extends BaseMdmRulesR4Test {
myJohny = buildJohny();
}
@Test
public void testEmptyPath() {
myMdmRulesJson = new MdmRulesJson();
myMdmRulesJson.setMdmTypes(Arrays.asList(new String[]{"Patient"}));
myGivenNameMatchField = new MdmFieldMatchJson()
.setName("empty-given")
.setResourceType("Patient")
.setResourcePath("name.given")
.setMatcher(new MdmMatcherJson().setAlgorithm(MdmMatcherEnum.EMPTY_FIELD));
myComparator = new MdmResourceFieldMatcher(ourFhirContext, myGivenNameMatchField, myMdmRulesJson);
assertFalse(myComparator.match(myJohn, myJohny).match);
myJohn.getName().clear();
myJohny.getName().clear();
assertTrue(myComparator.match(myJohn, myJohny).match);
myJohn = buildJohn();
myJohny.getName().clear();
assertFalse(myComparator.match(myJohn, myJohny).match);
myJohn.getName().clear();
myJohny = buildJohny();
assertFalse(myComparator.match(myJohn, myJohny).match);
}
@Test
public void testSimplePatient() {
Patient patient = new Patient();