
001package org.hl7.fhir.r5.utils.validation; 002 003import java.util.EnumSet; 004import java.util.List; 005 006import org.hl7.fhir.r5.elementmodel.Element; 007import org.hl7.fhir.r5.model.ElementDefinition; 008import org.hl7.fhir.r5.model.StructureDefinition; 009import org.hl7.fhir.r5.model.ValueSet; 010import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy; 011import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy; 012import org.hl7.fhir.utilities.MarkedToMoveToAdjunctPackage; 013import org.hl7.fhir.utilities.validation.ValidationMessage; 014import org.hl7.fhir.r5.utils.validation.constants.CodedContentValidationPolicy; 015import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor.ElementValidationAction; 016import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor.ReferenceDestinationType; 017import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor.SpecialValidationAction; 018import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor.SpecialValidationRule; 019import org.hl7.fhir.r5.utils.validation.constants.BindingKind; 020 021@MarkedToMoveToAdjunctPackage 022public interface IValidationPolicyAdvisor { 023 024 025 026 public enum ReferenceDestinationType { 027 CONTAINED, // the reference points to a contained resource in the resource being validated 028 INTERNAL, // the reference points to another resource in the scope of what is being validated 029 EXTERNAL; // the reference points outside what is being validated. 030 // Note that at the point this is called, the validator has not tried to see whether the reference 031 // is resolvable based on the resources made available to it 032 033 public String toCode() { 034 switch (this) { 035 case CONTAINED: return "contained"; 036 case EXTERNAL: return "external"; 037 case INTERNAL: return "internal"; 038 } 039 return null; 040 } 041 } 042 043 public IValidationPolicyAdvisor getPolicyAdvisor(); 044 public IValidationPolicyAdvisor setPolicyAdvisor(IValidationPolicyAdvisor policyAdvisor); 045 046 /** 047 * Internal use, for chaining advisors - if you define an implementation, you return the default policy. 048 * Usually, this is the policy for the operating policy advisor in place before your implementation is 049 * registered, so keep a reference to that and pass the value through 050 * 051 * @return 052 */ 053 ReferenceValidationPolicy getReferencePolicy(); 054 055 /** 056 * Return true if the validation message for this message id should not be reported 057 * 058 * Note that this is generally a pretty blunt instrument. E.g. you might want to suppress 059 * errors associated with a particular code system, but this can only suppress errors associated 060 * with all code systems 061 * 062 * @param path - the current path of the element 063 * @param messageId - the message id (from messages.properties) 064 * @return true if the validator should ignore the message 065 */ 066 boolean isSuppressMessageId(String path, String messageId); 067 068 /** 069 * Whether to try validating a reference, and if so, how much validation to apply 070 * 071 * @param validator 072 * @param appContext What was originally provided from the app for it's context 073 * @param path Path that led us to this resource. 074 * @param url Url of the profile the container resource is being validated against. 075 * @return {@link ReferenceValidationPolicy} 076 */ 077 ReferenceValidationPolicy policyForReference(IResourceValidator validator, 078 Object appContext, 079 String path, 080 String url, 081 ReferenceDestinationType destinationType); 082 083 /** 084 * whether to validate a contained resource. Note that if there's a reference to the 085 * contained resource (and there should be), then the policyForReference will override 086 * this value (e.g. if the result of policyForReference is CHECK_VALID, then the 087 * resource will be validated, irrespective of the value of policyForContained) 088 * 089 * //TODO pass through the actual containing Element as opposed to the type, id 090 * @param validator 091 * @param appContext What was originally provided from the app for it's context 092 * @param containerType Type of the resources that contains the resource being validated 093 * @param containerId Id of the resources that contains the resource being validated 094 * @param containingResourceType Type of the resource that will be validated (BUNDLE_ENTRY, BUNDLE_OUTCOME, CONTAINED_RESOURCE, PARAMETER) 095 * @param path Path that led us to this resource. 096 * @param url Url of the profile the container resource is being validated against. 097 * @return {@link ReferenceValidationPolicy} 098 */ 099 ContainedReferenceValidationPolicy policyForContained(IResourceValidator validator, 100 Object appContext, 101 StructureDefinition structure, 102 ElementDefinition element, 103 String containerType, 104 String containerId, 105 Element.SpecialElement containingResourceType, 106 String path, 107 String url); 108 109 110 public enum ResourceValidationAction { 111 BaseType, 112 StatedProfiles, 113 MetaProfiles, 114 GlobalProfiles 115 } 116 117 EnumSet<ResourceValidationAction> policyForResource(IResourceValidator validator, 118 Object appContext, 119 StructureDefinition type, 120 String path); 121 122 public enum ElementValidationAction { 123 Cardinality, // though you can't stop slice matching cardinality checks from happening 124 Invariants, 125 Bindings, 126 AdditionalBindings, 127 StatusCheck 128 } 129 130 EnumSet<ElementValidationAction> policyForElement(IResourceValidator validator, 131 Object appContext, 132 StructureDefinition structure, 133 ElementDefinition element, 134 String path); 135 136 public enum AdditionalBindingPurpose { 137 Minimum, 138 Required, 139 Extensible, 140 Current, 141 Preferred, 142 Ui 143 } 144 145 public enum CodedContentValidationAction { 146 VSCheck, 147 VSCheckThisCode, 148 NotFound, 149 InvalidCode, 150 InvalidDisplay, 151 CannotInfer, 152 CodeRule, 153 VSInvalid, 154 StatusCheck 155 } 156 157 /** 158 * Called before validating a concept in an instance against the terminology sub-system 159 * 160 * There's two reasons to use this policy advisor feature: 161 * - save time by not calling the terminology server for validation that don't bring value to the context calling the validation 162 * - suppressing known issues from being listed as a problem 163 * 164 * Note that the terminology subsystem has two parts: a mini-terminology server running inside the 165 * validator, and then calling out to an external terminology service (usually tx.fhir.org, though you 166 * run your own local copy of this - see https://confluence.hl7.org/display/FHIR/Running+your+own+copy+of+tx.fhir.org). 167 * You can't tell which subsystem will handle the terminology validation directly from the content provided here which 168 * subsystem will be called - you'll haev to investigate based on your set up. (matters, since it makes a huge performance 169 * difference, though it also depends on caching, and the impact of caching is also not known at this point) 170 * 171 * @param validator 172 * @param appContext What was originally provided from the app for it's context 173 * @param stackPath The current path for the stack. Note that the because of cross-references and FHIRPath conformsTo() statements, the stack can wind through the content unpredictably. 174 * @param definition the definition being validated against (might be useful: ElementDefinition.base.path, ElementDefinition.type, ElementDefinition.binding 175 * @param structure The structure definition that contains the element definition being validated against (may be from the base spec, may be from a profile) 176 * @param kind The part of the binding being validated 177 * @param valueSet The value set for the binding part that's being validated 178 * @param systems A list of canonical URls (including versions if known) of the systems in the instance that's being validated. Note that if a plain code is being validated, then there'll be no known system when this is called (systems will be empty, not null) 179 * @return {@link CodedContentValidationPolicy} 180 */ 181 EnumSet<CodedContentValidationAction> policyForCodedContent(IResourceValidator validator, 182 Object appContext, 183 String stackPath, 184 ElementDefinition definition, 185 StructureDefinition structure, 186 BindingKind kind, 187 AdditionalBindingPurpose purpose, 188 ValueSet valueSet, 189 List<String> systems); 190 191 public enum SpecialValidationAction { 192 CHECK_RULE, IGNORE_RULE 193 } 194 195 public enum SpecialValidationRule { 196 CODESYSTEM_METADATA_CHECKS, // check code system metadata - including count, heirarchy, etc 197 CODESYSTEM_SUPPLEMENT_CHECKS, // check supplement integrity 198 CODESYSTEM_VALUESET_CHECKS, // check that the designated value set actually is the right value set 199 CODESYSTEM_PROPERTY_CHECKS, // check that the properties are defined properly 200 CODESYSTEM_DESIGNATION_CHECKS, // check that concept designations (element = concept) 201 VALUESET_METADATA_CHECKS, // check the value set metadata (element = include/exclude) 202 VALUESET_SYSTEM_CHECKS, // check that value set against the system definition (element = include/exclude) 203 VALUESET_IMPORT_CHECKS // check the value set imports (element = include/exclude) 204 } 205 206 /** 207 * This routine gives control over the execution of the advanced validator functionality that applies to particular kinds of resources 208 * 209 * @param validator 210 * @param appContext What was originally provided from the app for it's context 211 * @param rule The rule that is to be executed (actually often a group of checks) 212 * @param stackPath The current path for the stack. Note that the because of cross-references and FHIRPath conformsTo() statements, the stack can wind through the content unpredictably. 213 * @param resource The resource that is being checked 214 * @param element The element that is being checked (if relevant for the rule) 215 * @return whether to execute the rule or not 216 */ 217 SpecialValidationAction policyForSpecialValidation(IResourceValidator validator, 218 Object appContext, 219 SpecialValidationRule rule, 220 String stackPath, 221 Element resource, 222 Element element); 223 224 /** 225 * This is called after a resource has been validated against the base structure, 226 * but before it's validated against any profiles specified in .meta.profile or in the parameters. 227 * This can be used to determine what additional profiles should be applied, for instance 228 * those derived from the http://hl7.org/fhir/tools/StructureDefinition/profile-mapping extension 229 * 230 * Note that the resource is an elementModel resource, not an IBaseResource. This is less convenient to 231 * read values from, but is the way the internals of the validator works (e.g. the version of the resource 232 * might be any version from R2-R6) 233 * 234 * The base implementation applies the mandatory vital signs to observations that have LOINC or SNOMED CT 235 * codes that indicate that they are vital signs. Note that these profiles are not optional; all vital sign resources 236 * are required to conform to them. For this reason, if you're providing your own policy advisor, you should 237 * keep a reference to the default one, or call BasePolicyAdvisorForFullValidation directly. You can choose not to, 238 * but if you do, you are allowing for resources that deviate from the FHIR specification (in a way that the 239 * community considers clinically unsafe, since it means that software (probably) will miss vital signs for 240 * patients). 241 * 242 * @param validator 243 * @param appContext What was originally provided from the app for it's context 244 * @param stackPath The current path for the stack. Note that the because of cross-references and FHIRPath conformsTo() statements, the stack can wind through the content unpredictably. 245 * @param definition the definition being validated against (might be useful: ElementDefinition.base.path, ElementDefinition.type, ElementDefinition.binding 246 * @param structure The structure definition that contains the element definition being validated against (may be from the base spec, may be from a profile) 247 * @param resource The actual resource (as an element model) so that the implementation can inspect the values in order to decide what profiles to apply 248 * @param valid true if the resource is so far considered valid 249 * @param messages all the validation messages. Implementations can inspect this, but the real purpose is to populate the messages with information messages explaining why profiles were (or weren't) applied 250 * @return 251 */ 252 List<StructureDefinition> getImpliedProfilesForResource(IResourceValidator validator, 253 Object appContext, 254 String stackPath, 255 ElementDefinition definition, 256 StructureDefinition structure, 257 Element resource, 258 boolean valid, 259 IMessagingServices msgServices, 260 List<ValidationMessage> messages); 261 262 263}