001package org.hl7.fhir.r4b.utils; 002 003/* 004 Copyright (c) 2011+, HL7, Inc. 005 All rights reserved. 006 007 Redistribution and use in source and binary forms, with or without modification, 008 are permitted provided that the following conditions are met: 009 010 * Redistributions of source code must retain the above copyright notice, this 011 list of conditions and the following disclaimer. 012 * Redistributions in binary form must reproduce the above copyright notice, 013 this list of conditions and the following disclaimer in the documentation 014 and/or other materials provided with the distribution. 015 * Neither the name of HL7 nor the names of its contributors may be used to 016 endorse or promote products derived from this software without specific 017 prior written permission. 018 019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 022 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 023 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 024 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 025 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 026 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 027 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 028 POSSIBILITY OF SUCH DAMAGE. 029 030 */ 031 032 033 034import java.io.IOException; 035import java.io.InputStream; 036import java.net.MalformedURLException; 037import java.net.URISyntaxException; 038import java.util.List; 039import java.util.Locale; 040 041import org.hl7.fhir.exceptions.DefinitionException; 042import org.hl7.fhir.exceptions.FHIRException; 043import org.hl7.fhir.exceptions.FHIRFormatError; 044import org.hl7.fhir.r4b.elementmodel.Element; 045import org.hl7.fhir.r4b.elementmodel.Manager.FhirFormat; 046import org.hl7.fhir.r4b.model.CanonicalResource; 047import org.hl7.fhir.r4b.model.StructureDefinition; 048import org.hl7.fhir.r4b.utils.IResourceValidator.BundleValidationRule; 049import org.hl7.fhir.utilities.Utilities; 050import org.hl7.fhir.utilities.validation.ValidationMessage; 051 052import com.google.gson.JsonObject; 053 054/** 055 * Interface to the instance validator. This takes a resource, in one of many forms, and 056 * checks whether it is valid 057 * 058 * @author Grahame Grieve 059 * 060 */ 061public interface IResourceValidator { 062 063 public class BundleValidationRule { 064 private String rule; 065 private String profile; 066 private boolean checked; 067 068 public BundleValidationRule(String rule, String profile) { 069 super(); 070 this.rule = rule; 071 this.profile = profile; 072 } 073 public String getRule() { 074 return rule; 075 } 076 public String getProfile() { 077 return profile; 078 } 079 public boolean isChecked() { 080 return checked; 081 } 082 public void setChecked(boolean checked) { 083 this.checked = checked; 084 } 085 } 086 087 public enum ReferenceValidationPolicy { 088 IGNORE, CHECK_TYPE_IF_EXISTS, CHECK_EXISTS, CHECK_EXISTS_AND_TYPE, CHECK_VALID; 089 090 public boolean checkExists() { 091 return this == CHECK_EXISTS_AND_TYPE || this == CHECK_EXISTS || this == CHECK_VALID || this == CHECK_TYPE_IF_EXISTS; 092 } 093 094 public boolean checkType() { 095 return this == CHECK_TYPE_IF_EXISTS || this == CHECK_EXISTS_AND_TYPE || this == CHECK_VALID; 096 } 097 098 public boolean checkValid() { 099 return this == CHECK_VALID; 100 } 101 } 102 103 public interface IValidationProfileUsageTracker { 104 void recordProfileUsage(StructureDefinition profile, Object appContext, Element element); 105 } 106 107 108 public interface IValidatorResourceFetcher { 109 110 Element fetch(Object appContext, String url) throws FHIRFormatError, DefinitionException, FHIRException, IOException; 111 ReferenceValidationPolicy validationPolicy(Object appContext, String path, String url); 112 boolean resolveURL(Object appContext, String path, String url, String type) throws IOException, FHIRException; 113 114 byte[] fetchRaw(String url) throws MalformedURLException, IOException; // for attachment checking 115 116 IValidatorResourceFetcher setLocale(Locale locale); 117 118 119 /** 120 * this is used when the validator encounters a reference to a structure definition, value set or code system at some random URL reference 121 * while validating. 122 * 123 * Added in v5.2.2. return null to leave functionality as it was before then. 124 * 125 * @param primitiveValue 126 * @return an R5 version of the resource 127 * @throws URISyntaxException 128 */ 129 CanonicalResource fetchCanonicalResource(String url) throws URISyntaxException; 130 131 /** 132 * Whether to try calling fetchCanonicalResource for this reference (not whether it will succeed - just throw an exception from fetchCanonicalResource if it doesn't resolve. This is a policy thing. 133 * 134 * Added in v5.2.2. return false to leave functionality as it was before then. 135 * 136 * @param url 137 * @return 138 */ 139 boolean fetchesCanonicalResource(String url); 140 } 141 142 public enum BestPracticeWarningLevel { 143 Ignore, 144 Hint, 145 Warning, 146 Error 147 } 148 149 public enum CheckDisplayOption { 150 Ignore, 151 Check, 152 CheckCaseAndSpace, 153 CheckCase, 154 CheckSpace 155 } 156 157 enum IdStatus { 158 OPTIONAL, REQUIRED, PROHIBITED 159 } 160 161 /** 162 * how much to check displays for coded elements 163 * @return 164 */ 165 CheckDisplayOption getCheckDisplay(); 166 void setCheckDisplay(CheckDisplayOption checkDisplay); 167 168 /** 169 * whether the resource must have an id or not (depends on context) 170 * 171 * @return 172 */ 173 174 IdStatus getResourceIdRule(); 175 void setResourceIdRule(IdStatus resourceIdRule); 176 177 /** 178 * whether the validator should enforce best practice guidelines 179 * as defined by various HL7 committees 180 * 181 */ 182 BestPracticeWarningLevel getBestPracticeWarningLevel(); 183 IResourceValidator setBestPracticeWarningLevel(BestPracticeWarningLevel value); 184 185 IValidatorResourceFetcher getFetcher(); 186 IResourceValidator setFetcher(IValidatorResourceFetcher value); 187 188 IValidationProfileUsageTracker getTracker(); 189 IResourceValidator setTracker(IValidationProfileUsageTracker value); 190 191 boolean isNoBindingMsgSuppressed(); 192 IResourceValidator setNoBindingMsgSuppressed(boolean noBindingMsgSuppressed); 193 194 public boolean isNoInvariantChecks(); 195 public IResourceValidator setNoInvariantChecks(boolean value) ; 196 197 public boolean isNoTerminologyChecks(); 198 public IResourceValidator setNoTerminologyChecks(boolean noTerminologyChecks); 199 200 public boolean isNoExtensibleWarnings(); 201 public IResourceValidator setNoExtensibleWarnings(boolean noExtensibleWarnings); 202 203 /** 204 * Whether being unable to resolve a profile in found in Resource.meta.profile or ElementDefinition.type.profile or targetProfile is an error or just a warning 205 * @return 206 */ 207 public boolean isErrorForUnknownProfiles(); 208 public void setErrorForUnknownProfiles(boolean errorForUnknownProfiles); 209 210 public boolean isShowMessagesFromReferences(); 211 public void setShowMessagesFromReferences(boolean value); 212 213 /** 214 * this is used internally in the publishing stack to ensure that everything is water tight, but 215 * this check is not necessary or appropriate at run time when the validator is hosted in HAPI 216 * @return 217 */ 218 public boolean isWantCheckSnapshotUnchanged(); 219 public void setWantCheckSnapshotUnchanged(boolean wantCheckSnapshotUnchanged); 220 221 //FIXME: don't need that, gets never used? 222// public String getValidationLanguage(); 223// public void setValidationLanguage(String value); 224 225 /** 226 * It's common to see references such as Patient/234234 - these usually mean a reference to a Patient resource. 227 * But there's no actual technical rule that it does, so the validator doesn't enforce that unless this setting is 228 * set to true 229 * 230 * @return 231 */ 232 public boolean isAssumeValidRestReferences(); 233 public void setAssumeValidRestReferences(boolean value); 234 235 /** 236 * if this is true, the validator will accept extensions and references to example.org and acme.com as 237 * valid, on the basis that they are understood to be references to content that could exist in priniple but can't in practice 238 */ 239 public boolean isAllowExamples(); 240 public void setAllowExamples(boolean value) ; 241 242 public boolean isNoCheckAggregation(); 243 public void setNoCheckAggregation(boolean value); 244 /** 245 * CrumbTrail - whether the validator creates hints to 246 * @return 247 */ 248 public boolean isCrumbTrails(); 249 public void setCrumbTrails(boolean crumbTrails); 250 251 public boolean isValidateValueSetCodesOnTxServer(); 252 public void setValidateValueSetCodesOnTxServer(boolean value); 253 254 /** 255 * Bundle validation rules allow for requesting particular entries in a bundle get validated against particular profiles 256 * Typically this is used from the command line to avoid having to construct profile just to validate a particular resource 257 * in a bundle against a particular profile 258 * 259 * @return 260 */ 261 public List<BundleValidationRule> getBundleValidationRules(); 262 263 /** 264 * Validate suite 265 * 266 * you can validate one of the following representations of resources: 267 * 268 * stream - provide a format - this is the preferred choice 269 * 270 * Use one of these two if the content is known to be valid XML/JSON, and already parsed 271 * - a DOM element or Document 272 * - a Json Object 273 * 274 * In order to use these, the content must already be parsed - e.g. it must syntactically valid 275 * - a native resource 276 * - a elementmodel resource 277 * 278 * in addition, you can pass one or more profiles ti validate beyond the base standard - as structure definitions or canonical URLs 279 * @throws IOException 280 */ 281 void validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r4b.elementmodel.Element element) throws FHIRException; 282 void validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r4b.elementmodel.Element element, String profile) throws FHIRException; 283 void validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r4b.elementmodel.Element element, List<StructureDefinition> profiles) throws FHIRException; 284 285 org.hl7.fhir.r4b.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, InputStream stream, FhirFormat format) throws FHIRException; 286 org.hl7.fhir.r4b.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, InputStream stream, FhirFormat format, String profile) throws FHIRException; 287 org.hl7.fhir.r4b.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, InputStream stream, FhirFormat format, List<StructureDefinition> profiles) throws FHIRException; 288 289 org.hl7.fhir.r4b.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r4b.model.Resource resource) throws FHIRException; 290 org.hl7.fhir.r4b.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r4b.model.Resource resource, String profile) throws FHIRException; 291 org.hl7.fhir.r4b.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.r4b.model.Resource resource, List<StructureDefinition> profiles) throws FHIRException; 292 293 org.hl7.fhir.r4b.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Element element) throws FHIRException; 294 org.hl7.fhir.r4b.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Element element, String profile) throws FHIRException; 295 org.hl7.fhir.r4b.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Element element, List<StructureDefinition> profile) throws FHIRException; 296 297 org.hl7.fhir.r4b.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Document document) throws FHIRException; 298 org.hl7.fhir.r4b.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Document document, String profile) throws FHIRException; 299 org.hl7.fhir.r4b.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Document document, List<StructureDefinition> profile) throws FHIRException; 300 301 org.hl7.fhir.r4b.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, JsonObject object) throws FHIRException; 302 org.hl7.fhir.r4b.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, JsonObject object, String profile) throws FHIRException; 303 org.hl7.fhir.r4b.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, JsonObject object, List<StructureDefinition> profile) throws FHIRException; 304 305 306}