Omit extensions when encoding in summary mode (except for

CapabilityStatement)
This commit is contained in:
James Agnew 2019-07-11 16:28:50 -04:00
parent 0fb8db11a2
commit 32a8e1aead
7 changed files with 208 additions and 53 deletions

View File

@ -34,6 +34,7 @@ import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.hl7.fhir.instance.model.api.*;
import javax.annotation.Nullable;
import java.io.*;
import java.lang.reflect.Modifier;
import java.util.*;
@ -65,6 +66,7 @@ public abstract class BaseParser implements IParser {
private boolean mySummaryMode;
private boolean mySuppressNarratives;
private Set<String> myDontStripVersionsFromReferencesAtPaths;
/**
* Constructor
*/
@ -165,8 +167,6 @@ public abstract class BaseParser implements IParser {
myNext = null;
} else if (!myNext.shouldBeEncoded(theContainedResource)) {
myNext = null;
} else if (isSummaryMode() && !myNext.getDef().isSummary()) {
myNext = null;
} else if (myNext.getDef() instanceof RuntimeChildNarrativeDefinition) {
if (isSuppressNarratives() || isSummaryMode()) {
myNext = null;
@ -1004,7 +1004,7 @@ public abstract class BaseParser implements IParser {
private final RuntimeResourceDefinition myResDef;
private final EncodeContext myEncodeContext;
public CompositeChildElement(CompositeChildElement theParent, BaseRuntimeChildDefinition theDef, EncodeContext theEncodeContext) {
public CompositeChildElement(CompositeChildElement theParent, @Nullable BaseRuntimeChildDefinition theDef, EncodeContext theEncodeContext) {
myDef = theDef;
myParent = theParent;
myResDef = null;
@ -1015,7 +1015,9 @@ public abstract class BaseParser implements IParser {
StringBuilder path = theParent.buildPath();
if (path != null) {
path.append('.');
path.append(myDef.getElementName());
if (myDef != null) {
path.append(myDef.getElementName());
}
ourLog.trace(" * Next path: {}", path.toString());
}
}
@ -1165,6 +1167,21 @@ public abstract class BaseParser implements IParser {
if (theContainedResource) {
retVal = !notEncodeForContainedResource.contains(myDef.getElementName());
}
if (retVal && isSummaryMode() && (getDef() == null || !getDef().isSummary())) {
String resourceName = myEncodeContext.getLeafResourceName();
// Technically the spec says we shouldn't include extensions in CapabilityStatement
// but we will do so because there are people who depend on this behaviour, at least
// as of 2019-07. See
// https://github.com/smart-on-fhir/Swift-FHIR/issues/26
// for example.
if (("Conformance".equals(resourceName) || "CapabilityStatement".equals(resourceName)) &&
("extension".equals(myDef.getElementName()) || "extension".equals(myEncodeContext.getLeafElementName())
)) {
// skip
} else {
retVal = false;
}
}
return retVal;
}
@ -1183,7 +1200,7 @@ public abstract class BaseParser implements IParser {
@Override
public String toString() {
return myPath.stream().map(t->t.toString()).collect(Collectors.joining("."));
return myPath.stream().map(t -> t.toString()).collect(Collectors.joining("."));
}
protected List<EncodeContextPathElement> getPath() {
@ -1251,6 +1268,14 @@ public abstract class BaseParser implements IParser {
return myResourcePath;
}
public String getLeafElementName() {
return getPath().get(getPath().size() - 1).getName();
}
public String getLeafResourceName() {
return myResourcePath.get(myResourcePath.size() - 1).getName();
}
public String getLeafResourcePathFirstField() {
String retVal = null;
for (int i = getPath().size() - 1; i >= 0; i--) {

View File

@ -80,7 +80,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
theListToAddTo.add(null);
}
if (theListToAddTo.get(valueIdx) == null) {
theListToAddTo.set(valueIdx, new ArrayList<String>());
theListToAddTo.set(valueIdx, new ArrayList<>());
}
theListToAddTo.get(valueIdx).addAll(theCommentsToAdd);
return true;
@ -89,21 +89,34 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
}
private boolean addToHeldExtensions(int valueIdx, List<? extends IBaseExtension<?, ?>> ext, ArrayList<ArrayList<HeldExtension>> list, boolean theIsModifier, CompositeChildElement theChildElem,
CompositeChildElement theParent) {
CompositeChildElement theParent, EncodeContext theEncodeContext, boolean theContainedResource, IBase theContainingElement) {
boolean retVal = false;
if (ext.size() > 0) {
list.ensureCapacity(valueIdx);
while (list.size() <= valueIdx) {
list.add(null);
}
if (list.get(valueIdx) == null) {
list.set(valueIdx, new ArrayList<JsonParser.HeldExtension>());
}
Boolean encodeExtension = null;
for (IBaseExtension<?, ?> next : ext) {
list.get(valueIdx).add(new HeldExtension(next, theIsModifier, theChildElem, theParent));
// Make sure we respect _summary and _elements
if (encodeExtension == null) {
encodeExtension = isEncodeExtension(theParent, theEncodeContext, theContainedResource, theContainingElement);
}
if (encodeExtension) {
HeldExtension extension = new HeldExtension(next, theIsModifier, theChildElem, theParent);
list.ensureCapacity(valueIdx);
while (list.size() <= valueIdx) {
list.add(null);
}
ArrayList<HeldExtension> extensionList = list.get(valueIdx);
if (extensionList == null) {
extensionList = new ArrayList<>();
list.set(valueIdx, extensionList);
}
extensionList.add(extension);
retVal = true;
}
}
return true;
}
return false;
return retVal;
}
private void addToHeldIds(int theValueIdx, ArrayList<String> theListToAddTo, String theId) {
@ -342,7 +355,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
if (nextChildElem.getDef().getElementName().equals("extension") || nextChildElem.getDef().getElementName().equals("modifierExtension")
|| nextChild instanceof RuntimeChildDeclaredExtensionDefinition) {
if (!haveWrittenExtensions) {
extractAndWriteExtensionsAsDirectChild(theElement, theEventWriter, myContext.getElementDefinition(theElement.getClass()), theResDef, theResource, nextChildElem, theParent, theEncodeContext);
extractAndWriteExtensionsAsDirectChild(theElement, theEventWriter, myContext.getElementDefinition(theElement.getClass()), theResDef, theResource, nextChildElem, theParent, theEncodeContext, theContainedResource);
haveWrittenExtensions = true;
}
continue;
@ -433,20 +446,20 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
if (primitive) {
if (nextValue instanceof ISupportsUndeclaredExtensions) {
List<ExtensionDt> ext = ((ISupportsUndeclaredExtensions) nextValue).getUndeclaredExtensions();
force |= addToHeldExtensions(valueIdx, ext, extensions, false, nextChildElem, theParent);
force |= addToHeldExtensions(valueIdx, ext, extensions, false, nextChildElem, theParent, theEncodeContext, theContainedResource, theElement);
ext = ((ISupportsUndeclaredExtensions) nextValue).getUndeclaredModifierExtensions();
force |= addToHeldExtensions(valueIdx, ext, modifierExtensions, true, nextChildElem, theParent);
force |= addToHeldExtensions(valueIdx, ext, modifierExtensions, true, nextChildElem, theParent, theEncodeContext, theContainedResource, theElement);
} else {
if (nextValue instanceof IBaseHasExtensions) {
IBaseHasExtensions element = (IBaseHasExtensions) nextValue;
List<? extends IBaseExtension<?, ?>> ext = element.getExtension();
force |= addToHeldExtensions(valueIdx, ext, extensions, false, nextChildElem, theParent);
force |= addToHeldExtensions(valueIdx, ext, extensions, false, nextChildElem, theParent, theEncodeContext, theContainedResource, theElement);
}
if (nextValue instanceof IBaseHasModifierExtensions) {
IBaseHasModifierExtensions element = (IBaseHasModifierExtensions) nextValue;
List<? extends IBaseExtension<?, ?>> ext = element.getModifierExtension();
force |= addToHeldExtensions(valueIdx, ext, extensions, true, nextChildElem, theParent);
force |= addToHeldExtensions(valueIdx, ext, extensions, true, nextChildElem, theParent, theEncodeContext, theContainedResource, theElement);
}
}
if (nextValue.hasFormatComment()) {
@ -486,6 +499,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
theEventWriter.endArray();
}
if (!extensions.isEmpty() || !modifierExtensions.isEmpty() || !comments.isEmpty()) {
if (inArray) {
// If this is a repeatable field, the extensions go in an array too
@ -541,7 +555,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
}
theEventWriter.endArray();
}
writeExtensionsAsDirectChild(theResource, theEventWriter, theResDef, heldExts, heldModExts, theEncodeContext);
writeExtensionsAsDirectChild(theResource, theEventWriter, theResDef, heldExts, heldModExts, theEncodeContext, theContainedResource);
if (inArray) {
theEventWriter.endObject();
}
@ -626,7 +640,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
final List<HeldExtension> extensions = new ArrayList<>(0);
final List<HeldExtension> modifierExtensions = new ArrayList<>(0);
// Undeclared extensions
extractUndeclaredExtensions(theResourceId, extensions, modifierExtensions, null, null);
extractUndeclaredExtensions(theResourceId, extensions, modifierExtensions, null, null, theEncodeContext, theContainedResource);
boolean haveExtension = false;
if (!extensions.isEmpty()) {
haveExtension = true;
@ -638,7 +652,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
writeCommentsPreAndPost(theResourceId, theEventWriter);
}
if (haveExtension) {
writeExtensionsAsDirectChild(theResource, theEventWriter, theResDef, extensions, modifierExtensions, theEncodeContext);
writeExtensionsAsDirectChild(theResource, theEventWriter, theResDef, extensions, modifierExtensions, theEncodeContext, theContainedResource);
}
theEventWriter.endObject();
}
@ -741,12 +755,12 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
* called _name): resource extensions, and extension extensions
*/
private void extractAndWriteExtensionsAsDirectChild(IBase theElement, JsonLikeWriter theEventWriter, BaseRuntimeElementDefinition<?> theElementDef, RuntimeResourceDefinition theResDef,
IBaseResource theResource, CompositeChildElement theChildElem, CompositeChildElement theParent, EncodeContext theEncodeContext) throws IOException {
IBaseResource theResource, CompositeChildElement theChildElem, CompositeChildElement theParent, EncodeContext theEncodeContext, boolean theContainedResource) throws IOException {
List<HeldExtension> extensions = new ArrayList<>(0);
List<HeldExtension> modifierExtensions = new ArrayList<>(0);
// Undeclared extensions
extractUndeclaredExtensions(theElement, extensions, modifierExtensions, theChildElem, theParent);
extractUndeclaredExtensions(theElement, extensions, modifierExtensions, theChildElem, theParent, theEncodeContext, theContainedResource);
// Declared extensions
if (theElementDef != null) {
@ -754,7 +768,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
}
// Write the extensions
writeExtensionsAsDirectChild(theResource, theEventWriter, theResDef, extensions, modifierExtensions, theEncodeContext);
writeExtensionsAsDirectChild(theResource, theEventWriter, theResDef, extensions, modifierExtensions, theEncodeContext, theContainedResource);
}
private void extractDeclaredExtensions(IBase theResource, BaseRuntimeElementDefinition<?> resDef, List<HeldExtension> extensions, List<HeldExtension> modifierExtensions,
@ -782,7 +796,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
}
private void extractUndeclaredExtensions(IBase theElement, List<HeldExtension> extensions, List<HeldExtension> modifierExtensions, CompositeChildElement theChildElem,
CompositeChildElement theParent) {
CompositeChildElement theParent, EncodeContext theEncodeContext, boolean theContainedResource) {
if (theElement instanceof ISupportsUndeclaredExtensions) {
ISupportsUndeclaredExtensions element = (ISupportsUndeclaredExtensions) theElement;
List<ExtensionDt> ext = element.getUndeclaredExtensions();
@ -804,11 +818,21 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
if (theElement instanceof IBaseHasExtensions) {
IBaseHasExtensions element = (IBaseHasExtensions) theElement;
List<? extends IBaseExtension<?, ?>> ext = element.getExtension();
Boolean encodeExtension = null;
for (IBaseExtension<?, ?> next : ext) {
if (next == null || (ElementUtil.isEmpty(next.getValue()) && next.getExtension().isEmpty())) {
continue;
}
extensions.add(new HeldExtension(next, false, theChildElem, theParent));
// Make sure we respect _elements and _summary
if (encodeExtension == null) {
encodeExtension = isEncodeExtension(theParent, theEncodeContext, theContainedResource, element);
}
if (encodeExtension) {
HeldExtension extension = new HeldExtension(next, false, theChildElem, theParent);
extensions.add(extension);
}
}
}
if (theElement instanceof IBaseHasModifierExtensions) {
@ -818,12 +842,23 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
if (next == null || next.isEmpty()) {
continue;
}
modifierExtensions.add(new HeldExtension(next, true, theChildElem, theParent));
HeldExtension extension = new HeldExtension(next, true, theChildElem, theParent);
modifierExtensions.add(extension);
}
}
}
}
private boolean isEncodeExtension(CompositeChildElement theParent, EncodeContext theEncodeContext, boolean theContainedResource, IBase theElement) {
theEncodeContext.pushPath("extension", false);
BaseRuntimeChildDefinition childDef = ((BaseRuntimeElementCompositeDefinition) myContext.getElementDefinition(theElement.getClass())).getChildByName("extension");
CompositeChildElement c = new CompositeChildElement(theParent, childDef, theEncodeContext);
boolean retVal = c.shouldBeEncoded(theContainedResource);
theEncodeContext.popPath();
return retVal;
}
@Override
public EncodingEnum getEncoding() {
return EncodingEnum.JSON;
@ -1275,21 +1310,24 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
}
private void writeExtensionsAsDirectChild(IBaseResource theResource, JsonLikeWriter theEventWriter, RuntimeResourceDefinition resDef, List<HeldExtension> extensions,
List<HeldExtension> modifierExtensions, EncodeContext theEncodeContext) throws IOException {
List<HeldExtension> modifierExtensions, EncodeContext theEncodeContext, boolean theContainedResource) throws IOException {
// Write Extensions
if (extensions.isEmpty() == false) {
theEncodeContext.pushPath("extension", false);
beginArray(theEventWriter, "extension");
for (HeldExtension next : extensions) {
next.write(resDef, theResource, theEventWriter, theEncodeContext);
next.write(resDef, theResource, theEventWriter, theEncodeContext, theContainedResource);
}
theEventWriter.endArray();
theEncodeContext.popPath();
}
// Write ModifierExtensions
if (modifierExtensions.isEmpty() == false) {
theEncodeContext.pushPath("modifierExtension", false);
beginArray(theEventWriter, "modifierExtension");
for (HeldExtension next : modifierExtensions) {
next.write(resDef, theResource, theEventWriter, theEncodeContext);
next.write(resDef, theResource, theEventWriter, theEncodeContext, theContainedResource);
}
theEventWriter.endArray();
theEncodeContext.popPath();
@ -1353,12 +1391,12 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
return url1.compareTo(url2);
}
private void managePrimitiveExtension(final IBase theValue, final RuntimeResourceDefinition theResDef, final IBaseResource theResource, final JsonLikeWriter theEventWriter, final BaseRuntimeElementDefinition<?> def, final String childName, EncodeContext theEncodeContext) throws IOException {
private void managePrimitiveExtension(final IBase theValue, final RuntimeResourceDefinition theResDef, final IBaseResource theResource, final JsonLikeWriter theEventWriter, final BaseRuntimeElementDefinition<?> def, final String childName, EncodeContext theEncodeContext, boolean theContainedResource) throws IOException {
if (def.getChildType().equals(ID_DATATYPE) || def.getChildType().equals(PRIMITIVE_DATATYPE)) {
final List<HeldExtension> extensions = new ArrayList<HeldExtension>(0);
final List<HeldExtension> modifierExtensions = new ArrayList<HeldExtension>(0);
// Undeclared extensions
extractUndeclaredExtensions(theValue, extensions, modifierExtensions, myParent, null);
extractUndeclaredExtensions(theValue, extensions, modifierExtensions, myParent, null, theEncodeContext, theContainedResource);
// Declared extensions
if (def != null) {
extractDeclaredExtensions(theValue, def, extensions, modifierExtensions, myParent);
@ -1369,15 +1407,15 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
}
if (haveContent) {
beginObject(theEventWriter, '_' + childName);
writeExtensionsAsDirectChild(theResource, theEventWriter, theResDef, extensions, modifierExtensions, theEncodeContext);
writeExtensionsAsDirectChild(theResource, theEventWriter, theResDef, extensions, modifierExtensions, theEncodeContext, theContainedResource);
theEventWriter.endObject();
}
}
}
public void write(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonLikeWriter theEventWriter, EncodeContext theEncodeContext) throws IOException {
public void write(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonLikeWriter theEventWriter, EncodeContext theEncodeContext, boolean theContainedResource) throws IOException {
if (myUndeclaredExtension != null) {
writeUndeclaredExtension(theResDef, theResource, theEventWriter, myUndeclaredExtension, theEncodeContext);
writeUndeclaredExtension(theResDef, theResource, theEventWriter, myUndeclaredExtension, theEncodeContext, theContainedResource);
} else {
theEventWriter.beginObject();
@ -1410,18 +1448,18 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
BaseRuntimeElementDefinition<?> def = myDef.getChildElementDefinitionByDatatype(myValue.getClass());
if (def.getChildType() == ChildTypeEnum.RESOURCE_BLOCK) {
extractAndWriteExtensionsAsDirectChild(myValue, theEventWriter, def, theResDef, theResource, myChildElem, null, theEncodeContext);
extractAndWriteExtensionsAsDirectChild(myValue, theEventWriter, def, theResDef, theResource, myChildElem, null, theEncodeContext, theContainedResource);
} else {
String childName = myDef.getChildNameByDatatype(myValue.getClass());
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, myValue, def, childName, false, myParent, false, theEncodeContext);
managePrimitiveExtension(myValue, theResDef, theResource, theEventWriter, def, childName, theEncodeContext);
managePrimitiveExtension(myValue, theResDef, theResource, theEventWriter, def, childName, theEncodeContext, theContainedResource);
}
theEventWriter.endObject();
}
}
private void writeUndeclaredExtension(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonLikeWriter theEventWriter, IBaseExtension<?, ?> ext, EncodeContext theEncodeContext) throws IOException {
private void writeUndeclaredExtension(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonLikeWriter theEventWriter, IBaseExtension<?, ?> ext, EncodeContext theEncodeContext, boolean theContainedResource) throws IOException {
IBase value = ext.getValue();
final String extensionUrl = getExtensionUrl(ext.getUrl());
@ -1465,7 +1503,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
}
for (Object next : ext.getExtension()) {
writeUndeclaredExtension(theResDef, theResource, theEventWriter, (IBaseExtension<?, ?>) next, theEncodeContext);
writeUndeclaredExtension(theResDef, theResource, theEventWriter, (IBaseExtension<?, ?>) next, theEncodeContext, theContainedResource);
}
theEventWriter.endArray();
@ -1490,7 +1528,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
throw new ConfigurationException("Unable to encode extension, unrecognized child element type: " + value.getClass().getCanonicalName());
}
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, value, childDef, childName, false, myParent,false, theEncodeContext);
managePrimitiveExtension(value, theResDef, theResource, theEventWriter, childDef, childName, theEncodeContext);
managePrimitiveExtension(value, theResDef, theResource, theEventWriter, childDef, childName, theEncodeContext, theContainedResource);
}
}

View File

@ -51,15 +51,9 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
* This class is the FHIR XML parser/encoder. Users should not interact with this class directly, but should use
* {@link FhirContext#newXmlParser()} to get an instance.
*/
public class XmlParser extends BaseParser /* implements IParser */ {
public class XmlParser extends BaseParser {
static final String ATOM_NS = "http://www.w3.org/2005/Atom";
static final String FHIR_NS = "http://hl7.org/fhir";
static final String OPENSEARCH_NS = "http://a9.com/-/spec/opensearch/1.1/";
static final String RESREF_DISPLAY = "display";
static final String RESREF_REFERENCE = "reference";
static final String TOMBSTONES_NS = "http://purl.org/atompub/tombstones/1.0";
static final String XHTML_NS = "http://www.w3.org/1999/xhtml";
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlParser.class);
// private static final Set<String> RESOURCE_NAMESPACES;

View File

@ -22,7 +22,7 @@ package org.hl7.fhir.instance.model.api;
import java.util.List;
public interface IBaseHasExtensions {
public interface IBaseHasExtensions extends IBase {
IBaseExtension<?, ?> addExtension();

View File

@ -715,13 +715,26 @@ public class JsonParserDstu3Test {
.setValue(new Reference("Practitioner/A"));
IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
parser.setDontEncodeElements(new HashSet<String>(Arrays.asList("*.id", "*.meta")));
parser.setDontEncodeElements(new HashSet<>(Arrays.asList("*.id", "*.meta")));
String encoded = parser.encodeResourceToString(p);
ourLog.info(encoded);
assertThat(encoded, containsString("http://foo"));
assertThat(encoded, containsString("Practitioner/A"));
// Now with exclude
parser = ourCtx.newJsonParser().setPrettyPrint(true);
parser.setDontEncodeElements(new HashSet<>(Arrays.asList("*.id", "*.meta", "*.extension")));
encoded = parser.encodeResourceToString(p);
ourLog.info(encoded);
assertThat(encoded, (containsString("http://foo")));
assertThat(encoded, (containsString("Practitioner/A")));
}
@Test
@ -1064,6 +1077,57 @@ public class JsonParserDstu3Test {
assertThat(encoded, not(containsString("maritalStatus")));
}
/**
* We specifically include extensions on CapabilityStatment even in
* summary mode, since this is behaviour that people depend on
*/
@Test
public void testEncodeSummaryCapabilityStatementExtensions() {
CapabilityStatement cs = new CapabilityStatement();
CapabilityStatement.CapabilityStatementRestComponent rest = cs.addRest();
rest.setMode(CapabilityStatement.RestfulCapabilityMode.CLIENT);
rest.getSecurity()
.addExtension()
.setUrl("http://foo")
.setValue(new StringType("bar"));
cs.getVersionElement().addExtension()
.setUrl("http://goo")
.setValue(new StringType("ber"));
String encoded = ourCtx.newJsonParser().setSummaryMode(true).setPrettyPrint(true).setPrettyPrint(true).encodeResourceToString(cs);
ourLog.info(encoded);
assertThat(encoded, (containsString("http://foo")));
assertThat(encoded, (containsString("bar")));
assertThat(encoded, (containsString("http://goo")));
assertThat(encoded, (containsString("ber")));
}
@Test
public void testEncodeSummaryPatientExtensions() {
Patient cs = new Patient();
Address address = cs.addAddress();
address.setCity("CITY");
address
.addExtension()
.setUrl("http://foo")
.setValue(new StringType("bar"));
address.getCityElement().addExtension()
.setUrl("http://goo")
.setValue(new StringType("ber"));
String encoded = ourCtx.newJsonParser().setSummaryMode(true).setPrettyPrint(true).setPrettyPrint(true).encodeResourceToString(cs);
ourLog.info(encoded);
assertThat(encoded, not(containsString("http://foo")));
assertThat(encoded, not(containsString("bar")));
assertThat(encoded, not(containsString("http://goo")));
assertThat(encoded, not(containsString("ber")));
}
@Test
public void testEncodeSummary2() {
Patient patient = new Patient();

View File

@ -12,6 +12,7 @@ import com.google.common.collect.Sets;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.hamcrest.Matchers;
import org.hamcrest.collection.IsEmptyCollection;
import org.hamcrest.core.StringContains;
import org.hamcrest.text.StringContainsInOrder;
@ -69,6 +70,35 @@ public class XmlParserDstu3Test {
ourCtx.setNarrativeGenerator(null);
}
/**
* We specifically include extensions on CapabilityStatment even in
* summary mode, since this is behaviour that people depend on
*/
@Test
public void testEncodeSummaryCapabilityStatementExtensions() {
CapabilityStatement cs = new CapabilityStatement();
CapabilityStatement.CapabilityStatementRestComponent rest = cs.addRest();
rest.setMode(CapabilityStatement.RestfulCapabilityMode.CLIENT);
rest.getSecurity()
.addExtension()
.setUrl("http://foo")
.setValue(new StringType("bar"));
cs.getVersionElement().addExtension()
.setUrl("http://goo")
.setValue(new StringType("ber"));
String encoded = ourCtx.newXmlParser().setSummaryMode(true).setPrettyPrint(true).setPrettyPrint(true).encodeResourceToString(cs);
ourLog.info(encoded);
assertThat(encoded, Matchers.containsString("http://foo"));
assertThat(encoded, Matchers.containsString("bar"));
assertThat(encoded, Matchers.containsString("http://goo"));
assertThat(encoded, Matchers.containsString("ber"));
}
@Test
public void testEncodeInvalidMetaTime() {

View File

@ -266,6 +266,10 @@
A new server interceptor hook called PROCESSING_COMPLETED has been added. This
hook is called by the server at the end of processing every request (success and failure).
</action>
<action type="fix">
The <![CDATA[<code>_summary</code>]]> element was not always respected when encoding
JSON resources.
</action>
</release>
<release version="3.8.0" date="2019-05-30" description="Hippo">
<action type="fix">