Skip to content

Commit e00ba32

Browse files
committed
parameter matching fixed
1 parent 5e62512 commit e00ba32

File tree

1 file changed

+87
-76
lines changed

1 file changed

+87
-76
lines changed

hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java

+87-76
Original file line numberDiff line numberDiff line change
@@ -490,20 +490,14 @@ private InMemoryMatchResult matchResourceParam(
490490
return InMemoryMatchResult.successfulMatch();
491491
} else {
492492
return InMemoryMatchResult.fromBoolean(theAndOrParams.stream()
493-
.allMatch(nextAnd -> nextAnd.stream().anyMatch(token -> {
494-
if (token instanceof ReferenceParam
495-
&& ((ReferenceParam) token).getChain() != null) {
496-
return matchChainedReferenceParam(
497-
theParamName, theResourceName, theResource, (ReferenceParam) token);
498-
}
499-
return matchParam(
500-
theStorageSettings,
501-
theResourceName,
502-
theParamName,
503-
theParamDef,
504-
theSearchParams,
505-
token);
506-
})));
493+
.allMatch(nextAnd -> matchParams(
494+
theStorageSettings,
495+
theResourceName,
496+
theParamName,
497+
theParamDef,
498+
nextAnd,
499+
theSearchParams,
500+
theResource)));
507501
}
508502
case COMPOSITE:
509503
case HAS:
@@ -522,80 +516,37 @@ private InMemoryMatchResult matchResourceParam(
522516
}
523517
}
524518

525-
private boolean matchChainedReferenceParam(
526-
String theParamName, String theResourceName, IBaseResource theResource, ReferenceParam referenceParam) {
527-
RuntimeSearchParam activeSearchParam =
528-
mySearchParamRegistry.getActiveSearchParam(theResourceName, theParamName);
529-
List<? extends IBase> bases = searchParamExtractor
530-
.getPathValueExtractor(theResource, activeSearchParam.getPath())
531-
.get();
532-
return bases.stream()
533-
.filter(IBaseReference.class::isInstance)
534-
.map(IBaseReference.class::cast)
535-
.map(IBaseReference::getResource)
536-
.anyMatch(resource -> {
537-
// Obtain the next parameter name, modifier and chain
538-
String[] chains = referenceParam.getChain().split("\\.");
539-
String parameterNameWithModifier = chains[0];
540-
String chain = chains.length > 1 ? StringUtils.join(chains, ".", 1, chains.length) : null;
541-
542-
String[] parameterNameAndModifier = parameterNameWithModifier.split(":");
543-
String parameterName = parameterNameAndModifier[0];
544-
String resourceType = parameterNameAndModifier.length > 1 ? parameterNameAndModifier[1] : null;
545-
546-
// Find the path of next search parameter in the next resource
547-
RuntimeSearchParam resourceSearchParam = mySearchParamRegistry.getActiveSearchParam(
548-
resource.getIdElement().getResourceType(), parameterName);
549-
// Make sure the search param exists and modifier matches with next resource
550-
if (resourceSearchParam == null
551-
|| (referenceParam.getResourceType() != null
552-
&& !referenceParam
553-
.getResourceType()
554-
.equals(resource.getIdElement().getResourceType()))) {
555-
return false;
556-
}
557-
558-
// Create new search parameter map to match the next resource
559-
SearchParameterMap searchParameterMap = new SearchParameterMap();
560-
if (resourceSearchParam.getParamType().equals(RestSearchParameterTypeEnum.REFERENCE)) {
561-
searchParameterMap.add(
562-
parameterName, new ReferenceParam(resourceType, chain, referenceParam.getValue()));
563-
} else {
564-
TokenParam tokenParam;
565-
if (referenceParam.getValue().contains("|")) {
566-
String[] systemAndValue = referenceParam.getValue().split("\\|");
567-
tokenParam = new TokenParam(systemAndValue[0], systemAndValue[1]);
568-
} else {
569-
tokenParam = new TokenParam(referenceParam.getValue());
570-
}
571-
searchParameterMap.add(parameterName, tokenParam);
572-
}
573-
574-
// Recursively match the chained resources
575-
return searchParamMatcher
576-
.match(searchParameterMap, resource)
577-
.matched();
578-
});
579-
}
580-
581519
private boolean matchParams(
582520
StorageSettings theStorageSettings,
583521
String theResourceName,
584522
String theParamName,
585523
RuntimeSearchParam theParamDef,
586524
List<? extends IQueryParameterType> theOrList,
587-
ResourceIndexedSearchParams theSearchParams) {
525+
ResourceIndexedSearchParams theSearchParams,
526+
IBaseResource theResource) {
588527

589528
boolean isNegativeTest = isNegative(theParamDef, theOrList);
590529
// negative tests like :not and :not-in must not match any or-clause, so we invert the quantifier.
591530
if (isNegativeTest) {
592531
return theOrList.stream()
593532
.allMatch(token -> matchParam(
594-
theStorageSettings, theResourceName, theParamName, theParamDef, theSearchParams, token));
533+
theStorageSettings,
534+
theResourceName,
535+
theParamName,
536+
theParamDef,
537+
theSearchParams,
538+
token,
539+
theResource));
595540
} else {
596541
return theOrList.stream()
597542
.anyMatch(token -> matchParam(
598-
theStorageSettings, theResourceName, theParamName, theParamDef, theSearchParams, token));
543+
theStorageSettings,
544+
theResourceName,
545+
theParamName,
546+
theParamDef,
547+
theSearchParams,
548+
token,
549+
theResource));
599550
}
600551
}
601552

