001/*-
002 * #%L
003 * HAPI FHIR JPA Server - Master Data Management
004 * %%
005 * Copyright (C) 2014 - 2023 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.mdm.svc.candidate;
021
022import ca.uhn.fhir.interceptor.model.RequestPartitionId;
023import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
024import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
025import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
026import ca.uhn.fhir.mdm.api.IMdmSettings;
027import ca.uhn.fhir.mdm.svc.MdmSearchParamSvc;
028import ca.uhn.fhir.rest.api.server.IBundleProvider;
029import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
030import org.hl7.fhir.instance.model.api.IAnyResource;
031import org.slf4j.Logger;
032import org.slf4j.LoggerFactory;
033import org.springframework.beans.factory.annotation.Autowired;
034
035import java.util.Optional;
036
037public class CandidateSearcher {
038        private static final Logger ourLog = LoggerFactory.getLogger(CandidateSearcher.class);
039        private final DaoRegistry myDaoRegistry;
040        private final IMdmSettings myMdmSettings;
041        private final MdmSearchParamSvc myMdmSearchParamSvc;
042
043        @Autowired
044        public CandidateSearcher(
045                        DaoRegistry theDaoRegistry, IMdmSettings theMdmSettings, MdmSearchParamSvc theMdmSearchParamSvc) {
046                myDaoRegistry = theDaoRegistry;
047                myMdmSettings = theMdmSettings;
048                myMdmSearchParamSvc = theMdmSearchParamSvc;
049        }
050
051        /**
052         * Perform a search for mdm candidates.
053         *
054         * @param theResourceType     the type of resources searched on
055         * @param theResourceCriteria the criteria used to search for the candidates
056         * @param partitionId         the partition for the search
057         * @return Optional.empty() if >= IMdmSettings.getCandidateSearchLimit() candidates are found, otherwise
058         * return the bundle provider for the search results.
059         */
060        public Optional<IBundleProvider> search(
061                        String theResourceType, String theResourceCriteria, RequestPartitionId partitionId) {
062                SearchParameterMap searchParameterMap =
063                                myMdmSearchParamSvc.mapFromCriteria(theResourceType, theResourceCriteria);
064
065                searchParameterMap.setLoadSynchronousUpTo(myMdmSettings.getCandidateSearchLimit());
066
067                IFhirResourceDao<?> resourceDao = myDaoRegistry.getResourceDao(theResourceType);
068                SystemRequestDetails systemRequestDetails = new SystemRequestDetails();
069                systemRequestDetails.setRequestPartitionId(partitionId);
070                IBundleProvider retval = resourceDao.search(searchParameterMap, systemRequestDetails);
071
072                if (retval.size() != null && retval.size() >= myMdmSettings.getCandidateSearchLimit()) {
073                        return Optional.empty();
074                }
075                return Optional.of(retval);
076        }
077
078        /**
079         * Perform a search for mdm candidates.
080         *
081         * @param theResourceType     the type of resources searched on
082         * @param theResourceCriteria the criteria used to search for the candidates
083         * @return Optional.empty() if >= IMdmSettings.getCandidateSearchLimit() candidates are found, otherwise
084         * return the bundle provider for the search results.
085         */
086        public Optional<IBundleProvider> search(String theResourceType, String theResourceCriteria) {
087                return this.search(theResourceType, theResourceCriteria, RequestPartitionId.allPartitions());
088        }
089
090        public static String idOrType(IAnyResource theResource, String theResourceType) {
091                if (theResource.getIdElement() == null || theResource.getIdElement().isEmpty()) {
092                        return theResourceType;
093                }
094                return theResource.getIdElement().toUnqualifiedVersionless().toString();
095        }
096}