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.api;
021
022import org.apache.commons.lang3.builder.ToStringBuilder;
023
024/**
025 * This data object captures the final outcome of an MDM match
026 */
027public final class MdmMatchOutcome {
028
029        public static final MdmMatchOutcome POSSIBLE_DUPLICATE =
030                        new MdmMatchOutcome(null, null).setMatchResultEnum(MdmMatchResultEnum.POSSIBLE_DUPLICATE);
031        public static final MdmMatchOutcome NO_MATCH =
032                        new MdmMatchOutcome(null, null).setMatchResultEnum(MdmMatchResultEnum.NO_MATCH);
033        public static final MdmMatchOutcome NEW_GOLDEN_RESOURCE_MATCH = new MdmMatchOutcome(null, 1.0)
034                        .setMatchResultEnum(MdmMatchResultEnum.MATCH)
035                        .setCreatedNewResource(true);
036        public static final MdmMatchOutcome EID_MATCH = new MdmMatchOutcome(null, 1.0)
037                        .setMatchResultEnum(MdmMatchResultEnum.MATCH)
038                        .setEidMatch(true);
039        public static final MdmMatchOutcome POSSIBLE_MATCH =
040                        new MdmMatchOutcome(null, null).setMatchResultEnum(MdmMatchResultEnum.POSSIBLE_MATCH);
041
042        /**
043         * A bitmap that indicates which rules matched
044         */
045        private final Long vector;
046
047        /**
048         * The sum of all scores for all rules evaluated.  Similarity rules add the similarity score (between 0.0 and 1.0) whereas
049         * matcher rules add either a 0.0 or 1.0.
050         */
051        private final Double score;
052
053        /**
054         * Did the MDM match operation result in creating a new golden resource?
055         */
056        private boolean myCreatedNewResource;
057
058        /**
059         * Did the MDM match occur as a result of EIDs matching?
060         */
061        private boolean myEidMatch;
062
063        /**
064         * Based on the MDM Rules, what was the final match result?
065         */
066        private MdmMatchResultEnum myMatchResultEnum;
067
068        /**
069         * Total number of MDM rules checked for this outcome
070         */
071        private int myMdmRuleCount;
072
073        public MdmMatchOutcome(Long theVector, Double theScore) {
074                vector = theVector;
075                score = theScore;
076        }
077
078        public boolean isMatch() {
079                return myMatchResultEnum == MdmMatchResultEnum.MATCH;
080        }
081
082        public boolean isPossibleMatch() {
083                return myMatchResultEnum == MdmMatchResultEnum.POSSIBLE_MATCH;
084        }
085
086        public boolean isPossibleDuplicate() {
087                return myMatchResultEnum == MdmMatchResultEnum.POSSIBLE_DUPLICATE;
088        }
089
090        public MdmMatchResultEnum getMatchResultEnum() {
091                return myMatchResultEnum;
092        }
093
094        public MdmMatchOutcome setMatchResultEnum(MdmMatchResultEnum theMatchResultEnum) {
095                myMatchResultEnum = theMatchResultEnum;
096                return this;
097        }
098
099        public boolean isCreatedNewResource() {
100                return myCreatedNewResource;
101        }
102
103        /** @param theCreatedNewResource        this match is creating a new golden resource */
104        public MdmMatchOutcome setCreatedNewResource(boolean theCreatedNewResource) {
105                myCreatedNewResource = theCreatedNewResource;
106                return this;
107        }
108
109        public boolean isEidMatch() {
110                return myEidMatch;
111        }
112
113        /**
114         * Sets the number of MDM rules checked for this match outcome
115         *
116         * @param theMdmRuleCount
117         *      Number of MDM rules that were checked for this match outcome
118         * @return
119         *      Returns this instance
120         */
121        public MdmMatchOutcome setMdmRuleCount(int theMdmRuleCount) {
122                myMdmRuleCount = theMdmRuleCount;
123                return this;
124        }
125
126        /**
127         * Gets the number of MDM rules checked for this match outcome
128         *
129         * @return
130         *      Returns the number of rules
131         */
132        public int getMdmRuleCount() {
133                return myMdmRuleCount;
134        }
135
136        /** @param theEidMatch the link was established via a shared EID */
137        public MdmMatchOutcome setEidMatch(boolean theEidMatch) {
138                myEidMatch = theEidMatch;
139                return this;
140        }
141
142        public Double getScore() {
143                return score;
144        }
145
146        public Long getVector() {
147                return vector;
148        }
149
150        /**
151         * Gets normalized score that is in the range from zero to one
152         *
153         * @return
154         *      Returns the normalized score
155         */
156        public Double getNormalizedScore() {
157                if (myMdmRuleCount == 0) {
158                        return score;
159                }
160                return score / myMdmRuleCount;
161        }
162
163        @Override
164        public String toString() {
165                return new ToStringBuilder(this)
166                                .append("vector", vector)
167                                .append("score", score)
168                                .append("myCreatedNewResource", myCreatedNewResource)
169                                .append("myEidMatch", myEidMatch)
170                                .append("myMatchResultEnum", myMatchResultEnum)
171                                .toString();
172        }
173}