Skip to content

Commit

Permalink
LNK-1809 Improvements to issue FHIRPath expressions (#702)
Browse files Browse the repository at this point in the history
* Improving issue FHIRPath expressions to use format `Bundle.entry[x].resource.where(id = Y)`, which is requested by FHIR Analysts to make it easier to work with validation results.
Tested the resulting FHIRPath with dev.fhirpath-lab.com and the FHIRPath still works.

* Adding the `.ofType()` back to the FHIRPath expression
  • Loading branch information
seanmcilvenna committed Feb 23, 2024
1 parent 78ad84f commit f65d608
Showing 1 changed file with 36 additions and 0 deletions.
36 changes: 36 additions & 0 deletions core/src/main/java/com/lantanagroup/link/validation/Validator.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class Validator {
Expand Down Expand Up @@ -272,6 +274,39 @@ private void validateResource(Resource resource, OperationOutcome outcome, Opera
}
}

/**
* Update the issue locations/expressions to use resource IDs instead of "ofType(MedicationRequest)" (for example).
* Only works on Bundle resources and looks for patterns such as "Bundle.entry[X].resource.ofType(MedicationRequest)" to replace with "Bundle.entry[X].resource.where(id = '123')"
*
* @param resource The resource to amend
* @param outcome The outcome to amend
*/
private void improveIssueExpressions(Resource resource, OperationOutcome outcome) {
final String regex = "^Bundle.entry\\[(\\d+)\\]\\.resource\\.ofType\\(.+?\\)(.*)$";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);

if (resource.getResourceType() == ResourceType.Bundle) {
Bundle bundle = (Bundle) resource;
for (OperationOutcome.OperationOutcomeIssueComponent issue : outcome.getIssue()) {
if (!issue.getExpression().isEmpty()) {
String location = issue.getExpression().get(0).asStringValue();
final Matcher matcher = pattern.matcher(location);

if (matcher.matches()) {
int entryIndex = Integer.parseInt(matcher.group(1));
if (entryIndex < bundle.getEntry().size()) {
String resourceId = bundle.getEntry().get(entryIndex).getResource().getIdElement().getIdPart();
String resourceType = bundle.getEntry().get(entryIndex).getResource().getResourceType().toString();
ArrayList newExpressions = new ArrayList<>(issue.getExpression());
newExpressions.set(0, new StringType("Bundle.entry[" + entryIndex + "].resource.ofType(" + resourceType + ").where(id = '" + resourceId + "')" + matcher.group(2)));
issue.setExpression(newExpressions);
}
}
}
}
}
}

public OperationOutcome validate(Resource resource, OperationOutcome.IssueSeverity severity) {
logger.debug("Validating {}", resource.getResourceType().toString().toLowerCase());

Expand All @@ -282,6 +317,7 @@ public OperationOutcome validate(Resource resource, OperationOutcome.IssueSeveri
outcome.setId(UUID.randomUUID().toString());

this.validateResource(resource, outcome, severity);
this.improveIssueExpressions(resource, outcome);

Date end = new Date();
logger.debug("Validation took {} seconds", TimeUnit.MILLISECONDS.toSeconds(end.getTime() - start.getTime()));
Expand Down

0 comments on commit f65d608

Please sign in to comment.