package ca.uhn.fhir.parser;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
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.Composition;
import ca.uhn.fhir.model.dstu.resource.Composition.Section;
import ca.uhn.fhir.model.dstu.resource.Condition;
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
import ca.uhn.fhir.model.dstu.resource.Observation;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.resource.Practitioner;
import ca.uhn.fhir.model.dstu.valueset.AdministrativeGenderCodesEnum;
import ca.uhn.fhir.model.dstu.valueset.ConditionStatusEnum;
import ca.uhn.fhir.model.dstu.valueset.NameUseEnum;
import ca.uhn.fhir.model.dstu.valueset.PractitionerRoleEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.server.IVersionSpecificBundleFactory;
import ca.uhn.fhir.util.TestUtil;
/**
* Initially contributed by Alexander Kley for bug #29
*/
public class ContainedResourceEncodingTest {
private static Logger ourLog = LoggerFactory.getLogger(ContainedResourceEncodingTest.class);
private FhirContext ctx;
private Composition comp;
private Practitioner author;
private Patient patient;
private final String patFamName1 = "FirstFamilyName";
private final String patGivName1 = "FirstGivenName";
@Before
public void initTest() {
ourLog.info("[initTest]");
initPatient();
initAuthor();
initComposition();
this.ctx = FhirContext.forDstu1();
}
private void initComposition() {
// new ConditionList
final Condition c = new Condition();
c.setId(UUID.randomUUID().toString());
c.setNotes("This is a note");
c.setSubject(new ResourceReferenceDt(this.patient));
c.setCode(new CodeableConceptDt("mySystem", "theCode"));
c.setStatus(ConditionStatusEnum.CONFIRMED);
// new General Note Section
final Section generalNoteSection = new Section();
generalNoteSection.setElementSpecificId("Note");
generalNoteSection.setTitle("Note");
generalNoteSection.setContent(new ResourceReferenceDt(c));
// new SectionList
final List<Section> sectionList = new ArrayList<Section>();
sectionList.add(generalNoteSection);
// fill composition
this.comp = new Composition();
this.comp.addAuthor().setResource(this.author);
this.comp.setSubject(new ResourceReferenceDt(this.patient));
this.comp.setSection(sectionList);
}
private void initPatient() {
this.patient = new Patient();
this.patient.setId(new IdDt(UUID.randomUUID().toString()));
this.patient.addIdentifier().setSystem("http://example.com/fictitious-mrns").setValue("MRN001");
this.patient.setGender(AdministrativeGenderCodesEnum.M);
this.patient.addName().setUse(NameUseEnum.OFFICIAL).addFamily(this.patFamName1).addGiven(this.patGivName1);
}
private void initAuthor() {
this.author = new Practitioner();
this.author.setId(new IdDt(UUID.randomUUID().toString()));
this.author.addIdentifier().setSystem("DoctorID").setValue("4711");
this.author.addRole(PractitionerRoleEnum.DOCTOR);
this.author.setName(new HumanNameDt().addFamily("Mueller").addGiven("Klaus").addPrefix("Prof. Dr."));
}
@Test
public void testPatient() {
ourLog.debug("[xmlEncoding] encode resource to xml.");
/**
* This works fine, although patient instance is modifing from encoder
*/
final String expectedPatientXml = this.ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(this.patient);
ourLog.debug("[xmlEncoding] first encoding: {}", expectedPatientXml);
final String actualPatientXml = this.ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(this.patient);
// second encoding - xml is corrupt - i.e.: patient content 4 times! should be the same as after first encoding!
ourLog.debug("[xmlEncoding] second encoding: {}", actualPatientXml);
Assert.assertEquals(expectedPatientXml.length(), actualPatientXml.length());
Assert.assertArrayEquals(expectedPatientXml.getBytes(), actualPatientXml.getBytes());
}
@Test
public void testComposition() {
IParser parser = this.ctx.newXmlParser().setPrettyPrint(true);
assertEquals(0, this.comp.getContained().getContainedResources().size());
/**
* This doesn't works, secund encoding creates corrupt xml
*/
final String expectedCompXml = parser.encodeResourceToString(this.comp);
ourLog.debug("[xmlEncoding] first encoding: {}", expectedCompXml);
assertEquals(0, this.comp.getContained().getContainedResources().size());
final String actualCompXml = parser.encodeResourceToString(this.comp);
assertEquals(0, this.comp.getContained().getContainedResources().size());
// second encoding - xml could not be parsed back to compositon - i.e.: patient content 4 times! should be the same
// as after first encoding!
ourLog.debug("[xmlEncoding] second encoding: {}", actualCompXml);
final String thirdCompXml = parser.encodeResourceToString(this.comp);
assertEquals(0, this.comp.getContained().getContainedResources().size());
// third encoding - xml could not be parsed back to compositon i.e.: patient content 4 times! should be the same as
// afterfirst encoding!
ourLog.debug("[xmlEncoding] third encoding: {}", thirdCompXml);
Assert.assertEquals(expectedCompXml.length(), actualCompXml.length());
Assert.assertArrayEquals(expectedCompXml.getBytes(), actualCompXml.getBytes());
}
@Test
public void testBundleWithContained() {
DiagnosticReport dr = new DiagnosticReport();
dr.setId(new IdDt("DiagnosticReport", "123"));
Observation observation = new Observation();
CodeableConceptDt obsName = new CodeableConceptDt();
obsName.setText("name");
observation.setName(obsName);
dr.addResult().setResource(observation);
ArrayList<ResourceReferenceDt> performers = new ArrayList<ResourceReferenceDt>();
ResourceReferenceDt performer = new ResourceReferenceDt();
Practitioner p = new Practitioner();
p.setId("#" + IdDt.newRandomUuid());
p.addIdentifier().setSystem("DoctorID").setValue("4711");
p.addRole(PractitionerRoleEnum.DOCTOR);
p.setName(new HumanNameDt().addFamily("Mueller").addGiven("Klaus").addPrefix("Prof. Dr."));
performer.setResource(p);
performers.add(performer);
observation.setPerformer(performers);
IParser parser = this.ctx.newXmlParser().setPrettyPrint(true);
String xml = parser.encodeResourceToString(dr);
ourLog.info(xml);
Assert.assertTrue(xml.contains("Mueller"));
List<IBaseResource> list = new ArrayList<IBaseResource>();
list.add(dr);
IVersionSpecificBundleFactory factory = ctx.newBundleFactory();
factory.initializeBundleFromResourceList("", list, "http://foo", "http://foo", 2, null);
Bundle bundle = factory.getDstu1Bundle();
parser = this.ctx.newXmlParser().setPrettyPrint(true);
xml = parser.encodeBundleToString(bundle);
ourLog.info(xml);
Assert.assertTrue(xml.contains("Mueller"));
}
@Test
public void testBundleWithContainedWithNoIdDt() {
DiagnosticReport dr = new DiagnosticReport();
dr.setId(new IdDt("DiagnosticReport", "123"));
Observation observation = new Observation();
CodeableConceptDt obsName = new CodeableConceptDt();
obsName.setText("name");
observation.setName(obsName);
ResourceReferenceDt result = dr.addResult();
result.setResource(observation);
ArrayList<ResourceReferenceDt> performers = new ArrayList<ResourceReferenceDt>();
ResourceReferenceDt performer = new ResourceReferenceDt();
Practitioner p = new Practitioner();
// no idDt on practitioner p
p.addIdentifier().setSystem("DoctorID").setValue("4711");
p.addRole(PractitionerRoleEnum.DOCTOR);
p.setName(new HumanNameDt().addFamily("Mueller").addGiven("Klaus").addPrefix("Prof. Dr."));
performer.setResource(p);
performers.add(performer);
observation.setPerformer(performers);
List<IBaseResource> list = new ArrayList<IBaseResource>();
list.add(dr);
IVersionSpecificBundleFactory factory = ctx.newBundleFactory();
factory.initializeBundleFromResourceList("", list, "http://foo", "http://foo", 2, null);
Bundle bundle = factory.getDstu1Bundle();
IParser parser = this.ctx.newXmlParser().setPrettyPrint(true);
String xml = parser.encodeBundleToString(bundle);
ourLog.info(xml);
Assert.assertTrue(xml.contains("Mueller"));
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
}