001/*-
002 * #%L
003 * HAPI FHIR JPA Server
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.search.autocomplete;
021
022import ca.uhn.fhir.context.FhirContext;
023import ca.uhn.fhir.jpa.model.entity.StorageSettings;
024import ca.uhn.fhir.rest.param.TokenParam;
025import org.hibernate.search.mapper.orm.session.SearchSession;
026import org.hl7.fhir.instance.model.api.IBaseResource;
027import org.hl7.fhir.r4.model.Enumerations;
028import org.hl7.fhir.r4.model.ValueSet;
029
030import java.util.List;
031
032/**
033 * Adapt the autocomplete result into a ValueSet suitable for our $expand extension.
034 */
035public class ValueSetAutocompleteSearch {
036        private final FhirContext myFhirContext;
037        private final StorageSettings myStorageSettings;
038        private final TokenAutocompleteSearch myAutocompleteSearch;
039        static final int DEFAULT_SIZE = 30;
040
041        public ValueSetAutocompleteSearch(
042                        FhirContext theFhirContext, StorageSettings theStorageSettings, SearchSession theSession) {
043                myFhirContext = theFhirContext;
044                myStorageSettings = theStorageSettings;
045                myAutocompleteSearch = new TokenAutocompleteSearch(myFhirContext, myStorageSettings, theSession);
046        }
047
048        public IBaseResource search(ValueSetAutocompleteOptions theOptions) {
049                List<TokenAutocompleteHit> aggEntries = myAutocompleteSearch.search(
050                                theOptions.getResourceType(),
051                                theOptions.getSearchParamCode(),
052                                theOptions.getFilter(),
053                                theOptions.getSearchParamModifier(),
054                                (int) theOptions.getCount().orElse(DEFAULT_SIZE));
055
056                ValueSet result = new ValueSet();
057                ValueSet.ValueSetExpansionComponent expansion = new ValueSet.ValueSetExpansionComponent();
058                result.setExpansion(expansion);
059                result.setStatus(Enumerations.PublicationStatus.ACTIVE);
060                aggEntries.stream().map(this::makeCoding).forEach(expansion::addContains);
061
062                return result;
063        }
064
065        ValueSet.ValueSetExpansionContainsComponent makeCoding(TokenAutocompleteHit theSearchHit) {
066                TokenParam tokenParam = new TokenParam();
067                tokenParam.setValueAsQueryToken(myFhirContext, null, null, theSearchHit.mySystemCode);
068
069                // R4 only for now.
070                //              IBaseCoding coding = TerserUtil.newElement(myFhirContext, "Coding");
071                ValueSet.ValueSetExpansionContainsComponent coding = new ValueSet.ValueSetExpansionContainsComponent();
072                coding.setCode(tokenParam.getValue());
073                coding.setSystem(tokenParam.getSystem());
074                coding.setDisplay(theSearchHit.myDisplayText);
075
076                return coding;
077        }
078}