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