This commit is contained in:
parent
240decc210
commit
874b16207f
|
@ -991,7 +991,7 @@ public abstract class BaseParser implements IParser {
|
||||||
|
|
||||||
protected boolean shouldEncodeResourceId(IBaseResource theResource, EncodeContext theEncodeContext) {
|
protected boolean shouldEncodeResourceId(IBaseResource theResource, EncodeContext theEncodeContext) {
|
||||||
boolean retVal = true;
|
boolean retVal = true;
|
||||||
if (isOmitResourceId()) {
|
if (isOmitResourceId() && theEncodeContext.getPath().size() == 1) {
|
||||||
retVal = false;
|
retVal = false;
|
||||||
} else {
|
} else {
|
||||||
if (myDontEncodeElements != null) {
|
if (myDontEncodeElements != null) {
|
||||||
|
|
|
@ -57,6 +57,11 @@ public interface IParser {
|
||||||
*/
|
*/
|
||||||
IIdType getEncodeForceResourceId();
|
IIdType getEncodeForceResourceId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When encoding, force this resource ID to be encoded as the resource ID
|
||||||
|
*/
|
||||||
|
IParser setEncodeForceResourceId(IIdType theForceResourceId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Which encoding does this parser instance produce?
|
* Which encoding does this parser instance produce?
|
||||||
*/
|
*/
|
||||||
|
@ -64,117 +69,163 @@ public interface IParser {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the preferred types, as set using {@link #setPreferTypes(List)}
|
* Gets the preferred types, as set using {@link #setPreferTypes(List)}
|
||||||
*
|
*
|
||||||
* @return Returns the preferred types, or <code>null</code>
|
* @return Returns the preferred types, or <code>null</code>
|
||||||
* @see #setPreferTypes(List)
|
* @see #setPreferTypes(List)
|
||||||
*/
|
*/
|
||||||
List<Class<? extends IBaseResource>> getPreferTypes();
|
List<Class<? extends IBaseResource>> getPreferTypes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set, when parsing resources the parser will try to use the given types when possible, in
|
||||||
|
* the order that they are provided (from highest to lowest priority). For example, if a custom
|
||||||
|
* type which declares to implement the Patient resource is passed in here, and the
|
||||||
|
* parser is parsing a Bundle containing a Patient resource, the parser will use the given
|
||||||
|
* custom type.
|
||||||
|
* <p>
|
||||||
|
* This feature is related to, but not the same as the
|
||||||
|
* {@link FhirContext#setDefaultTypeForProfile(String, Class)} feature.
|
||||||
|
* <code>setDefaultTypeForProfile</code> is used to specify a type to be used
|
||||||
|
* when a resource explicitly declares support for a given profile. This
|
||||||
|
* feature specifies a type to be used irrespective of the profile declaration
|
||||||
|
* in the metadata statement.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param thePreferTypes The preferred types, or <code>null</code>
|
||||||
|
*/
|
||||||
|
void setPreferTypes(List<Class<? extends IBaseResource>> thePreferTypes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if resource IDs should be omitted
|
* Returns true if resource IDs should be omitted
|
||||||
*
|
*
|
||||||
* @see #setOmitResourceId(boolean)
|
* @see #setOmitResourceId(boolean)
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
boolean isOmitResourceId();
|
boolean isOmitResourceId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set to <code>true</code> (default is <code>false</code>) the ID of any resources being encoded will not be
|
||||||
|
* included in the output. Note that this does not apply to contained resources, only to root resources. In other
|
||||||
|
* words, if this is set to <code>true</code>, contained resources will still have local IDs but the outer/containing
|
||||||
|
* ID will not have an ID.
|
||||||
|
* <p>
|
||||||
|
* If the resource being encoded is a Bundle or Parameters resource, this setting only applies to the
|
||||||
|
* outer resource being encoded, not any resources contained wihthin.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param theOmitResourceId Should resource IDs be omitted
|
||||||
|
* @return Returns a reference to <code>this</code> parser so that method calls can be chained together
|
||||||
|
* @since 1.1
|
||||||
|
*/
|
||||||
|
IParser setOmitResourceId(boolean theOmitResourceId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to <code>true<code> (which is the default), resource references containing a version
|
* If set to <code>true<code> (which is the default), resource references containing a version
|
||||||
* will have the version removed when the resource is encoded. This is generally good behaviour because
|
* will have the version removed when the resource is encoded. This is generally good behaviour because
|
||||||
* in most situations, references from one resource to another should be to the resource by ID, not
|
* in most situations, references from one resource to another should be to the resource by ID, not
|
||||||
* by ID and version. In some cases though, it may be desirable to preserve the version in resource
|
* by ID and version. In some cases though, it may be desirable to preserve the version in resource
|
||||||
* links. In that case, this value should be set to <code>false</code>.
|
* links. In that case, this value should be set to <code>false</code>.
|
||||||
*
|
*
|
||||||
* @return Returns the parser instance's configuration setting for stripping versions from resource references when
|
* @return Returns the parser instance's configuration setting for stripping versions from resource references when
|
||||||
* encoding. This method will retun <code>null</code> if no value is set, in which case
|
* encoding. This method will retun <code>null</code> if no value is set, in which case
|
||||||
* the value from the {@link ParserOptions} will be used (default is <code>true</code>)
|
* the value from the {@link ParserOptions} will be used (default is <code>true</code>)
|
||||||
* @see ParserOptions
|
* @see ParserOptions
|
||||||
*/
|
*/
|
||||||
Boolean getStripVersionsFromReferences();
|
Boolean getStripVersionsFromReferences();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set to <code>true<code> (which is the default), resource references containing a version
|
||||||
|
* will have the version removed when the resource is encoded. This is generally good behaviour because
|
||||||
|
* in most situations, references from one resource to another should be to the resource by ID, not
|
||||||
|
* by ID and version. In some cases though, it may be desirable to preserve the version in resource
|
||||||
|
* links. In that case, this value should be set to <code>false</code>.
|
||||||
|
* <p>
|
||||||
|
* This method provides the ability to globally disable reference encoding. If finer-grained
|
||||||
|
* control is needed, use {@link #setDontStripVersionsFromReferencesAtPaths(String...)}
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @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}
|
||||||
|
* @return Returns a reference to <code>this</code> parser so that method calls can be chained together
|
||||||
|
* @see #setDontStripVersionsFromReferencesAtPaths(String...)
|
||||||
|
* @see ParserOptions
|
||||||
|
*/
|
||||||
|
IParser setStripVersionsFromReferences(Boolean theStripVersionsFromReferences);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the parser in "summary mode"? See {@link #setSummaryMode(boolean)} for information
|
* Is the parser in "summary mode"? See {@link #setSummaryMode(boolean)} for information
|
||||||
*
|
*
|
||||||
* @see {@link #setSummaryMode(boolean)} for information
|
* @see {@link #setSummaryMode(boolean)} for information
|
||||||
*/
|
*/
|
||||||
boolean isSummaryMode();
|
boolean isSummaryMode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set to <code>true</code> (default is <code>false</code>) only elements marked by the FHIR specification as
|
||||||
|
* being "summary elements" will be included.
|
||||||
|
*
|
||||||
|
* @return Returns a reference to <code>this</code> parser so that method calls can be chained together
|
||||||
|
*/
|
||||||
|
IParser setSummaryMode(boolean theSummaryMode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a resource
|
* Parses a resource
|
||||||
*
|
*
|
||||||
* @param theResourceType
|
* @param theResourceType The resource type to use. This can be used to explicitly specify a class which extends a built-in type
|
||||||
* The resource type to use. This can be used to explicitly specify a class which extends a built-in type
|
* (e.g. a custom type extending the default Patient class)
|
||||||
* (e.g. a custom type extending the default Patient class)
|
* @param theReader The reader to parse input from. Note that the Reader will not be closed by the parser upon completion.
|
||||||
* @param theReader
|
|
||||||
* The reader to parse input from. Note that the Reader will not be closed by the parser upon completion.
|
|
||||||
* @return A parsed resource
|
* @return A parsed resource
|
||||||
* @throws DataFormatException
|
* @throws DataFormatException If the resource can not be parsed because the data is not recognized or invalid for any reason
|
||||||
* If the resource can not be parsed because the data is not recognized or invalid for any reason
|
|
||||||
*/
|
*/
|
||||||
<T extends IBaseResource> T parseResource(Class<T> theResourceType, Reader theReader) throws DataFormatException;
|
<T extends IBaseResource> T parseResource(Class<T> theResourceType, Reader theReader) throws DataFormatException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a resource
|
* Parses a resource
|
||||||
*
|
*
|
||||||
* @param theResourceType
|
* @param theResourceType The resource type to use. This can be used to explicitly specify a class which extends a built-in type
|
||||||
* The resource type to use. This can be used to explicitly specify a class which extends a built-in type
|
* (e.g. a custom type extending the default Patient class)
|
||||||
* (e.g. a custom type extending the default Patient class)
|
* @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.
|
||||||
* @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.
|
|
||||||
* @return A parsed resource
|
* @return A parsed resource
|
||||||
* @throws DataFormatException
|
* @throws DataFormatException If the resource can not be parsed because the data is not recognized or invalid for any reason
|
||||||
* If the resource can not be parsed because the data is not recognized or invalid for any reason
|
|
||||||
*/
|
*/
|
||||||
<T extends IBaseResource> T parseResource(Class<T> theResourceType, InputStream theInputStream) throws DataFormatException;
|
<T extends IBaseResource> T parseResource(Class<T> theResourceType, InputStream theInputStream) throws DataFormatException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a resource
|
* Parses a resource
|
||||||
*
|
*
|
||||||
* @param theResourceType
|
* @param theResourceType The resource type to use. This can be used to explicitly specify a class which extends a built-in type
|
||||||
* The resource type to use. This can be used to explicitly specify a class which extends a built-in type
|
* (e.g. a custom type extending the default Patient class)
|
||||||
* (e.g. a custom type extending the default Patient class)
|
* @param theString The string to parse
|
||||||
* @param theString
|
|
||||||
* The string to parse
|
|
||||||
* @return A parsed resource
|
* @return A parsed resource
|
||||||
* @throws DataFormatException
|
* @throws DataFormatException If the resource can not be parsed because the data is not recognized or invalid for any reason
|
||||||
* If the resource can not be parsed because the data is not recognized or invalid for any reason
|
|
||||||
*/
|
*/
|
||||||
<T extends IBaseResource> T parseResource(Class<T> theResourceType, String theString) throws DataFormatException;
|
<T extends IBaseResource> T parseResource(Class<T> theResourceType, String theString) throws DataFormatException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a resource
|
* Parses a resource
|
||||||
*
|
*
|
||||||
* @param theReader
|
* @param theReader The reader to parse input from. Note that the Reader will not be closed by the parser upon completion.
|
||||||
* The reader to parse input from. Note that the Reader will not be closed by the parser upon completion.
|
|
||||||
* @return A parsed resource. Note that the returned object will be an instance of {@link IResource} or
|
* @return A parsed resource. Note that the returned object will be an instance of {@link IResource} or
|
||||||
* {@link IAnyResource} depending on the specific FhirContext which created this parser.
|
* {@link IAnyResource} depending on the specific FhirContext which created this parser.
|
||||||
* @throws DataFormatException
|
* @throws DataFormatException If the resource can not be parsed because the data is not recognized or invalid for any reason
|
||||||
* If the resource can not be parsed because the data is not recognized or invalid for any reason
|
|
||||||
*/
|
*/
|
||||||
IBaseResource parseResource(Reader theReader) throws ConfigurationException, DataFormatException;
|
IBaseResource parseResource(Reader theReader) throws ConfigurationException, DataFormatException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a resource
|
* Parses a resource
|
||||||
*
|
*
|
||||||
* @param theInputStream
|
* @param theInputStream The InputStream to parse input from (charset is assumed to be UTF-8).
|
||||||
* The InputStream to parse input from (charset is assumed to be UTF-8).
|
* Note that the stream will not be closed by the parser upon completion.
|
||||||
* Note that the stream will not be closed by the parser upon completion.
|
|
||||||
* @return A parsed resource. Note that the returned object will be an instance of {@link IResource} or
|
* @return A parsed resource. Note that the returned object will be an instance of {@link IResource} or
|
||||||
* {@link IAnyResource} depending on the specific FhirContext which created this parser.
|
* {@link IAnyResource} depending on the specific FhirContext which created this parser.
|
||||||
* @throws DataFormatException
|
* @throws DataFormatException If the resource can not be parsed because the data is not recognized or invalid for any reason
|
||||||
* If the resource can not be parsed because the data is not recognized or invalid for any reason
|
|
||||||
*/
|
*/
|
||||||
IBaseResource parseResource(InputStream theInputStream) throws ConfigurationException, DataFormatException;
|
IBaseResource parseResource(InputStream theInputStream) throws ConfigurationException, DataFormatException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a resource
|
* Parses a resource
|
||||||
*
|
*
|
||||||
* @param theMessageString
|
* @param theMessageString The string to parse
|
||||||
* The string to parse
|
|
||||||
* @return A parsed resource. Note that the returned object will be an instance of {@link IResource} or
|
* @return A parsed resource. Note that the returned object will be an instance of {@link IResource} or
|
||||||
* {@link IAnyResource} depending on the specific FhirContext which created this parser.
|
* {@link IAnyResource} depending on the specific FhirContext which created this parser.
|
||||||
* @throws DataFormatException
|
* @throws DataFormatException If the resource can not be parsed because the data is not recognized or invalid for any reason
|
||||||
* If the resource can not be parsed because the data is not recognized or invalid for any reason
|
|
||||||
*/
|
*/
|
||||||
IBaseResource parseResource(String theMessageString) throws ConfigurationException, DataFormatException;
|
IBaseResource parseResource(String theMessageString) throws ConfigurationException, DataFormatException;
|
||||||
|
|
||||||
|
@ -194,9 +245,8 @@ public interface IParser {
|
||||||
* as <code>Patient.meta.lastUpdated</code> will only work in
|
* as <code>Patient.meta.lastUpdated</code> will only work in
|
||||||
* DSTU3+ mode.
|
* DSTU3+ mode.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param theDontEncodeElements
|
* @param theDontEncodeElements The elements to encode
|
||||||
* The elements to encode
|
|
||||||
* @see #setEncodeElements(Set)
|
* @see #setEncodeElements(Set)
|
||||||
*/
|
*/
|
||||||
IParser setDontEncodeElements(Set<String> theDontEncodeElements);
|
IParser setDontEncodeElements(Set<String> theDontEncodeElements);
|
||||||
|
@ -212,9 +262,8 @@ public interface IParser {
|
||||||
* wildcard)</li>
|
* wildcard)</li>
|
||||||
* <li><b>*.(mandatory)</b> - This is a special case which causes any mandatory fields (min > 0) to be encoded</li>
|
* <li><b>*.(mandatory)</b> - This is a special case which causes any mandatory fields (min > 0) to be encoded</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @param theEncodeElements
|
* @param theEncodeElements The elements to encode
|
||||||
* The elements to encode
|
|
||||||
* @see #setDontEncodeElements(Set)
|
* @see #setDontEncodeElements(Set)
|
||||||
*/
|
*/
|
||||||
IParser setEncodeElements(Set<String> theEncodeElements);
|
IParser setEncodeElements(Set<String> theEncodeElements);
|
||||||
|
@ -225,7 +274,7 @@ public interface IParser {
|
||||||
* resource (typically a Bundle), but will be applied to any sub-resources
|
* resource (typically a Bundle), but will be applied to any sub-resources
|
||||||
* contained within it (i.e. search result resources in that bundle)
|
* contained within it (i.e. search result resources in that bundle)
|
||||||
*/
|
*/
|
||||||
void setEncodeElementsAppliesToChildResourcesOnly(boolean theEncodeElementsAppliesToChildResourcesOnly);
|
boolean isEncodeElementsAppliesToChildResourcesOnly();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to <code>true</code> (default is false), the values supplied
|
* If set to <code>true</code> (default is false), the values supplied
|
||||||
|
@ -233,60 +282,20 @@ public interface IParser {
|
||||||
* resource (typically a Bundle), but will be applied to any sub-resources
|
* resource (typically a Bundle), but will be applied to any sub-resources
|
||||||
* contained within it (i.e. search result resources in that bundle)
|
* contained within it (i.e. search result resources in that bundle)
|
||||||
*/
|
*/
|
||||||
boolean isEncodeElementsAppliesToChildResourcesOnly();
|
void setEncodeElementsAppliesToChildResourcesOnly(boolean theEncodeElementsAppliesToChildResourcesOnly);
|
||||||
|
|
||||||
/**
|
|
||||||
* When encoding, force this resource ID to be encoded as the resource ID
|
|
||||||
*/
|
|
||||||
IParser setEncodeForceResourceId(IIdType theForceResourceId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If set to <code>true</code> (default is <code>false</code>) the ID of any resources being encoded will not be
|
|
||||||
* included in the output. Note that this does not apply to contained resources, only to root resources. In other
|
|
||||||
* words, if this is set to <code>true</code>, contained resources will still have local IDs but the outer/containing
|
|
||||||
* ID will not have an ID.
|
|
||||||
*
|
|
||||||
* @param theOmitResourceId
|
|
||||||
* Should resource IDs be omitted
|
|
||||||
* @return Returns a reference to <code>this</code> parser so that method calls can be chained together
|
|
||||||
* @since 1.1
|
|
||||||
*/
|
|
||||||
IParser setOmitResourceId(boolean theOmitResourceId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers an error handler which will be invoked when any parse errors are found
|
* Registers an error handler which will be invoked when any parse errors are found
|
||||||
*
|
*
|
||||||
* @param theErrorHandler
|
* @param theErrorHandler The error handler to set. Must not be null.
|
||||||
* The error handler to set. Must not be null.
|
|
||||||
*/
|
*/
|
||||||
IParser setParserErrorHandler(IParserErrorHandler theErrorHandler);
|
IParser setParserErrorHandler(IParserErrorHandler theErrorHandler);
|
||||||
|
|
||||||
/**
|
|
||||||
* If set, when parsing resources the parser will try to use the given types when possible, in
|
|
||||||
* the order that they are provided (from highest to lowest priority). For example, if a custom
|
|
||||||
* type which declares to implement the Patient resource is passed in here, and the
|
|
||||||
* parser is parsing a Bundle containing a Patient resource, the parser will use the given
|
|
||||||
* custom type.
|
|
||||||
* <p>
|
|
||||||
* This feature is related to, but not the same as the
|
|
||||||
* {@link FhirContext#setDefaultTypeForProfile(String, Class)} feature.
|
|
||||||
* <code>setDefaultTypeForProfile</code> is used to specify a type to be used
|
|
||||||
* when a resource explicitly declares support for a given profile. This
|
|
||||||
* feature specifies a type to be used irrespective of the profile declaration
|
|
||||||
* in the metadata statement.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param thePreferTypes
|
|
||||||
* The preferred types, or <code>null</code>
|
|
||||||
*/
|
|
||||||
void setPreferTypes(List<Class<? extends IBaseResource>> thePreferTypes);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the "pretty print" flag, meaning that the parser will encode resources with human-readable spacing and
|
* Sets the "pretty print" flag, meaning that the parser will encode resources with human-readable spacing and
|
||||||
* newlines between elements instead of condensing output as much as possible.
|
* newlines between elements instead of condensing output as much as possible.
|
||||||
*
|
*
|
||||||
* @param thePrettyPrint
|
* @param thePrettyPrint The flag
|
||||||
* The flag
|
|
||||||
* @return Returns an instance of <code>this</code> parser so that method calls can be chained together
|
* @return Returns an instance of <code>this</code> parser so that method calls can be chained together
|
||||||
*/
|
*/
|
||||||
IParser setPrettyPrint(boolean thePrettyPrint);
|
IParser setPrettyPrint(boolean thePrettyPrint);
|
||||||
|
@ -294,62 +303,42 @@ public interface IParser {
|
||||||
/**
|
/**
|
||||||
* Sets the server's base URL used by this parser. If a value is set, resource references will be turned into
|
* Sets the server's base URL used by this parser. If a value is set, resource references will be turned into
|
||||||
* relative references if they are provided as absolute URLs but have a base matching the given base.
|
* relative references if they are provided as absolute URLs but have a base matching the given base.
|
||||||
*
|
*
|
||||||
* @param theUrl
|
* @param theUrl The base URL, e.g. "http://example.com/base"
|
||||||
* The base URL, e.g. "http://example.com/base"
|
|
||||||
* @return Returns an instance of <code>this</code> parser so that method calls can be chained together
|
* @return Returns an instance of <code>this</code> parser so that method calls can be chained together
|
||||||
*/
|
*/
|
||||||
IParser setServerBaseUrl(String theUrl);
|
IParser setServerBaseUrl(String theUrl);
|
||||||
|
|
||||||
/**
|
|
||||||
* If set to <code>true<code> (which is the default), resource references containing a version
|
|
||||||
* will have the version removed when the resource is encoded. This is generally good behaviour because
|
|
||||||
* in most situations, references from one resource to another should be to the resource by ID, not
|
|
||||||
* by ID and version. In some cases though, it may be desirable to preserve the version in resource
|
|
||||||
* links. In that case, this value should be set to <code>false</code>.
|
|
||||||
* <p>
|
|
||||||
* This method provides the ability to globally disable reference encoding. If finer-grained
|
|
||||||
* control is needed, use {@link #setDontStripVersionsFromReferencesAtPaths(String...)}
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @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}
|
|
||||||
* @see #setDontStripVersionsFromReferencesAtPaths(String...)
|
|
||||||
* @see ParserOptions
|
|
||||||
* @return Returns a reference to <code>this</code> parser so that method calls can be chained together
|
|
||||||
*/
|
|
||||||
IParser setStripVersionsFromReferences(Boolean theStripVersionsFromReferences);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to <code>true</code> (which is the default), the Bundle.entry.fullUrl will override the Bundle.entry.resource's
|
* If set to <code>true</code> (which is the default), the Bundle.entry.fullUrl will override the Bundle.entry.resource's
|
||||||
* resource id if the fullUrl is defined. This behavior happens when parsing the source data into a Bundle object. Set this
|
* resource id if the fullUrl is defined. This behavior happens when parsing the source data into a Bundle object. Set this
|
||||||
* to <code>false</code> if this is not the desired behavior (e.g. the client code wishes to perform additional
|
* to <code>false</code> if this is not the desired behavior (e.g. the client code wishes to perform additional
|
||||||
* validation checks between the fullUrl and the resource id).
|
* validation checks between the fullUrl and the resource id).
|
||||||
*
|
*
|
||||||
* @param theOverrideResourceIdWithBundleEntryFullUrl
|
* @param theOverrideResourceIdWithBundleEntryFullUrl Set this to <code>false</code> to prevent the parser from overriding resource ids with the
|
||||||
* Set this to <code>false</code> to prevent the parser from overriding resource ids with the
|
* Bundle.entry.fullUrl (or <code>null</code> to apply the default setting from the {@link ParserOptions})
|
||||||
* Bundle.entry.fullUrl (or <code>null</code> to apply the default setting from the {@link ParserOptions})
|
|
||||||
*
|
|
||||||
* @see ParserOptions
|
|
||||||
*
|
|
||||||
* @return Returns a reference to <code>this</code> parser so that method calls can be chained together
|
* @return Returns a reference to <code>this</code> parser so that method calls can be chained together
|
||||||
|
* @see ParserOptions
|
||||||
*/
|
*/
|
||||||
IParser setOverrideResourceIdWithBundleEntryFullUrl(Boolean theOverrideResourceIdWithBundleEntryFullUrl);
|
IParser setOverrideResourceIdWithBundleEntryFullUrl(Boolean theOverrideResourceIdWithBundleEntryFullUrl);
|
||||||
|
|
||||||
/**
|
|
||||||
* If set to <code>true</code> (default is <code>false</code>) only elements marked by the FHIR specification as
|
|
||||||
* being "summary elements" will be included.
|
|
||||||
*
|
|
||||||
* @return Returns a reference to <code>this</code> parser so that method calls can be chained together
|
|
||||||
*/
|
|
||||||
IParser setSummaryMode(boolean theSummaryMode);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to <code>true</code> (default is <code>false</code>), narratives will not be included in the encoded
|
* If set to <code>true</code> (default is <code>false</code>), narratives will not be included in the encoded
|
||||||
* values.
|
* values.
|
||||||
*/
|
*/
|
||||||
IParser setSuppressNarratives(boolean theSuppressNarratives);
|
IParser setSuppressNarratives(boolean theSuppressNarratives);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value supplied to {@link IParser#setDontStripVersionsFromReferencesAtPaths(String...)}
|
||||||
|
* or <code>null</code> if no value has been set for this parser (in which case the default from
|
||||||
|
* the {@link ParserOptions} will be used}
|
||||||
|
*
|
||||||
|
* @see #setDontStripVersionsFromReferencesAtPaths(String...)
|
||||||
|
* @see #setStripVersionsFromReferences(Boolean)
|
||||||
|
* @see ParserOptions
|
||||||
|
*/
|
||||||
|
Set<String> getDontStripVersionsFromReferencesAtPaths();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If supplied value(s), any resource references at the specified paths will have their
|
* If supplied value(s), any resource references at the specified paths will have their
|
||||||
* resource versions encoded instead of being automatically stripped during the encoding
|
* resource versions encoded instead of being automatically stripped during the encoding
|
||||||
|
@ -360,15 +349,14 @@ public interface IParser {
|
||||||
* has been set to <code>true</code> (which is the default)
|
* has been set to <code>true</code> (which is the default)
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param thePaths
|
* @param thePaths A collection of paths for which the resource versions will not be removed automatically
|
||||||
* A collection of paths for which the resource versions will not be removed automatically
|
* when serializing, e.g. "Patient.managingOrganization" or "AuditEvent.object.reference". Note that
|
||||||
* when serializing, e.g. "Patient.managingOrganization" or "AuditEvent.object.reference". Note that
|
* only resource name and field names with dots separating is allowed here (no repetition
|
||||||
* only resource name and field names with dots separating is allowed here (no repetition
|
* indicators, FluentPath expressions, etc.). Set to <code>null</code> to use the value
|
||||||
* indicators, FluentPath expressions, etc.). Set to <code>null</code> to use the value
|
* set in the {@link ParserOptions}
|
||||||
* set in the {@link ParserOptions}
|
* @return Returns a reference to <code>this</code> parser so that method calls can be chained together
|
||||||
* @see #setStripVersionsFromReferences(Boolean)
|
* @see #setStripVersionsFromReferences(Boolean)
|
||||||
* @see ParserOptions
|
* @see ParserOptions
|
||||||
* @return Returns a reference to <code>this</code> parser so that method calls can be chained together
|
|
||||||
*/
|
*/
|
||||||
IParser setDontStripVersionsFromReferencesAtPaths(String... thePaths);
|
IParser setDontStripVersionsFromReferencesAtPaths(String... thePaths);
|
||||||
|
|
||||||
|
@ -382,27 +370,15 @@ public interface IParser {
|
||||||
* has been set to <code>true</code> (which is the default)
|
* has been set to <code>true</code> (which is the default)
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param thePaths
|
* @param thePaths A collection of paths for which the resource versions will not be removed automatically
|
||||||
* A collection of paths for which the resource versions will not be removed automatically
|
* when serializing, e.g. "Patient.managingOrganization" or "AuditEvent.object.reference". Note that
|
||||||
* when serializing, e.g. "Patient.managingOrganization" or "AuditEvent.object.reference". Note that
|
* only resource name and field names with dots separating is allowed here (no repetition
|
||||||
* only resource name and field names with dots separating is allowed here (no repetition
|
* indicators, FluentPath expressions, etc.). Set to <code>null</code> to use the value
|
||||||
* indicators, FluentPath expressions, etc.). Set to <code>null</code> to use the value
|
* set in the {@link ParserOptions}
|
||||||
* set in the {@link ParserOptions}
|
* @return Returns a reference to <code>this</code> parser so that method calls can be chained together
|
||||||
* @see #setStripVersionsFromReferences(Boolean)
|
* @see #setStripVersionsFromReferences(Boolean)
|
||||||
* @see ParserOptions
|
* @see ParserOptions
|
||||||
* @return Returns a reference to <code>this</code> parser so that method calls can be chained together
|
|
||||||
*/
|
*/
|
||||||
IParser setDontStripVersionsFromReferencesAtPaths(Collection<String> thePaths);
|
IParser setDontStripVersionsFromReferencesAtPaths(Collection<String> thePaths);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value supplied to {@link IParser#setDontStripVersionsFromReferencesAtPaths(String...)}
|
|
||||||
* or <code>null</code> if no value has been set for this parser (in which case the default from
|
|
||||||
* the {@link ParserOptions} will be used}
|
|
||||||
*
|
|
||||||
* @see #setDontStripVersionsFromReferencesAtPaths(String...)
|
|
||||||
* @see #setStripVersionsFromReferences(Boolean)
|
|
||||||
* @see ParserOptions
|
|
||||||
*/
|
|
||||||
Set<String> getDontStripVersionsFromReferencesAtPaths();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,6 +193,14 @@ public class BundleBuilder {
|
||||||
return new CreateBuilder(request);
|
return new CreateBuilder(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an entry for a Collection bundle type
|
||||||
|
*/
|
||||||
|
public void addCollectionEntry(IBaseResource theResource) {
|
||||||
|
setType("collection");
|
||||||
|
addEntryAndReturnRequest(theResource);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new entry and adds it to the bundle
|
* Creates new entry and adds it to the bundle
|
||||||
*
|
*
|
||||||
|
@ -321,6 +329,16 @@ public class BundleBuilder {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a value for <code>Bundle.type</code>. That this is a coded field so {@literal theType}
|
||||||
|
* must be an actual valid value for this field or a {@link ca.uhn.fhir.parser.DataFormatException}
|
||||||
|
* will be thrown.
|
||||||
|
*/
|
||||||
|
public void setType(String theType) {
|
||||||
|
setBundleField("type", theType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class UpdateBuilder {
|
public static class UpdateBuilder {
|
||||||
|
|
||||||
private final IPrimitiveType<?> myUrl;
|
private final IPrimitiveType<?> myUrl;
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 2297
|
||||||
|
title: "When performing a FHIR create using the HAPI FHIR client, if the payload is a Bundle resource
|
||||||
|
the individual resources in the Bundle had their IDs removed by the client during payload serialization.
|
||||||
|
This has been corrected."
|
|
@ -30,6 +30,7 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
||||||
|
import ca.uhn.fhir.util.BundleBuilder;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
import ca.uhn.fhir.util.UrlUtil;
|
import ca.uhn.fhir.util.UrlUtil;
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
|
@ -48,6 +49,7 @@ import org.apache.http.message.BasicHeader;
|
||||||
import org.apache.http.message.BasicStatusLine;
|
import org.apache.http.message.BasicStatusLine;
|
||||||
import org.hamcrest.core.StringContains;
|
import org.hamcrest.core.StringContains;
|
||||||
import org.hamcrest.core.StringEndsWith;
|
import org.hamcrest.core.StringEndsWith;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.r4.model.*;
|
import org.hl7.fhir.r4.model.*;
|
||||||
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
|
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
|
||||||
|
@ -73,6 +75,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.either;
|
import static org.hamcrest.Matchers.either;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
@ -206,6 +209,51 @@ public class ClientR4Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #2297
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testCreateBundlePreservesIds() throws Exception {
|
||||||
|
|
||||||
|
BundleBuilder bb = new BundleBuilder(ourCtx);
|
||||||
|
bb.setType("collection");
|
||||||
|
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.setId("Patient/123");
|
||||||
|
patient.addIdentifier().setSystem("urn:foo").setValue("bar");
|
||||||
|
bb.addCollectionEntry(patient);
|
||||||
|
|
||||||
|
IBaseBundle inputBundle = bb.getBundle();
|
||||||
|
inputBundle.setId("ABC");
|
||||||
|
|
||||||
|
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||||
|
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||||
|
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK"));
|
||||||
|
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_TEXT + "; charset=UTF-8"));
|
||||||
|
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), StandardCharsets.UTF_8));
|
||||||
|
when(myHttpResponse.getAllHeaders()).thenReturn(toHeaderArray("Location", "http://example.com/fhir/Patient/100/_history/200"));
|
||||||
|
|
||||||
|
IGenericClient client = ourCtx.newRestfulGenericClient("http://foo");
|
||||||
|
client.setEncoding(EncodingEnum.JSON);
|
||||||
|
CapturingInterceptor interceptor = new CapturingInterceptor();
|
||||||
|
client.registerInterceptor(interceptor);
|
||||||
|
|
||||||
|
client.create().resource(inputBundle).execute();
|
||||||
|
|
||||||
|
assertEquals("http://foo/Bundle?_format=json", ((ApacheHttpRequest) interceptor.getLastRequest()).getApacheRequest().getURI().toASCIIString());
|
||||||
|
|
||||||
|
assertEquals(HttpPost.class, capt.getValue().getClass());
|
||||||
|
HttpPost post = (HttpPost) capt.getValue();
|
||||||
|
String requestBody = IOUtils.toString(post.getEntity().getContent(), Charsets.UTF_8);
|
||||||
|
ourLog.info("Request body: {}", requestBody);
|
||||||
|
assertThat(requestBody, StringContains.containsString("{\"resourceType\":\"Patient\""));
|
||||||
|
Bundle requestBundle = ourCtx.newJsonParser().parseResource(Bundle.class, requestBody);
|
||||||
|
|
||||||
|
assertEquals("123", requestBundle.getEntry().get(0).getResource().getIdElement().getIdPart());
|
||||||
|
assertThat(requestBody, containsString("\"id\":\"123\""));
|
||||||
|
assertThat(requestBody, not(containsString("\"id\":\"ABC\"")));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some servers (older ones?) return the resourcde you created instead of an OperationOutcome. We just need to ignore
|
* Some servers (older ones?) return the resourcde you created instead of an OperationOutcome. We just need to ignore
|
||||||
* it.
|
* it.
|
||||||
|
|
Loading…
Reference in New Issue