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.validation.ValidationMessage;
013import org.hl7.fhir.r5.utils.validation.constants.CodedContentValidationPolicy;
014import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor.ElementValidationAction;
015import org.hl7.fhir.r5.utils.validation.constants.BindingKind;
016
017public interface IValidationPolicyAdvisor {
018
019  /** 
020   * Internal use, for chaining advisors
021   * 
022   * @return
023   */
024  ReferenceValidationPolicy getReferencePolicy();
025  
026  /**
027   * 
028   * @param path - the current path of the element
029   * @param messageId - the message id (from messages.properties)
030   * @return true if the validator should ignore the message
031   */
032  boolean isSuppressMessageId(String path, String messageId);
033  
034  /**
035   *
036   * @param validator
037   * @param appContext What was originally provided from the app for it's context
038   * @param path Path that led us to this resource.
039   * @param url Url of the profile the container resource is being validated against.
040   * @return {@link ReferenceValidationPolicy}
041   */
042  ReferenceValidationPolicy policyForReference(IResourceValidator validator,
043                                               Object appContext,
044                                               String path,
045                                               String url);
046
047  /**
048   * //TODO pass through the actual containing Element as opposed to the type, id
049   * @param validator
050   * @param appContext What was originally provided from the app for it's context
051   * @param containerType Type of the resources that contains the resource being validated
052   * @param containerId Id of the resources that contains the resource being validated
053   * @param containingResourceType Type of the resource that will be validated (BUNDLE_ENTRY, BUNDLE_OUTCOME, CONTAINED_RESOURCE, PARAMETER)
054   * @param path Path that led us to this resource.
055   * @param url Url of the profile the container resource is being validated against.
056   * @return {@link ReferenceValidationPolicy}
057   */
058  ContainedReferenceValidationPolicy policyForContained(IResourceValidator validator,
059                                                        Object appContext,
060                                                        StructureDefinition structure,
061                                                        ElementDefinition element,
062                                                        String containerType,
063                                                        String containerId,
064                                                        Element.SpecialElement containingResourceType,
065                                                        String path,
066                                                        String url);
067
068
069  public enum ResourceValidationAction {
070    BaseType,
071    StatedProfiles,
072    MetaProfiles,
073    GlobalProfiles
074  }
075  
076  EnumSet<ResourceValidationAction> policyForResource(IResourceValidator validator,
077      Object appContext,
078      StructureDefinition type,
079      String path);
080
081  public enum ElementValidationAction {
082    Cardinality, // though you can't stop slice matching cardinality checks from happening 
083    Invariants, 
084    Bindings,
085    AdditionalBindings,
086    StatusCheck
087  }
088  
089  EnumSet<ElementValidationAction> policyForElement(IResourceValidator validator,
090                                                      Object appContext,
091                                                      StructureDefinition structure,
092                                                      ElementDefinition element,
093                                                      String path);
094  
095  public enum AdditionalBindingPurpose {
096    Minimum,
097    Required,
098    Extensible,
099    Current,
100    Preferred,
101    Ui
102  }
103  
104  public enum CodedContentValidationAction {
105    VSCheck,  
106    VSCheckThisCode,
107    NotFound, 
108    InvalidCode,
109    InvalidDisplay,
110    CannotInfer,
111    CodeRule,
112    VSInvalid,
113    StatusCheck
114  }
115  
116  /**
117   * Called before validating a concept in an instance against the terminology sub-system
118   * 
119   * There's two reasons to use this policy advisor feature:
120   *   - save time by not calling the terminology server for validation that don't bring value to the context calling the validation
121   *   - suppressing known issues from being listed as a problem
122   *   
123   * Note that the terminology subsystem has two parts: a mini-terminology server running inside the 
124   * validator, and then calling out to an external terminology service (usually tx.fhir.org, though you
125   * run your own local copy of this - see https://confluence.hl7.org/display/FHIR/Running+your+own+copy+of+tx.fhir.org).
126   * You can't tell which subsystem will handle the terminology validation directly from the content provided here which
127   * subsystem will be called - you'll haev to investigate based on your set up. (matters, since it makes a huge performance 
128   * difference, though it also depends on caching, and the impact of caching is also not known at this point)
129   *   
130   * @param validator
131   * @param appContext What was originally provided from the app for it's context
132   * @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. 
133   * @param definition the definition being validated against (might be useful: ElementDefinition.base.path, ElementDefinition.type, ElementDefinition.binding
134   * @param structure The structure definition that contains the element definition being validated against (may be from the base spec, may be from a profile)
135   * @param kind The part of the binding being validated
136   * @param valueSet The value set for the binding part that's being validated 
137   * @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) 
138   * @return {@link CodedContentValidationPolicy}
139   */
140  EnumSet<CodedContentValidationAction> policyForCodedContent(IResourceValidator validator,
141                                                        Object appContext,
142                                                        String stackPath,
143                                                        ElementDefinition definition,
144                                                        StructureDefinition structure,
145                                                        BindingKind kind,
146                                                        AdditionalBindingPurpose purpose,
147                                                        ValueSet valueSet,
148                                                        List<String> systems);
149
150  /**
151   * This is called after a resource has been validated against the base structure, 
152   * but before it's validated against any profiles specified in .meta.profile or in the parameters. 
153   * This can be used to determine what additional profiles should be applied, for instance
154   * those derived from the http://hl7.org/fhir/tools/StructureDefinition/profile-mapping extension
155   *  
156   * Note that the resource is an elementModel resource, not an IBaseResource. This is less convenient to 
157   * read values from, but is the way the internals of the validator works (e.g. the version of the resource 
158   * might be any version from R2-R6)
159   * 
160   * The base implementation applies the mandatory vital signs to observations that have LOINC or SNOMED CT
161   * codes that indicate that they are vital signs. Note that these profiles are not optional; all vital sign resources 
162   * are required to conform to them. For this reason, if you're providing your own policy advisor, you should
163   * keep a reference to the default one, or call BasePolicyAdvisorForFullValidation directly. You can choose not to,
164   * but if you do, you are allowing for resources that deviate from the FHIR specification (in a way that the 
165   * community considers clinically unsafe, since it means that software (probably) will miss vital signs for 
166   * patients).
167   * 
168   * @param validator
169   * @param appContext What was originally provided from the app for it's context
170   * @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. 
171   * @param definition the definition being validated against (might be useful: ElementDefinition.base.path, ElementDefinition.type, ElementDefinition.binding
172   * @param structure The structure definition that contains the element definition being validated against (may be from the base spec, may be from a profile)
173   * @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 
174   * @param valid true if the resource is so far considered valid
175   * @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
176   * @return
177   */
178  List<StructureDefinition> getImpliedProfilesForResource(IResourceValidator validator,
179                                                        Object appContext,
180                                                        String stackPath,
181                                                        ElementDefinition definition,
182                                                        StructureDefinition structure,
183                                                        Element resource,
184                                                        boolean valid,
185                                                        IMessagingServices msgServices,
186                                                        List<ValidationMessage> messages);
187
188  
189}