enforce constraints in slicer as well as in slice + Handle -tx n/a better
This commit is contained in:
parent
d20582ca9d
commit
920c3193d0
|
@ -49,6 +49,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
import org.fhir.ucum.UcumService;
|
import org.fhir.ucum.UcumService;
|
||||||
import org.hl7.fhir.exceptions.DefinitionException;
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.exceptions.NoTerminologyServiceException;
|
||||||
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
||||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.context.CanonicalResourceManager.CanonicalResourceProxy;
|
import org.hl7.fhir.r5.context.CanonicalResourceManager.CanonicalResourceProxy;
|
||||||
|
@ -910,6 +911,9 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
||||||
txCache.cacheValidation(cacheToken, res, TerminologyCache.TRANSIENT);
|
txCache.cacheValidation(cacheToken, res, TerminologyCache.TRANSIENT);
|
||||||
return res;
|
return res;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
if (e instanceof NoTerminologyServiceException) {
|
||||||
|
return new ValidationResult(IssueSeverity.ERROR, "No Terminology Service", TerminologyServiceErrorClass.NOSERVICE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.exceptions.NoTerminologyServiceException;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
||||||
import org.hl7.fhir.r5.model.CanonicalType;
|
import org.hl7.fhir.r5.model.CanonicalType;
|
||||||
|
@ -515,6 +516,9 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
|
||||||
if (res.getErrorClass() == TerminologyServiceErrorClass.UNKNOWN || res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED || res.getErrorClass() == TerminologyServiceErrorClass.VALUESET_UNSUPPORTED) {
|
if (res.getErrorClass() == TerminologyServiceErrorClass.UNKNOWN || res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED || res.getErrorClass() == TerminologyServiceErrorClass.VALUESET_UNSUPPORTED) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (res.getErrorClass() == TerminologyServiceErrorClass.NOSERVICE) {
|
||||||
|
throw new NoTerminologyServiceException();
|
||||||
|
}
|
||||||
return res.isOk();
|
return res.isOk();
|
||||||
} else {
|
} else {
|
||||||
if (vsi.hasFilter()) {
|
if (vsi.hasFilter()) {
|
||||||
|
|
|
@ -37,10 +37,8 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -51,15 +49,10 @@ import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64InputStream;
|
import org.apache.commons.codec.binary.Base64InputStream;
|
||||||
import org.apache.commons.io.Charsets;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.apache.commons.lang3.NotImplementedException;
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.hl7.fhir.r5.model.Reference;
|
|
||||||
import org.hl7.fhir.convertors.*;
|
|
||||||
import org.hl7.fhir.exceptions.DefinitionException;
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
|
||||||
import org.hl7.fhir.exceptions.PathEngineException;
|
import org.hl7.fhir.exceptions.PathEngineException;
|
||||||
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
||||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||||
|
@ -86,6 +79,7 @@ import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
|
||||||
import org.hl7.fhir.r5.model.CodeableConcept;
|
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||||
import org.hl7.fhir.r5.model.Coding;
|
import org.hl7.fhir.r5.model.Coding;
|
||||||
import org.hl7.fhir.r5.model.ContactPoint;
|
import org.hl7.fhir.r5.model.ContactPoint;
|
||||||
|
import org.hl7.fhir.r5.model.DataType;
|
||||||
import org.hl7.fhir.r5.model.DateTimeType;
|
import org.hl7.fhir.r5.model.DateTimeType;
|
||||||
import org.hl7.fhir.r5.model.DateType;
|
import org.hl7.fhir.r5.model.DateType;
|
||||||
import org.hl7.fhir.r5.model.DecimalType;
|
import org.hl7.fhir.r5.model.DecimalType;
|
||||||
|
@ -114,6 +108,7 @@ import org.hl7.fhir.r5.model.PrimitiveType;
|
||||||
import org.hl7.fhir.r5.model.Quantity;
|
import org.hl7.fhir.r5.model.Quantity;
|
||||||
import org.hl7.fhir.r5.model.Range;
|
import org.hl7.fhir.r5.model.Range;
|
||||||
import org.hl7.fhir.r5.model.Ratio;
|
import org.hl7.fhir.r5.model.Ratio;
|
||||||
|
import org.hl7.fhir.r5.model.Reference;
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
import org.hl7.fhir.r5.model.SampledData;
|
import org.hl7.fhir.r5.model.SampledData;
|
||||||
import org.hl7.fhir.r5.model.SearchParameter;
|
import org.hl7.fhir.r5.model.SearchParameter;
|
||||||
|
@ -127,18 +122,30 @@ import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionSnapshotComp
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||||
import org.hl7.fhir.r5.model.TimeType;
|
import org.hl7.fhir.r5.model.TimeType;
|
||||||
import org.hl7.fhir.r5.model.Timing;
|
import org.hl7.fhir.r5.model.Timing;
|
||||||
import org.hl7.fhir.r5.model.DataType;
|
|
||||||
import org.hl7.fhir.r5.model.TypeDetails;
|
import org.hl7.fhir.r5.model.TypeDetails;
|
||||||
import org.hl7.fhir.r5.model.UriType;
|
import org.hl7.fhir.r5.model.UriType;
|
||||||
import org.hl7.fhir.r5.model.ValueSet;
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||||
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
|
||||||
import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
|
import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
||||||
import org.hl7.fhir.r5.utils.IResourceValidator;
|
import org.hl7.fhir.r5.utils.IResourceValidator;
|
||||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||||
import org.hl7.fhir.r5.utils.XVerExtensionManager;
|
import org.hl7.fhir.r5.utils.XVerExtensionManager;
|
||||||
|
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
import org.hl7.fhir.utilities.Utilities.DecimalStatus;
|
||||||
|
import org.hl7.fhir.utilities.VersionUtilities;
|
||||||
|
import org.hl7.fhir.utilities.VersionUtilities.VersionURLInfo;
|
||||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||||
|
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||||
|
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||||
|
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
||||||
|
import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
|
||||||
|
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||||
|
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||||
|
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||||
import org.hl7.fhir.validation.BaseValidator;
|
import org.hl7.fhir.validation.BaseValidator;
|
||||||
import org.hl7.fhir.validation.Validator.QuestionnaireMode;
|
import org.hl7.fhir.validation.Validator.QuestionnaireMode;
|
||||||
import org.hl7.fhir.validation.instance.type.BundleValidator;
|
import org.hl7.fhir.validation.instance.type.BundleValidator;
|
||||||
|
@ -148,19 +155,13 @@ import org.hl7.fhir.validation.instance.type.QuestionnaireValidator;
|
||||||
import org.hl7.fhir.validation.instance.type.SearchParameterValidator;
|
import org.hl7.fhir.validation.instance.type.SearchParameterValidator;
|
||||||
import org.hl7.fhir.validation.instance.type.StructureDefinitionValidator;
|
import org.hl7.fhir.validation.instance.type.StructureDefinitionValidator;
|
||||||
import org.hl7.fhir.validation.instance.type.ValueSetValidator;
|
import org.hl7.fhir.validation.instance.type.ValueSetValidator;
|
||||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
import org.hl7.fhir.validation.instance.utils.ChildIterator;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.validation.instance.utils.ElementInfo;
|
||||||
import org.hl7.fhir.utilities.Utilities.DecimalStatus;
|
import org.hl7.fhir.validation.instance.utils.IndexedElement;
|
||||||
import org.hl7.fhir.utilities.VersionUtilities;
|
import org.hl7.fhir.validation.instance.utils.NodeStack;
|
||||||
import org.hl7.fhir.utilities.VersionUtilities.VersionURLInfo;
|
import org.hl7.fhir.validation.instance.utils.ResolvedReference;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
import org.hl7.fhir.validation.instance.utils.ResourceValidationTracker;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
import org.hl7.fhir.validation.instance.utils.ValidatorHostContext;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
|
|
||||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
|
||||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
|
||||||
import org.hl7.fhir.validation.instance.utils.*;
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
@ -343,6 +344,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
private String validationLanguage;
|
private String validationLanguage;
|
||||||
private boolean baseOnly;
|
private boolean baseOnly;
|
||||||
private boolean noCheckAggregation;
|
private boolean noCheckAggregation;
|
||||||
|
private boolean wantCheckSnapshotUnchanged;
|
||||||
|
|
||||||
private List<ImplementationGuide> igs = new ArrayList<>();
|
private List<ImplementationGuide> igs = new ArrayList<>();
|
||||||
private List<String> extensionDomains = new ArrayList<String>();
|
private List<String> extensionDomains = new ArrayList<String>();
|
||||||
|
@ -1004,7 +1006,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
ValidationResult vr = checkCodeOnServer(stack, valueset, cc, true); // we're going to validate the codings directly, so only check the valueset
|
ValidationResult vr = checkCodeOnServer(stack, valueset, cc, true); // we're going to validate the codings directly, so only check the valueset
|
||||||
if (!vr.isOk()) {
|
if (!vr.isOk()) {
|
||||||
bindingsOk = false;
|
bindingsOk = false;
|
||||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) {
|
if (vr.getErrorClass() != null && vr.getErrorClass() == TerminologyServiceErrorClass.NOSERVICE) {
|
||||||
|
if (binding.getStrength() == BindingStrength.REQUIRED || (binding.getStrength() == BindingStrength.EXTENSIBLE && binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))) {
|
||||||
|
hint(errors, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOSVC_BOUND_REQ, describeReference(binding.getValueSet()));
|
||||||
|
} else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
||||||
|
hint(errors, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOSVC_BOUND_EXT, describeReference(binding.getValueSet()));
|
||||||
|
}
|
||||||
|
} else if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) {
|
||||||
if (binding.getStrength() == BindingStrength.REQUIRED)
|
if (binding.getStrength() == BindingStrength.REQUIRED)
|
||||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_1, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
|
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_1, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
|
||||||
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
||||||
|
@ -3860,7 +3868,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
} else if (element.getType().equals("SearchParameter")) {
|
} else if (element.getType().equals("SearchParameter")) {
|
||||||
new SearchParameterValidator(context, timeTracker, fpe).validateSearchParameter(errors, element, stack);
|
new SearchParameterValidator(context, timeTracker, fpe).validateSearchParameter(errors, element, stack);
|
||||||
} else if (element.getType().equals("StructureDefinition")) {
|
} else if (element.getType().equals("StructureDefinition")) {
|
||||||
new StructureDefinitionValidator(context, timeTracker, fpe).validateStructureDefinition(errors, element, stack);
|
new StructureDefinitionValidator(context, timeTracker, fpe, wantCheckSnapshotUnchanged).validateStructureDefinition(errors, element, stack);
|
||||||
} else if (element.getType().equals("ValueSet")) {
|
} else if (element.getType().equals("ValueSet")) {
|
||||||
new ValueSetValidator(context, timeTracker, this).validateValueSet(errors, element, stack);
|
new ValueSetValidator(context, timeTracker, this).validateValueSet(errors, element, stack);
|
||||||
}
|
}
|
||||||
|
@ -4128,17 +4136,29 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
Element resource, Element element, String actualType, NodeStack stack, boolean inCodeableConcept, boolean checkDisplayInContext, ElementInfo ei, String extensionUrl)
|
Element resource, Element element, String actualType, NodeStack stack, boolean inCodeableConcept, boolean checkDisplayInContext, ElementInfo ei, String extensionUrl)
|
||||||
throws FHIRException, DefinitionException {
|
throws FHIRException, DefinitionException {
|
||||||
|
|
||||||
List<String> profiles = new ArrayList<String>();
|
|
||||||
if (ei.definition != null) {
|
if (ei.definition != null) {
|
||||||
|
checkChildByDefinition(hostContext, errors, profile, definition, resource, element, actualType, stack, inCodeableConcept, checkDisplayInContext, ei,
|
||||||
|
extensionUrl, ei.definition, false);
|
||||||
|
}
|
||||||
|
if (ei.slice != null) {
|
||||||
|
checkChildByDefinition(hostContext, errors, profile, definition, resource, element, actualType, stack, inCodeableConcept, checkDisplayInContext, ei,
|
||||||
|
extensionUrl, ei.slice, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkChildByDefinition(ValidatorHostContext hostContext, List<ValidationMessage> errors, StructureDefinition profile,
|
||||||
|
ElementDefinition definition, Element resource, Element element, String actualType, NodeStack stack, boolean inCodeableConcept,
|
||||||
|
boolean checkDisplayInContext, ElementInfo ei, String extensionUrl, ElementDefinition checkDefn, boolean isSlice) {
|
||||||
|
List<String> profiles = new ArrayList<String>();
|
||||||
String type = null;
|
String type = null;
|
||||||
ElementDefinition typeDefn = null;
|
ElementDefinition typeDefn = null;
|
||||||
checkMustSupport(profile, ei);
|
checkMustSupport(profile, ei);
|
||||||
|
|
||||||
if (ei.definition.getType().size() == 1 && !"*".equals(ei.definition.getType().get(0).getWorkingCode()) && !"Element".equals(ei.definition.getType().get(0).getWorkingCode())
|
if (checkDefn.getType().size() == 1 && !"*".equals(checkDefn.getType().get(0).getWorkingCode()) && !"Element".equals(checkDefn.getType().get(0).getWorkingCode())
|
||||||
&& !"BackboneElement".equals(ei.definition.getType().get(0).getWorkingCode())) {
|
&& !"BackboneElement".equals(checkDefn.getType().get(0).getWorkingCode())) {
|
||||||
type = ei.definition.getType().get(0).getWorkingCode();
|
type = checkDefn.getType().get(0).getWorkingCode();
|
||||||
String stype = ei.getElement().fhirType();
|
String stype = ei.getElement().fhirType();
|
||||||
if (ei.definition.isChoice() && !stype.equals(type)) {
|
if (checkDefn.isChoice() && !stype.equals(type)) {
|
||||||
if ("Extension".equals(profile.getType())) {
|
if ("Extension".equals(profile.getType())) {
|
||||||
// error will be raised elsewhere
|
// error will be raised elsewhere
|
||||||
} else {
|
} else {
|
||||||
|
@ -4147,32 +4167,32 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Excluding reference is a kludge to get around versioning issues
|
// Excluding reference is a kludge to get around versioning issues
|
||||||
if (ei.definition.getType().get(0).hasProfile()) {
|
if (checkDefn.getType().get(0).hasProfile()) {
|
||||||
for (CanonicalType p : ei.definition.getType().get(0).getProfile()) {
|
for (CanonicalType p : checkDefn.getType().get(0).getProfile()) {
|
||||||
profiles.add(p.getValue());
|
profiles.add(p.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (ei.definition.getType().size() == 1 && "*".equals(ei.definition.getType().get(0).getWorkingCode())) {
|
} else if (checkDefn.getType().size() == 1 && "*".equals(checkDefn.getType().get(0).getWorkingCode())) {
|
||||||
String prefix = tail(ei.definition.getPath());
|
String prefix = tail(checkDefn.getPath());
|
||||||
assert prefix.endsWith("[x]");
|
assert prefix.endsWith("[x]");
|
||||||
type = ei.getName().substring(prefix.length() - 3);
|
type = ei.getName().substring(prefix.length() - 3);
|
||||||
if (isPrimitiveType(type))
|
if (isPrimitiveType(type))
|
||||||
type = Utilities.uncapitalize(type);
|
type = Utilities.uncapitalize(type);
|
||||||
if (ei.definition.getType().get(0).hasProfile()) {
|
if (checkDefn.getType().get(0).hasProfile()) {
|
||||||
for (CanonicalType p : ei.definition.getType().get(0).getProfile()) {
|
for (CanonicalType p : checkDefn.getType().get(0).getProfile()) {
|
||||||
profiles.add(p.getValue());
|
profiles.add(p.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (ei.definition.getType().size() > 1) {
|
} else if (checkDefn.getType().size() > 1) {
|
||||||
|
|
||||||
String prefix = tail(ei.definition.getPath());
|
String prefix = tail(checkDefn.getPath());
|
||||||
assert typesAreAllReference(ei.definition.getType()) || ei.definition.hasRepresentation(PropertyRepresentation.TYPEATTR) || prefix.endsWith("[x]") : prefix;
|
assert typesAreAllReference(checkDefn.getType()) || checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR) || prefix.endsWith("[x]") : prefix;
|
||||||
|
|
||||||
if (ei.definition.hasRepresentation(PropertyRepresentation.TYPEATTR))
|
if (checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR))
|
||||||
type = ei.getElement().getType();
|
type = ei.getElement().getType();
|
||||||
else {
|
else {
|
||||||
prefix = prefix.substring(0, prefix.length() - 3);
|
prefix = prefix.substring(0, prefix.length() - 3);
|
||||||
for (TypeRefComponent t : ei.definition.getType())
|
for (TypeRefComponent t : checkDefn.getType())
|
||||||
if ((prefix + Utilities.capitalize(t.getWorkingCode())).equals(ei.getName())) {
|
if ((prefix + Utilities.capitalize(t.getWorkingCode())).equals(ei.getName())) {
|
||||||
type = t.getWorkingCode();
|
type = t.getWorkingCode();
|
||||||
// Excluding reference is a kludge to get around versioning issues
|
// Excluding reference is a kludge to get around versioning issues
|
||||||
|
@ -4181,18 +4201,18 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
TypeRefComponent trc = ei.definition.getType().get(0);
|
TypeRefComponent trc = checkDefn.getType().get(0);
|
||||||
if (trc.getWorkingCode().equals("Reference"))
|
if (trc.getWorkingCode().equals("Reference"))
|
||||||
type = "Reference";
|
type = "Reference";
|
||||||
else
|
else
|
||||||
rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOTYPE, ei.getName(), describeTypes(ei.definition.getType()));
|
rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOTYPE, ei.getName(), describeTypes(checkDefn.getType()));
|
||||||
}
|
}
|
||||||
} else if (ei.definition.getContentReference() != null) {
|
} else if (checkDefn.getContentReference() != null) {
|
||||||
typeDefn = resolveNameReference(profile.getSnapshot(), ei.definition.getContentReference());
|
typeDefn = resolveNameReference(profile.getSnapshot(), checkDefn.getContentReference());
|
||||||
|
|
||||||
} else if (ei.definition.getType().size() == 1 && ("Element".equals(ei.definition.getType().get(0).getWorkingCode()) || "BackboneElement".equals(ei.definition.getType().get(0).getWorkingCode()))) {
|
} else if (checkDefn.getType().size() == 1 && ("Element".equals(checkDefn.getType().get(0).getWorkingCode()) || "BackboneElement".equals(checkDefn.getType().get(0).getWorkingCode()))) {
|
||||||
if (ei.definition.getType().get(0).hasProfile()) {
|
if (checkDefn.getType().get(0).hasProfile()) {
|
||||||
CanonicalType pu = ei.definition.getType().get(0).getProfile().get(0);
|
CanonicalType pu = checkDefn.getType().get(0).getProfile().get(0);
|
||||||
if (pu.hasExtension(ToolingExtensions.EXT_PROFILE_ELEMENT))
|
if (pu.hasExtension(ToolingExtensions.EXT_PROFILE_ELEMENT))
|
||||||
profiles.add(pu.getValue() + "#" + pu.getExtensionString(ToolingExtensions.EXT_PROFILE_ELEMENT));
|
profiles.add(pu.getValue() + "#" + pu.getExtensionString(ToolingExtensions.EXT_PROFILE_ELEMENT));
|
||||||
else
|
else
|
||||||
|
@ -4202,11 +4222,16 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
|
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
if (type.startsWith("@")) {
|
if (type.startsWith("@")) {
|
||||||
ei.definition = findElement(profile, type.substring(1));
|
checkDefn = findElement(profile, type.substring(1));
|
||||||
|
if (isSlice) {
|
||||||
|
ei.slice = ei.definition;
|
||||||
|
} else {
|
||||||
|
ei.definition = ei.definition;
|
||||||
|
}
|
||||||
type = null;
|
type = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NodeStack localStack = stack.push(ei.getElement(), ei.count, ei.definition, type == null ? typeDefn : resolveType(type, ei.definition.getType()));
|
NodeStack localStack = stack.push(ei.getElement(), ei.count, checkDefn, type == null ? typeDefn : resolveType(type, checkDefn.getType()));
|
||||||
// if (debug) {
|
// if (debug) {
|
||||||
// System.out.println(" check " + localStack.getLiteralPath()+" against "+ei.getDefinition().getId()+" in profile "+profile.getUrl());
|
// System.out.println(" check " + localStack.getLiteralPath()+" against "+ei.getDefinition().getId()+" in profile "+profile.getUrl());
|
||||||
// }
|
// }
|
||||||
|
@ -4217,34 +4242,34 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
String thisExtension = null;
|
String thisExtension = null;
|
||||||
boolean checkDisplay = true;
|
boolean checkDisplay = true;
|
||||||
|
|
||||||
checkInvariants(hostContext, errors, profile, typeDefn != null ? typeDefn : ei.definition, resource, ei.getElement(), localStack, true);
|
checkInvariants(hostContext, errors, profile, typeDefn != null ? typeDefn : checkDefn, resource, ei.getElement(), localStack, true);
|
||||||
|
|
||||||
ei.getElement().markValidation(profile, ei.definition);
|
ei.getElement().markValidation(profile, checkDefn);
|
||||||
boolean elementValidated = false;
|
boolean elementValidated = false;
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
if (isPrimitiveType(type)) {
|
if (isPrimitiveType(type)) {
|
||||||
checkPrimitive(hostContext, errors, ei.getPath(), type, ei.definition, ei.getElement(), profile, stack);
|
checkPrimitive(hostContext, errors, ei.getPath(), type, checkDefn, ei.getElement(), profile, stack);
|
||||||
} else {
|
} else {
|
||||||
if (ei.definition.hasFixed()) {
|
if (checkDefn.hasFixed()) {
|
||||||
checkFixedValue(errors, ei.getPath(), ei.getElement(), ei.definition.getFixed(), profile.getUrl(), ei.definition.getSliceName(), null);
|
checkFixedValue(errors, ei.getPath(), ei.getElement(), checkDefn.getFixed(), profile.getUrl(), checkDefn.getSliceName(), null);
|
||||||
}
|
}
|
||||||
if (ei.definition.hasPattern()) {
|
if (checkDefn.hasPattern()) {
|
||||||
checkFixedValue(errors, ei.getPath(), ei.getElement(), ei.definition.getPattern(), profile.getUrl(), ei.definition.getSliceName(), null, true);
|
checkFixedValue(errors, ei.getPath(), ei.getElement(), checkDefn.getPattern(), profile.getUrl(), checkDefn.getSliceName(), null, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type.equals("Identifier")) {
|
if (type.equals("Identifier")) {
|
||||||
checkIdentifier(errors, ei.getPath(), ei.getElement(), ei.definition);
|
checkIdentifier(errors, ei.getPath(), ei.getElement(), checkDefn);
|
||||||
} else if (type.equals("Coding")) {
|
} else if (type.equals("Coding")) {
|
||||||
checkCoding(errors, ei.getPath(), ei.getElement(), profile, ei.definition, inCodeableConcept, checkDisplayInContext, stack);
|
checkCoding(errors, ei.getPath(), ei.getElement(), profile, checkDefn, inCodeableConcept, checkDisplayInContext, stack);
|
||||||
} else if (type.equals("Quantity")) {
|
} else if (type.equals("Quantity")) {
|
||||||
checkQuantity(errors, ei.getPath(), ei.getElement(), profile, ei.definition, stack);
|
checkQuantity(errors, ei.getPath(), ei.getElement(), profile, checkDefn, stack);
|
||||||
} else if (type.equals("Attachment")) {
|
} else if (type.equals("Attachment")) {
|
||||||
checkAttachment(errors, ei.getPath(), ei.getElement(), profile, ei.definition, inCodeableConcept, checkDisplayInContext, stack);
|
checkAttachment(errors, ei.getPath(), ei.getElement(), profile, checkDefn, inCodeableConcept, checkDisplayInContext, stack);
|
||||||
} else if (type.equals("CodeableConcept")) {
|
} else if (type.equals("CodeableConcept")) {
|
||||||
checkDisplay = checkCodeableConcept(errors, ei.getPath(), ei.getElement(), profile, ei.definition, stack);
|
checkDisplay = checkCodeableConcept(errors, ei.getPath(), ei.getElement(), profile, checkDefn, stack);
|
||||||
thisIsCodeableConcept = true;
|
thisIsCodeableConcept = true;
|
||||||
} else if (type.equals("Reference")) {
|
} else if (type.equals("Reference")) {
|
||||||
checkReference(hostContext, errors, ei.getPath(), ei.getElement(), profile, ei.definition, actualType, localStack);
|
checkReference(hostContext, errors, ei.getPath(), ei.getElement(), profile, checkDefn, actualType, localStack);
|
||||||
// We only check extensions if we're not in a complex extension or if the element we're dealing with is not defined as part of that complex extension
|
// We only check extensions if we're not in a complex extension or if the element we're dealing with is not defined as part of that complex extension
|
||||||
} else if (type.equals("Extension")) {
|
} else if (type.equals("Extension")) {
|
||||||
Element eurl = ei.getElement().getNamedChild("url");
|
Element eurl = ei.getElement().getNamedChild("url");
|
||||||
|
@ -4253,12 +4278,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
thisExtension = url;
|
thisExtension = url;
|
||||||
if (rule(errors, IssueType.INVALID, ei.getPath(), !Utilities.noString(url), I18nConstants.EXTENSION_EXT_URL_NOTFOUND)) {
|
if (rule(errors, IssueType.INVALID, ei.getPath(), !Utilities.noString(url), I18nConstants.EXTENSION_EXT_URL_NOTFOUND)) {
|
||||||
if (rule(errors, IssueType.INVALID, ei.getPath(), (extensionUrl != null) || Utilities.isAbsoluteUrl(url), I18nConstants.EXTENSION_EXT_URL_ABSOLUTE)) {
|
if (rule(errors, IssueType.INVALID, ei.getPath(), (extensionUrl != null) || Utilities.isAbsoluteUrl(url), I18nConstants.EXTENSION_EXT_URL_ABSOLUTE)) {
|
||||||
checkExtension(hostContext, errors, ei.getPath(), resource, element, ei.getElement(), ei.definition, profile, localStack, stack, extensionUrl);
|
checkExtension(hostContext, errors, ei.getPath(), resource, element, ei.getElement(), checkDefn, profile, localStack, stack, extensionUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (type.equals("Resource") || isResource(type)) {
|
} else if (type.equals("Resource") || isResource(type)) {
|
||||||
validateContains(hostContext, errors, ei.getPath(), ei.definition, definition, resource, ei.getElement(), localStack, idStatusForEntry(element, ei)); // if
|
validateContains(hostContext, errors, ei.getPath(), checkDefn, definition, resource, ei.getElement(), localStack, idStatusForEntry(element, ei)); // if
|
||||||
elementValidated = true;
|
elementValidated = true;
|
||||||
// (str.matches(".*([.,/])work\\1$"))
|
// (str.matches(".*([.,/])work\\1$"))
|
||||||
} else if (Utilities.isAbsoluteUrl(type)) {
|
} else if (Utilities.isAbsoluteUrl(type)) {
|
||||||
|
@ -4266,22 +4291,22 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
if (defn != null && hasMapping("http://hl7.org/fhir/terminology-pattern", defn, defn.getSnapshot().getElementFirstRep())) {
|
if (defn != null && hasMapping("http://hl7.org/fhir/terminology-pattern", defn, defn.getSnapshot().getElementFirstRep())) {
|
||||||
List<String> txtype = getMapping("http://hl7.org/fhir/terminology-pattern", defn, defn.getSnapshot().getElementFirstRep());
|
List<String> txtype = getMapping("http://hl7.org/fhir/terminology-pattern", defn, defn.getSnapshot().getElementFirstRep());
|
||||||
if (txtype.contains("CodeableConcept")) {
|
if (txtype.contains("CodeableConcept")) {
|
||||||
checkTerminologyCodeableConcept(errors, ei.getPath(), ei.getElement(), profile, ei.definition, stack, defn);
|
checkTerminologyCodeableConcept(errors, ei.getPath(), ei.getElement(), profile, checkDefn, stack, defn);
|
||||||
thisIsCodeableConcept = true;
|
thisIsCodeableConcept = true;
|
||||||
} else if (txtype.contains("Coding")) {
|
} else if (txtype.contains("Coding")) {
|
||||||
checkTerminologyCoding(errors, ei.getPath(), ei.getElement(), profile, ei.definition, inCodeableConcept, checkDisplayInContext, stack, defn);
|
checkTerminologyCoding(errors, ei.getPath(), ei.getElement(), profile, checkDefn, inCodeableConcept, checkDisplayInContext, stack, defn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), ei.definition != null, I18nConstants.VALIDATION_VAL_CONTENT_UNKNOWN, ei.getName()))
|
if (rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), checkDefn != null, I18nConstants.VALIDATION_VAL_CONTENT_UNKNOWN, ei.getName()))
|
||||||
validateElement(hostContext, errors, profile, ei.definition, null, null, resource, ei.getElement(), type, localStack, false, true, null);
|
validateElement(hostContext, errors, profile, checkDefn, null, null, resource, ei.getElement(), type, localStack, false, true, null);
|
||||||
}
|
}
|
||||||
StructureDefinition p = null;
|
StructureDefinition p = null;
|
||||||
String tail = null;
|
String tail = null;
|
||||||
if (profiles.isEmpty()) {
|
if (profiles.isEmpty()) {
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
p = getProfileForType(type, ei.definition.getType());
|
p = getProfileForType(type, checkDefn.getType());
|
||||||
|
|
||||||
// If dealing with a primitive type, then we need to check the current child against
|
// If dealing with a primitive type, then we need to check the current child against
|
||||||
// the invariants (constraints) on the current element, because otherwise it only gets
|
// the invariants (constraints) on the current element, because otherwise it only gets
|
||||||
|
@ -4314,7 +4339,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
p = this.context.fetchResource(StructureDefinition.class, typeProfile);
|
p = this.context.fetchResource(StructureDefinition.class, typeProfile);
|
||||||
if (rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), p != null, I18nConstants.VALIDATION_VAL_UNKNOWN_PROFILE, typeProfile)) {
|
if (rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), p != null, I18nConstants.VALIDATION_VAL_UNKNOWN_PROFILE, typeProfile)) {
|
||||||
List<ValidationMessage> profileErrors = new ArrayList<ValidationMessage>();
|
List<ValidationMessage> profileErrors = new ArrayList<ValidationMessage>();
|
||||||
validateElement(hostContext, profileErrors, p, getElementByTail(p, tail), profile, ei.definition, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension);
|
validateElement(hostContext, profileErrors, p, getElementByTail(p, tail), profile, checkDefn, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension);
|
||||||
if (hasErrors(profileErrors))
|
if (hasErrors(profileErrors))
|
||||||
badProfiles.put(typeProfile, profileErrors);
|
badProfiles.put(typeProfile, profileErrors);
|
||||||
else
|
else
|
||||||
|
@ -4348,16 +4373,15 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
|
|
||||||
if (!elementValidated) {
|
if (!elementValidated) {
|
||||||
if (ei.getElement().getSpecial() == SpecialElement.BUNDLE_ENTRY || ei.getElement().getSpecial() == SpecialElement.BUNDLE_OUTCOME || ei.getElement().getSpecial() == SpecialElement.PARAMETER)
|
if (ei.getElement().getSpecial() == SpecialElement.BUNDLE_ENTRY || ei.getElement().getSpecial() == SpecialElement.BUNDLE_OUTCOME || ei.getElement().getSpecial() == SpecialElement.PARAMETER)
|
||||||
validateElement(hostContext, errors, p, getElementByTail(p, tail), profile, ei.definition, ei.getElement(), ei.getElement(), type, localStack.resetIds(), thisIsCodeableConcept, checkDisplay, thisExtension);
|
validateElement(hostContext, errors, p, getElementByTail(p, tail), profile, checkDefn, ei.getElement(), ei.getElement(), type, localStack.resetIds(), thisIsCodeableConcept, checkDisplay, thisExtension);
|
||||||
else
|
else
|
||||||
validateElement(hostContext, errors, p, getElementByTail(p, tail), profile, ei.definition, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension);
|
validateElement(hostContext, errors, p, getElementByTail(p, tail), profile, checkDefn, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension);
|
||||||
}
|
}
|
||||||
int index = profile.getSnapshot().getElement().indexOf(ei.definition);
|
int index = profile.getSnapshot().getElement().indexOf(checkDefn);
|
||||||
if (index < profile.getSnapshot().getElement().size() - 1) {
|
if (index < profile.getSnapshot().getElement().size() - 1) {
|
||||||
String nextPath = profile.getSnapshot().getElement().get(index + 1).getPath();
|
String nextPath = profile.getSnapshot().getElement().get(index + 1).getPath();
|
||||||
if (!nextPath.equals(ei.definition.getPath()) && nextPath.startsWith(ei.definition.getPath()))
|
if (!nextPath.equals(checkDefn.getPath()) && nextPath.startsWith(checkDefn.getPath()))
|
||||||
validateElement(hostContext, errors, profile, ei.definition, null, null, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension);
|
validateElement(hostContext, errors, profile, checkDefn, null, null, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5091,4 +5115,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
return questionnaireMode;
|
return questionnaireMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isWantCheckSnapshotUnchanged() {
|
||||||
|
return wantCheckSnapshotUnchanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWantCheckSnapshotUnchanged(boolean wantCheckSnapshotUnchanged) {
|
||||||
|
this.wantCheckSnapshotUnchanged = wantCheckSnapshotUnchanged;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue