001package ca.uhn.fhir.parser;
002
003/*
004 * #%L
005 * HAPI FHIR - Core Library
006 * %%
007 * Copyright (C) 2014 - 2016 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.Set;
027
028import org.hl7.fhir.instance.model.api.IAnyResource;
029import org.hl7.fhir.instance.model.api.IBaseResource;
030
031import ca.uhn.fhir.context.ConfigurationException;
032import ca.uhn.fhir.model.api.Bundle;
033import ca.uhn.fhir.model.api.IResource;
034import ca.uhn.fhir.model.api.TagList;
035import ca.uhn.fhir.rest.server.EncodingEnum;
036
037/**
038 * A parser, which can be used to convert between HAPI FHIR model/structure objects, and their respective String wire
039 * formats, in either XML or JSON.
040 * <p>
041 * Thread safety: <b>Parsers are not guaranteed to be thread safe</b>. Create a new parser instance for every thread or
042 * every message being parsed/encoded.
043 * </p>
044 */
045public interface IParser {
046
047        String encodeBundleToString(Bundle theBundle) throws DataFormatException;
048
049        void encodeBundleToWriter(Bundle theBundle, Writer theWriter) throws IOException, DataFormatException;
050
051        String encodeResourceToString(IBaseResource theResource) throws DataFormatException;
052
053        void encodeResourceToWriter(IBaseResource theResource, Writer theWriter) throws IOException, DataFormatException;
054
055        /**
056         * Encodes a tag list, as defined in the <a href="http://hl7.org/implement/standards/fhir/http.html#tags">FHIR
057         * Specification</a>.
058         * 
059         * @param theTagList
060         *           The tag list to encode. Must not be null.
061         * @return An encoded tag list
062         */
063        String encodeTagListToString(TagList theTagList);
064
065        /**
066         * Encodes a tag list, as defined in the <a href="http://hl7.org/implement/standards/fhir/http.html#tags">FHIR
067         * Specification</a>.
068         * 
069         * @param theTagList
070         *           The tag list to encode. Must not be null.
071         * @param theWriter
072         *           The writer to encode to
073         */
074        void encodeTagListToWriter(TagList theTagList, Writer theWriter) throws IOException;
075
076        /**
077         * See {@link #setEncodeElements(Set)}
078         */
079        Set<String> getEncodeElements();
080
081        /**
082         * See {@link #setEncodeElementsAppliesToResourceTypes(Set)}
083         */
084        Set<String> getEncodeElementsAppliesToResourceTypes();
085
086        /**
087         * Returns true if resource IDs should be omitted
088         * 
089         * @see #setOmitResourceId(boolean)
090         * @since 1.1
091         */
092        boolean isOmitResourceId();
093
094        /**
095         * If set to <code>true<code> (which is the default), resource references containing a version 
096         * will have the version removed when the resource is encoded. This is generally good behaviour because
097         * in most situations, references from one resource to another should be to the resource by ID, not
098         * by ID and version. In some cases though, it may be desirable to preserve the version in resource
099         * links. In that case, this value should be set to <code>false</code>.
100         * 
101         * @return Returns the parser instance's configuration setting for stripping versions from resource references when
102         *         encoding. Default is <code>true</code>.
103         */
104        boolean isStripVersionsFromReferences();
105
106        /**
107         * Is the parser in "summary mode"? See {@link #setSummaryMode(boolean)} for information
108         * 
109         * @see {@link #setSummaryMode(boolean)} for information
110         */
111        boolean isSummaryMode();
112
113        /**
114         * Parse a DSTU1 style Atom Bundle. Note that as of DSTU2, Bundle is a resource so you should use
115         * {@link #parseResource(Class, Reader)} with the Bundle class found in the
116         * <code>ca.uhn.hapi.fhir.model.[version].resource</code> package instead.
117         */
118        <T extends IBaseResource> Bundle parseBundle(Class<T> theResourceType, Reader theReader);
119
120        /**
121         * Parse a DSTU1 style Atom Bundle. Note that as of DSTU2, Bundle is a resource so you should use
122         * {@link #parseResource(Class, Reader)} with the Bundle class found in the
123         * <code>ca.uhn.hapi.fhir.model.[version].resource</code> package instead.
124         */
125        Bundle parseBundle(Reader theReader);
126
127        /**
128         * Parse a DSTU1 style Atom Bundle. Note that as of DSTU2, Bundle is a resource so you should use
129         * {@link #parseResource(Class, String)} with the Bundle class found in the
130         * <code>ca.uhn.hapi.fhir.model.[version].resource</code> package instead.
131         */
132        Bundle parseBundle(String theMessageString) throws ConfigurationException, DataFormatException;
133
134        /**
135         * Parses a resource
136         * 
137         * @param theResourceType
138         *           The resource type to use. This can be used to explicitly specify a class which extends a built-in type
139         *           (e.g. a custom type extending the default Patient class)
140         * @param theReader
141         *           The reader to parse input from. Note that the Reader will not be closed by the parser upon completion.
142         * @return A parsed resource
143         * @throws DataFormatException
144         *            If the resource can not be parsed because the data is not recognized or invalid for any reason
145         */
146        <T extends IBaseResource> T parseResource(Class<T> theResourceType, Reader theReader) throws DataFormatException;
147
148        /**
149         * Parses a resource
150         * 
151         * @param theResourceType
152         *           The resource type to use. This can be used to explicitly specify a class which extends a built-in type
153         *           (e.g. a custom type extending the default Patient class)
154         * @param theString
155         *           The string to parse
156         * @return A parsed resource
157         * @throws DataFormatException
158         *            If the resource can not be parsed because the data is not recognized or invalid for any reason
159         */
160        <T extends IBaseResource> T parseResource(Class<T> theResourceType, String theString) throws DataFormatException;
161
162        /**
163         * Parses a resource
164         * 
165         * @param theReader
166         *           The reader to parse input from. Note that the Reader will not be closed by the parser upon completion.
167         * @return A parsed resource. Note that the returned object will be an instance of {@link IResource} or
168         *         {@link IAnyResource} depending on the specific FhirContext which created this parser.
169         * @throws DataFormatException
170         *            If the resource can not be parsed because the data is not recognized or invalid for any reason
171         */
172        IBaseResource parseResource(Reader theReader) throws ConfigurationException, DataFormatException;
173
174        /**
175         * Parses a resource
176         * 
177         * @param theMessageString
178         *           The string to parse
179         * @return A parsed resource. Note that the returned object will be an instance of {@link IResource} or
180         *         {@link IAnyResource} depending on the specific FhirContext which created this parser.
181         * @throws DataFormatException
182         *            If the resource can not be parsed because the data is not recognized or invalid for any reason
183         */
184        IBaseResource parseResource(String theMessageString) throws ConfigurationException, DataFormatException;
185
186        /**
187         * Parses a tag list, as defined in the <a href="http://hl7.org/implement/standards/fhir/http.html#tags">FHIR
188         * Specification</a>.
189         * 
190         * @param theReader
191         *           A reader which will supply a tag list
192         * @return A parsed tag list
193         */
194        TagList parseTagList(Reader theReader);
195
196        /**
197         * Parses a tag list, as defined in the <a href="http://hl7.org/implement/standards/fhir/http.html#tags">FHIR
198         * Specification</a>.
199         * 
200         * @param theString
201         *           A string containing a tag list
202         * @return A parsed tag list
203         */
204        TagList parseTagList(String theString);
205
206        /**
207         * If provided, specifies the elements which should be encoded, to the exclusion of all others. Valid values for this
208         * field would include:
209         * <ul>
210         * <li><b>Patient</b> - Encode patient and all its children</li>
211         * <li><b>Patient.name</b> - Encoding only the patient's name</li>
212         * <li><b>Patient.name.family</b> - Encode only the patient's family name</li>
213         * <li><b>*.text</b> - Encode the text element on any resource (only the very first position may contain a wildcard)</li>
214         * </ul>
215         * 
216         * @param theEncodeElements
217         *           The elements to encode
218         */
219        void setEncodeElements(Set<String> theEncodeElements);
220
221        /**
222         * If provided, tells the parse which resource types to apply {@link #setEncodeElements(Set) encode elements} to. Any
223         * resource types not specified here will be encoded completely, with no elements excluded.
224         * 
225         * @param theEncodeElementsAppliesToResourceTypes
226         */
227        void setEncodeElementsAppliesToResourceTypes(Set<String> theEncodeElementsAppliesToResourceTypes);
228
229        /**
230         * If set to <code>true</code> (default is <code>false</code>) the ID of any resources being encoded will not be
231         * included in the output. Note that this does not apply to contained resources, only to root resources. In other
232         * words, if this is set to <code>true</code>, contained resources will still have local IDs but the outer/containing
233         * ID will not have an ID.
234         * 
235         * @param theOmitResourceId
236         *           Should resource IDs be omitted
237         * @return Returns a reference to <code>this</code> parser so that method calls can be chained together
238         * @since 1.1
239         */
240        IParser setOmitResourceId(boolean theOmitResourceId);
241
242        /**
243         * Registers an error handler which will be invoked when any parse errors are found
244         * 
245         * @param theErrorHandler
246         *           The error handler to set. Must not be null.
247         */
248        IParser setParserErrorHandler(IParserErrorHandler theErrorHandler);
249
250        /**
251         * Sets the "pretty print" flag, meaning that the parser will encode resources with human-readable spacing and
252         * newlines between elements instead of condensing output as much as possible.
253         * 
254         * @param thePrettyPrint
255         *           The flag
256         * @return Returns an instance of <code>this</code> parser so that method calls can be chained together
257         */
258        IParser setPrettyPrint(boolean thePrettyPrint);
259
260        /**
261         * Sets the server's base URL used by this parser. If a value is set, resource references will be turned into
262         * relative references if they are provided as absolute URLs but have a base matching the given base.
263         * 
264         * @param theUrl
265         *           The base URL, e.g. "http://example.com/base"
266         * @return Returns an instance of <code>this</code> parser so that method calls can be chained together
267         */
268        IParser setServerBaseUrl(String theUrl);
269
270        /**
271         * If set to <code>true<code> (which is the default), resource references containing a version 
272         * will have the version removed when the resource is encoded. This is generally good behaviour because
273         * in most situations, references from one resource to another should be to the resource by ID, not
274         * by ID and version. In some cases though, it may be desirable to preserve the version in resource
275         * links. In that case, this value should be set to <code>false</code>.
276         * 
277         * @param theStripVersionsFromReferences
278         *           Set this to <code>false<code> to prevent the parser from removing
279         * resource versions from references.
280         * @return Returns a reference to <code>this</code> parser so that method calls can be chained together
281         */
282        IParser setStripVersionsFromReferences(boolean theStripVersionsFromReferences);
283
284        /**
285         * If set to <code>true</code> (default is <code>false</code>) only elements marked by the FHIR specification as
286         * being "summary elements" will be included.
287         * 
288         * @return Returns a reference to <code>this</code> parser so that method calls can be chained together
289         */
290        IParser setSummaryMode(boolean theSummaryMode);
291
292        /**
293         * If set to <code>true</code> (default is <code>false</code>), narratives will not be included in the encoded
294         * values.
295         */
296        IParser setSuppressNarratives(boolean theSuppressNarratives);
297
298        /**
299         * Which encoding does this parser instance produce?
300         */
301        EncodingEnum getEncoding();
302
303}