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.model; 021 022import ca.uhn.fhir.context.FhirContext; 023import ca.uhn.fhir.fhirpath.IFhirPath; 024import org.hl7.fhir.instance.model.api.IBase; 025import org.hl7.fhir.instance.model.api.IBaseResource; 026import org.hl7.fhir.instance.model.api.IPrimitiveType; 027import org.hl7.fhir.r4.model.Identifier; 028 029import java.util.List; 030import java.util.Objects; 031import java.util.stream.Collectors; 032 033public class CanonicalEID { 034 035 private String mySystem; 036 private String myUse; 037 private String myValue; 038 039 public CanonicalEID(String theSystem, String theValue, String theUse) { 040 mySystem = theSystem; 041 myUse = theUse; 042 myValue = theValue; 043 } 044 045 /** 046 * Constructor is private as we expect you to use the factory method. 047 */ 048 @SuppressWarnings("rawtypes") 049 private CanonicalEID(IFhirPath theFhirPath, IBase theIBase) { 050 List<IPrimitiveType> value = theFhirPath.evaluate(theIBase, "value", IPrimitiveType.class); 051 List<IPrimitiveType> system = theFhirPath.evaluate(theIBase, "system", IPrimitiveType.class); 052 List<IPrimitiveType> use = theFhirPath.evaluate(theIBase, "use", IPrimitiveType.class); 053 054 myUse = use.isEmpty() ? null : use.get(0).getValueAsString(); 055 myValue = value.isEmpty() ? null : value.get(0).getValueAsString(); 056 mySystem = system.isEmpty() ? null : system.get(0).getValueAsString(); 057 } 058 059 /** 060 * Get the appropriate FHIRPath expression to extract the EID identifier value, regardless of resource type. 061 * e.g. if theBaseResource is a patient, and the MDM EID system is test-system, this will return 062 * 063 * Patient.identifier.where(system='test-system').value 064 * 065 */ 066 private static String buildEidFhirPath( 067 FhirContext theFhirContext, String theEidSystem, IBaseResource theBaseResource) { 068 return theFhirContext.getResourceType(theBaseResource) + ".identifier.where(system='" + theEidSystem + "')"; 069 } 070 071 public Identifier toR4() { 072 return new Identifier() 073 .setUse(Identifier.IdentifierUse.fromCode(myUse)) 074 .setSystem(mySystem) 075 .setValue(myValue); 076 } 077 078 public org.hl7.fhir.dstu3.model.Identifier toDSTU3() { 079 return new org.hl7.fhir.dstu3.model.Identifier() 080 .setUse(org.hl7.fhir.dstu3.model.Identifier.IdentifierUse.fromCode(myUse)) 081 .setSystem(mySystem) 082 .setValue(myValue); 083 } 084 085 public org.hl7.fhir.r5.model.Identifier toR5() { 086 return new org.hl7.fhir.r5.model.Identifier() 087 .setUse(org.hl7.fhir.r5.model.Identifier.IdentifierUse.fromCode(myUse)) 088 .setSystem(mySystem) 089 .setValue(myValue); 090 } 091 092 public String getSystem() { 093 return mySystem; 094 } 095 096 public String getUse() { 097 return myUse; 098 } 099 100 public String getValue() { 101 return myValue; 102 } 103 104 public void setSystem(String theSystem) { 105 mySystem = theSystem; 106 } 107 108 public void setUse(String theUse) { 109 myUse = theUse; 110 } 111 112 private void setValue(String theValue) { 113 myValue = theValue; 114 } 115 116 @Override 117 public String toString() { 118 return mySystem + '|' + myValue; 119 } 120 121 /** 122 * A Factory method to generate a {@link CanonicalEID} object from an incoming resource. 123 * 124 * @param theFhirContext the {@link FhirContext} of the application, used to generate a FHIRPath parser. 125 * @param theEidSystem the enterprise identifier system URI used by this instance. 126 * @param theBaseResource the {@link IBaseResource} from which you would like to extract EIDs. 127 * 128 * @return an optional {@link CanonicalEID} object, representing a resource identifier that matched the given eidSystem. 129 */ 130 public static List<CanonicalEID> extractFromResource( 131 FhirContext theFhirContext, String theEidSystem, IBaseResource theBaseResource) { 132 IFhirPath fhirPath = theFhirContext.newFhirPath(); 133 String eidPath = buildEidFhirPath(theFhirContext, theEidSystem, theBaseResource); 134 List<IBase> evaluate = fhirPath.evaluate(theBaseResource, eidPath, IBase.class); 135 136 return evaluate.stream().map(ibase -> new CanonicalEID(fhirPath, ibase)).collect(Collectors.toList()); 137 } 138 139 @Override 140 public boolean equals(Object o) { 141 if (!(o instanceof CanonicalEID)) { 142 return false; 143 } 144 CanonicalEID otherEid = (CanonicalEID) o; 145 return Objects.equals(otherEid.getSystem(), this.getSystem()) 146 && Objects.equals(otherEid.getValue(), this.getValue()) 147 && Objects.equals(otherEid.getUse(), this.getUse()); 148 } 149 150 @Override 151 public int hashCode() { 152 return Objects.hash(mySystem, myValue, myUse); 153 } 154}