From b66a446c28ac18e49a2081b4ac908333a4a9a4b5 Mon Sep 17 00:00:00 2001 From: Thomas Papke Date: Sun, 19 May 2024 15:21:03 +0200 Subject: [PATCH] #10 Add evaluation of authorPerson query criteria as in-memory evaluation --- .../registry/query/StoredQueryVistorImpl.java | 48 ++++++++++++++++--- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/openehealth/app/xdstofhir/registry/query/StoredQueryVistorImpl.java b/src/main/java/org/openehealth/app/xdstofhir/registry/query/StoredQueryVistorImpl.java index 9d2fa04..6155ea0 100644 --- a/src/main/java/org/openehealth/app/xdstofhir/registry/query/StoredQueryVistorImpl.java +++ b/src/main/java/org/openehealth/app/xdstofhir/registry/query/StoredQueryVistorImpl.java @@ -1,5 +1,6 @@ package org.openehealth.app.xdstofhir.registry.query; +import static java.util.Collections.singletonList; import static org.openehealth.app.xdstofhir.registry.common.MappingSupport.URI_URN; import static org.openehealth.app.xdstofhir.registry.query.StoredQueryMapper.assignDefaultVersioning; import static org.openehealth.app.xdstofhir.registry.query.StoredQueryMapper.buildIdentifierQuery; @@ -14,6 +15,8 @@ import java.util.List; import java.util.Objects; import java.util.UUID; +import java.util.function.Predicate; +import java.util.regex.Pattern; import java.util.stream.StreamSupport; import ca.uhn.fhir.rest.client.api.IGenericClient; @@ -34,7 +37,11 @@ import org.openehealth.ipf.commons.ihe.xds.core.metadata.Association; import org.openehealth.ipf.commons.ihe.xds.core.metadata.AssociationLabel; import org.openehealth.ipf.commons.ihe.xds.core.metadata.AssociationType; +import org.openehealth.ipf.commons.ihe.xds.core.metadata.Author; +import org.openehealth.ipf.commons.ihe.xds.core.metadata.DocumentEntry; +import org.openehealth.ipf.commons.ihe.xds.core.metadata.Hl7v2Based; import org.openehealth.ipf.commons.ihe.xds.core.metadata.ObjectReference; +import org.openehealth.ipf.commons.ihe.xds.core.metadata.SubmissionSet; import org.openehealth.ipf.commons.ihe.xds.core.requests.query.FindDocumentsByReferenceIdQuery; import org.openehealth.ipf.commons.ihe.xds.core.requests.query.FindDocumentsQuery; import org.openehealth.ipf.commons.ihe.xds.core.requests.query.FindFoldersQuery; @@ -81,10 +88,9 @@ public class StoredQueryVistorImpl extends AbstractStoredQueryVisitor { @Override public void visit(FindDocumentsQuery query) { IQuery documentFhirQuery = prepareQuery(query); - mapDocuments(buildResultForDocuments(documentFhirQuery)); + mapDocuments(buildResultForDocuments(documentFhirQuery), doc -> authorMatcher(query.getAuthorPersons(), doc.getAuthors())); } - @Override public void visit(GetDocumentsQuery query) { var documentFhirQuery = initDocumentQuery(); @@ -282,7 +288,8 @@ public void visit(FindSubmissionSetsQuery query) { mapStatus(query.getStatus(),ListResource.STATUS, submissionSetfhirQuery); if (query.getSourceIds() != null && !query.getSourceIds().isEmpty()) submissionSetfhirQuery.where(new TokenClientParam("sourceId").exactly().codes(query.getSourceIds())); - mapSubmissionSets(buildResultForSubmissionSet(submissionSetfhirQuery)); + Predicate authorMatch = query.getAuthorPerson() != null ? sub -> authorMatcher(singletonList(query.getAuthorPerson()), sub.getAuthors()) : sub -> true; + mapSubmissionSets(buildResultForSubmissionSet(submissionSetfhirQuery), authorMatch); } @Override @@ -298,7 +305,7 @@ public void visit(FindDocumentsByReferenceIdQuery query) { documentFhirQuery.where(new TokenClientParam("related:identifier").exactly().codes(searchToken)); } } - mapDocuments(buildResultForDocuments(documentFhirQuery)); + mapDocuments(buildResultForDocuments(documentFhirQuery), doc -> authorMatcher(query.getAuthorPersons(), doc.getAuthors())); } @@ -520,13 +527,17 @@ private void mapAssociations(List associations) { } private List mapSubmissionSets(Iterable fhirSubmissions) { + return mapSubmissionSets(fhirSubmissions, (sub) -> true); + } + + private List mapSubmissionSets(Iterable fhirSubmissions, Predicate xdsSubmissionSetCriteria) { var processedFhirSubmissions = new ArrayList(); for (var submissionset : fhirSubmissions) { if (evaluateMaxCount(response)) { break; } var xdsSubmission = queryProcessor.apply(submissionset); - if (xdsSubmission != null) { + if (xdsSubmission != null && xdsSubmissionSetCriteria.test(xdsSubmission)) { assignDefaultVersioning().accept(xdsSubmission); if (isObjectRefResult) response.getReferences().add(new ObjectReference(xdsSubmission.getEntryUuid())); @@ -539,13 +550,17 @@ private List mapSubmissionSets(Iterable fhir } private List mapDocuments(Iterable fhirDocuments) { + return mapDocuments(fhirDocuments, (doc) -> true); + } + + private List mapDocuments(Iterable fhirDocuments, Predicate xdsDocumentCriteria) { var processedFhirDocs = new ArrayList(); for (var document : fhirDocuments) { if (evaluateMaxCount(response)) { break; } var xdsDoc = queryProcessor.apply(document); - if (xdsDoc != null) { + if (xdsDoc != null && xdsDocumentCriteria.test(xdsDoc)) { assignDefaultVersioning().accept(xdsDoc); if (isObjectRefResult) response.getReferences().add(new ObjectReference(xdsDoc.getEntryUuid())); @@ -570,4 +585,25 @@ private boolean evaluateMaxCount(QueryResponse response) { } + /** + * Provide a in-memory evaluation if a given authorPerson restrictions matches to a given Author. + * + * @param authorPersons - the person criteria from the incoming XDS query + * @param authorsToMatch - the authors that should match. + * @return true, if the authorPersons matches to the author's. + */ + private boolean authorMatcher(List authorPersons, List authorsToMatch) { + if (authorPersons == null) + return true; + return authorPersons.stream().allMatch(authorNameCriteria -> { + var regexQuotedQuery = Pattern.quote(authorNameCriteria) + .replace("_", "\\E.\\Q") //Map SQL single "_" to a sincle character match in regex "." + .replace("%", "\\E.*\\Q") // Map SQL wildcard "%" to a wildcard match in regx "%" + .replace("\\Q\\Q", "\\Q") // Avoid duplicate quoting + .replace("\\E\\E", "\\E"); // Avoid duplicate quoting + return authorsToMatch.stream().anyMatch(a -> Hl7v2Based.render(a.getAuthorPerson()).matches(regexQuotedQuery)); + }); + } + + }