
001/*- 002 * #%L 003 * HAPI FHIR - Core Library 004 * %% 005 * Copyright (C) 2014 - 2025 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.interceptor.auth; 021 022import jakarta.annotation.Nonnull; 023 024import java.util.HashMap; 025import java.util.HashSet; 026import java.util.Map; 027import java.util.Set; 028 029/** 030 * This class is used in RuleBuilder, as a way to allow adding or removing certain Search Parameters 031 * to the compartment. 032 * For example, if you were to add as additional SPs 033 * [device -> ["patient", "subject"] 034 * and apply it to compartment Patient/123, then any device with Patient/123 as its patient would be considered "in" 035 * the compartment, despite the fact that device is technically not part of the compartment definition for patient. 036 */ 037public class CompartmentSearchParameterModifications { 038 039 /** 040 * Construct compartment modifications from resource type and sets of SP names to add or omit respectively. 041 * @param theResourceType the resource type the SPs are based on 042 * @param theAdditionalSPs the additional SP names 043 * @param theOmittedSps the omitted SP names 044 * @return 045 */ 046 public static CompartmentSearchParameterModifications fromAdditionalAndOmittedSPNames( 047 @Nonnull String theResourceType, 048 @Nonnull Set<String> theAdditionalSPs, 049 @Nonnull Set<String> theOmittedSps) { 050 CompartmentSearchParameterModifications modifications = new CompartmentSearchParameterModifications(); 051 theAdditionalSPs.forEach(spName -> { 052 modifications.addSPToIncludeInCompartment(theResourceType, spName); 053 }); 054 theOmittedSps.forEach(spName -> { 055 modifications.addSPToOmitFromCompartment(theResourceType, spName); 056 }); 057 return modifications; 058 } 059 060 public static CompartmentSearchParameterModifications fromAdditionalCompartmentParamNames( 061 String theResourceType, @Nonnull Set<String> theAdditionalCompartmentParamNames) { 062 return fromAdditionalAndOmittedSPNames(theResourceType, theAdditionalCompartmentParamNames, Set.of()); 063 } 064 065 private final Map<String, Set<String>> myAdditionalResourceTypeToParameterCodeMap; 066 067 private final Map<String, Set<String>> myOmittedResourceTypeToParameterCodeMap; 068 069 public CompartmentSearchParameterModifications() { 070 myAdditionalResourceTypeToParameterCodeMap = new HashMap<>(); 071 myOmittedResourceTypeToParameterCodeMap = new HashMap<>(); 072 } 073 074 /** 075 * Add an SP, normally included in the compartment, that will be omitted 076 * hereafter. 077 * @param theResourceType the resource type on which the SP exists 078 * @param theSPName the name of the search parameter 079 */ 080 public void addSPToOmitFromCompartment(String theResourceType, String theSPName) { 081 myOmittedResourceTypeToParameterCodeMap 082 .computeIfAbsent(theResourceType.toLowerCase(), (key) -> new HashSet<>()) 083 .add(theSPName); 084 } 085 086 /** 087 * Add an SP, not in the compartment, that will now be included hereafter 088 * @param theResourceType the resource type on which the SP exists 089 * @param theSPName the name of the search parameter 090 */ 091 public void addSPToIncludeInCompartment(String theResourceType, String theSPName) { 092 myAdditionalResourceTypeToParameterCodeMap 093 .computeIfAbsent(theResourceType.toLowerCase(), (key) -> new HashSet<>()) 094 .add(theSPName); 095 } 096 097 public Set<String> getAdditionalSearchParamNamesForResourceType(@Nonnull String theResourceType) { 098 return myAdditionalResourceTypeToParameterCodeMap.computeIfAbsent( 099 theResourceType.toLowerCase(), (key) -> new HashSet<>()); 100 } 101 102 public Set<String> getOmittedSPNamesForResourceType(String theResourceType) { 103 return myOmittedResourceTypeToParameterCodeMap.computeIfAbsent( 104 theResourceType.toLowerCase(), (key) -> new HashSet<>()); 105 } 106}