001/* 002 * #%L 003 * HAPI FHIR - Core Library 004 * %% 005 * Copyright (C) 2014 - 2024 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.parser; 021 022import ca.uhn.fhir.context.ConfigurationException; 023import ca.uhn.fhir.context.FhirContext; 024import ca.uhn.fhir.context.ParserOptions; 025import ca.uhn.fhir.model.api.IResource; 026import ca.uhn.fhir.rest.api.EncodingEnum; 027import org.hl7.fhir.instance.model.api.IAnyResource; 028import org.hl7.fhir.instance.model.api.IBase; 029import org.hl7.fhir.instance.model.api.IBaseResource; 030import org.hl7.fhir.instance.model.api.IIdType; 031 032import java.io.IOException; 033import java.io.InputStream; 034import java.io.Reader; 035import java.io.Writer; 036import java.util.Collection; 037import java.util.List; 038import java.util.Set; 039 040/** 041 * A parser, which can be used to convert between HAPI FHIR model/structure objects, and their respective String wire 042 * formats, in either XML or JSON. 043 * <p> 044 * Thread safety: <b>Parsers are not guaranteed to be thread safe</b>. Create a new parser instance for every thread or 045 * every message being parsed/encoded. 046 * </p> 047 */ 048public interface IParser { 049 050 /** 051 * Encodes a resource using the parser's given encoding format. 052 * 053 * @param theResource The resource to encode. Must not be null. 054 * @return A string representation of the encoding 055 * @throws DataFormatException If any invalid elements within the contents to be encoded prevent successful encoding. 056 */ 057 String encodeResourceToString(IBaseResource theResource) throws DataFormatException; 058 059 /** 060 * Encodes a resource using the parser's given encoding format. 061 * 062 * @param theResource The resource to encode. Must not be null. 063 * @param theWriter The writer to write to. 064 * @throws DataFormatException If any invalid elements within the contents to be encoded prevent successful encoding. 065 */ 066 void encodeResourceToWriter(IBaseResource theResource, Writer theWriter) throws IOException, DataFormatException; 067 068 /** 069 * Encodes any FHIR element to a string. 070 * If a {@link IBaseResource resource object} is passed in, the resource will be encoded using standard FHIR 071 * encoding rules. If a {@link org.hl7.fhir.instance.model.api.IPrimitiveType primitive datatype} is passed in, 072 * the string value of the primitive type is encoded. Any extensions on the primitive type are not encoded. 073 * If any other object is passed in, a fragment is encoded. The format of the fragment depends on the encoding: 074 * <ul> 075 * <li><b>JSON</b>: The fragment is output as a simple JSON object, exactly as it would appear within an encoded resource.</li> 076 * <li><b>XML</b>: The fragment is output as an XML element as it would appear within an encoded resource, however it is wrapped in an element called <code><element></code> in order to avoid producing a document with multiple root tags.</li> 077 * <li><b>RDF/Turtle</b>: This mode is not supported and will throw an {@link ca.uhn.fhir.rest.server.exceptions.InternalErrorException}</li> 078 * </ul> 079 * 080 * @since 6.8.0 081 */ 082 String encodeToString(IBase theElement) throws DataFormatException; 083 084 /** 085 * Encodes any FHIR element to a writer. 086 * If a {@link IBaseResource resource object} is passed in, the resource will be encoded using standard FHIR 087 * encoding rules. If a {@link org.hl7.fhir.instance.model.api.IPrimitiveType primitive datatype} is passed in, 088 * the string value of the primitive type is encoded. Any extensions on the primitive type are not encoded. 089 * If any other object is passed in, a fragment is encoded. The format of the fragment depends on the encoding: 090 * <ul> 091 * <li><b>JSON</b>: The fragment is output as a simple JSON object, exactly as it would appear within an encoded resource.</li> 092 * <li><b>XML</b>: The fragment is output as an XML element as it would appear within an encoded resource, however it is wrapped in an element called <code><element></code> in order to avoid producing a document with multiple root tags.</li> 093 * <li><b>RDF/Turtle</b>: This mode is not supported and will throw an {@link ca.uhn.fhir.rest.server.exceptions.InternalErrorException}</li> 094 * </ul> 095 * 096 * @since 6.8.0 097 */ 098 void encodeToWriter(IBase theElement, Writer theWriter) throws DataFormatException, IOException; 099 100 /** 101 * If not set to null (as is the default) this ID will be used as the ID in any 102 * resources encoded by this parser 103 */ 104 IIdType getEncodeForceResourceId(); 105 106 /** 107 * When encoding, force this resource ID to be encoded as the resource ID 108 */ 109 IParser setEncodeForceResourceId(IIdType theForceResourceId); 110 111 /** 112 * Which encoding does this parser instance produce? 113 */ 114 EncodingEnum getEncoding(); 115 116 /** 117 * Gets the preferred types, as set using {@link #setPreferTypes(List)} 118 * 119 * @return Returns the preferred types, or <code>null</code> 120 * @see #setPreferTypes(List) 121 */ 122 List<Class<? extends IBaseResource>> getPreferTypes(); 123 124 /** 125 * If set, when parsing resources the parser will try to use the given types when possible, in 126 * the order that they are provided (from highest to lowest priority). For example, if a custom 127 * type which declares to implement the Patient resource is passed in here, and the 128 * parser is parsing a Bundle containing a Patient resource, the parser will use the given 129 * custom type. 130 * <p> 131 * This feature is related to, but not the same as the 132 * {@link FhirContext#setDefaultTypeForProfile(String, Class)} feature. 133 * <code>setDefaultTypeForProfile</code> is used to specify a type to be used 134 * when a resource explicitly declares support for a given profile. This 135 * feature specifies a type to be used irrespective of the profile declaration 136 * in the metadata statement. 137 * </p> 138 * 139 * @param thePreferTypes The preferred types, or <code>null</code> 140 */ 141 void setPreferTypes(List<Class<? extends IBaseResource>> thePreferTypes); 142 143 /** 144 * Returns true if resource IDs should be omitted 145 * 146 * @see #setOmitResourceId(boolean) 147 * @since 1.1 148 */ 149 boolean isOmitResourceId(); 150 151 /** 152 * If set to <code>true</code> (default is <code>false</code>) the ID of any resources being encoded will not be 153 * included in the output. Note that this does not apply to contained resources, only to root resources. In other 154 * words, if this is set to <code>true</code>, contained resources will still have local IDs but the outer/containing 155 * ID will not have an ID. 156 * <p> 157 * If the resource being encoded is a Bundle or Parameters resource, this setting only applies to the 158 * outer resource being encoded, not any resources contained wihthin. 159 * </p> 160 * 161 * @param theOmitResourceId Should resource IDs be omitted 162 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together 163 * @since 1.1 164 */ 165 IParser setOmitResourceId(boolean theOmitResourceId); 166 167 /** 168 * If set to <code>true<code> (which is the default), resource references containing a version 169 * will have the version removed when the resource is encoded. This is generally good behaviour because 170 * in most situations, references from one resource to another should be to the resource by ID, not 171 * by ID and version. In some cases though, it may be desirable to preserve the version in resource 172 * links. In that case, this value should be set to <code>false</code>. 173 * 174 * @return Returns the parser instance's configuration setting for stripping versions from resource references when 175 * encoding. This method will retun <code>null</code> if no value is set, in which case 176 * the value from the {@link ParserOptions} will be used (default is <code>true</code>) 177 * @see ParserOptions 178 */ 179 Boolean getStripVersionsFromReferences(); 180 181 /** 182 * If set to <code>true<code> (which is the default), resource references containing a version 183 * will have the version removed when the resource is encoded. This is generally good behaviour because 184 * in most situations, references from one resource to another should be to the resource by ID, not 185 * by ID and version. In some cases though, it may be desirable to preserve the version in resource 186 * links. In that case, this value should be set to <code>false</code>. 187 * <p> 188 * This method provides the ability to globally disable reference encoding. If finer-grained 189 * control is needed, use {@link #setDontStripVersionsFromReferencesAtPaths(String...)} 190 * </p> 191 * 192 * @param theStripVersionsFromReferences Set this to <code>false<code> to prevent the parser from removing resource versions from references (or <code>null</code> to apply the default setting from the {@link ParserOptions} 193 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together 194 * @see #setDontStripVersionsFromReferencesAtPaths(String...) 195 * @see ParserOptions 196 */ 197 IParser setStripVersionsFromReferences(Boolean theStripVersionsFromReferences); 198 199 /** 200 * Is the parser in "summary mode"? See {@link #setSummaryMode(boolean)} for information 201 * 202 * @see {@link #setSummaryMode(boolean)} for information 203 */ 204 boolean isSummaryMode(); 205 206 /** 207 * If set to <code>true</code> (default is <code>false</code>) only elements marked by the FHIR specification as 208 * being "summary elements" will be included. 209 * 210 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together 211 */ 212 IParser setSummaryMode(boolean theSummaryMode); 213 214 /** 215 * Parses a resource 216 * 217 * @param theResourceType The resource type to use. This can be used to explicitly specify a class which extends a built-in type 218 * (e.g. a custom type extending the default Patient class) 219 * @param theReader The reader to parse input from. Note that the Reader will not be closed by the parser upon completion. 220 * @return A parsed resource 221 * @throws DataFormatException If the resource can not be parsed because the data is not recognized or invalid for any reason 222 */ 223 <T extends IBaseResource> T parseResource(Class<T> theResourceType, Reader theReader) throws DataFormatException; 224 225 /** 226 * Parses a resource 227 * 228 * @param theResourceType The resource type to use. This can be used to explicitly specify a class which extends a built-in type 229 * (e.g. a custom type extending the default Patient class) 230 * @param theInputStream The InputStream to parse input from, <b>with an implied charset of UTF-8</b>. Note that the InputStream will not be closed by the parser upon completion. 231 * @return A parsed resource 232 * @throws DataFormatException If the resource can not be parsed because the data is not recognized or invalid for any reason 233 */ 234 <T extends IBaseResource> T parseResource(Class<T> theResourceType, InputStream theInputStream) 235 throws DataFormatException; 236 237 /** 238 * Parses a resource 239 * 240 * @param theResourceType The resource type to use. This can be used to explicitly specify a class which extends a built-in type 241 * (e.g. a custom type extending the default Patient class) 242 * @param theString The string to parse 243 * @return A parsed resource 244 * @throws DataFormatException If the resource can not be parsed because the data is not recognized or invalid for any reason 245 */ 246 <T extends IBaseResource> T parseResource(Class<T> theResourceType, String theString) throws DataFormatException; 247 248 /** 249 * Parses a resource 250 * 251 * @param theReader The reader to parse input from. Note that the Reader will not be closed by the parser upon completion. 252 * @return A parsed resource. Note that the returned object will be an instance of {@link IResource} or 253 * {@link IAnyResource} depending on the specific FhirContext which created this parser. 254 * @throws DataFormatException If the resource can not be parsed because the data is not recognized or invalid for any reason 255 */ 256 IBaseResource parseResource(Reader theReader) throws ConfigurationException, DataFormatException; 257 258 /** 259 * Parses a resource 260 * 261 * @param theInputStream The InputStream to parse input from (charset is assumed to be UTF-8). 262 * Note that the stream will not be closed by the parser upon completion. 263 * @return A parsed resource. Note that the returned object will be an instance of {@link IResource} or 264 * {@link IAnyResource} depending on the specific FhirContext which created this parser. 265 * @throws DataFormatException If the resource can not be parsed because the data is not recognized or invalid for any reason 266 */ 267 IBaseResource parseResource(InputStream theInputStream) throws ConfigurationException, DataFormatException; 268 269 /** 270 * Parses a resource 271 * 272 * @param theMessageString The string to parse 273 * @return A parsed resource. Note that the returned object will be an instance of {@link IResource} or 274 * {@link IAnyResource} depending on the specific FhirContext which created this parser. 275 * @throws DataFormatException If the resource can not be parsed because the data is not recognized or invalid for any reason 276 */ 277 IBaseResource parseResource(String theMessageString) throws ConfigurationException, DataFormatException; 278 279 /** 280 * If provided, specifies the elements which should NOT be encoded. Valid values for this 281 * field would include: 282 * <ul> 283 * <li><b>Patient</b> - Don't encode patient and all its children</li> 284 * <li><b>Patient.name</b> - Don't encode the patient's name</li> 285 * <li><b>Patient.name.family</b> - Don't encode the patient's family name</li> 286 * <li><b>*.text</b> - Don't encode the text element on any resource (only the very first position may contain a 287 * wildcard)</li> 288 * </ul> 289 * <p> 290 * DSTU2 note: Note that values including meta, such as <code>Patient.meta</code> 291 * will work for DSTU2 parsers, but values with subelements on meta such 292 * as <code>Patient.meta.lastUpdated</code> will only work in 293 * DSTU3+ mode. 294 * </p> 295 * 296 * @param theDontEncodeElements The elements to encode 297 * @see #setEncodeElements(Set) 298 */ 299 IParser setDontEncodeElements(Collection<String> theDontEncodeElements); 300 301 /** 302 * If provided, specifies the elements which should be encoded, to the exclusion of all others. Valid values for this 303 * field would include: 304 * <ul> 305 * <li><b>Patient</b> - Encode patient and all its children</li> 306 * <li><b>Patient.name</b> - Encode only the patient's name</li> 307 * <li><b>Patient.name.family</b> - Encode only the patient's family name</li> 308 * <li><b>*.text</b> - Encode the text element on any resource (only the very first position may contain a 309 * wildcard)</li> 310 * <li><b>*.(mandatory)</b> - This is a special case which causes any mandatory fields (min > 0) to be encoded</li> 311 * </ul> 312 * 313 * @param theEncodeElements The elements to encode 314 * @see #setDontEncodeElements(Collection) 315 */ 316 IParser setEncodeElements(Set<String> theEncodeElements); 317 318 /** 319 * If set to <code>true</code> (default is false), the values supplied 320 * to {@link #setEncodeElements(Set)} will not be applied to the root 321 * resource (typically a Bundle), but will be applied to any sub-resources 322 * contained within it (i.e. search result resources in that bundle) 323 */ 324 boolean isEncodeElementsAppliesToChildResourcesOnly(); 325 326 /** 327 * If set to <code>true</code> (default is false), the values supplied 328 * to {@link #setEncodeElements(Set)} will not be applied to the root 329 * resource (typically a Bundle), but will be applied to any sub-resources 330 * contained within it (i.e. search result resources in that bundle) 331 */ 332 void setEncodeElementsAppliesToChildResourcesOnly(boolean theEncodeElementsAppliesToChildResourcesOnly); 333 334 /** 335 * Registers an error handler which will be invoked when any parse errors are found 336 * 337 * @param theErrorHandler The error handler to set. Must not be null. 338 */ 339 IParser setParserErrorHandler(IParserErrorHandler theErrorHandler); 340 341 /** 342 * Sets the "pretty print" flag, meaning that the parser will encode resources with human-readable spacing and 343 * newlines between elements instead of condensing output as much as possible. 344 * 345 * @param thePrettyPrint The flag 346 * @return Returns an instance of <code>this</code> parser so that method calls can be chained together 347 */ 348 IParser setPrettyPrint(boolean thePrettyPrint); 349 350 /** 351 * Sets the server's base URL used by this parser. If a value is set, resource references will be turned into 352 * relative references if they are provided as absolute URLs but have a base matching the given base. 353 * 354 * @param theUrl The base URL, e.g. "http://example.com/base" 355 * @return Returns an instance of <code>this</code> parser so that method calls can be chained together 356 */ 357 IParser setServerBaseUrl(String theUrl); 358 359 /** 360 * If set to <code>true</code> (which is the default), the Bundle.entry.fullUrl will override the Bundle.entry.resource's 361 * resource id if the fullUrl is defined. This behavior happens when parsing the source data into a Bundle object. Set this 362 * to <code>false</code> if this is not the desired behavior (e.g. the client code wishes to perform additional 363 * validation checks between the fullUrl and the resource id). 364 * 365 * @param theOverrideResourceIdWithBundleEntryFullUrl Set this to <code>false</code> to prevent the parser from overriding resource ids with the 366 * Bundle.entry.fullUrl (or <code>null</code> to apply the default setting from the {@link ParserOptions}) 367 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together 368 * @see ParserOptions 369 */ 370 IParser setOverrideResourceIdWithBundleEntryFullUrl(Boolean theOverrideResourceIdWithBundleEntryFullUrl); 371 372 /** 373 * If set to <code>true</code> (default is <code>false</code>), narratives will not be included in the encoded 374 * values. 375 */ 376 IParser setSuppressNarratives(boolean theSuppressNarratives); 377 378 /** 379 * Returns the value supplied to {@link IParser#setDontStripVersionsFromReferencesAtPaths(String...)} 380 * or <code>null</code> if no value has been set for this parser (in which case the default from 381 * the {@link ParserOptions} will be used} 382 * 383 * @see #setDontStripVersionsFromReferencesAtPaths(String...) 384 * @see #setStripVersionsFromReferences(Boolean) 385 * @see ParserOptions 386 */ 387 Set<String> getDontStripVersionsFromReferencesAtPaths(); 388 389 /** 390 * If supplied value(s), any resource references at the specified paths will have their 391 * resource versions encoded instead of being automatically stripped during the encoding 392 * process. This setting has no effect on the parsing process. 393 * <p> 394 * This method provides a finer-grained level of control than {@link #setStripVersionsFromReferences(Boolean)} 395 * and any paths specified by this method will be encoded even if {@link #setStripVersionsFromReferences(Boolean)} 396 * has been set to <code>true</code> (which is the default) 397 * </p> 398 * 399 * @param thePaths A collection of paths for which the resource versions will not be removed automatically 400 * when serializing, e.g. "Patient.managingOrganization" or "AuditEvent.object.reference". Note that 401 * only resource name and field names with dots separating is allowed here (no repetition 402 * indicators, FluentPath expressions, etc.). Set to <code>null</code> to use the value 403 * set in the {@link ParserOptions} 404 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together 405 * @see #setStripVersionsFromReferences(Boolean) 406 * @see ParserOptions 407 */ 408 IParser setDontStripVersionsFromReferencesAtPaths(String... thePaths); 409 410 /** 411 * If supplied value(s), any resource references at the specified paths will have their 412 * resource versions encoded instead of being automatically stripped during the encoding 413 * process. This setting has no effect on the parsing process. 414 * <p> 415 * This method provides a finer-grained level of control than {@link #setStripVersionsFromReferences(Boolean)} 416 * and any paths specified by this method will be encoded even if {@link #setStripVersionsFromReferences(Boolean)} 417 * has been set to <code>true</code> (which is the default) 418 * </p> 419 * 420 * @param thePaths A collection of paths for which the resource versions will not be removed automatically 421 * when serializing, e.g. "Patient.managingOrganization" or "AuditEvent.object.reference". Note that 422 * only resource name and field names with dots separating is allowed here (no repetition 423 * indicators, FluentPath expressions, etc.). Set to <code>null</code> to use the value 424 * set in the {@link ParserOptions} 425 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together 426 * @see #setStripVersionsFromReferences(Boolean) 427 * @see ParserOptions 428 */ 429 IParser setDontStripVersionsFromReferencesAtPaths(Collection<String> thePaths); 430}