Narrative generation continuing
This commit is contained in:
parent
21619e5e46
commit
de50244875
|
@ -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>
|
||||
|
|
|
@ -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() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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>"));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue