diff --git a/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/BaseDao.java b/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/BaseDao.java index ac4518fec..697dcdced 100644 --- a/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/BaseDao.java +++ b/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/BaseDao.java @@ -704,35 +704,35 @@ protected void handleProviderReference(OpenmrsFhirCriteriaContext c protected Optional handleCodeableConcept(OpenmrsFhirCriteriaContext criteriaContext, TokenAndListParam concepts, @Nonnull From ConceptAliasJoin, @Nonnull String conceptMapAlias, @Nonnull String conceptReferenceTermAlias) { - if (concepts == null) { - return Optional.empty(); - } - - Optional> conceptAliasJoin = criteriaContext.getJoin(ConceptAliasJoin.getAlias()); - return conceptAliasJoin - .map(join -> handleAndListParamBySystem(criteriaContext.getCriteriaBuilder(), concepts, (system, tokens) -> { - if (system.isEmpty()) { - criteriaContext.getCriteriaBuilder() - .literal(tokensToParams(tokens).map(NumberUtils::toInt).collect(Collectors.toList())); - return Optional - .of(criteriaContext.getCriteriaBuilder().or( - criteriaContext.getCriteriaBuilder() - .in(join.get("conceptId") - .in(criteriaContext.getCriteriaBuilder() - .literal(tokensToParams(tokens).map(NumberUtils::toInt) - .collect(Collectors.toList())))), - criteriaContext.getCriteriaBuilder().in(join.get("uuid") - .in(criteriaContext.getCriteriaBuilder().literal(tokensToList(tokens)))))); - - } else { - Join conceptMapAliasJoin = criteriaContext.addJoin(join, "conceptMappings", conceptMapAlias); - criteriaContext.addJoin(conceptMapAliasJoin, "conceptReferenceTerm", conceptReferenceTermAlias); - - return Optional.of( - generateSystemQuery(criteriaContext, system, tokensToList(tokens), conceptReferenceTermAlias)); - } - })).orElse(null); - + // if (concepts == null) { + // return Optional.empty(); + // } + // + // Optional> conceptAliasJoin = criteriaContext.getJoin(ConceptAliasJoin.getAlias()); + // return conceptAliasJoin + // .map(join -> handleAndListParamBySystem(criteriaContext.getCriteriaBuilder(), concepts, (system, tokens) -> { + // if (system.isEmpty()) { + // criteriaContext.getCriteriaBuilder() + // .literal(tokensToParams(tokens).map(NumberUtils::toInt).collect(Collectors.toList())); + // return Optional + // .of(criteriaContext.getCriteriaBuilder().or( + // criteriaContext.getCriteriaBuilder() + // .in(join.get("conceptId") + // .in(criteriaContext.getCriteriaBuilder() + // .literal(tokensToParams(tokens).map(NumberUtils::toInt) + // .collect(Collectors.toList())))), + // criteriaContext.getCriteriaBuilder().in(join.get("uuid") + // .in(criteriaContext.getCriteriaBuilder().literal(tokensToList(tokens)))))); + // + // } else { + // Join conceptMapAliasJoin = criteriaContext.addJoin(join, "conceptMappings", conceptMapAlias); + // criteriaContext.addJoin(conceptMapAliasJoin, "conceptReferenceTerm", conceptReferenceTermAlias); + // + // return Optional.of( + // generateSystemQuery(criteriaContext, system, tokensToList(tokens), conceptReferenceTermAlias)); + // } + // })).orElse(null); + return Optional.empty(); } protected void handleNames(OpenmrsFhirCriteriaContext criteriaContext, StringAndListParam name, @@ -950,31 +950,18 @@ protected Optional> handleSort( return Optional.of(orderings); } - @SuppressWarnings("unchecked") - protected Predicate generateSystemQuery(OpenmrsFhirCriteriaContext criteriaContext, String system, + protected Optional generateSystemQuery(OpenmrsFhirCriteriaContext criteriaContext, String system, List codes, String conceptReferenceTermAlias) { - //detached criteria - Specification spec = (root, query, - cb) -> (Predicate) query.select(root.get("conceptSource")).where(cb.equal(root.get("url"), system)); - - criteriaContext.getCriteriaQuery().where(spec.toPredicate((Root) criteriaContext.getRoot(), - (CriteriaQuery) criteriaContext.getCriteriaQuery(), criteriaContext.getCriteriaBuilder())); + OpenmrsFhirCriteriaSubquery conceptSourceSubquery = criteriaContext + .addSubquery(FhirConceptSource.class); + conceptSourceSubquery.addPredicate( + conceptSourceSubquery.getCriteriaBuilder().equal(conceptSourceSubquery.getRoot().get("url"), system)); - if (codes.size() > 1) { - return criteriaContext.getCriteriaBuilder().and( - criteriaContext.getCriteriaBuilder().equal( - getRootOrJoin(criteriaContext, conceptReferenceTermAlias).get("conceptSource"), - criteriaContext.getCriteriaQuery()), - criteriaContext.getCriteriaBuilder().in(criteriaContext.getRoot() - .get(String.format("%s.code", conceptReferenceTermAlias)).get(codes.toString()))); - } else { - return criteriaContext.getCriteriaBuilder().and( - criteriaContext.getCriteriaBuilder().equal( - getRootOrJoin(criteriaContext, conceptReferenceTermAlias).get("conceptSource"), - criteriaContext.getCriteriaQuery()), - criteriaContext.getCriteriaBuilder().equal( - criteriaContext.getRoot().get(String.format("%s.code", conceptReferenceTermAlias)), codes.get(0))); - } + return criteriaContext.getJoin(conceptReferenceTermAlias) + .map((conceptReferenceTermJoin) -> criteriaContext.getCriteriaBuilder().and( + criteriaContext.getCriteriaBuilder().in(conceptReferenceTermJoin.get("conceptSource")) + .value(conceptSourceSubquery.finalizeQuery()), + criteriaContext.getCriteriaBuilder().in(conceptReferenceTermJoin.get("code")).value(codes))); } protected Predicate generateActiveOrderQuery(OpenmrsFhirCriteriaContext criteriaContext, String path, diff --git a/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/OpenmrsFhirCriteriaContext.java b/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/OpenmrsFhirCriteriaContext.java index 9d4dfc821..14dcdc071 100644 --- a/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/OpenmrsFhirCriteriaContext.java +++ b/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/OpenmrsFhirCriteriaContext.java @@ -19,6 +19,7 @@ import javax.persistence.criteria.Order; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; +import javax.persistence.criteria.Subquery; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -118,6 +119,11 @@ public class OpenmrsFhirCriteriaContext { }); } + public OpenmrsFhirCriteriaSubquery addSubquery(Class type) { + Subquery subquery = criteriaQuery.subquery(type); + return new OpenmrsFhirCriteriaSubquery<>(criteriaBuilder, subquery, subquery.from(type)); + } + public OpenmrsFhirCriteriaContext addPredicate(Predicate predicate) { predicates.add(predicate); return this; @@ -137,10 +143,6 @@ public OpenmrsFhirCriteriaContext addResults(T result) { return Optional.ofNullable(aliases.get(alias)); } - public boolean hasAlias(String alias) { - return aliases.containsKey(alias); - } - public CriteriaQuery finalizeQuery() { return criteriaQuery.where(predicates.toArray(new Predicate[0])).orderBy(orders); } diff --git a/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/OpenmrsFhirCriteriaSubquery.java b/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/OpenmrsFhirCriteriaSubquery.java new file mode 100644 index 000000000..88c3b98e9 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/OpenmrsFhirCriteriaSubquery.java @@ -0,0 +1,49 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under + * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. + * + * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS + * graphic logo is a trademark of OpenMRS Inc. + */ +package org.openmrs.module.fhir2.api.dao.impl; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; +import javax.persistence.criteria.Subquery; + +import java.util.ArrayList; +import java.util.List; + +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class OpenmrsFhirCriteriaSubquery { + + @Getter + @NonNull + private final CriteriaBuilder criteriaBuilder; + + @Getter + @NonNull + Subquery subquery; + + @Getter + @NonNull + Root root; + + private final List predicates = new ArrayList<>(); + + public OpenmrsFhirCriteriaSubquery addPredicate(Predicate predicate) { + predicates.add(predicate); + return this; + } + + public Subquery finalizeQuery() { + return subquery.where(predicates.toArray(new Predicate[0])); + } +}