001package ca.uhn.fhir.cql.common.evaluation; 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 org.apache.commons.lang3.Validate; 025import org.cqframework.cql.cql2elm.CqlTranslator; 026import org.cqframework.cql.cql2elm.CqlTranslatorException; 027import org.cqframework.cql.cql2elm.CqlTranslatorOptions; 028import org.cqframework.cql.cql2elm.LibraryManager; 029import org.cqframework.cql.cql2elm.ModelManager; 030import org.cqframework.cql.elm.execution.Library; 031import org.cqframework.cql.elm.execution.VersionedIdentifier; 032 033import javax.xml.bind.JAXBException; 034import java.io.ByteArrayInputStream; 035import java.nio.charset.StandardCharsets; 036import java.util.ArrayList; 037import java.util.Collection; 038import java.util.HashMap; 039import java.util.Map; 040 041import static ca.uhn.fhir.cql.common.helper.TranslatorHelper.errorsToString; 042import static ca.uhn.fhir.cql.common.helper.TranslatorHelper.getTranslator; 043import static ca.uhn.fhir.cql.common.helper.TranslatorHelper.readLibrary; 044 045public class LibraryLoader implements org.opencds.cqf.cql.engine.execution.LibraryLoader { 046 private LibraryManager libraryManager; 047 private ModelManager modelManager; 048 private Map<String, Library> libraries = new HashMap<>(); 049 050 // private static final Logger logger = 051 // LoggerFactory.getLogger(LibraryLoader.class); 052 053 public Collection<Library> getLibraries() { 054 return this.libraries.values(); 055 } 056 057 public LibraryManager getLibraryManager() { 058 return this.libraryManager; 059 } 060 061 public ModelManager getModelManager() { 062 return this.modelManager; 063 } 064 065 public LibraryLoader(LibraryManager libraryManager, ModelManager modelManager) { 066 this.libraryManager = libraryManager; 067 this.modelManager = modelManager; 068 } 069 070 private Library resolveLibrary(VersionedIdentifier libraryIdentifier) { 071 Validate.notNull(libraryIdentifier, "Library identifier is null."); 072 073 Validate.notNull(libraryIdentifier.getId(), "Library identifier id is null."); 074 075 String mangledId = this.mangleIdentifer(libraryIdentifier); 076 077 Library library = libraries.get(mangledId); 078 if (library == null) { 079 library = loadLibrary(libraryIdentifier); 080 libraries.put(mangledId, library); 081 } 082 083 return library; 084 } 085 086 private String mangleIdentifer(VersionedIdentifier libraryIdentifier) { 087 String id = libraryIdentifier.getId(); 088 String version = libraryIdentifier.getVersion(); 089 090 return version == null ? id : id + "-" + version; 091 } 092 093 private Library loadLibrary(VersionedIdentifier libraryIdentifier) { 094 org.hl7.elm.r1.VersionedIdentifier identifier = new org.hl7.elm.r1.VersionedIdentifier() 095 .withId(libraryIdentifier.getId()).withSystem(libraryIdentifier.getSystem()) 096 .withVersion(libraryIdentifier.getVersion()); 097 098 ArrayList<CqlTranslatorException> errors = new ArrayList<>(); 099 org.hl7.elm.r1.Library translatedLibrary = libraryManager.resolveLibrary(identifier, CqlTranslatorOptions.defaultOptions(), errors).getLibrary(); 100 101 if (CqlTranslatorException.HasErrors(errors)) { 102 throw new IllegalArgumentException(Msg.code(1657) + errorsToString(errors)); 103 } 104 try { 105 CqlTranslator translator = getTranslator("", libraryManager, modelManager); 106 107 if (translator.getErrors().size() > 0) { 108 throw new IllegalArgumentException(Msg.code(1658) + errorsToString(translator.getErrors())); 109 } 110 111 return readLibrary(new ByteArrayInputStream( 112 translator.convertToXml(translatedLibrary).getBytes(StandardCharsets.UTF_8))); 113 } catch (JAXBException e) { 114 throw new IllegalArgumentException(Msg.code(1659) + String.format("Errors occurred translating library %s%s.", 115 identifier.getId(), identifier.getVersion() != null ? ("-" + identifier.getVersion()) : "")); 116 } 117 } 118 119 @Override 120 public Library load(VersionedIdentifier versionedIdentifier) { 121 return resolveLibrary(versionedIdentifier); 122 } 123}