More narrative work
This commit is contained in:
parent
57a3a4881e
commit
81b2b1cc50
|
@ -13,6 +13,7 @@ import java.util.Properties;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.io.input.ReaderInputStream;
|
import org.apache.commons.io.input.ReaderInputStream;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.thymeleaf.Arguments;
|
import org.thymeleaf.Arguments;
|
||||||
import org.thymeleaf.Configuration;
|
import org.thymeleaf.Configuration;
|
||||||
import org.thymeleaf.TemplateEngine;
|
import org.thymeleaf.TemplateEngine;
|
||||||
|
@ -32,6 +33,7 @@ import org.thymeleaf.standard.expression.StandardExpressions;
|
||||||
import org.thymeleaf.templateresolver.TemplateResolver;
|
import org.thymeleaf.templateresolver.TemplateResolver;
|
||||||
import org.thymeleaf.util.DOMUtils;
|
import org.thymeleaf.util.DOMUtils;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
|
import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.NarrativeStatusEnum;
|
import ca.uhn.fhir.model.dstu.valueset.NarrativeStatusEnum;
|
||||||
|
@ -42,56 +44,44 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseThymeleafNarrativeGenerator.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseThymeleafNarrativeGenerator.class);
|
||||||
|
|
||||||
private boolean myCleanWhitespace = true;
|
private boolean myCleanWhitespace = true;
|
||||||
|
|
||||||
private HashMap<String, String> myDatatypeClassNameToNarrativeTemplate;
|
|
||||||
private TemplateEngine myDatatypeTemplateEngine;
|
|
||||||
private boolean myIgnoreFailures = true;
|
private boolean myIgnoreFailures = true;
|
||||||
|
|
||||||
private boolean myIgnoreMissingTemplates = true;
|
private boolean myIgnoreMissingTemplates = true;
|
||||||
|
|
||||||
private TemplateEngine myProfileTemplateEngine;
|
private TemplateEngine myProfileTemplateEngine;
|
||||||
private HashMap<String, String> myProfileToNarrativeTemplate;
|
private HashMap<String, String> myProfileToNarrativeName;
|
||||||
|
private HashMap<Class<?>, String> myClassToNarrativeName;
|
||||||
|
private HashMap<String, String> myNameToNarrativeTemplate;
|
||||||
|
|
||||||
public BaseThymeleafNarrativeGenerator() throws IOException {
|
private volatile boolean myInitialized;
|
||||||
myProfileToNarrativeTemplate = new HashMap<String, String>();
|
|
||||||
myDatatypeClassNameToNarrativeTemplate = new HashMap<String, String>();
|
|
||||||
|
|
||||||
String propFileName = getPropertyFile();
|
|
||||||
loadProperties(propFileName);
|
|
||||||
|
|
||||||
{
|
|
||||||
myProfileTemplateEngine = new TemplateEngine();
|
|
||||||
TemplateResolver resolver = new TemplateResolver();
|
|
||||||
resolver.setResourceResolver(new ProfileResourceResolver());
|
|
||||||
myProfileTemplateEngine.setTemplateResolver(resolver);
|
|
||||||
StandardDialect dialect = new StandardDialect();
|
|
||||||
HashSet<IProcessor> additionalProcessors = new HashSet<IProcessor>();
|
|
||||||
additionalProcessors.add(new MyProcessor());
|
|
||||||
dialect.setAdditionalProcessors(additionalProcessors);
|
|
||||||
myProfileTemplateEngine.setDialect(dialect);
|
|
||||||
myProfileTemplateEngine.initialize();
|
|
||||||
}
|
|
||||||
{
|
|
||||||
myDatatypeTemplateEngine = new TemplateEngine();
|
|
||||||
TemplateResolver resolver = new TemplateResolver();
|
|
||||||
resolver.setResourceResolver(new DatatypeResourceResolver());
|
|
||||||
myDatatypeTemplateEngine.setTemplateResolver(resolver);
|
|
||||||
myDatatypeTemplateEngine.setDialect(new StandardDialect());
|
|
||||||
myDatatypeTemplateEngine.initialize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NarrativeDt generateNarrative(String theProfile, IResource theResource) {
|
public NarrativeDt generateNarrative(String theProfile, IResource theResource) {
|
||||||
if (myIgnoreMissingTemplates && !myProfileToNarrativeTemplate.containsKey(theProfile)) {
|
if (!myInitialized) {
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
String name = null;
|
||||||
|
if (StringUtils.isNotBlank(theProfile)) {
|
||||||
|
name = myProfileToNarrativeName.get(theProfile);
|
||||||
|
}
|
||||||
|
if (name == null) {
|
||||||
|
name = myClassToNarrativeName.get(theResource.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == null) {
|
||||||
|
if (myIgnoreMissingTemplates) {
|
||||||
ourLog.debug("No narrative template available for profile: {}", theProfile);
|
ourLog.debug("No narrative template available for profile: {}", theProfile);
|
||||||
return new NarrativeDt(new XhtmlDt("<div>No narrative available</div>"), NarrativeStatusEnum.EMPTY);
|
return new NarrativeDt(new XhtmlDt("<div>No narrative available</div>"), NarrativeStatusEnum.EMPTY);
|
||||||
|
} else {
|
||||||
|
throw new DataFormatException("No narrative template for class " + theResource.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Context context = new Context();
|
Context context = new Context();
|
||||||
context.setVariable("resource", theResource);
|
context.setVariable("resource", theResource);
|
||||||
|
|
||||||
String result = myProfileTemplateEngine.process(theProfile, context);
|
String result = myProfileTemplateEngine.process(name, context);
|
||||||
|
|
||||||
if (myCleanWhitespace) {
|
if (myCleanWhitespace) {
|
||||||
ourLog.trace("Pre-whitespace cleaning: ", result);
|
ourLog.trace("Pre-whitespace cleaning: ", result);
|
||||||
|
@ -111,15 +101,47 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized void initialize() {
|
||||||
|
if (myInitialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
myProfileToNarrativeName = new HashMap<String, String>();
|
||||||
|
myClassToNarrativeName = new HashMap<Class<?>, String>();
|
||||||
|
myNameToNarrativeTemplate = new HashMap<String, String>();
|
||||||
|
|
||||||
|
String propFileName = getPropertyFile();
|
||||||
|
if (isBlank(propFileName)) {
|
||||||
|
throw new ConfigurationException("Property file name can not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
loadProperties(propFileName);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ConfigurationException("Can not load property file " + propFileName, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
myProfileTemplateEngine = new TemplateEngine();
|
||||||
|
TemplateResolver resolver = new TemplateResolver();
|
||||||
|
resolver.setResourceResolver(new ProfileResourceResolver());
|
||||||
|
myProfileTemplateEngine.setTemplateResolver(resolver);
|
||||||
|
StandardDialect dialect = new StandardDialect();
|
||||||
|
HashSet<IProcessor> additionalProcessors = new HashSet<IProcessor>();
|
||||||
|
additionalProcessors.add(new NarrativeAttributeProcessor());
|
||||||
|
dialect.setAdditionalProcessors(additionalProcessors);
|
||||||
|
myProfileTemplateEngine.setDialect(dialect);
|
||||||
|
myProfileTemplateEngine.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
myInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract String getPropertyFile();
|
protected abstract String getPropertyFile();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to <code>true</code> (which is the default), most whitespace will
|
* If set to <code>true</code> (which is the default), most whitespace will be trimmed from the generated narrative before it is returned.
|
||||||
* be trimmed from the generated narrative before it is returned.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Note that in order to preserve formatting, not all whitespace is trimmed.
|
* Note that in order to preserve formatting, not all whitespace is trimmed. Repeated whitespace characters (e.g. "\n \n ") will be trimmed to a single space.
|
||||||
* Repeated whitespace characters (e.g. "\n \n ") will be
|
|
||||||
* trimmed to a single space.
|
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public boolean isCleanWhitespace() {
|
public boolean isCleanWhitespace() {
|
||||||
|
@ -127,30 +149,24 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to <code>true</code>, which is the default, if any failure occurs
|
* 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
|
||||||
* during narrative generation the generator will suppress any generated
|
* indicating that no narrative is available.
|
||||||
* exceptions, and simply return a default narrative indicating that no
|
|
||||||
* narrative is available.
|
|
||||||
*/
|
*/
|
||||||
public boolean isIgnoreFailures() {
|
public boolean isIgnoreFailures() {
|
||||||
return myIgnoreFailures;
|
return myIgnoreFailures;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to true, will return an empty narrative block for any profiles
|
* If set to true, will return an empty narrative block for any profiles where no template is available
|
||||||
* where no template is available
|
|
||||||
*/
|
*/
|
||||||
public boolean isIgnoreMissingTemplates() {
|
public boolean isIgnoreMissingTemplates() {
|
||||||
return myIgnoreMissingTemplates;
|
return myIgnoreMissingTemplates;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to <code>true</code> (which is the default), most whitespace will
|
* If set to <code>true</code> (which is the default), most whitespace will be trimmed from the generated narrative before it is returned.
|
||||||
* be trimmed from the generated narrative before it is returned.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Note that in order to preserve formatting, not all whitespace is trimmed.
|
* Note that in order to preserve formatting, not all whitespace is trimmed. Repeated whitespace characters (e.g. "\n \n ") will be trimmed to a single space.
|
||||||
* Repeated whitespace characters (e.g. "\n \n ") will be
|
|
||||||
* trimmed to a single space.
|
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public void setCleanWhitespace(boolean theCleanWhitespace) {
|
public void setCleanWhitespace(boolean theCleanWhitespace) {
|
||||||
|
@ -158,18 +174,15 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to <code>true</code>, which is the default, if any failure occurs
|
* 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
|
||||||
* during narrative generation the generator will suppress any generated
|
* indicating that no narrative is available.
|
||||||
* exceptions, and simply return a default narrative indicating that no
|
|
||||||
* narrative is available.
|
|
||||||
*/
|
*/
|
||||||
public void setIgnoreFailures(boolean theIgnoreFailures) {
|
public void setIgnoreFailures(boolean theIgnoreFailures) {
|
||||||
myIgnoreFailures = theIgnoreFailures;
|
myIgnoreFailures = theIgnoreFailures;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to true, will return an empty narrative block for any profiles
|
* If set to true, will return an empty narrative block for any profiles where no template is available
|
||||||
* where no template is available
|
|
||||||
*/
|
*/
|
||||||
public void setIgnoreMissingTemplates(boolean theIgnoreMissingTemplates) {
|
public void setIgnoreMissingTemplates(boolean theIgnoreMissingTemplates) {
|
||||||
myIgnoreMissingTemplates = theIgnoreMissingTemplates;
|
myIgnoreMissingTemplates = theIgnoreMissingTemplates;
|
||||||
|
@ -188,15 +201,19 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String narrativeName = file.getProperty(name + ".narrative");
|
String narrativePropName = name + ".narrative";
|
||||||
|
String narrativeName = file.getProperty(narrativePropName);
|
||||||
if (isBlank(narrativeName)) {
|
if (isBlank(narrativeName)) {
|
||||||
continue;
|
throw new ConfigurationException("Found property '" + nextKey + "' but no corresponding property '" + narrativePropName + "' in file " + propFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
String narrative = IOUtils.toString(loadResource(narrativeName));
|
String narrative = IOUtils.toString(loadResource(narrativeName));
|
||||||
myProfileToNarrativeTemplate.put(file.getProperty(nextKey), narrative);
|
myProfileToNarrativeName.put(file.getProperty(nextKey), name);
|
||||||
} else if (nextKey.endsWith(".dtclass")) {
|
myNameToNarrativeTemplate.put(name, narrative);
|
||||||
String name = nextKey.substring(0, nextKey.indexOf(".dtclass"));
|
|
||||||
|
} else if (nextKey.endsWith(".class")) {
|
||||||
|
|
||||||
|
String name = nextKey.substring(0, nextKey.indexOf(".class"));
|
||||||
if (isBlank(name)) {
|
if (isBlank(name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -211,13 +228,20 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String narrativeName = file.getProperty(name + ".dtnarrative");
|
String narrativePropName = name + ".narrative";
|
||||||
|
String narrativeName = file.getProperty(narrativePropName);
|
||||||
if (isBlank(narrativeName)) {
|
if (isBlank(narrativeName)) {
|
||||||
continue;
|
throw new ConfigurationException("Found property '" + nextKey + "' but no corresponding property '" + narrativePropName + "' in file " + propFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
String narrative = IOUtils.toString(loadResource(narrativeName));
|
String narrative = IOUtils.toString(loadResource(narrativeName));
|
||||||
myDatatypeClassNameToNarrativeTemplate.put(dtClass.getCanonicalName(), narrative);
|
myClassToNarrativeName.put(dtClass, name);
|
||||||
|
myNameToNarrativeTemplate.put(name, narrative);
|
||||||
|
|
||||||
|
} else if (nextKey.endsWith(".narrative")) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
throw new ConfigurationException("Invalid property name: " + nextKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -292,9 +316,9 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
|
||||||
return b.toString();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MyProcessor extends AbstractAttrProcessor {
|
public class NarrativeAttributeProcessor extends AbstractAttrProcessor {
|
||||||
|
|
||||||
protected MyProcessor() {
|
protected NarrativeAttributeProcessor() {
|
||||||
super("narrative");
|
super("narrative");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +340,18 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
|
||||||
Context context = new Context();
|
Context context = new Context();
|
||||||
context.setVariable("resource", value);
|
context.setVariable("resource", value);
|
||||||
|
|
||||||
String result = myDatatypeTemplateEngine.process(value.getClass().getCanonicalName(), context);
|
String name = myClassToNarrativeName.get(value.getClass());
|
||||||
|
|
||||||
|
if (name == null) {
|
||||||
|
if (myIgnoreMissingTemplates) {
|
||||||
|
ourLog.debug("No narrative template available for type: {}", value.getClass());
|
||||||
|
return ProcessorResult.ok();
|
||||||
|
} else {
|
||||||
|
throw new DataFormatException("No narrative template for class " + value.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String result = myProfileTemplateEngine.process(name, context);
|
||||||
Document dom = DOMUtils.getXhtmlDOMFor(new StringReader(result));
|
Document dom = DOMUtils.getXhtmlDOMFor(new StringReader(result));
|
||||||
|
|
||||||
theElement.removeAttribute(theAttributeName);
|
theElement.removeAttribute(theAttributeName);
|
||||||
|
@ -332,22 +367,6 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class DatatypeResourceResolver implements IResourceResolver {
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return getClass().getCanonicalName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getResourceAsStream(TemplateProcessingParameters theTemplateProcessingParameters, String theClassName) {
|
|
||||||
String template = myDatatypeClassNameToNarrativeTemplate.get(theClassName);
|
|
||||||
if (template == null) {
|
|
||||||
throw new NullPointerException("No narrative template exists for datatype: " + theClassName);
|
|
||||||
}
|
|
||||||
return new ReaderInputStream(new StringReader(template));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// public String generateString(Patient theValue) {
|
// public String generateString(Patient theValue) {
|
||||||
//
|
//
|
||||||
// Context context = new Context();
|
// Context context = new Context();
|
||||||
|
@ -368,10 +387,10 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream getResourceAsStream(TemplateProcessingParameters theTemplateProcessingParameters, String theResourceName) {
|
public InputStream getResourceAsStream(TemplateProcessingParameters theTemplateProcessingParameters, String theName) {
|
||||||
String template = myProfileToNarrativeTemplate.get(theResourceName);
|
String template = myNameToNarrativeTemplate.get(theName);
|
||||||
if (template == null) {
|
if (template == null) {
|
||||||
ourLog.info("No narative template for resource profile: {}", theResourceName);
|
ourLog.info("No narative template for resource profile: {}", theName);
|
||||||
return new ReaderInputStream(new StringReader(""));
|
return new ReaderInputStream(new StringReader(""));
|
||||||
}
|
}
|
||||||
return new ReaderInputStream(new StringReader(template));
|
return new ReaderInputStream(new StringReader(template));
|
||||||
|
|
|
@ -3,35 +3,35 @@
|
||||||
# Primitive Datatypes
|
# Primitive Datatypes
|
||||||
################################################
|
################################################
|
||||||
|
|
||||||
string.dtclass=ca.uhn.fhir.model.primitive.StringDt
|
string.class=ca.uhn.fhir.model.primitive.StringDt
|
||||||
string.dtnarrative=classpath:ca/uhn/fhir/narrative/StringDt.html
|
string.narrative=classpath:ca/uhn/fhir/narrative/StringDt.html
|
||||||
|
|
||||||
datetime.dtclass=ca.uhn.fhir.model.primitive.DateTimeDt
|
datetime.class=ca.uhn.fhir.model.primitive.DateTimeDt
|
||||||
datetime.dtnarrative=classpath:ca/uhn/fhir/narrative/DateTimeDt.html
|
datetime.narrative=classpath:ca/uhn/fhir/narrative/DateTimeDt.html
|
||||||
|
|
||||||
# Instant uses DateTime narrative
|
# Instant uses DateTime narrative
|
||||||
instant.dtclass=ca.uhn.fhir.model.primitive.InstantDt
|
instant.class=ca.uhn.fhir.model.primitive.InstantDt
|
||||||
instant.dtnarrative=classpath:ca/uhn/fhir/narrative/DateTimeDt.html
|
instant.narrative=classpath:ca/uhn/fhir/narrative/DateTimeDt.html
|
||||||
|
|
||||||
################################################
|
################################################
|
||||||
# Composite Datatypes
|
# Composite Datatypes
|
||||||
################################################
|
################################################
|
||||||
|
|
||||||
address.dtclass=ca.uhn.fhir.model.dstu.composite.AddressDt
|
address.class=ca.uhn.fhir.model.dstu.composite.AddressDt
|
||||||
address.dtnarrative=classpath:ca/uhn/fhir/narrative/AddressDt.html
|
address.narrative=classpath:ca/uhn/fhir/narrative/AddressDt.html
|
||||||
|
|
||||||
humanname.dtclass=ca.uhn.fhir.model.dstu.composite.HumanNameDt
|
humanname.class=ca.uhn.fhir.model.dstu.composite.HumanNameDt
|
||||||
humanname.dtnarrative=classpath:ca/uhn/fhir/narrative/HumanNameDt.html
|
humanname.narrative=classpath:ca/uhn/fhir/narrative/HumanNameDt.html
|
||||||
|
|
||||||
quantity.dtclass=ca.uhn.fhir.model.dstu.composite.QuantityDt
|
quantity.class=ca.uhn.fhir.model.dstu.composite.QuantityDt
|
||||||
quantity.dtnarrative=classpath:ca/uhn/fhir/narrative/QuantityDt.html
|
quantity.narrative=classpath:ca/uhn/fhir/narrative/QuantityDt.html
|
||||||
|
|
||||||
################################################
|
################################################
|
||||||
# Resources
|
# Resources
|
||||||
################################################
|
################################################
|
||||||
|
|
||||||
patient.profile=http://hl7.org/fhir/profiles/Patient
|
patient.class=ca.uhn.fhir.model.dstu.resource.Patient
|
||||||
patient.narrative=classpath:ca/uhn/fhir/narrative/Patient.html
|
patient.narrative=classpath:ca/uhn/fhir/narrative/Patient.html
|
||||||
|
|
||||||
diagnosticreport.profile=http://hl7.org/fhir/profiles/DiagnosticReport
|
diagnosticreport.class=ca.uhn.fhir.model.dstu.resource.DiagnosticReport
|
||||||
diagnosticreport.narrative=classpath:ca/uhn/fhir/narrative/DiagnosticReport.html
|
diagnosticreport.narrative=classpath:ca/uhn/fhir/narrative/DiagnosticReport.html
|
|
@ -11,6 +11,8 @@ public class CustomThymeleafNarrativeGeneratorTest {
|
||||||
|
|
||||||
CustomThymeleafNarrativeGenerator gen = new CustomThymeleafNarrativeGenerator("src/test/resources/narrative/customnarrative.properties");
|
CustomThymeleafNarrativeGenerator gen = new CustomThymeleafNarrativeGenerator("src/test/resources/narrative/customnarrative.properties");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class DefaultThymeleafNarrativeGeneratorTest {
|
||||||
public void before() throws IOException {
|
public void before() throws IOException {
|
||||||
gen = new DefaultThymeleafNarrativeGenerator();
|
gen = new DefaultThymeleafNarrativeGenerator();
|
||||||
gen.setIgnoreFailures(false);
|
gen.setIgnoreFailures(false);
|
||||||
gen.setIgnoreMissingTemplates(true);
|
gen.setIgnoreMissingTemplates(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -1,21 +1,16 @@
|
||||||
|
|
||||||
# Each resource to be defined has a pair or properties.
|
# Each resource to be defined has a pair or properties.
|
||||||
#
|
#
|
||||||
# The first (name.profile) defines the profile for the resource
|
# The first (name.class) defines the class name of the
|
||||||
# to generate a narrative for. This profile URL string can be
|
# resource to define a template for
|
||||||
# found by examining the JavaDoc for the resource in question.
|
|
||||||
#
|
#
|
||||||
# The second (name.narrative) defines the path/classpath to the
|
# The second (name.narrative) defines the path/classpath to the
|
||||||
# template file.
|
# template file.
|
||||||
# Format is file:/path/foo.html or classpath:/com/classpath/foo.html
|
# Format is file:/path/foo.html or classpath:/com/classpath/foo.html
|
||||||
#
|
#
|
||||||
practitioner.profile=http://hl7.org/fhir/profiles/Practitioner
|
practitioner.class=ca.uhn.fhir.model.dstu.resource.Practitioner
|
||||||
practitioner.narrative=file:src/test/resource/narrative/Practitioner.html
|
practitioner.narrative=file:src/test/resource/narrative/Practitioner.html
|
||||||
|
|
||||||
# You may also override/define behaviour for datatypes, but the
|
# You may also override/define behaviour for datatypes
|
||||||
# format is a bit different.
|
humanname.class=ca.uhn.fhir.model.dstu.composite.HumanNameDt
|
||||||
#
|
humanname.narrative=classpath:ca/uhn/fhir/narrative/HumanNameDt.html
|
||||||
# For these, the first property (name.dtclass) is the classname
|
|
||||||
# The second property (name.dtnarrative) is the
|
|
||||||
humanname.dtclass=ca.uhn.fhir.model.dstu.composite.HumanNameDt
|
|
||||||
humanname.dtnarrative=classpath:ca/uhn/fhir/narrative/HumanNameDt.html
|
|
||||||
|
|
Loading…
Reference in New Issue