@@ -618,14 +569,17 @@ private boolean matchParam(
618569
String theParamName,
619570
RuntimeSearchParam theParamDef,
620571
ResourceIndexedSearchParams theSearchParams,
621-
IQueryParameterType theToken) {
572+
IQueryParameterType theToken,
573+
IBaseResource theResource) {
622574
if (theParamDef.getParamType().equals(RestSearchParameterTypeEnum.TOKEN)) {
623575
return matchTokenParam(
624576
theStorageSettings, theResourceName, theParamName, theParamDef, theSearchParams, (TokenParam)
625577
theToken);
626-
} else {
627-
return theSearchParams.matchParam(theStorageSettings, theResourceName, theParamName, theParamDef, theToken);
578+
} else if (theParamDef.getParamType().equals(RestSearchParameterTypeEnum.REFERENCE)
579+
&& ((ReferenceParam) theToken).getChain() != null) {
580+
return matchChainedReferenceParam(theParamName, theResourceName, theResource, (ReferenceParam) theToken);
628581
}
582+
return theSearchParams.matchParam(theStorageSettings, theResourceName, theParamName, theParamDef, theToken);
629583
}
630584

631585
/**
@@ -672,6 +626,63 @@ private boolean matchTokenParam(
672626
}
673627
}
674628

629+
private boolean matchChainedReferenceParam(
630+
String theParamName, String theResourceName, IBaseResource theResource, ReferenceParam referenceParam) {
631+
RuntimeSearchParam activeSearchParam =
632+
mySearchParamRegistry.getActiveSearchParam(theResourceName, theParamName);
633+
List<? extends IBase> bases = searchParamExtractor
634+
.getPathValueExtractor(theResource, activeSearchParam.getPath())
635+
.get();
636+
return bases.stream()
637+
.filter(IBaseReference.class::isInstance)
638+
.map(IBaseReference.class::cast)
639+
.map(IBaseReference::getResource)
640+
.anyMatch(resource -> {
641+
// Obtain the next parameter name, modifier and chain
642+
String[] chains = referenceParam.getChain().split("\\.");
643+
String parameterNameWithModifier = chains[0];
644+
String chain = chains.length > 1 ? StringUtils.join(chains, ".", 1, chains.length) : null;
645+
646+
String[] parameterNameAndModifier = parameterNameWithModifier.split(":");
647+
String parameterName = parameterNameAndModifier[0];
648+
String modifier = parameterNameAndModifier.length > 1 ? parameterNameAndModifier[1] : null;
649+
650+
// Find the path of next search parameter in the next resource
651+
RuntimeSearchParam resourceSearchParam = mySearchParamRegistry.getActiveSearchParam(
652+
resource.getIdElement().getResourceType(), parameterName);
653+
// Make sure the search param exists and modifier matches with next resource
654+
if (resourceSearchParam == null
655+
|| (referenceParam.getResourceType() != null
656+
&& !referenceParam
657+
.getResourceType()
658+
.equals(resource.getIdElement().getResourceType()))) {
659+
return false;
660+
}
661+
662+
// Create new search parameter map to match the next resource
663+
SearchParameterMap searchParameterMap = new SearchParameterMap();
664+
if (resourceSearchParam.getParamType().equals(RestSearchParameterTypeEnum.REFERENCE)) {
665+
searchParameterMap.add(
666+
parameterName, new ReferenceParam(modifier, chain, referenceParam.getValue()));
667+
} else {
668+
TokenParam tokenParam;
669+
if (referenceParam.getValue().contains("|")) {
670+
String[] systemAndValue = referenceParam.getValue().split("\\|");
671+
tokenParam = new TokenParam(systemAndValue[0], systemAndValue[1]);
672+
} else {
673+
tokenParam = new TokenParam(referenceParam.getValue());
674+
}
675+
tokenParam.setModifier(TokenParamModifier.forValue(":" + modifier));
676+
searchParameterMap.add(parameterName, tokenParam);
677+
}
678+
679+
// Recursively match the chained resources
680+
return searchParamMatcher
681+
.match(searchParameterMap, resource)
682+
.matched();
683+
});
684+
}
685+
675686
private boolean systemContainsCode(TokenParam theQueryParam, ResourceIndexedSearchParamToken theSearchParamToken) {
676687
IValidationSupport validationSupport = getValidationSupportOrNull();
677688
if (validationSupport == null) {

0 commit comments

Comments
 (0)