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}