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

com.ibm.fhir.persistence.jdbc.domain.ChainedSearchParam Maven / Gradle / Ivy

There is a newer version: 4.11.1
Show newest version
/*
 * (C) Copyright IBM Corp. 2021
 *
 * SPDX-License-Identifier: Apache-2.0
 */

package com.ibm.fhir.persistence.jdbc.domain;

import java.util.logging.Logger;

import com.ibm.fhir.persistence.exception.FHIRPersistenceException;
import com.ibm.fhir.search.SearchConstants.Modifier;
import com.ibm.fhir.search.SearchConstants.Type;
import com.ibm.fhir.search.parameters.QueryParameter;

/**
 * Search parameter chaining. We try to support both forward and reverse parameter
 * chaining here because one chain can be mixed
 */
public class ChainedSearchParam extends SearchParam {
    private static final String CLASSNAME = ChainedSearchParam.class.getName();
    private static final Logger logger = Logger.getLogger(CLASSNAME);

    /**
     * Public constructor
     * @param rootResourceType
     * @param name
     * @param queryParameter
     */
    public ChainedSearchParam(String rootResourceType, String name, QueryParameter queryParameter) {
        super(rootResourceType, name, queryParameter);
    }

    @Override
    public  T visit(T query, SearchQueryVisitor visitor) throws FHIRPersistenceException {
        QueryParameter currentParm = getQueryParameter();

        // The query representing the last exists to be added, to
        // which we'll add the final filter if there is one
        T currentSubQuery = query;

        // Walk the parameter chain, nesting an EXISTS clause each time
        while (currentParm != null) {
            QueryParameter nextParm = currentParm.getNextParameter();

            // need to check reverse-chained first, because reverse-chained params also have isChained() == true!
            if (currentParm.isReverseChained()) {
                currentSubQuery = addReverseChained(currentSubQuery, visitor, currentParm);
            } else if (currentParm.isChained()) {
                currentSubQuery = addChained(currentSubQuery, visitor, currentParm);
            } else if (nextParm == null) {
                addFinalFilter(currentSubQuery, visitor, currentParm);
            } else {
                logger.warning("intermediate chained search parameter must be chained or reverse-chained, not " + currentParm);
                throw new FHIRPersistenceException("Invalid search parameter chain");
            }

            currentParm = nextParm;
        }
        return query;
    }

    private  T addChained(T currentSubQuery, SearchQueryVisitor visitor, QueryParameter currentParm) throws FHIRPersistenceException {
        // Ask the visitor to attach an exists sub-query to the currentSubQuery
        return visitor.addChained(currentSubQuery, currentParm);
    }

    private  T addReverseChained(T currentSubQuery, SearchQueryVisitor visitor, QueryParameter currentParm) throws FHIRPersistenceException {
        return visitor.addReverseChained(currentSubQuery, currentParm);
    }

    /**
     * Add a final filter to the last element of the chain (the current query). This could be a simple parameter
     * filter, or a composite (which is slightly more complex, and could be multiple EXISTS).
     * @param 
     * @param currentSubQuery
     * @param visitor
     * @param currentParm
     * @throws FHIRPersistenceException
     */
    private  void addFinalFilter(T currentSubQuery, SearchQueryVisitor visitor, QueryParameter currentParm) throws FHIRPersistenceException {
        if (currentParm.getModifier() == Modifier.MISSING) {
            // Process this final element as a MissingSearchParam
            MissingSearchParam msp = new MissingSearchParam(getRootResourceType(), getName(), currentParm);
            msp.visit(currentSubQuery, visitor);
        }
        else if (currentParm.getType() == Type.COMPOSITE) {
            visitor.addCompositeParam(currentSubQuery, currentParm);
        } else {
            visitor.addFilter(currentSubQuery, currentParm);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy