Skip to content

Commit

Permalink
Move the operational logic out of the controller
Browse files Browse the repository at this point in the history
  • Loading branch information
jkotanchik-SB committed May 18, 2023
1 parent c193d04 commit df56374
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 87 deletions.
Original file line number Diff line number Diff line change
@@ -1,36 +1,23 @@
package gov.cms.mat.cql_elm_translation.controllers;

import gov.cms.mat.cql_elm_translation.cql_translator.MadieLibrarySourceProvider;
import gov.cms.mat.cql_elm_translation.data.RequestData;
import gov.cms.mat.cql_elm_translation.data.DataCriteria;
import gov.cms.mat.cql_elm_translation.exceptions.CqlFormatException;
import gov.cms.mat.cql_elm_translation.service.CqlConversionService;
import gov.cms.mat.cql_elm_translation.service.DataCriteriaService;
import gov.cms.mat.cql_elm_translation.utils.cql.CQLFilter;
import gov.cms.mat.cql_elm_translation.utils.cql.parsing.CqlParserListener;
import gov.cms.mat.cql_elm_translation.utils.cql.parsing.model.CQLModel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.cqframework.cql.cql2elm.CqlTranslator;
import org.cqframework.cql.cql2elm.LibraryBuilder;
import org.cqframework.cql.cql2elm.model.CompiledLibrary;
import org.cqframework.cql.tools.formatter.CqlFormatterVisitor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.w3._1999.xhtml.Q;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.Principal;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequiredArgsConstructor
public class CqlToolsController {

private final CqlConversionService cqlConversionService;
private final DataCriteriaService dataCriteriaService;

@PutMapping("/cql/format")
Expand All @@ -52,45 +39,11 @@ public ResponseEntity<String> formatCql(@RequestBody String cqlData, Principal p
}

@GetMapping("/cql/dataCriteria")
public ResponseEntity<Map<String,Set<String>>> getDataCriteria(
public ResponseEntity<DataCriteria> getDataCriteria(
@RequestBody String cql,
@RequestHeader("Authorization") String accessToken) {

//Run Translator to compile libraries
RequestData requestData =
RequestData.builder()
.cqlData(cql)
.showWarnings(false)
.signatures(LibraryBuilder.SignatureLevel.All)
.annotations(true)
.locators(true)
.disableListDemotion(true)
.disableListPromotion(true)
.disableMethodInvocation(false)
.validateUnits(true)
.resultTypes(true)
.build();

MadieLibrarySourceProvider librarySourceProvider = new MadieLibrarySourceProvider();
cqlConversionService.setUpLibrarySourceProvider(cql, accessToken);
CqlTranslator cqlTranslator = cqlConversionService.processCqlData(requestData);

Map<String, String> includedLibrariesCql = new HashMap<>();
for (CompiledLibrary l : cqlTranslator.getTranslatedLibraries().values()) {
try {
includedLibrariesCql.putIfAbsent(
l.getIdentifier().getId() +"-"+l.getIdentifier().getVersion(),
new String(
librarySourceProvider
.getLibrarySource(l.getLibrary().getIdentifier())
.readAllBytes(),
StandardCharsets.UTF_8));
} catch (IOException e) {
throw new RuntimeException(e);
}
}

return ResponseEntity.ok(
dataCriteriaService.parseDataCriteriaFromCql(cql, includedLibrariesCql, cqlTranslator));
dataCriteriaService.parseDataCriteriaFromCql(cql, accessToken));
}
}
Original file line number Diff line number Diff line change
@@ -1,73 +1,90 @@
package gov.cms.mat.cql_elm_translation.service;

