001/*- 002 * #%L 003 * HAPI FHIR JPA - Search Parameters 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.jpa.searchparam.registry; 021 022import ca.uhn.fhir.context.RuntimeSearchParam; 023import ca.uhn.fhir.rest.server.util.ResourceSearchParams; 024import org.slf4j.Logger; 025import org.slf4j.LoggerFactory; 026 027import java.util.Map; 028import java.util.Set; 029 030import static org.apache.commons.lang3.StringUtils.isNotBlank; 031 032public class RuntimeSearchParamCache extends ReadOnlySearchParamCache { 033 private static final Logger ourLog = LoggerFactory.getLogger(RuntimeSearchParamCache.class); 034 035 protected RuntimeSearchParamCache() {} 036 037 public void add(String theResourceName, String theName, RuntimeSearchParam theSearchParam) { 038 ResourceSearchParams resourceSearchParams = getSearchParamMap(theResourceName); 039 resourceSearchParams.put(theName, theSearchParam); 040 String uri = theSearchParam.getUri(); 041 if (isNotBlank(uri)) { 042 RuntimeSearchParam existingForUrl = myUrlToParam.get(uri); 043 if (existingForUrl == theSearchParam) { 044 // This is expected, since the same SP can span multiple resource types 045 // so it may get added more than once by this method 046 ourLog.trace("Search param was previously registered for url: {}", uri); 047 } else if (existingForUrl != null) { 048 ourLog.debug("Multiple search parameters have URL: {}", uri); 049 } else { 050 myUrlToParam.put(uri, theSearchParam); 051 } 052 } 053 if (theSearchParam.getId() != null && theSearchParam.getId().hasIdPart()) { 054 String value = theSearchParam.getId().toUnqualifiedVersionless().getValue(); 055 myUrlToParam.put(value, theSearchParam); 056 } 057 } 058 059 public void remove(String theResourceName, String theName) { 060 if (!myResourceNameToSpNameToSp.containsKey(theResourceName)) { 061 return; 062 } 063 myResourceNameToSpNameToSp.get(theResourceName).remove(theName); 064 } 065 066 private void putAll(ReadOnlySearchParamCache theReadOnlySearchParamCache) { 067 Set<Map.Entry<String, ResourceSearchParams>> builtInSps = 068 theReadOnlySearchParamCache.myResourceNameToSpNameToSp.entrySet(); 069 for (Map.Entry<String, ResourceSearchParams> nextBuiltInEntry : builtInSps) { 070 for (RuntimeSearchParam nextParam : nextBuiltInEntry.getValue().values()) { 071 String nextResourceName = nextBuiltInEntry.getKey(); 072 String nextParamName = nextParam.getName(); 073 add(nextResourceName, nextParamName, nextParam); 074 } 075 076 ourLog.trace( 077 "Have {} built-in SPs for: {}", nextBuiltInEntry.getValue().size(), nextBuiltInEntry.getKey()); 078 } 079 } 080 081 public RuntimeSearchParam get(String theResourceName, String theParamName) { 082 RuntimeSearchParam retVal = null; 083 ResourceSearchParams params = myResourceNameToSpNameToSp.get(theResourceName); 084 if (params != null) { 085 retVal = params.get(theParamName); 086 } 087 return retVal; 088 } 089 090 public Set<String> getResourceNameKeys() { 091 return myResourceNameToSpNameToSp.keySet(); 092 } 093 094 @Override 095 protected ResourceSearchParams getSearchParamMap(String theResourceName) { 096 return myResourceNameToSpNameToSp.computeIfAbsent( 097 theResourceName, k -> new ResourceSearchParams(theResourceName)); 098 } 099 100 public static RuntimeSearchParamCache fromReadOnlySearchParamCache( 101 ReadOnlySearchParamCache theBuiltInSearchParams) { 102 RuntimeSearchParamCache retVal = new RuntimeSearchParamCache(); 103 retVal.putAll(theBuiltInSearchParams); 104 return retVal; 105 } 106}