Merge pull request #907 from hapifhir/gg-202208-rendering
Gg 202208 rendering
This commit is contained in:
commit
0da5b20cc7
|
@ -559,5 +559,14 @@ public abstract class CanonicalResource extends DomainResource {
|
||||||
}
|
}
|
||||||
// end addition
|
// end addition
|
||||||
|
|
||||||
|
public String oid() {
|
||||||
|
for (Identifier id : getIdentifier()) {
|
||||||
|
if (id.getValue().startsWith("urn:oid:")) {
|
||||||
|
return id.getValue().substring(8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -183,7 +183,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
||||||
hierarchy = hierarchy || csNav.isRestructure();
|
hierarchy = hierarchy || csNav.isRestructure();
|
||||||
|
|
||||||
List<String> langs = new ArrayList<>();
|
List<String> langs = new ArrayList<>();
|
||||||
addMapHeaders(addTableHeaderRowStandard(t, hierarchy, display, definitions, commentS, version, deprecated, properties, null, null, false), maps);
|
addCopyColumn(addMapHeaders(addTableHeaderRowStandard(t, hierarchy, display, definitions, commentS, version, deprecated, properties, null, null, false), maps));
|
||||||
for (ConceptDefinitionComponent c : csNav.getConcepts(null)) {
|
for (ConceptDefinitionComponent c : csNav.getConcepts(null)) {
|
||||||
hasExtensions = addDefineRowToTable(t, c, 0, hierarchy, display, definitions, commentS, version, deprecated, maps, cs.getUrl(), cs, properties, csNav, langs, isSupplement) || hasExtensions;
|
hasExtensions = addDefineRowToTable(t, c, 0, hierarchy, display, definitions, commentS, version, deprecated, maps, cs.getUrl(), cs, properties, csNav, langs, isSupplement) || hasExtensions;
|
||||||
}
|
}
|
||||||
|
@ -202,6 +202,13 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
||||||
return hasExtensions;
|
return hasExtensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addCopyColumn(XhtmlNode tr) {
|
||||||
|
if (context.isCopyButton()) {
|
||||||
|
tr.td().b().tx("Copy");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private boolean conceptsHaveDefinition(ConceptDefinitionComponent c) {
|
private boolean conceptsHaveDefinition(ConceptDefinitionComponent c) {
|
||||||
if (c.hasDefinition()) {
|
if (c.hasDefinition()) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -492,6 +499,12 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
||||||
}
|
}
|
||||||
td = tr.td().colspan(Integer.toString(w));
|
td = tr.td().colspan(Integer.toString(w));
|
||||||
}
|
}
|
||||||
|
if (context.isCopyButton()) {
|
||||||
|
td = tr.td();
|
||||||
|
clipboard(td, "icon_clipboard_x.png", "XML", "<system value=\""+Utilities.escapeXml(cs.getUrl())+"\">\n"+(cs.getVersionNeeded() ? "<version value=\""+Utilities.escapeXml(cs.getVersion())+"\">\n" : "")+"<code value=\""+Utilities.escapeXml(c.getCode())+"\">\n<display value=\""+Utilities.escapeXml(c.getDisplay())+"\">\n");
|
||||||
|
td.nbsp();
|
||||||
|
clipboard(td, "icon_clipboard_j.png", "JSON", "\"system\" : \""+Utilities.escapeXml(cs.getUrl())+"\",\n"+(cs.getVersionNeeded() ? "\"version\" : \""+Utilities.escapeXml(cs.getVersion())+"\",\n" : "")+"\"code\" : \""+Utilities.escapeXml(c.getCode())+"\",\n\"display\" : \""+Utilities.escapeXml(c.getDisplay())+"\"\n");
|
||||||
|
}
|
||||||
return hasExtensions;
|
return hasExtensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,19 +6,42 @@ import java.io.UnsupportedEncodingException;
|
||||||
import org.hl7.fhir.exceptions.DefinitionException;
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
|
import org.hl7.fhir.r5.elementmodel.Element;
|
||||||
|
import org.hl7.fhir.r5.model.Base;
|
||||||
|
import org.hl7.fhir.r5.model.DataType;
|
||||||
import org.hl7.fhir.r5.model.DomainResource;
|
import org.hl7.fhir.r5.model.DomainResource;
|
||||||
|
import org.hl7.fhir.r5.model.Reference;
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
||||||
|
import org.hl7.fhir.r5.renderers.LiquidRenderer.LiquidRendererContxt;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||||
import org.hl7.fhir.r5.utils.EOperationOutcome;
|
import org.hl7.fhir.r5.utils.EOperationOutcome;
|
||||||
import org.hl7.fhir.r5.utils.LiquidEngine;
|
import org.hl7.fhir.r5.utils.LiquidEngine;
|
||||||
|
import org.hl7.fhir.r5.utils.LiquidEngine.ILiquidRenderingSupport;
|
||||||
import org.hl7.fhir.r5.utils.LiquidEngine.LiquidDocument;
|
import org.hl7.fhir.r5.utils.LiquidEngine.LiquidDocument;
|
||||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||||
|
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
|
||||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||||
import org.hl7.fhir.utilities.xhtml.XhtmlParser;
|
import org.hl7.fhir.utilities.xhtml.XhtmlParser;
|
||||||
|
|
||||||
public class LiquidRenderer extends ResourceRenderer {
|
public class LiquidRenderer extends ResourceRenderer implements ILiquidRenderingSupport {
|
||||||
|
|
||||||
|
public class LiquidRendererContxt {
|
||||||
|
|
||||||
|
private ResourceContext rcontext;
|
||||||
|
private ResourceWrapper resource;
|
||||||
|
|
||||||
|
public LiquidRendererContxt(ResourceContext rcontext, ResourceWrapper r) {
|
||||||
|
this.rcontext = rcontext;
|
||||||
|
this.resource = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceWrapper getResource() {
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private String liquidTemplate;
|
private String liquidTemplate;
|
||||||
|
|
||||||
|
@ -56,6 +79,7 @@ public class LiquidRenderer extends ResourceRenderer {
|
||||||
XhtmlNode xn;
|
XhtmlNode xn;
|
||||||
try {
|
try {
|
||||||
engine.setIncludeResolver(new LiquidRendererIncludeResolver(context));
|
engine.setIncludeResolver(new LiquidRendererIncludeResolver(context));
|
||||||
|
engine.setRenderingSupport(this);
|
||||||
LiquidDocument doc = engine.parse(liquidTemplate, "template");
|
LiquidDocument doc = engine.parse(liquidTemplate, "template");
|
||||||
String html = engine.evaluate(doc, r, rcontext);
|
String html = engine.evaluate(doc, r, rcontext);
|
||||||
xn = new XhtmlParser().parseFragment(html);
|
xn = new XhtmlParser().parseFragment(html);
|
||||||
|
@ -90,7 +114,8 @@ public class LiquidRenderer extends ResourceRenderer {
|
||||||
XhtmlNode xn;
|
XhtmlNode xn;
|
||||||
try {
|
try {
|
||||||
LiquidDocument doc = engine.parse(liquidTemplate, "template");
|
LiquidDocument doc = engine.parse(liquidTemplate, "template");
|
||||||
String html = engine.evaluate(doc, r.getBase(), rcontext);
|
engine.setRenderingSupport(this);
|
||||||
|
String html = engine.evaluate(doc, r.getBase(), new LiquidRendererContxt(rcontext, r));
|
||||||
xn = new XhtmlParser().parseFragment(html);
|
xn = new XhtmlParser().parseFragment(html);
|
||||||
if (!x.getName().equals("div"))
|
if (!x.getName().equals("div"))
|
||||||
throw new FHIRException("Error in template: Root element is not 'div'");
|
throw new FHIRException("Error in template: Root element is not 'div'");
|
||||||
|
@ -102,4 +127,31 @@ public class LiquidRenderer extends ResourceRenderer {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RendererType getRendererType() {
|
||||||
|
return RendererType.LIQUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String renderForLiquid(Object appContext, Base base) throws FHIRException {
|
||||||
|
try {
|
||||||
|
if (base instanceof Element) {
|
||||||
|
base = context.getParser().parseType((Element) base);
|
||||||
|
}
|
||||||
|
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||||
|
if (base instanceof Reference) {
|
||||||
|
renderReference(((LiquidRendererContxt) appContext).getResource(), x, (Reference) base);
|
||||||
|
} else if (base instanceof DataType) {
|
||||||
|
render(x, (DataType) base);
|
||||||
|
} else {
|
||||||
|
x.tx(base.toString());
|
||||||
|
}
|
||||||
|
String res = new XhtmlComposer(true).compose(x).substring(5);
|
||||||
|
return res.substring(0, res.length()-6);
|
||||||
|
} catch (FHIRFormatError e) {
|
||||||
|
throw new FHIRException(e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new FHIRException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,7 +207,6 @@ public class ListRenderer extends ResourceRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private XhtmlNode shortForRef(XhtmlNode x, Base ref) throws UnsupportedEncodingException, IOException {
|
private XhtmlNode shortForRef(XhtmlNode x, Base ref) throws UnsupportedEncodingException, IOException {
|
||||||
if (ref == null) {
|
if (ref == null) {
|
||||||
x.tx("(null)");
|
x.tx("(null)");
|
||||||
|
@ -215,6 +214,9 @@ public class ListRenderer extends ResourceRenderer {
|
||||||
String disp = ref.getChildByName("display") != null && ref.getChildByName("display").hasValues() ? ref.getChildByName("display").getValues().get(0).primitiveValue() : null;
|
String disp = ref.getChildByName("display") != null && ref.getChildByName("display").hasValues() ? ref.getChildByName("display").getValues().get(0).primitiveValue() : null;
|
||||||
if (ref.getChildByName("reference").hasValues()) {
|
if (ref.getChildByName("reference").hasValues()) {
|
||||||
String url = ref.getChildByName("reference").getValues().get(0).primitiveValue();
|
String url = ref.getChildByName("reference").getValues().get(0).primitiveValue();
|
||||||
|
if (url.startsWith("#")) {
|
||||||
|
x.tx("?ngen-16a?");
|
||||||
|
} else {
|
||||||
ResourceWithReference r = context.getResolver().resolve(context, url);
|
ResourceWithReference r = context.getResolver().resolve(context, url);
|
||||||
if (r == null) {
|
if (r == null) {
|
||||||
if (disp == null) {
|
if (disp == null) {
|
||||||
|
@ -224,7 +226,8 @@ public class ListRenderer extends ResourceRenderer {
|
||||||
} else if (r.getResource() != null) {
|
} else if (r.getResource() != null) {
|
||||||
RendererFactory.factory(r.getResource().getName(), context).renderReference(r.getResource(), x, (Reference) ref);
|
RendererFactory.factory(r.getResource().getName(), context).renderReference(r.getResource(), x, (Reference) ref);
|
||||||
} else {
|
} else {
|
||||||
RendererFactory.factory(url, context).renderReference(r.getResource(), x, (Reference) ref);
|
x.ah(r.getReference()).tx(url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (disp != null) {
|
} else if (disp != null) {
|
||||||
x.tx(disp);
|
x.tx(disp);
|
||||||
|
|
|
@ -1015,4 +1015,8 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
||||||
return context.getWorker().getResourceNames().contains(resource.fhirType());
|
return context.getWorker().getResourceNames().contains(resource.fhirType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RendererType getRendererType() {
|
||||||
|
return RendererType.PROFILE;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@ import org.hl7.fhir.r5.model.Resource;
|
||||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
|
||||||
public class RendererFactory {
|
public class RendererFactory {
|
||||||
|
|
||||||
|
@ -131,5 +132,11 @@ public class RendererFactory {
|
||||||
return factory(rw, lrc, null);
|
return factory(rw, lrc, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hasSpecificRenderer(String rt) {
|
||||||
|
|
||||||
|
return Utilities.existsInList(rt,
|
||||||
|
"CodeSystem", "ValueSet", "ConceptMap",
|
||||||
|
"CapabilityStatement", "CompartmentDefinition", "ImplementationGuide", "Library", "NamingSystem", "OperationDefinition", "Questionnaire", "SearchParameter", "StructureDefinition");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -26,6 +26,7 @@ import org.hl7.fhir.r5.renderers.utils.BaseWrappers.PropertyWrapper;
|
||||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
||||||
import org.hl7.fhir.r5.renderers.utils.DirectWrappers.ResourceWrapperDirect;
|
import org.hl7.fhir.r5.renderers.utils.DirectWrappers.ResourceWrapperDirect;
|
||||||
import org.hl7.fhir.r5.renderers.utils.ElementWrappers.ResourceWrapperMetaElement;
|
import org.hl7.fhir.r5.renderers.utils.ElementWrappers.ResourceWrapperMetaElement;
|
||||||
|
import org.hl7.fhir.r5.renderers.ResourceRenderer.RendererType;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference;
|
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference;
|
||||||
|
@ -39,6 +40,11 @@ import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||||
|
|
||||||
public abstract class ResourceRenderer extends DataRenderer {
|
public abstract class ResourceRenderer extends DataRenderer {
|
||||||
|
|
||||||
|
public enum RendererType {
|
||||||
|
NATIVE, PROFILE, LIQUID
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
protected ResourceContext rcontext;
|
protected ResourceContext rcontext;
|
||||||
protected XVerExtensionManager xverManager;
|
protected XVerExtensionManager xverManager;
|
||||||
protected boolean forResource;
|
protected boolean forResource;
|
||||||
|
@ -507,4 +513,8 @@ public abstract class ResourceRenderer extends DataRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RendererType getRendererType() {
|
||||||
|
return RendererType.NATIVE;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -111,7 +111,7 @@ public abstract class TerminologyRenderer extends ResourceRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void addMapHeaders(XhtmlNode tr, List<UsedConceptMap> maps) throws FHIRFormatError, DefinitionException, IOException {
|
protected XhtmlNode addMapHeaders(XhtmlNode tr, List<UsedConceptMap> maps) throws FHIRFormatError, DefinitionException, IOException {
|
||||||
for (UsedConceptMap m : maps) {
|
for (UsedConceptMap m : maps) {
|
||||||
XhtmlNode td = tr.td();
|
XhtmlNode td = tr.td();
|
||||||
XhtmlNode b = td.b();
|
XhtmlNode b = td.b();
|
||||||
|
@ -120,6 +120,7 @@ public abstract class TerminologyRenderer extends ResourceRenderer {
|
||||||
if (m.getDetails().isDoDescription() && m.getMap().hasDescription())
|
if (m.getDetails().isDoDescription() && m.getMap().hasDescription())
|
||||||
addMarkdown(td, m.getMap().getDescription());
|
addMarkdown(td, m.getMap().getDescription());
|
||||||
}
|
}
|
||||||
|
return tr;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getHeader() {
|
protected String getHeader() {
|
||||||
|
@ -311,8 +312,6 @@ public abstract class TerminologyRenderer extends ResourceRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected String getDisplayForConcept(String system, String version, String value) {
|
protected String getDisplayForConcept(String system, String version, String value) {
|
||||||
if (value == null || system == null)
|
if (value == null || system == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -320,4 +319,13 @@ public abstract class TerminologyRenderer extends ResourceRenderer {
|
||||||
return cl == null ? null : cl.getDisplay();
|
return cl == null ? null : cl.getDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void clipboard(XhtmlNode x, String img, String title, String source) {
|
||||||
|
XhtmlNode span = x.span("cursor: pointer", "Copy "+title+" Format to clipboard");
|
||||||
|
span.attribute("onClick", "navigator.clipboard.writeText('"+Utilities.escapeJson(source)+"');");
|
||||||
|
span.img(img).setAttribute("width", "24px").setAttribute("height", "16px");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -15,6 +15,7 @@ import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider;
|
import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
|
import org.hl7.fhir.r5.elementmodel.Element;
|
||||||
import org.hl7.fhir.r5.model.Base;
|
import org.hl7.fhir.r5.model.Base;
|
||||||
import org.hl7.fhir.r5.model.DomainResource;
|
import org.hl7.fhir.r5.model.DomainResource;
|
||||||
import org.hl7.fhir.r5.model.Enumerations.FHIRVersion;
|
import org.hl7.fhir.r5.model.Enumerations.FHIRVersion;
|
||||||
|
@ -38,6 +39,7 @@ public class RenderingContext {
|
||||||
// parses xml to an XML instance. Whatever codes provides this needs to provide something that parses the right version
|
// parses xml to an XML instance. Whatever codes provides this needs to provide something that parses the right version
|
||||||
public interface ITypeParser {
|
public interface ITypeParser {
|
||||||
Base parseType(String xml, String type) throws FHIRFormatError, IOException, FHIRException ;
|
Base parseType(String xml, String type) throws FHIRFormatError, IOException, FHIRException ;
|
||||||
|
Base parseType(Element base) throws FHIRFormatError, IOException, FHIRException ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -131,6 +133,7 @@ public class RenderingContext {
|
||||||
private DateTimeFormatter dateFormat;
|
private DateTimeFormatter dateFormat;
|
||||||
private DateTimeFormatter dateYearFormat;
|
private DateTimeFormatter dateYearFormat;
|
||||||
private DateTimeFormatter dateYearMonthFormat;
|
private DateTimeFormatter dateYearMonthFormat;
|
||||||
|
private boolean copyButton;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -190,6 +193,7 @@ public class RenderingContext {
|
||||||
res.targetVersion = targetVersion;
|
res.targetVersion = targetVersion;
|
||||||
res.locale = locale;
|
res.locale = locale;
|
||||||
res.showComments = showComments;
|
res.showComments = showComments;
|
||||||
|
res.copyButton = copyButton;
|
||||||
|
|
||||||
res.terminologyServiceOptions = terminologyServiceOptions.copy();
|
res.terminologyServiceOptions = terminologyServiceOptions.copy();
|
||||||
return res;
|
return res;
|
||||||
|
@ -596,6 +600,13 @@ public class RenderingContext {
|
||||||
this.showComments = showComments;
|
this.showComments = showComments;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
public boolean isCopyButton() {
|
||||||
|
return copyButton;
|
||||||
|
}
|
||||||
|
public RenderingContext setCopyButton(boolean copyButton) {
|
||||||
|
this.copyButton = copyButton;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package org.hl7.fhir.r5.utils;
|
package org.hl7.fhir.r5.utils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -37,22 +38,31 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
import org.hl7.fhir.exceptions.PathEngineException;
|
import org.hl7.fhir.exceptions.PathEngineException;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
|
import org.hl7.fhir.r5.elementmodel.Element;
|
||||||
import org.hl7.fhir.r5.model.Base;
|
import org.hl7.fhir.r5.model.Base;
|
||||||
import org.hl7.fhir.r5.model.ExpressionNode;
|
import org.hl7.fhir.r5.model.ExpressionNode;
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
import org.hl7.fhir.r5.model.Tuple;
|
import org.hl7.fhir.r5.model.Tuple;
|
||||||
import org.hl7.fhir.r5.model.TypeDetails;
|
import org.hl7.fhir.r5.model.TypeDetails;
|
||||||
import org.hl7.fhir.r5.model.ValueSet;
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
|
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
|
||||||
|
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine.ExpressionNodeWithOffset;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine.ExpressionNodeWithOffset;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
||||||
|
import org.hl7.fhir.r5.utils.LiquidEngine.ILiquidRenderingSupport;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||||
|
|
||||||
public class LiquidEngine implements IEvaluationContext {
|
public class LiquidEngine implements IEvaluationContext {
|
||||||
|
|
||||||
|
public interface ILiquidRenderingSupport {
|
||||||
|
String renderForLiquid(Object appContext, Base i) throws FHIRException;
|
||||||
|
}
|
||||||
|
|
||||||
public interface ILiquidEngineIncludeResolver {
|
public interface ILiquidEngineIncludeResolver {
|
||||||
public String fetchInclude(LiquidEngine engine, String name);
|
public String fetchInclude(LiquidEngine engine, String name);
|
||||||
}
|
}
|
||||||
|
@ -60,6 +70,7 @@ public class LiquidEngine implements IEvaluationContext {
|
||||||
private IEvaluationContext externalHostServices;
|
private IEvaluationContext externalHostServices;
|
||||||
private FHIRPathEngine engine;
|
private FHIRPathEngine engine;
|
||||||
private ILiquidEngineIncludeResolver includeResolver;
|
private ILiquidEngineIncludeResolver includeResolver;
|
||||||
|
private ILiquidRenderingSupport renderingSupport;
|
||||||
|
|
||||||
private class LiquidEngineContext {
|
private class LiquidEngineContext {
|
||||||
private Object externalContext;
|
private Object externalContext;
|
||||||
|
@ -92,6 +103,14 @@ public class LiquidEngine implements IEvaluationContext {
|
||||||
this.includeResolver = includeResolver;
|
this.includeResolver = includeResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ILiquidRenderingSupport getRenderingSupport() {
|
||||||
|
return renderingSupport;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRenderingSupport(ILiquidRenderingSupport renderingSupport) {
|
||||||
|
this.renderingSupport = renderingSupport;
|
||||||
|
}
|
||||||
|
|
||||||
public LiquidDocument parse(String source, String sourceName) throws FHIRException {
|
public LiquidDocument parse(String source, String sourceName) throws FHIRException {
|
||||||
return new LiquidParser(source).parse(sourceName);
|
return new LiquidParser(source).parse(sourceName);
|
||||||
}
|
}
|
||||||
|
@ -105,6 +124,7 @@ public class LiquidEngine implements IEvaluationContext {
|
||||||
return b.toString();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private abstract class LiquidNode {
|
private abstract class LiquidNode {
|
||||||
protected void closeUp() {
|
protected void closeUp() {
|
||||||
}
|
}
|
||||||
|
@ -130,6 +150,7 @@ public class LiquidEngine implements IEvaluationContext {
|
||||||
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) {
|
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) {
|
||||||
b.append(constant);
|
b.append(constant);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class LiquidStatement extends LiquidNode {
|
private class LiquidStatement extends LiquidNode {
|
||||||
|
@ -140,7 +161,13 @@ public class LiquidEngine implements IEvaluationContext {
|
||||||
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) throws FHIRException {
|
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||||
if (compiled == null)
|
if (compiled == null)
|
||||||
compiled = engine.parse(statement);
|
compiled = engine.parse(statement);
|
||||||
b.append(engine.evaluateToString(ctxt, resource, resource, resource, compiled));
|
List<Base> items = engine.evaluate(ctxt, resource, resource, resource, compiled);
|
||||||
|
boolean first = true;
|
||||||
|
for (Base i : items) {
|
||||||
|
if (first) first = false; else b.append(", ");
|
||||||
|
String s = renderingSupport != null ? renderingSupport.renderForLiquid(ctxt.externalContext, i) : null;
|
||||||
|
b.append(s != null ? s : engine.convertToString(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,10 @@ public class NarrativeGenerationTests {
|
||||||
public Base parseType(String xml, String type) throws FHIRFormatError, IOException, FHIRException {
|
public Base parseType(String xml, String type) throws FHIRFormatError, IOException, FHIRException {
|
||||||
return new org.hl7.fhir.r5.formats.XmlParser().parseType(xml, type);
|
return new org.hl7.fhir.r5.formats.XmlParser().parseType(xml, type);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public Base parseType(org.hl7.fhir.r5.elementmodel.Element e) throws FHIRFormatError, IOException, FHIRException {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String WINDOWS = "WINDOWS";
|
public static final String WINDOWS = "WINDOWS";
|
||||||
|
|
|
@ -9,6 +9,7 @@ import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
|
@ -50,6 +51,11 @@ public class VocabTests {
|
||||||
public Base parseType(String xml, String type) throws FHIRFormatError, IOException, FHIRException {
|
public Base parseType(String xml, String type) throws FHIRFormatError, IOException, FHIRException {
|
||||||
return new org.hl7.fhir.r5.formats.XmlParser().parseType(xml, type);
|
return new org.hl7.fhir.r5.formats.XmlParser().parseType(xml, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Base parseType(org.hl7.fhir.r5.elementmodel.Element e) throws FHIRFormatError, IOException, FHIRException {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IWorkerContext context;
|
private static IWorkerContext context;
|
||||||
|
|
|
@ -1542,3 +1542,12 @@ v: {
|
||||||
"system" : "urn:iso:std:iso:3166"
|
"system" : "urn:iso:std:iso:3166"
|
||||||
}
|
}
|
||||||
-------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"code" : "en-AU"
|
||||||
|
}, "url": "http://hl7.org/fhir/ValueSet/languages", "version": "4.0.1", "lang":"en-AU", "useServer":"true", "useClient":"true", "guessSystem":"true", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false"}####
|
||||||
|
v: {
|
||||||
|
"display" : "English (Australia)",
|
||||||
|
"code" : "en-AU",
|
||||||
|
"system" : "urn:ietf:bcp:47"
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue