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