All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cqframework.cql.elm.requirements.ElmQueryContext Maven / Gradle / Ivy

package org.cqframework.cql.elm.requirements;

import java.util.*;
import java.util.List;
import org.hl7.elm.r1.*;

public class ElmQueryContext {
    public ElmQueryContext(VersionedIdentifier libraryIdentifier, Query query) {
        if (libraryIdentifier == null) {
            throw new IllegalArgumentException("libraryIdentifier is required");
        }
        if (query == null) {
            throw new IllegalArgumentException("query is required");
        }
        this.libraryIdentifier = libraryIdentifier;
        this.query = query;
        this.queryRequirements = new ElmConjunctiveRequirement(libraryIdentifier, query);
        this.queryRequirement = new ElmQueryRequirement(libraryIdentifier, query);
    }

    private VersionedIdentifier libraryIdentifier;
    private Query query;
    private ElmExpressionRequirement queryRequirements;
    private ElmQueryAliasContext definitionContext;
    private List aliasContexts = new ArrayList();
    private ElmQueryLetContext letDefinitionContext;
    private List letContexts = new ArrayList();
    private ElmQueryRequirement queryRequirement;

    public void enterLetDefinitionContext(LetClause letClause) {
        if (letDefinitionContext != null) {
            throw new IllegalArgumentException("Let clause definition already in progress");
        }
        letDefinitionContext = new ElmQueryLetContext(libraryIdentifier, letClause);
    }

    public ElmQueryLetContext exitLetDefinitionContext(ElmRequirement requirements) {
        if (letDefinitionContext == null) {
            throw new IllegalArgumentException("Let definition not in progress");
        }
        letContexts.add(letDefinitionContext);
        ElmQueryLetContext result = letDefinitionContext;
        result.setRequirements(requirements);
        letDefinitionContext = null;
        return result;
    }

    public ElmQueryLetContext resolveLet(String identifier) {
        for (ElmQueryLetContext letContext : letContexts) {
            if (letContext.getIdentifier().equals(identifier)) {
                return letContext;
            }
        }
        return null;
    }

    public ElmQueryLetContext getLetContext(LetClause letClause) {
        for (ElmQueryLetContext letContext : letContexts) {
            if (letContext.getLetClause() == letClause) {
                return letContext;
            }
        }
        return null;
    }

    public void enterAliasDefinitionContext(AliasedQuerySource querySource) {
        if (definitionContext != null) {
            throw new IllegalArgumentException("Alias definition already in progress");
        }
        definitionContext = new ElmQueryAliasContext(libraryIdentifier, querySource);
    }

    public ElmQueryAliasContext exitAliasDefinitionContext(ElmRequirement requirements) {
        if (definitionContext == null) {
            throw new IllegalArgumentException("Alias definition not in progress");
        }
        aliasContexts.add(definitionContext);
        ElmQueryAliasContext result = definitionContext;
        result.setRequirements(requirements);
        definitionContext = null;
        return result;
    }

    public ElmQueryAliasContext resolveAlias(String aliasName) {
        for (ElmQueryAliasContext aliasContext : aliasContexts) {
            if (aliasContext.getAlias().equals(aliasName)) {
                return aliasContext;
            }
        }

        return null;
    }

    private ElmQueryAliasContext getAliasContext(AliasedQuerySource querySource) {
        for (ElmQueryAliasContext aliasContext : aliasContexts) {
            if (aliasContext.getAlias().equals(querySource.getAlias())) {
                return aliasContext;
            }
        }

        return null;
    }

    public void descopeAlias(AliasedQuerySource querySource) {
        ElmQueryAliasContext aliasContext = getAliasContext(querySource);
        if (aliasContext != null) {
            aliasContexts.remove(aliasContext);
            queryRequirement.addDataRequirements(aliasContext.getRequirements());
        }
        aliasContexts.removeIf(x -> x.getAlias().equals(querySource.getAlias()));
    }

    public void reportQueryRequirements(ElmRequirement requirements) {
        if (requirements instanceof ElmExpressionRequirement) {
            queryRequirements = queryRequirements.combine((ElmExpressionRequirement) requirements);
        }
    }

    public ElmQueryRequirement getQueryRequirement(ElmRequirement childRequirements, ElmRequirementsContext context) {
        // Gather requirements from any lets in scope in the query
        for (ElmQueryLetContext letContext : letContexts) {
            queryRequirement.addDataRequirements(letContext.getRequirements());
        }

        // Gather requirements from any sources still in scope in the query
        for (ElmQueryAliasContext aliasContext : aliasContexts) {
            queryRequirement.addDataRequirements(aliasContext.getRequirements());
        }

        // add child requirements gathered during the context
        queryRequirement.addChildRequirements(childRequirements);

        // distribute query requirements to each alias
        if (context.getOptions().getAnalyzeDataRequirements()) {
            queryRequirement.distributeExpressionRequirement(queryRequirements, context);
        }

        return queryRequirement;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy