
001/* 002 * #%L 003 * HAPI FHIR JPA Server 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.jpa.dao; 021 022import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient; 023import ca.uhn.fhir.jpa.api.dao.PatientEverythingParameters; 024import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc; 025import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; 026import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum; 027import ca.uhn.fhir.model.api.IResource; 028import ca.uhn.fhir.rest.api.CacheControlDirective; 029import ca.uhn.fhir.rest.api.Constants; 030import ca.uhn.fhir.rest.api.SortSpec; 031import ca.uhn.fhir.rest.api.server.IBundleProvider; 032import ca.uhn.fhir.rest.api.server.RequestDetails; 033import ca.uhn.fhir.rest.param.DateRangeParam; 034import ca.uhn.fhir.rest.param.StringAndListParam; 035import ca.uhn.fhir.rest.param.TokenOrListParam; 036import ca.uhn.fhir.rest.param.TokenParam; 037import jakarta.servlet.http.HttpServletRequest; 038import org.hl7.fhir.instance.model.api.IBaseResource; 039import org.hl7.fhir.instance.model.api.IIdType; 040import org.hl7.fhir.instance.model.api.IPrimitiveType; 041import org.slf4j.Logger; 042import org.slf4j.LoggerFactory; 043import org.springframework.beans.factory.annotation.Autowired; 044import org.springframework.transaction.annotation.Propagation; 045import org.springframework.transaction.annotation.Transactional; 046 047import java.util.Collections; 048 049public class JpaResourceDaoPatient<T extends IBaseResource> extends BaseHapiFhirResourceDao<T> 050 implements IFhirResourceDaoPatient<T> { 051 052 private static final Logger ourLog = LoggerFactory.getLogger(JpaResourceDaoPatient.class); 053 054 @Autowired 055 private IRequestPartitionHelperSvc myPartitionHelperSvc; 056 057 private IBundleProvider doEverythingOperation( 058 TokenOrListParam theIds, 059 IPrimitiveType<Integer> theCount, 060 IPrimitiveType<Integer> theOffset, 061 DateRangeParam theLastUpdated, 062 SortSpec theSort, 063 StringAndListParam theContent, 064 StringAndListParam theNarrative, 065 StringAndListParam theFilter, 066 StringAndListParam theTypes, 067 boolean theMdmExpand, 068 RequestDetails theRequest) { 069 SearchParameterMap paramMap = new SearchParameterMap(); 070 if (theCount != null) { 071 paramMap.setCount(theCount.getValue()); 072 } 073 if (theOffset != null) { 074 paramMap.setOffset(theOffset.getValue()); 075 } 076 if (theContent != null) { 077 paramMap.add(Constants.PARAM_CONTENT, theContent); 078 } 079 if (theNarrative != null) { 080 paramMap.add(Constants.PARAM_TEXT, theNarrative); 081 } 082 if (theTypes != null) { 083 paramMap.add(Constants.PARAM_TYPE, theTypes); 084 } else { 085 paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive())); 086 } 087 088 paramMap.setEverythingMode( 089 theIds != null && theIds.getValuesAsQueryTokens().size() == 1 090 ? EverythingModeEnum.PATIENT_INSTANCE 091 : EverythingModeEnum.PATIENT_TYPE); 092 paramMap.setSort(theSort); 093 paramMap.setLastUpdated(theLastUpdated); 094 if (theIds != null) { 095 if (theMdmExpand) { 096 theIds.getValuesAsQueryTokens().forEach(param -> param.setMdmExpand(true)); 097 } 098 paramMap.add("_id", theIds); 099 } 100 101 if (!isPagingProviderDatabaseBacked(theRequest)) { 102 paramMap.setLoadSynchronous(true); 103 } 104 105 adjustCount(theRequest, paramMap); 106 107 return mySearchCoordinatorSvc.registerSearch( 108 this, 109 paramMap, 110 getResourceName(), 111 new CacheControlDirective().parse(theRequest.getHeaders(Constants.HEADER_CACHE_CONTROL)), 112 theRequest); 113 } 114 115 private void adjustCount(RequestDetails theRequest, SearchParameterMap theParamMap) { 116 if (theRequest.getServer() == null) { 117 return; 118 } 119 120 if (theParamMap.getCount() == null && theRequest.getServer().getDefaultPageSize() != null) { 121 theParamMap.setCount(theRequest.getServer().getDefaultPageSize()); 122 return; 123 } 124 125 Integer maxPageSize = theRequest.getServer().getMaximumPageSize(); 126 if (maxPageSize != null && theParamMap.getCount() > maxPageSize) { 127 ourLog.info( 128 "Reducing {} from {} to {} which is the maximum allowable page size.", 129 Constants.PARAM_COUNT, 130 theParamMap.getCount(), 131 maxPageSize); 132 theParamMap.setCount(maxPageSize); 133 } 134 } 135 136 @Override 137 @Transactional(propagation = Propagation.SUPPORTS) 138 public IBundleProvider patientInstanceEverything( 139 HttpServletRequest theServletRequest, 140 RequestDetails theRequestDetails, 141 PatientEverythingParameters theQueryParams, 142 IIdType theId) { 143 TokenOrListParam id = new TokenOrListParam().add(new TokenParam(theId.getIdPart())); 144 return doEverythingOperation( 145 id, 146 theQueryParams.getCount(), 147 theQueryParams.getOffset(), 148 theQueryParams.getLastUpdated(), 149 theQueryParams.getSort(), 150 theQueryParams.getContent(), 151 theQueryParams.getNarrative(), 152 theQueryParams.getFilter(), 153 theQueryParams.getTypes(), 154 theQueryParams.getMdmExpand(), 155 theRequestDetails); 156 } 157 158 @Override 159 @Transactional(propagation = Propagation.SUPPORTS) 160 public IBundleProvider patientTypeEverything( 161 HttpServletRequest theServletRequest, 162 RequestDetails theRequestDetails, 163 PatientEverythingParameters theQueryParams, 164 TokenOrListParam theId) { 165 return doEverythingOperation( 166 theId, 167 theQueryParams.getCount(), 168 theQueryParams.getOffset(), 169 theQueryParams.getLastUpdated(), 170 theQueryParams.getSort(), 171 theQueryParams.getContent(), 172 theQueryParams.getNarrative(), 173 theQueryParams.getFilter(), 174 theQueryParams.getTypes(), 175 theQueryParams.getMdmExpand(), 176 theRequestDetails); 177 } 178}