001/*- 002 * #%L 003 * HAPI FHIR - Master Data Management 004 * %% 005 * Copyright (C) 2014 - 2024 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.mdm.rules.similarity; 021 022import ca.uhn.fhir.context.FhirContext; 023import ca.uhn.fhir.mdm.api.MdmMatchEvaluation; 024import info.debatty.java.stringsimilarity.Cosine; 025import info.debatty.java.stringsimilarity.Jaccard; 026import info.debatty.java.stringsimilarity.JaroWinkler; 027import info.debatty.java.stringsimilarity.NormalizedLevenshtein; 028import info.debatty.java.stringsimilarity.SorensenDice; 029import jakarta.annotation.Nullable; 030import org.hl7.fhir.instance.model.api.IBase; 031 032public enum MdmSimilarityEnum { 033 JARO_WINKLER(new HapiStringSimilarity(new JaroWinkler())), 034 COSINE(new HapiStringSimilarity(new Cosine())), 035 JACCARD(new HapiStringSimilarity(new Jaccard())), 036 LEVENSCHTEIN(new HapiStringSimilarity(new NormalizedLevenshtein())), 037 SORENSEN_DICE(new HapiStringSimilarity(new SorensenDice())), 038 NUMERIC_JARO_WINKLER(new HapiNumericSimilarity(new JaroWinkler())), 039 NUMERIC_COSINE(new HapiNumericSimilarity(new Cosine())), 040 NUMERIC_JACCARD(new HapiNumericSimilarity(new Jaccard())), 041 NUMERIC_LEVENSCHTEIN(new HapiNumericSimilarity(new NormalizedLevenshtein())), 042 NUMERIC_SORENSEN_DICE(new HapiNumericSimilarity(new SorensenDice())); 043 044 private final IMdmFieldSimilarity myMdmFieldSimilarity; 045 046 MdmSimilarityEnum(IMdmFieldSimilarity theMdmFieldSimilarity) { 047 myMdmFieldSimilarity = theMdmFieldSimilarity; 048 } 049 050 public MdmMatchEvaluation match( 051 FhirContext theFhirContext, 052 IBase theLeftBase, 053 IBase theRightBase, 054 boolean theExact, 055 @Nullable Double theThreshold) { 056 return matchBySimilarity( 057 myMdmFieldSimilarity, theFhirContext, theLeftBase, theRightBase, theExact, theThreshold); 058 } 059 060 private MdmMatchEvaluation matchBySimilarity( 061 IMdmFieldSimilarity theSimilarity, 062 FhirContext theFhirContext, 063 IBase theLeftBase, 064 IBase theRightBase, 065 boolean theExact, 066 Double theThreshold) { 067 double similarityResult = theSimilarity.similarity(theFhirContext, theLeftBase, theRightBase, theExact); 068 return new MdmMatchEvaluation(similarityResult >= theThreshold, similarityResult); 069 } 070}