use of ca.uhn.fhir.context.RuntimeSearchParam in project pathling by aehrc.
the class ManifestConverter method populateScope.
void populateScope(@Nonnull final PassportScope passportScope, @Nonnull final VisaManifest manifest) {
// Create a filter for the Patient resource.
final String patientIdCollection = manifest.getPatientIds().stream().map(id -> "'" + id + "'").collect(Collectors.joining(" combine "));
final String patientIdFilter = "identifier.where(system = '" + StringLiteralPath.escapeFhirPathString(patientIdSystem) + "').where(value in (" + patientIdCollection + "))" + ".empty().not()";
final Set<String> patientFilters = passportScope.get(ResourceType.PATIENT);
if (patientFilters == null) {
passportScope.put(ResourceType.PATIENT, new HashSet<>(List.of(patientIdFilter)));
} else {
patientFilters.add(patientIdFilter);
}
// See: https://www.hl7.org/fhir/r4/compartmentdefinition-patient.html
for (final ResourceType resourceType : ResourceType.values()) {
if (resourceType.equals(ResourceType.DOMAINRESOURCE) || resourceType.equals(ResourceType.RESOURCE) || resourceType.equals(ResourceType.NULL)) {
continue;
}
final RuntimeResourceDefinition definition = fhirContext.getResourceDefinition(resourceType.toCode());
final List<RuntimeSearchParam> searchParams = definition.getSearchParamsForCompartmentName("Patient");
for (final RuntimeSearchParam searchParam : searchParams) {
final String path = searchParam.getPath();
// Remove the leading "[resource type]." from the path.
final String pathTrimmed = path.replaceFirst("^" + resourceType.toCode() + "\\.", "");
// Paths that end with this resolve pattern are polymorphic references, and will need
// to be resolved using `ofType()` within our implementation.
final String resolvePattern = ".where(resolve() is Patient)";
final String filter;
if (pathTrimmed.endsWith(resolvePattern)) {
filter = pathTrimmed.replace(resolvePattern, ".resolve().ofType(Patient)." + patientIdFilter);
} else {
final Set<String> targets = searchParam.getTargets();
if (targets.size() > 0 && !targets.contains("Patient")) {
// Patient, we need to skip it altogether.
continue;
} else if (targets.size() == 1) {
// If the search parameter is monomorphic, we can resolve it without `ofType`.
filter = pathTrimmed + ".resolve()." + patientIdFilter;
} else {
// If the search parameter is polymorphic, we also need to resolve it to Patient. Note
// that polymorphic references with an "Any" type have zero targets.
filter = pathTrimmed + ".resolve().ofType(Patient)." + patientIdFilter;
}
}
// Add the filter to the map.
final Set<String> filters = passportScope.get(resourceType);
if (filters == null) {
passportScope.put(resourceType, new HashSet<>(List.of(filter)));
} else {
filters.add(filter);
}
}
}
}
Aggregations