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