use of org.hl7.gravity.refimpl.sdohexchange.dto.Validated in project org.hl7.fhir.core by hapifhir.
the class InstanceValidator method checkReference.
private void checkReference(ValidatorHostContext hostContext, List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, ElementDefinition container, String parentType, NodeStack stack) throws FHIRException {
Reference reference = ObjectConverter.readAsReference(element);
String ref = reference.getReference();
if (Utilities.noString(ref)) {
if (!path.contains("element.pattern")) {
// this business rule doesn't apply to patterns
if (Utilities.noString(reference.getIdentifier().getSystem()) && Utilities.noString(reference.getIdentifier().getValue())) {
warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, !Utilities.noString(element.getNamedChildValue("display")), I18nConstants.REFERENCE_REF_NODISPLAY);
}
}
return;
} else if (Utilities.existsInList(ref, "http://tools.ietf.org/html/bcp47")) {
// special known URLs that can't be validated but are known to be valid
return;
}
warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, !isSuspiciousReference(ref), I18nConstants.REFERENCE_REF_SUSPICIOUS, ref);
ResolvedReference we = localResolve(ref, stack, errors, path, hostContext.getRootResource(), hostContext.getGroupingResource(), element);
String refType;
if (ref.startsWith("#")) {
refType = "contained";
} else {
if (we == null) {
refType = "remote";
} else {
refType = "bundled";
}
}
ReferenceValidationPolicy pol;
if (refType.equals("contained") || refType.equals("bundled")) {
pol = ReferenceValidationPolicy.CHECK_VALID;
} else {
if (policyAdvisor == null)
pol = ReferenceValidationPolicy.IGNORE;
else
pol = policyAdvisor.policyForReference(this, hostContext.getAppContext(), path, ref);
}
if (pol.checkExists()) {
if (we == null) {
if (!refType.equals("contained")) {
if (fetcher == null) {
throw new FHIRException(context.formatMessage(I18nConstants.RESOURCE_RESOLUTION_SERVICES_NOT_PROVIDED));
} else {
Element ext = null;
if (fetchCache.containsKey(ref)) {
ext = fetchCache.get(ref);
} else {
try {
ext = fetcher.fetch(this, hostContext.getAppContext(), ref);
} catch (IOException e) {
if (STACK_TRACE)
e.printStackTrace();
throw new FHIRException(e);
}
if (ext != null) {
setParents(ext);
fetchCache.put(ref, ext);
}
}
we = ext == null ? null : makeExternalRef(ext, path);
}
}
}
boolean ok = (allowExamples && (ref.contains("example.org") || ref.contains("acme.com"))) || (we != null || pol == ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ok, I18nConstants.REFERENCE_REF_CANTRESOLVE, ref);
}
String ft;
if (we != null) {
ft = we.getType();
} else {
ft = tryParse(ref);
}
if (reference.hasType()) {
// R4 onwards...
// the type has to match the specified
String tu = isAbsolute(reference.getType()) ? reference.getType() : "http://hl7.org/fhir/StructureDefinition/" + reference.getType();
TypeRefComponent containerType = container.getType("Reference");
if (!containerType.hasTargetProfile(tu) && !containerType.hasTargetProfile("http://hl7.org/fhir/StructureDefinition/Resource") && !containerType.getTargetProfile().isEmpty()) {
boolean matchingResource = false;
for (CanonicalType target : containerType.getTargetProfile()) {
StructureDefinition sd = resolveProfile(profile, target.asStringValue());
if (rule(errors, IssueType.NOTFOUND, element.line(), element.col(), path, sd != null, I18nConstants.REFERENCE_REF_CANTRESOLVEPROFILE, target.asStringValue())) {
if (("http://hl7.org/fhir/StructureDefinition/" + sd.getType()).equals(tu)) {
matchingResource = true;
break;
}
}
}
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, matchingResource, I18nConstants.REFERENCE_REF_WRONGTARGET, reference.getType(), container.getType("Reference").getTargetProfile());
}
// the type has to match the actual
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ft == null || ft.equals(reference.getType()), I18nConstants.REFERENCE_REF_BADTARGETTYPE, reference.getType(), ft);
}
if (we != null && pol.checkType()) {
if (warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ft != null, I18nConstants.REFERENCE_REF_NOTYPE)) {
// we validate as much as we can. First, can we infer a type from the profile?
boolean ok = false;
TypeRefComponent type = getReferenceTypeRef(container.getType());
if (type.hasTargetProfile() && !type.hasTargetProfile("http://hl7.org/fhir/StructureDefinition/Resource")) {
Set<String> types = new HashSet<>();
List<StructureDefinition> profiles = new ArrayList<>();
for (UriType u : type.getTargetProfile()) {
StructureDefinition sd = resolveProfile(profile, u.getValue());
if (rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, sd != null, I18nConstants.REFERENCE_REF_CANTRESOLVEPROFILE, u.getValue())) {
types.add(sd.getType());
if (ft.equals(sd.getType())) {
ok = true;
profiles.add(sd);
}
}
}
if (!pol.checkValid()) {
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, profiles.size() > 0, I18nConstants.REFERENCE_REF_CANTMATCHTYPE, ref, StringUtils.join("; ", type.getTargetProfile()));
} else {
Map<StructureDefinition, List<ValidationMessage>> badProfiles = new HashMap<>();
Map<StructureDefinition, List<ValidationMessage>> goodProfiles = new HashMap<>();
int goodCount = 0;
for (StructureDefinition pr : profiles) {
List<ValidationMessage> profileErrors = new ArrayList<ValidationMessage>();
validateResource(we.hostContext(hostContext, pr), profileErrors, we.getResource(), we.getFocus(), pr, IdStatus.OPTIONAL, we.getStack().resetIds());
if (!hasErrors(profileErrors)) {
goodCount++;
goodProfiles.put(pr, profileErrors);
trackUsage(pr, hostContext, element);
} else {
badProfiles.put(pr, profileErrors);
}
}
if (goodCount == 1) {
if (showMessagesFromReferences) {
for (ValidationMessage vm : goodProfiles.values().iterator().next()) {
if (!errors.contains(vm)) {
errors.add(vm);
}
}
}
} else if (goodProfiles.size() == 0) {
if (!isShowMessagesFromReferences()) {
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, areAllBaseProfiles(profiles), I18nConstants.REFERENCE_REF_CANTMATCHCHOICE, ref, asList(type.getTargetProfile()));
for (StructureDefinition sd : badProfiles.keySet()) {
slicingHint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, false, context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, ref, sd.getUrl()), errorSummaryForSlicingAsHtml(badProfiles.get(sd)), errorSummaryForSlicingAsText(badProfiles.get(sd)));
}
} else {
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, profiles.size() == 1, I18nConstants.REFERENCE_REF_CANTMATCHCHOICE, ref, asList(type.getTargetProfile()));
for (List<ValidationMessage> messages : badProfiles.values()) {
for (ValidationMessage vm : messages) {
if (!errors.contains(vm)) {
errors.add(vm);
}
}
}
}
} else {
if (!isShowMessagesFromReferences()) {
warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, I18nConstants.REFERENCE_REF_MULTIPLEMATCHES, ref, asListByUrl(goodProfiles.keySet()));
for (StructureDefinition sd : badProfiles.keySet()) {
slicingHint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, false, context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, ref, sd.getUrl()), errorSummaryForSlicingAsHtml(badProfiles.get(sd)), errorSummaryForSlicingAsText(badProfiles.get(sd)));
}
} else {
warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, I18nConstants.REFERENCE_REF_MULTIPLEMATCHES, ref, asListByUrl(goodProfiles.keySet()));
for (List<ValidationMessage> messages : goodProfiles.values()) {
for (ValidationMessage vm : messages) {
if (!errors.contains(vm)) {
errors.add(vm);
}
}
}
}
}
}
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ok, I18nConstants.REFERENCE_REF_BADTARGETTYPE, ft, types.toString());
}
if (type.hasAggregation() && !noCheckAggregation) {
boolean modeOk = false;
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
for (Enumeration<AggregationMode> mode : type.getAggregation()) {
b.append(mode.getCode());
if (mode.getValue().equals(AggregationMode.CONTAINED) && refType.equals("contained"))
modeOk = true;
else if (mode.getValue().equals(AggregationMode.BUNDLED) && refType.equals("bundled"))
modeOk = true;
else if (mode.getValue().equals(AggregationMode.REFERENCED) && (refType.equals("bundled") || refType.equals("remote")))
modeOk = true;
}
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, modeOk, I18nConstants.REFERENCE_REF_AGGREGATION, refType, b.toString());
}
}
}
if (we == null) {
TypeRefComponent type = getReferenceTypeRef(container.getType());
boolean okToRef = !type.hasAggregation() || type.hasAggregation(AggregationMode.REFERENCED);
rule(errors, IssueType.REQUIRED, -1, -1, path, okToRef, I18nConstants.REFERENCE_REF_NOTFOUND_BUNDLE, ref);
}
if (we == null && ft != null && assumeValidRestReferences) {
// if we == null, we inferred ft from the reference. if we are told to treat this as gospel
TypeRefComponent type = getReferenceTypeRef(container.getType());
Set<String> types = new HashSet<>();
StructureDefinition sdFT = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/" + ft);
boolean ok = false;
for (CanonicalType tp : type.getTargetProfile()) {
StructureDefinition sd = context.fetchResource(StructureDefinition.class, tp.getValue());
if (sd != null) {
types.add(sd.getType());
}
StructureDefinition sdF = sdFT;
while (sdF != null) {
if (sdF.getType().equals(sd.getType())) {
ok = true;
break;
}
sdF = sdF.hasBaseDefinition() ? context.fetchResource(StructureDefinition.class, sdF.getBaseDefinition()) : null;
}
}
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, types.isEmpty() || ok, I18nConstants.REFERENCE_REF_BADTARGETTYPE2, ft, ref, types);
}
if (pol == ReferenceValidationPolicy.CHECK_VALID) {
// todo....
}
}
use of org.hl7.gravity.refimpl.sdohexchange.dto.Validated in project org.hl7.fhir.core by hapifhir.
the class EnableWhenEvaluator method isQuestionEnabled.
/**
* the stack contains a set of QR items that represent the tree of the QR being validated, each tagged with the definition of the item from the Q for the QR being validated
* <p>
* the itembeing validated is in the context of the stack. For root items, the stack is empty.
* <p>
* The context Questionnaire and QuestionnaireResponse are always available
*/
public boolean isQuestionEnabled(ValidatorHostContext hostContext, QuestionnaireItemComponent qitem, QStack qstack, FHIRPathEngine engine) {
if (hasExpressionExtension(qitem)) {
String expr = getExpression(qitem);
ExpressionNode node = engine.parse(expr);
return engine.evaluateToBoolean(hostContext, qstack.a, qstack.a, qstack.a, node);
}
if (!qitem.hasEnableWhen()) {
return true;
}
List<EnableWhenResult> evaluationResults = new ArrayList<>();
for (QuestionnaireItemEnableWhenComponent enableCondition : qitem.getEnableWhen()) {
evaluationResults.add(evaluateCondition(enableCondition, qitem, qstack));
}
return checkConditionResults(evaluationResults, qitem);
}
use of org.hl7.gravity.refimpl.sdohexchange.dto.Validated in project org.hl7.fhir.core by hapifhir.
the class RdfParser method composeTestScriptTestScriptMetadataCapabilityComponent.
protected void composeTestScriptTestScriptMetadataCapabilityComponent(Complex parent, String parentType, String name, TestScript.TestScriptMetadataCapabilityComponent element, int index) {
if (element == null)
return;
Complex t;
if (Utilities.noString(parentType))
t = parent;
else {
t = parent.predicate("fhir:" + parentType + '.' + name);
}
composeBackboneElement(t, "capability", name, element, index);
if (element.hasRequiredElement())
composeBoolean(t, "TestScript", "required", element.getRequiredElement(), -1);
if (element.hasValidatedElement())
composeBoolean(t, "TestScript", "validated", element.getValidatedElement(), -1);
if (element.hasDescriptionElement())
composeString(t, "TestScript", "description", element.getDescriptionElement(), -1);
for (int i = 0; i < element.getOrigin().size(); i++) composeInteger(t, "TestScript", "origin", element.getOrigin().get(i), i);
if (element.hasDestinationElement())
composeInteger(t, "TestScript", "destination", element.getDestinationElement(), -1);
for (int i = 0; i < element.getLink().size(); i++) composeUri(t, "TestScript", "link", element.getLink().get(i), i);
if (element.hasCapabilities())
composeReference(t, "TestScript", "capabilities", element.getCapabilities(), -1);
}
use of org.hl7.gravity.refimpl.sdohexchange.dto.Validated in project org.hl7.fhir.core by hapifhir.
the class RdfParser method composeTestScriptTestScriptMetadataCapabilityComponent.
protected void composeTestScriptTestScriptMetadataCapabilityComponent(Complex parent, String parentType, String name, TestScript.TestScriptMetadataCapabilityComponent element, int index) {
if (element == null)
return;
Complex t;
if (Utilities.noString(parentType))
t = parent;
else {
t = parent.predicate("fhir:" + parentType + '.' + name);
}
composeBackboneElement(t, "capability", name, element, index);
if (element.hasRequiredElement())
composeBoolean(t, "TestScript", "required", element.getRequiredElement(), -1);
if (element.hasValidatedElement())
composeBoolean(t, "TestScript", "validated", element.getValidatedElement(), -1);
if (element.hasDescriptionElement())
composeString(t, "TestScript", "description", element.getDescriptionElement(), -1);
for (int i = 0; i < element.getOrigin().size(); i++) composeInteger(t, "TestScript", "origin", element.getOrigin().get(i), i);
if (element.hasDestinationElement())
composeInteger(t, "TestScript", "destination", element.getDestinationElement(), -1);
for (int i = 0; i < element.getLink().size(); i++) composeUri(t, "TestScript", "link", element.getLink().get(i), i);
if (element.hasConformance())
composeReference(t, "TestScript", "conformance", element.getConformance(), -1);
}
Aggregations