001package ca.uhn.fhir.cql.common.helper; 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.cqframework.cql.cql2elm.CqlTranslator; 025import org.cqframework.cql.cql2elm.CqlTranslatorException; 026import org.cqframework.cql.cql2elm.LibraryManager; 027import org.cqframework.cql.cql2elm.ModelManager; 028import org.cqframework.cql.elm.execution.Library; 029import org.cqframework.cql.elm.tracking.TrackBack; 030import org.opencds.cqf.cql.engine.execution.CqlLibraryReader; 031 032import javax.xml.bind.JAXBException; 033import java.io.ByteArrayInputStream; 034import java.io.IOException; 035import java.io.InputStream; 036import java.nio.charset.StandardCharsets; 037import java.util.ArrayList; 038 039public class TranslatorHelper { 040 public static Library readLibrary(InputStream xmlStream) { 041 try { 042 return CqlLibraryReader.read(xmlStream); 043 } catch (IOException | JAXBException e) { 044 throw new IllegalArgumentException(Msg.code(1660) + "Error encountered while reading ELM xml: " + e.getMessage()); 045 } 046 } 047 048 public static String errorsToString(Iterable<CqlTranslatorException> exceptions) { 049 ArrayList<String> errors = new ArrayList<>(); 050 for (CqlTranslatorException error : exceptions) { 051 TrackBack tb = error.getLocator(); 052 String lines = tb == null ? "[n/a]" 053 : String.format("%s [%d:%d, %d:%d] ", 054 (tb.getLibrary() != null ? tb.getLibrary().getId() 055 + (tb.getLibrary().getVersion() != null ? ("-" + tb.getLibrary().getVersion()) : "") 056 : ""), 057 tb.getStartLine(), tb.getStartChar(), tb.getEndLine(), tb.getEndChar()); 058 errors.add(lines + error.getMessage()); 059 } 060 061 return String.join("\n", errors); 062 } 063 064 public static CqlTranslator getTranslator(String cql, LibraryManager libraryManager, ModelManager modelManager) { 065 return getTranslator(new ByteArrayInputStream(cql.getBytes(StandardCharsets.UTF_8)), libraryManager, 066 modelManager); 067 } 068 069 public static CqlTranslator getTranslator(InputStream cqlStream, LibraryManager libraryManager, 070 ModelManager modelManager) { 071 ArrayList<CqlTranslator.Options> options = new ArrayList<>(); 072 options.add(CqlTranslator.Options.EnableAnnotations); 073 options.add(CqlTranslator.Options.EnableLocators); 074 options.add(CqlTranslator.Options.DisableListDemotion); 075 options.add(CqlTranslator.Options.DisableListPromotion); 076 options.add(CqlTranslator.Options.DisableMethodInvocation); 077 CqlTranslator translator; 078 try { 079 translator = CqlTranslator.fromStream(cqlStream, modelManager, libraryManager, 080 options.toArray(new CqlTranslator.Options[options.size()])); 081 } catch (IOException e) { 082 throw new IllegalArgumentException(Msg.code(1661) + String.format("Errors occurred translating library: %s", e.getMessage())); 083 } 084 085 return translator; 086 } 087 088 public static Library translateLibrary(String cql, LibraryManager libraryManager, ModelManager modelManager) { 089 return translateLibrary(new ByteArrayInputStream(cql.getBytes(StandardCharsets.UTF_8)), libraryManager, 090 modelManager); 091 } 092 093 public static Library translateLibrary(InputStream cqlStream, LibraryManager libraryManager, 094 ModelManager modelManager) { 095 CqlTranslator translator = getTranslator(cqlStream, libraryManager, modelManager); 096 return readLibrary(new ByteArrayInputStream(translator.toXml().getBytes(StandardCharsets.UTF_8))); 097 } 098 099 public static Library translateLibrary(CqlTranslator translator) { 100 return readLibrary(new ByteArrayInputStream(translator.toXml().getBytes(StandardCharsets.UTF_8))); 101 } 102}