001package ca.cdr.api.consent; 002 003import ca.uhn.fhir.context.FhirContext; 004import org.hl7.fhir.instance.model.api.IBaseResource; 005import org.hl7.fhir.instance.model.api.IIdType; 006import org.slf4j.Logger; 007import org.slf4j.LoggerFactory; 008 009import java.util.ArrayList; 010import java.util.Collections; 011import java.util.List; 012import java.util.Objects; 013import java.util.Optional; 014import java.util.Set; 015import java.util.stream.Collectors; 016 017import static org.apache.commons.collections4.CollectionUtils.isEmpty; 018 019public class CompartmentUtil { 020 private static final Logger ourLog = LoggerFactory.getLogger(CompartmentUtil.class); 021 public static final String PATIENT = "Patient"; 022 023 private CompartmentUtil() { 024 // utility class 025 } 026 027 public static Optional<IIdType> getPatientCompartmentForResource( 028 FhirContext theFhirContext, IBaseResource theResource) { 029 List<IIdType> patientCompartments = getPatientCompartmentForResourceMultiple(theFhirContext, theResource); 030 if (isEmpty(patientCompartments)) { 031 return Optional.empty(); 032 } 033 if (patientCompartments.size() > 1) { 034 String allIds = patientCompartments.stream().map(IIdType::getIdPart).collect(Collectors.joining(", ")); 035 ourLog.warn("Multiple patient compartments found: {}. Selecting first compartment.", allIds); 036 } 037 return Optional.of(patientCompartments.get(0)); 038 } 039 040 public static List<IIdType> getPatientCompartmentForResourceMultiple( 041 FhirContext theFhirContext, IBaseResource theResource) { 042 043 if (theResource == null) { 044 return Collections.emptyList(); 045 } 046 047 List<IIdType> retVal = new ArrayList<>(); 048 try { 049 if (isPatient(theResource)) { 050 retVal.add(theResource.getIdElement()); 051 } else { 052 List<IIdType> patientIds = 053 theFhirContext 054 .newTerser() 055 .getCompartmentOwnersForResource(PATIENT, theResource, Set.of()) 056 .stream() 057 .map(id -> theFhirContext.getVersion().newIdType(id.getValue())) 058 .filter(id -> Objects.equals(PATIENT, id.getResourceType())) 059 .toList(); 060 retVal.addAll(patientIds); 061 } 062 } catch (Exception e) { 063 ourLog.warn( 064 "Error finding Patient compartment for: {}", 065 theResource.getIdElement().getValueAsString()); 066 } 067 068 return retVal; 069 } 070 071 private static boolean isPatient(IBaseResource theResource) { 072 return theResource != null && PATIENT.equals(theResource.fhirType()); 073 } 074}