Fix #158 - Don't encode empty tags

This commit is contained in:
jamesagnew 2015-07-18 17:35:54 -04:00
parent af0db664db
commit a35d20b999
9 changed files with 881 additions and 836 deletions

View File

@ -138,9 +138,12 @@ public class Tag extends BaseElement implements IElement {
return result;
}
/**
* Returns <code>true</code> if either scheme or term is populated.
*/
@Override
public boolean isEmpty() {
return StringUtils.isBlank(myLabel) && StringUtils.isBlank(myScheme) && StringUtils.isBlank(myTerm);
return StringUtils.isBlank(myScheme) && StringUtils.isBlank(myTerm);
}
/**

View File

@ -191,7 +191,12 @@ public class TagList implements Set<Tag>, Serializable, IBase {
@Override
public boolean isEmpty() {
return myTagSet.isEmpty();
for (Tag next : myTagSet) {
if (next.isEmpty() == false) {
return false;
}
}
return true;
}
@Override

View File

@ -754,6 +754,9 @@ public class JsonParser extends BaseParser implements IParser {
if (tags != null && tags.isEmpty() == false) {
theEventWriter.writeStartArray("tag");
for (Tag tag : tags) {
if (tag.isEmpty()) {
continue;
}
theEventWriter.writeStartObject();
writeOptionalTagWithTextNode(theEventWriter, "system", tag.getScheme());
writeOptionalTagWithTextNode(theEventWriter, "code", tag.getTerm());

View File

@ -820,6 +820,9 @@ public class XmlParser extends BaseParser implements IParser {
}
if (tags != null) {
for (Tag tag : tags) {
if (tag.isEmpty()) {
continue;
}
theEventWriter.writeStartElement("tag");
writeOptionalTagWithValue(theEventWriter, "system", tag.getScheme());
writeOptionalTagWithValue(theEventWriter, "code", tag.getTerm());

View File

@ -36,6 +36,12 @@
<artifactId>junit</artifactId>
<version>${junit_version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>hamcrest-core</artifactId>
<groupId>org.hamcrest</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>xmlunit</groupId>

View File

@ -96,30 +96,6 @@ public class XmlParserDstu2Test {
}
@Test
public void testParseMetaUpdatedDate() {
//@formatter:off
String input = "<Bundle xmlns=\"http://hl7.org/fhir\">\n" +
" <id value=\"e2ee823b-ee4d-472d-b79d-495c23f16b99\"/>\n" +
" <meta>\n" +
" <lastUpdated value=\"2015-06-22T15:48:57.554-04:00\"/>\n" +
" </meta>\n" +
" <type value=\"searchset\"/>\n" +
" <base value=\"http://localhost:58109/fhir/context\"/>\n" +
" <total value=\"0\"/>\n" +
" <link>\n" +
" <relation value=\"self\"/>\n" +
" <url value=\"http://localhost:58109/fhir/context/Patient?_pretty=true\"/>\n" +
" </link>\n" +
"</Bundle>";
//@formatter:on
ca.uhn.fhir.model.dstu2.resource.Bundle b = ourCtx.newXmlParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, input);
InstantDt updated = ResourceMetadataKeyEnum.UPDATED.get(b);
assertEquals("2015-06-22T15:48:57.554-04:00", updated.getValueAsString());
}
@Test
public void testContainedResourceInExtensionUndeclared() {
Patient p = new Patient();
@ -156,9 +132,6 @@ public class XmlParserDstu2Test {
assertThat(str, containsString("<length><value value=\"123\"/><units value=\"day\"/></length>"));
}
@Test
public void testEncodeAndParseBundleWithoutResourceIds() {
Organization org = new Organization();
@ -173,42 +146,6 @@ public class XmlParserDstu2Test {
assertTrue(parsed.getEntries().get(0).getResource().getId().isEmpty());
}
public static void main(String[] args) {
IGenericClient c = ourCtx.newRestfulGenericClient("http://fhir-dev.healthintersections.com.au/open");
// c.registerInterceptor(new LoggingInterceptor(true));
c.read().resource("Patient").withId("324").execute();
}
@Test
public void testEncodeBundleWithContained() {
DiagnosticReport rpt = new DiagnosticReport();
rpt.addResult().setResource(new Observation().setCode(new CodeableConceptDt().setText("Sharp1")).setId("#1"));
rpt.addResult().setResource(new Observation().setCode(new CodeableConceptDt().setText("Uuid1")).setId("urn:uuid:UUID1"));
ca.uhn.fhir.model.dstu2.resource.Bundle b = new ca.uhn.fhir.model.dstu2.resource.Bundle();
b.addEntry().setResource(rpt);
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b);
ourLog.info(encoded);
assertThat(encoded, stringContainsInOrder(
"<DiagnosticReport",
"<contained",
"<Observation",
"<text value=\"Sharp1\"",
"</DiagnosticReport"
));
assertThat(encoded, not(stringContainsInOrder(
"<DiagnosticReport",
"<contained",
"<Observation",
"<contained",
"<Observation",
"</DiagnosticReport"
)));
}
@Test
public void testEncodeAndParseContained() {
IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true);
@ -278,7 +215,6 @@ public class XmlParserDstu2Test {
}
@Test
public void testEncodeAndParseExtensionOnResourceReference() {
DataElement de = new DataElement();
@ -304,7 +240,6 @@ public class XmlParserDstu2Test {
}
@Test
public void testEncodeAndParseExtensions() throws Exception {
@ -348,9 +283,7 @@ public class XmlParserDstu2Test {
String enc = ourCtx.newXmlParser().encodeResourceToString(patient);
assertThat(enc, containsString("<Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://example.com/extensions#someext\"><valueDateTime value=\"2011-01-02T11:13:15\"/></extension>"));
assertThat(enc, containsString("<modifierExtension url=\"http://example.com/extensions#modext\"><valueDate value=\"1995-01-02\"/></modifierExtension>"));
assertThat(
enc,
containsString("<extension url=\"http://example.com#parent\"><extension url=\"http://example.com#child\"><valueString value=\"value1\"/></extension><extension url=\"http://example.com#child\"><valueString value=\"value2\"/></extension></extension>"));
assertThat(enc, containsString("<extension url=\"http://example.com#parent\"><extension url=\"http://example.com#child\"><valueString value=\"value1\"/></extension><extension url=\"http://example.com#child\"><valueString value=\"value2\"/></extension></extension>"));
assertThat(enc, containsString("<given value=\"Joe\"><extension url=\"http://examples.com#givenext\"><valueString value=\"given\"/></extension></given>"));
assertThat(enc, containsString("<given value=\"Shmoe\"><extension url=\"http://examples.com#givenext_parent\"><extension url=\"http://examples.com#givenext_child\"><valueString value=\"CHILD\"/></extension></extension></given>"));
@ -451,7 +384,6 @@ public class XmlParserDstu2Test {
assertEquals(new Tag("scheme2", "term2", "label2"), tagList.get(1));
}
@Test
public void testEncodeAndParseMetaProfiles() {
Patient p = new Patient();
@ -692,7 +624,6 @@ public class XmlParserDstu2Test {
assertThat(encoded, stringContainsInOrder("<Bundle", "<base value=\"urn:uuid:\"/>", "<entry>", "<Patient", "<id value="));
}
@Test
public void testEncodeBundleOldStyleContainingResourceWithUuidBaseBundleBaseIsSetDifferently() {
Patient p = new Patient();
@ -708,6 +639,22 @@ public class XmlParserDstu2Test {
assertThat(encoded, stringContainsInOrder("<Bundle", "<base value=\"urn:oid:\"/>", "<entry>", "<base value=\"urn:uuid:\"/>", "<Patient", "<id value="));
}
@Test
public void testEncodeBundleWithContained() {
DiagnosticReport rpt = new DiagnosticReport();
rpt.addResult().setResource(new Observation().setCode(new CodeableConceptDt().setText("Sharp1")).setId("#1"));
rpt.addResult().setResource(new Observation().setCode(new CodeableConceptDt().setText("Uuid1")).setId("urn:uuid:UUID1"));
ca.uhn.fhir.model.dstu2.resource.Bundle b = new ca.uhn.fhir.model.dstu2.resource.Bundle();
b.addEntry().setResource(rpt);
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b);
ourLog.info(encoded);
assertThat(encoded, stringContainsInOrder("<DiagnosticReport", "<contained", "<Observation", "<text value=\"Sharp1\"", "</DiagnosticReport"));
assertThat(encoded, not(stringContainsInOrder("<DiagnosticReport", "<contained", "<Observation", "<contained", "<Observation", "</DiagnosticReport")));
}
/**
* See #113
*/
@ -739,32 +686,14 @@ public class XmlParserDstu2Test {
ourLog.info(encoded);
// @formatter:on
assertThat(encoded, stringContainsInOrder(
"<MedicationPrescription xmlns=\"http://hl7.org/fhir\">",
"<contained>",
"<Medication xmlns=\"http://hl7.org/fhir\">",
"<id value=\"123\"/>",
"<code>",
"<coding>",
"<system value=\"urn:sys\"/>",
"<code value=\"code1\"/>",
"</coding>",
"</code>",
"</Medication>",
"</contained>",
"<medication>",
"<reference value=\"#123\"/>",
"<display value=\"MedRef\"/>",
"</medication>",
"</MedicationPrescription>"));
assertThat(
encoded,
stringContainsInOrder("<MedicationPrescription xmlns=\"http://hl7.org/fhir\">", "<contained>", "<Medication xmlns=\"http://hl7.org/fhir\">", "<id value=\"123\"/>", "<code>", "<coding>", "<system value=\"urn:sys\"/>", "<code value=\"code1\"/>", "</coding>", "</code>", "</Medication>",
"</contained>", "<medication>", "<reference value=\"#123\"/>", "<display value=\"MedRef\"/>", "</medication>", "</MedicationPrescription>"));
//@formatter:off
}
/**
* See #113
*/
@ -792,27 +721,14 @@ public class XmlParserDstu2Test {
ourLog.info(encoded);
//@formatter:on
assertThat(encoded, stringContainsInOrder(
"<MedicationPrescription xmlns=\"http://hl7.org/fhir\">",
"<contained>",
"<Medication xmlns=\"http://hl7.org/fhir\">",
"<id value=\"1\"/>",
"<code>",
"<coding>",
"<system value=\"urn:sys\"/>",
"<code value=\"code1\"/>",
"</coding>",
"</code>",
"</Medication>",
"</contained>",
"<medication>",
"<reference value=\"#1\"/>",
"<display value=\"MedRef\"/>",
"</medication>",
"</MedicationPrescription>"));
assertThat(
encoded,
stringContainsInOrder("<MedicationPrescription xmlns=\"http://hl7.org/fhir\">", "<contained>", "<Medication xmlns=\"http://hl7.org/fhir\">", "<id value=\"1\"/>", "<code>", "<coding>", "<system value=\"urn:sys\"/>", "<code value=\"code1\"/>", "</coding>", "</code>", "</Medication>",
"</contained>", "<medication>", "<reference value=\"#1\"/>", "<display value=\"MedRef\"/>", "</medication>", "</MedicationPrescription>"));
//@formatter:off
}
/**
* See #113
*/
@ -844,29 +760,14 @@ public class XmlParserDstu2Test {
ourLog.info(encoded);
//@formatter:on
assertThat(encoded, stringContainsInOrder(
"<MedicationPrescription xmlns=\"http://hl7.org/fhir\">",
"<contained>",
"<Medication xmlns=\"http://hl7.org/fhir\">",
"<id value=\"123\"/>",
"<code>",
"<coding>",
"<system value=\"urn:sys\"/>",
"<code value=\"code1\"/>",
"</coding>",
"</code>",
"</Medication>",
"</contained>",
"<medication>",
"<reference value=\"#123\"/>",
"<display value=\"MedRef\"/>",
"</medication>",
"</MedicationPrescription>"));
assertThat(
encoded,
stringContainsInOrder("<MedicationPrescription xmlns=\"http://hl7.org/fhir\">", "<contained>", "<Medication xmlns=\"http://hl7.org/fhir\">", "<id value=\"123\"/>", "<code>", "<coding>", "<system value=\"urn:sys\"/>", "<code value=\"code1\"/>", "</coding>", "</code>", "</Medication>",
"</contained>", "<medication>", "<reference value=\"#123\"/>", "<display value=\"MedRef\"/>", "</medication>", "</MedicationPrescription>"));
//@formatter:off
}
@Test
public void testEncodeContainedWithNarrativeIsSuppresed() throws Exception {
IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
@ -895,6 +796,43 @@ public class XmlParserDstu2Test {
}
/**
* #158
*/
@Test
public void testEncodeEmptyTag() {
TagList tagList = new TagList();
tagList.addTag(null, null, null);
tagList.addTag(null, null, "Label");
Patient p = new Patient();
ResourceMetadataKeyEnum.TAG_LIST.put(p, tagList);
String encoded = ourCtx.newXmlParser().encodeResourceToString(p);
assertThat(encoded, not(containsString("tag")));
}
/**
* #158
*/
@Test
public void testEncodeEmptyTag2() {
TagList tagList = new TagList();
tagList.addTag("scheme", "code", null);
tagList.addTag(null, null, "Label");
Patient p = new Patient();
ResourceMetadataKeyEnum.TAG_LIST.put(p, tagList);
String encoded = ourCtx.newXmlParser().encodeResourceToString(p);
assertThat(encoded, containsString("tag"));
assertThat(encoded, containsString("scheme"));
assertThat(encoded, not(containsString("Label")));
}
@Test
public void testEncodeExtensionWithResourceContent() {
IParser parser = ourCtx.newXmlParser();
@ -916,6 +854,7 @@ public class XmlParserDstu2Test {
}
@Test
public void testEncodeNonContained() {
// Create an organization
@ -956,6 +895,7 @@ public class XmlParserDstu2Test {
}
@Test
public void testMoreExtensions() throws Exception {
@ -1324,25 +1264,6 @@ public class XmlParserDstu2Test {
assertEquals(input, output);
}
/**
* See #191
*/
@Test
public void testParseBundleWithLinksOfUnknownRelation() throws Exception {
String input =IOUtils.toString(XmlParserDstu2Test.class.getResourceAsStream("/bundle_orion.xml"));
ca.uhn.fhir.model.dstu2.resource.Bundle parsed = ourCtx.newXmlParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, input);
Link link = parsed.getLink().get(0);
assertEquals("just trying add link", link.getRelation());
assertEquals("blarion", link.getUrl());
Entry entry = parsed.getEntry().get(0);
link = entry.getLink().get(0);
assertEquals("orionhealth.edit", link.getRelation());
assertEquals("Observation", link.getUrl());
}
@Test
public void testParseBundleNewWithPlaceholderIds() {
//@formatter:off
@ -1472,7 +1393,6 @@ public class XmlParserDstu2Test {
Bundle b = ourCtx.newXmlParser().parseBundle(bundle);
assertEquals(1, b.getEntries().size());
}
@Test
@ -1513,12 +1433,29 @@ public class XmlParserDstu2Test {
}
@Test
public void testParseBundleWithBinary() {
// TODO: implement this test, make sure we handle ID and meta correctly in Binary
}
/**
* See #191
*/
@Test
public void testParseBundleWithLinksOfUnknownRelation() throws Exception {
String input = IOUtils.toString(XmlParserDstu2Test.class.getResourceAsStream("/bundle_orion.xml"));
ca.uhn.fhir.model.dstu2.resource.Bundle parsed = ourCtx.newXmlParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, input);
Link link = parsed.getLink().get(0);
assertEquals("just trying add link", link.getRelation());
assertEquals("blarion", link.getUrl());
Entry entry = parsed.getEntry().get(0);
link = entry.getLink().get(0);
assertEquals("orionhealth.edit", link.getRelation());
assertEquals("Observation", link.getUrl());
}
/**
* see #144 and #146
*/
@ -1557,7 +1494,6 @@ public class XmlParserDstu2Test {
assertEquals("patient family", p.getNameFirstRep().getFamilyAsSingleString());
}
/**
* Thanks to Alexander Kley!
*/
@ -1649,6 +1585,30 @@ public class XmlParserDstu2Test {
}
@Test
public void testParseMetaUpdatedDate() {
//@formatter:off
String input = "<Bundle xmlns=\"http://hl7.org/fhir\">\n" +
" <id value=\"e2ee823b-ee4d-472d-b79d-495c23f16b99\"/>\n" +
" <meta>\n" +
" <lastUpdated value=\"2015-06-22T15:48:57.554-04:00\"/>\n" +
" </meta>\n" +
" <type value=\"searchset\"/>\n" +
" <base value=\"http://localhost:58109/fhir/context\"/>\n" +
" <total value=\"0\"/>\n" +
" <link>\n" +
" <relation value=\"self\"/>\n" +
" <url value=\"http://localhost:58109/fhir/context/Patient?_pretty=true\"/>\n" +
" </link>\n" +
"</Bundle>";
//@formatter:on
ca.uhn.fhir.model.dstu2.resource.Bundle b = ourCtx.newXmlParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, input);
InstantDt updated = ResourceMetadataKeyEnum.UPDATED.get(b);
assertEquals("2015-06-22T15:48:57.554-04:00", updated.getValueAsString());
}
@Test
public void testParseNarrative() throws Exception {
//@formatter:off
@ -1703,6 +1663,10 @@ public class XmlParserDstu2Test {
XMLUnit.setIgnoreWhitespace(true);
}
public static void main(String[] args) {
IGenericClient c = ourCtx.newRestfulGenericClient("http://fhir-dev.healthintersections.com.au/open");
// c.registerInterceptor(new LoggingInterceptor(true));
c.read().resource("Patient").withId("324").execute();
}
}

View File

@ -59,6 +59,8 @@ import org.xml.sax.SAXException;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
import ca.uhn.fhir.narrative.INarrativeGenerator;
import ca.uhn.fhir.parser.JsonParserHl7OrgTest.MyPatientWithOneDeclaredAddressExtension;
@ -598,6 +600,27 @@ public class XmlParserHl7OrgDstu2Test {
}
/**
* #158
*/
@Test
public void testEncodeEmptyTag() {
Patient p = new Patient();
p.getMeta().addTag();
String encoded = ourCtx.newXmlParser().encodeResourceToString(p);
assertThat(encoded, not(containsString("tag")));
// With tag
p = new Patient();
p.getMeta().addTag().setSystem("sys").setCode("code");
encoded = ourCtx.newXmlParser().encodeResourceToString(p);
assertThat(encoded, (containsString("tag")));
}
/**
* Thanks to Alexander Kley!
*/

View File

@ -37,6 +37,10 @@
into a BaseServerResponseException. This is useful so that servers using ResponseHighlighterInterceptor
will highlight exceptions even if they aren't created with an OperationOutcome.
</action>
<action type="fix" issue="158">
XmlParser and JsonParser in DSTU2 mode should not encode empty
tags in resource. Thanks to Bill De Beaubien for reporting!
</action>
</release>
<release version="1.1" date="2015-07-13">
<action type="add">