001/*-
002 * #%L
003 * HAPI FHIR - Master Data Management
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.mdm.svc;
021
022import ca.uhn.fhir.context.FhirContext;
023import ca.uhn.fhir.context.RuntimeResourceDefinition;
024import ca.uhn.fhir.context.RuntimeSearchParam;
025import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
026import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
027import ca.uhn.fhir.jpa.dao.ISearchBuilder;
028import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
029import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
030import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
031import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorService;
032import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
033import ca.uhn.fhir.util.SearchParameterUtil;
034import jakarta.annotation.Nullable;
035import org.apache.commons.lang3.StringUtils;
036import org.hl7.fhir.instance.model.api.IBaseResource;
037import org.springframework.beans.factory.annotation.Autowired;
038import org.springframework.stereotype.Service;
039
040import java.util.List;
041
042@Service
043public class MdmSearchParamSvc {
044        @Autowired
045        FhirContext myFhirContext;
046
047        @Autowired
048        private MatchUrlService myMatchUrlService;
049
050        @Autowired
051        private ISearchParamRegistry mySearchParamRegistry;
052
053        @Autowired
054        private SearchParamExtractorService mySearchParamExtractorService;
055
056        @Autowired
057        private SearchBuilderFactory mySearchBuilderFactory;
058
059        @Autowired
060        private DaoRegistry myDaoRegistry;
061
062        public SearchParameterMap mapFromCriteria(String theResourceType, String theResourceCriteria) {
063                RuntimeResourceDefinition resourceDef = myFhirContext.getResourceDefinition(theResourceType);
064                return myMatchUrlService.translateMatchUrl(theResourceCriteria, resourceDef);
065        }
066
067        public List<String> getValueFromResourceForSearchParam(IBaseResource theResource, String theSearchParam) {
068                String resourceType = myFhirContext.getResourceType(theResource);
069                String searchParam = SearchParameterUtil.stripModifier(theSearchParam);
070                RuntimeSearchParam activeSearchParam = mySearchParamRegistry.getActiveSearchParam(resourceType, searchParam);
071                return mySearchParamExtractorService.extractParamValuesAsStrings(activeSearchParam, theResource);
072        }
073
074        /**
075         * Given a source type, and a criteria string of the shape name=x&birthDate=y, generate a {@link SearchParameterMap}
076         * that represents this query.
077         *
078         * @param theSourceType the resource type to execute the search on
079         * @param theCriteria   the string search criteria.
080         * @return the generated SearchParameterMap, or an empty one if there is no criteria.
081         */
082        public SearchParameterMap getSearchParameterMapFromCriteria(String theSourceType, @Nullable String theCriteria) {
083                SearchParameterMap spMap;
084                if (StringUtils.isBlank(theCriteria)) {
085                        spMap = new SearchParameterMap();
086                } else {
087                        spMap = mapFromCriteria(theSourceType, theCriteria);
088                }
089                return spMap;
090        }
091
092        public ISearchBuilder generateSearchBuilderForType(String theSourceType) {
093                IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao(theSourceType);
094                return mySearchBuilderFactory.newSearchBuilder(resourceDao, theSourceType, resourceDao.getResourceType());
095        }
096
097        /**
098         * Will return true if the types match, or the search param type is '*', otherwise false.
099         *
100         * @param theSearchParamType
101         * @param theResourceType
102         * @return
103         */
104        public boolean searchParamTypeIsValidForResourceType(String theSearchParamType, String theResourceType) {
105                return theSearchParamType.equalsIgnoreCase(theResourceType) || theSearchParamType.equalsIgnoreCase("*");
106        }
107}