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