001package ca.uhn.fhir.parser;
002
003/*
004 * #%L
005 * HAPI FHIR - Core Library
006 * %%
007 * Copyright (C) 2014 - 2021 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}