001/*- 002 * #%L 003 * HAPI FHIR JPA Server 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.search; 021 022import ca.uhn.fhir.jpa.api.config.JpaStorageSettings; 023import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc; 024import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; 025import ca.uhn.fhir.rest.api.server.IBundleProvider; 026import ca.uhn.fhir.rest.api.server.RequestDetails; 027import ca.uhn.fhir.rest.server.SimpleBundleProvider; 028import jakarta.annotation.Nullable; 029import org.hl7.fhir.instance.model.api.IBaseResource; 030 031import java.util.Collections; 032import java.util.List; 033import java.util.function.Supplier; 034 035/** 036 * Figure out how we're going to run the query up front, and build a branchless strategy object. 037 */ 038public class SearchStrategyFactory { 039 private final JpaStorageSettings myStorageSettings; 040 041 @Nullable 042 private final IFulltextSearchSvc myFulltextSearchSvc; 043 044 public interface ISearchStrategy extends Supplier<IBundleProvider> {} 045 046 // someday 047 // public class DirectHSearch implements ISearchStrategy {}; 048 // public class JPAOffsetSearch implements ISearchStrategy {}; 049 // public class JPASavedSearch implements ISearchStrategy {}; 050 // public class JPAHybridHSearchSavedSearch implements ISearchStrategy {}; 051 // public class SavedSearchAdaptorStrategy implements ISearchStrategy {}; 052 053 public SearchStrategyFactory( 054 JpaStorageSettings theStorageSettings, @Nullable IFulltextSearchSvc theFulltextSearchSvc) { 055 myStorageSettings = theStorageSettings; 056 myFulltextSearchSvc = theFulltextSearchSvc; 057 } 058 059 public boolean isSupportsHSearchDirect( 060 String theResourceType, SearchParameterMap theParams, RequestDetails theRequestDetails) { 061 return myFulltextSearchSvc != null 062 && myStorageSettings.isStoreResourceInHSearchIndex() 063 && myStorageSettings.isAdvancedHSearchIndexing() 064 && myFulltextSearchSvc.supportsAllOf(theParams) 065 && theParams.getSummaryMode() == null 066 && theParams.getSearchTotalMode() == null; 067 } 068 069 public ISearchStrategy makeDirectStrategy( 070 String theSearchUUID, 071 String theResourceType, 072 SearchParameterMap theParams, 073 RequestDetails theRequestDetails) { 074 return () -> { 075 if (myFulltextSearchSvc == null) { 076 return new SimpleBundleProvider(Collections.emptyList(), theSearchUUID); 077 } 078 079 List<IBaseResource> resources = 080 myFulltextSearchSvc.searchForResources(theResourceType, theParams, theRequestDetails); 081 SimpleBundleProvider result = new SimpleBundleProvider(resources, theSearchUUID); 082 result.setSize(resources.size()); 083 return result; 084 }; 085 } 086}