use of org.hl7.fhir.validation.instance.utils.ValidatorHostContext in project org.hl7.fhir.core by hapifhir.
the class InstanceValidator method sliceMatches.
/**
* @param element - the candidate that might be in the slice
* @param path - for reporting any errors. the XPath for the element
* @param slicer - the definition of how slicing is determined
* @param ed - the slice for which to test membership
* @param errors
* @param stack
* @param srcProfile
* @return
* @throws DefinitionException
* @throws DefinitionException
* @throws IOException
* @throws FHIRException
*/
private boolean sliceMatches(ValidatorHostContext hostContext, Element element, String path, ElementDefinition slicer, ElementDefinition ed, StructureDefinition profile, List<ValidationMessage> errors, List<ValidationMessage> sliceInfo, NodeStack stack, StructureDefinition srcProfile) throws DefinitionException, FHIRException {
if (!slicer.getSlicing().hasDiscriminator())
// cannot validate in this case
return false;
ExpressionNode n = (ExpressionNode) ed.getUserData("slice.expression.cache");
if (n == null) {
long t = System.nanoTime();
// GG: this approach is flawed because it treats discriminators individually rather than collectively
StringBuilder expression = new StringBuilder("true");
boolean anyFound = false;
Set<String> discriminators = new HashSet<>();
for (ElementDefinitionSlicingDiscriminatorComponent s : slicer.getSlicing().getDiscriminator()) {
String discriminator = s.getPath();
discriminators.add(discriminator);
List<ElementDefinition> criteriaElements = getCriteriaForDiscriminator(path, ed, discriminator, profile, s.getType() == DiscriminatorType.PROFILE, srcProfile);
boolean found = false;
for (ElementDefinition criteriaElement : criteriaElements) {
found = true;
if (s.getType() == DiscriminatorType.TYPE) {
String type = null;
if (!criteriaElement.getPath().contains("[") && discriminator.contains("[")) {
discriminator = discriminator.substring(0, discriminator.indexOf('['));
String lastNode = tail(discriminator);
type = tail(criteriaElement.getPath()).substring(lastNode.length());
type = type.substring(0, 1).toLowerCase() + type.substring(1);
} else if (!criteriaElement.hasType() || criteriaElement.getType().size() == 1) {
if (discriminator.contains("["))
discriminator = discriminator.substring(0, discriminator.indexOf('['));
if (criteriaElement.hasType()) {
type = criteriaElement.getType().get(0).getWorkingCode();
} else if (!criteriaElement.getPath().contains(".")) {
type = criteriaElement.getPath();
} else {
throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES, discriminator, ed.getId(), profile.getUrl()));
}
} else if (criteriaElement.getType().size() > 1) {
throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_MULTIPLE_TYPES_, discriminator, ed.getId(), profile.getUrl(), criteriaElement.typeSummary()));
} else
throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES, discriminator, ed.getId(), profile.getUrl()));
if (discriminator.isEmpty())
expression.append(" and $this is " + type);
else
expression.append(" and " + discriminator + " is " + type);
} else if (s.getType() == DiscriminatorType.PROFILE) {
if (criteriaElement.getType().size() == 0) {
throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl()));
}
if (criteriaElement.getType().size() != 1) {
throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_ONLY_ONE_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl()));
}
List<CanonicalType> list = discriminator.endsWith(".resolve()") || discriminator.equals("resolve()") ? criteriaElement.getType().get(0).getTargetProfile() : criteriaElement.getType().get(0).getProfile();
if (list.size() == 0) {
throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE_WITH_A_PROFILE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl()));
} else if (list.size() > 1) {
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(" or ");
for (CanonicalType c : list) {
b.append(discriminator + ".conformsTo('" + c.getValue() + "')");
}
expression.append(" and (" + b + ")");
} else {
expression.append(" and " + discriminator + ".conformsTo('" + list.get(0).getValue() + "')");
}
} else if (s.getType() == DiscriminatorType.EXISTS) {
if (criteriaElement.hasMin() && criteriaElement.getMin() >= 1)
expression.append(" and (" + discriminator + ".exists())");
else if (criteriaElement.hasMax() && criteriaElement.getMax().equals("0"))
expression.append(" and (" + discriminator + ".exists().not())");
else
throw new FHIRException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_ELEMENT_EXISTENCE_BUT_SLICE__NEITHER_SETS_MIN1_OR_MAX0, discriminator, ed.getId()));
} else if (criteriaElement.hasFixed()) {
buildFixedExpression(ed, expression, discriminator, criteriaElement);
} else if (criteriaElement.hasPattern()) {
buildPattternExpression(ed, expression, discriminator, criteriaElement);
} else if (criteriaElement.hasBinding() && criteriaElement.getBinding().hasStrength() && criteriaElement.getBinding().getStrength().equals(BindingStrength.REQUIRED) && criteriaElement.getBinding().hasValueSet()) {
expression.append(" and (" + discriminator + " memberOf '" + criteriaElement.getBinding().getValueSet() + "')");
} else {
found = false;
}
if (found)
break;
}
if (found)
anyFound = true;
}
if (!anyFound) {
if (slicer.getSlicing().getDiscriminator().size() > 1)
throw new DefinitionException(context.formatMessage(I18nConstants.COULD_NOT_MATCH_ANY_DISCRIMINATORS__FOR_SLICE__IN_PROFILE___NONE_OF_THE_DISCRIMINATOR__HAVE_FIXED_VALUE_BINDING_OR_EXISTENCE_ASSERTIONS, discriminators, ed.getId(), profile.getUrl(), discriminators));
else
throw new DefinitionException(context.formatMessage(I18nConstants.COULD_NOT_MATCH_DISCRIMINATOR__FOR_SLICE__IN_PROFILE___THE_DISCRIMINATOR__DOES_NOT_HAVE_FIXED_VALUE_BINDING_OR_EXISTENCE_ASSERTIONS, discriminators, ed.getId(), profile.getUrl(), discriminators));
}
try {
n = fpe.parse(fixExpr(expression.toString(), null));
} catch (FHIRLexerException e) {
if (STACK_TRACE)
e.printStackTrace();
throw new FHIRException(context.formatMessage(I18nConstants.PROBLEM_PROCESSING_EXPRESSION__IN_PROFILE__PATH__, expression, profile.getUrl(), path, e.getMessage()));
}
timeTracker.fpe(t);
ed.setUserData("slice.expression.cache", n);
}
ValidatorHostContext shc = hostContext.forSlicing();
boolean pass = evaluateSlicingExpression(shc, element, path, profile, n);
if (!pass) {
slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), (context.formatMessage(I18nConstants.DOES_NOT_MATCH_SLICE_, ed.getSliceName())), "discriminator = " + Utilities.escapeXml(n.toString()), null);
for (String url : shc.getSliceRecords().keySet()) {
slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, stack.getLiteralPath(), url), context.formatMessage(I18nConstants.PROFILE__DOES_NOT_MATCH_FOR__BECAUSE_OF_THE_FOLLOWING_PROFILE_ISSUES__, url, stack.getLiteralPath(), errorSummaryForSlicingAsHtml(shc.getSliceRecords().get(url))), errorSummaryForSlicingAsText(shc.getSliceRecords().get(url)));
}
}
return pass;
}
use of org.hl7.fhir.validation.instance.utils.ValidatorHostContext in project org.hl7.fhir.core by hapifhir.
the class ValidationEngine method evaluateFhirPath.
public String evaluateFhirPath(String source, String expression) throws FHIRException, IOException {
Content cnt = igLoader.loadContent(source, "validate", false);
FHIRPathEngine fpe = this.getValidator(null).getFHIRPathEngine();
Element e = Manager.parseSingle(context, new ByteArrayInputStream(cnt.focus), cnt.cntType);
ExpressionNode exp = fpe.parse(expression);
return fpe.evaluateToString(new ValidatorHostContext(context, e), e, e, e, exp);
}
use of org.hl7.fhir.validation.instance.utils.ValidatorHostContext in project org.hl7.fhir.core by hapifhir.
the class InstanceValidator method checkInvariants.
private void checkInvariants(ValidatorHostContext hostContext, List<ValidationMessage> errors, String path, StructureDefinition profile, ElementDefinition ed, String typename, String typeProfile, Element resource, Element element, boolean onlyNonInherited) throws FHIRException, FHIRException {
if (noInvariantChecks)
return;
for (ElementDefinitionConstraintComponent inv : ed.getConstraint()) {
if (inv.hasExpression() && (!onlyNonInherited || !inv.hasSource() || (!isInheritedProfile(profile, inv.getSource()) && !isInheritedProfile(ed.getType(), inv.getSource())))) {
@SuppressWarnings("unchecked") Map<String, List<ValidationMessage>> invMap = executionId.equals(element.getUserString(EXECUTION_ID)) ? (Map<String, List<ValidationMessage>>) element.getUserData(EXECUTED_CONSTRAINT_LIST) : null;
if (invMap == null) {
invMap = new HashMap<>();
element.setUserData(EXECUTED_CONSTRAINT_LIST, invMap);
element.setUserData(EXECUTION_ID, executionId);
}
List<ValidationMessage> invErrors = null;
// We key based on inv.expression rather than inv.key because expressions can change in derived profiles and aren't guaranteed to be consistent across profiles.
String key = fixExpr(inv.getExpression(), inv.getKey());
if (!invMap.keySet().contains(key)) {
invErrors = new ArrayList<ValidationMessage>();
invMap.put(key, invErrors);
checkInvariant(hostContext, invErrors, path, profile, resource, element, inv);
} else {
invErrors = (ArrayList<ValidationMessage>) invMap.get(key);
}
errors.addAll(invErrors);
}
}
}
use of org.hl7.fhir.validation.instance.utils.ValidatorHostContext in project org.hl7.fhir.core by hapifhir.
the class InstanceValidator method startInner.
public void startInner(ValidatorHostContext hostContext, List<ValidationMessage> errors, Element resource, Element element, StructureDefinition defn, NodeStack stack, boolean checkSpecials) {
// the first piece of business is to see if we've validated this resource against this profile before.
// if we have (*or if we still are*), then we'll just return our existing errors
ResourceValidationTracker resTracker = getResourceTracker(element);
List<ValidationMessage> cachedErrors = resTracker.getOutcomes(defn);
if (cachedErrors != null) {
for (ValidationMessage vm : cachedErrors) {
if (!errors.contains(vm)) {
errors.add(vm);
}
}
return;
}
if (rule(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), defn.hasSnapshot(), I18nConstants.VALIDATION_VAL_PROFILE_NOSNAPSHOT, defn.getUrl())) {
List<ValidationMessage> localErrors = new ArrayList<ValidationMessage>();
resTracker.startValidating(defn);
trackUsage(defn, hostContext, element);
validateElement(hostContext, localErrors, defn, defn.getSnapshot().getElement().get(0), null, null, resource, element, element.getName(), stack, false, true, null);
resTracker.storeOutcomes(defn, localErrors);
for (ValidationMessage vm : localErrors) {
if (!errors.contains(vm)) {
errors.add(vm);
}
}
}
if (checkSpecials) {
checkSpecials(hostContext, errors, element, stack, checkSpecials);
validateResourceRules(errors, element, stack);
}
}
use of org.hl7.fhir.validation.instance.utils.ValidatorHostContext in project org.hl7.fhir.core by hapifhir.
the class InstanceValidator method checkChildByDefinition.
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;
ElementDefinition typeDefn = null;
checkMustSupport(profile, ei);
if (checkDefn.getType().size() == 1 && !"*".equals(checkDefn.getType().get(0).getWorkingCode()) && !"Element".equals(checkDefn.getType().get(0).getWorkingCode()) && !"BackboneElement".equals(checkDefn.getType().get(0).getWorkingCode())) {
type = checkDefn.getType().get(0).getWorkingCode();
String stype = ei.getElement().fhirType();
if (checkDefn.isChoice() && !stype.equals(type)) {
if ("Extension".equals(profile.getType())) {
// error will be raised elsewhere
} else {
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), false, I18nConstants.EXTENSION_PROF_TYPE, profile.getUrl(), type, stype);
}
}
// Excluding reference is a kludge to get around versioning issues
if (checkDefn.getType().get(0).hasProfile()) {
for (CanonicalType p : checkDefn.getType().get(0).getProfile()) {
profiles.add(p.getValue());
}
}
} else if (checkDefn.getType().size() == 1 && "*".equals(checkDefn.getType().get(0).getWorkingCode())) {
String prefix = tail(checkDefn.getPath());
assert prefix.endsWith("[x]");
type = ei.getName().substring(prefix.length() - 3);
if (isPrimitiveType(type))
type = Utilities.uncapitalize(type);
if (checkDefn.getType().get(0).hasProfile()) {
for (CanonicalType p : checkDefn.getType().get(0).getProfile()) {
profiles.add(p.getValue());
}
}
} else if (checkDefn.getType().size() > 1) {
String prefix = tail(checkDefn.getPath());
assert typesAreAllReference(checkDefn.getType()) || checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR) || prefix.endsWith("[x]") || isResourceAndTypes(checkDefn) : "Multiple Types allowed, but name is wrong @ " + checkDefn.getPath() + ": " + checkDefn.typeSummaryVB();
if (checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR)) {
type = ei.getElement().getType();
} else if (ei.getElement().isResource()) {
type = ei.getElement().fhirType();
} else {
prefix = prefix.substring(0, prefix.length() - 3);
for (TypeRefComponent t : checkDefn.getType()) if ((prefix + Utilities.capitalize(t.getWorkingCode())).equals(ei.getName())) {
type = t.getWorkingCode();
// Excluding reference is a kludge to get around versioning issues
if (t.hasProfile() && !type.equals("Reference"))
profiles.add(t.getProfile().get(0).getValue());
}
}
if (type == null) {
TypeRefComponent trc = checkDefn.getType().get(0);
if (trc.getWorkingCode().equals("Reference"))
type = "Reference";
else
rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOTYPE, ei.getName(), describeTypes(checkDefn.getType()));
}
} else if (checkDefn.getContentReference() != null) {
typeDefn = resolveNameReference(profile.getSnapshot(), checkDefn.getContentReference());
} else if (checkDefn.getType().size() == 1 && ("Element".equals(checkDefn.getType().get(0).getWorkingCode()) || "BackboneElement".equals(checkDefn.getType().get(0).getWorkingCode()))) {
if (checkDefn.getType().get(0).hasProfile()) {
CanonicalType pu = checkDefn.getType().get(0).getProfile().get(0);
if (pu.hasExtension(ToolingExtensions.EXT_PROFILE_ELEMENT))
profiles.add(pu.getValue() + "#" + pu.getExtensionString(ToolingExtensions.EXT_PROFILE_ELEMENT));
else
profiles.add(pu.getValue());
}
}
if (type != null) {
if (type.startsWith("@")) {
checkDefn = findElement(profile, type.substring(1));
if (isSlice) {
ei.slice = ei.definition;
} else {
ei.definition = ei.definition;
}
type = null;
}
}
NodeStack localStack = stack.push(ei.getElement(), "*".equals(ei.getDefinition().getBase().getMax()) && ei.count == -1 ? 0 : ei.count, checkDefn, type == null ? typeDefn : resolveType(type, checkDefn.getType()));
// if (debug) {
// System.out.println(" check " + localStack.getLiteralPath()+" against "+ei.getDefinition().getId()+" in profile "+profile.getUrl());
// }
String localStackLiteralPath = localStack.getLiteralPath();
String eiPath = ei.getPath();
if (!eiPath.equals(localStackLiteralPath)) {
assert (eiPath.equals(localStackLiteralPath)) : "ei.path: " + ei.getPath() + " - localStack.getLiteralPath: " + localStackLiteralPath;
}
boolean thisIsCodeableConcept = false;
String thisExtension = null;
boolean checkDisplay = true;
SpecialElement special = ei.getElement().getSpecial();
if (special == SpecialElement.BUNDLE_ENTRY || special == SpecialElement.BUNDLE_OUTCOME || special == SpecialElement.PARAMETER) {
checkInvariants(hostContext, errors, profile, typeDefn != null ? typeDefn : checkDefn, ei.getElement(), ei.getElement(), localStack, false);
} else {
checkInvariants(hostContext, errors, profile, typeDefn != null ? typeDefn : checkDefn, resource, ei.getElement(), localStack, false);
}
ei.getElement().markValidation(profile, checkDefn);
boolean elementValidated = false;
if (type != null) {
if (isPrimitiveType(type)) {
checkPrimitive(hostContext, errors, ei.getPath(), type, checkDefn, ei.getElement(), profile, stack);
} else {
if (checkDefn.hasFixed()) {
checkFixedValue(errors, ei.getPath(), ei.getElement(), checkDefn.getFixed(), profile.getUrl(), checkDefn.getSliceName(), null, false);
}
if (checkDefn.hasPattern()) {
checkFixedValue(errors, ei.getPath(), ei.getElement(), checkDefn.getPattern(), profile.getUrl(), checkDefn.getSliceName(), null, true);
}
}
if (type.equals("Identifier")) {
checkIdentifier(errors, ei.getPath(), ei.getElement(), checkDefn);
} else if (type.equals("Coding")) {
checkCoding(errors, ei.getPath(), ei.getElement(), profile, checkDefn, inCodeableConcept, checkDisplayInContext, stack);
} else if (type.equals("Quantity")) {
checkQuantity(errors, ei.getPath(), ei.getElement(), profile, checkDefn, stack);
} else if (type.equals("Attachment")) {
checkAttachment(errors, ei.getPath(), ei.getElement(), profile, checkDefn, inCodeableConcept, checkDisplayInContext, stack);
} else if (type.equals("CodeableConcept")) {
checkDisplay = checkCodeableConcept(errors, ei.getPath(), ei.getElement(), profile, checkDefn, stack);
thisIsCodeableConcept = true;
} else if (type.equals("Reference")) {
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
} else if (type.equals("Extension")) {
Element eurl = ei.getElement().getNamedChild("url");
if (rule(errors, IssueType.INVALID, ei.getPath(), eurl != null, I18nConstants.EXTENSION_EXT_URL_NOTFOUND)) {
String url = eurl.primitiveValue();
thisExtension = url;
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)) {
checkExtension(hostContext, errors, ei.getPath(), resource, element, ei.getElement(), checkDefn, profile, localStack, stack, extensionUrl);
}
}
}
} else if (type.equals("Resource") || isResource(type)) {
validateContains(hostContext, errors, ei.getPath(), checkDefn, definition, resource, ei.getElement(), localStack, idStatusForEntry(element, ei), // if
profile);
elementValidated = true;
// (str.matches(".*([.,/])work\\1$"))
} else if (Utilities.isAbsoluteUrl(type)) {
StructureDefinition defn = context.fetchTypeDefinition(type);
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());
if (txtype.contains("CodeableConcept")) {
checkTerminologyCodeableConcept(errors, ei.getPath(), ei.getElement(), profile, checkDefn, stack, defn);
thisIsCodeableConcept = true;
} else if (txtype.contains("Coding")) {
checkTerminologyCoding(errors, ei.getPath(), ei.getElement(), profile, checkDefn, inCodeableConcept, checkDisplayInContext, stack, defn);
}
}
}
} else {
if (rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), checkDefn != null, I18nConstants.VALIDATION_VAL_CONTENT_UNKNOWN, ei.getName()))
validateElement(hostContext, errors, profile, checkDefn, null, null, resource, ei.getElement(), type, localStack, false, true, null);
}
StructureDefinition p = null;
String tail = null;
if (profiles.isEmpty()) {
if (type != null) {
p = getProfileForType(type, checkDefn.getType());
// 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
// checked against the primary type's invariants: LLoyd
// if (p.getKind() == StructureDefinitionKind.PRIMITIVETYPE) {
// checkInvariants(hostContext, errors, ei.path, profile, ei.definition, null, null, resource, ei.element);
// }
rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), p != null, I18nConstants.VALIDATION_VAL_NOTYPE, type);
}
} else if (profiles.size() == 1) {
String url = profiles.get(0);
if (url.contains("#")) {
tail = url.substring(url.indexOf("#") + 1);
url = url.substring(0, url.indexOf("#"));
}
p = this.context.fetchResource(StructureDefinition.class, url);
rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), p != null, I18nConstants.VALIDATION_VAL_UNKNOWN_PROFILE, profiles.get(0));
} else {
elementValidated = true;
HashMap<String, List<ValidationMessage>> goodProfiles = new HashMap<String, List<ValidationMessage>>();
HashMap<String, List<ValidationMessage>> badProfiles = new HashMap<String, List<ValidationMessage>>();
for (String typeProfile : profiles) {
String url = typeProfile;
tail = null;
if (url.contains("#")) {
tail = url.substring(url.indexOf("#") + 1);
url = url.substring(0, url.indexOf("#"));
}
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)) {
List<ValidationMessage> profileErrors = new ArrayList<ValidationMessage>();
validateElement(hostContext, profileErrors, p, getElementByTail(p, tail), profile, checkDefn, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension);
if (hasErrors(profileErrors))
badProfiles.put(typeProfile, profileErrors);
else
goodProfiles.put(typeProfile, profileErrors);
}
}
if (goodProfiles.size() == 1) {
errors.addAll(goodProfiles.values().iterator().next());
} else if (goodProfiles.size() == 0) {
rule(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOMATCH, StringUtils.join("; ", profiles));
for (String m : badProfiles.keySet()) {
p = this.context.fetchResource(StructureDefinition.class, m);
for (ValidationMessage message : badProfiles.get(m)) {
message.setMessage(message.getMessage() + " (validating against " + p.getUrl() + (p.hasVersion() ? "|" + p.getVersion() : "") + " [" + p.getName() + "])");
errors.add(message);
}
}
} else {
warning(errors, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_MULTIPLEMATCHES, StringUtils.join("; ", goodProfiles.keySet()));
for (String m : goodProfiles.keySet()) {
p = this.context.fetchResource(StructureDefinition.class, m);
for (ValidationMessage message : goodProfiles.get(m)) {
message.setMessage(message.getMessage() + " (validating against " + p.getUrl() + (p.hasVersion() ? "|" + p.getVersion() : "") + " [" + p.getName() + "])");
errors.add(message);
}
}
}
}
if (p != null) {
trackUsage(p, hostContext, element);
if (!elementValidated) {
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, checkDefn, ei.getElement(), ei.getElement(), type, localStack.resetIds(), thisIsCodeableConcept, checkDisplay, thisExtension);
else
validateElement(hostContext, errors, p, getElementByTail(p, tail), profile, checkDefn, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension);
}
int index = profile.getSnapshot().getElement().indexOf(checkDefn);
if (index < profile.getSnapshot().getElement().size() - 1) {
String nextPath = profile.getSnapshot().getElement().get(index + 1).getPath();
if (!nextPath.equals(checkDefn.getPath()) && nextPath.startsWith(checkDefn.getPath()))
validateElement(hostContext, errors, profile, checkDefn, null, null, resource, ei.getElement(), type, localStack, thisIsCodeableConcept, checkDisplay, thisExtension);
}
}
}
Aggregations