Exemple #1
0
  @Override
  public FhirQueryAuditDataset enrichAuditDatasetFromRequest(
      FhirQueryAuditDataset auditDataset, Object request, Map<String, Object> parameters) {
    FhirQueryAuditDataset dataset =
        super.enrichAuditDatasetFromRequest(auditDataset, request, parameters);

    Parameters params = (Parameters) request;
    if (params != null) {
      Type sourceIdentifier =
          params
              .getParameter()
              .stream()
              .filter(ppc -> Constants.SOURCE_IDENTIFIER_NAME.equals(ppc.getName()))
              .map(Parameters.ParametersParameterComponent::getValue)
              .findFirst()
              .orElseThrow(() -> new RuntimeException("No sourceIdentifier in PIX query"));

      if (sourceIdentifier instanceof Identifier) {
        Identifier identifier = (Identifier) sourceIdentifier;
        dataset
            .getPatientIds()
            .add(String.format("%s|%s", identifier.getSystem(), identifier.getValue()));
      } else if (sourceIdentifier instanceof StringType) {
        StringType identifier = (StringType) sourceIdentifier;
        dataset.getPatientIds().add(identifier.getValue());
      } else {
        dataset.getPatientIds().add(sourceIdentifier.toString());
      }
    }
    return dataset;
  }
 public OperationOutcomeIssueComponent asIssue(OperationOutcome op) throws Exception {
   OperationOutcomeIssueComponent issue = new OperationOutcome.OperationOutcomeIssueComponent();
   issue.setCode(new CodeableConcept());
   issue.getCode().addCoding().setSystem(type.getSystem()).setCode(type.toCode());
   if (location != null) {
     StringType s = new StringType();
     s.setValue(
         location
             + (line >= 0 && col >= 0
                 ? " (line " + Integer.toString(line) + ", col" + Integer.toString(col) + ")"
                 : ""));
     issue.getLocation().add(s);
   }
   issue.setSeverity(level);
   issue.setDetails(message);
   if (source != null) {
     issue.getExtension().add(ToolingExtensions.makeIssueSource(source));
   }
   return issue;
 }
  private void validateQuestionAnswers(
      List<ValidationMessage> theErrors,
      QuestionComponent theQuestion,
      LinkedList<String> thePathStack,
      AnswerFormat type,
      org.hl7.fhir.instance.model.QuestionnaireResponse.QuestionComponent answerQuestion,
      QuestionnaireResponse theAnswers,
      boolean theValidateRequired) {

    String linkId = theQuestion.getLinkId();
    Set<Class<? extends Type>> allowedAnswerTypes = determineAllowedAnswerTypes(type);
    if (allowedAnswerTypes.isEmpty()) {
      for (QuestionAnswerComponent nextAnswer : answerQuestion.getAnswer()) {
        rule(
            theErrors,
            IssueType.BUSINESSRULE,
            thePathStack,
            ElementUtil.isEmpty(nextAnswer.getValue()),
            "Question with linkId[{0}] has no answer type but an answer was provided",
            linkId);
      }
    } else {
      rule(
          theErrors,
          IssueType.BUSINESSRULE,
          thePathStack,
          !(answerQuestion.getAnswer().size() > 1 && !theQuestion.getRepeats()),
          "Multiple answers to non repeating question with linkId[{0}]",
          linkId);
      if (theValidateRequired) {
        rule(
            theErrors,
            IssueType.BUSINESSRULE,
            thePathStack,
            !(theQuestion.getRequired() && answerQuestion.getAnswer().isEmpty()),
            "Missing answer to required question with linkId[{0}]",
            linkId);
      } else {
        hint(
            theErrors,
            IssueType.BUSINESSRULE,
            thePathStack,
            !(theQuestion.getRequired() && answerQuestion.getAnswer().isEmpty()),
            "Missing answer to required question with linkId[{0}]",
            linkId);
      }
    }

    int answerIdx = -1;
    for (QuestionAnswerComponent nextAnswer : answerQuestion.getAnswer()) {
      answerIdx++;
      try {
        thePathStack.add("answer[" + answerIdx + "]");
        Type nextValue = nextAnswer.getValue();
        if (nextValue == null) {
          continue;
        }
        if (!allowedAnswerTypes.contains(nextValue.getClass())) {
          rule(
              theErrors,
              IssueType.BUSINESSRULE,
              thePathStack,
              false,
              "Answer to question with linkId[{0}] found of type [{1}] but this is invalid for question of type [{2}]",
              linkId,
              nextValue.getClass().getSimpleName(),
              type.toCode());
          continue;
        }

        // Validate choice answers
        if (type == AnswerFormat.CHOICE || type == AnswerFormat.OPENCHOICE) {
          if (nextAnswer.getValue() instanceof StringType) {
            StringType answer = (StringType) nextAnswer.getValue();
            if (answer == null || isBlank(answer.getValueAsString())) {
              rule(
                  theErrors,
                  IssueType.BUSINESSRULE,
                  thePathStack,
                  false,
                  "Answer to question with linkId[{0}] is required but answer does not have a value",
                  linkId);
              continue;
            }
          } else {
            Coding coding = (Coding) nextAnswer.getValue();
            if (isBlank(coding.getCode())) {
              rule(
                  theErrors,
                  IssueType.BUSINESSRULE,
                  thePathStack,
                  false,
                  "Answer to question with linkId[{0}] is of type {1} but coding answer does not have a code",
                  linkId,
                  type.name());
              continue;
            }
            if (isBlank(coding.getSystem())) {
              rule(
                  theErrors,
                  IssueType.BUSINESSRULE,
                  thePathStack,
                  false,
                  "Answer to question with linkId[{0}] is of type {1} but coding answer does not have a system",
                  linkId,
                  type.name());
              continue;
            }

            String optionsRef = theQuestion.getOptions().getReference();
            if (isNotBlank(optionsRef)) {
              ValueSet valueSet = getValueSet(theAnswers, theQuestion.getOptions());
              if (valueSet == null) {
                rule(
                    theErrors,
                    IssueType.BUSINESSRULE,
                    thePathStack,
                    false,
                    "Question with linkId[{0}] has options ValueSet[{1}] but this ValueSet can not be found",
                    linkId,
                    optionsRef);
                continue;
              }

              boolean found = false;
              if (coding.getSystem().equals(valueSet.getCodeSystem().getSystem())) {
                for (ConceptDefinitionComponent next : valueSet.getCodeSystem().getConcept()) {
                  if (coding.getCode().equals(next.getCode())) {
                    found = true;
                    break;
                  }
                }
              }
              if (!found) {
                for (ConceptSetComponent nextCompose : valueSet.getCompose().getInclude()) {
                  if (coding.getSystem().equals(nextCompose.getSystem())) {
                    for (ConceptReferenceComponent next : nextCompose.getConcept()) {
                      if (coding.getCode().equals(next.getCode())) {
                        found = true;
                        break;
                      }
                    }
                  }
                  if (found) {
                    break;
                  }
                }
              }

              rule(
                  theErrors,
                  IssueType.BUSINESSRULE,
                  thePathStack,
                  found,
                  "Question with linkId[{0}] has answer with system[{1}] and code[{2}] but this is not a valid answer for ValueSet[{3}]",
                  linkId,
                  coding.getSystem(),
                  coding.getCode(),
                  optionsRef);
            }
          }
        }

      } finally {
        thePathStack.removeLast();
      }
    } // for answers
  }