Narrative generation continuing

This commit is contained in:
jamesagnew 2014-03-25 18:08:57 -04:00
parent 21619e5e46
commit de50244875
8 changed files with 210 additions and 108 deletions

View File

@ -46,12 +46,12 @@
<!-- <dependency> <groupId>org.codehaus.woodstox</groupId> <artifactId>stax2-api</artifactId> <version>3.1.3</version> </dependency> -->
<dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>2.1.2.RELEASE</version>
<optional>true</optional>
</dependency>
</dependency>
<!-- General -->
<dependency>

View File

@ -8,4 +8,9 @@ public abstract class BasePrimitive<T> extends BaseElement implements IPrimitive
return super.isBaseEmpty() && getValue() == null;
}
@Override
public String toString() {
return getClass().getSimpleName() + "[" + getValueAsString() + "]";
}
}

View File

@ -41,30 +41,15 @@ import ca.uhn.fhir.parser.DataFormatException;
public class ThymeleafNarrativeGenerator implements INarrativeGenerator {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ThymeleafNarrativeGenerator.class);
private HashMap<String, String> myProfileToNarrativeTemplate;
private TemplateEngine myProfileTemplateEngine;
private HashMap<String, String> myDatatypeClassNameToNarrativeTemplate;
private TemplateEngine myDatatypeTemplateEngine;
private boolean myIgnoreFailures = true;
/**
* If set to <code>true</code>, which is the default, if any failure occurs during narrative generation the generator will suppress any generated exceptions, and simply return a default narrative
* indicating that no narrative is available.
*/
public boolean isIgnoreFailures() {
return myIgnoreFailures;
}
private boolean myIgnoreMissingTemplates = true;
/**
* If set to <code>true</code>, which is the default, if any failure occurs during narrative generation the generator will suppress any generated exceptions, and simply return a default narrative
* indicating that no narrative is available.
*/
public void setIgnoreFailures(boolean theIgnoreFailures) {
myIgnoreFailures = theIgnoreFailures;
}
private TemplateEngine myProfileTemplateEngine;
private HashMap<String, String> myProfileToNarrativeTemplate;
public ThymeleafNarrativeGenerator() throws IOException {
myProfileToNarrativeTemplate = new HashMap<String, String>();
@ -96,6 +81,48 @@ public class ThymeleafNarrativeGenerator implements INarrativeGenerator {
}
@Override
public NarrativeDt generateNarrative(String theProfile, IResource theResource) {
if (myIgnoreMissingTemplates && !myProfileToNarrativeTemplate.containsKey(theProfile)) {
ourLog.debug("No narrative template available for profile: {}", theProfile);
return new NarrativeDt(new XhtmlDt("<div>No narrative available</div>"), NarrativeStatusEnum.EMPTY);
}
try {
Context context = new Context();
context.setVariable("resource", theResource);
String result = myProfileTemplateEngine.process(theProfile, context);
result = result.replaceAll("\\s+", " ").replace("> ", ">").replace(" <", "<");
XhtmlDt div = new XhtmlDt(result);
return new NarrativeDt(div, NarrativeStatusEnum.GENERATED);
} catch (Exception e) {
if (myIgnoreFailures) {
ourLog.error("Failed to generate narrative", e);
return new NarrativeDt(new XhtmlDt("<div>No narrative available</div>"), NarrativeStatusEnum.EMPTY);
} else {
throw new DataFormatException(e);
}
}
}
/**
* If set to <code>true</code>, which is the default, if any failure occurs during narrative generation the generator will suppress any generated exceptions, and simply return a default narrative
* indicating that no narrative is available.
*/
public boolean isIgnoreFailures() {
return myIgnoreFailures;
}
/**
* If set to true, will return an empty narrative block for any
* profiles where no template is available
*/
public boolean isIgnoreMissingTemplates() {
return myIgnoreMissingTemplates;
}
private void loadProperties(String propFileName) throws IOException {
Properties file = new Properties();
@ -144,37 +171,6 @@ public class ThymeleafNarrativeGenerator implements INarrativeGenerator {
}
}
@Override
public NarrativeDt generateNarrative(String theProfile, IResource theResource) {
try {
Context context = new Context();
context.setVariable("resource", theResource);
String result = myProfileTemplateEngine.process(theProfile, context);
result = result.replaceAll("\\s+", " ").replace("> ", ">").replace(" <", "<");
return new NarrativeDt(new XhtmlDt(result), NarrativeStatusEnum.GENERATED);
} catch (Exception e) {
if (myIgnoreFailures) {
ourLog.error("Failed to generate narrative", e);
return new NarrativeDt(new XhtmlDt("<div>Error: no narrative available</div>"), NarrativeStatusEnum.EMPTY);
} else {
throw new DataFormatException(e);
}
}
}
// public String generateString(Patient theValue) {
//
// Context context = new Context();
// context.setVariable("resource", theValue);
// String result = myProfileTemplateEngine.process("ca/uhn/fhir/narrative/Patient.html", context);
//
// ourLog.info("Result: {}", result);
//
// return result;
// }
private InputStream loadResource(String name) {
if (name.startsWith("classpath:")) {
String cpName = name.substring("classpath:".length());
@ -191,17 +187,31 @@ public class ThymeleafNarrativeGenerator implements INarrativeGenerator {
}
}
private final class ProfileResourceResolver implements IResourceResolver {
@Override
public String getName() {
return getClass().getCanonicalName();
/**
* If set to <code>true</code>, which is the default, if any failure occurs during narrative generation the generator will suppress any generated exceptions, and simply return a default narrative
* indicating that no narrative is available.
*/
public void setIgnoreFailures(boolean theIgnoreFailures) {
myIgnoreFailures = theIgnoreFailures;
}
@Override
public InputStream getResourceAsStream(TemplateProcessingParameters theTemplateProcessingParameters, String theResourceName) {
String template = myProfileToNarrativeTemplate.get(theResourceName);
return new ReaderInputStream(new StringReader(template));
}
// public String generateString(Patient theValue) {
//
// Context context = new Context();
// context.setVariable("resource", theValue);
// String result = myProfileTemplateEngine.process("ca/uhn/fhir/narrative/Patient.html", context);
//
// ourLog.info("Result: {}", result);
//
// return result;
// }
/**
* If set to true, will return an empty narrative block for any
* profiles where no template is available
*/
public void setIgnoreMissingTemplates(boolean theIgnoreMissingTemplates) {
myIgnoreMissingTemplates = theIgnoreMissingTemplates;
}
private final class DatatypeResourceResolver implements IResourceResolver {
@ -223,6 +233,11 @@ public class ThymeleafNarrativeGenerator implements INarrativeGenerator {
super("narrative");
}
@Override
public int getPrecedence() {
return 0;
}
@Override
protected ProcessorResult processAttribute(Arguments theArguments, Element theElement, String theAttributeName) {
final String attributeValue = theElement.getAttributeValue(theAttributeName);
@ -251,11 +266,23 @@ public class ThymeleafNarrativeGenerator implements INarrativeGenerator {
return ProcessorResult.ok();
}
@Override
public int getPrecedence() {
return 0;
}
private final class ProfileResourceResolver implements IResourceResolver {
@Override
public String getName() {
return getClass().getCanonicalName();
}
@Override
public InputStream getResourceAsStream(TemplateProcessingParameters theTemplateProcessingParameters, String theResourceName) {
String template = myProfileToNarrativeTemplate.get(theResourceName);
if (template == null) {
ourLog.info("No narative template for resource profile: {}", theResourceName);
return new ReaderInputStream(new StringReader(""));
}
return new ReaderInputStream(new StringReader(template));
}
}
}

View File

@ -29,12 +29,14 @@ import javax.json.stream.JsonGenerator;
import javax.json.stream.JsonGeneratorFactory;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
import ca.uhn.fhir.context.RuntimeChildNarrativeDefinition;
import ca.uhn.fhir.context.RuntimeChildUndeclaredExtensionDefinition;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.BaseBundle;
@ -48,6 +50,7 @@ import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
import ca.uhn.fhir.model.api.UndeclaredExtension;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.dstu.composite.ContainedDt;
import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.primitive.BooleanDt;
import ca.uhn.fhir.model.primitive.DecimalDt;
@ -55,6 +58,7 @@ import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.IntegerDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.model.primitive.XhtmlDt;
import ca.uhn.fhir.narrative.INarrativeGenerator;
public class JsonParser extends BaseParser implements IParser {
@ -118,7 +122,8 @@ public class JsonParser extends BaseParser implements IParser {
writeAuthor(nextEntry, eventWriter);
IResource resource = nextEntry.getResource();
encodeResourceToJsonStreamWriter(resource, eventWriter, "content");
RuntimeResourceDefinition resDef = myContext.getResourceDefinition(resource);
encodeResourceToJsonStreamWriter(resDef, resource, eventWriter, "content");
eventWriter.writeEnd(); // entry object
}
@ -137,9 +142,12 @@ public class JsonParser extends BaseParser implements IParser {
@Override
public void encodeResourceToWriter(IResource theResource, Writer theWriter) throws IOException {
Validate.notNull(theResource, "Resource can not be null");
JsonGenerator eventWriter = createJsonGenerator(theWriter);
encodeResourceToJsonStreamWriter(theResource, eventWriter, null);
RuntimeResourceDefinition resDef = myContext.getResourceDefinition(theResource);
encodeResourceToJsonStreamWriter(resDef, theResource, eventWriter, null);
eventWriter.flush();
}
@ -431,7 +439,7 @@ public class JsonParser extends BaseParser implements IParser {
return eventWriter;
}
private void encodeChildElementToStreamWriter(JsonGenerator theWriter, IElement theValue, BaseRuntimeElementDefinition<?> theChildDef, String theChildName) throws IOException {
private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theWriter, IElement theValue, BaseRuntimeElementDefinition<?> theChildDef, String theChildName) throws IOException {
switch (theChildDef.getChildType()) {
case PRIMITIVE_DATATYPE: {
@ -470,10 +478,9 @@ public class JsonParser extends BaseParser implements IParser {
if (theChildName != null) {
theWriter.writeStartObject(theChildName);
} else {
theWriter.flush();// TODO: remove
theWriter.writeStartObject();
}
encodeCompositeElementToStreamWriter(theValue, theWriter, childCompositeDef);
encodeCompositeElementToStreamWriter(theResDef, theResource, theValue, theWriter, childCompositeDef);
theWriter.writeEnd();
break;
}
@ -505,7 +512,7 @@ public class JsonParser extends BaseParser implements IParser {
theWriter.writeStartArray(theChildName);
ContainedDt value = (ContainedDt) theValue;
for (IResource next : value.getContainedResources()) {
encodeResourceToJsonStreamWriter(next, theWriter, null);
encodeResourceToJsonStreamWriter(theResDef, next, theWriter, null);
}
theWriter.writeEnd();
break;
@ -526,8 +533,22 @@ public class JsonParser extends BaseParser implements IParser {
}
private void encodeCompositeElementChildrenToStreamWriter(IElement theElement, JsonGenerator theEventWriter, List<? extends BaseRuntimeChildDefinition> theChildren) throws IOException {
private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, JsonGenerator theEventWriter, List<? extends BaseRuntimeChildDefinition> theChildren) throws IOException {
for (BaseRuntimeChildDefinition nextChild : theChildren) {
if (nextChild instanceof RuntimeChildNarrativeDefinition) {
INarrativeGenerator gen = myContext.getNarrativeGenerator();
if (gen != null) {
NarrativeDt narr = gen.generateNarrative(theResDef.getResourceProfile(), theResource);
if (narr!=null) {
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
String childName = nextChild.getChildNameByDatatype(child.getDatatype());
BaseRuntimeElementDefinition<?> type = child.getChildByName(childName);
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, narr, type, childName);
continue;
}
}
}
List<? extends IElement> values = nextChild.getAccessor().getValues(theElement);
if (values == null || values.isEmpty()) {
continue;
@ -565,7 +586,7 @@ public class JsonParser extends BaseParser implements IParser {
String extensionUrl = nextChild.getExtensionUrl();
theEventWriter.write("url", extensionUrl);
// theEventWriter.writeName(childName);
encodeChildElementToStreamWriter(theEventWriter, nextValue, childDef, childName);
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, childName);
theEventWriter.writeEnd();
@ -578,14 +599,13 @@ public class JsonParser extends BaseParser implements IParser {
if (nextChild.getMax() > 1 || nextChild.getMax() == Child.MAX_UNLIMITED) {
theEventWriter.writeStartArray(childName);
inArray = true;
encodeChildElementToStreamWriter(theEventWriter, nextValue, childDef, null);
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null);
} else {
encodeChildElementToStreamWriter(theEventWriter, nextValue, childDef, childName);
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, childName);
}
currentChildName = childName;
} else {
theEventWriter.flush();// TODO: remove
encodeChildElementToStreamWriter(theEventWriter, nextValue, childDef, null);
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null);
}
if (nextValue instanceof ISupportsUndeclaredExtensions) {
@ -615,7 +635,7 @@ public class JsonParser extends BaseParser implements IParser {
theEventWriter.writeStartObject();
theEventWriter.writeStartArray("extension");
for (HeldExtension nextExt : extensions.get(i)) {
nextExt.write(theEventWriter);
nextExt.write(theResDef, theResource, theEventWriter);
}
theEventWriter.writeEnd();
theEventWriter.writeEnd();
@ -623,7 +643,6 @@ public class JsonParser extends BaseParser implements IParser {
if (!haveContent) {
// theEventWriter.writeEnd();
theEventWriter.flush(); // TODO: remove
theEventWriter.writeNull();
}
}
@ -648,27 +667,26 @@ public class JsonParser extends BaseParser implements IParser {
// }
theEventWriter.writeEnd();
theEventWriter.flush(); // TODO: remove
}
}
}
private void encodeCompositeElementToStreamWriter(IElement theElement, JsonGenerator theEventWriter, BaseRuntimeElementCompositeDefinition<?> resDef) throws IOException, DataFormatException {
encodeExtensionsIfPresent(theEventWriter, theElement);
encodeCompositeElementChildrenToStreamWriter(theElement, theEventWriter, resDef.getExtensions());
encodeCompositeElementChildrenToStreamWriter(theElement, theEventWriter, resDef.getChildren());
private void encodeCompositeElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, JsonGenerator theEventWriter, BaseRuntimeElementCompositeDefinition<?> resDef) throws IOException, DataFormatException {
encodeExtensionsIfPresent(theResDef, theResource, theEventWriter, theElement);
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getExtensions());
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getChildren());
}
private void encodeExtensionsIfPresent(JsonGenerator theWriter, IElement theResource) throws IOException {
if (theResource instanceof ISupportsUndeclaredExtensions) {
ISupportsUndeclaredExtensions res = (ISupportsUndeclaredExtensions) theResource;
encodeUndeclaredExtensions(theWriter, res.getUndeclaredExtensions(), "extension");
encodeUndeclaredExtensions(theWriter, res.getUndeclaredModifierExtensions(), "modifierExtension");
private void encodeExtensionsIfPresent(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theWriter, IElement theElement) throws IOException {
if (theElement instanceof ISupportsUndeclaredExtensions) {
ISupportsUndeclaredExtensions res = (ISupportsUndeclaredExtensions) theElement;
encodeUndeclaredExtensions(theResDef, theResource, theWriter, res.getUndeclaredExtensions(), "extension");
encodeUndeclaredExtensions(theResDef, theResource, theWriter, res.getUndeclaredModifierExtensions(), "modifierExtension");
}
}
private void encodeResourceToJsonStreamWriter(IResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull) throws IOException {
private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull) throws IOException {
super.containResourcesForEncoding(theResource);
RuntimeResourceDefinition resDef = myContext.getResourceDefinition(theResource);
@ -684,12 +702,12 @@ public class JsonParser extends BaseParser implements IParser {
theEventWriter.write("id", theResource.getId().getValue());
}
encodeCompositeElementToStreamWriter(theResource, theEventWriter, resDef);
encodeCompositeElementToStreamWriter(theResDef, theResource, theResource, theEventWriter, resDef);
theEventWriter.writeEnd();
}
private void encodeUndeclaredExtensions(JsonGenerator theWriter, List<UndeclaredExtension> extensions, String theTagName) throws IOException {
private void encodeUndeclaredExtensions(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theWriter, List<UndeclaredExtension> extensions, String theTagName) throws IOException {
if (extensions.isEmpty()) {
return;
}
@ -707,11 +725,11 @@ public class JsonParser extends BaseParser implements IParser {
RuntimeChildUndeclaredExtensionDefinition extDef = myContext.getRuntimeChildUndeclaredExtensionDefinition();
BaseRuntimeElementDefinition<?> childDef = extDef.getChildElementDefinitionByDatatype(nextValue.getClass());
// theWriter.writeName("value" + childDef.getName());
encodeChildElementToStreamWriter(theWriter, nextValue, childDef, "value" + childDef.getName());
encodeChildElementToStreamWriter(theResDef, theResource, theWriter, nextValue, childDef, "value" + childDef.getName());
}
encodeUndeclaredExtensions(theWriter, next.getUndeclaredExtensions(), "extension");
encodeUndeclaredExtensions(theWriter, next.getUndeclaredModifierExtensions(), "modifierExtension");
encodeUndeclaredExtensions(theResDef, theResource, theWriter, next.getUndeclaredExtensions(), "extension");
encodeUndeclaredExtensions(theResDef, theResource, theWriter, next.getUndeclaredModifierExtensions(), "modifierExtension");
theWriter.writeEnd();
}
@ -762,13 +780,13 @@ public class JsonParser extends BaseParser implements IParser {
myUndeclaredExtension = theUndeclaredExtension;
}
public void write(JsonGenerator theEventWriter) throws IOException {
public void write(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theEventWriter) throws IOException {
if (myUndeclaredExtension != null) {
writeUndeclaredExt(theEventWriter, myUndeclaredExtension);
writeUndeclaredExt(theResDef, theResource, theEventWriter, myUndeclaredExtension);
}
}
private void writeUndeclaredExt(JsonGenerator theEventWriter, UndeclaredExtension ext) throws IOException {
private void writeUndeclaredExt(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theEventWriter, UndeclaredExtension ext) throws IOException {
theEventWriter.writeStartObject();
theEventWriter.write("url", ext.getUrl());
@ -778,13 +796,13 @@ public class JsonParser extends BaseParser implements IParser {
} else if (value == null) {
theEventWriter.writeStartArray("extension");
for (UndeclaredExtension next : ext.getUndeclaredExtensions()) {
writeUndeclaredExt(theEventWriter, next);
writeUndeclaredExt(theResDef, theResource, theEventWriter, next);
}
theEventWriter.writeEnd();
} else {
BaseRuntimeElementDefinition<?> def = myContext.getElementDefinition(value.getClass());
// theEventWriter.writeName("value" + def.getName());
encodeChildElementToStreamWriter(theEventWriter, value, def, "value" + def.getName());
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, value, def, "value" + def.getName());
}
// theEventWriter.name(myUndeclaredExtension.get);

View File

@ -519,7 +519,11 @@ public class XmlParser extends BaseParser implements IParser {
if (firstEvent) {
theEventWriter.writeStartElement(se.getName().getLocalPart());
if (StringUtils.isBlank(se.getName().getPrefix())) {
theEventWriter.writeDefaultNamespace(se.getName().getNamespaceURI());
String namespaceURI = se.getName().getNamespaceURI();
if (StringUtils.isBlank(namespaceURI)) {
namespaceURI = "http://www.w3.org/1999/xhtml";
}
theEventWriter.writeDefaultNamespace(namespaceURI);
} else {
theEventWriter.writeNamespace(se.getName().getPrefix(), se.getName().getNamespaceURI());
}
@ -538,6 +542,10 @@ public class XmlParser extends BaseParser implements IParser {
} else {
theEventWriter.writeStartElement(se.getName().getPrefix(), se.getName().getLocalPart(), se.getName().getNamespaceURI());
}
for (Iterator<?> attrIter = se.getAttributes(); attrIter.hasNext(); ) {
Attribute next = (Attribute) attrIter.next();
theEventWriter.writeAttribute(next.getName().getLocalPart(), next.getValue());
}
}
break;
case XMLStreamConstants.DTD:

View File

@ -1,11 +1,15 @@
package ca.uhn.fhir.narrative;
import static org.junit.Assert.assertThat;
import java.io.IOException;
import java.util.Date;
import org.hamcrest.core.StringContains;
import org.junit.Before;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
import ca.uhn.fhir.model.dstu.composite.QuantityDt;
@ -15,7 +19,6 @@ import ca.uhn.fhir.model.dstu.resource.Observation;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.valueset.ObservationStatusEnum;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
public class ThymeleafNarrativeGeneratorTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ThymeleafNarrativeGeneratorTest.class);
@ -25,10 +28,11 @@ public class ThymeleafNarrativeGeneratorTest {
public void before() throws IOException {
gen = new ThymeleafNarrativeGenerator();
gen.setIgnoreFailures(false);
gen.setIgnoreMissingTemplates(true);
}
@Test
public void testGeneratePatient() throws DataFormatException, InternalErrorException {
public void testGeneratePatient() throws DataFormatException {
Patient value = new Patient();
value.addIdentifier().setSystem("urn:names").setValue("123456");
@ -44,7 +48,7 @@ public class ThymeleafNarrativeGeneratorTest {
}
@Test
public void testGenerateDiagnosticReport() throws DataFormatException, InternalErrorException {
public void testGenerateDiagnosticReport() throws DataFormatException {
DiagnosticReport value = new DiagnosticReport();
value.getName().setText("Some Diagnostic Report");
@ -58,7 +62,7 @@ public class ThymeleafNarrativeGeneratorTest {
}
@Test
public void testGenerateDiagnosticReportWithObservations() throws DataFormatException, InternalErrorException {
public void testGenerateDiagnosticReportWithObservations() throws DataFormatException, IOException {
DiagnosticReport value = new DiagnosticReport();
value.getName().setText("Some Diagnostic Report");
@ -76,6 +80,16 @@ public class ThymeleafNarrativeGeneratorTest {
String output = generateNarrative.getDiv().getValueAsString();
ourLog.info(output);
assertThat(output, StringContains.containsString("<div class=\"hapiHeaderText\">Some Diagnostic Report</div>"));
// Now try it with the parser
FhirContext context = new FhirContext();
context.setNarrativeGenerator(gen);
output = context.newXmlParser().setPrettyPrint(true).encodeResourceToString(value);
ourLog.info(output);
assertThat(output, StringContains.containsString("<div class=\"hapiHeaderText\">Some Diagnostic Report</div>"));
}
}

View File

@ -1,6 +1,9 @@
package ca.uhn.fhir.parser;
import static org.junit.Assert.*;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.io.OutputStreamWriter;
@ -19,13 +22,17 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.UndeclaredExtension;
import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
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.Specimen;
import ca.uhn.fhir.model.dstu.valueset.NarrativeStatusEnum;
import ca.uhn.fhir.model.primitive.DecimalDt;
import ca.uhn.fhir.model.primitive.XhtmlDt;
import ca.uhn.fhir.narrative.INarrativeGenerator;
public class JsonParserTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonParserTest.class);
@ -53,6 +60,29 @@ public class JsonParserTest {
}
@Test
public void testNarrativeGeneration() throws DataFormatException, IOException {
Patient patient = new Patient();
patient.addName().addFamily("Smith");
INarrativeGenerator gen = mock(INarrativeGenerator.class);
XhtmlDt xhtmlDt = new XhtmlDt("<div>help</div>");
NarrativeDt nar = new NarrativeDt(xhtmlDt, NarrativeStatusEnum.GENERATED);
when(gen.generateNarrative(eq("http://hl7.org/fhir/profiles/Patient"), eq(patient))).thenReturn(nar);
FhirContext context = new FhirContext();
context.setNarrativeGenerator(gen);
IParser p = context.newJsonParser();
p.encodeResourceToWriter(patient, new OutputStreamWriter(System.out));
String str = p.encodeResourceToString(patient);
ourLog.info(str);
assertThat(str, StringContains.containsString(",\"text\":{\"status\":\"generated\",\"div\":\"<div>help</div>\"},"));
}
@Test
public void testSimpleResourceEncode() throws IOException {

View File

@ -194,7 +194,7 @@ public class XmlParserTest {
String str = p.encodeResourceToString(rpt);
ourLog.info(str);
assertThat(str, StringContains.containsString("<div xmlns=\"\">AAA</div>"));
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();