001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.model.dataformat;
018
019import java.util.List;
020import java.util.Set;
021
022import javax.xml.bind.annotation.XmlAttribute;
023import javax.xml.bind.annotation.XmlTransient;
024
025import org.apache.camel.CamelContext;
026import org.apache.camel.model.DataFormatDefinition;
027import org.apache.camel.spi.DataFormat;
028import org.apache.camel.spi.Metadata;
029import org.apache.camel.util.ObjectHelper;
030
031public abstract class FhirDataformat extends DataFormatDefinition {
032    @XmlTransient
033    @Metadata(label = "advanced")
034    private Object fhirContext;
035
036    @XmlAttribute
037    @Metadata(enums = "DSTU2,DSTU2_HL7ORG,DSTU2_1,DSTU3,R4", defaultValue = "DSTU3")
038    private String fhirVersion;
039
040    @XmlAttribute
041    private Boolean prettyPrint;
042
043    @XmlTransient
044    @Metadata(label = "advanced")
045    private Object parserErrorHandler;
046
047    @XmlTransient
048    @Metadata(label = "advanced")
049    private Object parserOptions;
050
051    @XmlTransient
052    @Metadata(label = "advanced")
053    private Object preferTypes;
054
055    @XmlTransient
056    @Metadata(label = "advanced")
057    private Object forceResourceId;
058
059    @XmlAttribute
060    @Metadata(label = "advanced")
061    private String serverBaseUrl;
062
063    @XmlAttribute
064    @Metadata(label = "advanced")
065    private Boolean omitResourceId;
066
067    @XmlAttribute
068    @Metadata(label = "advanced")
069    private Set<String> encodeElementsAppliesToResourceTypes;
070
071    @XmlAttribute
072    @Metadata(label = "advanced")
073    private Boolean encodeElementsAppliesToChildResourcesOnly;
074
075    @XmlAttribute
076    @Metadata(label = "advanced")
077    private Set<String> encodeElements;
078
079    @XmlAttribute
080    @Metadata(label = "advanced")
081    private Set<String> dontEncodeElements;
082
083    @XmlAttribute
084    @Metadata(label = "advanced")
085    private Boolean stripVersionsFromReferences;
086
087    @XmlAttribute
088    @Metadata(label = "advanced")
089    private Boolean overrideResourceIdWithBundleEntryFullUrl;
090
091    @XmlAttribute
092    @Metadata(label = "advanced")
093    private Boolean summaryMode;
094
095    @XmlAttribute
096    @Metadata(label = "advanced")
097    private Boolean suppressNarratives;
098
099    @XmlAttribute
100    @Metadata(label = "advanced")
101    private List<String> dontStripVersionsFromReferencesAtPaths;
102
103    protected FhirDataformat(String dataFormatName) {
104        super(dataFormatName);
105    }
106
107    protected FhirDataformat() {
108        // This constructor is needed by jaxb for schema generation
109    }
110
111
112
113    @Override
114    protected void configureDataFormat(DataFormat dataFormat, CamelContext camelContext) {
115        if (getContentTypeHeader() != null) {
116            setProperty(camelContext, dataFormat, "contentTypeHeader", getContentTypeHeader());
117        }
118        if (getFhirContext() != null) {
119            setProperty(camelContext, dataFormat, "fhirContext", getFhirContext());
120        }
121        if (getFhirVersion() != null) {
122            setProperty(camelContext, dataFormat, "fhirVersion", getFhirVersion());
123        }
124        if (ObjectHelper.isNotEmpty(getDontStripVersionsFromReferencesAtPaths())) {
125            setProperty(camelContext, dataFormat, "dontStripVersionsFromReferencesAtPaths", getDontStripVersionsFromReferencesAtPaths());
126        }
127        if (ObjectHelper.isNotEmpty(getDontEncodeElements())) {
128            setProperty(camelContext, dataFormat, "dontEncodeElements", getDontEncodeElements());
129        }
130        if (ObjectHelper.isNotEmpty(getEncodeElements())) {
131            setProperty(camelContext, dataFormat, "encodeElements", getEncodeElements());
132        }
133        if (ObjectHelper.isNotEmpty(getEncodeElementsAppliesToResourceTypes())) {
134            setProperty(camelContext, dataFormat, "encodeElementsAppliesToResourceTypes", getEncodeElementsAppliesToResourceTypes());
135        }
136        if (ObjectHelper.isNotEmpty(getServerBaseUrl())) {
137            setProperty(camelContext, dataFormat, "serverBaseUrl", getServerBaseUrl());
138        }
139        if (ObjectHelper.isNotEmpty(getForceResourceId())) {
140            setProperty(camelContext, dataFormat, "forceResourceId", getForceResourceId());
141        }
142        if (ObjectHelper.isNotEmpty(getPreferTypes())) {
143            setProperty(camelContext, dataFormat, "preferTypes", getPreferTypes());
144        }
145        if (ObjectHelper.isNotEmpty(getParserOptions())) {
146            setProperty(camelContext, dataFormat, "parserOptions", getParserOptions());
147        }
148        if (ObjectHelper.isNotEmpty(getParserErrorHandler())) {
149            setProperty(camelContext, dataFormat, "parserErrorHandler", getParserErrorHandler());
150        }
151
152        Boolean answer = ObjectHelper.toBoolean(isEncodeElementsAppliesToChildResourcesOnly());
153        if (answer != null) {
154            setProperty(camelContext, dataFormat, "encodeElementsAppliesToChildResourcesOnly", answer);
155        }
156        answer = ObjectHelper.toBoolean(isOmitResourceId());
157        if (answer != null) {
158            setProperty(camelContext, dataFormat, "omitResourceId", answer);
159        }
160        answer = ObjectHelper.toBoolean(isPrettyPrint());
161        if (answer != null) {
162            setProperty(camelContext, dataFormat, "prettyPrint", answer);
163        }
164        answer = ObjectHelper.toBoolean(isSuppressNarratives());
165        if (answer != null) {
166            setProperty(camelContext, dataFormat, "suppressNarratives", answer);
167        }
168        answer = ObjectHelper.toBoolean(isSummaryMode());
169        if (answer != null) {
170            setProperty(camelContext, dataFormat, "summaryMode", answer);
171        }
172        answer = ObjectHelper.toBoolean(getOverrideResourceIdWithBundleEntryFullUrl());
173        if (answer != null) {
174            setProperty(camelContext, dataFormat, "overrideResourceIdWithBundleEntryFullUrl", answer);
175        }
176        answer = ObjectHelper.toBoolean(getStripVersionsFromReferences());
177        if (answer != null) {
178            setProperty(camelContext, dataFormat, "stripVersionsFromReferences", answer);
179        }
180    }
181
182    public Object getFhirContext() {
183        return fhirContext;
184    }
185
186    public void setFhirContext(Object fhirContext) {
187        this.fhirContext = fhirContext;
188    }
189
190    public String getFhirVersion() {
191        return fhirVersion;
192    }
193
194    /**
195     * The version of FHIR to use. Possible values are: DSTU2,DSTU2_HL7ORG,DSTU2_1,DSTU3,R4
196     */
197    public void setFhirVersion(String fhirVersion) {
198        this.fhirVersion = fhirVersion;
199    }
200
201    public Boolean isPrettyPrint() {
202        return prettyPrint;
203    }
204
205    /**
206     * Sets the "pretty print" flag, meaning that the parser will encode resources with human-readable spacing and
207     * newlines between elements instead of condensing output as much as possible.
208     *
209     * @param prettyPrint The flag
210     */
211    public void setPrettyPrint(Boolean prettyPrint) {
212        this.prettyPrint = prettyPrint;
213    }
214
215    public Object getParserErrorHandler() {
216        return parserErrorHandler;
217    }
218
219    /**
220     * Registers an error handler which will be invoked when any parse errors are found
221     *
222     * @param parserErrorHandler The error handler to set. Must not be null.
223     */
224    public void setParserErrorHandler(Object parserErrorHandler) {
225        this.parserErrorHandler = parserErrorHandler;
226    }
227
228    public Object getParserOptions() {
229        return parserOptions;
230    }
231
232    /**
233     * Sets the parser options object which will be used to supply default
234     * options to newly created parsers.
235     *
236     * @param parserOptions The parser options object
237     */
238    public void setParserOptions(Object parserOptions) {
239        this.parserOptions = parserOptions;
240    }
241
242    public Object getPreferTypes() {
243        return preferTypes;
244    }
245
246    /**
247     * If set, when parsing resources the parser will try to use the given types when possible, in
248     * the order that they are provided (from highest to lowest priority). For example, if a custom
249     * type which declares to implement the Patient resource is passed in here, and the
250     * parser is parsing a Bundle containing a Patient resource, the parser will use the given
251     * custom type.
252     *
253     * @param preferTypes The preferred types, or <code>null</code>
254     */
255    public void setPreferTypes(Object preferTypes) {
256        this.preferTypes = preferTypes;
257    }
258
259    public Object getForceResourceId() {
260        return forceResourceId;
261    }
262
263    /**
264     * When encoding, force this resource ID to be encoded as the resource ID
265     */
266    public void setForceResourceId(Object forceResourceId) {
267        this.forceResourceId = forceResourceId;
268    }
269
270    public String getServerBaseUrl() {
271        return serverBaseUrl;
272    }
273
274    /**
275     * Sets the server's base URL used by this parser. If a value is set, resource references will be turned into
276     * relative references if they are provided as absolute URLs but have a base matching the given base.
277     *
278     * @param serverBaseUrl The base URL, e.g. "http://example.com/base"
279     */
280    public void setServerBaseUrl(String serverBaseUrl) {
281        this.serverBaseUrl = serverBaseUrl;
282    }
283
284    public Boolean isOmitResourceId() {
285        return omitResourceId;
286    }
287
288    /**
289     * If set to <code>true</code> (default is <code>false</code>) the ID of any resources being encoded will not be
290     * included in the output. Note that this does not apply to contained resources, only to root resources. In other
291     * words, if this is set to <code>true</code>, contained resources will still have local IDs but the outer/containing
292     * ID will not have an ID.
293     *
294     * @param omitResourceId Should resource IDs be omitted
295     */
296    public void setOmitResourceId(Boolean omitResourceId) {
297        this.omitResourceId = omitResourceId;
298    }
299
300    public Set<String> getEncodeElementsAppliesToResourceTypes() {
301        return encodeElementsAppliesToResourceTypes;
302    }
303
304    /**
305     * If provided, tells the parse which resource types to apply {@link #setEncodeElements(Set) encode elements} to. Any
306     * resource types not specified here will be encoded completely, with no elements excluded.
307     *
308     * @param encodeElementsAppliesToResourceTypes resouce types
309     */
310    public void setEncodeElementsAppliesToResourceTypes(Set<String> encodeElementsAppliesToResourceTypes) {
311        this.encodeElementsAppliesToResourceTypes = encodeElementsAppliesToResourceTypes;
312    }
313
314    public Boolean isEncodeElementsAppliesToChildResourcesOnly() {
315        return encodeElementsAppliesToChildResourcesOnly;
316    }
317
318    /**
319     * If set to <code>true</code> (default is false), the values supplied
320     * to {@link #setEncodeElements(Set)} will not be applied to the root
321     * resource (typically a Bundle), but will be applied to any sub-resources
322     * contained within it (i.e. search result resources in that bundle)
323     */
324    public void setEncodeElementsAppliesToChildResourcesOnly(Boolean encodeElementsAppliesToChildResourcesOnly) {
325        this.encodeElementsAppliesToChildResourcesOnly = encodeElementsAppliesToChildResourcesOnly;
326    }
327
328    public Set<String> getEncodeElements() {
329        return encodeElements;
330    }
331
332    /**
333     * If provided, specifies the elements which should be encoded, to the exclusion of all others. Valid values for this
334     * field would include:
335     * <ul>
336     * <li><b>Patient</b> - Encode patient and all its children</li>
337     * <li><b>Patient.name</b> - Encode only the patient's name</li>
338     * <li><b>Patient.name.family</b> - Encode only the patient's family name</li>
339     * <li><b>*.text</b> - Encode the text element on any resource (only the very first position may contain a
340     * wildcard)</li>
341     * <li><b>*.(mandatory)</b> - This is a special case which causes any mandatory fields (min > 0) to be encoded</li>
342     * </ul>
343     *
344     * @param encodeElements The elements to encode
345     * @see #setDontEncodeElements(Set)
346     */
347    public void setEncodeElements(Set<String> encodeElements) {
348        this.encodeElements = encodeElements;
349    }
350
351    public Set<String> getDontEncodeElements() {
352        return dontEncodeElements;
353    }
354
355    /**
356     * If provided, specifies the elements which should NOT be encoded. Valid values for this
357     * field would include:
358     * <ul>
359     * <li><b>Patient</b> - Don't encode patient and all its children</li>
360     * <li><b>Patient.name</b> - Don't encode the patient's name</li>
361     * <li><b>Patient.name.family</b> - Don't encode the patient's family name</li>
362     * <li><b>*.text</b> - Don't encode the text element on any resource (only the very first position may contain a
363     * wildcard)</li>
364     * </ul>
365     * <p>
366     * DSTU2 note: Note that values including meta, such as <code>Patient.meta</code>
367     * will work for DSTU2 parsers, but values with subelements on meta such
368     * as <code>Patient.meta.lastUpdated</code> will only work in
369     * DSTU3+ mode.
370     * </p>
371     *
372     * @param dontEncodeElements The elements to encode
373     * @see #setEncodeElements(Set)
374     */
375    public void setDontEncodeElements(Set<String> dontEncodeElements) {
376        this.dontEncodeElements = dontEncodeElements;
377    }
378
379    public Boolean getStripVersionsFromReferences() {
380        return stripVersionsFromReferences;
381    }
382
383    /**
384     * If set to <code>true<code> (which is the default), resource references containing a version
385     * will have the version removed when the resource is encoded. This is generally good behaviour because
386     * in most situations, references from one resource to another should be to the resource by ID, not
387     * by ID and version. In some cases though, it may be desirable to preserve the version in resource
388     * links. In that case, this value should be set to <code>false</code>.
389     * <p>
390     * This method provides the ability to globally disable reference encoding. If finer-grained
391     * control is needed, use {@link #setDontStripVersionsFromReferencesAtPaths(List)}
392     * </p>
393     *
394     * @param stripVersionsFromReferences Set this to <code>false<code> to prevent the parser from removing resource versions
395     *                                    from references (or <code>null</code> to apply the default setting from the {@link #setParserOptions(Object)}
396     * @see #setDontStripVersionsFromReferencesAtPaths(List)
397     */
398    public void setStripVersionsFromReferences(Boolean stripVersionsFromReferences) {
399        this.stripVersionsFromReferences = stripVersionsFromReferences;
400    }
401
402    public Boolean getOverrideResourceIdWithBundleEntryFullUrl() {
403        return overrideResourceIdWithBundleEntryFullUrl;
404    }
405
406    /**
407     * If set to <code>true</code> (which is the default), the Bundle.entry.fullUrl will override the Bundle.entry.resource's
408     * resource id if the fullUrl is defined. This behavior happens when parsing the source data into a Bundle object. Set this
409     * to <code>false</code> if this is not the desired behavior (e.g. the client code wishes to perform additional
410     * validation checks between the fullUrl and the resource id).
411     *
412     * @param overrideResourceIdWithBundleEntryFullUrl
413     *           Set this to <code>false</code> to prevent the parser from overriding resource ids with the
414     *           Bundle.entry.fullUrl (or <code>null</code> to apply the default setting from the {@link #setParserOptions(Object)})
415     */
416    public void setOverrideResourceIdWithBundleEntryFullUrl(Boolean overrideResourceIdWithBundleEntryFullUrl) {
417        this.overrideResourceIdWithBundleEntryFullUrl = overrideResourceIdWithBundleEntryFullUrl;
418    }
419
420    public Boolean isSummaryMode() {
421        return summaryMode;
422    }
423
424    /**
425     * If set to <code>true</code> (default is <code>false</code>) only elements marked by the FHIR specification as
426     * being "summary elements" will be included.
427     */
428    public void setSummaryMode(Boolean summaryMode) {
429        this.summaryMode = summaryMode;
430    }
431
432    public Boolean isSuppressNarratives() {
433        return suppressNarratives;
434    }
435
436    /**
437     * If set to <code>true</code> (default is <code>false</code>), narratives will not be included in the encoded
438     * values.
439     */
440    public void setSuppressNarratives(Boolean suppressNarratives) {
441        this.suppressNarratives = suppressNarratives;
442    }
443
444    public List<String> getDontStripVersionsFromReferencesAtPaths() {
445        return dontStripVersionsFromReferencesAtPaths;
446    }
447
448    /**
449     * If supplied value(s), any resource references at the specified paths will have their
450     * resource versions encoded instead of being automatically stripped during the encoding
451     * process. This setting has no effect on the parsing process.
452     * <p>
453     * This method provides a finer-grained level of control than {@link #setStripVersionsFromReferences(Boolean)}
454     * and any paths specified by this method will be encoded even if {@link #setStripVersionsFromReferences(Boolean)}
455     * has been set to <code>true</code> (which is the default)
456     * </p>
457     *
458     * @param dontStripVersionsFromReferencesAtPaths
459     *           A collection of paths for which the resource versions will not be removed automatically
460     *           when serializing, e.g. "Patient.managingOrganization" or "AuditEvent.object.reference". Note that
461     *           only resource name and field names with dots separating is allowed here (no repetition
462     *           indicators, FluentPath expressions, etc.). Set to <code>null</code> to use the value
463     *           set in the {@link #setParserOptions(Object)}
464     * @see #setStripVersionsFromReferences(Boolean)
465     */
466    public void setDontStripVersionsFromReferencesAtPaths(List<String> dontStripVersionsFromReferencesAtPaths) {
467        this.dontStripVersionsFromReferencesAtPaths = dontStripVersionsFromReferencesAtPaths;
468    }
469
470}