Clean up encoding of contained resources so that resources are not
modified as a part of the encoding
This commit is contained in:
parent
507ea9bedf
commit
2a9d92df7a
|
@ -96,6 +96,14 @@
|
||||||
have also caused resource validation to fail occasionally on these platforms as well.
|
have also caused resource validation to fail occasionally on these platforms as well.
|
||||||
Thanks to Bill de Beaubien for reporting!
|
Thanks to Bill de Beaubien for reporting!
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix">
|
||||||
|
toString() method on TokenParam was incorrectly showing the system as the value.
|
||||||
|
Thanks to Bill de Beaubien for reporting!
|
||||||
|
</action>
|
||||||
|
<action type="update">
|
||||||
|
Documentation on contained resources contained a typo and did not actually produce contained resources. Thanks
|
||||||
|
to David Hay of Orion Health for reporting!
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="0.6" date="2014-Sep-08" description="This release brings a number of new features and bug fixes!">
|
<release version="0.6" date="2014-Sep-08" description="This release brings a number of new features and bug fixes!">
|
||||||
<!--
|
<!--
|
||||||
|
|
|
@ -201,6 +201,9 @@ public class FhirContext {
|
||||||
* Create and return a new JSON parser.
|
* Create and return a new JSON parser.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
|
* Thread safety: <b>Parsers are not guaranteed to be thread safe</b>. Create a new parser instance for every thread or every message being parsed/encoded.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
* Performance Note: <b>This method is cheap</b> to call, and may be called once for every message being processed without incurring any performance penalty
|
* Performance Note: <b>This method is cheap</b> to call, and may be called once for every message being processed without incurring any performance penalty
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
|
@ -261,6 +264,9 @@ public class FhirContext {
|
||||||
* Create and return a new XML parser.
|
* Create and return a new XML parser.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
|
* Thread safety: <b>Parsers are not guaranteed to be thread safe</b>. Create a new parser instance for every thread or every message being parsed/encoded.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
* Performance Note: <b>This method is cheap</b> to call, and may be called once for every message being processed without incurring any performance penalty
|
* Performance Note: <b>This method is cheap</b> to call, and may be called once for every message being processed without incurring any performance penalty
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -25,7 +25,9 @@ import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.IdentityHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -45,29 +47,60 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
|
||||||
public abstract class BaseParser implements IParser {
|
public abstract class BaseParser implements IParser {
|
||||||
|
|
||||||
private boolean mySuppressNarratives;
|
private ContainedResources myContainedResources;
|
||||||
private FhirContext myContext;
|
private FhirContext myContext;
|
||||||
|
private boolean mySuppressNarratives;
|
||||||
|
|
||||||
public BaseParser(FhirContext theContext) {
|
public BaseParser(FhirContext theContext) {
|
||||||
myContext = theContext;
|
myContext = theContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void containResourcesForEncoding(ContainedResources theContained, IResource theResource, IResource theTarget) {
|
||||||
public TagList parseTagList(String theString) {
|
List<ResourceReferenceDt> allElements = myContext.newTerser().getAllPopulatedChildElementsOfType(theResource, ResourceReferenceDt.class);
|
||||||
return parseTagList(new StringReader(theString));
|
|
||||||
|
Set<String> allIds = new HashSet<String>();
|
||||||
|
|
||||||
|
for (IResource next : theTarget.getContained().getContainedResources()) {
|
||||||
|
String nextId = next.getId().getValue();
|
||||||
|
if (StringUtils.isNotBlank(nextId)) {
|
||||||
|
allIds.add(nextId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ResourceReferenceDt next : allElements) {
|
||||||
|
IResource resource = next.getResource();
|
||||||
|
if (resource != null) {
|
||||||
|
if (resource.getId().isEmpty()) {
|
||||||
|
theContained.addContained(resource);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
containResourcesForEncoding(theContained, resource, theTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("cast")
|
public void containResourcesForEncoding(IResource theResource) {
|
||||||
@Override
|
ContainedResources contained = new ContainedResources();
|
||||||
public <T extends IResource> T parseResource(Class<T> theResourceType, String theMessageString) {
|
containResourcesForEncoding(contained, theResource, theResource);
|
||||||
StringReader reader = new StringReader(theMessageString);
|
myContainedResources = contained;
|
||||||
return (T) parseResource(theResourceType, reader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Bundle parseBundle(String theXml) throws ConfigurationException, DataFormatException {
|
public String encodeBundleToString(Bundle theBundle) throws DataFormatException {
|
||||||
StringReader reader = new StringReader(theXml);
|
if (theBundle == null) {
|
||||||
return parseBundle(reader);
|
throw new NullPointerException("Bundle can not be null");
|
||||||
|
}
|
||||||
|
StringWriter stringWriter = new StringWriter();
|
||||||
|
try {
|
||||||
|
encodeBundleToWriter(theBundle, stringWriter);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error("Encountered IOException during write to string - This should not happen!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringWriter.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -92,24 +125,15 @@ public abstract class BaseParser implements IParser {
|
||||||
return stringWriter.toString();
|
return stringWriter.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
ContainedResources getContainedResources() {
|
||||||
public String encodeBundleToString(Bundle theBundle) throws DataFormatException {
|
return myContainedResources;
|
||||||
if (theBundle == null) {
|
|
||||||
throw new NullPointerException("Bundle can not be null");
|
|
||||||
}
|
|
||||||
StringWriter stringWriter = new StringWriter();
|
|
||||||
try {
|
|
||||||
encodeBundleToWriter(theBundle, stringWriter);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new Error("Encountered IOException during write to string - This should not happen!");
|
|
||||||
}
|
|
||||||
|
|
||||||
return stringWriter.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public IResource parseResource(String theMessageString) throws ConfigurationException, DataFormatException {
|
* If set to <code>true</code> (default is <code>false</code>), narratives will not be included in the encoded values.
|
||||||
return parseResource(null, theMessageString);
|
*/
|
||||||
|
public boolean getSuppressNarratives() {
|
||||||
|
return mySuppressNarratives;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -117,49 +141,38 @@ public abstract class BaseParser implements IParser {
|
||||||
return parseBundle(null, theReader);
|
return parseBundle(null, theReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bundle parseBundle(String theXml) throws ConfigurationException, DataFormatException {
|
||||||
|
StringReader reader = new StringReader(theXml);
|
||||||
|
return parseBundle(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("cast")
|
||||||
|
@Override
|
||||||
|
public <T extends IResource> T parseResource(Class<T> theResourceType, String theMessageString) {
|
||||||
|
StringReader reader = new StringReader(theMessageString);
|
||||||
|
return (T) parseResource(theResourceType, reader);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IResource parseResource(Reader theReader) throws ConfigurationException, DataFormatException {
|
public IResource parseResource(Reader theReader) throws ConfigurationException, DataFormatException {
|
||||||
return parseResource(null, theReader);
|
return parseResource(null, theReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void containResourcesForEncoding(IResource theResource) {
|
@Override
|
||||||
containResourcesForEncoding(theResource, theResource);
|
public IResource parseResource(String theMessageString) throws ConfigurationException, DataFormatException {
|
||||||
|
return parseResource(null, theMessageString);
|
||||||
}
|
}
|
||||||
|
|
||||||
private long myNextContainedId = 1;
|
@Override
|
||||||
|
public TagList parseTagList(String theString) {
|
||||||
private void containResourcesForEncoding(IResource theResource, IResource theTarget) {
|
return parseTagList(new StringReader(theString));
|
||||||
List<ResourceReferenceDt> allElements = myContext.newTerser().getAllPopulatedChildElementsOfType(theResource, ResourceReferenceDt.class);
|
}
|
||||||
|
|
||||||
Set<String> allIds = new HashSet<String>();
|
|
||||||
|
|
||||||
for (IResource next : theTarget.getContained().getContainedResources()) {
|
|
||||||
String nextId = next.getId().getValue();
|
|
||||||
if (StringUtils.isNotBlank(nextId)) {
|
|
||||||
allIds.add(nextId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ResourceReferenceDt next : allElements) {
|
|
||||||
IResource resource = next.getResource();
|
|
||||||
if (resource != null) {
|
|
||||||
if (resource.getId().isEmpty()) { // TODO: make this configurable between the two below (and something else?)
|
|
||||||
resource.setId(new IdDt(myNextContainedId++));
|
|
||||||
// resource.setId(new IdDt(UUID.randomUUID().toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
String nextResourceId = resource.getId().getValue();
|
|
||||||
if (!allIds.contains(nextResourceId)) {
|
|
||||||
theTarget.getContained().getContainedResources().add(resource);
|
|
||||||
allIds.add(resource.getId().getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
next.setReference("#" + resource.getId().getValue());
|
|
||||||
|
|
||||||
containResourcesForEncoding(resource, theTarget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IParser setSuppressNarratives(boolean theSuppressNarratives) {
|
||||||
|
mySuppressNarratives = theSuppressNarratives;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void throwExceptionForUnknownChildType(BaseRuntimeChildDefinition nextChild, Class<? extends IElement> type) {
|
protected void throwExceptionForUnknownChildType(BaseRuntimeChildDefinition nextChild, Class<? extends IElement> type) {
|
||||||
|
@ -178,18 +191,37 @@ public abstract class BaseParser implements IParser {
|
||||||
throw new DataFormatException(nextChild + " has no child of type " + type);
|
throw new DataFormatException(nextChild + " has no child of type " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
static class ContainedResources {
|
||||||
public IParser setSuppressNarratives(boolean theSuppressNarratives) {
|
private long myNextContainedId = 1;
|
||||||
mySuppressNarratives = theSuppressNarratives;
|
|
||||||
return this;
|
private IdentityHashMap<IResource, IdDt> myResourceToId = new IdentityHashMap<IResource, IdDt>();
|
||||||
}
|
private List<IResource> myResources = new ArrayList<IResource>();
|
||||||
|
|
||||||
|
public void addContained(IResource theResource) {
|
||||||
|
if (myResourceToId.containsKey(theResource)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: make this configurable between the two below (and something else?)
|
||||||
|
IdDt newId = new IdDt(myNextContainedId++);
|
||||||
|
// newId = new IdDt(UUID.randomUUID().toString());
|
||||||
|
|
||||||
|
myResourceToId.put(theResource, newId);
|
||||||
|
myResources.add(theResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IResource> getContainedResources() {
|
||||||
|
return myResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdDt getResourceId(IResource theResource) {
|
||||||
|
return myResourceToId.get(theResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return myResourceToId.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* If set to <code>true</code> (default is <code>false</code>), narratives
|
|
||||||
* will not be included in the encoded values.
|
|
||||||
*/
|
|
||||||
public boolean getSuppressNarratives() {
|
|
||||||
return mySuppressNarratives;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,12 @@ import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.api.TagList;
|
import ca.uhn.fhir.model.api.TagList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Thread safety: <b>Parsers are not guaranteed to be thread safe</b>. Create a new parser instance for every thread or every message being parsed/encoded.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
public interface IParser {
|
public interface IParser {
|
||||||
|
|
||||||
String encodeBundleToString(Bundle theBundle) throws DataFormatException;
|
String encodeBundleToString(Bundle theBundle) throws DataFormatException;
|
||||||
|
@ -40,26 +46,24 @@ public interface IParser {
|
||||||
void encodeResourceToWriter(IResource theResource, Writer theWriter) throws IOException, DataFormatException;
|
void encodeResourceToWriter(IResource theResource, Writer theWriter) throws IOException, DataFormatException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encodes a tag list, as defined in the <a
|
* Encodes a tag list, as defined in the <a href="http://hl7.org/implement/standards/fhir/http.html#tags">FHIR Specification</a>.
|
||||||
* href="http://hl7.org/implement/standards/fhir/http.html#tags">FHIR
|
|
||||||
* Specification</a>.
|
|
||||||
*
|
*
|
||||||
* @param theTagList The tag list to encode. Must not be null.
|
* @param theTagList
|
||||||
|
* The tag list to encode. Must not be null.
|
||||||
* @return An encoded tag list
|
* @return An encoded tag list
|
||||||
*/
|
*/
|
||||||
String encodeTagListToString(TagList theTagList);
|
String encodeTagListToString(TagList theTagList);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encodes a tag list, as defined in the <a
|
* Encodes a tag list, as defined in the <a href="http://hl7.org/implement/standards/fhir/http.html#tags">FHIR Specification</a>.
|
||||||
* href="http://hl7.org/implement/standards/fhir/http.html#tags">FHIR
|
|
||||||
* Specification</a>.
|
|
||||||
*
|
*
|
||||||
* @param theTagList The tag list to encode. Must not be null.
|
* @param theTagList
|
||||||
* @param theWriter The writer to encode to
|
* The tag list to encode. Must not be null.
|
||||||
|
* @param theWriter
|
||||||
|
* The writer to encode to
|
||||||
*/
|
*/
|
||||||
void encodeTagListToWriter(TagList theTagList, Writer theWriter) throws IOException;
|
void encodeTagListToWriter(TagList theTagList, Writer theWriter) throws IOException;
|
||||||
|
|
||||||
|
|
||||||
<T extends IResource> Bundle parseBundle(Class<T> theResourceType, Reader theReader);
|
<T extends IResource> Bundle parseBundle(Class<T> theResourceType, Reader theReader);
|
||||||
|
|
||||||
Bundle parseBundle(Reader theReader);
|
Bundle parseBundle(Reader theReader);
|
||||||
|
@ -70,15 +74,12 @@ public interface IParser {
|
||||||
* Parses a resource
|
* Parses a resource
|
||||||
*
|
*
|
||||||
* @param theResourceType
|
* @param theResourceType
|
||||||
* The resource type to use. This can be used to explicitly
|
* 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)
|
||||||
* specify a class which extends a built-in type (e.g. a custom
|
|
||||||
* type extending the default Patient class)
|
|
||||||
* @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
|
* @return A parsed resource
|
||||||
* @throws DataFormatException
|
* @throws DataFormatException
|
||||||
* If the resource can not be parsed because the data is not
|
* If the resource can not be parsed because the data is not recognized or invalid for any reason
|
||||||
* recognized or invalid for any reason
|
|
||||||
*/
|
*/
|
||||||
<T extends IResource> T parseResource(Class<T> theResourceType, Reader theReader) throws DataFormatException;
|
<T extends IResource> T parseResource(Class<T> theResourceType, Reader theReader) throws DataFormatException;
|
||||||
|
|
||||||
|
@ -86,15 +87,12 @@ public interface IParser {
|
||||||
* Parses a resource
|
* Parses a resource
|
||||||
*
|
*
|
||||||
* @param theResourceType
|
* @param theResourceType
|
||||||
* The resource type to use. This can be used to explicitly
|
* 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)
|
||||||
* specify a class which extends a built-in type (e.g. a custom
|
|
||||||
* type extending the default Patient class)
|
|
||||||
* @param theString
|
* @param theString
|
||||||
* The string to parse
|
* 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
|
* If the resource can not be parsed because the data is not recognized or invalid for any reason
|
||||||
* recognized or invalid for any reason
|
|
||||||
*/
|
*/
|
||||||
<T extends IResource> T parseResource(Class<T> theResourceType, String theString) throws DataFormatException;
|
<T extends IResource> T parseResource(Class<T> theResourceType, String theString) throws DataFormatException;
|
||||||
|
|
||||||
|
@ -105,8 +103,7 @@ public interface IParser {
|
||||||
* 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
|
* @return A parsed resource
|
||||||
* @throws DataFormatException
|
* @throws DataFormatException
|
||||||
* If the resource can not be parsed because the data is not
|
* If the resource can not be parsed because the data is not recognized or invalid for any reason
|
||||||
* recognized or invalid for any reason
|
|
||||||
*/
|
*/
|
||||||
IResource parseResource(Reader theReader) throws ConfigurationException, DataFormatException;
|
IResource parseResource(Reader theReader) throws ConfigurationException, DataFormatException;
|
||||||
|
|
||||||
|
@ -117,15 +114,12 @@ public interface IParser {
|
||||||
* The string to parse
|
* 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
|
* If the resource can not be parsed because the data is not recognized or invalid for any reason
|
||||||
* recognized or invalid for any reason
|
|
||||||
*/
|
*/
|
||||||
IResource parseResource(String theMessageString) throws ConfigurationException, DataFormatException;
|
IResource parseResource(String theMessageString) throws ConfigurationException, DataFormatException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a tag list, as defined in the <a
|
* Parses a tag list, as defined in the <a href="http://hl7.org/implement/standards/fhir/http.html#tags">FHIR Specification</a>.
|
||||||
* href="http://hl7.org/implement/standards/fhir/http.html#tags">FHIR
|
|
||||||
* Specification</a>.
|
|
||||||
*
|
*
|
||||||
* @param theReader
|
* @param theReader
|
||||||
* A reader which will supply a tag list
|
* A reader which will supply a tag list
|
||||||
|
@ -134,9 +128,7 @@ public interface IParser {
|
||||||
TagList parseTagList(Reader theReader);
|
TagList parseTagList(Reader theReader);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a tag list, as defined in the <a
|
* Parses a tag list, as defined in the <a href="http://hl7.org/implement/standards/fhir/http.html#tags">FHIR Specification</a>.
|
||||||
* href="http://hl7.org/implement/standards/fhir/http.html#tags">FHIR
|
|
||||||
* Specification</a>.
|
|
||||||
*
|
*
|
||||||
* @param theString
|
* @param theString
|
||||||
* A string containing a tag list
|
* A string containing a tag list
|
||||||
|
@ -145,20 +137,16 @@ public interface IParser {
|
||||||
TagList parseTagList(String theString);
|
TagList parseTagList(String theString);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the "pretty print" flag, meaning that the parser will encode
|
* 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.
|
||||||
* resources with human-readable spacing and 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
|
* @return Returns an instance of <code>this</code> parser so that method calls can be conveniently chained
|
||||||
* calls can be conveniently chained
|
|
||||||
*/
|
*/
|
||||||
IParser setPrettyPrint(boolean thePrettyPrint);
|
IParser setPrettyPrint(boolean thePrettyPrint);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to <code>true</code> (default is <code>false</code>), narratives
|
* If set to <code>true</code> (default is <code>false</code>), narratives will not be included in the encoded values.
|
||||||
* will not be included in the encoded values.
|
|
||||||
*/
|
*/
|
||||||
IParser setSuppressNarratives(boolean theSuppressNarratives);
|
IParser setSuppressNarratives(boolean theSuppressNarratives);
|
||||||
|
|
||||||
|
|
|
@ -230,7 +230,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theWriter, IElement theValue, BaseRuntimeElementDefinition<?> theChildDef,
|
private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theWriter, IElement theValue, BaseRuntimeElementDefinition<?> theChildDef,
|
||||||
String theChildName) throws IOException {
|
String theChildName, boolean theIsSubElementWithinResource) throws IOException {
|
||||||
|
|
||||||
switch (theChildDef.getChildType()) {
|
switch (theChildDef.getChildType()) {
|
||||||
case PRIMITIVE_DATATYPE: {
|
case PRIMITIVE_DATATYPE: {
|
||||||
|
@ -278,7 +278,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
if (theValue instanceof ExtensionDt) {
|
if (theValue instanceof ExtensionDt) {
|
||||||
theWriter.write("url", ((ExtensionDt) theValue).getUrlAsString());
|
theWriter.write("url", ((ExtensionDt) theValue).getUrlAsString());
|
||||||
}
|
}
|
||||||
encodeCompositeElementToStreamWriter(theResDef, theResource, theValue, theWriter, childCompositeDef);
|
encodeCompositeElementToStreamWriter(theResDef, theResource, theValue, theWriter, childCompositeDef, theIsSubElementWithinResource);
|
||||||
theWriter.writeEnd();
|
theWriter.writeEnd();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -297,6 +297,16 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
reference = myContext.getResourceDefinition(value.getResourceType()).getName() + '/' + value.getIdPart();
|
reference = myContext.getResourceDefinition(value.getResourceType()).getName() + '/' + value.getIdPart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (StringUtils.isBlank(reference)) {
|
||||||
|
if (referenceDt.getResource() != null) {
|
||||||
|
IdDt containedId = getContainedResources().getResourceId(referenceDt.getResource());
|
||||||
|
if (containedId != null) {
|
||||||
|
reference = "#" + containedId.getValue();
|
||||||
|
} else if (referenceDt.getResource().getId() != null && referenceDt.getResource().getId().hasIdPart()) {
|
||||||
|
reference = referenceDt.getResource().getId().getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(reference)) {
|
if (StringUtils.isNotBlank(reference)) {
|
||||||
theWriter.write(XmlParser.RESREF_REFERENCE, reference);
|
theWriter.write(XmlParser.RESREF_REFERENCE, reference);
|
||||||
|
@ -313,6 +323,10 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
for (IResource next : value.getContainedResources()) {
|
for (IResource next : value.getContainedResources()) {
|
||||||
encodeResourceToJsonStreamWriter(theResDef, next, theWriter, null, true);
|
encodeResourceToJsonStreamWriter(theResDef, next, theWriter, null, true);
|
||||||
}
|
}
|
||||||
|
for (IResource next : getContainedResources().getContainedResources()) {
|
||||||
|
IdDt resourceId = getContainedResources().getResourceId(next);
|
||||||
|
encodeResourceToJsonStreamWriter(theResDef, next, theWriter, null, true, resourceId.getValue());
|
||||||
|
}
|
||||||
theWriter.writeEnd();
|
theWriter.writeEnd();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -341,7 +355,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, JsonGenerator theEventWriter,
|
private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, JsonGenerator theEventWriter,
|
||||||
List<? extends BaseRuntimeChildDefinition> theChildren) throws IOException {
|
List<? extends BaseRuntimeChildDefinition> theChildren, boolean theIsSubElementWithinResource) throws IOException {
|
||||||
for (BaseRuntimeChildDefinition nextChild : theChildren) {
|
for (BaseRuntimeChildDefinition nextChild : theChildren) {
|
||||||
if (nextChild instanceof RuntimeChildNarrativeDefinition) {
|
if (nextChild instanceof RuntimeChildNarrativeDefinition) {
|
||||||
INarrativeGenerator gen = myContext.getNarrativeGenerator();
|
INarrativeGenerator gen = myContext.getNarrativeGenerator();
|
||||||
|
@ -351,7 +365,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
|
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
|
||||||
String childName = nextChild.getChildNameByDatatype(child.getDatatype());
|
String childName = nextChild.getChildNameByDatatype(child.getDatatype());
|
||||||
BaseRuntimeElementDefinition<?> type = child.getChildByName(childName);
|
BaseRuntimeElementDefinition<?> type = child.getChildByName(childName);
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, narr, type, childName);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, narr, type, childName, theIsSubElementWithinResource);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -371,7 +385,13 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
int valueIdx = 0;
|
int valueIdx = 0;
|
||||||
for (IElement nextValue : values) {
|
for (IElement nextValue : values) {
|
||||||
if (nextValue == null || nextValue.isEmpty()) {
|
if (nextValue == null || nextValue.isEmpty()) {
|
||||||
continue;
|
if (nextValue instanceof ContainedDt) {
|
||||||
|
if (theIsSubElementWithinResource || getContainedResources().isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Class<? extends IElement> type = nextValue.getClass();
|
Class<? extends IElement> type = nextValue.getClass();
|
||||||
|
@ -382,6 +402,10 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
boolean primitive = childDef.getChildType() == ChildTypeEnum.PRIMITIVE_DATATYPE;
|
boolean primitive = childDef.getChildType() == ChildTypeEnum.PRIMITIVE_DATATYPE;
|
||||||
|
|
||||||
|
if (childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES && theIsSubElementWithinResource) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (nextChild instanceof RuntimeChildDeclaredExtensionDefinition) {
|
if (nextChild instanceof RuntimeChildDeclaredExtensionDefinition) {
|
||||||
// Don't encode extensions
|
// Don't encode extensions
|
||||||
// RuntimeChildDeclaredExtensionDefinition extDef = (RuntimeChildDeclaredExtensionDefinition) nextChild;
|
// RuntimeChildDeclaredExtensionDefinition extDef = (RuntimeChildDeclaredExtensionDefinition) nextChild;
|
||||||
|
@ -399,13 +423,13 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
if (nextChild.getMax() > 1 || nextChild.getMax() == Child.MAX_UNLIMITED) {
|
if (nextChild.getMax() > 1 || nextChild.getMax() == Child.MAX_UNLIMITED) {
|
||||||
theEventWriter.writeStartArray(childName);
|
theEventWriter.writeStartArray(childName);
|
||||||
inArray = true;
|
inArray = true;
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theIsSubElementWithinResource);
|
||||||
} else {
|
} else {
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, childName);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, childName, theIsSubElementWithinResource);
|
||||||
}
|
}
|
||||||
currentChildName = childName;
|
currentChildName = childName;
|
||||||
} else {
|
} else {
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theIsSubElementWithinResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextValue instanceof ISupportsUndeclaredExtensions && primitive) {
|
if (nextValue instanceof ISupportsUndeclaredExtensions && primitive) {
|
||||||
|
@ -453,14 +477,24 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeCompositeElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, JsonGenerator theEventWriter,
|
private void encodeCompositeElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, JsonGenerator theEventWriter,
|
||||||
BaseRuntimeElementCompositeDefinition<?> resDef) throws IOException, DataFormatException {
|
BaseRuntimeElementCompositeDefinition<?> resDef, boolean theIsSubElementWithinResource) throws IOException, DataFormatException {
|
||||||
extractAndWriteExtensionsAsDirectChild(theElement, theEventWriter, resDef, theResDef, theResource);
|
extractAndWriteExtensionsAsDirectChild(theElement, theEventWriter, resDef, theResDef, theResource);
|
||||||
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getExtensions());
|
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getExtensions(), theIsSubElementWithinResource);
|
||||||
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getChildren());
|
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getChildren(),theIsSubElementWithinResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull,
|
private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull,
|
||||||
boolean theIsSubElementWithinResource) throws IOException {
|
boolean theIsSubElementWithinResource) throws IOException {
|
||||||
|
String resourceId = null;
|
||||||
|
if (theIsSubElementWithinResource && StringUtils.isNotBlank(theResource.getId().getValue())) {
|
||||||
|
resourceId = theResource.getId().getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
encodeResourceToJsonStreamWriter(theResDef, theResource, theEventWriter, theObjectNameOrNull, theIsSubElementWithinResource, resourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull, boolean theIsSubElementWithinResource,
|
||||||
|
String theResourceId) throws IOException {
|
||||||
if (!theIsSubElementWithinResource) {
|
if (!theIsSubElementWithinResource) {
|
||||||
super.containResourcesForEncoding(theResource);
|
super.containResourcesForEncoding(theResource);
|
||||||
}
|
}
|
||||||
|
@ -474,8 +508,8 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
theEventWriter.write("resourceType", resDef.getName());
|
theEventWriter.write("resourceType", resDef.getName());
|
||||||
if (theIsSubElementWithinResource && theResource.getId() != null && isNotBlank(theResource.getId().getValue())) {
|
if (theResourceId != null) {
|
||||||
theEventWriter.write("id", theResource.getId().getValue());
|
theEventWriter.write("id", theResourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theResource instanceof Binary) {
|
if (theResource instanceof Binary) {
|
||||||
|
@ -483,7 +517,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
theEventWriter.write("contentType", bin.getContentType());
|
theEventWriter.write("contentType", bin.getContentType());
|
||||||
theEventWriter.write("content", bin.getContentAsBase64());
|
theEventWriter.write("content", bin.getContentAsBase64());
|
||||||
} else {
|
} else {
|
||||||
encodeCompositeElementToStreamWriter(theResDef, theResource, theResource, theEventWriter, resDef);
|
encodeCompositeElementToStreamWriter(theResDef, theResource, theResource, theEventWriter, resDef, theIsSubElementWithinResource);
|
||||||
}
|
}
|
||||||
theEventWriter.writeEnd();
|
theEventWriter.writeEnd();
|
||||||
}
|
}
|
||||||
|
@ -972,7 +1006,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
// theEventWriter, myValue, def, "value" +
|
// theEventWriter, myValue, def, "value" +
|
||||||
// WordUtils.capitalize(def.getName()));
|
// WordUtils.capitalize(def.getName()));
|
||||||
String childName = myDef.getChildNameByDatatype(myValue.getClass());
|
String childName = myDef.getChildNameByDatatype(myValue.getClass());
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, myValue, def, childName);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, myValue, def, childName,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// theEventWriter.name(myUndeclaredExtension.get);
|
// theEventWriter.name(myUndeclaredExtension.get);
|
||||||
|
@ -1003,7 +1037,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
throw new ConfigurationException("Unable to encode extension, unregognized child element type: " + value.getClass().getCanonicalName());
|
throw new ConfigurationException("Unable to encode extension, unregognized child element type: " + value.getClass().getCanonicalName());
|
||||||
}
|
}
|
||||||
BaseRuntimeElementDefinition<?> childDef = extDef.getChildElementDefinitionByDatatype(value.getClass());
|
BaseRuntimeElementDefinition<?> childDef = extDef.getChildElementDefinitionByDatatype(value.getClass());
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, value, childDef, childName);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, value, childDef, childName,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// theEventWriter.name(myUndeclaredExtension.get);
|
// theEventWriter.name(myUndeclaredExtension.get);
|
||||||
|
|
|
@ -34,8 +34,6 @@ import java.util.List;
|
||||||
import javax.xml.namespace.QName;
|
import javax.xml.namespace.QName;
|
||||||
import javax.xml.stream.FactoryConfigurationError;
|
import javax.xml.stream.FactoryConfigurationError;
|
||||||
import javax.xml.stream.XMLEventReader;
|
import javax.xml.stream.XMLEventReader;
|
||||||
import javax.xml.stream.XMLInputFactory;
|
|
||||||
import javax.xml.stream.XMLOutputFactory;
|
|
||||||
import javax.xml.stream.XMLStreamConstants;
|
import javax.xml.stream.XMLStreamConstants;
|
||||||
import javax.xml.stream.XMLStreamException;
|
import javax.xml.stream.XMLStreamException;
|
||||||
import javax.xml.stream.XMLStreamWriter;
|
import javax.xml.stream.XMLStreamWriter;
|
||||||
|
@ -52,6 +50,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||||
|
import ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum;
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
|
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
|
||||||
|
@ -153,9 +152,9 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
eventWriter.writeNamespace("at", TOMBSTONES_NS);
|
eventWriter.writeNamespace("at", TOMBSTONES_NS);
|
||||||
eventWriter.writeAttribute("ref", nextEntry.getId().getValueAsString());
|
eventWriter.writeAttribute("ref", nextEntry.getId().getValueAsString());
|
||||||
eventWriter.writeAttribute("when", nextEntry.getDeletedAt().getValueAsString());
|
eventWriter.writeAttribute("when", nextEntry.getDeletedAt().getValueAsString());
|
||||||
if (nextEntry.getDeletedByEmail().isEmpty() == false || nextEntry.getDeletedByName().isEmpty()==false) {
|
if (nextEntry.getDeletedByEmail().isEmpty() == false || nextEntry.getDeletedByName().isEmpty() == false) {
|
||||||
eventWriter.writeStartElement(TOMBSTONES_NS, "by");
|
eventWriter.writeStartElement(TOMBSTONES_NS, "by");
|
||||||
if (nextEntry.getDeletedByName().isEmpty()==false) {
|
if (nextEntry.getDeletedByName().isEmpty() == false) {
|
||||||
eventWriter.writeStartElement(TOMBSTONES_NS, "name");
|
eventWriter.writeStartElement(TOMBSTONES_NS, "name");
|
||||||
eventWriter.writeCharacters(nextEntry.getDeletedByName().getValue());
|
eventWriter.writeCharacters(nextEntry.getDeletedByName().getValue());
|
||||||
eventWriter.writeEndElement();
|
eventWriter.writeEndElement();
|
||||||
|
@ -167,7 +166,7 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
eventWriter.writeEndElement();
|
eventWriter.writeEndElement();
|
||||||
}
|
}
|
||||||
if (nextEntry.getDeletedComment().isEmpty()==false) {
|
if (nextEntry.getDeletedComment().isEmpty() == false) {
|
||||||
eventWriter.writeStartElement(TOMBSTONES_NS, "comment");
|
eventWriter.writeStartElement(TOMBSTONES_NS, "comment");
|
||||||
eventWriter.writeCharacters(nextEntry.getDeletedComment().getValue());
|
eventWriter.writeCharacters(nextEntry.getDeletedComment().getValue());
|
||||||
eventWriter.writeEndElement();
|
eventWriter.writeEndElement();
|
||||||
|
@ -206,14 +205,13 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
} else {
|
} else {
|
||||||
ourLog.debug("Bundle entry contains null resource");
|
ourLog.debug("Bundle entry contains null resource");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nextEntry.getSummary().isEmpty()) {
|
if (!nextEntry.getSummary().isEmpty()) {
|
||||||
eventWriter.writeStartElement("summary");
|
eventWriter.writeStartElement("summary");
|
||||||
eventWriter.writeAttribute("type", "xhtml");
|
eventWriter.writeAttribute("type", "xhtml");
|
||||||
encodeXhtml(nextEntry.getSummary(), eventWriter);
|
encodeXhtml(nextEntry.getSummary(), eventWriter);
|
||||||
eventWriter.writeEndElement();
|
eventWriter.writeEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
eventWriter.writeEndElement(); // entry
|
eventWriter.writeEndElement(); // entry
|
||||||
}
|
}
|
||||||
|
@ -225,7 +223,7 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeCategories(XMLStreamWriter eventWriter, TagList categories) throws XMLStreamException {
|
private void writeCategories(XMLStreamWriter eventWriter, TagList categories) throws XMLStreamException {
|
||||||
if (categories != null) {
|
if (categories != null) {
|
||||||
for (Tag next : categories) {
|
for (Tag next : categories) {
|
||||||
eventWriter.writeStartElement("category");
|
eventWriter.writeStartElement("category");
|
||||||
|
@ -335,16 +333,16 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
} catch (XMLStreamException e1) {
|
} catch (XMLStreamException e1) {
|
||||||
throw new DataFormatException(e1);
|
throw new DataFormatException(e1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// XMLEventReader streamReader;
|
// XMLEventReader streamReader;
|
||||||
// try {
|
// try {
|
||||||
// streamReader = myXmlInputFactory.createXMLEventReader(theReader);
|
// streamReader = myXmlInputFactory.createXMLEventReader(theReader);
|
||||||
// } catch (XMLStreamException e) {
|
// } catch (XMLStreamException e) {
|
||||||
// throw new DataFormatException(e);
|
// throw new DataFormatException(e);
|
||||||
// } catch (FactoryConfigurationError e) {
|
// } catch (FactoryConfigurationError e) {
|
||||||
// throw new ConfigurationException("Failed to initialize STaX event factory", e);
|
// throw new ConfigurationException("Failed to initialize STaX event factory", e);
|
||||||
// }
|
// }
|
||||||
// return streamReader;
|
// return streamReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
private XMLStreamWriter decorateStreamWriter(XMLStreamWriter eventWriter) {
|
private XMLStreamWriter decorateStreamWriter(XMLStreamWriter eventWriter) {
|
||||||
|
@ -426,7 +424,11 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, XMLStreamWriter theEventWriter, IElement nextValue, String childName,
|
private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, XMLStreamWriter theEventWriter, IElement nextValue, String childName,
|
||||||
BaseRuntimeElementDefinition<?> childDef, String theExtensionUrl, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
|
BaseRuntimeElementDefinition<?> childDef, String theExtensionUrl, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
|
||||||
if (nextValue.isEmpty()) {
|
if (nextValue.isEmpty()) {
|
||||||
return;
|
if (childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES && getContainedResources().isEmpty()==false && theIncludedResource == false) {
|
||||||
|
// We still want to go in..
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (childDef.getChildType()) {
|
switch (childDef.getChildType()) {
|
||||||
|
@ -467,6 +469,10 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
for (IResource next : value.getContainedResources()) {
|
for (IResource next : value.getContainedResources()) {
|
||||||
encodeResourceToXmlStreamWriter(next, theEventWriter, true);
|
encodeResourceToXmlStreamWriter(next, theEventWriter, true);
|
||||||
}
|
}
|
||||||
|
for (IResource next : getContainedResources().getContainedResources()) {
|
||||||
|
IdDt resourceId = getContainedResources().getResourceId(next);
|
||||||
|
encodeResourceToXmlStreamWriter(next, theEventWriter, true, resourceId.getValue());
|
||||||
|
}
|
||||||
theEventWriter.writeEndElement();
|
theEventWriter.writeEndElement();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -512,7 +518,7 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IElement nextValue : values) {
|
for (IElement nextValue : values) {
|
||||||
if (nextValue == null || nextValue.isEmpty()) {
|
if ((nextValue == null || nextValue.isEmpty()) && !(nextValue instanceof ContainedDt)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Class<? extends IElement> type = nextValue.getClass();
|
Class<? extends IElement> type = nextValue.getClass();
|
||||||
|
@ -570,6 +576,17 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
if (isBlank(reference)) {
|
||||||
|
if (theRef.getResource() != null) {
|
||||||
|
IdDt containedId = getContainedResources().getResourceId(theRef.getResource());
|
||||||
|
if (containedId != null) {
|
||||||
|
reference = "#" + containedId.getValue();
|
||||||
|
} else if (theRef.getResource().getId() != null && theRef.getResource().getId().hasIdPart()) {
|
||||||
|
reference = theRef.getResource().getId().getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(reference)) {
|
if (StringUtils.isNotBlank(reference)) {
|
||||||
theEventWriter.writeStartElement(RESREF_REFERENCE);
|
theEventWriter.writeStartElement(RESREF_REFERENCE);
|
||||||
theEventWriter.writeAttribute("value", reference);
|
theEventWriter.writeAttribute("value", reference);
|
||||||
|
@ -582,12 +599,16 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param theIncludedResource
|
|
||||||
* Set to true only if this resource is an "included" resource, as opposed to a "root level" resource by itself or in a bundle entry
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private void encodeResourceToXmlStreamWriter(IResource theResource, XMLStreamWriter theEventWriter, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
|
private void encodeResourceToXmlStreamWriter(IResource theResource, XMLStreamWriter theEventWriter, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
|
||||||
|
String resourceId = null;
|
||||||
|
if (theIncludedResource && StringUtils.isNotBlank(theResource.getId().getValue())) {
|
||||||
|
resourceId = theResource.getId().getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
encodeResourceToXmlStreamWriter(theResource, theEventWriter, theIncludedResource, resourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void encodeResourceToXmlStreamWriter(IResource theResource, XMLStreamWriter theEventWriter, boolean theIncludedResource, String theResourceId) throws XMLStreamException {
|
||||||
if (!theIncludedResource) {
|
if (!theIncludedResource) {
|
||||||
super.containResourcesForEncoding(theResource);
|
super.containResourcesForEncoding(theResource);
|
||||||
}
|
}
|
||||||
|
@ -600,8 +621,8 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
theEventWriter.writeStartElement(resDef.getName());
|
theEventWriter.writeStartElement(resDef.getName());
|
||||||
theEventWriter.writeDefaultNamespace(FHIR_NS);
|
theEventWriter.writeDefaultNamespace(FHIR_NS);
|
||||||
|
|
||||||
if (theIncludedResource && StringUtils.isNotBlank(theResource.getId().getValue())) {
|
if (theResourceId != null) {
|
||||||
theEventWriter.writeAttribute("id", theResource.getId().getValue());
|
theEventWriter.writeAttribute("id", theResourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theResource instanceof Binary) {
|
if (theResource instanceof Binary) {
|
||||||
|
|
|
@ -159,13 +159,13 @@ public class TokenParam extends BaseParam implements IQueryParameterType {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||||
builder.append("system", defaultString(getValue()));
|
builder.append("system", defaultString(getSystem()));
|
||||||
builder.append("value", getValue());
|
builder.append("value", getValue());
|
||||||
if (myText) {
|
if (myText) {
|
||||||
builder.append("text", myText);
|
builder.append(":text", myText);
|
||||||
}
|
}
|
||||||
if (getMissing() != null) {
|
if (getMissing() != null) {
|
||||||
builder.append("missing", getMissing());
|
builder.append(":missing", getMissing());
|
||||||
}
|
}
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,13 +72,15 @@ public class UnprocessableEntityException extends BaseServerResponseException {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OperationOutcome toOperationOutcome(String... theMessage) {
|
private static OperationOutcome toOperationOutcome(String... theMessage) {
|
||||||
OperationOutcome operationOutcome = new OperationOutcome();
|
OperationOutcome OperationOutcome = new OperationOutcome();
|
||||||
if (theMessage != null) {
|
if (theMessage != null) {
|
||||||
for (String next : theMessage) {
|
for (String next : theMessage) {
|
||||||
operationOutcome.addIssue().setDetails(next);
|
OperationOutcome.addIssue().setDetails(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return operationOutcome;
|
return OperationOutcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,31 +103,109 @@ patient.getManagingOrganization().setReference("Organization/124362");]]></sourc
|
||||||
<p>
|
<p>
|
||||||
In the following example, the Organization resource has an ID set, so it will not
|
In the following example, the Organization resource has an ID set, so it will not
|
||||||
be contained but will rather appear as a distinct entry in any returned
|
be contained but will rather appear as a distinct entry in any returned
|
||||||
bundles.
|
bundles. Both resources are added to a bundle, which will then have
|
||||||
|
two entries:
|
||||||
</p>
|
</p>
|
||||||
<source><![CDATA[Organization org = new Organization();
|
<source><![CDATA[// Create an organization
|
||||||
|
Organization org = new Organization();
|
||||||
org.setId("Organization/65546");
|
org.setId("Organization/65546");
|
||||||
org.getName().setValue("Contained Test Organization");
|
org.getName().setValue("Contained Test Organization");
|
||||||
|
|
||||||
|
// Create a patient
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.setId("Patient/1333");
|
patient.setId("Patient/1333");
|
||||||
patient.addIdentifier("urn:mrns", "253345");
|
patient.addIdentifier("urn:mrns", "253345");
|
||||||
patient.getManagingOrganization().setResource(patient);]]></source>
|
patient.getManagingOrganization().setResource(org);
|
||||||
|
|
||||||
|
// Create a list containing both resources. In a server method, you might just
|
||||||
|
// return this list, but here we will create a bundle to encode.
|
||||||
|
List<IResource> resources = new ArrayList<IResource>();
|
||||||
|
resources.add(org);
|
||||||
|
resources.add(patient);
|
||||||
|
|
||||||
|
// Create a bundle with both
|
||||||
|
Bundle b = Bundle.withResources(resources, ourCtx, "http://example.com/base");
|
||||||
|
|
||||||
|
// Encode the buntdle
|
||||||
|
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(b);
|
||||||
|
System.out.println(encoded);]]></source>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This will give the following output:
|
||||||
|
</p>
|
||||||
|
<source><![CDATA[<feed xmlns="http://www.w3.org/2005/Atom">
|
||||||
|
<entry>
|
||||||
|
<title>Organization Organization/65546</title>
|
||||||
|
<id>http://example.com/base/Organization/65546</id>
|
||||||
|
<published>2014-10-14T09:22:54-04:00</published>
|
||||||
|
<link rel="self" href="http://example.com/base/Organization/65546"/>
|
||||||
|
<content type="text/xml">
|
||||||
|
<Organization xmlns="http://hl7.org/fhir">
|
||||||
|
<name value="Contained Test Organization"/>
|
||||||
|
</Organization>
|
||||||
|
</content>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<title>Patient Patient/1333</title>
|
||||||
|
<id>http://example.com/base/Patient/1333</id>
|
||||||
|
<published>2014-10-14T09:22:54-04:00</published>
|
||||||
|
<link rel="self" href="http://example.com/base/Patient/1333"/>
|
||||||
|
<content type="text/xml">
|
||||||
|
<Patient xmlns="http://hl7.org/fhir">
|
||||||
|
<identifier>
|
||||||
|
<system value="urn:mrns"/>
|
||||||
|
<value value="253345"/>
|
||||||
|
</identifier>
|
||||||
|
<managingOrganization>
|
||||||
|
<reference value="Organization/65546"/>
|
||||||
|
</managingOrganization>
|
||||||
|
</Patient>
|
||||||
|
</content>
|
||||||
|
</entry>
|
||||||
|
</feed>]]></source>
|
||||||
|
|
||||||
|
</subsection>
|
||||||
|
|
||||||
|
<subsection name="Contained Resources">
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
On the other hand, if the linked resource
|
On the other hand, if the linked resource
|
||||||
does not have an ID set, the linked resource will
|
does not have an ID set, the linked resource will
|
||||||
be included in the returned bundle as a "contained" resource. In this
|
be included in the returned bundle as a "contained" resource. In this
|
||||||
case, HAPI itself will define a local reference ID (e.g. "#001").
|
case, HAPI itself will define a local reference ID (e.g. "#1").
|
||||||
</p>
|
</p>
|
||||||
<source><![CDATA[Organization org = new Organization();
|
<source><![CDATA[// Create an organization, note that the organization does not have an ID
|
||||||
// org.setId("Organization/65546");
|
Organization org = new Organization();
|
||||||
org.getName().setValue("Normal (not contained) Test Organization");
|
org.getName().setValue("Contained Test Organization");
|
||||||
|
|
||||||
|
// Create a patient
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.setId("Patient/1333");
|
patient.setId("Patient/1333");
|
||||||
patient.addIdentifier("urn:mrns", "253345");
|
patient.addIdentifier("urn:mrns", "253345");
|
||||||
patient.getManagingOrganization().setResource(patient);]]></source>
|
|
||||||
|
// Put the organization as a reference in the patient resource
|
||||||
|
patient.getManagingOrganization().setResource(org);
|
||||||
|
|
||||||
|
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||||
|
System.out.println(encoded);]]></source>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This will give the following output:
|
||||||
|
</p>
|
||||||
|
<source><![CDATA[<Patient xmlns="http://hl7.org/fhir">
|
||||||
|
<contained>
|
||||||
|
<Organization xmlns="http://hl7.org/fhir" id="1">
|
||||||
|
<name value="Contained Test Organization"/>
|
||||||
|
</Organization>
|
||||||
|
</contained>
|
||||||
|
<identifier>
|
||||||
|
<system value="urn:mrns"/>
|
||||||
|
<value value="253345"/>
|
||||||
|
</identifier>
|
||||||
|
<managingOrganization>
|
||||||
|
<reference value="#1"/>
|
||||||
|
</managingOrganization>
|
||||||
|
</Patient>]]></source>
|
||||||
|
|
||||||
</subsection>
|
</subsection>
|
||||||
|
|
||||||
|
|
|
@ -133,11 +133,11 @@ public class ContainedResourceEncodingTest {
|
||||||
final String expectedCompXml = parser.encodeResourceToString(this.comp);
|
final String expectedCompXml = parser.encodeResourceToString(this.comp);
|
||||||
logger.debug("[xmlEncoding] first encoding: {}", expectedCompXml);
|
logger.debug("[xmlEncoding] first encoding: {}", expectedCompXml);
|
||||||
|
|
||||||
assertEquals(3, this.comp.getContained().getContainedResources().size());
|
assertEquals(0, this.comp.getContained().getContainedResources().size());
|
||||||
|
|
||||||
final String actualCompXml = parser.encodeResourceToString(this.comp);
|
final String actualCompXml = parser.encodeResourceToString(this.comp);
|
||||||
|
|
||||||
assertEquals(3, this.comp.getContained().getContainedResources().size());
|
assertEquals(0, this.comp.getContained().getContainedResources().size());
|
||||||
|
|
||||||
// second encoding - xml could not be parsed back to compositon - i.e.: patient content 4 times! should be the same
|
// second encoding - xml could not be parsed back to compositon - i.e.: patient content 4 times! should be the same
|
||||||
// as after first encoding!
|
// as after first encoding!
|
||||||
|
@ -145,7 +145,7 @@ public class ContainedResourceEncodingTest {
|
||||||
|
|
||||||
final String thirdCompXml = parser.encodeResourceToString(this.comp);
|
final String thirdCompXml = parser.encodeResourceToString(this.comp);
|
||||||
|
|
||||||
assertEquals(3, this.comp.getContained().getContainedResources().size());
|
assertEquals(0, this.comp.getContained().getContainedResources().size());
|
||||||
|
|
||||||
// third encoding - xml could not be parsed back to compositon i.e.: patient content 4 times! should be the same as
|
// third encoding - xml could not be parsed back to compositon i.e.: patient content 4 times! should be the same as
|
||||||
// afterfirst encoding!
|
// afterfirst encoding!
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.io.StringReader;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import net.sf.json.JSON;
|
import net.sf.json.JSON;
|
||||||
|
@ -88,6 +89,30 @@ public class JsonParserTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEncodeNonContained() {
|
||||||
|
Organization org = new Organization();
|
||||||
|
org.setId("Organization/65546");
|
||||||
|
org.getName().setValue("Contained Test Organization");
|
||||||
|
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.setId("Patient/1333");
|
||||||
|
patient.addIdentifier("urn:mrns", "253345");
|
||||||
|
patient.getManagingOrganization().setResource(org);
|
||||||
|
|
||||||
|
Bundle b = Bundle.withResources(Collections.singletonList((IResource)patient), ourCtx, "http://foo");
|
||||||
|
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeBundleToString(b);
|
||||||
|
ourLog.info(encoded);
|
||||||
|
assertThat(encoded, not(containsString("contained")));
|
||||||
|
assertThat(encoded, containsString("\"reference\":\"Organization/65546\""));
|
||||||
|
|
||||||
|
encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||||
|
ourLog.info(encoded);
|
||||||
|
assertThat(encoded, not(containsString("contained")));
|
||||||
|
assertThat(encoded, containsString("\"reference\":\"Organization/65546\""));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncodeIds() {
|
public void testEncodeIds() {
|
||||||
Patient pt =new Patient();
|
Patient pt =new Patient();
|
||||||
|
@ -437,6 +462,38 @@ public class JsonParserTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEncodeContained() {
|
||||||
|
// Create an organization
|
||||||
|
Organization org = new Organization();
|
||||||
|
org.getName().setValue("Contained Test Organization");
|
||||||
|
|
||||||
|
// Create a patient
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.setId("Patient/1333");
|
||||||
|
patient.addIdentifier("urn:mrns", "253345");
|
||||||
|
patient.getManagingOrganization().setResource(org);
|
||||||
|
|
||||||
|
// Create a bundle with just the patient resource
|
||||||
|
List<IResource> resources = new ArrayList<IResource>();
|
||||||
|
resources.add(patient);
|
||||||
|
Bundle b = Bundle.withResources(resources, ourCtx, "http://example.com/base");
|
||||||
|
|
||||||
|
// Encode the buntdle
|
||||||
|
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeBundleToString(b);
|
||||||
|
ourLog.info(encoded);
|
||||||
|
assertThat(encoded, stringContainsInOrder(Arrays.asList("\"contained\"", "resourceType\":\"Organization", "id\":\"1\"")));
|
||||||
|
assertThat(encoded, containsString("reference\":\"#1\""));
|
||||||
|
|
||||||
|
encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||||
|
ourLog.info(encoded);
|
||||||
|
assertThat(encoded, stringContainsInOrder(Arrays.asList("\"contained\"", "resourceType\":\"Organization", "id\":\"1\"")));
|
||||||
|
assertThat(encoded, containsString("reference\":\"#1\""));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncodeContainedResources() throws IOException {
|
public void testEncodeContainedResources() throws IOException {
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.io.StringReader;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -78,6 +79,77 @@ public class XmlParserTest {
|
||||||
System.setProperty("file.encoding", "ISO-8859-1");
|
System.setProperty("file.encoding", "ISO-8859-1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEncodeNonContained() {
|
||||||
|
// Create an organization
|
||||||
|
Organization org = new Organization();
|
||||||
|
org.setId("Organization/65546");
|
||||||
|
org.getName().setValue("Contained Test Organization");
|
||||||
|
|
||||||
|
// Create a patient
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.setId("Patient/1333");
|
||||||
|
patient.addIdentifier("urn:mrns", "253345");
|
||||||
|
patient.getManagingOrganization().setResource(org);
|
||||||
|
|
||||||
|
// Create a list containing both resources. In a server method, you might just
|
||||||
|
// return this list, but here we will create a bundle to encode.
|
||||||
|
List<IResource> resources = new ArrayList<IResource>();
|
||||||
|
resources.add(org);
|
||||||
|
resources.add(patient);
|
||||||
|
|
||||||
|
// Create a bundle with both
|
||||||
|
Bundle b = Bundle.withResources(resources, ourCtx, "http://example.com/base");
|
||||||
|
|
||||||
|
// Encode the buntdle
|
||||||
|
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(b);
|
||||||
|
ourLog.info(encoded);
|
||||||
|
assertThat(encoded, not(containsString("<contained>")));
|
||||||
|
assertThat(encoded, containsString("<reference value=\"Organization/65546\"/>"));
|
||||||
|
|
||||||
|
encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||||
|
ourLog.info(encoded);
|
||||||
|
assertThat(encoded, not(containsString("<contained>")));
|
||||||
|
assertThat(encoded, containsString("<reference value=\"Organization/65546\"/>"));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEncodeContained() {
|
||||||
|
// Create an organization, note that the organization does not have an ID
|
||||||
|
Organization org = new Organization();
|
||||||
|
org.getName().setValue("Contained Test Organization");
|
||||||
|
|
||||||
|
// Create a patient
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.setId("Patient/1333");
|
||||||
|
patient.addIdentifier("urn:mrns", "253345");
|
||||||
|
|
||||||
|
// Put the organization as a reference in the patient resource
|
||||||
|
patient.getManagingOrganization().setResource(org);
|
||||||
|
|
||||||
|
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||||
|
ourLog.info(encoded);
|
||||||
|
assertThat(encoded, containsString("<contained>"));
|
||||||
|
assertThat(encoded, containsString("<reference value=\"#1\"/>"));
|
||||||
|
|
||||||
|
// Create a bundle with just the patient resource
|
||||||
|
List<IResource> resources = new ArrayList<IResource>();
|
||||||
|
resources.add(patient);
|
||||||
|
Bundle b = Bundle.withResources(resources, ourCtx, "http://example.com/base");
|
||||||
|
|
||||||
|
// Encode the buntdle
|
||||||
|
encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(b);
|
||||||
|
ourLog.info(encoded);
|
||||||
|
assertThat(encoded, containsString("<contained>"));
|
||||||
|
assertThat(encoded, containsString("<reference value=\"#1\"/>"));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thanks to Alexander Kley!
|
* Thanks to Alexander Kley!
|
||||||
*/
|
*/
|
||||||
|
@ -85,9 +157,9 @@ public class XmlParserTest {
|
||||||
public void testParseContainedBinaryResource() {
|
public void testParseContainedBinaryResource() {
|
||||||
byte[] bin = new byte[] {0,1,2,3,4};
|
byte[] bin = new byte[] {0,1,2,3,4};
|
||||||
final Binary binary = new Binary("PatientConsent", bin);
|
final Binary binary = new Binary("PatientConsent", bin);
|
||||||
binary.setId(UUID.randomUUID().toString());
|
// binary.setId(UUID.randomUUID().toString());
|
||||||
DocumentManifest manifest = new DocumentManifest();
|
DocumentManifest manifest = new DocumentManifest();
|
||||||
manifest.setId(UUID.randomUUID().toString());
|
// manifest.setId(UUID.randomUUID().toString());
|
||||||
manifest.setType(new CodeableConceptDt("mySystem", "PatientDocument"));
|
manifest.setType(new CodeableConceptDt("mySystem", "PatientDocument"));
|
||||||
manifest.setMasterIdentifier("mySystem", UUID.randomUUID().toString());
|
manifest.setMasterIdentifier("mySystem", UUID.randomUUID().toString());
|
||||||
manifest.addContent().setResource(binary);
|
manifest.addContent().setResource(binary);
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
package ca.uhn.fhir.rest.server;
|
package ca.uhn.fhir.rest.server;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -25,6 +26,8 @@ import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.google.common.net.UrlEscapers;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
@ -42,6 +45,7 @@ import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||||
import ca.uhn.fhir.rest.param.StringOrListParam;
|
import ca.uhn.fhir.rest.param.StringOrListParam;
|
||||||
import ca.uhn.fhir.rest.param.StringParam;
|
import ca.uhn.fhir.rest.param.StringParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
||||||
|
import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
import ca.uhn.fhir.util.PortUtil;
|
import ca.uhn.fhir.util.PortUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,6 +125,23 @@ public class SearchTest {
|
||||||
assertEquals("bbb", p.getIdentifier().get(1).getValue().getValue());
|
assertEquals("bbb", p.getIdentifier().get(1).getValue().getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchWithTokenParameter() throws Exception {
|
||||||
|
String token = UrlEscapers.urlFragmentEscaper().asFunction().apply("http://www.dmix.gov/vista/2957|301");
|
||||||
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?tokenParam="+token);
|
||||||
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
|
||||||
|
assertEquals(1, bundle.getEntries().size());
|
||||||
|
|
||||||
|
Patient p = bundle.getResources(Patient.class).get(0);
|
||||||
|
assertEquals("http://www.dmix.gov/vista/2957", p.getNameFirstRep().getFamilyAsSingleString());
|
||||||
|
assertEquals("301", p.getNameFirstRep().getGivenAsSingleString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchByPost() throws Exception {
|
public void testSearchByPost() throws Exception {
|
||||||
HttpPost filePost = new HttpPost("http://localhost:" + ourPort + "/Patient/_search");
|
HttpPost filePost = new HttpPost("http://localhost:" + ourPort + "/Patient/_search");
|
||||||
|
@ -325,6 +346,18 @@ public class SearchTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Search()
|
||||||
|
public List<Patient> findPatientWithToken(@RequiredParam(name = "tokenParam") TokenParam theParam) {
|
||||||
|
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||||
|
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.setId("1");
|
||||||
|
patient.addName().addFamily(theParam.getSystem()).addGiven(theParam.getValue());
|
||||||
|
retVal.add(patient);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Search(queryName = "findWithLinks")
|
@Search(queryName = "findWithLinks")
|
||||||
public List<Patient> findWithLinks() {
|
public List<Patient> findWithLinks() {
|
||||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||||
|
|
Loading…
Reference in New Issue