001package ca.uhn.fhir.cql.r4.provider;
002
003/*-
004 * #%L
005 * HAPI FHIR JPA Server - Clinical Quality Language
006 * %%
007 * Copyright (C) 2014 - 2022 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.i18n.Msg;
024import ca.uhn.fhir.cql.common.provider.LibraryResolutionProvider;
025import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
026import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
027import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
028import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
029import ca.uhn.fhir.rest.api.server.RequestDetails;
030import ca.uhn.fhir.rest.param.StringParam;
031import ca.uhn.fhir.rest.param.TokenParam;
032import ca.uhn.fhir.rest.param.UriParam;
033import org.hl7.fhir.instance.model.api.IBaseResource;
034import org.hl7.fhir.r4.model.IdType;
035import org.hl7.fhir.r4.model.Library;
036import org.opencds.cqf.cql.engine.terminology.TerminologyProvider;
037import org.springframework.beans.factory.annotation.Autowired;
038import org.springframework.stereotype.Component;
039
040import java.util.ArrayList;
041import java.util.List;
042import java.util.Objects;
043
044@Component
045public class LibraryResolutionProviderImpl implements LibraryResolutionProvider<Library> {
046        @Autowired
047        private IFhirResourceDao<Library> myLibraryDao;
048        @Autowired
049        DaoRegistry registry;
050        @Autowired
051        TerminologyProvider defaultTerminologyProvider;
052
053        // TODO: Figure out if we should throw an exception or something here.
054        @Override
055        public void update(Library library) {
056                myLibraryDao.update(library);
057        }
058
059        @Override
060        public Library resolveLibraryById(String libraryId, RequestDetails theRequestDetails) {
061                try {
062                        return myLibraryDao.read(new IdType(libraryId), theRequestDetails);
063                } catch (Exception e) {
064                        throw new IllegalArgumentException(Msg.code(1665) + String.format("Could not resolve library id %s", libraryId));
065                }
066        }
067
068        @Override
069        public Library resolveLibraryByName(String libraryName, String libraryVersion) {
070                Iterable<org.hl7.fhir.r4.model.Library> libraries = getLibrariesByName(libraryName, new SystemRequestDetails());
071                org.hl7.fhir.r4.model.Library library = LibraryResolutionProvider.selectFromList(libraries, libraryVersion,
072                        x -> x.getVersion());
073
074                if (library == null) {
075                        throw new IllegalArgumentException(Msg.code(1666) + String.format("Could not resolve library name %s", libraryName));
076                }
077
078                return library;
079        }
080
081        @Override
082        public Library resolveLibraryByCanonicalUrl(String url, RequestDetails theRequestDetails) {
083                Objects.requireNonNull(url, "url must not be null");
084
085                String[] parts = url.split("\\|");
086                String resourceUrl = parts[0];
087                String version = null;
088                if (parts.length > 1) {
089                        version = parts[1];
090                }
091
092                SearchParameterMap map = SearchParameterMap.newSynchronous();
093                map.add("url", new UriParam(resourceUrl));
094                if (version != null) {
095                        map.add("version", new TokenParam(version));
096                }
097
098                ca.uhn.fhir.rest.api.server.IBundleProvider bundleProvider = myLibraryDao.search(map, theRequestDetails);
099
100                if (bundleProvider.size() == null || bundleProvider.size() == 0) {
101                        return null;
102                }
103                List<IBaseResource> resourceList = bundleProvider.getAllResources();
104                return LibraryResolutionProvider.selectFromList(resolveLibraries(resourceList), version, x -> x.getVersion());
105        }
106
107        private Iterable<org.hl7.fhir.r4.model.Library> getLibrariesByName(String name, RequestDetails theRequestDetails) {
108                // Search for libraries by name
109                SearchParameterMap map = SearchParameterMap.newSynchronous();
110                map.add("name", new StringParam(name, true));
111                ca.uhn.fhir.rest.api.server.IBundleProvider bundleProvider = myLibraryDao.search(map, theRequestDetails);
112
113                if (bundleProvider.size() == null || bundleProvider.size() == 0) {
114                        return new ArrayList<>();
115                }
116                List<IBaseResource> resourceList = bundleProvider.getAllResources();
117                return resolveLibraries(resourceList);
118        }
119
120        private Iterable<org.hl7.fhir.r4.model.Library> resolveLibraries(List<IBaseResource> resourceList) {
121                List<org.hl7.fhir.r4.model.Library> ret = new ArrayList<>();
122                for (IBaseResource res : resourceList) {
123                        Class<?> clazz = res.getClass();
124                        ret.add((org.hl7.fhir.r4.model.Library) clazz.cast(res));
125                }
126                return ret;
127        }
128}