
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.search; 021 022import ca.uhn.fhir.interceptor.model.RequestPartitionId; 023import ca.uhn.fhir.jpa.config.JpaConfig; 024import ca.uhn.fhir.jpa.dao.ISearchBuilder; 025import ca.uhn.fhir.jpa.entity.Search; 026import ca.uhn.fhir.jpa.entity.SearchTypeEnum; 027import ca.uhn.fhir.jpa.model.dao.JpaPid; 028import ca.uhn.fhir.jpa.model.search.SearchStatusEnum; 029import ca.uhn.fhir.jpa.search.builder.tasks.SearchTask; 030import ca.uhn.fhir.rest.api.server.IBundleProvider; 031import ca.uhn.fhir.rest.api.server.RequestDetails; 032import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId; 033import ca.uhn.fhir.rest.param.HistorySearchStyleEnum; 034import jakarta.annotation.Nonnull; 035import jakarta.annotation.Nullable; 036import org.springframework.beans.factory.annotation.Autowired; 037import org.springframework.context.ApplicationContext; 038 039import java.util.Date; 040import java.util.List; 041import java.util.UUID; 042 043import static org.apache.commons.lang3.StringUtils.defaultIfBlank; 044 045public class PersistedJpaBundleProviderFactory { 046 047 @Autowired 048 private ApplicationContext myApplicationContext; 049 050 public PersistedJpaBundleProvider newInstance(RequestDetails theRequest, String theUuid) { 051 Object retVal = myApplicationContext.getBean(JpaConfig.PERSISTED_JPA_BUNDLE_PROVIDER, theRequest, theUuid); 052 return (PersistedJpaBundleProvider) retVal; 053 } 054 055 public PersistedJpaBundleProvider newInstance(RequestDetails theRequest, Search theSearch) { 056 Object retVal = 057 myApplicationContext.getBean(JpaConfig.PERSISTED_JPA_BUNDLE_PROVIDER_BY_SEARCH, theRequest, theSearch); 058 return (PersistedJpaBundleProvider) retVal; 059 } 060 061 public PersistedJpaSearchFirstPageBundleProvider newInstanceFirstPage( 062 RequestDetails theRequestDetails, 063 SearchTask theTask, 064 ISearchBuilder<JpaPid> theSearchBuilder, 065 RequestPartitionId theRequestPartitionId) { 066 return (PersistedJpaSearchFirstPageBundleProvider) myApplicationContext.getBean( 067 JpaConfig.PERSISTED_JPA_SEARCH_FIRST_PAGE_BUNDLE_PROVIDER, 068 theRequestDetails, 069 theTask, 070 theSearchBuilder, 071 theRequestPartitionId); 072 } 073 074 public IBundleProvider history( 075 RequestDetails theRequest, 076 String theResourceType, 077 @Nullable JpaPid theResourcePid, 078 Date theRangeStartInclusive, 079 Date theRangeEndInclusive, 080 Integer theOffset, 081 RequestPartitionId theRequestPartitionId) { 082 return history( 083 theRequest, 084 theResourceType, 085 theResourcePid, 086 theRangeStartInclusive, 087 theRangeEndInclusive, 088 theOffset, 089 null, 090 theRequestPartitionId); 091 } 092 093 public IBundleProvider history( 094 RequestDetails theRequest, 095 String theResourceType, 096 @Nullable JpaPid theResourcePid, 097 Date theRangeStartInclusive, 098 Date theRangeEndInclusive, 099 Integer theOffset, 100 HistorySearchStyleEnum searchParameterType, 101 RequestPartitionId theRequestPartitionId) { 102 String resourceName = defaultIfBlank(theResourceType, null); 103 104 Search search = new Search(); 105 search.setOffset(theOffset); 106 search.setDeleted(false); 107 search.setCreated(new Date()); 108 search.setLastUpdated(theRangeStartInclusive, theRangeEndInclusive); 109 search.setUuid(UUID.randomUUID().toString()); 110 search.setResourceType(resourceName); 111 search.setResourceId(theResourcePid); 112 search.setSearchType(SearchTypeEnum.HISTORY); 113 search.setStatus(SearchStatusEnum.FINISHED); 114 search.setHistorySearchStyle(searchParameterType); 115 116 PersistedJpaBundleProvider provider = newInstance(theRequest, search); 117 provider.setRequestPartitionId(theRequestPartitionId); 118 119 return provider; 120 } 121 122 /** 123 * Create an unlimited history bundle provider for bulk export operations 124 * that can paginate through history entries for specific resource IDs. 125 */ 126 public IBundleProvider historyFromResourceIds( 127 String theResourceType, 128 @Nullable List<IResourcePersistentId<?>> theResourceIds, 129 RequestPartitionId theRequestPartitionId, 130 @Nullable Date theRangeStartInclusive, 131 @Nonnull Date theRangeEndInclusive) { 132 133 return (PersistedJpaIdSearchBundleProvider) myApplicationContext.getBean( 134 JpaConfig.PERSISTED_JPA_ID_SEARCH_BUNDLE_PROVIDER, 135 theResourceType, 136 theResourceIds, 137 theRequestPartitionId, 138 theRangeStartInclusive, 139 theRangeEndInclusive); 140 } 141}