import gov.cms.mat.cql_elm_translation.utils.cql.CQLFilter;
import gov.cms.mat.cql_elm_translation.cql_translator.MadieLibrarySourceProvider;
import gov.cms.mat.cql_elm_translation.data.DataCriteria;
import gov.cms.mat.cql_elm_translation.data.RequestData;
import gov.cms.mat.cql_elm_translation.utils.cql.CQLTools;
import gov.cms.mat.cql_elm_translation.utils.cql.parsing.CqlParserListener;
import gov.cms.mat.cql_elm_translation.utils.cql.parsing.model.CQLModel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.cqframework.cql.cql2elm.CqlTranslator;
import org.cqframework.cql.cql2elm.LibraryBuilder;
import org.cqframework.cql.cql2elm.model.CompiledLibrary;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Slf4j
@Service
@RequiredArgsConstructor
public class DataCriteriaService {

public Map<String, Set<String>> parseDataCriteriaFromCql(String cql, Map<String,String> includedLibraries, CqlTranslator cqlTranslator) {
private final CqlConversionService cqlConversionService;

CQLFilter cqlFilter = new CQLFilter(
public DataCriteria parseDataCriteriaFromCql(String cql, String accessToken) {
//Run Translator to compile libraries
MadieLibrarySourceProvider librarySourceProvider = new MadieLibrarySourceProvider();
cqlConversionService.setUpLibrarySourceProvider(cql, accessToken);
CqlTranslator cqlTranslator = runTranslator(cql);

CQLTools cqlTools = new CQLTools(
cql,
includedLibraries,
getExpressionsFromCql(cql),
getIncludedLibrariesCql(librarySourceProvider, cqlTranslator),
getParentExpressions(cql),
cqlTranslator
);

try {
cqlFilter.filter();
cqlTools.generate();
} catch (IOException e) {
throw new RuntimeException(e);
}

return buildDataCriteria(cqlFilter.getExpressionNameToValuesetDataTypeMap(),
cqlFilter.getExpressionNameToCodeDataTypeMap());
return cqlTools.getDataCriteria();
}

private Map<String, Set<String>> buildDataCriteria(Map<String, Map<String, Set<String>>> valueSetBackedDataCriteriaByExpression,
Map<String, Map<String, Set<String>>> codeBackedDataCriteriaByExpression) {
Map<String, Set<String>> dataCriteria = new HashMap<>();
condense(valueSetBackedDataCriteriaByExpression, dataCriteria);
condense(codeBackedDataCriteriaByExpression, dataCriteria);
return dataCriteria;
private Map<String, String> getIncludedLibrariesCql(MadieLibrarySourceProvider librarySourceProvider,
CqlTranslator cqlTranslator) {
Map<String, String> includedLibrariesCql = new HashMap<>();
for (CompiledLibrary l : cqlTranslator.getTranslatedLibraries().values()) {
try {
includedLibrariesCql.putIfAbsent(
l.getIdentifier().getId() +"-"+l.getIdentifier().getVersion(),
new String(
librarySourceProvider
.getLibrarySource(l.getLibrary().getIdentifier())
.readAllBytes(),
StandardCharsets.UTF_8));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return includedLibrariesCql;
}

private void condense(Map<String, Map<String, Set<String>>> expressionMap,
Map<String, Set<String>> target) {
// key -> Definition/Function (aka Expressions)
// Value -> Map
// Key -> Expression
// Value -> Map
// Key -> ValueSet/Code
// Value -> Set
// Key -> ValueSet/Code
// Value -> QDM Data Type
expressionMap.values().forEach(ex -> {
for (String terminology : ex.keySet()) {
if (target.get(terminology) != null) {
target.get(terminology).addAll(ex.get(terminology));
} else {
target.put(terminology, ex.get(terminology));
}
}
});
}
private CqlTranslator runTranslator(String cql) {
RequestData requestData =
RequestData.builder()
.cqlData(cql)
.showWarnings(false)
.signatures(LibraryBuilder.SignatureLevel.All)
.annotations(true)
.locators(true)
.disableListDemotion(true)
.disableListPromotion(true)
.disableMethodInvocation(false)
.validateUnits(true)
.resultTypes(true)
.build();

return cqlConversionService.processCqlData(requestData);
}

private List<String> getExpressionsFromCql(String cql) {
private List<String> getParentExpressions(String cql) {
CQLModel cqlModel;
try {
CqlParserListener listener = new CqlParserListener(cql);
Expand Down

0 comments on commit df56374

Please sign in to comment.