001package ca.uhn.fhir.parser;
002
003/*
004 * #%L
005 * HAPI FHIR - Core Library
006 * %%
007 * Copyright (C) 2014 - 2019 University Health Network
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         * Which encoding does this parser instance produce?
062         */
063        EncodingEnum getEncoding();
064
065        /**
066         * Gets the preferred types, as set using {@link #setPreferTypes(List)}
067         * 
068         * @return Returns the preferred types, or <code>null</code>
069         * @see #setPreferTypes(List)
070         */
071        List<Class<? extends IBaseResource>> getPreferTypes();
072
073        /**
074         * Returns true if resource IDs should be omitted
075         * 
076         * @see #setOmitResourceId(boolean)
077         * @since 1.1
078         */
079        boolean isOmitResourceId();
080
081        /**
082         * If set to <code>true<code> (which is the default), resource references containing a version
083         * will have the version removed when the resource is encoded. This is generally good behaviour because
084         * in most situations, references from one resource to another should be to the resource by ID, not
085         * by ID and version. In some cases though, it may be desirable to preserve the version in resource
086         * links. In that case, this value should be set to <code>false</code>.
087         * 
088         * @return Returns the parser instance's configuration setting for stripping versions from resource references when
089         *         encoding. This method will retun <code>null</code> if no value is set, in which case
090         *         the value from the {@link ParserOptions} will be used (default is <code>true</code>)
091         * @see ParserOptions
092         */
093        Boolean getStripVersionsFromReferences();
094
095        /**
096         * If set to <code>true</code> (which is the default), the Bundle.entry.fullUrl will override the Bundle.entry.resource's
097         * resource id if the fullUrl is defined. This behavior happens when parsing the source data into a Bundle object. Set this
098         * to <code>false</code> if this is not the desired behavior (e.g. the client code wishes to perform additional
099         * 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        IParser 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        IParser 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}