View Javadoc
1   package ca.uhn.fhir.parser;
2   
3   /*
4    * #%L
5    * HAPI FHIR - Core Library
6    * %%
7    * Copyright (C) 2014 - 2019 University Health Network
8    * %%
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   * 
13   * http://www.apache.org/licenses/LICENSE-2.0
14   * 
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * #L%
21   */
22  
23  import ca.uhn.fhir.context.ConfigurationException;
24  import ca.uhn.fhir.context.FhirContext;
25  import ca.uhn.fhir.context.ParserOptions;
26  import ca.uhn.fhir.model.api.IResource;
27  import ca.uhn.fhir.rest.api.EncodingEnum;
28  import org.hl7.fhir.instance.model.api.IAnyResource;
29  import org.hl7.fhir.instance.model.api.IBaseResource;
30  import org.hl7.fhir.instance.model.api.IIdType;
31  
32  import java.io.IOException;
33  import java.io.InputStream;
34  import java.io.Reader;
35  import java.io.Writer;
36  import java.util.Collection;
37  import java.util.List;
38  import java.util.Set;
39  
40  /**
41   * A parser, which can be used to convert between HAPI FHIR model/structure objects, and their respective String wire
42   * formats, in either XML or JSON.
43   * <p>
44   * Thread safety: <b>Parsers are not guaranteed to be thread safe</b>. Create a new parser instance for every thread or
45   * every message being parsed/encoded.
46   * </p>
47   */
48  public interface IParser {
49  
50  	String encodeResourceToString(IBaseResource theResource) throws DataFormatException;
51  
52  	void encodeResourceToWriter(IBaseResource theResource, Writer theWriter) throws IOException, DataFormatException;
53  
54  	/**
55  	 * If not set to null (as is the default) this ID will be used as the ID in any
56  	 * resources encoded by this parser
57  	 */
58  	IIdType getEncodeForceResourceId();
59  
60  	/**
61  	 * Which encoding does this parser instance produce?
62  	 */
63  	EncodingEnum getEncoding();
64  
65  	/**
66  	 * Gets the preferred types, as set using {@link #setPreferTypes(List)}
67  	 * 
68  	 * @return Returns the preferred types, or <code>null</code>
69  	 * @see #setPreferTypes(List)
70  	 */
71  	List<Class<? extends IBaseResource>> getPreferTypes();
72  
73  	/**
74  	 * Returns true if resource IDs should be omitted
75  	 * 
76  	 * @see #setOmitResourceId(boolean)
77  	 * @since 1.1
78  	 */
79  	boolean isOmitResourceId();
80  
81  	/**
82  	 * If set to <code>true<code> (which is the default), resource references containing a version
83  	 * will have the version removed when the resource is encoded. This is generally good behaviour because
84  	 * in most situations, references from one resource to another should be to the resource by ID, not
85  	 * by ID and version. In some cases though, it may be desirable to preserve the version in resource
86  	 * links. In that case, this value should be set to <code>false</code>.
87  	 * 
88  	 * @return Returns the parser instance's configuration setting for stripping versions from resource references when
89  	 *         encoding. This method will retun <code>null</code> if no value is set, in which case
90  	 *         the value from the {@link ParserOptions} will be used (default is <code>true</code>)
91  	 * @see ParserOptions
92  	 */
93  	Boolean getStripVersionsFromReferences();
94  
95  	/**
96  	 * If set to <code>true</code> (which is the default), the Bundle.entry.fullUrl will override the Bundle.entry.resource's
97  	 * resource id if the fullUrl is defined. This behavior happens when parsing the source data into a Bundle object. Set this
98  	 * to <code>false</code> if this is not the desired behavior (e.g. the client code wishes to perform additional
99  	 * validation checks between the fullUrl and the resource id).
100 	 *
101 	 * @return Returns the parser instance's configuration setting for overriding resource ids with Bundle.entry.fullUrl when
102 	 *         parsing the source data into a Bundle object. This method will return <code>null</code> if no value is set, in
103 	 *         which case the value from the {@link ParserOptions} will be used (default is <code>true</code>)
104 	 * @see ParserOptions
105 	 */
106 	Boolean getOverrideResourceIdWithBundleEntryFullUrl();
107 
108 	/**
109 	 * Is the parser in "summary mode"? See {@link #setSummaryMode(boolean)} for information
110 	 * 
111 	 * @see {@link #setSummaryMode(boolean)} for information
112 	 */
113 	boolean isSummaryMode();
114 
115 	/**
116 	 * Parses a resource
117 	 * 
118 	 * @param theResourceType
119 	 *           The resource type to use. This can be used to explicitly specify a class which extends a built-in type
120 	 *           (e.g. a custom type extending the default Patient class)
121 	 * @param theReader
122 	 *           The reader to parse input from. Note that the Reader will not be closed by the parser upon completion.
123 	 * @return A parsed resource
124 	 * @throws DataFormatException
125 	 *            If the resource can not be parsed because the data is not recognized or invalid for any reason
126 	 */
127 	<T extends IBaseResource> T parseResource(Class<T> theResourceType, Reader theReader) throws DataFormatException;
128 
129 	/**
130 	 * Parses a resource
131 	 *
132 	 * @param theResourceType
133 	 *           The resource type to use. This can be used to explicitly specify a class which extends a built-in type
134 	 *           (e.g. a custom type extending the default Patient class)
135 	 * @param theInputStream
136 	 *           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.
137 	 * @return A parsed resource
138 	 * @throws DataFormatException
139 	 *            If the resource can not be parsed because the data is not recognized or invalid for any reason
140 	 */
141 	<T extends IBaseResource> T parseResource(Class<T> theResourceType, InputStream theInputStream) throws DataFormatException;
142 
143 	/**
144 	 * Parses a resource
145 	 * 
146 	 * @param theResourceType
147 	 *           The resource type to use. This can be used to explicitly specify a class which extends a built-in type
148 	 *           (e.g. a custom type extending the default Patient class)
149 	 * @param theString
150 	 *           The string to parse
151 	 * @return A parsed resource
152 	 * @throws DataFormatException
153 	 *            If the resource can not be parsed because the data is not recognized or invalid for any reason
154 	 */
155 	<T extends IBaseResource> T parseResource(Class<T> theResourceType, String theString) throws DataFormatException;
156 
157 	/**
158 	 * Parses a resource
159 	 * 
160 	 * @param theReader
161 	 *           The reader to parse input from. Note that the Reader will not be closed by the parser upon completion.
162 	 * @return A parsed resource. Note that the returned object will be an instance of {@link IResource} or
163 	 *         {@link IAnyResource} depending on the specific FhirContext which created this parser.
164 	 * @throws DataFormatException
165 	 *            If the resource can not be parsed because the data is not recognized or invalid for any reason
166 	 */
167 	IBaseResource parseResource(Reader theReader) throws ConfigurationException, DataFormatException;
168 
169 	/**
170 	 * Parses a resource
171 	 *
172 	 * @param theInputStream
173 	 *           The InputStream to parse input from (charset is assumed to be UTF-8).
174 	 *           Note that the stream will not be closed by the parser upon completion.
175 	 * @return A parsed resource. Note that the returned object will be an instance of {@link IResource} or
176 	 *         {@link IAnyResource} depending on the specific FhirContext which created this parser.
177 	 * @throws DataFormatException
178 	 *            If the resource can not be parsed because the data is not recognized or invalid for any reason
179 	 */
180 	IBaseResource parseResource(InputStream theInputStream) throws ConfigurationException, DataFormatException;
181 
182 	/**
183 	 * Parses a resource
184 	 * 
185 	 * @param theMessageString
186 	 *           The string to parse
187 	 * @return A parsed resource. Note that the returned object will be an instance of {@link IResource} or
188 	 *         {@link IAnyResource} depending on the specific FhirContext which created this parser.
189 	 * @throws DataFormatException
190 	 *            If the resource can not be parsed because the data is not recognized or invalid for any reason
191 	 */
192 	IBaseResource parseResource(String theMessageString) throws ConfigurationException, DataFormatException;
193 
194 	/**
195 	 * If provided, specifies the elements which should NOT be encoded. Valid values for this
196 	 * field would include:
197 	 * <ul>
198 	 * <li><b>Patient</b> - Don't encode patient and all its children</li>
199 	 * <li><b>Patient.name</b> - Don't encode the patient's name</li>
200 	 * <li><b>Patient.name.family</b> - Don't encode the patient's family name</li>
201 	 * <li><b>*.text</b> - Don't encode the text element on any resource (only the very first position may contain a
202 	 * wildcard)</li>
203 	 * </ul>
204 	 * <p>
205 	 * DSTU2 note: Note that values including meta, such as <code>Patient.meta</code>
206 	 * will work for DSTU2 parsers, but values with subelements on meta such
207 	 * as <code>Patient.meta.lastUpdated</code> will only work in
208 	 * DSTU3+ mode.
209 	 * </p>
210 	 * 
211 	 * @param theDontEncodeElements
212 	 *           The elements to encode
213 	 * @see #setEncodeElements(Set)
214 	 */
215 	void setDontEncodeElements(Set<String> theDontEncodeElements);
216 
217 	/**
218 	 * If provided, specifies the elements which should be encoded, to the exclusion of all others. Valid values for this
219 	 * field would include:
220 	 * <ul>
221 	 * <li><b>Patient</b> - Encode patient and all its children</li>
222 	 * <li><b>Patient.name</b> - Encode only the patient's name</li>
223 	 * <li><b>Patient.name.family</b> - Encode only the patient's family name</li>
224 	 * <li><b>*.text</b> - Encode the text element on any resource (only the very first position may contain a
225 	 * wildcard)</li>
226 	 * <li><b>*.(mandatory)</b> - This is a special case which causes any mandatory fields (min > 0) to be encoded</li>
227 	 * </ul>
228 	 * 
229 	 * @param theEncodeElements
230 	 *           The elements to encode
231 	 * @see #setDontEncodeElements(Set)
232 	 */
233 	void setEncodeElements(Set<String> theEncodeElements);
234 
235 	/**
236 	 * If set to <code>true</code> (default is false), the values supplied
237 	 * to {@link #setEncodeElements(Set)} will not be applied to the root
238 	 * resource (typically a Bundle), but will be applied to any sub-resources
239 	 * contained within it (i.e. search result resources in that bundle)
240 	 */
241 	void setEncodeElementsAppliesToChildResourcesOnly(boolean theEncodeElementsAppliesToChildResourcesOnly);
242 
243 	/**
244 	 * If set to <code>true</code> (default is false), the values supplied
245 	 * to {@link #setEncodeElements(Set)} will not be applied to the root
246 	 * resource (typically a Bundle), but will be applied to any sub-resources
247 	 * contained within it (i.e. search result resources in that bundle)
248 	 */
249 	boolean isEncodeElementsAppliesToChildResourcesOnly();
250 
251 	/**
252 	 * When encoding, force this resource ID to be encoded as the resource ID
253 	 */
254 	IParser setEncodeForceResourceId(IIdType theForceResourceId);
255 
256 	/**
257 	 * If set to <code>true</code> (default is <code>false</code>) the ID of any resources being encoded will not be
258 	 * included in the output. Note that this does not apply to contained resources, only to root resources. In other
259 	 * words, if this is set to <code>true</code>, contained resources will still have local IDs but the outer/containing
260 	 * ID will not have an ID.
261 	 * 
262 	 * @param theOmitResourceId
263 	 *           Should resource IDs be omitted
264 	 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together
265 	 * @since 1.1
266 	 */
267 	IParser setOmitResourceId(boolean theOmitResourceId);
268 
269 	/**
270 	 * Registers an error handler which will be invoked when any parse errors are found
271 	 * 
272 	 * @param theErrorHandler
273 	 *           The error handler to set. Must not be null.
274 	 */
275 	IParser setParserErrorHandler(IParserErrorHandler theErrorHandler);
276 
277 	/**
278 	 * If set, when parsing resources the parser will try to use the given types when possible, in
279 	 * the order that they are provided (from highest to lowest priority). For example, if a custom
280 	 * type which declares to implement the Patient resource is passed in here, and the
281 	 * parser is parsing a Bundle containing a Patient resource, the parser will use the given
282 	 * custom type.
283 	 * <p>
284 	 * This feature is related to, but not the same as the
285 	 * {@link FhirContext#setDefaultTypeForProfile(String, Class)} feature.
286 	 * <code>setDefaultTypeForProfile</code> is used to specify a type to be used
287 	 * when a resource explicitly declares support for a given profile. This
288 	 * feature specifies a type to be used irrespective of the profile declaration
289 	 * in the metadata statement.
290 	 * </p>
291 	 * 
292 	 * @param thePreferTypes
293 	 *           The preferred types, or <code>null</code>
294 	 */
295 	void setPreferTypes(List<Class<? extends IBaseResource>> thePreferTypes);
296 
297 	/**
298 	 * Sets the "pretty print" flag, meaning that the parser will encode resources with human-readable spacing and
299 	 * newlines between elements instead of condensing output as much as possible.
300 	 * 
301 	 * @param thePrettyPrint
302 	 *           The flag
303 	 * @return Returns an instance of <code>this</code> parser so that method calls can be chained together
304 	 */
305 	IParser setPrettyPrint(boolean thePrettyPrint);
306 
307 	/**
308 	 * Sets the server's base URL used by this parser. If a value is set, resource references will be turned into
309 	 * relative references if they are provided as absolute URLs but have a base matching the given base.
310 	 * 
311 	 * @param theUrl
312 	 *           The base URL, e.g. "http://example.com/base"
313 	 * @return Returns an instance of <code>this</code> parser so that method calls can be chained together
314 	 */
315 	IParser setServerBaseUrl(String theUrl);
316 
317 	/**
318 	 * If set to <code>true<code> (which is the default), resource references containing a version
319 	 * will have the version removed when the resource is encoded. This is generally good behaviour because
320 	 * in most situations, references from one resource to another should be to the resource by ID, not
321 	 * by ID and version. In some cases though, it may be desirable to preserve the version in resource
322 	 * links. In that case, this value should be set to <code>false</code>.
323 	 * <p>
324 	 * This method provides the ability to globally disable reference encoding. If finer-grained
325 	 * control is needed, use {@link #setDontStripVersionsFromReferencesAtPaths(String...)}
326 	 * </p>
327 	 * 
328 	 * @param theStripVersionsFromReferences
329 	 *           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}
330 	 * @see #setDontStripVersionsFromReferencesAtPaths(String...)
331 	 * @see ParserOptions
332 	 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together
333 	 */
334 	IParser setStripVersionsFromReferences(Boolean theStripVersionsFromReferences);
335 
336 	/**
337 	 * If set to <code>true</code> (which is the default), the Bundle.entry.fullUrl will override the Bundle.entry.resource's
338 	 * resource id if the fullUrl is defined. This behavior happens when parsing the source data into a Bundle object. Set this
339 	 * to <code>false</code> if this is not the desired behavior (e.g. the client code wishes to perform additional
340 	 * validation checks between the fullUrl and the resource id).
341 	 *
342 	 * @param theOverrideResourceIdWithBundleEntryFullUrl
343 	 *           Set this to <code>false</code> to prevent the parser from overriding resource ids with the
344 	 *           Bundle.entry.fullUrl (or <code>null</code> to apply the default setting from the {@link ParserOptions})
345 	 *
346 	 * @see ParserOptions
347 	 *
348 	 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together
349 	 */
350 	IParser setOverrideResourceIdWithBundleEntryFullUrl(Boolean theOverrideResourceIdWithBundleEntryFullUrl);
351 
352 	/**
353 	 * If set to <code>true</code> (default is <code>false</code>) only elements marked by the FHIR specification as
354 	 * being "summary elements" will be included.
355 	 * 
356 	 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together
357 	 */
358 	IParser setSummaryMode(boolean theSummaryMode);
359 
360 	/**
361 	 * If set to <code>true</code> (default is <code>false</code>), narratives will not be included in the encoded
362 	 * values.
363 	 */
364 	IParser setSuppressNarratives(boolean theSuppressNarratives);
365 
366 	/**
367 	 * If supplied value(s), any resource references at the specified paths will have their
368 	 * resource versions encoded instead of being automatically stripped during the encoding
369 	 * process. This setting has no effect on the parsing process.
370 	 * <p>
371 	 * This method provides a finer-grained level of control than {@link #setStripVersionsFromReferences(Boolean)}
372 	 * and any paths specified by this method will be encoded even if {@link #setStripVersionsFromReferences(Boolean)}
373 	 * has been set to <code>true</code> (which is the default)
374 	 * </p>
375 	 *
376 	 * @param thePaths
377 	 *           A collection of paths for which the resource versions will not be removed automatically
378 	 *           when serializing, e.g. "Patient.managingOrganization" or "AuditEvent.object.reference". Note that
379 	 *           only resource name and field names with dots separating is allowed here (no repetition
380 	 *           indicators, FluentPath expressions, etc.). Set to <code>null</code> to use the value
381 	 *           set in the {@link ParserOptions}
382 	 * @see #setStripVersionsFromReferences(Boolean)
383 	 * @see ParserOptions
384 	 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together
385 	 */
386 	IParser setDontStripVersionsFromReferencesAtPaths(String... thePaths);
387 
388 	/**
389 	 * If supplied value(s), any resource references at the specified paths will have their
390 	 * resource versions encoded instead of being automatically stripped during the encoding
391 	 * process. This setting has no effect on the parsing process.
392 	 * <p>
393 	 * This method provides a finer-grained level of control than {@link #setStripVersionsFromReferences(Boolean)}
394 	 * and any paths specified by this method will be encoded even if {@link #setStripVersionsFromReferences(Boolean)}
395 	 * has been set to <code>true</code> (which is the default)
396 	 * </p>
397 	 *
398 	 * @param thePaths
399 	 *           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 	 * @see #setStripVersionsFromReferences(Boolean)
405 	 * @see ParserOptions
406 	 * @return Returns a reference to <code>this</code> parser so that method calls can be chained together
407 	 */
408 	IParser setDontStripVersionsFromReferencesAtPaths(Collection<String> thePaths);
409 
410 	/**
411 	 * Returns the value supplied to {@link IParser#setDontStripVersionsFromReferencesAtPaths(String...)}
412 	 * or <code>null</code> if no value has been set for this parser (in which case the default from
413 	 * the {@link ParserOptions} will be used}
414 	 * 
415 	 * @see #setDontStripVersionsFromReferencesAtPaths(String...)
416 	 * @see #setStripVersionsFromReferences(Boolean)
417 	 * @see ParserOptions
418 	 */
419 	Set<String> getDontStripVersionsFromReferencesAtPaths();
420 
421 }