001/*
002 * #%L
003 * HAPI FHIR JPA - Search Parameters
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.searchparam.extractor;
021
022import ca.uhn.fhir.context.RuntimeSearchParam;
023import ca.uhn.fhir.jpa.model.entity.*;
024import org.hl7.fhir.instance.model.api.IBase;
025import org.hl7.fhir.instance.model.api.IBaseResource;
026
027import java.util.ArrayList;
028import java.util.Collection;
029import java.util.Collections;
030import java.util.Date;
031import java.util.HashSet;
032import java.util.List;
033
034public interface ISearchParamExtractor {
035
036        /**
037         * Constant for the {@literal theSearchParamFilter} parameters on this interface
038         * indicating that all search parameters should be indexed.
039         */
040        ISearchParamFilter ALL_PARAMS = t -> t;
041
042        /**
043         * Constant for the {@literal theSearchParamFilter} parameters on this interface
044         * indicating that no search parameters should be indexed.
045         */
046        ISearchParamFilter NO_PARAMS = t -> Collections.emptyList();
047
048        default SearchParamSet<ResourceIndexedSearchParamDate> extractSearchParamDates(IBaseResource theResource) {
049                return extractSearchParamDates(theResource, ALL_PARAMS);
050        }
051
052        SearchParamSet<ResourceIndexedSearchParamDate> extractSearchParamDates(
053                        IBaseResource theResource, ISearchParamFilter theSearchParamFilter);
054
055        default SearchParamSet<ResourceIndexedSearchParamNumber> extractSearchParamNumber(IBaseResource theResource) {
056                return extractSearchParamNumber(theResource, ALL_PARAMS);
057        }
058
059        SearchParamSet<ResourceIndexedSearchParamNumber> extractSearchParamNumber(
060                        IBaseResource theResource, ISearchParamFilter theSearchParamFilter);
061
062        default SearchParamSet<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(IBaseResource theResource) {
063                return extractSearchParamQuantity(theResource, ALL_PARAMS);
064        }
065
066        SearchParamSet<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(
067                        IBaseResource theResource, ISearchParamFilter theSearchParamFilter);
068
069        default SearchParamSet<ResourceIndexedSearchParamQuantityNormalized> extractSearchParamQuantityNormalized(
070                        IBaseResource theResource) {
071                return extractSearchParamQuantityNormalized(theResource, ALL_PARAMS);
072        }
073
074        SearchParamSet<ResourceIndexedSearchParamQuantityNormalized> extractSearchParamQuantityNormalized(
075                        IBaseResource theResource, ISearchParamFilter theSearchParamFilter);
076
077        default SearchParamSet<ResourceIndexedSearchParamString> extractSearchParamStrings(IBaseResource theResource) {
078                return extractSearchParamStrings(theResource, ALL_PARAMS);
079        }
080
081        SearchParamSet<ResourceIndexedSearchParamString> extractSearchParamStrings(
082                        IBaseResource theResource, ISearchParamFilter theSearchParamFilter);
083
084        default SearchParamSet<ResourceIndexedSearchParamComposite> extractSearchParamComposites(
085                        IBaseResource theResource) {
086                return extractSearchParamComposites(theResource, ALL_PARAMS);
087        }
088
089        SearchParamSet<ResourceIndexedSearchParamComposite> extractSearchParamComposites(
090                        IBaseResource theResource, ISearchParamFilter theSearchParamFilter);
091
092        default SearchParamSet<BaseResourceIndexedSearchParam> extractSearchParamTokens(IBaseResource theResource) {
093                return extractSearchParamTokens(theResource, ALL_PARAMS);
094        }
095
096        SearchParamSet<BaseResourceIndexedSearchParam> extractSearchParamTokens(
097                        IBaseResource theResource, ISearchParamFilter theSearchParamFilter);
098
099        SearchParamSet<BaseResourceIndexedSearchParam> extractSearchParamTokens(
100                        IBaseResource theResource, RuntimeSearchParam theSearchParam);
101
102        SearchParamSet<BaseResourceIndexedSearchParam> extractSearchParamSpecial(
103                        IBaseResource theResource, ISearchParamFilter theSearchParamFilter);
104
105        SearchParamSet<ResourceIndexedComboStringUnique> extractSearchParamComboUnique(
106                        String theResourceType, ResourceIndexedSearchParams theParams);
107
108        SearchParamSet<ResourceIndexedComboTokenNonUnique> extractSearchParamComboNonUnique(
109                        String theResourceType, ResourceIndexedSearchParams theParams);
110
111        default SearchParamSet<ResourceIndexedSearchParamUri> extractSearchParamUri(IBaseResource theResource) {
112                return extractSearchParamUri(theResource, ALL_PARAMS);
113        }
114
115        SearchParamSet<ResourceIndexedSearchParamUri> extractSearchParamUri(
116                        IBaseResource theResource, ISearchParamFilter theSearchParamFilter);
117
118        SearchParamSet<PathAndRef> extractResourceLinks(IBaseResource theResource, boolean theWantLocalReferences);
119
120        String[] split(String theExpression);
121
122        List<String> extractParamValuesAsStrings(RuntimeSearchParam theActiveSearchParam, IBaseResource theResource);
123
124        List<IBase> extractValues(String thePaths, IBase theResource);
125
126        String toRootTypeName(IBase nextObject);
127
128        String toTypeName(IBase nextObject);
129
130        PathAndRef extractReferenceLinkFromResource(IBase theValue, String thePath);
131
132        Date extractDateFromResource(IBase theValue, String thePath);
133
134        ResourceIndexedSearchParamToken createSearchParamForCoding(
135                        String theResourceType, RuntimeSearchParam theSearchParam, IBase theValue);
136
137        String getDisplayTextForCoding(IBase theValue);
138
139        BaseSearchParamExtractor.IValueExtractor getPathValueExtractor(IBase theResource, String theSinglePath);
140
141        List<IBase> getCodingsFromCodeableConcept(IBase theValue);
142
143        String getDisplayTextFromCodeableConcept(IBase theValue);
144
145        @FunctionalInterface
146        interface ISearchParamFilter {
147
148                /**
149                 * Given the list of search parameters for indexing, an implementation of this
150                 * interface may selectively remove any that it wants to remove (or can add if desired).
151                 * <p>
152                 * Implementations must not modify the list that is passed in. If changes are
153                 * desired, a new list must be created and returned.
154                 */
155                Collection<RuntimeSearchParam> filterSearchParams(Collection<RuntimeSearchParam> theSearchParams);
156        }
157
158        class SearchParamSet<T> extends HashSet<T> {
159
160                private List<String> myWarnings;
161
162                public void addWarning(String theWarning) {
163                        if (myWarnings == null) {
164                                myWarnings = new ArrayList<>();
165                        }
166                        myWarnings.add(theWarning);
167                }
168
169                List<String> getWarnings() {
170                        if (myWarnings == null) {
171                                return Collections.emptyList();
172                        }
173                        return myWarnings;
174                }
175        }
176}