package ca.uhn.fhir.parser;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import org.apache.commons.io.IOUtils;
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.XMLUnit;
import org.hamcrest.Matchers;
import org.hamcrest.core.IsNot;
import org.hamcrest.core.StringContains;
import org.hamcrest.text.StringContainsInOrder;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.INarrative;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.xml.sax.SAXException;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.ResourceWithExtensionsA;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.dstu.composite.AddressDt;
import ca.uhn.fhir.model.dstu.composite.AttachmentDt;
import ca.uhn.fhir.model.dstu.composite.CodeableConceptDt;
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.AllergyIntolerance;
import ca.uhn.fhir.model.dstu.resource.Binary;
import ca.uhn.fhir.model.dstu.resource.CarePlan;
import ca.uhn.fhir.model.dstu.resource.Composition;
import ca.uhn.fhir.model.dstu.resource.Condition;
import ca.uhn.fhir.model.dstu.resource.Conformance;
import ca.uhn.fhir.model.dstu.resource.Conformance.RestResource;
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
import ca.uhn.fhir.model.dstu.resource.DocumentManifest;
import ca.uhn.fhir.model.dstu.resource.ListResource;
import ca.uhn.fhir.model.dstu.resource.Observation;
import ca.uhn.fhir.model.dstu.resource.Organization;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.resource.Profile;
import ca.uhn.fhir.model.dstu.resource.Query;
import ca.uhn.fhir.model.dstu.resource.Specimen;
import ca.uhn.fhir.model.dstu.resource.ValueSet;
import ca.uhn.fhir.model.dstu.valueset.AddressUseEnum;
import ca.uhn.fhir.model.dstu.valueset.AdministrativeGenderCodesEnum;
import ca.uhn.fhir.model.dstu.valueset.DocumentReferenceStatusEnum;
import ca.uhn.fhir.model.dstu.valueset.IdentifierUseEnum;
import ca.uhn.fhir.model.dstu.valueset.NarrativeStatusEnum;
import ca.uhn.fhir.model.primitive.DateDt;
import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.DecimalDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.IdrefDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
import ca.uhn.fhir.narrative.INarrativeGenerator;
import ca.uhn.fhir.parser.JsonParserTest.MyPatientWithOneDeclaredAddressExtension;
import ca.uhn.fhir.parser.JsonParserTest.MyPatientWithOneDeclaredExtension;
import ca.uhn.fhir.util.TestUtil;
public class XmlParserTest {
private static FhirContext ourCtx;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlParserTest.class);
@Test
public void testComposition() {
Composition comp = new Composition();
comp.setId("1");
ourCtx.newXmlParser().encodeResourceToString(comp);
ourCtx.newXmlParser().encodeResourceToString(comp);
ourCtx.newXmlParser().encodeResourceToString(comp);
ourCtx.newXmlParser().encodeResourceToString(comp);
// comp.
}
@Test
public void testUnknownElementInDstu1() throws Exception {
String input = IOUtils.toString(getClass().getResourceAsStream("/old_07_feed.xml"));
Bundle b = ourCtx.newXmlParser().parseBundle(input);
assertEquals(1, b.getEntries().size());
}
@Test
public void testEncodeAndParseIdref() {
CarePlan cp = new CarePlan();
cp.addGoal().setNotes("Goal Notes").setElementSpecificId("goalId0");
IdrefDt idref = new IdrefDt();
idref.setValue("#goalId0");
idref.setTarget(cp);
idref.getTarget();
cp.addActivity().getGoal().add(idref);
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(cp);
ourLog.info(encoded);
}
/**
* Test for #82 - Not yet enabled because the test won't pass
*/
// @Test
public void testCustomTypeInExtension() throws DataFormatException {
MyPatient patient = new MyPatient();
patient.addName().addFamily("PatientName");
MyOrganization org = new MyOrganization();
org.setName("OrgName");
patient.getSomeOrganization().setResource(org);
String str = ourCtx.newXmlParser().encodeResourceToString(patient);
ourLog.info(str);
assertThat(str, Matchers.stringContainsInOrder(
"<Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://foo/someOrg\"><valueResource><reference value=\"#1\"/></valueResource></extension><contained><Organization xmlns=\"http://hl7.org/fhir\" id=\"1\"><name value=\"OrgName\"/></Organization></contained><name><family value=\"PatientName\"/></name></Patient>"));
MyPatient parse = ourCtx.newXmlParser().parseResource(MyPatient.class, str);
assertEquals("PatientName", parse.getNameFirstRep().getFamilyAsSingleString());
assertEquals("OrgName", ((MyOrganization) parse.getSomeOrganization().getResource()).getName().getValue());
}
/**
* Test for #82 - Not yet enabled because the test won't pass
*/
// @Test
public void testCustomTypeInReplaceParent() throws DataFormatException {
MyPatient patient = new MyPatient();
patient.addName().addFamily("PatientName");
MyOrganization org = new MyOrganization();
org.setName("OrgName");
patient.getManagingOrganization().setResource(org);
String str = ourCtx.newXmlParser().encodeResourceToString(patient);
ourLog.info(str);
assertThat(str, Matchers.stringContainsInOrder(
"<Patient xmlns=\"http://hl7.org/fhir\"><contained><Organization xmlns=\"http://hl7.org/fhir\" id=\"1\"><name value=\"OrgName\"/></Organization></contained><name><family value=\"PatientName\"/></name><managingOrganization><reference value=\"#1\"/></managingOrganization></Patient>"));
MyPatient parse = ourCtx.newXmlParser().parseResource(MyPatient.class, str);
assertEquals("PatientName", parse.getNameFirstRep().getFamilyAsSingleString());
assertEquals("OrgName", ((MyOrganization) parse.getManagingOrganization().getResource()).getName().getValue());
}
/**
* See #91
*/
@Test
public void testCustomTypeWithUnoderedExtensions() {
MyPatientWithUnorderedExtensions pat = new MyPatientWithUnorderedExtensions();
pat.getExtAtt1().setValue(true);
pat.getExtAtt2().setValue("val2");
pat.getExtAtt3().setValueAsString("2011-01-02");
String string = ourCtx.newXmlParser().encodeResourceToString(pat);
ourLog.info(string);
//@formatter:off
assertThat(string, stringContainsInOrder(Arrays.asList(
"<extension url=\"urn:ex1\"><valueBoolean value=\"true\"/></extension>",
"<extension url=\"urn:ex2\"><valueString value=\"val2\"/></extension>",
"<extension url=\"urn:ex3\"><valueDate value=\"2011-01-02\"/></extension>"
)));
//@formatter:on
}
@Test
public void testDuplicateContainedResources() {
Observation resA = new Observation();
resA.getName().setText("A");
Observation resB = new Observation();
resB.getName().setText("B");
resB.addRelated().setTarget(new ResourceReferenceDt(resA));
resB.addRelated().setTarget(new ResourceReferenceDt(resA));
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resB);
ourLog.info(encoded);
assertThat(encoded, stringContainsInOrder(Arrays.asList("<contained>", "<Observation", "</Observation>", "</contained>")));
assertThat(encoded, not(stringContainsInOrder(Arrays.asList("<contained>", "<Observation", "</Observation>", "<Obser", "</contained>"))));
}
@Test
public void testEncodeAndParseExtensions() throws Exception {
Patient patient = new Patient();
patient.addIdentifier().setUse(IdentifierUseEnum.OFFICIAL).setSystem("urn:example").setValue("7000135");
ExtensionDt ext = new ExtensionDt();
ext.setUrl("http://example.com/extensions#someext");
ext.setValue(new DateTimeDt("2011-01-02T11:13:15"));
patient.addUndeclaredExtension(ext);
ExtensionDt parent = new ExtensionDt().setUrl("http://example.com#parent");
patient.addUndeclaredExtension(parent);
ExtensionDt child1 = new ExtensionDt().setUrl("http://example.com#child").setValue(new StringDt("value1"));
parent.addUndeclaredExtension(child1);
ExtensionDt child2 = new ExtensionDt().setUrl("http://example.com#child").setValue(new StringDt("value2"));
parent.addUndeclaredExtension(child2);
ExtensionDt modExt = new ExtensionDt();
modExt.setUrl("http://example.com/extensions#modext");
modExt.setValue(new DateDt("1995-01-02"));
modExt.setModifier(true);
patient.addUndeclaredExtension(modExt);
HumanNameDt name = patient.addName();
name.addFamily("Blah");
StringDt given = name.addGiven();
given.setValue("Joe");
ExtensionDt ext2 = new ExtensionDt().setUrl("http://examples.com#givenext").setValue(new StringDt("given"));
given.addUndeclaredExtension(ext2);
StringDt given2 = name.addGiven();
given2.setValue("Shmoe");
ExtensionDt given2ext = new ExtensionDt().setUrl("http://examples.com#givenext_parent");
given2.addUndeclaredExtension(given2ext);
given2ext.addUndeclaredExtension(new ExtensionDt().setUrl("http://examples.com#givenext_child").setValue(new StringDt("CHILD")));
String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
ourLog.info(output);
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("<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>"));
/*
* Now parse this back
*/
Patient parsed = ourCtx.newXmlParser().parseResource(Patient.class, enc);
ext = parsed.getUndeclaredExtensions().get(0);
assertEquals("http://example.com/extensions#someext", ext.getUrl());
assertEquals("2011-01-02T11:13:15", ((DateTimeDt) ext.getValue()).getValueAsString());
parent = patient.getUndeclaredExtensions().get(1);
assertEquals("http://example.com#parent", parent.getUrl());
assertNull(parent.getValue());
child1 = parent.getExtension().get(0);
assertEquals("http://example.com#child", child1.getUrl());
assertEquals("value1", ((StringDt) child1.getValue()).getValueAsString());
child2 = parent.getExtension().get(1);
assertEquals("http://example.com#child", child2.getUrl());
assertEquals("value2", ((StringDt) child2.getValue()).getValueAsString());
modExt = parsed.getUndeclaredModifierExtensions().get(0);
assertEquals("http://example.com/extensions#modext", modExt.getUrl());
assertEquals("1995-01-02", ((DateDt) modExt.getValue()).getValueAsString());
name = parsed.getName().get(0);
ext2 = name.getGiven().get(0).getUndeclaredExtensions().get(0);
assertEquals("http://examples.com#givenext", ext2.getUrl());
assertEquals("given", ((StringDt) ext2.getValue()).getValueAsString());
given2ext = name.getGiven().get(1).getUndeclaredExtensions().get(0);
assertEquals("http://examples.com#givenext_parent", given2ext.getUrl());
assertNull(given2ext.getValue());
ExtensionDt given2ext2 = given2ext.getExtension().get(0);
assertEquals("http://examples.com#givenext_child", given2ext2.getUrl());
assertEquals("CHILD", ((StringDt) given2ext2.getValue()).getValue());
}
/**
* See #103
*/
@Test
public void testEncodeAndReEncodeContainedJson() {
Composition comp = new Composition();
comp.addSection().getContent().setResource(new AllergyIntolerance().addIdentifier("foo", "bar"));
comp.addSection().getContent().setResource(new AllergyIntolerance().addIdentifier("foo", "bar"));
comp.addSection().getContent().setResource(new AllergyIntolerance().addIdentifier("foo", "bar"));
IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
String string = parser.encodeResourceToString(comp);
ourLog.info(string);
Composition parsed = parser.parseResource(Composition.class, string);
parsed.getSection().remove(0);
string = parser.encodeResourceToString(parsed);
ourLog.info(string);
parsed = parser.parseResource(Composition.class, string);
assertEquals(2, parsed.getContained().getContainedResources().size());
}
/**
* See #103
*/
@Test
public void testEncodeAndReEncodeContainedXml() {
Composition comp = new Composition();
comp.addSection().getContent().setResource(new AllergyIntolerance().addIdentifier("foo", "bar"));
comp.addSection().getContent().setResource(new AllergyIntolerance().addIdentifier("foo", "bar"));
comp.addSection().getContent().setResource(new AllergyIntolerance().addIdentifier("foo", "bar"));
IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
String string = parser.encodeResourceToString(comp);
ourLog.info(string);
Composition parsed = parser.parseResource(Composition.class, string);
parsed.getSection().remove(0);
string = parser.encodeResourceToString(parsed);
ourLog.info(string);
parsed = parser.parseResource(Composition.class, string);
assertEquals(2, parsed.getContained().getContainedResources().size());
}
@Test
public void testEncodeBinaryResource() {
Binary patient = new Binary();
patient.setContentType("foo");
patient.setContent(new byte[] { 1, 2, 3, 4 });
String val = ourCtx.newXmlParser().encodeResourceToString(patient);
assertEquals("<Binary xmlns=\"http://hl7.org/fhir\" contentType=\"foo\">AQIDBA==</Binary>", val);
}
@Test
public void testEncodeBinaryWithNoContentType() {
Binary b = new Binary();
b.setContent(new byte[] { 1, 2, 3, 4 });
String output = ourCtx.newXmlParser().encodeResourceToString(b);
ourLog.info(output);
assertEquals("<Binary xmlns=\"http://hl7.org/fhir\">AQIDBA==</Binary>", output);
}
@Test
public void testEncodeBoundCode() {
Patient patient = new Patient();
patient.addAddress().setUse(AddressUseEnum.HOME);
patient.getGender().setValueAsEnum(AdministrativeGenderCodesEnum.M);
String val = ourCtx.newXmlParser().encodeResourceToString(patient);
ourLog.info(val);
}
@Test
public void testEncodeBundle() throws InterruptedException {
Bundle b = new Bundle();
b.getCategories().addTag("http://hl7.org/fhir/tag", "http://hl7.org/fhir/tag/message", "Message");
InstantDt pub = InstantDt.withCurrentTime();
Thread.sleep(2);
Patient p1 = new Patient();
p1.addName().addFamily("Family1");
p1.getId().setValue("1");
BundleEntry entry = b.addEntry();
entry.setResource(p1);
entry.getSummary().setValueAsString("this is the summary");
Patient p2 = new Patient();
p2.addName().addFamily("Family2");
p2.getId().setValue("2");
entry = b.addEntry();
entry.setLinkAlternate(new StringDt("http://foo/bar"));
entry.setLinkSearch(new StringDt("http://foo/bar/search"));
entry.setResource(p2);
BundleEntry deletedEntry = b.addEntry();
deletedEntry.setDeletedResourceId(new IdDt("Patient/3"));
deletedEntry.setDeleted(InstantDt.withCurrentTime());
String bundleString = ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(b);
ourLog.info(bundleString);
List<String> strings = new ArrayList<String>();
strings.add("<category term=\"http://hl7.org/fhir/tag/message\" label=\"Message\" scheme=\"http://hl7.org/fhir/tag\"/>");
strings.addAll(Arrays.asList("<entry>", "<id>1</id>", "</Patient>", "<summary type=\"xhtml\">", "<div", "</entry>"));
strings.addAll(Arrays.asList("<entry>", "<id>2</id>", "<link rel=\"alternate\" href=\"http://foo/bar\"/>", "<link rel=\"search\" href=\"http://foo/bar/search\"/>", "</entry>"));
strings.addAll(Arrays.asList("<at:deleted-entry", "ref=\"Patient/3", "/>"));
assertThat(bundleString, StringContainsInOrder.stringContainsInOrder(strings));
assertThat(bundleString, not(containsString("at:by")));
}
@Test
public void testEncodeBundleEntryAuthor() {
Bundle b = new Bundle();
BundleEntry e = b.addEntry();
e.getAuthorName().setValue("The Author");
e.setResource(new Patient());
String val = ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(b);
ourLog.info(val);
assertThat(val, StringContains.containsString("<name>The Author</name>"));
b = ourCtx.newXmlParser().parseBundle(val);
assertEquals(1, b.getEntries().size());
assertEquals("The Author", b.getEntries().get(0).getAuthorName().getValue());
}
@Test
public void testEncodeBundleCategory() {
Bundle b = new Bundle();
BundleEntry e = b.addEntry();
e.setResource(new Patient());
e.addCategory("scheme", "term", "label");
String val = ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(b);
ourLog.info(val);
assertThat(val, StringContains.containsString("<category term=\"term\" label=\"label\" scheme=\"scheme\"/>"));
b = ourCtx.newXmlParser().parseBundle(val);
assertEquals(1, b.getEntries().size());
assertEquals(1, b.getEntries().get(0).getCategories().size());
assertEquals("term", b.getEntries().get(0).getCategories().get(0).getTerm());
assertEquals("label", b.getEntries().get(0).getCategories().get(0).getLabel());
assertEquals("scheme", b.getEntries().get(0).getCategories().get(0).getScheme());
assertNull(b.getEntries().get(0).getResource());
}
@SuppressWarnings("deprecation")
@Test
public void testEncodeBundleOldIdForm() throws InterruptedException {
Bundle b = new Bundle();
b.getCategories().addTag("http://hl7.org/fhir/tag", "http://hl7.org/fhir/tag/message", "Message");
InstantDt pub = InstantDt.withCurrentTime();
Thread.sleep(2);
Patient p1 = new Patient();
p1.addName().addFamily("Family1");
BundleEntry entry = b.addEntry();
entry.getId().setValue("1");
entry.setResource(p1);
entry.getSummary().setValueAsString("this is the summary");
Patient p2 = new Patient();
p2.addName().addFamily("Family2");
entry = b.addEntry();
entry.getId().setValue("2");
entry.setLinkAlternate(new StringDt("http://foo/bar"));
entry.setLinkSearch(new StringDt("http://foo/bar/search"));
entry.setResource(p2);
BundleEntry deletedEntry = b.addEntry();
deletedEntry.setId(new IdDt("Patient/3"));
deletedEntry.setDeleted(InstantDt.withCurrentTime());
String bundleString = ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(b);
ourLog.info(bundleString);
List<String> strings = new ArrayList<String>();
strings.add("<category term=\"http://hl7.org/fhir/tag/message\" label=\"Message\" scheme=\"http://hl7.org/fhir/tag\"/>");
strings.addAll(Arrays.asList("<entry>", "<id>1</id>", "</Patient>", "<summary type=\"xhtml\">", "<div", "</entry>"));
strings.addAll(Arrays.asList("<entry>", "<id>2</id>", "<link rel=\"alternate\" href=\"http://foo/bar\"/>", "<link rel=\"search\" href=\"http://foo/bar/search\"/>", "</entry>"));
strings.addAll(Arrays.asList("<at:deleted-entry", "ref=\"Patient/3", "/>"));
assertThat(bundleString, StringContainsInOrder.stringContainsInOrder(strings));
assertThat(bundleString, not(containsString("at:by")));
}
@Test
public void testEncodeBundleResultCount() {
Bundle b = new Bundle();
b.getTotalResults().setValue(123);
String val = ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(b);
ourLog.info(val);
assertThat(val, StringContains.containsString("<os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">123</os:totalResults>"));
}
@Test
public void testEncodeContained() {
IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true);
// 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 = xmlParser.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 = xmlParser.encodeBundleToString(b);
ourLog.info(encoded);
assertThat(encoded, stringContainsInOrder(Arrays.asList("<contained>", "id=\"1\"", "</contained>")));
assertThat(encoded, containsString("<reference value=\"#1\"/>"));
assertThat(encoded, stringContainsInOrder(Arrays.asList("<entry>", "</entry>")));
assertThat(encoded, not(stringContainsInOrder(Arrays.asList("<entry>", "</entry>", "<entry>"))));
// Re-parse the bundle
patient = (Patient) xmlParser.parseResource(xmlParser.encodeResourceToString(patient));
assertEquals("#1", patient.getManagingOrganization().getReference().getValue());
assertEquals(null, patient.getManagingOrganization().getReference().getBaseUrl());
assertEquals("#1", patient.getManagingOrganization().getReference().getIdPart());
assertNotNull(patient.getManagingOrganization().getResource());
org = (Organization) patient.getManagingOrganization().getResource();
assertEquals("#1", org.getId().getValue());
assertEquals("Contained Test Organization", org.getName().getValue());
// And re-encode a second time
encoded = xmlParser.encodeResourceToString(patient);
ourLog.info(encoded);
assertThat(encoded, stringContainsInOrder(Arrays.asList("<contained>", "<Organization ", "id=\"1\"", "</Organization", "</contained>", "<reference value=\"#1\"/>")));
assertThat(encoded, not(stringContainsInOrder(Arrays.asList("<contained>", "<Org", "<contained>"))));
assertThat(encoded, containsString("<reference value=\"#1\"/>"));
// And re-encode once more, with the references cleared
patient.getContained().getContainedResources().clear();
patient.getManagingOrganization().setReference((IdDt) null);
encoded = xmlParser.encodeResourceToString(patient);
ourLog.info(encoded);
assertThat(encoded, stringContainsInOrder(Arrays.asList("<contained>", "<Organization ", "id=\"1\"", "</Organization", "</contained>", "<reference value=\"#1\"/>")));
assertThat(encoded, not(stringContainsInOrder(Arrays.asList("<contained>", "<Org", "<contained>"))));
assertThat(encoded, containsString("<reference value=\"#1\"/>"));
// And re-encode once more, with the references cleared and a manually set local ID
patient.getContained().getContainedResources().clear();
patient.getManagingOrganization().setReference((IdDt) null);
patient.getManagingOrganization().getResource().setId(new IdDt("#333"));
encoded = xmlParser.encodeResourceToString(patient);
ourLog.info(encoded);
assertThat(encoded, stringContainsInOrder(Arrays.asList("<contained>", "<Organization ", "id=\"333\"", "</Organization", "</contained>", "<reference value=\"#333\"/>")));
assertThat(encoded, not(stringContainsInOrder(Arrays.asList("<contained>", "<Org", "<contained>"))));
}
@Test
public void testEncodeContainedAndIncludedResources() {
DiagnosticReport rpt = new DiagnosticReport();
rpt.getName().setText("Report");
Specimen spm = new Specimen();
spm.addIdentifier().setLabel("Report1ContainedSpecimen1");
rpt.addSpecimen().setResource(spm);
IParser p = ourCtx.newXmlParser().setPrettyPrint(true);
String str = p.encodeResourceToString(rpt);
ourLog.info(str);
}
@Test
public void testEncodeContainedResources() {
DiagnosticReport rpt = new DiagnosticReport();
rpt.getText().setDiv("AAA");
Specimen spm = new Specimen();
spm.addIdentifier("urn", "123");
rpt.addSpecimen().setResource(spm);
spm = new Specimen();
spm.addIdentifier("urn", "456");
rpt.addSpecimen().setResource(spm);
IParser p = ourCtx.newXmlParser().setPrettyPrint(true);
String str = p.encodeResourceToString(rpt);
ourLog.info(str);
//@formatter:off
// Ensure that contained resources are encoded as children of separate <contained> elements
// (As of 0.9, See #84)
assertThat(str, stringContainsInOrder(Arrays.asList(
"<contained>", "<Specimen", "</contained>",
"<contained>", "<Specimen", "</contained>",
"<specimen>", "<reference")));
//@formatter:on
assertThat(str, StringContains.containsString("<div xmlns=\"http://www.w3.org/1999/xhtml\">AAA</div>"));
assertThat(str, StringContains.containsString("reference value=\"#"));
int idx = str.indexOf("reference value=\"#") + "reference value=\"#".length();
int idx2 = str.indexOf('"', idx + 1);
String id = str.substring(idx, idx2);
assertThat(str, StringContains.containsString("<Specimen xmlns=\"http://hl7.org/fhir\" id=\"" + id + "\">"));
assertThat(str, IsNot.not(StringContains.containsString("<?xml version='1.0'?>")));
}
@Test
public void testEncodeContainedWithNarrativeIsSuppresed() {
IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
// Create an organization, note that the organization does not have an ID
Organization org = new Organization();
org.getName().setValue("Contained Test Organization");
org.getText().setDiv("<div>FOOBAR</div>");
// Create a patient
Patient patient = new Patient();
patient.setId("Patient/1333");
patient.addIdentifier("urn:mrns", "253345");
patient.getText().setDiv("<div>BARFOO</div>");
patient.getManagingOrganization().setResource(org);
String encoded = parser.encodeResourceToString(patient);
ourLog.info(encoded);
assertThat(encoded, not(containsString("FOOBAR")));
assertThat(encoded, (containsString("BARFOO")));
}
@Test
public void testEncodeContainedWithSelfReference() {
IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true);
// Create an organization, note that the organization does not have an ID
Organization org = new Organization();
org.getName().setValue("Contained Test Organization");
org.setPartOf(new ResourceReferenceDt(org));
// Create a patient
Patient patient = new Patient();
patient.getManagingOrganization().setResource(org);
String encoded = xmlParser.encodeResourceToString(patient);
ourLog.info(encoded);
assertThat(encoded, containsString("<contained>"));
assertThat(encoded, containsString("<reference value=\"#1\"/>"));
}
@Test
public void testEncodeDeclaredExtensionWithAddressContent() {
IParser parser = ourCtx.newXmlParser();
MyPatientWithOneDeclaredAddressExtension patient = new MyPatientWithOneDeclaredAddressExtension();
patient.addAddress().setUse(AddressUseEnum.HOME);
patient.setFoo(new AddressDt().addLine("line1"));
String val = parser.encodeResourceToString(patient);
ourLog.info(val);
assertThat(val, StringContains.containsString("<extension url=\"urn:foo\"><valueAddress><line value=\"line1\"/></valueAddress></extension>"));
MyPatientWithOneDeclaredAddressExtension actual = parser.parseResource(MyPatientWithOneDeclaredAddressExtension.class, val);
assertEquals(AddressUseEnum.HOME, patient.getAddressFirstRep().getUse().getValueAsEnum());
AddressDt ref = actual.getFoo();
assertEquals("line1", ref.getLineFirstRep().getValue());
}
@Test
public void testEncodeDeclaredExtensionWithResourceContent() {
IParser parser = ourCtx.newXmlParser();
MyPatientWithOneDeclaredExtension patient = new MyPatientWithOneDeclaredExtension();
patient.addAddress().setUse(AddressUseEnum.HOME);
patient.setFoo(new ResourceReferenceDt("Organization/123"));
String val = parser.encodeResourceToString(patient);
ourLog.info(val);
assertThat(val, StringContains.containsString("<extension url=\"urn:foo\"><valueResource><reference value=\"Organization/123\"/></valueResource></extension>"));
MyPatientWithOneDeclaredExtension actual = parser.parseResource(MyPatientWithOneDeclaredExtension.class, val);
assertEquals(AddressUseEnum.HOME, patient.getAddressFirstRep().getUse().getValueAsEnum());
ResourceReferenceDt ref = actual.getFoo();
assertEquals("Organization/123", ref.getReference().getValue());
}
@Test
public void testEncodeEscapedChars() {
Patient p = new Patient();
p.addName().addFamily("and <>&ü");
String enc = ourCtx.newXmlParser().encodeResourceToString(p);
ourLog.info(enc);
p = ourCtx.newXmlParser().parseResource(Patient.class, enc);
assertEquals("and <>&ü", p.getNameFirstRep().getFamilyFirstRep().getValue());
p = ourCtx.newXmlParser().parseResource(Patient.class, "<Patient xmlns=\"http://hl7.org/fhir\"><name><family value=\"quot "\"/></name></Patient>");
assertEquals("quot \"", p.getNameFirstRep().getFamilyFirstRep().getValue());
}
@Test
public void testEncodeEscapedExtendedChars() {
Patient p = ourCtx.newXmlParser().parseResource(Patient.class, "<Patient xmlns=\"http://hl7.org/fhir\"><name><family value=\"uuml ü\"/></name></Patient>");
assertEquals("uuml ü", p.getNameFirstRep().getFamilyFirstRep().getValue());
}
@Test
public void testEncodeExtensionWithResourceContent() {
IParser parser = ourCtx.newXmlParser();
Patient patient = new Patient();
patient.addAddress().setUse(AddressUseEnum.HOME);
patient.addUndeclaredExtension(false, "urn:foo", new ResourceReferenceDt("Organization/123"));
String val = parser.encodeResourceToString(patient);
assertThat(val, StringContains.containsString("<extension url=\"urn:foo\"><valueResource><reference value=\"Organization/123\"/></valueResource></extension>"));
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient));
Patient actual = parser.parseResource(Patient.class, val);
assertEquals(AddressUseEnum.HOME, patient.getAddressFirstRep().getUse().getValueAsEnum());
List<ExtensionDt> ext = actual.getUndeclaredExtensionsByUrl("urn:foo");
assertEquals(1, ext.size());
ResourceReferenceDt ref = (ResourceReferenceDt) ext.get(0).getValue();
assertEquals("Organization/123", ref.getReference().getValue());
}
@Test
public void testEncodeInvalidChildGoodException() {
Observation obs = new Observation();
obs.setValue(new DecimalDt(112.22));
IParser p = ourCtx.newJsonParser();
try {
p.encodeResourceToString(obs);
} catch (DataFormatException e) {
assertThat(e.getMessage(), StringContains.containsString("DecimalDt"));
}
}
@Test
public void testEncodeNarrativeBlockInBundle() {
Patient p = new Patient();
p.addIdentifier("foo", "bar");
p.getText().setStatus(NarrativeStatusEnum.GENERATED);
p.getText().setDiv("<div>hello</div>");
Bundle b = new Bundle();
b.getTotalResults().setValue(123);
b.addEntry().setResource(p);
String out = ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(b);
ourLog.info(out);
assertThat(out, containsString("<div xmlns=\"http://www.w3.org/1999/xhtml\">hello</div>"));
p.getText().setDiv("<xhtml:div xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">hello</xhtml:div>");
out = ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(b);
ourLog.info(out);
assertThat(out, containsString("<xhtml:div xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">hello</xhtml:div>"));
}
@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 testEncodeOmitsVersionAndBase() {
Patient p = new Patient();
p.getManagingOrganization().setReference("http://example.com/base/Patient/1/_history/2");
String enc;
enc = ourCtx.newXmlParser().encodeResourceToString(p);
ourLog.info(enc);
assertThat(enc, containsString("\"http://example.com/base/Patient/1\""));
enc = ourCtx.newXmlParser().setServerBaseUrl("http://example.com/base").encodeResourceToString(p);
ourLog.info(enc);
assertThat(enc, containsString("\"Patient/1\""));
enc = ourCtx.newXmlParser().setServerBaseUrl("http://example.com/base2").encodeResourceToString(p);
ourLog.info(enc);
assertThat(enc, containsString("\"http://example.com/base/Patient/1\""));
}
@Test
public void testEncodePrettyPrint() throws DataFormatException {
Patient patient = new Patient();
patient.getText().getDiv().setValueAsString("<div>\n <i> hello <pre>\n LINE1\n LINE2</pre></i>\n\n\n\n</div>");
patient.addName().addFamily("Family").addGiven("Given");
//@formatter:off
String encoded = ourCtx.newXmlParser().setPrettyPrint(false).encodeResourceToString(patient);
ourLog.info(encoded);
/*
* Note at least one space is placed where any whitespace was, as
* it is hard to tell what whitespace had no purpose
*/
String expected = "<Patient xmlns=\"http://hl7.org/fhir\"><text><div xmlns=\"http://www.w3.org/1999/xhtml\">"
+ " <i> hello "
+ "<pre>\n LINE1\n LINE2</pre>"
+ "</i> </div></text><name><family value=\"Family\"/><given value=\"Given\"/></name></Patient>";
assertEquals(expected, encoded);
encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
ourLog.info(encoded);
expected = "<Patient xmlns=\"http://hl7.org/fhir\">\n"
+ " <text>\n"
+ " <div xmlns=\"http://www.w3.org/1999/xhtml\"> \n"
+ " <i> hello \n"
+ " <pre>\n LINE1\n LINE2</pre>\n"
+ " </i> \n"
+ " </div>\n"
+ " </text>\n"
+ " <name>\n"
+ " <family value=\"Family\"/>\n"
+ " <given value=\"Given\"/>\n"
+ " </name>\n"
+ "</Patient>";
//@formatter:on
// Whitespace should be preserved and not reformatted in narrative blocks
assertEquals(expected, encoded);
}
@Test
public void testEncodeProfile() {
Profile p = new Profile();
p.getStructureFirstRep().getElementFirstRep().getDefinition().getBinding().setReference(new ResourceReferenceDt("ValudSet/123"));
String encoded = ourCtx.newXmlParser().encodeResourceToString(p);
ourLog.info(encoded);
}
@Test
public void testEncodeQuery() {
Query q = new Query();
ExtensionDt parameter = q.addParameter();
parameter.setUrl("http://foo").setValue(new StringDt("bar"));
String val = ourCtx.newXmlParser().encodeResourceToString(q);
ourLog.info(val);
String expected = "<Query xmlns=\"http://hl7.org/fhir\"><parameter url=\"http://foo\"><valueString value=\"bar\"/></parameter></Query>";
ourLog.info("Expected: {}", expected);
ourLog.info("Actual : {}", val);
assertEquals(expected, val);
}
@Test
public void testEncodeResourceRef() throws DataFormatException {
Patient patient = new Patient();
patient.setManagingOrganization(new ResourceReferenceDt());
IParser p = ourCtx.newXmlParser();
String str = p.encodeResourceToString(patient);
assertThat(str, IsNot.not(StringContains.containsString("managingOrganization")));
ResourceReferenceDt ref = new ResourceReferenceDt();
ref.setReference("Organization/123");
ref.setDisplay("DISPLAY!");
patient.setManagingOrganization(ref);
str = p.encodeResourceToString(patient);
assertThat(str, StringContains.containsString("<managingOrganization><reference value=\"Organization/123\"/><display value=\"DISPLAY!\"/></managingOrganization>"));
Organization org = new Organization();
org.addIdentifier().setSystem("foo").setValue("bar");
patient.setManagingOrganization(new ResourceReferenceDt(org));
str = p.encodeResourceToString(patient);
assertThat(str, StringContains.containsString("<contained><Organization"));
}
@Test
public void testEncodeUndeclaredExtensionWithAddressContent() {
IParser parser = ourCtx.newXmlParser();
Patient patient = new Patient();
patient.addAddress().setUse(AddressUseEnum.HOME);
patient.addUndeclaredExtension(false, "urn:foo", new AddressDt().addLine("line1"));
String val = parser.encodeResourceToString(patient);
ourLog.info(val);
assertThat(val, StringContains.containsString("<extension url=\"urn:foo\"><valueAddress><line value=\"line1\"/></valueAddress></extension>"));
MyPatientWithOneDeclaredAddressExtension actual = parser.parseResource(MyPatientWithOneDeclaredAddressExtension.class, val);
assertEquals(AddressUseEnum.HOME, patient.getAddressFirstRep().getUse().getValueAsEnum());
AddressDt ref = actual.getFoo();
assertEquals("line1", ref.getLineFirstRep().getValue());
}
@Test
public void testExtensionOnComposite() throws Exception {
Patient patient = new Patient();
HumanNameDt name = patient.addName();
name.addFamily().setValue("Shmoe");
HumanNameDt given = name.addGiven("Joe");
ExtensionDt ext2 = new ExtensionDt(false, "http://examples.com#givenext", new StringDt("Hello"));
given.addUndeclaredExtension(ext2);
String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
ourLog.info(output);
String enc = ourCtx.newXmlParser().encodeResourceToString(patient);
assertThat(enc, containsString("<name><extension url=\"http://examples.com#givenext\"><valueString value=\"Hello\"/></extension><family value=\"Shmoe\"/><given value=\"Joe\"/></name>"));
Patient parsed = ourCtx.newXmlParser().parseResource(Patient.class, new StringReader(enc));
assertEquals(1, parsed.getNameFirstRep().getUndeclaredExtensionsByUrl("http://examples.com#givenext").size());
ExtensionDt ext = parsed.getNameFirstRep().getUndeclaredExtensionsByUrl("http://examples.com#givenext").get(0);
assertEquals("Hello", ext.getValueAsPrimitive().getValue());
}
@Test
public void testExtensionOnPrimitive() throws Exception {
Patient patient = new Patient();
HumanNameDt name = patient.addName();
StringDt family = name.addFamily();
family.setValue("Shmoe");
ExtensionDt ext2 = new ExtensionDt(false, "http://examples.com#givenext", new StringDt("Hello"));
family.addUndeclaredExtension(ext2);
String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
ourLog.info(output);
String enc = ourCtx.newXmlParser().encodeResourceToString(patient);
assertThat(enc, containsString("<name><family value=\"Shmoe\"><extension url=\"http://examples.com#givenext\"><valueString value=\"Hello\"/></extension></family></name>"));
Patient parsed = ourCtx.newXmlParser().parseResource(Patient.class, new StringReader(enc));
assertEquals(1, parsed.getNameFirstRep().getFamilyFirstRep().getUndeclaredExtensionsByUrl("http://examples.com#givenext").size());
ExtensionDt ext = parsed.getNameFirstRep().getFamilyFirstRep().getUndeclaredExtensionsByUrl("http://examples.com#givenext").get(0);
assertEquals("Hello", ext.getValueAsPrimitive().getValue());
}
@Test
public void testExtensionsWithDatatypes() throws DataFormatException {
MyPatient patient = new MyPatient();
patient.setPetName(new StringDt("Fido"));
patient.getImportantDates().add(new DateTimeDt("2010-01-02"));
patient.getImportantDates().add(new DateTimeDt("2014-01-26T11:11:11"));
patient.addName().addFamily("Smith");
IParser p = ourCtx.newXmlParser();
String str = p.encodeResourceToString(patient);
ourLog.info(str);
assertThat(str, StringContains.containsString("<Patient xmlns=\"http://hl7.org/fhir\">"));
assertThat(str, StringContains.containsString("<extension url=\"http://example.com/dontuse#petname\"><valueString value=\"Fido\"/></extension>"));
assertThat(str, StringContains.containsString("<modifierExtension url=\"http://example.com/dontuse#importantDates\"><valueDateTime value=\"2010-01-02\"/></modifierExtension>"));
assertThat(str, StringContains.containsString("<modifierExtension url=\"http://example.com/dontuse#importantDates\"><valueDateTime value=\"2014-01-26T11:11:11\"/></modifierExtension>"));
assertThat(str, StringContains.containsString("<name><family value=\"Smith\"/></name>"));
}
@Test
public void testLoadAndAncodeMessage() throws SAXException, IOException {
//@formatter:off
String msg = "<Patient xmlns=\"http://hl7.org/fhir\">"
+ "<text><status value=\"generated\" /><div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal: 444333333 </div></text>"
+ "<identifier><label value=\"SSN\" /><system value=\"http://orionhealth.com/mrn\" /><value value=\"PRP1660\" /></identifier>"
+ "<name><use value=\"official\" /><family value=\"Cardinal\" /><given value=\"John\" /></name>"
+ "<name><family value=\"Kramer\" /><given value=\"Doe\" /></name>"
+ "<telecom><system value=\"phone\" /><value value=\"555-555-2004\" /><use value=\"work\" /></telecom>"
+ "<gender><coding><system value=\"http://hl7.org/fhir/v3/AdministrativeGender\" /><code value=\"M\" /></coding></gender>"
+ "<address><use value=\"home\" /><line value=\"2222 Home Street\" /></address><active value=\"true\" />"
+ "</Patient>";
//@formatter:on
Patient patient = ourCtx.newXmlParser().parseResource(Patient.class, msg);
assertEquals(NarrativeStatusEnum.GENERATED, patient.getText().getStatus().getValueAsEnum());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal: 444333333 </div>", patient.getText().getDiv().getValueAsString());
assertEquals("PRP1660", patient.getIdentifier().get(0).getValue().getValueAsString());
String encoded = ourCtx.newXmlParser().encodeResourceToString(patient);
Diff d = new Diff(new StringReader(msg), new StringReader(encoded));
assertTrue(d.toString(), d.identical());
}
@Test
public void testLoadAndEncodeDeclaredExtensions() throws ConfigurationException, DataFormatException, SAXException, IOException {
IParser p = new FhirContext(ResourceWithExtensionsA.class).newXmlParser();
//@formatter:off
String msg = "<ResourceWithExtensionsA xmlns=\"http://hl7.org/fhir\">\n" +
" <extension url=\"http://foo/#f1\">\n" +
" <valueString value=\"Foo1Value\"/>\n" +
" </extension>\n" +
" <extension url=\"http://foo/#f1\">\n" +
" <valueString value=\"Foo1Value2\"/>\n" +
" </extension>\n" +
" <extension url=\"http://bar/#b1\">\n" +
" <extension url=\"http://bar/#b1/1\">\n" +
" <valueDate value=\"2013-01-01\"/>\n" +
" </extension>\n" +
" <extension url=\"http://bar/#b1/2\">\n" +
" <extension url=\"http://bar/#b1/2/1\">\n" +
" <valueDate value=\"2013-01-02\"/>\n" +
" </extension>\n" +
" <extension url=\"http://bar/#b1/2/1\">\n" +
" <valueDate value=\"2013-01-12\"/>\n" +
" </extension>\n" +
" <extension url=\"http://bar/#b1/2/2\">\n" +
" <valueDate value=\"2013-01-03\"/>\n" +
" </extension>\n" +
" </extension>\n" +
" </extension>\n" +
" <modifierExtension url=\"http://foo/#f2\">\n" +
" <valueString value=\"Foo2Value1\"/>\n" +
" </modifierExtension>\n" +
" <identifier>\n" +
" <label value=\"IdentifierLabel\"/>\n" +
" </identifier>\n" +
"</ResourceWithExtensionsA>";
//@formatter:on
ResourceWithExtensionsA resource = (ResourceWithExtensionsA) p.parseResource(msg);
assertEquals("IdentifierLabel", resource.getIdentifier().get(0).getLabel().getValue());
assertEquals("Foo1Value", resource.getFoo1().get(0).getValue());
assertEquals("Foo1Value2", resource.getFoo1().get(1).getValue());
assertEquals("Foo2Value1", resource.getFoo2().getValue());
assertEquals("2013-01-01", resource.getBar1().get(0).getBar11().get(0).getValueAsString());
assertEquals("2013-01-02", resource.getBar1().get(0).getBar12().get(0).getBar121().get(0).getValueAsString());
assertEquals("2013-01-12", resource.getBar1().get(0).getBar12().get(0).getBar121().get(1).getValueAsString());
assertEquals("2013-01-03", resource.getBar1().get(0).getBar12().get(0).getBar122().get(0).getValueAsString());
String encoded = p.encodeResourceToString(resource);
ourLog.info(encoded);
Diff d = new Diff(new StringReader(msg), new StringReader(encoded));
assertTrue(d.toString(), d.identical());
}
@Test
public void testLoadAndEncodeUndeclaredExtensions() throws ConfigurationException, DataFormatException, SAXException, IOException {
IParser p = ourCtx.newXmlParser();
//@formatter:off
String msg = "<Patient xmlns=\"http://hl7.org/fhir\">\n" +
" <extension url=\"http://foo/#f1\">\n" +
" <valueString value=\"Foo1Value\"/>\n" +
" </extension>\n" +
" <extension url=\"http://foo/#f1\">\n" +
" <valueString value=\"Foo1Value2\"/>\n" +
" </extension>\n" +
" <extension url=\"http://bar/#b1\">\n" +
" <extension url=\"http://bar/#b1/1\">\n" +
" <valueDate value=\"2013-01-01\"/>\n" +
" </extension>\n" +
" <extension url=\"http://bar/#b1/2\">\n" +
" <extension url=\"http://bar/#b1/2/1\">\n" +
" <valueDate value=\"2013-01-02\"/>\n" +
" </extension>\n" +
" <extension url=\"http://bar/#b1/2/1\">\n" +
" <valueDate value=\"2013-01-12\"/>\n" +
" </extension>\n" +
" <extension url=\"http://bar/#b1/2/2\">\n" +
" <valueDate value=\"2013-01-03\"/>\n" +
" </extension>\n" +
" </extension>\n" +
" </extension>\n" +
" <modifierExtension url=\"http://foo/#f2\">\n" +
" <valueString value=\"Foo2Value1\"/>\n" +
" </modifierExtension>\n" +
" <identifier>\n" +
" <label value=\"IdentifierLabel\"/>\n" +
" </identifier>\n" +
"</Patient>";
//@formatter:on
Patient resource = (Patient) p.parseResource(msg);
assertEquals("IdentifierLabel", resource.getIdentifier().get(0).getLabel().getValue());
assertEquals("Foo1Value", resource.getUndeclaredExtensions().get(0).getValueAsPrimitive().getValueAsString());
assertEquals("Foo1Value2", resource.getUndeclaredExtensions().get(1).getValueAsPrimitive().getValueAsString());
assertEquals("Foo2Value1", resource.getUndeclaredModifierExtensions().get(0).getValueAsPrimitive().getValueAsString());
assertEquals("2013-01-01", resource.getUndeclaredExtensions().get(2).getUndeclaredExtensions().get(0).getValueAsPrimitive().getValueAsString());
assertEquals("2013-01-02", resource.getUndeclaredExtensions().get(2).getUndeclaredExtensions().get(1).getUndeclaredExtensions().get(0).getValueAsPrimitive().getValueAsString());
String encoded = p.encodeResourceToString(resource);
ourLog.info(encoded);
Diff d = new Diff(new StringReader(msg), new StringReader(encoded));
assertTrue(d.toString(), d.identical());
}
@Test
public void testLoadObservation() throws ConfigurationException, DataFormatException, IOException {
IParser p = ourCtx.newXmlParser();
String string = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/observation-example-eeg.xml"), Charset.forName("UTF-8"));
IBaseResource resource = p.parseResource(string);
String result = p.encodeResourceToString(resource);
ourLog.info(result);
}
@Test
public void testLoadPatient() throws ConfigurationException, DataFormatException, IOException {
IParser p = ourCtx.newXmlParser();
String string = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/patient-example-dicom.xml"), Charset.forName("UTF-8"));
IBaseResource resource = p.parseResource(string);
String result = p.encodeResourceToString(resource);
ourLog.info(result);
// Nothing
string = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/patient-example-us-extensions.xml"), Charset.forName("UTF-8"));
resource = p.parseResource(string);
result = p.encodeResourceToString(resource);
ourLog.info(result);
}
@Test
public void testLoadQuestionnaire() throws ConfigurationException, DataFormatException, IOException {
IParser p = ourCtx.newXmlParser();
String string = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/questionnaire-example.xml"), Charset.forName("UTF-8"));
IBaseResource resource = p.parseResource(string);
String result = p.encodeResourceToString(resource);
ourLog.info(result);
}
@Test
public void testMessageWithMultipleTypes() throws SAXException, IOException {
//@formatter:off
String msg = "<Patient xmlns=\"http://hl7.org/fhir\">"
+ "<identifier><label value=\"SSN\" /><system value=\"http://orionhealth.com/mrn\" /><value value=\"PRP1660\" /></identifier>"
+ "</Patient>";
//@formatter:on
Patient patient1 = ourCtx.newXmlParser().parseResource(Patient.class, msg);
String encoded1 = ourCtx.newXmlParser().encodeResourceToString(patient1);
ca.uhn.fhir.testmodel.Patient patient2 = ourCtx.newXmlParser().parseResource(ca.uhn.fhir.testmodel.Patient.class, msg);
String encoded2 = ourCtx.newXmlParser().encodeResourceToString(patient2);
Diff d = new Diff(new StringReader(encoded1), new StringReader(encoded2));
assertTrue(d.toString(), d.identical());
}
@Test
public void testMoreExtensions() throws Exception {
Patient patient = new Patient();
patient.addIdentifier(IdentifierUseEnum.OFFICIAL, "urn:example", "7000135", null);
ExtensionDt ext = new ExtensionDt();
ext.setModifier(false);
ext.setUrl("http://example.com/extensions#someext");
ext.setValue(new DateTimeDt("2011-01-02T11:13:15"));
// Add the extension to the resource
patient.addUndeclaredExtension(ext);
// END SNIPPET: resourceExtension
// START SNIPPET: resourceStringExtension
HumanNameDt name = patient.addName();
name.addFamily().setValue("Shmoe");
StringDt given = name.addGiven();
given.setValue("Joe");
ExtensionDt ext2 = new ExtensionDt(false, "http://examples.com#givenext", new StringDt("given"));
given.addUndeclaredExtension(ext2);
// END SNIPPET: resourceStringExtension
// START SNIPPET: subExtension
ExtensionDt parent = new ExtensionDt(false, "http://example.com#parent");
patient.addUndeclaredExtension(parent);
ExtensionDt child1 = new ExtensionDt(false, "http://example.com#child", new StringDt("value1"));
parent.addUndeclaredExtension(child1);
ExtensionDt child2 = new ExtensionDt(false, "http://example.com#child", new StringDt("value1"));
parent.addUndeclaredExtension(child2);
// END SNIPPET: subExtension
String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
ourLog.info(output);
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("<extension url=\"http://example.com#parent\"><extension url=\"http://example.com#child\"><valueString value=\"value1\"/></extension><extension url=\"http://example.com#child\"><valueString value=\"value1\"/></extension></extension>"));
assertThat(enc, containsString("<given value=\"Joe\"><extension url=\"http://examples.com#givenext\"><valueString value=\"given\"/></extension></given>"));
}
@Test
public void testNarrativeGeneration() throws DataFormatException {
Patient patient = new Patient();
patient.addName().addFamily("Smith");
INarrativeGenerator gen = new INarrativeGenerator() {
@Override
public void generateNarrative(FhirContext theContext, IBaseResource theResource, INarrative theNarrative) {
try {
theNarrative.setDivAsString("<div>help</div>");
} catch (Exception e) {
throw new Error(e);
}
theNarrative.setStatusAsString("generated");
}
};
try {
ourCtx.setNarrativeGenerator(gen);
IParser p = ourCtx.newXmlParser();
String str = p.encodeResourceToString(patient);
ourLog.info(str);
assertThat(str, StringContains.containsString("<Patient xmlns=\"http://hl7.org/fhir\">"));
assertThat(str, StringContains.containsString("<Patient xmlns=\"http://hl7.org/fhir\">"));
} finally {
ourCtx.setNarrativeGenerator(null);
}
}
@Test
public void testNestedContainedResources() {
Observation A = new Observation();
A.getName().setText("A");
Observation B = new Observation();
B.getName().setText("B");
A.addRelated().setTarget(new ResourceReferenceDt(B));
Observation C = new Observation();
C.getName().setText("C");
B.addRelated().setTarget(new ResourceReferenceDt(C));
String str = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(A);
ourLog.info(str);
assertThat(str, stringContainsInOrder(Arrays.asList("<text value=\"B\"/>", "<text value=\"C\"/>", "<text value=\"A\"/>")));
assertThat(str, stringContainsInOrder(Arrays.asList("<contained>", "</contained>")));
// Only one pair of (outer) contained blocks
int idx0 = str.indexOf("<contained>");
int idx1 = str.indexOf("<contained>", idx0 + 1);
int idx2 = str.indexOf("<contained>", idx1 + 1);
assertNotEquals(-1, idx0);
assertNotEquals(-1, idx1);
assertEquals(-1, idx2);
Observation obs = ourCtx.newXmlParser().parseResource(Observation.class, str);
assertEquals("A", obs.getName().getText().getValue());
Observation obsB = (Observation) obs.getRelatedFirstRep().getTarget().getResource();
assertEquals("B", obsB.getName().getText().getValue());
Observation obsC = (Observation) obsB.getRelatedFirstRep().getTarget().getResource();
assertEquals("C", obsC.getName().getText().getValue());
}
@Test
public void testParseAndEncodeHugeValue() {
int len = 1000000;
byte[] bytes = new byte[len];
for (int i = 0; i < len; i++) {
bytes[i] = (byte) (Math.random() * Byte.MAX_VALUE);
}
AttachmentDt att = new AttachmentDt();
att.setData(bytes);
Observation obs = new Observation();
obs.setValue(att);
String str = ourCtx.newXmlParser().encodeResourceToString(obs);
assertThat(str.length(), Matchers.greaterThan(len));
obs = ourCtx.newXmlParser().parseResource(Observation.class, str);
att = (AttachmentDt) obs.getValue();
assertArrayEquals(bytes, att.getData().getValue());
}
/**
* See #131
*/
@Test
public void testParseAndReencodeCondition() {
FhirContext ctx = FhirContext.forDstu1();
ctx.setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
InputStreamReader reader = new InputStreamReader(XmlParserTest.class.getResourceAsStream("/condition.xml"));
Condition cond = ctx.newXmlParser().parseResource(Condition.class, reader);
String enc = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(cond);
ourLog.info(enc);
assertThat(enc, not(containsString("generated")));
}
@Test
public void testParseBinaryResource() {
Binary val = ourCtx.newXmlParser().parseResource(Binary.class, "<Binary xmlns=\"http://hl7.org/fhir\" contentType=\"foo\">AQIDBA==</Binary>");
assertEquals("foo", val.getContentType());
assertArrayEquals(new byte[] { 1, 2, 3, 4 }, val.getContent());
}
@SuppressWarnings("deprecation")
@Test
public void testParseBundle() {
//@formatter:off
String summaryText =
"<div xmlns=\"http://www.w3.org/1999/xhtml\">\n" +
" <p>Value set \"LOINC Codes for Cholesterol\": This is an example value set that includes \n" +
" all the LOINC codes for serum cholesterol from v2.36. \n" +
" Developed by: FHIR project team (example)</p></div>";
String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n" +
" <title>FHIR Core Valuesets</title>\n" +
" <id>http://hl7.org/fhir/profile/valuesets</id>\n" +
" <link href=\"http://hl7.org/implement/standards/fhir/valuesets.xml\" rel=\"self\"/>\n" +
" <category term=\"http://hl7.org/fhir/tag/message\" label=\"Message\" scheme=\"http://hl7.org/fhir/tag\"/>\n" +
" <updated>2014-02-10T04:11:24.435-00:00</updated>\n" +
" <entry>\n" +
" <title>Valueset "256a5231-a2bb-49bd-9fea-f349d428b70d" to support automated processing</title>\n" +
" <id>http://hl7.org/fhir/valueset/256a5231-a2bb-49bd-9fea-f349d428b70d</id>\n" +
" <link href=\"http://hl7.org/implement/standards/fhir/valueset/256a5231-a2bb-49bd-9fea-f349d428b70d\" rel=\"self\"/>\n" +
" <link href=\"http://hl7.org/foo\" rel=\"alternate\"/>\n" +
" <link href=\"http://hl7.org/foo/search\" rel=\"search\"/>\n" +
" <updated>2014-02-10T04:10:46.987-00:00</updated>\n" +
" <author>\n" +
" <name>HL7, Inc (FHIR Project)</name>\n" +
" <uri>http://hl7.org/fhir</uri>\n" +
" </author>\n" +
" <published>2014-02-10T04:10:46.987-00:00</published>\n" +
" <category term=\"term\" label=\"label\" scheme=\"http://foo\"/>\n "+
" <content type=\"text/xml\">\n" +
" <ValueSet xmlns=\"http://hl7.org/fhir\">\n" +
" <text>\n" +
" <status value=\"generated\"/>" +
" </text>\n" +
" <identifier value=\"256a5231-a2bb-49bd-9fea-f349d428b70d\"/>\n" +
" <version value=\"20120613\"/>\n" +
" <name value=\"LOINC Codes for Cholesterol\"/>\n" +
" <publisher value=\"FHIR project team (example)\"/>\n" +
" <telecom>\n" +
" <system value=\"url\"/>\n" +
" <value value=\"http://hl7.org/fhir\"/>\n" +
" </telecom>\n" +
" <description value=\"This is an example value set that includes all the LOINC codes for serum cholesterol from v2.36\"/>\n" +
" <status value=\"draft\"/>\n" +
" <experimental value=\"true\"/>\n" +
" <date value=\"2012-06-13\"/>\n" +
" <compose>\n" +
" <include>\n" +
" <system value=\"http://loinc.org\"/>\n" +
" <version value=\"2.36\"/>\n" +
" <code value=\"14647-2\"/>\n" +
" <code value=\"2093-3\"/>\n" +
" <code value=\"35200-5\"/>\n" +
" <code value=\"9342-7\"/>\n" +
" </include>\n" +
" </compose>\n" +
" </ValueSet>\n" +
" </content>\n" +
" <summary type=\"xhtml\">"+
summaryText +
" </summary>\n" +
" </entry>" +
"</feed>";
//@formatter:on
IParser p = new FhirContext(ValueSet.class).newXmlParser();
Bundle bundle = p.parseBundle(msg);
assertEquals(1, bundle.getCategories().size());
assertEquals("http://hl7.org/fhir/tag", bundle.getCategories().get(0).getScheme());
assertEquals("FHIR Core Valuesets", bundle.getTitle().getValue());
assertEquals("http://hl7.org/implement/standards/fhir/valuesets.xml", bundle.getLinkSelf().getValue());
assertEquals("2014-02-10T04:11:24.435-00:00", bundle.getUpdated().getValueAsString());
assertEquals(1, bundle.getEntries().size());
BundleEntry entry = bundle.getEntries().get(0);
assertEquals("HL7, Inc (FHIR Project)", entry.getAuthorName().getValue());
assertEquals("http://hl7.org/fhir/valueset/256a5231-a2bb-49bd-9fea-f349d428b70d", entry.getId().getValue());
assertEquals("http://hl7.org/foo", entry.getLinkAlternate().getValue());
assertEquals("http://hl7.org/foo/search", entry.getLinkSearch().getValue());
assertEquals(1, entry.getCategories().size());
assertEquals("term", entry.getCategories().get(0).getTerm());
assertEquals("label", entry.getCategories().get(0).getLabel());
assertEquals("http://foo", entry.getCategories().get(0).getScheme());
ValueSet resource = (ValueSet) entry.getResource();
assertEquals("LOINC Codes for Cholesterol", resource.getName().getValue());
String exp = summaryText.trim();
exp = exp.replace("\"LOINC", ""LOINC");
exp = exp.replace("terol\"", "terol"");
assertEquals(exp, entry.getSummary().getValueAsString().trim());
TagList tl = (TagList) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
assertEquals(1, tl.size());
assertEquals("term", tl.get(0).getTerm());
assertEquals("label", tl.get(0).getLabel());
assertEquals("http://foo", tl.get(0).getScheme());
assertEquals("256a5231-a2bb-49bd-9fea-f349d428b70d", resource.getId().getIdPart());
msg = msg.replace("<link href=\"http://hl7.org/implement/standards/fhir/valueset/256a5231-a2bb-49bd-9fea-f349d428b70d\" rel=\"self\"/>", "<link href=\"http://hl7.org/implement/standards/fhir/valueset/256a5231-a2bb-49bd-9fea-f349d428b70d/_history/12345\" rel=\"self\"/>");
entry = p.parseBundle(msg).getEntries().get(0);
resource = (ValueSet) entry.getResource();
assertEquals("256a5231-a2bb-49bd-9fea-f349d428b70d", resource.getId().getIdPart());
assertEquals("12345", resource.getId().getVersionIdPart());
assertEquals("12345", ((IdDt) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.VERSION_ID)).getVersionIdPart());
assertThat(entry.getSummary().getValueAsString(), containsString("LOINC Codes for Cholesterol"));
}
@SuppressWarnings("deprecation")
@Test
public void testParseBundleDeletedEntry() {
//@formatter:off
String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\">" +
"<title>FHIR Core Valuesets</title>" +
"<id>http://hl7.org/fhir/profile/valuesets</id>" +
"<link rel=\"self\" href=\"http://hl7.org/implement/standards/fhir/valuesets.xml\"/>" +
"<updated>2014-02-10T04:11:24.435+00:00</updated>" +
"<at:deleted-entry xmlns:at=\"http://purl.org/atompub/tombstones/1.0\" ref=\"http://foo/Patient/1\" when=\"2013-02-10T04:11:24.435+00:00\">" +
"<at:by>" +
"<at:name>John Doe</at:name>" +
"<at:email>jdoe@example.org</at:email>" +
"</at:by>" +
"<at:comment>Removed comment spam</at:comment>" +
"<link rel=\"self\" href=\"http://foo/Patient/1/_history/2\"/>" +
"</at:deleted-entry>" +
"</feed>";
//@formatter:on
IParser p = ourCtx.newXmlParser();
Bundle bundle = p.parseBundle(msg);
BundleEntry entry = bundle.getEntries().get(0);
assertEquals("http://foo/Patient/1", entry.getId().getValue());
assertEquals("2013-02-10T04:11:24.435+00:00", entry.getDeletedAt().getValueAsString());
assertEquals("http://foo/Patient/1/_history/2", entry.getLinkSelf().getValue());
assertEquals("1", entry.getResource().getId().getIdPart());
assertEquals("2", entry.getResource().getId().getVersionIdPart());
assertEquals("2", ((IdDt) entry.getResource().getResourceMetadata().get(ResourceMetadataKeyEnum.VERSION_ID)).getVersionIdPart());
assertEquals("John Doe", entry.getDeletedByName().getValue());
assertEquals("jdoe@example.org", entry.getDeletedByEmail().getValue());
assertEquals("Removed comment spam", entry.getDeletedComment().getValue());
assertEquals(new InstantDt("2013-02-10T04:11:24.435+00:00"), entry.getResource().getResourceMetadata().get(ResourceMetadataKeyEnum.DELETED_AT));
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(bundle));
String encoded = ourCtx.newXmlParser().encodeBundleToString(bundle);
assertEquals(msg, encoded);
}
@Test
public void testParseBundleLarge() throws IOException {
String msg = IOUtils.toString(XmlParser.class.getResourceAsStream("/atom-document-large.xml"));
IParser p = ourCtx.newXmlParser();
Bundle bundle = p.parseBundle(msg);
assertEquals("http://spark.furore.com/fhir/_snapshot?id=327d6bb9-83b0-4929-aa91-6dd9c41e587b&start=0&_count=20", bundle.getLinkSelf().getValue());
assertEquals("Patient resource with id 3216379", bundle.getEntries().get(0).getTitle().getValue());
assertEquals("http://spark.furore.com/fhir/Patient/3216379", bundle.getEntries().get(0).getId().getValue());
assertEquals("3216379", bundle.getEntries().get(0).getResource().getId().getIdPart());
}
@Test
public void testParseBundleWithMixedReturnTypes() {
InputStreamReader str = new InputStreamReader(getClass().getResourceAsStream("/mixed-return-bundle.xml"));
Bundle b = ourCtx.newXmlParser().parseBundle(Patient.class, str);
assertEquals(Patient.class, b.getEntries().get(0).getResource().getClass());
assertEquals(Patient.class, b.getEntries().get(1).getResource().getClass());
assertEquals(Organization.class, b.getEntries().get(2).getResource().getClass());
}
/**
* see #144 and #146
*/
@Test
public void testParseContained() {
FhirContext c = FhirContext.forDstu1();
IParser parser = c.newXmlParser().setPrettyPrint(true);
Observation o = new Observation();
o.getName().setText("obs text");
Patient p = new Patient();
p.addName().addFamily("patient family");
o.getSubject().setResource(p);
String enc = parser.encodeResourceToString(o);
ourLog.info(enc);
//@formatter:off
assertThat(enc, stringContainsInOrder(
"<Observation xmlns=\"http://hl7.org/fhir\">",
"<contained>",
"<Patient xmlns=\"http://hl7.org/fhir\" id=\"1\">",
"</contained>",
"<reference value=\"#1\"/>"
));
//@formatter:on
o = parser.parseResource(Observation.class, enc);
assertEquals("obs text", o.getName().getText().getValue());
assertNotNull(o.getSubject().getResource());
p = (Patient) o.getSubject().getResource();
assertEquals("patient family", p.getNameFirstRep().getFamilyAsSingleString());
}
/**
* Thanks to Alexander Kley!
*/
@Test
public void testParseContainedBinaryResource() {
byte[] bin = new byte[] { 0, 1, 2, 3, 4 };
final Binary binary = new Binary("PatientConsent", bin);
// binary.setId(UUID.randomUUID().toString());
DocumentManifest manifest = new DocumentManifest();
// manifest.setId(UUID.randomUUID().toString());
manifest.setType(new CodeableConceptDt("mySystem", "PatientDocument"));
manifest.setMasterIdentifier("mySystem", UUID.randomUUID().toString());
manifest.addContent().setResource(binary);
manifest.setStatus(DocumentReferenceStatusEnum.CURRENT);
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(manifest);
ourLog.info(encoded);
assertThat(encoded, StringContainsInOrder.stringContainsInOrder(Arrays.asList("contained>", "<Binary", "</contained>")));
DocumentManifest actual = ourCtx.newXmlParser().parseResource(DocumentManifest.class, encoded);
assertEquals(1, actual.getContained().getContainedResources().size());
assertEquals(1, actual.getContent().size());
assertNotNull(actual.getContent().get(0).getResource());
}
@Test
public void testParseContainedResources() throws IOException {
String msg = IOUtils.toString(XmlParser.class.getResourceAsStream("/contained-diagnosticreport.xml"));
IParser p = ourCtx.newXmlParser();
DiagnosticReport resource = p.parseResource(DiagnosticReport.class, msg);
Observation obs = (Observation) resource.getResult().get(0).getResource();
assertNotNull(obs);
assertEquals("718-7", obs.getName().getCoding().get(0).getCode().getValue());
obs = (Observation) resource.getResult().get(1).getResource();
assertNotNull(obs);
assertEquals("789-8", obs.getName().getCoding().get(0).getCode().getValue());
}
/**
* If the XML encoded resource has multiple contained resources in a single <contained></contained> tag, we still
* want to handle this as best we can, even though it's not technically correct. See #84
*/
@Test
public void testParseContainedResourcesWithSingleContainedElement() throws IOException {
String msg = IOUtils.toString(XmlParser.class.getResourceAsStream("/contained-diagnosticreport-singlecontainedelement.xml"));
IParser p = ourCtx.newXmlParser();
DiagnosticReport resource = p.parseResource(DiagnosticReport.class, msg);
Observation obs = (Observation) resource.getResult().get(0).getResource();
assertNotNull(obs);
assertEquals("718-7", obs.getName().getCoding().get(0).getCode().getValue());
obs = (Observation) resource.getResult().get(1).getResource();
assertNotNull(obs);
assertEquals("789-8", obs.getName().getCoding().get(0).getCode().getValue());
}
@Test
public void testParseEncodeNarrative() {
String input = "<Patient xmlns=\"http://hl7.org/fhir\"><text><status value=\"generated\"/><div xmlns=\"http://www.w3.org/1999/xhtml\"><div class=\"hapiHeaderText\"> Donald null <b>DUCK </b></div><table class=\"hapiPropertyTable\"><tbody><tr><td>Identifier</td><td>7000135</td></tr><tr><td>Address</td><td><span>10 Duxon Street </span><br/><span>VICTORIA </span><span>BC </span><span>Can </span></td></tr><tr><td>Date of birth</td><td><span>01 June 1980</span></td></tr></tbody></table></div></text><identifier><use value=\"official\"/><label value=\"University Health Network MRN 7000135\"/><system value=\"urn:oid:2.16.840.1.113883.3.239.18.148\"/><value value=\"7000135\"/><assigner><reference value=\"Organization/1.3.6.1.4.1.12201\"/></assigner></identifier><name><family value=\"Duck\"/><given value=\"Donald\"/></name><telecom><system value=\"phone\"/><use value=\"home\"/></telecom><telecom><system value=\"phone\"/><use value=\"work\"/></telecom><telecom><system value=\"phone\"/><use value=\"mobile\"/></telecom><telecom><system value=\"email\"/><use value=\"home\"/></telecom><gender><coding><system value=\"http://hl7.org/fhir/v3/AdministrativeGender\"/><code value=\"M\"/></coding></gender><birthDate value=\"1980-06-01T00:00:00\"/><address><use value=\"home\"/><line value=\"10 Duxon Street\"/><city value=\"VICTORIA\"/><state value=\"BC\"/><zip value=\"V8N 1Y4\"/><country value=\"Can\"/></address><managingOrganization><reference value=\"Organization/1.3.6.1.4.1.12201\"/></managingOrganization></Patient>";
IBaseResource res = ourCtx.newXmlParser().parseResource(input);
String output = ourCtx.newXmlParser().encodeResourceToString(res);
// Should occur exactly twice (once for the resource, once for the DIV
assertThat(output, (StringContainsInOrder.stringContainsInOrder(Arrays.asList("Patient xmlns", "div xmlns"))));
assertThat(output, not(StringContainsInOrder.stringContainsInOrder(Arrays.asList("b xmlns"))));
output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(res);
// Should occur exactly twice (once for the resource, once for the DIV
assertThat(output, (StringContainsInOrder.stringContainsInOrder(Arrays.asList("Patient xmlns", "div xmlns"))));
assertThat(output, not(StringContainsInOrder.stringContainsInOrder(Arrays.asList("b xmlns"))));
}
@Test
public void testParseErrorHandlerDuplicateElement() {
String input = "<Patient><active value=\"true\"/><active value=\"false\"/></Patient>";
try {
ourCtx.newXmlParser().setParserErrorHandler(new StrictErrorHandler()).parseResource(Patient.class, input);
fail();
} catch (DataFormatException e) {
assertThat(e.getMessage(), containsString("Multiple repetitions"));
}
Patient p = ourCtx.newXmlParser().setParserErrorHandler(new LenientErrorHandler()).parseResource(Patient.class, input);
assertEquals("true", p.getActive().getValueAsString());
}
@Test
public void testParseErrorHandlerNoError() {
String input = "<Patient></Patient>";
ourCtx.newXmlParser().setParserErrorHandler(new StrictErrorHandler()).parseResource(Patient.class, input);
}
@Test
public void testParseErrorHandlerUnexpectedAttribute() {
String input = "<Patient><name><family foo=\"FOO\" value=\"AAA\" bar=\"BAR\"/></name></Patient>";
try {
ourCtx.newXmlParser().setParserErrorHandler(new StrictErrorHandler()).parseResource(Patient.class, input);
fail();
} catch (DataFormatException e) {
assertThat(e.getMessage(), containsString("'foo'"));
}
Patient p = ourCtx.newXmlParser().setParserErrorHandler(new LenientErrorHandler()).parseResource(Patient.class, input);
assertEquals(p.getName().get(0).getFamily().get(0).getValue(), "AAA");
}
@Test
public void testParseErrorHandlerUnexpectedElement() {
String input = "<Patient><foo><bar/></foo><name><family value=\"AAA\"/></name></Patient>";
try {
ourCtx.newXmlParser().setParserErrorHandler(new StrictErrorHandler()).parseResource(Patient.class, input);
fail();
} catch (DataFormatException e) {
assertThat(e.getMessage(), containsString("'foo'"));
}
Patient p = ourCtx.newXmlParser().setParserErrorHandler(new LenientErrorHandler()).parseResource(Patient.class, input);
assertEquals(p.getName().get(0).getFamily().get(0).getValue(), "AAA");
}
@Test
public void testParseFeedWithListResource() throws ConfigurationException, DataFormatException, IOException {
IParser p = FhirContext.forDstu1().newXmlParser(); // Use new context here
String string = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/feed-with-list.xml"), Charset.forName("UTF-8"));
Bundle bundle = p.parseBundle(string);
ListResource res = (ListResource) bundle.toListOfResources().get(2);
assertEquals("cid:patient@bundle", res.getSubject().getReference().getValue());
}
/**
* This sample has extra elements in <searchParam> that are not actually a part of the spec any more..
*/
@Test
public void testParseFuroreMetadataWithExtraElements() throws IOException {
String msg = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/furore-conformance.xml"));
IParser p = new FhirContext(ValueSet.class).newXmlParser();
Conformance conf = p.parseResource(Conformance.class, msg);
RestResource res = conf.getRestFirstRep().getResourceFirstRep();
assertEquals("_id", res.getSearchParam().get(1).getName().getValue());
}
@Test
public void testParseLanguage() {
String input = "<Patient xmlns=\"http://hl7.org/fhir\"><language value=\"zh-CN\"/><text><status value=\"generated\"/><div xmlns=\"http://www.w3.org/1999/xhtml\"><div class=\"hapiHeaderText\"> 海生 <b>王 </b></div><table class=\"hapiPropertyTable\"><tbody><tr><td>Identifier</td><td>URNo</td></tr><tr><td>Address</td><td><span>99 Houston Road </span><br/><span>BENTLEIGH </span><span>Victoria </span></td></tr><tr><td>Date of birth</td><td><span>01 January 1997</span></td></tr></tbody></table></div></text><identifier><use value=\"usual\"/><label value=\"URNo\"/><value value=\"89532\"/></identifier><name><text value=\"王海生\"/><family value=\"王\"/><given value=\"海生\"/></name><telecom><system value=\"phone\"/><value value=\"9899 9878\"/><use value=\"home\"/></telecom><telecom><system value=\"email\"/><value value=\"zimmerman@datacorp.com.au\"/><use value=\"home\"/></telecom><gender><coding><system value=\"http://hl7.org/fhir/v3/AdministrativeGender\"/><code value=\"M\"/><display value=\"Male\"/></coding><text value=\"Male\"/></gender><birthDate value=\"1997-01-01\"/><address><use value=\"home\"/><text value=\"99 Houston Road, BENTLEIGH, 3204\"/><line value=\"99 Houston Road\"/><city value=\"BENTLEIGH\"/><state value=\"Victoria\"/><zip value=\"3204\"/><period><start value=\"2006-06-16\"/></period></address><active value=\"true\"/></Patient>";
Patient pt = ourCtx.newXmlParser().parseResource(Patient.class, input);
assertEquals("zh-CN", pt.getLanguage().getValue());
}
@Test
public void testParseQuery() {
String msg = "<Query xmlns=\"http://hl7.org/fhir\">\n" + " <text>\n" + " <status value=\"generated\"/>\n" + " <div xmlns=\"http://www.w3.org/1999/xhtml\">[Put rendering here]</div>\n" + " </text>\n" + "\n"
+ " <!-- this is an extermely simple query - a request to execute the query 'example' on the\n" + " responder -->\n" + " <identifier value=\"urn:uuid:42b253f5-fa17-40d0-8da5-44aeb4230376\"/>\n" + " <parameter url=\"http://hl7.org/fhir/query#_query\">\n"
+ " <valueString value=\"example\"/>\n" + " </parameter>\n" + "</Query>";
Query query = ourCtx.newXmlParser().parseResource(Query.class, msg);
assertEquals("urn:uuid:42b253f5-fa17-40d0-8da5-44aeb4230376", query.getIdentifier().getValueAsString());
assertEquals("http://hl7.org/fhir/query#_query", query.getParameterFirstRep().getUrlAsString());
assertEquals("example", query.getParameterFirstRep().getValueAsPrimitive().getValueAsString());
}
@Test
public void testParseReferenceWithUnexpectedChild() {
//@formatter:off
String input =
"<Patient xmlns=\"http://hl7.org/fhir\">"
+ " <managingOrganization>"
+ " <reference value=\"Patient/123\"/>"
+ " <text value=\"BLAH\"/>"
+ " </managingOrganization>"
+ "</Patient>";
//@formatter:on
Patient parsed = ourCtx.newXmlParser().parseResource(Patient.class, input);
String output = ourCtx.newXmlParser().encodeResourceToString(parsed);
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"><managingOrganization><reference value=\"Patient/123\"/></managingOrganization></Patient>", output);
}
/**
* #175
*/
// @Test
public void testParseTextWithUnknownEntity() {
String msg = "<Patient xmlns=\"http://hl7.org/fhir\"><text><status value=\"generated\"/>" + "<div xmlns=\"http://www.w3.org/1999/xhtml\">Trade ™</div></text></Patient>";
Patient pt = ourCtx.newXmlParser().parseResource(Patient.class, msg);
ourLog.info(pt.getText().getDiv().getValueAsString());
assertThat(pt.getText().getDiv().getValueAsString(), containsString("Trade ™"));
String enc = ourCtx.newXmlParser().encodeResourceToString(pt);
ourLog.info(enc);
assertThat(enc, containsString("Trade ™"));
}
@Test
public void testParseWithIncorrectResourceType() {
String input = "<Patient><foo><bar/></foo><name><family value=\"AAA\"/></name></Patient>";
try {
ourCtx.newXmlParser().parseResource(Organization.class, input);
fail();
} catch (DataFormatException e) {
assertThat(e.getMessage(), containsString("expected \"Organization\" but found \"Patient\""));
}
}
@Test
public void testParseWithXmlHeader() throws ConfigurationException, DataFormatException {
IParser p = ourCtx.newXmlParser();
//@formatter:off
String msg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<Patient xmlns=\"http://hl7.org/fhir\">\n" +
" <identifier>\n" +
" <label value=\"IdentifierLabel\"/>\n" +
" </identifier>\n" +
"</Patient>";
//@formatter:on
Patient resource = (Patient) p.parseResource(msg);
assertEquals("IdentifierLabel", resource.getIdentifier().get(0).getLabel().getValue());
}
@Test
public void testProfileWithBoundCode() throws IOException {
String content = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/DMIXAuditException.xml"), "UTF-8");
ourCtx.newXmlParser().parseResource(Profile.class, content);
}
@Test
public void testSimpleResourceEncode() throws IOException, SAXException {
String xmlString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general.json"), Charset.forName("UTF-8"));
Patient obs = ourCtx.newJsonParser().parseResource(Patient.class, xmlString);
List<ExtensionDt> undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getUndeclaredExtensions();
ExtensionDt undeclaredExtension = undeclaredExtensions.get(0);
assertEquals("http://hl7.org/fhir/Profile/iso-21090#qualifier", undeclaredExtension.getUrl());
ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToWriter(obs, new OutputStreamWriter(System.out));
IParser jsonParser = ourCtx.newXmlParser();
String encoded = jsonParser.encodeResourceToString(obs);
ourLog.info(encoded);
String jsonString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general.xml"), Charset.forName("UTF-8"));
String expected = (jsonString);
String actual = (encoded.trim());
Diff d = new Diff(new StringReader(expected), new StringReader(actual));
assertTrue(d.toString(), d.identical());
}
@Test
public void testSimpleResourceEncodeWithCustomType() throws IOException, SAXException {
FhirContext fhirCtx = new FhirContext(MyPatientWithExtensions.class);
String xmlString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general.json"), Charset.forName("UTF-8"));
MyPatientWithExtensions obs = fhirCtx.newJsonParser().parseResource(MyPatientWithExtensions.class, xmlString);
assertEquals(0, obs.getAllUndeclaredExtensions().size());
assertEquals("aaaa", obs.getExtAtt().getContentType().getValue());
assertEquals("str1", obs.getMoreExt().getStr1().getValue());
assertEquals("2011-01-02", obs.getModExt().getValueAsString());
List<ExtensionDt> undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getUndeclaredExtensions();
ExtensionDt undeclaredExtension = undeclaredExtensions.get(0);
assertEquals("http://hl7.org/fhir/Profile/iso-21090#qualifier", undeclaredExtension.getUrl());
fhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToWriter(obs, new OutputStreamWriter(System.out));
IParser jsonParser = fhirCtx.newXmlParser();
String encoded = jsonParser.encodeResourceToString(obs);
ourLog.info(encoded);
String jsonString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general.xml"), Charset.forName("UTF-8"));
String expected = (jsonString);
String actual = (encoded.trim());
Diff d = new Diff(new StringReader(expected), new StringReader(actual));
assertTrue(d.toString(), d.identical());
}
@Test
public void testTagList() {
//@formatter:off
String tagListStr = "<taglist xmlns=\"http://hl7.org/fhir\"> \n" +
" <category term=\"term0\" label=\"label0\" scheme=\"scheme0\" /> \n" +
" <category term=\"term1\" label=\"label1\" scheme=\"\" /> \n" +
" <category term=\"term2\" label=\"label2\" /> \n" +
"</taglist>";
//@formatter:on
TagList tagList = ourCtx.newXmlParser().parseTagList(tagListStr);
assertEquals(3, tagList.size());
assertEquals("term0", tagList.get(0).getTerm());
assertEquals("label0", tagList.get(0).getLabel());
assertEquals("scheme0", tagList.get(0).getScheme());
assertEquals("term1", tagList.get(1).getTerm());
assertEquals("label1", tagList.get(1).getLabel());
assertEquals(null, tagList.get(1).getScheme());
assertEquals("term2", tagList.get(2).getTerm());
assertEquals("label2", tagList.get(2).getLabel());
assertEquals(null, tagList.get(2).getScheme());
/*
* Encode
*/
//@formatter:off
String expected = "<taglist xmlns=\"http://hl7.org/fhir\">" +
"<category term=\"term0\" label=\"label0\" scheme=\"scheme0\"/>" +
"<category term=\"term1\" label=\"label1\"/>" +
"<category term=\"term2\" label=\"label2\"/>" +
"</taglist>";
//@formatter:on
String encoded = ourCtx.newXmlParser().encodeTagListToString(tagList);
assertEquals(expected, encoded);
}
@Test
public void testTotalResultsUsingOldNamespace() {
//@formatter:off
String bundle = "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n" +
" <title>Search results for Patient</title>\n" +
" <id>urn:uuid:374f2876-0da7-4441-87da-526e2fc624f8</id>\n" +
" <totalResults xmlns=\"http://purl.org/atompub/tombstones/1.0\">15</totalResults>\n" +
" <updated>2014-05-04T13:19:47.027-04:00</updated>\n" +
" <author>\n" +
" <name>AEGIS Wildfhir Server</name>\n" +
" </author>" +
"</feed>";
//@formatter:off
Bundle bundleR = ourCtx.newXmlParser().parseBundle(bundle);
assertEquals(15, bundleR.getTotalResults().getValue().intValue());
}
@Test
public void testCustomUrlExtension() {
final String expected = "<Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://www.example.com/petname\"><valueString value=\"myName\"/></extension></Patient>";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringDt("myName"));
final IParser xmlParser = ourCtx.newXmlParser();
xmlParser.setServerBaseUrl("http://www.example.com");
final String parsedPatient = xmlParser.encodeResourceToString(patient);
System.out.println(parsedPatient);
assertEquals(expected, parsedPatient);
// Parse with string
MyPatientWithCustomUrlExtension newPatient = xmlParser.parseResource(MyPatientWithCustomUrlExtension.class, parsedPatient);
assertEquals("myName", newPatient.getPetName().getValue());
// Parse with stream
newPatient = xmlParser.parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertEquals("myName", newPatient.getPetName().getValue());
//Check no NPE if base server not configure
newPatient = ourCtx.newXmlParser().parseResource(MyPatientWithCustomUrlExtension.class, new StringReader(parsedPatient));
assertNull("myName", newPatient.getPetName());
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@Test
public void testCustomUrlExtensioninBundle() {
final String expected = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id/><entry><id/><content type=\"text/xml\"><Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://www.example.com/petname\"><valueString value=\"myName\"/></extension></Patient></content></entry></feed>";
final MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
patient.setPetName(new StringDt("myName"));
final Bundle bundle = new Bundle();
final BundleEntry entry = new BundleEntry();
entry.setResource(patient);
bundle.addEntry(entry);
final IParser xmlParser = ourCtx.newXmlParser();
xmlParser.setServerBaseUrl("http://www.example.com");
final String parsedBundle = xmlParser.encodeBundleToString(bundle);
System.out.println(parsedBundle);
assertEquals(expected, parsedBundle);
// Parse with string
Bundle newBundle = xmlParser.parseBundle(parsedBundle);
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntries().size());
Patient newPatient = (Patient) newBundle.getEntries().get(0).getResource();
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
// Parse with stream
newBundle = xmlParser.parseBundle(new StringReader(parsedBundle));
assertNotNull(newBundle);
assertEquals(1, newBundle.getEntries().size());
newPatient = (Patient) newBundle.getEntries().get(0).getResource();
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
}
@BeforeClass
public static void beforeClass() {
XMLUnit.setIgnoreAttributeOrder(true);
XMLUnit.setIgnoreComments(true);
XMLUnit.setIgnoreWhitespace(true);
ourCtx = FhirContext.forDstu1();
}
@BeforeClass
public static void beforeClass2() {
System.setProperty("file.encoding", "ISO-8859-1");
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
}