001/*-
002 * #%L
003 * HAPI FHIR Storage api
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.bulk.export.svc;
021
022import ca.uhn.fhir.context.FhirContext;
023import ca.uhn.fhir.context.RuntimeResourceDefinition;
024import ca.uhn.fhir.jpa.bulk.export.model.ExportPIDIteratorParameters;
025import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
026import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
027import ca.uhn.fhir.rest.param.DateRangeParam;
028import org.hl7.fhir.instance.model.api.IIdType;
029import org.slf4j.Logger;
030import org.springframework.beans.factory.annotation.Autowired;
031
032import java.util.Collections;
033import java.util.Date;
034import java.util.List;
035import java.util.stream.Collectors;
036
037import static org.slf4j.LoggerFactory.getLogger;
038
039public class BulkExportHelperService {
040        private static final Logger ourLog = getLogger(BulkExportHelperService.class);
041
042        @Autowired
043        private MatchUrlService myMatchUrlService;
044
045        @Autowired
046        private FhirContext myContext;
047
048        /**
049         * Given the parameters, create the search parameter map based on type filters and the _since parameter.
050         *
051         * The input boolean theConsiderSince determines whether to consider the lastUpdated date in the search parameter map.
052         */
053        public List<SearchParameterMap> createSearchParameterMapsForResourceType(
054                        RuntimeResourceDefinition theDef, ExportPIDIteratorParameters theParams, boolean theConsiderSince) {
055                String resourceType = theDef.getName();
056                List<String> typeFilters = theParams.getFilters();
057                List<SearchParameterMap> spMaps = null;
058                spMaps = typeFilters.stream()
059                                .filter(typeFilter -> typeFilter.startsWith(resourceType + "?"))
060                                .map(filter -> buildSearchParameterMapForTypeFilter(filter, theDef, theParams.getStartDate()))
061                                .collect(Collectors.toList());
062
063                typeFilters.stream().filter(filter -> !filter.contains("?")).forEach(filter -> {
064                        ourLog.warn(
065                                        "Found a strange _typeFilter that we could not process: {}. _typeFilters should follow the format ResourceType?searchparameter=value .",
066                                        filter);
067                });
068
069                // None of the _typeFilters applied to the current resource type, so just make a simple one.
070                if (spMaps.isEmpty()) {
071                        SearchParameterMap defaultMap = new SearchParameterMap();
072                        if (theConsiderSince) {
073                                enhanceSearchParameterMapWithCommonParameters(defaultMap, theParams.getStartDate());
074                        }
075                        spMaps = Collections.singletonList(defaultMap);
076                }
077
078                return spMaps;
079        }
080
081        private SearchParameterMap buildSearchParameterMapForTypeFilter(
082                        String theFilter, RuntimeResourceDefinition theDef, Date theSinceDate) {
083                SearchParameterMap searchParameterMap = myMatchUrlService.translateMatchUrl(theFilter, theDef);
084                enhanceSearchParameterMapWithCommonParameters(searchParameterMap, theSinceDate);
085                return searchParameterMap;
086        }
087
088        private void enhanceSearchParameterMapWithCommonParameters(SearchParameterMap map, Date theSinceDate) {
089                map.setLoadSynchronous(true);
090                if (theSinceDate != null) {
091                        map.setLastUpdated(new DateRangeParam(theSinceDate, null));
092                }
093        }
094
095        /**
096         * Converts the ResourceId to an IIdType.
097         * Eg: Patient/123 -> IIdType
098         * @param theResourceId - string version if the id
099         * @return - the IIdType
100         */
101        public IIdType toId(String theResourceId) {
102                IIdType retVal = myContext.getVersion().newIdType();
103                retVal.setValue(theResourceId);
104                return retVal;
105        }
106}