001package ca.uhn.fhir.rest.server.util;
002
003/*
004 * #%L
005 * HAPI FHIR - Server Framework
006 * %%
007 * Copyright (C) 2014 - 2023 Smile CDR, Inc.
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import ca.uhn.fhir.context.ComboSearchParamType;
024import ca.uhn.fhir.context.RuntimeSearchParam;
025import ca.uhn.fhir.context.phonetic.IPhoneticEncoder;
026import ca.uhn.fhir.i18n.Msg;
027import ca.uhn.fhir.rest.api.Constants;
028import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
029import org.hl7.fhir.instance.model.api.IAnyResource;
030import org.hl7.fhir.instance.model.api.IIdType;
031
032import javax.annotation.Nullable;
033import java.util.Collection;
034import java.util.Collections;
035import java.util.List;
036import java.util.Optional;
037import java.util.Set;
038import java.util.TreeSet;
039
040// TODO: JA remove default methods
041public interface ISearchParamRegistry {
042
043        /**
044         * @return Returns {@literal null} if no match
045         */
046        RuntimeSearchParam getActiveSearchParam(String theResourceName, String theParamName);
047
048
049        /**
050         * @return Returns all active search params for the given resource
051         */
052        ResourceSearchParams getActiveSearchParams(String theResourceName);
053
054        /**
055         * Request that the cache be refreshed now, in the current thread
056         */
057        default void forceRefresh() {
058        }
059
060        /**
061         * Request that the cache be refreshed at the next convenient time (in a different thread)
062         */
063        default void requestRefresh() {
064        }
065
066        /**
067         * When indexing a HumanName, if a StringEncoder is set in the context, then the "phonetic" search parameter will normalize
068         * the String using this encoder.
069         *
070         * @since 5.1.0
071         */
072        default void setPhoneticEncoder(IPhoneticEncoder thePhoneticEncoder) {
073        }
074
075        default List<RuntimeSearchParam> getActiveComboSearchParams(String theResourceName) {
076                return Collections.emptyList();
077        }
078
079
080        // TODO ND remove default implementation
081        default List<RuntimeSearchParam> getActiveComboSearchParams(String theResourceName, ComboSearchParamType theParamType) {
082                return Collections.emptyList();
083        }
084
085        // TODO ND remove default implementation
086        default Optional<RuntimeSearchParam> getActiveComboSearchParamById(String theResourceName, IIdType theId) {
087                return Optional.empty();
088        }
089
090        default List<RuntimeSearchParam> getActiveComboSearchParams(String theResourceName, Set<String> theParamNames) {
091                return Collections.emptyList();
092        }
093
094        /**
095         * Returns a collection containing all of the valid active search parameters. This method is intended for
096         * creating error messages for users as opposed to actual search processing. It will include meta parameters
097         * such as <code>_id</code> and <code>_lastUpdated</code>.
098         */
099        default Collection<String> getValidSearchParameterNamesIncludingMeta(String theResourceName) {
100                TreeSet<String> retval;
101                ResourceSearchParams activeSearchParams = getActiveSearchParams(theResourceName);
102                if (activeSearchParams == null) {
103                        retval = new TreeSet<>();
104                } else {
105                        retval = new TreeSet<>(activeSearchParams.getSearchParamNames());
106                }
107                retval.add(IAnyResource.SP_RES_ID);
108                retval.add(Constants.PARAM_LASTUPDATED);
109                return retval;
110        }
111
112        /**
113         * Fetch a SearchParameter by URL
114         *
115         * @return Returns <code>null</code> if it can't be found
116         */
117        @Nullable
118        RuntimeSearchParam getActiveSearchParamByUrl(String theUrl);
119
120        /**
121         * Find a search param for a resource. First, check the resource itself, then check the top-level `Resource` resource.
122         *
123         * @param theResourceType the resource type.
124         * @param theParamName the search parameter name.
125         *
126         * @return the {@link RuntimeSearchParam} that is found.
127         */
128        default RuntimeSearchParam getRuntimeSearchParam(String theResourceType, String theParamName) {
129                RuntimeSearchParam availableSearchParamDef = getActiveSearchParam(theResourceType, theParamName);
130                if (availableSearchParamDef == null) {
131                        availableSearchParamDef = getActiveSearchParam("Resource", theParamName);
132                }
133                if (availableSearchParamDef == null) {
134                        throw new InvalidRequestException(Msg.code(1209) + "Unknown parameter name: " + theResourceType + ':' + theParamName);
135                }
136                return availableSearchParamDef;
137        }
138}