diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/I18nConstants.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/I18nConstants.java index de0550613..9c713c5dd 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/I18nConstants.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/I18nConstants.java @@ -355,4 +355,8 @@ public class I18nConstants { public final static String ELEMENT__NULL_ = "element__null_"; public final static String GETSLICELIST_SHOULD_ONLY_BE_CALLED_WHEN_THE_ELEMENT_HAS_SLICING = "getSliceList_should_only_be_called_when_the_element_has_slicing"; public final static String UNABLE_TO_RESOLVE_NAME_REFERENCE__AT_PATH_ = "Unable_to_resolve_name_reference__at_path_"; + public final static String DETAILS_FOR__MATCHING_AGAINST_PROFILE_ = "Details_for__matching_against_Profile_"; + public final static String DOES_NOT_MATCH_SLICE_ = "Does_not_match_slice_"; + public final static String PROFILE__DOES_NOT_MATCH_FOR__BECAUSE_OF_THE_FOLLOWING_PROFILE_ISSUES__ = "Profile__does_not_match_for__because_of_the_following_profile_issues__"; + public final static String THIS_ELEMENT_DOES_NOT_MATCH_ANY_KNOWN_SLICE_ = "This_element_does_not_match_any_known_slice_"; } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java index fad7276ba..1c1bc7144 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java @@ -26,6 +26,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; @@ -2190,7 +2191,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat 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, "Details for " + ref + " matching against Profile" + sd.getUrl(), errorSummaryForSlicingAsHtml(badProfiles.get(sd))); + slicingHint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, + formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, ref, sd.getUrl()), errorSummaryForSlicingAsHtml(badProfiles.get(sd))); } } else { rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, profiles.size() == 1, I18nConstants.REFERENCE_REF_CANTMATCHCHOICE, ref, asList(type.getTargetProfile())); @@ -2206,7 +2208,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat 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, "Details for " + ref + " matching against Profile" + sd.getUrl(), errorSummaryForSlicingAsHtml(badProfiles.get(sd))); + slicingHint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, ref, sd.getUrl()), errorSummaryForSlicingAsHtml(badProfiles.get(sd))); } } else { warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, I18nConstants.REFERENCE_REF_MULTIPLEMATCHES, ref, asListByUrl(goodProfiles.keySet())); @@ -3147,10 +3149,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat ValidatorHostContext shc = hostContext.forSlicing(); boolean pass = evaluateSlicingExpression(shc, element, path, profile, n); if (!pass) { - slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, "Does not match slice'" + ed.getSliceName(), "discriminator = " + Utilities.escapeXml(n.toString())); + slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, formatMessage(I18nConstants.DOES_NOT_MATCH_SLICE_, ed.getSliceName(), "discriminator = " + Utilities.escapeXml(n.toString())); for (String url : shc.getSliceRecords().keySet()) { - slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, "Details for " + stack.getLiteralPath() + " against profile " + url, - "Profile " + url + " does not match for " + stack.getLiteralPath() + " because of the following profile issues: " + errorSummaryForSlicingAsHtml(shc.getSliceRecords().get(url))); + slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, + formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, stack.getLiteralPath(), url), + formatMessage(I18nConstants.PROFILE__DOES_NOT_MATCH_FOR__BECAUSE_OF_THE_FOLLOWING_PROFILE_ISSUES__, + url, + stack.getLiteralPath(), errorSummaryForSlicingAsHtml(shc.getSliceRecords().get(url)))); } } return pass; @@ -5008,8 +5013,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (ei.additionalSlice && ei.definition != null) { if (ei.definition.getSlicing().getRules().equals(ElementDefinition.SlicingRules.OPEN) || ei.definition.getSlicing().getRules().equals(ElementDefinition.SlicingRules.OPENATEND) && true /* TODO: replace "true" with condition to check that this element is at "end" */) { - slicingHint(errors, IssueType.INFORMATIONAL, ei.line(), ei.col(), ei.getPath(), false, "This element does not match any known slice" + (profile == null ? "" : " defined in the profile " + profile.getUrl()), - "This element does not match any known slice" + (profile == null ? "" : " defined in the profile " + profile.getUrl() + ": " + errorSummaryForSlicingAsHtml(ei.sliceInfo))); + slicingHint(errors, IssueType.INFORMATIONAL, ei.line(), ei.col(), ei.getPath(), false, + formatMessage(I18nConstants.THIS_ELEMENT_DOES_NOT_MATCH_ANY_KNOWN_SLICE_, + profile == null ? "" : " defined in the profile " + profile.getUrl()), + formatMessage(I18nConstants.THIS_ELEMENT_DOES_NOT_MATCH_ANY_KNOWN_SLICE_, profile == null ? "" : " defined in the profile " + profile.getUrl()) + errorSummaryForSlicingAsHtml(ei.sliceInfo)); } else if (ei.definition.getSlicing().getRules().equals(ElementDefinition.SlicingRules.CLOSED)) { rule(errors, IssueType.INVALID, ei.line(), ei.col(), ei.getPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOTSLICE, (profile == null ? "" : " defined in the profile " + profile.getUrl() + " and slicing is CLOSED: " + errorSummaryForSlicing(ei.sliceInfo))); } diff --git a/org.hl7.fhir.validation/src/main/resources/Messages.properties b/org.hl7.fhir.validation/src/main/resources/Messages.properties index 233d851a7..44784b597 100644 --- a/org.hl7.fhir.validation/src/main/resources/Messages.properties +++ b/org.hl7.fhir.validation/src/main/resources/Messages.properties @@ -340,3 +340,7 @@ element_id__null__on_ = element id = null: {0} on {1} element__null_ = element = null: {0} getSliceList_should_only_be_called_when_the_element_has_slicing = getSliceList should only be called when the element has slicing Unable_to_resolve_name_reference__at_path_ = Unable to resolve name reference {0} at path {1} +Details_for__matching_against_Profile_ = Details for {0} matching against Profile{1} +Does_not_match_slice_ = Does not match slice "{0}" +Profile__does_not_match_for__because_of_the_following_profile_issues__ = Profile {0} does not match for {1} because of the following profile issues: {2} +This_element_does_not_match_any_known_slice_ = This element does not match any known slice{0} \ No newline at end of file