start building the renderer package
This commit is contained in:
parent
ef2f9e01c7
commit
37d4994c8f
|
@ -87,7 +87,7 @@ import org.hl7.fhir.r5.model.UriType;
|
|||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.r5.terminologies.TerminologyRenderer;
|
||||
import org.hl7.fhir.r5.renderers.TerminologyRenderer;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||
import org.hl7.fhir.r5.utils.NarrativeGenerator;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package org.hl7.fhir.r5.terminologies;
|
||||
package org.hl7.fhir.r5.renderers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -10,12 +10,12 @@ import java.util.Set;
|
|||
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
import org.hl7.fhir.r5.model.ConceptMap;
|
||||
import org.hl7.fhir.r5.model.Enumeration;
|
||||
import org.hl7.fhir.r5.model.Extension;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.CodeSystemContentMode;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.CodeSystemFilterComponent;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
|
||||
|
@ -25,34 +25,46 @@ import org.hl7.fhir.r5.model.CodeSystem.PropertyComponent;
|
|||
import org.hl7.fhir.r5.model.ConceptMap.ConceptMapGroupComponent;
|
||||
import org.hl7.fhir.r5.model.ConceptMap.SourceElementComponent;
|
||||
import org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent;
|
||||
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities.CodeSystemNavigator;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
public class CodeSystemRenderer extends TerminologyRenderer {
|
||||
|
||||
public CodeSystemRenderer(RenderingContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public CodeSystemRenderer(RenderingContext context, ResourceContext rcontext) {
|
||||
super(context, rcontext);
|
||||
}
|
||||
|
||||
private List<String> codeSystemPropList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mode - whether we are rendering for a resource directly, or for an IG
|
||||
* @param context - common services (terminology server, code system cache etc)
|
||||
* @param markdown - markdown processing engine of the correct sort for the version applicable
|
||||
* @param prefix - the path to the base FHIR specification
|
||||
* @param lang - the language to use (null for the default)
|
||||
*/
|
||||
public CodeSystemRenderer(TerminologyRendererMode mode, IWorkerContext context, MarkDownProcessor markdown, String prefix, String lang) {
|
||||
super(mode, context, markdown, prefix, lang);
|
||||
}
|
||||
|
||||
public List<String> getCodeSystemPropList() {
|
||||
return codeSystemPropList;
|
||||
}
|
||||
|
||||
public boolean generate(XhtmlNode x, CodeSystem cs, boolean header) throws FHIRFormatError, DefinitionException, IOException {
|
||||
public void render(CodeSystem cs) throws FHIRFormatError, DefinitionException, IOException {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
boolean hasExtensions = render(x, cs);
|
||||
inject(cs, x, hasExtensions ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
|
||||
}
|
||||
|
||||
public boolean render(XhtmlNode x, CodeSystem cs) throws FHIRFormatError, DefinitionException, IOException {
|
||||
return render(x, cs, false);
|
||||
}
|
||||
|
||||
public boolean render(XhtmlNode x, CodeSystem cs, boolean header) throws FHIRFormatError, DefinitionException, IOException {
|
||||
boolean hasExtensions = false;
|
||||
|
||||
if (header) {
|
||||
|
@ -71,15 +83,23 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
return hasExtensions;
|
||||
}
|
||||
|
||||
public void describe(XhtmlNode x, CodeSystem cs) {
|
||||
x.tx(display(cs));
|
||||
}
|
||||
|
||||
public String display(CodeSystem cs) {
|
||||
return cs.present();
|
||||
}
|
||||
|
||||
private void generateFilters(XhtmlNode x, CodeSystem cs) {
|
||||
if (cs.hasFilter()) {
|
||||
x.para().b().tx(context.translator().translate("xhtml-gen-cs", "Filters", lang));
|
||||
x.para().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Filters", getContext().getLang()));
|
||||
XhtmlNode tbl = x.table("grid");
|
||||
XhtmlNode tr = tbl.tr();
|
||||
tr.td().b().tx(context.translator().translate("xhtml-gen-cs", "Code", lang));
|
||||
tr.td().b().tx(context.translator().translate("xhtml-gen-cs", "Description", lang));
|
||||
tr.td().b().tx(context.translator().translate("xhtml-gen-cs", "operator", lang));
|
||||
tr.td().b().tx(context.translator().translate("xhtml-gen-cs", "Value", lang));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Code", getContext().getLang()));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Description", getContext().getLang()));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "operator", getContext().getLang()));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Value", getContext().getLang()));
|
||||
for (CodeSystemFilterComponent f : cs.getFilter()) {
|
||||
tr = tbl.tr();
|
||||
tr.td().tx(f.getCode());
|
||||
|
@ -99,16 +119,16 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
hasRendered = hasRendered || !p.getCode().equals(ToolingExtensions.getPresentation(p, p.getCodeElement()));
|
||||
}
|
||||
|
||||
x.para().b().tx(context.translator().translate("xhtml-gen-cs", "Properties", lang));
|
||||
x.para().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Properties", getContext().getLang()));
|
||||
XhtmlNode tbl = x.table("grid");
|
||||
XhtmlNode tr = tbl.tr();
|
||||
if (hasRendered) {
|
||||
tr.td().b().tx(context.translator().translate("xhtml-gen-cs", "Name", lang));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Name", getContext().getLang()));
|
||||
}
|
||||
tr.td().b().tx(context.translator().translate("xhtml-gen-cs", "Code", lang));
|
||||
tr.td().b().tx(context.translator().translate("xhtml-gen-cs", "URL", lang));
|
||||
tr.td().b().tx(context.translator().translate("xhtml-gen-cs", "Description", lang));
|
||||
tr.td().b().tx(context.translator().translate("xhtml-gen-cs", "Type", lang));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Code", getContext().getLang()));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "URL", getContext().getLang()));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Description", getContext().getLang()));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Type", getContext().getLang()));
|
||||
for (PropertyComponent p : cs.getProperty()) {
|
||||
tr = tbl.tr();
|
||||
if (hasRendered) {
|
||||
|
@ -125,13 +145,13 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
private boolean generateCodeSystemContent(XhtmlNode x, CodeSystem cs, boolean hasExtensions, List<UsedConceptMap> maps) throws FHIRFormatError, DefinitionException, IOException {
|
||||
XhtmlNode p = x.para();
|
||||
if (cs.getContent() == CodeSystemContentMode.COMPLETE)
|
||||
p.tx(context.translator().translateAndFormat("xhtml-gen-cs", lang, "This code system %s defines the following codes", cs.getUrl())+":");
|
||||
p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), "This code system %s defines the following codes", cs.getUrl())+":");
|
||||
else if (cs.getContent() == CodeSystemContentMode.EXAMPLE)
|
||||
p.tx(context.translator().translateAndFormat("xhtml-gen-cs", lang, "This code system %s defines many codes, of which the following are some examples", cs.getUrl())+":");
|
||||
p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), "This code system %s defines many codes, of which the following are some examples", cs.getUrl())+":");
|
||||
else if (cs.getContent() == CodeSystemContentMode.FRAGMENT )
|
||||
p.tx(context.translator().translateAndFormat("xhtml-gen-cs", lang, "This code system %s defines many codes, of which the following are a subset", cs.getUrl())+":");
|
||||
p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), "This code system %s defines many codes, of which the following are a subset", cs.getUrl())+":");
|
||||
else if (cs.getContent() == CodeSystemContentMode.NOTPRESENT ) {
|
||||
p.tx(context.translator().translateAndFormat("xhtml-gen-cs", lang, "This code system %s defines many codes, but they are not represented here", cs.getUrl()));
|
||||
p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), "This code system %s defines many codes, but they are not represented here", cs.getUrl()));
|
||||
return false;
|
||||
}
|
||||
XhtmlNode t = x.table( "codes");
|
||||
|
@ -212,7 +232,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
if (Utilities.existsInList(uri, "http://hl7.org/fhir/concept-properties") || codeSystemPropList.contains(uri)) {
|
||||
return true;
|
||||
};
|
||||
CodeSystem cs = context.fetchCodeSystem(uri);
|
||||
CodeSystem cs = getContext().getWorker().fetchCodeSystem(uri);
|
||||
if (cs == null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -298,12 +318,12 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
td = tr.td();
|
||||
if (c != null &&
|
||||
c.hasDefinitionElement()) {
|
||||
if (lang == null) {
|
||||
if (getContext().getLang() == null) {
|
||||
if (hasMarkdownInDefinitions(cs))
|
||||
addMarkdown(td, c.getDefinition());
|
||||
else
|
||||
td.addText(c.getDefinition());
|
||||
} else if (lang.equals("*")) {
|
||||
} else if (getContext().getLang().equals("*")) {
|
||||
boolean sl = false;
|
||||
for (ConceptDefinitionDesignationComponent cd : c.getDesignation())
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "definition") && cd.hasLanguage() && !c.getDefinition().equalsIgnoreCase(cd.getValue()))
|
||||
|
@ -315,11 +335,11 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
td.addText(cd.getLanguage()+": "+cd.getValue());
|
||||
}
|
||||
}
|
||||
} else if (lang.equals(cs.getLanguage()) || (lang.equals("en") && !cs.hasLanguage())) {
|
||||
} else if (getContext().getLang().equals(cs.getLanguage()) || (getContext().getLang().equals("en") && !cs.hasLanguage())) {
|
||||
td.addText(c.getDefinition());
|
||||
} else {
|
||||
for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) {
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "definition") && cd.hasLanguage() && cd.getLanguage().equals(lang)) {
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "definition") && cd.hasLanguage() && cd.getLanguage().equals(getContext().getLang())) {
|
||||
td.addText(cd.getValue());
|
||||
}
|
||||
}
|
||||
|
@ -329,7 +349,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
td = tr.td();
|
||||
Boolean b = CodeSystemUtilities.isDeprecated(cs, c);
|
||||
if (b != null && b) {
|
||||
smartAddText(td, context.translator().translate("xhtml-gen-cs", "Deprecated", lang));
|
||||
smartAddText(td, getContext().getWorker().translator().translate("xhtml-gen-cs", "Deprecated", getContext().getLang()));
|
||||
hasExtensions = true;
|
||||
if (ToolingExtensions.hasExtension(c, ToolingExtensions.EXT_REPLACED_BY)) {
|
||||
Coding cc = (Coding) ToolingExtensions.getExtension(c, ToolingExtensions.EXT_REPLACED_BY).getValue();
|
||||
|
@ -351,10 +371,10 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
String bc = ext.hasValue() ? ext.getValue().primitiveValue() : null;
|
||||
Map<String, String> translations = ToolingExtensions.getLanguageTranslations(ext.getValue());
|
||||
|
||||
if (lang == null) {
|
||||
if (getContext().getLang() == null) {
|
||||
if (bc != null)
|
||||
td.addText(bc);
|
||||
} else if (lang.equals("*")) {
|
||||
} else if (getContext().getLang().equals("*")) {
|
||||
boolean sl = false;
|
||||
for (String l : translations.keySet())
|
||||
if (bc == null || !bc.equalsIgnoreCase(translations.get(l)))
|
||||
|
@ -369,14 +389,14 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
td.addText(l+": "+translations.get(l));
|
||||
}
|
||||
}
|
||||
} else if (lang.equals(cs.getLanguage()) || (lang.equals("en") && !cs.hasLanguage())) {
|
||||
} else if (getContext().getLang().equals(cs.getLanguage()) || (getContext().getLang().equals("en") && !cs.hasLanguage())) {
|
||||
if (bc != null)
|
||||
td.addText(bc);
|
||||
} else {
|
||||
if (bc != null)
|
||||
translations.put(cs.getLanguage("en"), bc);
|
||||
for (String l : translations.keySet()) {
|
||||
if (l.equals(lang)) {
|
||||
if (l.equals(getContext().getLang())) {
|
||||
td.addText(translations.get(l));
|
||||
}
|
||||
}
|
||||
|
@ -416,7 +436,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
first = false;
|
||||
XhtmlNode span = td.span(null, mapping.comp.hasRelationship() ? mapping.comp.getRelationship().toCode() : "");
|
||||
span.addText(getCharForRelationship(mapping.comp));
|
||||
a = td.ah(prefix+m.getLink()+"#"+makeAnchor(mapping.group.getTarget(), mapping.comp.getCode()));
|
||||
a = td.ah(getContext().getPrefix()+m.getLink()+"#"+makeAnchor(mapping.group.getTarget(), mapping.comp.getCode()));
|
||||
a.addText(mapping.comp.getCode());
|
||||
if (!Utilities.noString(mapping.comp.getComment()))
|
||||
td.i().tx("("+mapping.comp.getComment()+")");
|
||||
|
@ -456,9 +476,9 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
|
||||
public void renderDisplayName(ConceptDefinitionComponent c, CodeSystem cs, XhtmlNode td) {
|
||||
if (c.hasDisplayElement()) {
|
||||
if (lang == null) {
|
||||
if (getContext().getLang() == null) {
|
||||
td.addText(c.getDisplay());
|
||||
} else if (lang.equals("*")) {
|
||||
} else if (getContext().getLang().equals("*")) {
|
||||
boolean sl = false;
|
||||
for (ConceptDefinitionDesignationComponent cd : c.getDesignation())
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "display") && cd.hasLanguage() && !c.getDisplay().equalsIgnoreCase(cd.getValue()))
|
||||
|
@ -470,11 +490,11 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
td.addText(cd.getLanguage()+": "+cd.getValue());
|
||||
}
|
||||
}
|
||||
} else if (lang.equals(cs.getLanguage()) || (lang.equals("en") && !cs.hasLanguage())) {
|
||||
} else if (getContext().getLang().equals(cs.getLanguage()) || (getContext().getLang().equals("en") && !cs.hasLanguage())) {
|
||||
td.addText(c.getDisplay());
|
||||
} else {
|
||||
for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) {
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "display") && cd.hasLanguage() && cd.getLanguage().equals(lang)) {
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "display") && cd.hasLanguage() && cd.getLanguage().equals(getContext().getLang())) {
|
||||
td.addText(cd.getValue());
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.hl7.fhir.r5.terminologies;
|
||||
package org.hl7.fhir.r5.renderers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
@ -8,50 +8,54 @@ import java.util.Map;
|
|||
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.ConceptMap;
|
||||
import org.hl7.fhir.r5.model.ContactDetail;
|
||||
import org.hl7.fhir.r5.model.ContactPoint;
|
||||
import org.hl7.fhir.r5.model.ConceptMap;
|
||||
import org.hl7.fhir.r5.model.ConceptMap.ConceptMapGroupComponent;
|
||||
import org.hl7.fhir.r5.model.ConceptMap.OtherElementComponent;
|
||||
import org.hl7.fhir.r5.model.ConceptMap.SourceElementComponent;
|
||||
import org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent;
|
||||
import org.hl7.fhir.r5.model.Enumerations.ConceptMapRelationship;
|
||||
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.r5.utils.NarrativeGenerator.ResourceContext;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
public class ConceptMapRenderer extends TerminologyRenderer {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mode - whether we are rendering for a resource directly, or for an IG
|
||||
* @param context - common services (terminology server, code system cache etc)
|
||||
* @param markdown - markdown processing engine of the correct sort for the version applicable
|
||||
* @param prefix - the path to the base FHIR specification
|
||||
* @param lang - the language to use (null for the default)
|
||||
*/
|
||||
public ConceptMapRenderer(TerminologyRendererMode mode, IWorkerContext context, MarkDownProcessor markdown, String prefix, String lang) {
|
||||
super(mode, context, markdown, prefix, lang);
|
||||
public ConceptMapRenderer(RenderingContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public boolean generate(ResourceContext rcontext, ConceptMap cm, XhtmlNode x) throws FHIRFormatError, DefinitionException, IOException {
|
||||
public ConceptMapRenderer(RenderingContext context, ResourceContext rcontext) {
|
||||
super(context, rcontext);
|
||||
}
|
||||
|
||||
public void render(ConceptMap cm) throws FHIRFormatError, DefinitionException, IOException {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
boolean hasExtensions = render(x, cm);
|
||||
inject(cm, x, hasExtensions ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
|
||||
}
|
||||
|
||||
public boolean render(XhtmlNode x, ConceptMap cm) throws FHIRFormatError, DefinitionException, IOException {
|
||||
x.h2().addText(cm.getName()+" ("+cm.getUrl()+")");
|
||||
|
||||
XhtmlNode p = x.para();
|
||||
p.tx("Mapping from ");
|
||||
if (cm.hasSource())
|
||||
AddVsRef(rcontext, cm.getSource().primitiveValue(), p);
|
||||
AddVsRef(cm.getSource().primitiveValue(), p);
|
||||
else
|
||||
p.tx("(not specified)");
|
||||
p.tx(" to ");
|
||||
if (cm.hasTarget())
|
||||
AddVsRef(rcontext, cm.getTarget().primitiveValue(), p);
|
||||
AddVsRef(cm.getTarget().primitiveValue(), p);
|
||||
else
|
||||
p.tx("(not specified)");
|
||||
|
||||
|
@ -89,9 +93,9 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
|||
|
||||
x.br();
|
||||
|
||||
CodeSystem cs = context.fetchCodeSystem("http://hl7.org/fhir/concept-map-relationship");
|
||||
CodeSystem cs = getContext().getWorker().fetchCodeSystem("http://hl7.org/fhir/concept-map-relationship");
|
||||
if (cs == null)
|
||||
cs = context.fetchCodeSystem("http://hl7.org/fhir/concept-map-equivalence");
|
||||
cs = getContext().getWorker().fetchCodeSystem("http://hl7.org/fhir/concept-map-equivalence");
|
||||
String eqpath = cs == null ? null : cs.getUserString("path");
|
||||
|
||||
for (ConceptMapGroupComponent grp : cm.getGroup()) {
|
||||
|
@ -307,6 +311,14 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
|||
return true;
|
||||
}
|
||||
|
||||
public void describe(XhtmlNode x, ConceptMap cm) {
|
||||
x.tx(display(cm));
|
||||
}
|
||||
|
||||
public String display(ConceptMap cm) {
|
||||
return cm.present();
|
||||
}
|
||||
|
||||
private boolean isSameCodeAndDisplay(String code, String display) {
|
||||
String c = code.replace(" ", "").replace("-", "").toLowerCase();
|
||||
String d = display.replace(" ", "").replace("-", "").toLowerCase();
|
||||
|
@ -359,7 +371,7 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
|||
public void renderCSDetailsLink(XhtmlNode tr, String url, boolean span2) {
|
||||
CodeSystem cs;
|
||||
XhtmlNode td;
|
||||
cs = context.fetchCodeSystem(url);
|
||||
cs = getContext().getWorker().fetchCodeSystem(url);
|
||||
td = tr.td();
|
||||
if (span2) {
|
||||
td.colspan("2");
|
|
@ -0,0 +1,715 @@
|
|||
package org.hl7.fhir.r5.renderers;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
||||
import org.hl7.fhir.r5.model.Address;
|
||||
import org.hl7.fhir.r5.model.Annotation;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
import org.hl7.fhir.r5.model.ContactPoint;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.Timing;
|
||||
import org.hl7.fhir.r5.model.UriType;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.ContactPoint.ContactPointSystem;
|
||||
import org.hl7.fhir.r5.model.HumanName.NameUse;
|
||||
import org.hl7.fhir.r5.model.Timing.EventTiming;
|
||||
import org.hl7.fhir.r5.model.Timing.TimingRepeatComponent;
|
||||
import org.hl7.fhir.r5.model.Timing.UnitsOfTime;
|
||||
import org.hl7.fhir.r5.model.DataType;
|
||||
import org.hl7.fhir.r5.model.DateTimeType;
|
||||
import org.hl7.fhir.r5.model.Enumeration;
|
||||
import org.hl7.fhir.r5.model.HumanName;
|
||||
import org.hl7.fhir.r5.model.Identifier;
|
||||
import org.hl7.fhir.r5.model.Period;
|
||||
import org.hl7.fhir.r5.model.Quantity;
|
||||
import org.hl7.fhir.r5.model.Range;
|
||||
import org.hl7.fhir.r5.model.SampledData;
|
||||
import org.hl7.fhir.r5.model.StringType;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceDesignationComponent;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlParser;
|
||||
|
||||
public class DataRenderer {
|
||||
|
||||
// -- 1. context --------------------------------------------------------------
|
||||
|
||||
protected RenderingContext context;
|
||||
|
||||
public DataRenderer(RenderingContext context) {
|
||||
super();
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
// -- 2. Markdown support -------------------------------------------------------
|
||||
|
||||
protected void addMarkdown(XhtmlNode x, String text) throws FHIRFormatError, IOException, DefinitionException {
|
||||
if (text != null) {
|
||||
// 1. custom FHIR extensions
|
||||
while (text.contains("[[[")) {
|
||||
String left = text.substring(0, text.indexOf("[[["));
|
||||
String link = text.substring(text.indexOf("[[[")+3, text.indexOf("]]]"));
|
||||
String right = text.substring(text.indexOf("]]]")+3);
|
||||
String url = link;
|
||||
String[] parts = link.split("\\#");
|
||||
StructureDefinition p = getContext().getWorker().fetchResource(StructureDefinition.class, parts[0]);
|
||||
if (p == null)
|
||||
p = getContext().getWorker().fetchTypeDefinition(parts[0]);
|
||||
if (p == null)
|
||||
p = getContext().getWorker().fetchResource(StructureDefinition.class, link);
|
||||
if (p != null) {
|
||||
url = p.getUserString("path");
|
||||
if (url == null)
|
||||
url = p.getUserString("filename");
|
||||
} else
|
||||
throw new DefinitionException("Unable to resolve markdown link "+link);
|
||||
|
||||
text = left+"["+link+"]("+url+")"+right;
|
||||
}
|
||||
|
||||
// 2. markdown
|
||||
String s = getContext().getMarkdown().process(Utilities.escapeXml(text), "narrative generator");
|
||||
XhtmlParser p = new XhtmlParser();
|
||||
XhtmlNode m;
|
||||
try {
|
||||
m = p.parse("<div>"+s+"</div>", "div");
|
||||
} catch (org.hl7.fhir.exceptions.FHIRFormatError e) {
|
||||
throw new FHIRFormatError(e.getMessage(), e);
|
||||
}
|
||||
x.getChildNodes().addAll(m.getChildNodes());
|
||||
}
|
||||
}
|
||||
|
||||
protected void smartAddText(XhtmlNode p, String text) {
|
||||
if (text == null)
|
||||
return;
|
||||
|
||||
String[] lines = text.split("\\r\\n");
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
if (i > 0)
|
||||
p.br();
|
||||
p.addText(lines[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// -- 3. Gener Purpose Terminology Support -----------------------------------------
|
||||
|
||||
public static String describeSystem(String system) {
|
||||
if (system == null)
|
||||
return "[not stated]";
|
||||
if (system.equals("http://loinc.org"))
|
||||
return "LOINC";
|
||||
if (system.startsWith("http://snomed.info"))
|
||||
return "SNOMED CT";
|
||||
if (system.equals("http://www.nlm.nih.gov/research/umls/rxnorm"))
|
||||
return "RxNorm";
|
||||
if (system.equals("http://hl7.org/fhir/sid/icd-9"))
|
||||
return "ICD-9";
|
||||
if (system.equals("http://dicom.nema.org/resources/ontology/DCM"))
|
||||
return "DICOM";
|
||||
if (system.equals("http://unitsofmeasure.org"))
|
||||
return "UCUM";
|
||||
|
||||
return system;
|
||||
}
|
||||
|
||||
protected String makeAnchor(String codeSystem, String code) {
|
||||
String s = codeSystem+'-'+code;
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (char c : s.toCharArray()) {
|
||||
if (Character.isAlphabetic(c) || Character.isDigit(c) || c == '.')
|
||||
b.append(c);
|
||||
else
|
||||
b.append('-');
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private String lookupCode(String system, String code) {
|
||||
ValidationResult t = getContext().getWorker().validateCode(getContext().getTerminologyServiceOptions(), system, code, null);
|
||||
|
||||
if (t != null && t.getDisplay() != null)
|
||||
return t.getDisplay();
|
||||
else
|
||||
return code;
|
||||
}
|
||||
|
||||
protected String describeLang(String lang) {
|
||||
ValueSet v = getContext().getWorker().fetchResource(ValueSet.class, "http://hl7.org/fhir/ValueSet/languages");
|
||||
if (v != null) {
|
||||
ConceptReferenceComponent l = null;
|
||||
for (ConceptReferenceComponent cc : v.getCompose().getIncludeFirstRep().getConcept()) {
|
||||
if (cc.getCode().equals(lang))
|
||||
l = cc;
|
||||
}
|
||||
if (l == null) {
|
||||
if (lang.contains("-"))
|
||||
lang = lang.substring(0, lang.indexOf("-"));
|
||||
for (ConceptReferenceComponent cc : v.getCompose().getIncludeFirstRep().getConcept()) {
|
||||
if (cc.getCode().equals(lang) || cc.getCode().startsWith(lang+"-"))
|
||||
l = cc;
|
||||
}
|
||||
}
|
||||
if (l != null) {
|
||||
if (lang.contains("-"))
|
||||
lang = lang.substring(0, lang.indexOf("-"));
|
||||
String en = l.getDisplay();
|
||||
String nativelang = null;
|
||||
for (ConceptReferenceDesignationComponent cd : l.getDesignation()) {
|
||||
if (cd.getLanguage().equals(lang))
|
||||
nativelang = cd.getValue();
|
||||
}
|
||||
if (nativelang == null)
|
||||
return en+" ("+lang+")";
|
||||
else
|
||||
return nativelang+" ("+en+", "+lang+")";
|
||||
}
|
||||
}
|
||||
return lang;
|
||||
}
|
||||
|
||||
|
||||
private boolean isCanonical(String path) {
|
||||
if (!path.endsWith(".url"))
|
||||
return false;
|
||||
StructureDefinition sd = getContext().getWorker().fetchTypeDefinition(path.substring(0, path.length()-4));
|
||||
if (sd == null)
|
||||
return false;
|
||||
if (Utilities.existsInList(path.substring(0, path.length()-4), "CapabilityStatement", "StructureDefinition", "ImplementationGuide", "SearchParameter", "MessageDefinition", "OperationDefinition", "CompartmentDefinition", "StructureMap", "GraphDefinition",
|
||||
"ExampleScenario", "CodeSystem", "ValueSet", "ConceptMap", "NamingSystem", "TerminologyCapabilities"))
|
||||
return true;
|
||||
return sd.getBaseDefinitionElement().hasExtension("http://hl7.org/fhir/StructureDefinition/structuredefinition-codegen-super");
|
||||
}
|
||||
|
||||
// -- 4. Data type Rendering ----------------------------------------------
|
||||
|
||||
public static String display(IWorkerContext context, DataType type) {
|
||||
return new DataRenderer(new RenderingContext(context, null, null, "", null, ResourceRendererMode.RESOURCE)).display(type);
|
||||
}
|
||||
|
||||
public String display(DataType type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void render(XhtmlNode x, DataType type) {
|
||||
|
||||
}
|
||||
|
||||
public void renderDateTime(XhtmlNode x, Base e) {
|
||||
if (e.hasPrimitiveValue())
|
||||
x.addText(((DateTimeType) e).toHumanDisplay());
|
||||
}
|
||||
|
||||
protected void renderUri(XhtmlNode x, UriType uri) {
|
||||
if (uri.getValue().startsWith("mailto:"))
|
||||
x.ah(uri.getValue()).addText(uri.getValue().substring(7));
|
||||
else
|
||||
x.ah(uri.getValue()).addText(uri.getValue());
|
||||
}
|
||||
|
||||
protected void renderUri(XhtmlNode x, UriType uri, String path, String id) {
|
||||
String url = uri.getValue();
|
||||
if (isCanonical(path)) {
|
||||
CanonicalResource mr = getContext().getWorker().fetchResource(null, url);
|
||||
if (mr != null) {
|
||||
if (path.startsWith(mr.fhirType()+".") && mr.getId().equals(id)) {
|
||||
url = null; // don't link to self whatever
|
||||
} else if (mr.hasUserData("path"))
|
||||
url = mr.getUserString("path");
|
||||
} else if (!getContext().isCanonicalUrlsAsLinks())
|
||||
url = null;
|
||||
}
|
||||
if (url == null)
|
||||
x.b().tx(uri.getValue());
|
||||
else if (uri.getValue().startsWith("mailto:"))
|
||||
x.ah(uri.getValue()).addText(uri.getValue().substring(7));
|
||||
else
|
||||
x.ah(uri.getValue()).addText(uri.getValue());
|
||||
}
|
||||
|
||||
protected void renderAnnotation(XhtmlNode x, Annotation annot) {
|
||||
renderAnnotation(x, annot, false);
|
||||
}
|
||||
|
||||
protected void renderAnnotation(XhtmlNode x, Annotation a, boolean showCodeDetails) throws FHIRException {
|
||||
StringBuilder s = new StringBuilder();
|
||||
if (a.hasAuthor()) {
|
||||
s.append("Author: ");
|
||||
|
||||
if (a.hasAuthorReference())
|
||||
s.append(a.getAuthorReference().getReference());
|
||||
else if (a.hasAuthorStringType())
|
||||
s.append(a.getAuthorStringType().getValue());
|
||||
}
|
||||
|
||||
|
||||
if (a.hasTimeElement()) {
|
||||
if (s.length() > 0)
|
||||
s.append("; ");
|
||||
|
||||
s.append("Made: ").append(a.getTimeElement().toHumanDisplay());
|
||||
}
|
||||
|
||||
if (a.hasText()) {
|
||||
if (s.length() > 0)
|
||||
s.append("; ");
|
||||
|
||||
s.append("Annotation: ").append(a.getText());
|
||||
}
|
||||
x.addText(s.toString());
|
||||
}
|
||||
|
||||
protected void renderCoding(XhtmlNode x, Coding c) {
|
||||
renderCoding(x, c, false);
|
||||
}
|
||||
|
||||
protected void renderCoding(XhtmlNode x, Coding c, boolean showCodeDetails) {
|
||||
String s = "";
|
||||
if (c.hasDisplayElement())
|
||||
s = c.getDisplay();
|
||||
if (Utilities.noString(s))
|
||||
s = lookupCode(c.getSystem(), c.getCode());
|
||||
|
||||
if (Utilities.noString(s))
|
||||
s = c.getCode();
|
||||
|
||||
if (showCodeDetails) {
|
||||
x.addText(s+" (Details: "+TerminologyRenderer.describeSystem(c.getSystem())+" code "+c.getCode()+" = '"+lookupCode(c.getSystem(), c.getCode())+"', stated as '"+c.getDisplay()+"')");
|
||||
} else
|
||||
x.span(null, "{"+c.getSystem()+" "+c.getCode()+"}").addText(s);
|
||||
}
|
||||
|
||||
public String displayCodeableConcept(CodeableConcept cc) {
|
||||
String s = cc.getText();
|
||||
if (Utilities.noString(s)) {
|
||||
for (Coding c : cc.getCoding()) {
|
||||
if (c.hasDisplayElement()) {
|
||||
s = c.getDisplay();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Utilities.noString(s)) {
|
||||
// still? ok, let's try looking it up
|
||||
for (Coding c : cc.getCoding()) {
|
||||
if (c.hasCode() && c.hasSystem()) {
|
||||
s = lookupCode(c.getSystem(), c.getCode());
|
||||
if (!Utilities.noString(s))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Utilities.noString(s)) {
|
||||
if (cc.getCoding().isEmpty())
|
||||
s = "";
|
||||
else
|
||||
s = cc.getCoding().get(0).getCode();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
protected void renderCodeableConcept(XhtmlNode x, CodeableConcept cc) {
|
||||
renderCodeableConcept(x, cc, false);
|
||||
}
|
||||
|
||||
protected void renderCodeableConcept(XhtmlNode x, CodeableConcept cc, boolean showCodeDetails) {
|
||||
if (cc.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String s = cc.getText();
|
||||
if (Utilities.noString(s)) {
|
||||
for (Coding c : cc.getCoding()) {
|
||||
if (c.hasDisplayElement()) {
|
||||
s = c.getDisplay();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Utilities.noString(s)) {
|
||||
// still? ok, let's try looking it up
|
||||
for (Coding c : cc.getCoding()) {
|
||||
if (c.hasCodeElement() && c.hasSystemElement()) {
|
||||
s = lookupCode(c.getSystem(), c.getCode());
|
||||
if (!Utilities.noString(s))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Utilities.noString(s)) {
|
||||
if (cc.getCoding().isEmpty())
|
||||
s = "";
|
||||
else
|
||||
s = cc.getCoding().get(0).getCode();
|
||||
}
|
||||
|
||||
if (showCodeDetails) {
|
||||
x.addText(s+" ");
|
||||
XhtmlNode sp = x.span("background: LightGoldenRodYellow", null);
|
||||
sp.tx("(Details ");
|
||||
boolean first = true;
|
||||
for (Coding c : cc.getCoding()) {
|
||||
if (first) {
|
||||
sp.tx(": ");
|
||||
first = false;
|
||||
} else
|
||||
sp.tx("; ");
|
||||
sp.tx("{"+TerminologyRenderer.describeSystem(c.getSystem())+" code '"+c.getCode()+"' = '"+lookupCode(c.getSystem(), c.getCode())+(c.hasDisplay() ? "', given as '"+c.getDisplay()+"'}" : ""));
|
||||
}
|
||||
sp.tx(")");
|
||||
} else {
|
||||
|
||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
|
||||
for (Coding c : cc.getCoding()) {
|
||||
if (c.hasCodeElement() && c.hasSystemElement()) {
|
||||
b.append("{"+c.getSystem()+" "+c.getCode()+"}");
|
||||
}
|
||||
}
|
||||
|
||||
x.span(null, "Codes: "+b.toString()).addText(s);
|
||||
}
|
||||
}
|
||||
|
||||
private String displayIdentifier(Identifier ii) {
|
||||
String s = Utilities.noString(ii.getValue()) ? "?ngen-9?" : ii.getValue();
|
||||
|
||||
if (ii.hasType()) {
|
||||
if (ii.getType().hasText())
|
||||
s = ii.getType().getText()+" = "+s;
|
||||
else if (ii.getType().hasCoding() && ii.getType().getCoding().get(0).hasDisplay())
|
||||
s = ii.getType().getCoding().get(0).getDisplay()+" = "+s;
|
||||
else if (ii.getType().hasCoding() && ii.getType().getCoding().get(0).hasCode())
|
||||
s = lookupCode(ii.getType().getCoding().get(0).getSystem(), ii.getType().getCoding().get(0).getCode())+" = "+s;
|
||||
}
|
||||
|
||||
if (ii.hasUse())
|
||||
s = s + " ("+ii.getUse().toString()+")";
|
||||
return s;
|
||||
}
|
||||
|
||||
protected void renderIdentifier(XhtmlNode x, Identifier ii) {
|
||||
x.addText(displayIdentifier(ii));
|
||||
}
|
||||
|
||||
public static String displayHumanName(HumanName name) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
if (name.hasText())
|
||||
s.append(name.getText());
|
||||
else {
|
||||
for (StringType p : name.getGiven()) {
|
||||
s.append(p.getValue());
|
||||
s.append(" ");
|
||||
}
|
||||
if (name.hasFamily()) {
|
||||
s.append(name.getFamily());
|
||||
s.append(" ");
|
||||
}
|
||||
}
|
||||
if (name.hasUse() && name.getUse() != NameUse.USUAL)
|
||||
s.append("("+name.getUse().toString()+")");
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
|
||||
protected void renderHumanName(XhtmlNode x, HumanName name) {
|
||||
x.addText(displayHumanName(name));
|
||||
}
|
||||
|
||||
private String displayAddress(Address address) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
if (address.hasText())
|
||||
s.append(address.getText());
|
||||
else {
|
||||
for (StringType p : address.getLine()) {
|
||||
s.append(p.getValue());
|
||||
s.append(" ");
|
||||
}
|
||||
if (address.hasCity()) {
|
||||
s.append(address.getCity());
|
||||
s.append(" ");
|
||||
}
|
||||
if (address.hasState()) {
|
||||
s.append(address.getState());
|
||||
s.append(" ");
|
||||
}
|
||||
|
||||
if (address.hasPostalCode()) {
|
||||
s.append(address.getPostalCode());
|
||||
s.append(" ");
|
||||
}
|
||||
|
||||
if (address.hasCountry()) {
|
||||
s.append(address.getCountry());
|
||||
s.append(" ");
|
||||
}
|
||||
}
|
||||
if (address.hasUse())
|
||||
s.append("("+address.getUse().toString()+")");
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
protected void renderAddress(XhtmlNode x, Address address) {
|
||||
x.addText(displayAddress(address));
|
||||
}
|
||||
|
||||
|
||||
public static String displayContactPoint(ContactPoint contact) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append(describeSystem(contact.getSystem()));
|
||||
if (Utilities.noString(contact.getValue()))
|
||||
s.append("-unknown-");
|
||||
else
|
||||
s.append(contact.getValue());
|
||||
if (contact.hasUse())
|
||||
s.append("("+contact.getUse().toString()+")");
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
protected void renderContactPoint(XhtmlNode x, ContactPoint contact) {
|
||||
x.addText(displayContactPoint(contact));
|
||||
}
|
||||
|
||||
|
||||
protected void addTelecom(XhtmlNode p, ContactPoint c) {
|
||||
if (c.getSystem() == ContactPointSystem.PHONE) {
|
||||
p.tx("Phone: "+c.getValue());
|
||||
} else if (c.getSystem() == ContactPointSystem.FAX) {
|
||||
p.tx("Fax: "+c.getValue());
|
||||
} else if (c.getSystem() == ContactPointSystem.EMAIL) {
|
||||
p.ah( "mailto:"+c.getValue()).addText(c.getValue());
|
||||
} else if (c.getSystem() == ContactPointSystem.URL) {
|
||||
if (c.getValue().length() > 30)
|
||||
p.ah(c.getValue()).addText(c.getValue().substring(0, 30)+"...");
|
||||
else
|
||||
p.ah(c.getValue()).addText(c.getValue());
|
||||
}
|
||||
}
|
||||
private static String describeSystem(ContactPointSystem system) {
|
||||
if (system == null)
|
||||
return "";
|
||||
switch (system) {
|
||||
case PHONE: return "ph: ";
|
||||
case FAX: return "fax: ";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected String displayQuantity(Quantity q) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
|
||||
s.append("(system = '").append(TerminologyRenderer.describeSystem(q.getSystem()))
|
||||
.append("' code ").append(q.getCode())
|
||||
.append(" = '").append(lookupCode(q.getSystem(), q.getCode())).append("')");
|
||||
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
protected void renderQuantity(XhtmlNode x, Quantity q) {
|
||||
renderQuantity(x, q, false);
|
||||
}
|
||||
|
||||
protected void renderQuantity(XhtmlNode x, Quantity q, boolean showCodeDetails) {
|
||||
if (q.hasComparator())
|
||||
x.addText(q.getComparator().toCode());
|
||||
x.addText(q.getValue().toString());
|
||||
if (q.hasUnit())
|
||||
x.tx(" "+q.getUnit());
|
||||
else if (q.hasCode())
|
||||
x.tx(" "+q.getCode());
|
||||
if (showCodeDetails && q.hasCode()) {
|
||||
x.span("background: LightGoldenRodYellow", null).tx(" (Details: "+TerminologyRenderer.describeSystem(q.getSystem())+" code "+q.getCode()+" = '"+lookupCode(q.getSystem(), q.getCode())+"')");
|
||||
}
|
||||
}
|
||||
|
||||
public String displayRange(Range q) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
if (q.hasLow())
|
||||
b.append(q.getLow().getValue().toString());
|
||||
else
|
||||
b.append("?");
|
||||
b.append("-");
|
||||
if (q.hasHigh())
|
||||
b.append(q.getHigh().getValue().toString());
|
||||
else
|
||||
b.append("?");
|
||||
if (q.getLow().hasUnit())
|
||||
b.append(" "+q.getLow().getUnit());
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
protected void renderRange(XhtmlNode x, Range q) {
|
||||
if (q.hasLow())
|
||||
x.addText(q.getLow().getValue().toString());
|
||||
else
|
||||
x.tx("?");
|
||||
x.tx("-");
|
||||
if (q.hasHigh())
|
||||
x.addText(q.getHigh().getValue().toString());
|
||||
else
|
||||
x.tx("?");
|
||||
if (q.getLow().hasUnit())
|
||||
x.tx(" "+q.getLow().getUnit());
|
||||
}
|
||||
|
||||
public static String displayPeriod(Period p) {
|
||||
String s = !p.hasStart() ? "?ngen-5?" : p.getStartElement().toHumanDisplay();
|
||||
s = s + " --> ";
|
||||
return s + (!p.hasEnd() ? "(ongoing)" : p.getEndElement().toHumanDisplay());
|
||||
}
|
||||
|
||||
public void renderPeriod(XhtmlNode x, Period p) {
|
||||
x.addText(!p.hasStart() ? "??" : p.getStartElement().toHumanDisplay());
|
||||
x.tx(" --> ");
|
||||
x.addText(!p.hasEnd() ? "(ongoing)" : p.getEndElement().toHumanDisplay());
|
||||
}
|
||||
|
||||
private String displayTiming(Timing s) throws FHIRException {
|
||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
|
||||
if (s.hasCode())
|
||||
b.append("Code: "+displayCodeableConcept(s.getCode()));
|
||||
|
||||
if (s.getEvent().size() > 0) {
|
||||
CommaSeparatedStringBuilder c = new CommaSeparatedStringBuilder();
|
||||
for (DateTimeType p : s.getEvent()) {
|
||||
c.append(p.toHumanDisplay());
|
||||
}
|
||||
b.append("Events: "+ c.toString());
|
||||
}
|
||||
|
||||
if (s.hasRepeat()) {
|
||||
TimingRepeatComponent rep = s.getRepeat();
|
||||
if (rep.hasBoundsPeriod() && rep.getBoundsPeriod().hasStart())
|
||||
b.append("Starting "+rep.getBoundsPeriod().getStartElement().toHumanDisplay());
|
||||
if (rep.hasCount())
|
||||
b.append("Count "+Integer.toString(rep.getCount())+" times");
|
||||
if (rep.hasDuration())
|
||||
b.append("Duration "+rep.getDuration().toPlainString()+displayTimeUnits(rep.getPeriodUnit()));
|
||||
|
||||
if (rep.hasWhen()) {
|
||||
String st = "";
|
||||
if (rep.hasOffset()) {
|
||||
st = Integer.toString(rep.getOffset())+"min ";
|
||||
}
|
||||
b.append("Do "+st);
|
||||
for (Enumeration<EventTiming> wh : rep.getWhen())
|
||||
b.append(displayEventCode(wh.getValue()));
|
||||
} else {
|
||||
String st = "";
|
||||
if (!rep.hasFrequency() || (!rep.hasFrequencyMax() && rep.getFrequency() == 1) )
|
||||
st = "Once";
|
||||
else {
|
||||
st = Integer.toString(rep.getFrequency());
|
||||
if (rep.hasFrequencyMax())
|
||||
st = st + "-"+Integer.toString(rep.getFrequency());
|
||||
}
|
||||
if (rep.hasPeriod()) {
|
||||
st = st + " per "+rep.getPeriod().toPlainString();
|
||||
if (rep.hasPeriodMax())
|
||||
st = st + "-"+rep.getPeriodMax().toPlainString();
|
||||
st = st + " "+displayTimeUnits(rep.getPeriodUnit());
|
||||
}
|
||||
b.append("Do "+st);
|
||||
}
|
||||
if (rep.hasBoundsPeriod() && rep.getBoundsPeriod().hasEnd())
|
||||
b.append("Until "+rep.getBoundsPeriod().getEndElement().toHumanDisplay());
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private String displayEventCode(EventTiming when) {
|
||||
switch (when) {
|
||||
case C: return "at meals";
|
||||
case CD: return "at lunch";
|
||||
case CM: return "at breakfast";
|
||||
case CV: return "at dinner";
|
||||
case AC: return "before meals";
|
||||
case ACD: return "before lunch";
|
||||
case ACM: return "before breakfast";
|
||||
case ACV: return "before dinner";
|
||||
case HS: return "before sleeping";
|
||||
case PC: return "after meals";
|
||||
case PCD: return "after lunch";
|
||||
case PCM: return "after breakfast";
|
||||
case PCV: return "after dinner";
|
||||
case WAKE: return "after waking";
|
||||
default: return "?ngen-6?";
|
||||
}
|
||||
}
|
||||
|
||||
private String displayTimeUnits(UnitsOfTime units) {
|
||||
if (units == null)
|
||||
return "?ngen-7?";
|
||||
switch (units) {
|
||||
case A: return "years";
|
||||
case D: return "days";
|
||||
case H: return "hours";
|
||||
case MIN: return "minutes";
|
||||
case MO: return "months";
|
||||
case S: return "seconds";
|
||||
case WK: return "weeks";
|
||||
default: return "?ngen-8?";
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderTiming(XhtmlNode x, Timing s) throws FHIRException {
|
||||
x.addText(displayTiming(s));
|
||||
}
|
||||
|
||||
|
||||
private String displaySampledData(SampledData s) {
|
||||
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
|
||||
if (s.hasOrigin())
|
||||
b.append("Origin: "+displayQuantity(s.getOrigin()));
|
||||
|
||||
if (s.hasPeriod())
|
||||
b.append("Period: "+s.getPeriod().toString());
|
||||
|
||||
if (s.hasFactor())
|
||||
b.append("Factor: "+s.getFactor().toString());
|
||||
|
||||
if (s.hasLowerLimit())
|
||||
b.append("Lower: "+s.getLowerLimit().toString());
|
||||
|
||||
if (s.hasUpperLimit())
|
||||
b.append("Upper: "+s.getUpperLimit().toString());
|
||||
|
||||
if (s.hasDimensions())
|
||||
b.append("Dimensions: "+s.getDimensions());
|
||||
|
||||
if (s.hasData())
|
||||
b.append("Data: "+s.getData());
|
||||
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
protected void renderSampledData(XhtmlNode x, SampledData sampledData) {
|
||||
x.addText(displaySampledData(sampledData));
|
||||
}
|
||||
|
||||
public RenderingContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package org.hl7.fhir.r5.renderers;
|
||||
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.Encounter;
|
||||
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
public class EncounterRenderer extends ResourceRenderer {
|
||||
|
||||
|
||||
public EncounterRenderer(RenderingContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public void render(Encounter enc) {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
boolean hasExtensions = render(x, enc);
|
||||
inject(enc, x, hasExtensions ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
|
||||
}
|
||||
|
||||
public boolean render(XhtmlNode x, Encounter enc) {
|
||||
describe(x, enc);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void describe(XhtmlNode x, Encounter enc) {
|
||||
x.tx(display(enc));
|
||||
}
|
||||
|
||||
public String display(Encounter enc) {
|
||||
return "Not done yet";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package org.hl7.fhir.r5.renderers;
|
||||
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.Patient;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
public class PatientRenderer extends ResourceRenderer {
|
||||
|
||||
|
||||
|
||||
public PatientRenderer(RenderingContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public void render(Patient pat) {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
boolean hasExtensions = render(x, pat);
|
||||
inject(pat, x, hasExtensions ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
|
||||
}
|
||||
|
||||
public boolean render(XhtmlNode x, Patient pat) {
|
||||
describe(x, pat);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void describe(XhtmlNode x, Patient pat) {
|
||||
x.tx(display(pat));
|
||||
}
|
||||
|
||||
public String display(Patient pat) {
|
||||
return "Not done yet";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
package org.hl7.fhir.r5.renderers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||
import org.hl7.fhir.r5.model.Provenance;
|
||||
import org.hl7.fhir.r5.model.Provenance;
|
||||
import org.hl7.fhir.r5.model.Reference;
|
||||
import org.hl7.fhir.r5.model.UriType;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
|
||||
import org.hl7.fhir.r5.model.Provenance.ProvenanceAgentComponent;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
public class ProvenanceRenderer extends ResourceRenderer {
|
||||
|
||||
public ProvenanceRenderer(RenderingContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public void render(Provenance prv) throws UnsupportedEncodingException, IOException {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
boolean hasExtensions = render(x, prv);
|
||||
inject(prv, x, hasExtensions ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
|
||||
}
|
||||
|
||||
public boolean render(XhtmlNode x, Provenance prv) throws UnsupportedEncodingException, IOException {
|
||||
boolean hasExtensions = false;
|
||||
|
||||
if (!prv.getTarget().isEmpty()) {
|
||||
if (prv.getTarget().size() == 1) {
|
||||
XhtmlNode p = x.para();
|
||||
p.tx("Provenance for ");
|
||||
renderReference(prv, p, prv.getTargetFirstRep());
|
||||
} else {
|
||||
x.para().tx("Provenance for:");
|
||||
XhtmlNode ul = x.ul();
|
||||
for (Reference ref : prv.getTarget()) {
|
||||
renderReference(prv, ul.li(), ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
// summary table
|
||||
x.para().tx("Summary");
|
||||
XhtmlNode t = x.table("grid");
|
||||
XhtmlNode tr;
|
||||
if (prv.hasOccurred()) {
|
||||
tr = t.tr();
|
||||
tr.td().tx("Occurrence");
|
||||
if (prv.hasOccurredPeriod()) {
|
||||
renderPeriod(tr.td(), prv.getOccurredPeriod());
|
||||
} else {
|
||||
renderDateTime(tr.td(), prv.getOccurredDateTimeType());
|
||||
}
|
||||
}
|
||||
if (prv.hasRecorded()) {
|
||||
tr = t.tr();
|
||||
tr.td().tx("Recorded");
|
||||
tr.td().addText(prv.getRecordedElement().toHumanDisplay());
|
||||
}
|
||||
if (prv.hasPolicy()) {
|
||||
tr = t.tr();
|
||||
tr.td().tx("Policy");
|
||||
if (prv.getPolicy().size() == 1) {
|
||||
renderUri(tr.td(), prv.getPolicy().get(0));
|
||||
} else {
|
||||
XhtmlNode ul = tr.td().ul();
|
||||
for (UriType u : prv.getPolicy()) {
|
||||
renderUri(ul.li(), u);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (prv.hasLocation()) {
|
||||
tr = t.tr();
|
||||
tr.td().tx("Location");
|
||||
renderReference(prv, tr.td(), prv.getLocation());
|
||||
}
|
||||
if (prv.hasActivity()) {
|
||||
tr = t.tr();
|
||||
tr.td().tx("Activity");
|
||||
renderCodeableConcept(tr.td(), prv.getActivity(), false);
|
||||
}
|
||||
|
||||
boolean hasType = false;
|
||||
boolean hasRole = false;
|
||||
boolean hasOnBehalfOf = false;
|
||||
for (ProvenanceAgentComponent a : prv.getAgent()) {
|
||||
hasType = hasType || a.hasType();
|
||||
hasRole = hasRole || a.hasRole();
|
||||
hasOnBehalfOf = hasOnBehalfOf || a.hasOnBehalfOf();
|
||||
}
|
||||
x.para().tx("Agents");
|
||||
t = x.table("grid");
|
||||
tr = t.tr();
|
||||
if (hasType) {
|
||||
tr.td().b().tx("type");
|
||||
}
|
||||
if (hasRole) {
|
||||
tr.td().b().tx("role");
|
||||
}
|
||||
tr.td().b().tx("who");
|
||||
if (hasOnBehalfOf) {
|
||||
tr.td().b().tx("onBehalfOf");
|
||||
}
|
||||
for (ProvenanceAgentComponent a : prv.getAgent()) {
|
||||
tr = t.tr();
|
||||
if (hasType) {
|
||||
if (a.hasType()) {
|
||||
renderCodeableConcept(tr.td(), a.getType(), false);
|
||||
} else {
|
||||
tr.td();
|
||||
}
|
||||
}
|
||||
if (hasRole) {
|
||||
if (a.hasRole()) {
|
||||
if (a.getRole().size() == 1) {
|
||||
renderCodeableConcept(tr.td(), a.getType(), false);
|
||||
} else {
|
||||
XhtmlNode ul = tr.td().ul();
|
||||
for (CodeableConcept cc : a.getRole()) {
|
||||
renderCodeableConcept(ul.li(), cc, false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tr.td();
|
||||
}
|
||||
}
|
||||
if (a.hasWho()) {
|
||||
renderReference(prv, tr.td(), a.getWho());
|
||||
} else {
|
||||
tr.td();
|
||||
}
|
||||
if (hasOnBehalfOf) {
|
||||
if (a.hasOnBehalfOf()) {
|
||||
renderReference(prv, tr.td(), a.getOnBehalfOf());
|
||||
} else {
|
||||
tr.td();
|
||||
}
|
||||
}
|
||||
}
|
||||
// agent table
|
||||
|
||||
return hasExtensions;
|
||||
}
|
||||
|
||||
public void describe(XhtmlNode x, Provenance prv) throws UnsupportedEncodingException, IOException {
|
||||
x.tx(display(prv));
|
||||
}
|
||||
|
||||
public String display(Provenance prv) throws UnsupportedEncodingException, IOException {
|
||||
return "Provenance for "+displayReference(prv, prv.getTargetFirstRep());
|
||||
}
|
||||
|
||||
|
||||
// }
|
||||
//
|
||||
|
||||
}
|
|
@ -0,0 +1,969 @@
|
|||
package org.hl7.fhir.r5.renderers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.formats.FormatUtilities;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.CodeType;
|
||||
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
import org.hl7.fhir.r5.model.ConceptMap;
|
||||
import org.hl7.fhir.r5.model.ContactDetail;
|
||||
import org.hl7.fhir.r5.model.ContactPoint;
|
||||
import org.hl7.fhir.r5.model.DateTimeType;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Dosage;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.Encounter;
|
||||
import org.hl7.fhir.r5.model.Enumeration;
|
||||
import org.hl7.fhir.r5.model.Extension;
|
||||
import org.hl7.fhir.r5.model.HumanName;
|
||||
import org.hl7.fhir.r5.model.IdType;
|
||||
import org.hl7.fhir.r5.model.Identifier;
|
||||
import org.hl7.fhir.r5.model.InstantType;
|
||||
import org.hl7.fhir.r5.model.Meta;
|
||||
import org.hl7.fhir.r5.model.Narrative;
|
||||
import org.hl7.fhir.r5.model.Period;
|
||||
import org.hl7.fhir.r5.model.PrimitiveType;
|
||||
import org.hl7.fhir.r5.model.Property;
|
||||
import org.hl7.fhir.r5.model.Provenance;
|
||||
import org.hl7.fhir.r5.model.Quantity;
|
||||
import org.hl7.fhir.r5.model.Range;
|
||||
import org.hl7.fhir.r5.model.Ratio;
|
||||
import org.hl7.fhir.r5.model.Reference;
|
||||
import org.hl7.fhir.r5.model.RelatedArtifact;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.SampledData;
|
||||
import org.hl7.fhir.r5.model.Signature;
|
||||
import org.hl7.fhir.r5.model.StringType;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.Timing;
|
||||
import org.hl7.fhir.r5.model.UriType;
|
||||
import org.hl7.fhir.r5.model.UsageContext;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.renderers.TerminologyRenderer.UsedConceptMap;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
|
||||
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.DOMWrappers.BaseWrapperElement;
|
||||
import org.hl7.fhir.r5.renderers.utils.DOMWrappers.ResourceWrapperElement;
|
||||
import org.hl7.fhir.r5.renderers.utils.DirectWrappers.ResourceWrapperDirect;
|
||||
import org.hl7.fhir.r5.renderers.utils.DirectWrappers.PropertyWrapperDirect;
|
||||
import org.hl7.fhir.r5.renderers.utils.DirectWrappers.BaseWrapperDirect;
|
||||
import org.hl7.fhir.r5.renderers.utils.ElementWrappers.ResourceWrapperMetaElement;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.IReferenceResolver;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.r5.utils.XVerExtensionManager;
|
||||
import org.hl7.fhir.r5.utils.XVerExtensionManager.XVerExtensionStatus;
|
||||
import org.hl7.fhir.r5.model.Address;
|
||||
import org.hl7.fhir.r5.model.Annotation;
|
||||
import org.hl7.fhir.r5.model.Attachment;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.Base64BinaryType;
|
||||
import org.hl7.fhir.r5.model.BooleanType;
|
||||
import org.hl7.fhir.r5.model.Bundle;
|
||||
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
|
||||
import org.hl7.fhir.r5.model.Patient;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
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.xml.XMLUtil;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
public class ResourceRenderer extends DataRenderer {
|
||||
|
||||
protected ResourceContext rcontext;
|
||||
private XVerExtensionManager xverManager;
|
||||
|
||||
|
||||
public ResourceRenderer(RenderingContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ResourceRenderer(RenderingContext context, ResourceContext rcontext) {
|
||||
super(context);
|
||||
this.rcontext = rcontext;
|
||||
}
|
||||
|
||||
/**
|
||||
* given a resource, update it's narrative with the best rendering available
|
||||
*
|
||||
* @param r - the domain resource in question
|
||||
*
|
||||
* @throws FHIRFormatError
|
||||
* @throws DefinitionException
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
public void render(DomainResource r) throws FHIRFormatError, DefinitionException, IOException {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
boolean hasExtensions = render(x, r);
|
||||
inject(r, x, hasExtensions ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
|
||||
}
|
||||
|
||||
public boolean render(XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException {
|
||||
if (r instanceof CodeSystem) {
|
||||
return new CodeSystemRenderer(context).render(x, (CodeSystem) r);
|
||||
}
|
||||
if (r instanceof ValueSet) {
|
||||
return new ValueSetRenderer(context).render(x, (ValueSet) r);
|
||||
}
|
||||
if (r instanceof ConceptMap) {
|
||||
return new ConceptMapRenderer(context).render(x, (ConceptMap) r);
|
||||
}
|
||||
if (r instanceof Patient) {
|
||||
return new PatientRenderer(context).render(x, (Patient) r);
|
||||
}
|
||||
if (r instanceof Encounter) {
|
||||
return new EncounterRenderer(context).render(x, (Encounter) r);
|
||||
}
|
||||
if (r instanceof Provenance) {
|
||||
return new ProvenanceRenderer(context).render(x, (Provenance) r);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void describe(XhtmlNode x, DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
x.tx(display(r));
|
||||
}
|
||||
|
||||
public String display(DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
if (r instanceof CodeSystem) {
|
||||
return new CodeSystemRenderer(context).display((CodeSystem) r);
|
||||
}
|
||||
if (r instanceof ValueSet) {
|
||||
return new ValueSetRenderer(context).display((ValueSet) r);
|
||||
}
|
||||
if (r instanceof ConceptMap) {
|
||||
return new ConceptMapRenderer(context).display((ConceptMap) r);
|
||||
}
|
||||
if (r instanceof Patient) {
|
||||
return new PatientRenderer(context).display((Patient) r);
|
||||
}
|
||||
if (r instanceof Encounter) {
|
||||
return new EncounterRenderer(context).display((Encounter) r);
|
||||
}
|
||||
if (r instanceof Provenance) {
|
||||
return new ProvenanceRenderer(context).display((Provenance) r);
|
||||
}
|
||||
return "todo";
|
||||
}
|
||||
|
||||
|
||||
protected void inject(DomainResource r, XhtmlNode x, NarrativeStatus status) {
|
||||
if (!x.hasAttribute("xmlns"))
|
||||
x.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
||||
if (r.hasLanguage()) {
|
||||
// use both - see https://www.w3.org/TR/i18n-html-tech-lang/#langvalues
|
||||
x.setAttribute("lang", r.getLanguage());
|
||||
x.setAttribute("xml:lang", r.getLanguage());
|
||||
}
|
||||
if (!r.hasText() || !r.getText().hasDiv() || r.getText().getDiv().getChildNodes().isEmpty()) {
|
||||
r.setText(new Narrative());
|
||||
r.getText().setDiv(x);
|
||||
r.getText().setStatus(status);
|
||||
} else {
|
||||
XhtmlNode n = r.getText().getDiv();
|
||||
n.hr();
|
||||
n.getChildNodes().addAll(x.getChildNodes());
|
||||
}
|
||||
}
|
||||
|
||||
public void inject(Element er, XhtmlNode x, NarrativeStatus status, boolean pretty) {
|
||||
if (!x.hasAttribute("xmlns"))
|
||||
x.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
||||
Element le = XMLUtil.getNamedChild(er, "language");
|
||||
String l = le == null ? null : le.getAttribute("value");
|
||||
if (!Utilities.noString(l)) {
|
||||
// use both - see https://www.w3.org/TR/i18n-html-tech-lang/#langvalues
|
||||
x.setAttribute("lang", l);
|
||||
x.setAttribute("xml:lang", l);
|
||||
}
|
||||
Element txt = XMLUtil.getNamedChild(er, "text");
|
||||
if (txt == null) {
|
||||
txt = er.getOwnerDocument().createElementNS(FormatUtilities.FHIR_NS, "text");
|
||||
Element n = XMLUtil.getFirstChild(er);
|
||||
while (n != null && (n.getNodeName().equals("id") || n.getNodeName().equals("meta") || n.getNodeName().equals("implicitRules") || n.getNodeName().equals("language")))
|
||||
n = XMLUtil.getNextSibling(n);
|
||||
if (n == null)
|
||||
er.appendChild(txt);
|
||||
else
|
||||
er.insertBefore(txt, n);
|
||||
}
|
||||
Element st = XMLUtil.getNamedChild(txt, "status");
|
||||
if (st == null) {
|
||||
st = er.getOwnerDocument().createElementNS(FormatUtilities.FHIR_NS, "status");
|
||||
Element n = XMLUtil.getFirstChild(txt);
|
||||
if (n == null)
|
||||
txt.appendChild(st);
|
||||
else
|
||||
txt.insertBefore(st, n);
|
||||
}
|
||||
st.setAttribute("value", status.toCode());
|
||||
Element div = XMLUtil.getNamedChild(txt, "div");
|
||||
if (div == null) {
|
||||
div = er.getOwnerDocument().createElementNS(FormatUtilities.XHTML_NS, "div");
|
||||
div.setAttribute("xmlns", FormatUtilities.XHTML_NS);
|
||||
txt.appendChild(div);
|
||||
}
|
||||
if (div.hasChildNodes())
|
||||
div.appendChild(er.getOwnerDocument().createElementNS(FormatUtilities.XHTML_NS, "hr"));
|
||||
new XhtmlComposer(XhtmlComposer.XML, pretty).compose(div, x);
|
||||
}
|
||||
|
||||
public void inject(org.hl7.fhir.r5.elementmodel.Element er, XhtmlNode x, NarrativeStatus status, boolean pretty) throws IOException, FHIRException {
|
||||
if (!x.hasAttribute("xmlns"))
|
||||
x.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
||||
String l = er.getChildValue("language");
|
||||
if (!Utilities.noString(l)) {
|
||||
// use both - see https://www.w3.org/TR/i18n-html-tech-lang/#langvalues
|
||||
x.setAttribute("lang", l);
|
||||
x.setAttribute("xml:lang", l);
|
||||
}
|
||||
org.hl7.fhir.r5.elementmodel.Element txt = er.getNamedChild("text");
|
||||
if (txt == null) {
|
||||
txt = new org.hl7.fhir.r5.elementmodel.Element("text", er.getProperty().getChild(null, "text"));
|
||||
int i = 0;
|
||||
while (i < er.getChildren().size() && (er.getChildren().get(i).getName().equals("id") || er.getChildren().get(i).getName().equals("meta") || er.getChildren().get(i).getName().equals("implicitRules") || er.getChildren().get(i).getName().equals("language")))
|
||||
i++;
|
||||
if (i >= er.getChildren().size())
|
||||
er.getChildren().add(txt);
|
||||
else
|
||||
er.getChildren().add(i, txt);
|
||||
}
|
||||
org.hl7.fhir.r5.elementmodel.Element st = txt.getNamedChild("status");
|
||||
if (st == null) {
|
||||
st = new org.hl7.fhir.r5.elementmodel.Element("status", txt.getProperty().getChild(null, "status"));
|
||||
txt.getChildren().add(0, st);
|
||||
}
|
||||
st.setValue(status.toCode());
|
||||
org.hl7.fhir.r5.elementmodel.Element div = txt.getNamedChild("div");
|
||||
if (div == null) {
|
||||
div = new org.hl7.fhir.r5.elementmodel.Element("div", txt.getProperty().getChild(null, "div"));
|
||||
txt.getChildren().add(div);
|
||||
div.setValue(new XhtmlComposer(XhtmlComposer.XML, pretty).compose(x));
|
||||
}
|
||||
div.setValue(x.toString());
|
||||
div.setXhtml(x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void generateCopyright(XhtmlNode x, CanonicalResource cs) {
|
||||
XhtmlNode p = x.para();
|
||||
p.b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Copyright Statement:", context.getLang()));
|
||||
smartAddText(p, " " + cs.getCopyright());
|
||||
}
|
||||
|
||||
public String displayReference(Resource res, Reference r) throws UnsupportedEncodingException, IOException {
|
||||
return "todo";
|
||||
}
|
||||
|
||||
public void renderReference(Resource res, XhtmlNode x, Reference r) throws UnsupportedEncodingException, IOException {
|
||||
ResourceWrapper rw = new ResourceWrapperDirect(this, res);
|
||||
renderReference(rw, x, r);
|
||||
}
|
||||
|
||||
public void renderReference(ResourceWrapper rw, XhtmlNode x, Reference r) throws UnsupportedEncodingException, IOException {
|
||||
XhtmlNode c = x;
|
||||
ResourceWithReference tr = null;
|
||||
if (r.hasReferenceElement()) {
|
||||
tr = resolveReference(rw, r.getReference());
|
||||
|
||||
if (!r.getReference().startsWith("#")) {
|
||||
if (tr != null && tr.getReference() != null)
|
||||
c = x.ah(tr.getReference());
|
||||
else
|
||||
c = x.ah(r.getReference());
|
||||
}
|
||||
}
|
||||
// what to display: if text is provided, then that. if the reference was resolved, then show the generated narrative
|
||||
if (r.hasDisplayElement()) {
|
||||
c.addText(r.getDisplay());
|
||||
if (tr != null && tr.getResource() != null) {
|
||||
c.tx(". Generated Summary: ");
|
||||
generateResourceSummary(c, tr.getResource(), true, r.getReference().startsWith("#"));
|
||||
}
|
||||
} else if (tr != null && tr.getResource() != null) {
|
||||
generateResourceSummary(c, tr.getResource(), r.getReference().startsWith("#"), r.getReference().startsWith("#"));
|
||||
} else {
|
||||
c.addText(r.getReference());
|
||||
}
|
||||
}
|
||||
|
||||
private ResourceWithReference resolveReference(ResourceWrapper res, String url) {
|
||||
if (url == null)
|
||||
return null;
|
||||
if (url.startsWith("#")) {
|
||||
for (ResourceWrapper r : res.getContained()) {
|
||||
if (r.getId().equals(url.substring(1)))
|
||||
return new ResourceWithReference(null, r);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (rcontext != null) {
|
||||
BundleEntryComponent bundleResource = rcontext.resolve(url);
|
||||
if (bundleResource != null) {
|
||||
String bundleUrl = "#" + bundleResource.getResource().getResourceType().name().toLowerCase() + "_" + bundleResource.getResource().getId();
|
||||
return new ResourceWithReference(bundleUrl, new ResourceWrapperDirect(this, bundleResource.getResource()));
|
||||
}
|
||||
org.hl7.fhir.r5.elementmodel.Element bundleElement = rcontext.resolveElement(url);
|
||||
if (bundleElement != null) {
|
||||
String bundleUrl = null;
|
||||
if (bundleElement.getNamedChild("resource").getChildValue("id") != null) {
|
||||
bundleUrl = "#" + bundleElement.fhirType().toLowerCase() + "_" + bundleElement.getNamedChild("resource").getChildValue("id");
|
||||
} else {
|
||||
bundleUrl = "#" +fullUrlToAnchor(bundleElement.getChildValue("fullUrl"));
|
||||
}
|
||||
return new ResourceWithReference(bundleUrl, new ResourceWrapperMetaElement(this, bundleElement));
|
||||
}
|
||||
}
|
||||
|
||||
Resource ae = getContext().getWorker().fetchResource(null, url);
|
||||
if (ae != null)
|
||||
return new ResourceWithReference(url, new ResourceWrapperDirect(this, ae));
|
||||
else if (context.getResolver() != null) {
|
||||
return context.getResolver().resolve(url);
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
private String fullUrlToAnchor(String url) {
|
||||
return url.replace(":", "").replace("/", "_");
|
||||
}
|
||||
|
||||
public Base parseType(String string, String type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void generateResourceSummary(XhtmlNode x, ResourceWrapper res, boolean textAlready, boolean showCodeDetails) throws FHIRException, UnsupportedEncodingException, IOException {
|
||||
if (!textAlready) {
|
||||
XhtmlNode div = res.getNarrative();
|
||||
if (div != null) {
|
||||
if (div.allChildrenAreText())
|
||||
x.getChildNodes().addAll(div.getChildNodes());
|
||||
if (div.getChildNodes().size() == 1 && div.getChildNodes().get(0).allChildrenAreText())
|
||||
x.getChildNodes().addAll(div.getChildNodes().get(0).getChildNodes());
|
||||
}
|
||||
x.tx("Generated Summary: ");
|
||||
}
|
||||
String path = res.getName();
|
||||
StructureDefinition profile = getContext().getWorker().fetchResource(StructureDefinition.class, path);
|
||||
if (profile == null)
|
||||
x.tx("unknown resource " +path);
|
||||
else {
|
||||
boolean firstElement = true;
|
||||
boolean last = false;
|
||||
for (PropertyWrapper p : res.children()) {
|
||||
ElementDefinition child = getElementDefinition(profile.getSnapshot().getElement(), path+"."+p.getName(), p);
|
||||
if (p.getValues().size() > 0 && p.getValues().get(0) != null && child != null && isPrimitive(child) && includeInSummary(child)) {
|
||||
if (firstElement)
|
||||
firstElement = false;
|
||||
else if (last)
|
||||
x.tx("; ");
|
||||
boolean first = true;
|
||||
last = false;
|
||||
for (BaseWrapper v : p.getValues()) {
|
||||
if (first)
|
||||
first = false;
|
||||
else if (last)
|
||||
x.tx(", ");
|
||||
last = displayLeaf(res, v, child, x, p.getName(), showCodeDetails) || last;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean includeInSummary(ElementDefinition child) {
|
||||
if (child.getIsModifier())
|
||||
return true;
|
||||
if (child.getMustSupport())
|
||||
return true;
|
||||
if (child.getType().size() == 1) {
|
||||
String t = child.getType().get(0).getWorkingCode();
|
||||
if (t.equals("Address") || t.equals("Contact") || t.equals("Reference") || t.equals("Uri") || t.equals("Url") || t.equals("Canonical"))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ElementDefinition getElementDefinition(List<ElementDefinition> elements, String path, PropertyWrapper p) {
|
||||
for (ElementDefinition element : elements)
|
||||
if (element.getPath().equals(path))
|
||||
return element;
|
||||
if (path.endsWith("\"]") && p.getStructure() != null)
|
||||
return p.getStructure().getSnapshot().getElement().get(0);
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderLeaf(ResourceWrapper res, BaseWrapper ew, ElementDefinition defn, XhtmlNode x, boolean title, boolean showCodeDetails, Map<String, String> displayHints, String path, int indent) throws FHIRException, UnsupportedEncodingException, IOException {
|
||||
if (ew == null)
|
||||
return;
|
||||
|
||||
|
||||
Base e = ew.getBase();
|
||||
|
||||
if (e instanceof StringType)
|
||||
x.addText(((StringType) e).getValue());
|
||||
else if (e instanceof CodeType)
|
||||
x.addText(((CodeType) e).getValue());
|
||||
else if (e instanceof IdType)
|
||||
x.addText(((IdType) e).getValue());
|
||||
else if (e instanceof Extension)
|
||||
return;
|
||||
else if (e instanceof InstantType)
|
||||
x.addText(((InstantType) e).toHumanDisplay());
|
||||
else if (e instanceof DateTimeType) {
|
||||
renderDateTime(x, e);
|
||||
} else if (e instanceof Base64BinaryType)
|
||||
x.addText(new Base64().encodeAsString(((Base64BinaryType) e).getValue()));
|
||||
else if (e instanceof org.hl7.fhir.r5.model.DateType)
|
||||
x.addText(((org.hl7.fhir.r5.model.DateType) e).toHumanDisplay());
|
||||
else if (e instanceof Enumeration) {
|
||||
Object ev = ((Enumeration<?>) e).getValue();
|
||||
x.addText(ev == null ? "" : ev.toString()); // todo: look up a display name if there is one
|
||||
} else if (e instanceof BooleanType)
|
||||
x.addText(((BooleanType) e).getValue().toString());
|
||||
else if (e instanceof CodeableConcept) {
|
||||
renderCodeableConcept(x, (CodeableConcept) e, showCodeDetails);
|
||||
} else if (e instanceof Coding) {
|
||||
renderCoding(x, (Coding) e, showCodeDetails);
|
||||
} else if (e instanceof Annotation) {
|
||||
renderAnnotation(x, (Annotation) e);
|
||||
} else if (e instanceof Identifier) {
|
||||
renderIdentifier(x, (Identifier) e);
|
||||
} else if (e instanceof org.hl7.fhir.r5.model.IntegerType) {
|
||||
x.addText(Integer.toString(((org.hl7.fhir.r5.model.IntegerType) e).getValue()));
|
||||
} else if (e instanceof org.hl7.fhir.r5.model.DecimalType) {
|
||||
x.addText(((org.hl7.fhir.r5.model.DecimalType) e).getValue().toString());
|
||||
} else if (e instanceof HumanName) {
|
||||
renderHumanName(x, (HumanName) e);
|
||||
} else if (e instanceof SampledData) {
|
||||
renderSampledData(x, (SampledData) e);
|
||||
} else if (e instanceof Address) {
|
||||
renderAddress(x, (Address) e);
|
||||
} else if (e instanceof ContactPoint) {
|
||||
renderContactPoint(x, (ContactPoint) e);
|
||||
} else if (e instanceof ContactDetail) {
|
||||
ContactDetail cd = (ContactDetail) e;
|
||||
if (cd.hasName()) {
|
||||
x.tx(cd.getName()+": ");
|
||||
}
|
||||
boolean first = true;
|
||||
for (ContactPoint c : cd.getTelecom()) {
|
||||
if (first) first = false; else x.tx(",");
|
||||
renderContactPoint(x, c);
|
||||
}
|
||||
} else if (e instanceof UriType) {
|
||||
renderUri(x, (UriType) e, defn.getPath(), rcontext != null && rcontext.getResourceResource() != null ? rcontext.getResourceResource().getId() : null);
|
||||
} else if (e instanceof Timing) {
|
||||
renderTiming(x, (Timing) e);
|
||||
} else if (e instanceof Range) {
|
||||
renderRange(x, (Range) e);
|
||||
} else if (e instanceof Quantity) {
|
||||
renderQuantity(x, (Quantity) e, showCodeDetails);
|
||||
} else if (e instanceof Ratio) {
|
||||
renderQuantity(x, ((Ratio) e).getNumerator(), showCodeDetails);
|
||||
x.tx("/");
|
||||
renderQuantity(x, ((Ratio) e).getDenominator(), showCodeDetails);
|
||||
} else if (e instanceof Period) {
|
||||
Period p = (Period) e;
|
||||
renderPeriod(x, p);
|
||||
} else if (e instanceof Reference) {
|
||||
Reference r = (Reference) e;
|
||||
renderReference(res, x, r);
|
||||
} else if (e instanceof Resource) {
|
||||
return;
|
||||
} else if (e instanceof ElementDefinition) {
|
||||
x.tx("todo-bundle");
|
||||
} else if (e != null && !(e instanceof Attachment) && !(e instanceof Narrative) && !(e instanceof Meta)) {
|
||||
StructureDefinition sd = getContext().getWorker().fetchTypeDefinition(e.fhirType());
|
||||
if (sd == null)
|
||||
throw new NotImplementedException("type "+e.getClass().getName()+" not handled yet, and no structure found");
|
||||
else
|
||||
generateByProfile(res, sd, ew, sd.getSnapshot().getElement(), sd.getSnapshot().getElementFirstRep(),
|
||||
getChildrenForPath(sd.getSnapshot().getElement(), sd.getSnapshot().getElementFirstRep().getPath()), x, path, showCodeDetails, indent + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean displayLeaf(ResourceWrapper res, BaseWrapper ew, ElementDefinition defn, XhtmlNode x, String name, boolean showCodeDetails) throws FHIRException, UnsupportedEncodingException, IOException {
|
||||
if (ew == null)
|
||||
return false;
|
||||
Base e = ew.getBase();
|
||||
if (e == null)
|
||||
return false;
|
||||
|
||||
Map<String, String> displayHints = readDisplayHints(defn);
|
||||
|
||||
if (name.endsWith("[x]"))
|
||||
name = name.substring(0, name.length() - 3);
|
||||
|
||||
if (!showCodeDetails && e instanceof PrimitiveType && isDefault(displayHints, ((PrimitiveType) e)))
|
||||
return false;
|
||||
|
||||
if (e instanceof StringType) {
|
||||
x.addText(name+": "+((StringType) e).getValue());
|
||||
return true;
|
||||
} else if (e instanceof CodeType) {
|
||||
x.addText(name+": "+((CodeType) e).getValue());
|
||||
return true;
|
||||
} else if (e instanceof IdType) {
|
||||
x.addText(name+": "+((IdType) e).getValue());
|
||||
return true;
|
||||
} else if (e instanceof UriType) {
|
||||
x.addText(name+": "+((UriType) e).getValue());
|
||||
return true;
|
||||
} else if (e instanceof DateTimeType) {
|
||||
x.addText(name+": "+((DateTimeType) e).toHumanDisplay());
|
||||
return true;
|
||||
} else if (e instanceof InstantType) {
|
||||
x.addText(name+": "+((InstantType) e).toHumanDisplay());
|
||||
return true;
|
||||
} else if (e instanceof Extension) {
|
||||
// x.tx("Extensions: todo");
|
||||
return false;
|
||||
} else if (e instanceof org.hl7.fhir.r5.model.DateType) {
|
||||
x.addText(name+": "+((org.hl7.fhir.r5.model.DateType) e).toHumanDisplay());
|
||||
return true;
|
||||
} else if (e instanceof Enumeration) {
|
||||
x.addText(((Enumeration<?>) e).getValue().toString()); // todo: look up a display name if there is one
|
||||
return true;
|
||||
} else if (e instanceof BooleanType) {
|
||||
if (((BooleanType) e).getValue()) {
|
||||
x.addText(name);
|
||||
return true;
|
||||
}
|
||||
} else if (e instanceof CodeableConcept) {
|
||||
renderCodeableConcept(x, (CodeableConcept) e, showCodeDetails);
|
||||
return true;
|
||||
} else if (e instanceof Coding) {
|
||||
renderCoding(x, (Coding) e, showCodeDetails);
|
||||
return true;
|
||||
} else if (e instanceof Annotation) {
|
||||
renderAnnotation(x, (Annotation) e, showCodeDetails);
|
||||
return true;
|
||||
} else if (e instanceof org.hl7.fhir.r5.model.IntegerType) {
|
||||
x.addText(Integer.toString(((org.hl7.fhir.r5.model.IntegerType) e).getValue()));
|
||||
return true;
|
||||
} else if (e instanceof org.hl7.fhir.r5.model.DecimalType) {
|
||||
x.addText(((org.hl7.fhir.r5.model.DecimalType) e).getValue().toString());
|
||||
return true;
|
||||
} else if (e instanceof Identifier) {
|
||||
renderIdentifier(x, (Identifier) e);
|
||||
return true;
|
||||
} else if (e instanceof HumanName) {
|
||||
renderHumanName(x, (HumanName) e);
|
||||
return true;
|
||||
} else if (e instanceof SampledData) {
|
||||
renderSampledData(x, (SampledData) e);
|
||||
return true;
|
||||
} else if (e instanceof Address) {
|
||||
renderAddress(x, (Address) e);
|
||||
return true;
|
||||
} else if (e instanceof ContactPoint) {
|
||||
renderContactPoint(x, (ContactPoint) e);
|
||||
return true;
|
||||
} else if (e instanceof Timing) {
|
||||
renderTiming(x, (Timing) e);
|
||||
return true;
|
||||
} else if (e instanceof Quantity) {
|
||||
renderQuantity(x, (Quantity) e, showCodeDetails);
|
||||
return true;
|
||||
} else if (e instanceof Ratio) {
|
||||
renderQuantity(x, ((Ratio) e).getNumerator(), showCodeDetails);
|
||||
x.tx("/");
|
||||
renderQuantity(x, ((Ratio) e).getDenominator(), showCodeDetails);
|
||||
return true;
|
||||
} else if (e instanceof Period) {
|
||||
Period p = (Period) e;
|
||||
x.addText(name+": ");
|
||||
x.addText(!p.hasStart() ? "?ngen-2?" : p.getStartElement().toHumanDisplay());
|
||||
x.tx(" --> ");
|
||||
x.addText(!p.hasEnd() ? "(ongoing)" : p.getEndElement().toHumanDisplay());
|
||||
return true;
|
||||
} else if (e instanceof Reference) {
|
||||
Reference r = (Reference) e;
|
||||
if (r.hasDisplayElement())
|
||||
x.addText(r.getDisplay());
|
||||
else if (r.hasReferenceElement()) {
|
||||
ResourceWithReference tr = resolveReference(res, r.getReference());
|
||||
x.addText(tr == null ? r.getReference() : "?ngen-3"); // getDisplayForReference(tr.getReference()));
|
||||
} else
|
||||
x.tx("?ngen-4?");
|
||||
return true;
|
||||
} else if (e instanceof Narrative) {
|
||||
return false;
|
||||
} else if (e instanceof Resource) {
|
||||
return false;
|
||||
} else if (e instanceof ContactDetail) {
|
||||
ContactDetail cd = (ContactDetail) e;
|
||||
if (cd.hasName()) {
|
||||
x.tx(cd.getName()+": ");
|
||||
}
|
||||
boolean first = true;
|
||||
for (ContactPoint c : cd.getTelecom()) {
|
||||
if (first) first = false; else x.tx(",");
|
||||
renderContactPoint(x, c);
|
||||
}
|
||||
return true;
|
||||
} else if (e instanceof Range) {
|
||||
return false;
|
||||
} else if (e instanceof Meta) {
|
||||
return false;
|
||||
} else if (e instanceof Dosage) {
|
||||
return false;
|
||||
} else if (e instanceof Signature) {
|
||||
return false;
|
||||
} else if (e instanceof UsageContext) {
|
||||
return false;
|
||||
} else if (e instanceof RelatedArtifact) {
|
||||
return false;
|
||||
} else if (e instanceof ElementDefinition) {
|
||||
return false;
|
||||
} else if (e instanceof Base64BinaryType) {
|
||||
return false;
|
||||
} else if (!(e instanceof Attachment))
|
||||
throw new NotImplementedException("type "+e.getClass().getName()+" not handled yet");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private boolean isPrimitive(ElementDefinition e) {
|
||||
//we can tell if e is a primitive because it has types
|
||||
if (e.getType().isEmpty())
|
||||
return false;
|
||||
if (e.getType().size() == 1 && isBase(e.getType().get(0).getWorkingCode()))
|
||||
return false;
|
||||
return true;
|
||||
// return !e.getType().isEmpty()
|
||||
}
|
||||
|
||||
private boolean isBase(String code) {
|
||||
return code.equals("Element") || code.equals("BackboneElement");
|
||||
}
|
||||
|
||||
private List<ElementDefinition> getChildrenForPath(List<ElementDefinition> elements, String path) throws DefinitionException {
|
||||
// do we need to do a name reference substitution?
|
||||
for (ElementDefinition e : elements) {
|
||||
if (e.getPath().equals(path) && e.hasContentReference()) {
|
||||
String ref = e.getContentReference();
|
||||
ElementDefinition t = null;
|
||||
// now, resolve the name
|
||||
for (ElementDefinition e1 : elements) {
|
||||
if (ref.equals("#"+e1.getId()))
|
||||
t = e1;
|
||||
}
|
||||
if (t == null)
|
||||
throw new DefinitionException("Unable to resolve content reference "+ref+" trying to resolve "+path);
|
||||
path = t.getPath();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
List<ElementDefinition> results = new ArrayList<ElementDefinition>();
|
||||
for (ElementDefinition e : elements) {
|
||||
if (e.getPath().startsWith(path+".") && !e.getPath().substring(path.length()+1).contains("."))
|
||||
results.add(e);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
private boolean generateByProfile(StructureDefinition profile, boolean showCodeDetails) {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
x.para().b().tx("Generated Narrative"+(showCodeDetails ? " with Details" : ""));
|
||||
try {
|
||||
generateByProfile(rcontext.getResourceResource(), profile, rcontext.getResourceResource(), profile.getSnapshot().getElement(), profile.getSnapshot().getElement().get(0), getChildrenForPath(profile.getSnapshot().getElement(), rcontext.getResourceResource().getResourceType().toString()), x, rcontext.getResourceResource().getResourceType().toString(), showCodeDetails);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
x.para().b().style("color: maroon").tx("Exception generating Narrative: "+e.getMessage());
|
||||
}
|
||||
inject(rcontext.getResourceResource(), x, NarrativeStatus.GENERATED);
|
||||
return true;
|
||||
}
|
||||
|
||||
private String generateByProfile(Element er, StructureDefinition profile, boolean showCodeDetails) throws IOException, org.hl7.fhir.exceptions.FHIRException {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
x.para().b().tx("Generated Narrative"+(showCodeDetails ? " with Details" : ""));
|
||||
try {
|
||||
generateByProfile(er, profile, er, profile.getSnapshot().getElement(), profile.getSnapshot().getElement().get(0), getChildrenForPath(profile.getSnapshot().getElement(), er.getLocalName()), x, er.getLocalName(), showCodeDetails);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
x.para().b().style("color: maroon").tx("Exception generating Narrative: "+e.getMessage());
|
||||
}
|
||||
inject(er, x, NarrativeStatus.GENERATED, false);
|
||||
String b = new XhtmlComposer(XhtmlComposer.XML, false).compose(x);
|
||||
return b;
|
||||
}
|
||||
|
||||
private void generateByProfile(Element eres, StructureDefinition profile, Element ee, List<ElementDefinition> allElements, ElementDefinition defn, List<ElementDefinition> children, XhtmlNode x, String path, boolean showCodeDetails) throws FHIRException, UnsupportedEncodingException, IOException {
|
||||
|
||||
ResourceWrapperElement resw = new ResourceWrapperElement(this, eres, profile);
|
||||
BaseWrapperElement base = new BaseWrapperElement(this, ee, null, profile, profile.getSnapshot().getElement().get(0));
|
||||
generateByProfile(resw, profile, base, allElements, defn, children, x, path, showCodeDetails, 0);
|
||||
}
|
||||
|
||||
|
||||
private void generateByProfile(Resource res, StructureDefinition profile, Base e, List<ElementDefinition> allElements, ElementDefinition defn, List<ElementDefinition> children, XhtmlNode x, String path, boolean showCodeDetails) throws FHIRException, UnsupportedEncodingException, IOException {
|
||||
generateByProfile(new ResourceWrapperDirect(this, res), profile, new BaseWrapperDirect(this, e), allElements, defn, children, x, path, showCodeDetails, 0);
|
||||
}
|
||||
|
||||
private void generateByProfile(ResourceWrapper res, StructureDefinition profile, BaseWrapper e, List<ElementDefinition> allElements, ElementDefinition defn, List<ElementDefinition> children, XhtmlNode x, String path, boolean showCodeDetails, int indent) throws FHIRException, UnsupportedEncodingException, IOException {
|
||||
if (children.isEmpty()) {
|
||||
renderLeaf(res, e, defn, x, false, showCodeDetails, readDisplayHints(defn), path, indent);
|
||||
} else {
|
||||
for (PropertyWrapper p : splitExtensions(profile, e.children())) {
|
||||
if (p.hasValues()) {
|
||||
ElementDefinition child = getElementDefinition(children, path+"."+p.getName(), p);
|
||||
if (child != null) {
|
||||
Map<String, String> displayHints = readDisplayHints(child);
|
||||
if (!exemptFromRendering(child)) {
|
||||
List<ElementDefinition> grandChildren = getChildrenForPath(allElements, path+"."+p.getName());
|
||||
filterGrandChildren(grandChildren, path+"."+p.getName(), p);
|
||||
if (p.getValues().size() > 0 && child != null) {
|
||||
if (isPrimitive(child)) {
|
||||
XhtmlNode para = x.para();
|
||||
String name = p.getName();
|
||||
if (name.endsWith("[x]"))
|
||||
name = name.substring(0, name.length() - 3);
|
||||
if (showCodeDetails || !isDefaultValue(displayHints, p.getValues())) {
|
||||
para.b().addText(name);
|
||||
para.tx(": ");
|
||||
if (renderAsList(child) && p.getValues().size() > 1) {
|
||||
XhtmlNode list = x.ul();
|
||||
for (BaseWrapper v : p.getValues())
|
||||
renderLeaf(res, v, child, list.li(), false, showCodeDetails, displayHints, path, indent);
|
||||
} else {
|
||||
boolean first = true;
|
||||
for (BaseWrapper v : p.getValues()) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
para.tx(", ");
|
||||
renderLeaf(res, v, child, para, false, showCodeDetails, displayHints, path, indent);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (canDoTable(path, p, grandChildren)) {
|
||||
x.addTag(getHeader()).addText(Utilities.capitalize(Utilities.camelCase(Utilities.pluralizeMe(p.getName()))));
|
||||
XhtmlNode tbl = x.table( "grid");
|
||||
XhtmlNode tr = tbl.tr();
|
||||
tr.td().tx("-"); // work around problem with empty table rows
|
||||
addColumnHeadings(tr, grandChildren);
|
||||
for (BaseWrapper v : p.getValues()) {
|
||||
if (v != null) {
|
||||
tr = tbl.tr();
|
||||
tr.td().tx("*"); // work around problem with empty table rows
|
||||
addColumnValues(res, tr, grandChildren, v, showCodeDetails, displayHints, path, indent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (BaseWrapper v : p.getValues()) {
|
||||
if (v != null) {
|
||||
XhtmlNode bq = x.addTag("blockquote");
|
||||
bq.para().b().addText(p.getName());
|
||||
generateByProfile(res, profile, v, allElements, child, grandChildren, bq, path+"."+p.getName(), showCodeDetails, indent+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String getHeader() {
|
||||
int i = 3;
|
||||
while (i <= context.getHeaderLevelContext())
|
||||
i++;
|
||||
if (i > 6)
|
||||
i = 6;
|
||||
return "h"+Integer.toString(i);
|
||||
}
|
||||
|
||||
private List<PropertyWrapper> getValues(String path, PropertyWrapper p, ElementDefinition e) {
|
||||
List<PropertyWrapper> res = new ArrayList<PropertyWrapper>();
|
||||
for (BaseWrapper v : p.getValues()) {
|
||||
for (PropertyWrapper g : v.children()) {
|
||||
if ((path+"."+p.getName()+"."+g.getName()).equals(e.getPath()))
|
||||
res.add(p);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private boolean canDoTable(String path, PropertyWrapper p, List<ElementDefinition> grandChildren) {
|
||||
for (ElementDefinition e : grandChildren) {
|
||||
List<PropertyWrapper> values = getValues(path, p, e);
|
||||
if (values.size() > 1 || !isPrimitive(e) || !canCollapse(e))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private boolean canCollapse(ElementDefinition e) {
|
||||
// we can collapse any data type
|
||||
return !e.getType().isEmpty();
|
||||
}
|
||||
private boolean exemptFromRendering(ElementDefinition child) {
|
||||
if (child == null)
|
||||
return false;
|
||||
if ("Composition.subject".equals(child.getPath()))
|
||||
return true;
|
||||
if ("Composition.section".equals(child.getPath()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean renderAsList(ElementDefinition child) {
|
||||
if (child.getType().size() == 1) {
|
||||
String t = child.getType().get(0).getWorkingCode();
|
||||
if (t.equals("Address") || t.equals("Reference"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addColumnHeadings(XhtmlNode tr, List<ElementDefinition> grandChildren) {
|
||||
for (ElementDefinition e : grandChildren)
|
||||
tr.td().b().addText(Utilities.capitalize(tail(e.getPath())));
|
||||
}
|
||||
|
||||
private void addColumnValues(ResourceWrapper res, XhtmlNode tr, List<ElementDefinition> grandChildren, BaseWrapper v, boolean showCodeDetails, Map<String, String> displayHints, String path, int indent) throws FHIRException, UnsupportedEncodingException, IOException {
|
||||
for (ElementDefinition e : grandChildren) {
|
||||
PropertyWrapper p = v.getChildByName(e.getPath().substring(e.getPath().lastIndexOf(".")+1));
|
||||
if (p == null || p.getValues().size() == 0 || p.getValues().get(0) == null)
|
||||
tr.td().tx(" ");
|
||||
else
|
||||
renderLeaf(res, p.getValues().get(0), e, tr.td(), false, showCodeDetails, displayHints, path, indent);
|
||||
}
|
||||
}
|
||||
|
||||
private void filterGrandChildren(List<ElementDefinition> grandChildren, String string, PropertyWrapper prop) {
|
||||
List<ElementDefinition> toRemove = new ArrayList<ElementDefinition>();
|
||||
toRemove.addAll(grandChildren);
|
||||
for (BaseWrapper b : prop.getValues()) {
|
||||
List<ElementDefinition> list = new ArrayList<ElementDefinition>();
|
||||
for (ElementDefinition ed : toRemove) {
|
||||
PropertyWrapper p = b.getChildByName(tail(ed.getPath()));
|
||||
if (p != null && p.hasValues())
|
||||
list.add(ed);
|
||||
}
|
||||
toRemove.removeAll(list);
|
||||
}
|
||||
grandChildren.removeAll(toRemove);
|
||||
}
|
||||
|
||||
private List<PropertyWrapper> splitExtensions(StructureDefinition profile, List<PropertyWrapper> children) throws UnsupportedEncodingException, IOException, FHIRException {
|
||||
List<PropertyWrapper> results = new ArrayList<PropertyWrapper>();
|
||||
Map<String, PropertyWrapper> map = new HashMap<String, PropertyWrapper>();
|
||||
for (PropertyWrapper p : children)
|
||||
if (p.getName().equals("extension") || p.getName().equals("modifierExtension")) {
|
||||
// we're going to split these up, and create a property for each url
|
||||
if (p.hasValues()) {
|
||||
for (BaseWrapper v : p.getValues()) {
|
||||
Extension ex = (Extension) v.getBase();
|
||||
String url = ex.getUrl();
|
||||
StructureDefinition ed = getContext().getWorker().fetchResource(StructureDefinition.class, url);
|
||||
if (ed == null) {
|
||||
if (xverManager == null) {
|
||||
xverManager = new XVerExtensionManager(context.getWorker());
|
||||
}
|
||||
if (xverManager.matchingUrl(url) && xverManager.status(url) == XVerExtensionStatus.Valid) {
|
||||
ed = xverManager.makeDefinition(url);
|
||||
getContext().getWorker().generateSnapshot(ed);
|
||||
getContext().getWorker().cacheResource(ed);
|
||||
}
|
||||
}
|
||||
if (p.getName().equals("modifierExtension") && ed == null)
|
||||
throw new DefinitionException("Unknown modifier extension "+url);
|
||||
PropertyWrapper pe = map.get(p.getName()+"["+url+"]");
|
||||
if (pe == null) {
|
||||
if (ed == null) {
|
||||
if (url.startsWith("http://hl7.org/fhir") && !url.startsWith("http://hl7.org/fhir/us"))
|
||||
throw new DefinitionException("unknown extension "+url);
|
||||
// System.out.println("unknown extension "+url);
|
||||
pe = new PropertyWrapperDirect(this, new Property(p.getName()+"["+url+"]", p.getTypeCode(), p.getDefinition(), p.getMinCardinality(), p.getMaxCardinality(), ex));
|
||||
} else {
|
||||
ElementDefinition def = ed.getSnapshot().getElement().get(0);
|
||||
pe = new PropertyWrapperDirect(this, new Property(p.getName()+"["+url+"]", "Extension", def.getDefinition(), def.getMin(), def.getMax().equals("*") ? Integer.MAX_VALUE : Integer.parseInt(def.getMax()), ex));
|
||||
((PropertyWrapperDirect) pe).getWrapped().setStructure(ed);
|
||||
}
|
||||
results.add(pe);
|
||||
} else
|
||||
pe.getValues().add(v);
|
||||
}
|
||||
}
|
||||
} else
|
||||
results.add(p);
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
private Map<String, String> readDisplayHints(ElementDefinition defn) throws DefinitionException {
|
||||
Map<String, String> hints = new HashMap<String, String>();
|
||||
if (defn != null) {
|
||||
String displayHint = ToolingExtensions.getDisplayHint(defn);
|
||||
if (!Utilities.noString(displayHint)) {
|
||||
String[] list = displayHint.split(";");
|
||||
for (String item : list) {
|
||||
String[] parts = item.split(":");
|
||||
if (parts.length != 2)
|
||||
throw new DefinitionException("error reading display hint: '"+displayHint+"'");
|
||||
hints.put(parts[0].trim(), parts[1].trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
return hints;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private boolean isDefaultValue(Map<String, String> displayHints, List<BaseWrapper> list) throws UnsupportedEncodingException, IOException, FHIRException {
|
||||
if (list.size() != 1)
|
||||
return false;
|
||||
if (list.get(0).getBase() instanceof PrimitiveType)
|
||||
return isDefault(displayHints, (PrimitiveType) list.get(0).getBase());
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isDefault(Map<String, String> displayHints, PrimitiveType primitiveType) {
|
||||
String v = primitiveType.asStringValue();
|
||||
if (!Utilities.noString(v) && displayHints.containsKey("default") && v.equals(displayHints.get("default")))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected String tail(String path) {
|
||||
return path.substring(path.lastIndexOf(".")+1);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.hl7.fhir.r5.terminologies;
|
||||
package org.hl7.fhir.r5.renderers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -7,8 +7,6 @@ import java.util.List;
|
|||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.ConceptMap;
|
||||
|
@ -17,6 +15,7 @@ import org.hl7.fhir.r5.model.Questionnaire;
|
|||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
||||
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.PropertyComponent;
|
||||
|
@ -29,20 +28,25 @@ import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceDesignationComponent;
|
|||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.r5.utils.NarrativeGenerator.ResourceContext;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor.Dialect;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlParser;
|
||||
|
||||
public class TerminologyRenderer {
|
||||
public class TerminologyRenderer extends ResourceRenderer {
|
||||
|
||||
public enum TerminologyRendererMode {
|
||||
RESOURCE, IG
|
||||
public TerminologyRenderer(RenderingContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public TerminologyRenderer(RenderingContext context, ResourceContext rcontext) {
|
||||
super(context, rcontext);
|
||||
}
|
||||
|
||||
protected class TargetElementComponentWrapper {
|
||||
|
@ -100,53 +104,8 @@ public class TerminologyRenderer {
|
|||
|
||||
}
|
||||
|
||||
protected TerminologyRendererMode mode;
|
||||
protected IWorkerContext context;
|
||||
protected MarkDownProcessor markdown;
|
||||
protected String lang;
|
||||
protected String prefix;
|
||||
protected int headerLevelContext;
|
||||
protected ValidationOptions terminologyServiceOptions = new ValidationOptions();
|
||||
protected boolean noSlowLookup;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mode - whether we are rendering for a resource directly, or for an IG
|
||||
* @param context - common services (terminology server, code system cache etc)
|
||||
* @param markdown - markdown processing engine of the correct sort for the version applicable
|
||||
* @param prefix - the path to the base FHIR specification
|
||||
* @param lang - the language to use (null for the default)
|
||||
*/
|
||||
public TerminologyRenderer(TerminologyRendererMode mode, IWorkerContext context, MarkDownProcessor markdown, String prefix, String lang) {
|
||||
super();
|
||||
this.mode = mode;
|
||||
this.context = context;
|
||||
this.markdown = markdown;
|
||||
this.lang = lang;
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public TerminologyRendererMode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public int getHeaderLevelContext() {
|
||||
return headerLevelContext;
|
||||
}
|
||||
|
||||
public void setHeaderLevelContext(int headerLevelContext) {
|
||||
this.headerLevelContext = headerLevelContext;
|
||||
}
|
||||
|
||||
public ValidationOptions getTerminologyServiceOptions() {
|
||||
return terminologyServiceOptions;
|
||||
}
|
||||
|
||||
public void setTerminologyServiceOptions(ValidationOptions terminologyServiceOptions) {
|
||||
this.terminologyServiceOptions = terminologyServiceOptions;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isNoSlowLookup() {
|
||||
return noSlowLookup;
|
||||
|
@ -156,66 +115,11 @@ public class TerminologyRenderer {
|
|||
this.noSlowLookup = noSlowLookup;
|
||||
}
|
||||
|
||||
protected void addMarkdown(XhtmlNode x, String text) throws FHIRFormatError, IOException, DefinitionException {
|
||||
if (text != null) {
|
||||
// 1. custom FHIR extensions
|
||||
while (text.contains("[[[")) {
|
||||
String left = text.substring(0, text.indexOf("[[["));
|
||||
String link = text.substring(text.indexOf("[[[")+3, text.indexOf("]]]"));
|
||||
String right = text.substring(text.indexOf("]]]")+3);
|
||||
String url = link;
|
||||
String[] parts = link.split("\\#");
|
||||
StructureDefinition p = context.fetchResource(StructureDefinition.class, parts[0]);
|
||||
if (p == null)
|
||||
p = context.fetchTypeDefinition(parts[0]);
|
||||
if (p == null)
|
||||
p = context.fetchResource(StructureDefinition.class, link);
|
||||
if (p != null) {
|
||||
url = p.getUserString("path");
|
||||
if (url == null)
|
||||
url = p.getUserString("filename");
|
||||
} else
|
||||
throw new DefinitionException("Unable to resolve markdown link "+link);
|
||||
|
||||
text = left+"["+link+"]("+url+")"+right;
|
||||
}
|
||||
|
||||
// 2. markdown
|
||||
String s = markdown.process(Utilities.escapeXml(text), "narrative generator");
|
||||
XhtmlParser p = new XhtmlParser();
|
||||
XhtmlNode m;
|
||||
try {
|
||||
m = p.parse("<div>"+s+"</div>", "div");
|
||||
} catch (org.hl7.fhir.exceptions.FHIRFormatError e) {
|
||||
throw new FHIRFormatError(e.getMessage(), e);
|
||||
}
|
||||
x.getChildNodes().addAll(m.getChildNodes());
|
||||
}
|
||||
}
|
||||
|
||||
protected void generateCopyright(XhtmlNode x, CanonicalResource cs) {
|
||||
XhtmlNode p = x.para();
|
||||
p.b().tx(context.translator().translate("xhtml-gen-cs", "Copyright Statement:", lang));
|
||||
smartAddText(p, " " + cs.getCopyright());
|
||||
}
|
||||
|
||||
protected void smartAddText(XhtmlNode p, String text) {
|
||||
if (text == null)
|
||||
return;
|
||||
|
||||
String[] lines = text.split("\\r\\n");
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
if (i > 0)
|
||||
p.br();
|
||||
p.addText(lines[i]);
|
||||
}
|
||||
}
|
||||
|
||||
protected void addMapHeaders(XhtmlNode tr, List<UsedConceptMap> maps) throws FHIRFormatError, DefinitionException, IOException {
|
||||
for (UsedConceptMap m : maps) {
|
||||
XhtmlNode td = tr.td();
|
||||
XhtmlNode b = td.b();
|
||||
XhtmlNode a = b.ah(prefix+m.getLink());
|
||||
XhtmlNode a = b.ah(getContext().getPrefix()+m.getLink());
|
||||
a.addText(m.getDetails().getName());
|
||||
if (m.getDetails().isDoDescription() && m.getMap().hasDescription())
|
||||
addMarkdown(td, m.getMap().getDescription());
|
||||
|
@ -224,45 +128,13 @@ public class TerminologyRenderer {
|
|||
|
||||
protected String getHeader() {
|
||||
int i = 3;
|
||||
while (i <= headerLevelContext)
|
||||
while (i <= getContext().getHeaderLevelContext())
|
||||
i++;
|
||||
if (i > 6)
|
||||
i = 6;
|
||||
return "h"+Integer.toString(i);
|
||||
}
|
||||
|
||||
public static String describeSystem(String system) {
|
||||
if (system == null)
|
||||
return "[not stated]";
|
||||
if (system.equals("http://loinc.org"))
|
||||
return "LOINC";
|
||||
if (system.startsWith("http://snomed.info"))
|
||||
return "SNOMED CT";
|
||||
if (system.equals("http://www.nlm.nih.gov/research/umls/rxnorm"))
|
||||
return "RxNorm";
|
||||
if (system.equals("http://hl7.org/fhir/sid/icd-9"))
|
||||
return "ICD-9";
|
||||
if (system.equals("http://dicom.nema.org/resources/ontology/DCM"))
|
||||
return "DICOM";
|
||||
if (system.equals("http://unitsofmeasure.org"))
|
||||
return "UCUM";
|
||||
|
||||
return system;
|
||||
}
|
||||
|
||||
|
||||
protected String makeAnchor(String codeSystem, String code) {
|
||||
String s = codeSystem+'-'+code;
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (char c : s.toCharArray()) {
|
||||
if (Character.isAlphabetic(c) || Character.isDigit(c) || c == '.')
|
||||
b.append(c);
|
||||
else
|
||||
b.append('-');
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
protected List<TargetElementComponentWrapper> findMappingsForCode(String code, ConceptMap map) {
|
||||
List<TargetElementComponentWrapper> mappings = new ArrayList<TargetElementComponentWrapper>();
|
||||
|
||||
|
@ -307,11 +179,11 @@ public class TerminologyRenderer {
|
|||
XhtmlNode a = li.ah(spec);
|
||||
a.code(inc.getSystem());
|
||||
} else if (cs != null && ref != null) {
|
||||
if (!Utilities.noString(prefix) && ref.startsWith("http://hl7.org/fhir/"))
|
||||
if (!Utilities.noString(getContext().getPrefix()) && ref.startsWith("http://hl7.org/fhir/"))
|
||||
ref = ref.substring(20)+"/index.html";
|
||||
else if (addHtml && !ref.contains(".html"))
|
||||
ref = ref + ".html";
|
||||
XhtmlNode a = li.ah(prefix+ref.replace("\\", "/"));
|
||||
XhtmlNode a = li.ah(getContext().getPrefix()+ref.replace("\\", "/"));
|
||||
a.code(inc.getSystem());
|
||||
} else {
|
||||
li.code(inc.getSystem());
|
||||
|
@ -335,17 +207,17 @@ public class TerminologyRenderer {
|
|||
XhtmlNode tr = t.tr();
|
||||
if (hasHierarchy)
|
||||
tr.td().b().tx("Lvl");
|
||||
tr.td().attribute("style", "white-space:nowrap").b().tx(context.translator().translate("xhtml-gen-cs", "Code", lang));
|
||||
tr.td().attribute("style", "white-space:nowrap").b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Code", getContext().getLang()));
|
||||
if (hasDisplay)
|
||||
tr.td().b().tx(context.translator().translate("xhtml-gen-cs", "Display", lang));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Display", getContext().getLang()));
|
||||
if (definitions)
|
||||
tr.td().b().tx(context.translator().translate("xhtml-gen-cs", "Definition", lang));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Definition", getContext().getLang()));
|
||||
if (deprecated)
|
||||
tr.td().b().tx(context.translator().translate("xhtml-gen-cs", "Deprecated", lang));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Deprecated", getContext().getLang()));
|
||||
if (comments)
|
||||
tr.td().b().tx(context.translator().translate("xhtml-gen-cs", "Comments", lang));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Comments", getContext().getLang()));
|
||||
if (version)
|
||||
tr.td().b().tx(context.translator().translate("xhtml-gen-cs", "Version", lang));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Version", getContext().getLang()));
|
||||
if (properties != null) {
|
||||
for (PropertyComponent pc : properties) {
|
||||
String display = ToolingExtensions.getPresentation(pc, pc.getCodeElement());
|
||||
|
@ -355,7 +227,7 @@ public class TerminologyRenderer {
|
|||
display = pc.getCode();
|
||||
}
|
||||
}
|
||||
tr.td().b().tx(context.translator().translate("xhtml-gen-cs", display, lang));
|
||||
tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", display, getContext().getLang()));
|
||||
}
|
||||
}
|
||||
return tr;
|
||||
|
@ -371,7 +243,7 @@ public class TerminologyRenderer {
|
|||
code = uri.substring(uri.indexOf("#")+1);
|
||||
uri = uri.substring(0, uri.indexOf("#"));
|
||||
}
|
||||
CodeSystem cs = context.fetchCodeSystem(uri);
|
||||
CodeSystem cs = getContext().getWorker().fetchCodeSystem(uri);
|
||||
if (cs == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -380,7 +252,7 @@ public class TerminologyRenderer {
|
|||
}
|
||||
|
||||
|
||||
protected void AddVsRef(ResourceContext rcontext, String value, XhtmlNode li) {
|
||||
protected void AddVsRef(String value, XhtmlNode li) {
|
||||
Resource res = null;
|
||||
if (rcontext != null) {
|
||||
BundleEntryComponent be = rcontext.resolve(value);
|
||||
|
@ -394,13 +266,13 @@ public class TerminologyRenderer {
|
|||
}
|
||||
CanonicalResource vs = (CanonicalResource) res;
|
||||
if (vs == null)
|
||||
vs = context.fetchResource(ValueSet.class, value);
|
||||
vs = getContext().getWorker().fetchResource(ValueSet.class, value);
|
||||
if (vs == null)
|
||||
vs = context.fetchResource(StructureDefinition.class, value);
|
||||
vs = getContext().getWorker().fetchResource(StructureDefinition.class, value);
|
||||
// if (vs == null)
|
||||
// vs = context.fetchResource(DataElement.class, value);
|
||||
// vs = context.getWorker().fetchResource(DataElement.class, value);
|
||||
if (vs == null)
|
||||
vs = context.fetchResource(Questionnaire.class, value);
|
||||
vs = getContext().getWorker().fetchResource(Questionnaire.class, value);
|
||||
if (vs != null) {
|
||||
String ref = (String) vs.getUserData("path");
|
||||
|
||||
|
@ -408,7 +280,7 @@ public class TerminologyRenderer {
|
|||
XhtmlNode a = li.ah(ref == null ? "?ngen-11?" : ref.replace("\\", "/"));
|
||||
a.addText(value);
|
||||
} else {
|
||||
CodeSystem cs = context.fetchCodeSystem(value);
|
||||
CodeSystem cs = getContext().getWorker().fetchCodeSystem(value);
|
||||
if (cs != null) {
|
||||
String ref = (String) cs.getUserData("path");
|
||||
ref = adjustForPath(ref);
|
||||
|
@ -427,69 +299,19 @@ public class TerminologyRenderer {
|
|||
}
|
||||
|
||||
private String adjustForPath(String ref) {
|
||||
if (prefix == null)
|
||||
if (getContext().getPrefix() == null)
|
||||
return ref;
|
||||
else
|
||||
return prefix+ref;
|
||||
return getContext().getPrefix()+ref;
|
||||
}
|
||||
|
||||
|
||||
protected void addTelecom(XhtmlNode p, ContactPoint c) {
|
||||
if (c.getSystem() == ContactPointSystem.PHONE) {
|
||||
p.tx("Phone: "+c.getValue());
|
||||
} else if (c.getSystem() == ContactPointSystem.FAX) {
|
||||
p.tx("Fax: "+c.getValue());
|
||||
} else if (c.getSystem() == ContactPointSystem.EMAIL) {
|
||||
p.ah( "mailto:"+c.getValue()).addText(c.getValue());
|
||||
} else if (c.getSystem() == ContactPointSystem.URL) {
|
||||
if (c.getValue().length() > 30)
|
||||
p.ah(c.getValue()).addText(c.getValue().substring(0, 30)+"...");
|
||||
else
|
||||
p.ah(c.getValue()).addText(c.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected String getDisplayForConcept(String system, String value) {
|
||||
if (value == null || system == null)
|
||||
return null;
|
||||
ValidationResult cl = context.validateCode(terminologyServiceOptions, system, value, null);
|
||||
ValidationResult cl = getContext().getWorker().validateCode(getContext().getTerminologyServiceOptions(), system, value, null);
|
||||
return cl == null ? null : cl.getDisplay();
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected String describeLang(String lang) {
|
||||
ValueSet v = context.fetchResource(ValueSet.class, "http://hl7.org/fhir/ValueSet/languages");
|
||||
if (v != null) {
|
||||
ConceptReferenceComponent l = null;
|
||||
for (ConceptReferenceComponent cc : v.getCompose().getIncludeFirstRep().getConcept()) {
|
||||
if (cc.getCode().equals(lang))
|
||||
l = cc;
|
||||
}
|
||||
if (l == null) {
|
||||
if (lang.contains("-"))
|
||||
lang = lang.substring(0, lang.indexOf("-"));
|
||||
for (ConceptReferenceComponent cc : v.getCompose().getIncludeFirstRep().getConcept()) {
|
||||
if (cc.getCode().equals(lang) || cc.getCode().startsWith(lang+"-"))
|
||||
l = cc;
|
||||
}
|
||||
}
|
||||
if (l != null) {
|
||||
if (lang.contains("-"))
|
||||
lang = lang.substring(0, lang.indexOf("-"));
|
||||
String en = l.getDisplay();
|
||||
String nativelang = null;
|
||||
for (ConceptReferenceDesignationComponent cd : l.getDesignation()) {
|
||||
if (cd.getLanguage().equals(lang))
|
||||
nativelang = cd.getValue();
|
||||
}
|
||||
if (nativelang == null)
|
||||
return en+" ("+lang+")";
|
||||
else
|
||||
return nativelang+" ("+en+", "+lang+")";
|
||||
}
|
||||
}
|
||||
return lang;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.hl7.fhir.r5.terminologies;
|
||||
package org.hl7.fhir.r5.renderers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
|
@ -12,7 +12,6 @@ import org.hl7.fhir.exceptions.DefinitionException;
|
|||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
||||
import org.hl7.fhir.r5.model.BooleanType;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
|
@ -21,6 +20,7 @@ import org.hl7.fhir.r5.model.ConceptMap;
|
|||
import org.hl7.fhir.r5.model.DataType;
|
||||
import org.hl7.fhir.r5.model.Extension;
|
||||
import org.hl7.fhir.r5.model.ExtensionHelper;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.PrimitiveType;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.UriType;
|
||||
|
@ -28,6 +28,7 @@ import org.hl7.fhir.r5.model.ValueSet;
|
|||
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionDesignationComponent;
|
||||
import org.hl7.fhir.r5.model.Enumerations.FilterOperator;
|
||||
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceDesignationComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||
|
@ -35,12 +36,16 @@ import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent;
|
|||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent;
|
||||
import org.hl7.fhir.r5.terminologies.TerminologyRenderer.ConceptMapRenderInstructions;
|
||||
import org.hl7.fhir.r5.renderers.TerminologyRenderer.ConceptMapRenderInstructions;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.r5.utils.NarrativeGenerator.ResourceContext;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
|
@ -49,81 +54,59 @@ import com.google.common.collect.Multimap;
|
|||
|
||||
public class ValueSetRenderer extends TerminologyRenderer {
|
||||
|
||||
public ValueSetRenderer(RenderingContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ValueSetRenderer(RenderingContext context, ResourceContext rcontext) {
|
||||
super(context, rcontext);
|
||||
}
|
||||
|
||||
private static final String ABSTRACT_CODE_HINT = "This code is not selectable ('Abstract')";
|
||||
|
||||
private String tooCostlyNoteEmpty;
|
||||
private String tooCostlyNoteNotEmpty;
|
||||
private String tooCostlyNoteEmptyDependent;
|
||||
private String tooCostlyNoteNotEmptyDependent;
|
||||
private List<ConceptMapRenderInstructions> renderingMaps = new ArrayList<ConceptMapRenderInstructions>();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mode - whether we are rendering for a resource directly, or for an IG
|
||||
* @param context - common services (terminology server, code system cache etc)
|
||||
* @param markdown - markdown processing engine of the correct sort for the version applicable
|
||||
* @param prefix - the path to the base FHIR specification
|
||||
* @param lang - the language to use (null for the default)
|
||||
*/
|
||||
public ValueSetRenderer(TerminologyRendererMode mode, IWorkerContext context, MarkDownProcessor markdown, String prefix, String lang) {
|
||||
super(mode, context, markdown, prefix, lang);
|
||||
renderingMaps.add(new ConceptMapRenderInstructions("Canonical Status", "http://hl7.org/fhir/ValueSet/resource-status", false));
|
||||
public void render(ValueSet vs) throws FHIRFormatError, DefinitionException, IOException {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
boolean hasExtensions = render(x, vs);
|
||||
inject(vs, x, hasExtensions ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
|
||||
}
|
||||
|
||||
public String getTooCostlyNoteEmpty() {
|
||||
return tooCostlyNoteEmpty;
|
||||
public boolean render(XhtmlNode x, ValueSet vs) throws FHIRFormatError, DefinitionException, IOException {
|
||||
return render(x, vs, false);
|
||||
}
|
||||
|
||||
public void setTooCostlyNoteEmpty(String tooCostlyNoteEmpty) {
|
||||
this.tooCostlyNoteEmpty = tooCostlyNoteEmpty;
|
||||
}
|
||||
|
||||
public String getTooCostlyNoteNotEmpty() {
|
||||
return tooCostlyNoteNotEmpty;
|
||||
}
|
||||
|
||||
public void setTooCostlyNoteNotEmpty(String tooCostlyNoteNotEmpty) {
|
||||
this.tooCostlyNoteNotEmpty = tooCostlyNoteNotEmpty;
|
||||
}
|
||||
|
||||
public String getTooCostlyNoteEmptyDependent() {
|
||||
return tooCostlyNoteEmptyDependent;
|
||||
}
|
||||
|
||||
public void setTooCostlyNoteEmptyDependent(String tooCostlyNoteEmptyDependent) {
|
||||
this.tooCostlyNoteEmptyDependent = tooCostlyNoteEmptyDependent;
|
||||
}
|
||||
|
||||
public String getTooCostlyNoteNotEmptyDependent() {
|
||||
return tooCostlyNoteNotEmptyDependent;
|
||||
}
|
||||
|
||||
public void setTooCostlyNoteNotEmptyDependent(String tooCostlyNoteNotEmptyDependent) {
|
||||
this.tooCostlyNoteNotEmptyDependent = tooCostlyNoteNotEmptyDependent;
|
||||
}
|
||||
|
||||
public boolean render(ResourceContext rcontext, XhtmlNode x, ValueSet vs, ValueSet src, boolean header) throws FHIRFormatError, DefinitionException, IOException {
|
||||
public boolean render(XhtmlNode x, ValueSet vs, boolean header) throws FHIRFormatError, DefinitionException, IOException {
|
||||
List<UsedConceptMap> maps = findReleventMaps(vs);
|
||||
|
||||
boolean hasExtensions;
|
||||
if (vs.hasExpansion()) {
|
||||
// for now, we just accept an expansion if there is one
|
||||
hasExtensions = generateExpansion(x, vs, src, header, maps);
|
||||
hasExtensions = generateExpansion(x, vs, header, maps);
|
||||
} else {
|
||||
hasExtensions = generateComposition(rcontext, x, vs, header, maps);
|
||||
hasExtensions = generateComposition(x, vs, header, maps);
|
||||
}
|
||||
return hasExtensions;
|
||||
}
|
||||
|
||||
public void describe(XhtmlNode x, ValueSet vs) {
|
||||
x.tx(display(vs));
|
||||
}
|
||||
|
||||
public String display(ValueSet vs) {
|
||||
return vs.present();
|
||||
}
|
||||
|
||||
|
||||
private List<UsedConceptMap> findReleventMaps(ValueSet vs) throws FHIRException {
|
||||
List<UsedConceptMap> res = new ArrayList<UsedConceptMap>();
|
||||
for (CanonicalResource md : context.allConformanceResources()) {
|
||||
for (CanonicalResource md : getContext().getWorker().allConformanceResources()) {
|
||||
if (md instanceof ConceptMap) {
|
||||
ConceptMap cm = (ConceptMap) md;
|
||||
if (isSource(vs, cm.getSource())) {
|
||||
ConceptMapRenderInstructions re = findByTarget(cm.getTarget());
|
||||
if (re != null) {
|
||||
ValueSet vst = cm.hasTarget() ? context.fetchResource(ValueSet.class, cm.hasTargetCanonicalType() ? cm.getTargetCanonicalType().getValue() : cm.getTargetUriType().asStringValue()) : null;
|
||||
ValueSet vst = cm.hasTarget() ? getContext().getWorker().fetchResource(ValueSet.class, cm.hasTargetCanonicalType() ? cm.getTargetCanonicalType().getValue() : cm.getTargetUriType().asStringValue()) : null;
|
||||
res.add(new UsedConceptMap(re, vst == null ? cm.getUserString("path") : vst.getUserString("path"), cm));
|
||||
}
|
||||
}
|
||||
|
@ -131,17 +114,17 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
}
|
||||
return res;
|
||||
// Map<ConceptMap, String> mymaps = new HashMap<ConceptMap, String>();
|
||||
// for (ConceptMap a : context.findMapsForSource(vs.getUrl())) {
|
||||
// for (ConceptMap a : context.getWorker().findMapsForSource(vs.getUrl())) {
|
||||
// String url = "";
|
||||
// ValueSet vsr = context.fetchResource(ValueSet.class, ((Reference) a.getTarget()).getReference());
|
||||
// ValueSet vsr = context.getWorker().fetchResource(ValueSet.class, ((Reference) a.getTarget()).getReference());
|
||||
// if (vsr != null)
|
||||
// url = (String) vsr.getUserData("filename");
|
||||
// mymaps.put(a, url);
|
||||
// }
|
||||
// Map<ConceptMap, String> mymaps = new HashMap<ConceptMap, String>();
|
||||
// for (ConceptMap a : context.findMapsForSource(cs.getValueSet())) {
|
||||
// for (ConceptMap a : context.getWorker().findMapsForSource(cs.getValueSet())) {
|
||||
// String url = "";
|
||||
// ValueSet vsr = context.fetchResource(ValueSet.class, ((Reference) a.getTarget()).getReference());
|
||||
// ValueSet vsr = context.getWorker().fetchResource(ValueSet.class, ((Reference) a.getTarget()).getReference());
|
||||
// if (vsr != null)
|
||||
// url = (String) vsr.getUserData("filename");
|
||||
// mymaps.put(a, url);
|
||||
|
@ -152,7 +135,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
// ConceptMap cm = (ConceptMap) r;
|
||||
// if (((Reference) cm.getSource()).getReference().equals(cs.getValueSet())) {
|
||||
// String url = "";
|
||||
// ValueSet vsr = context.fetchResource(ValueSet.class, ((Reference) cm.getTarget()).getReference());
|
||||
// ValueSet vsr = context.getWorker().fetchResource(ValueSet.class, ((Reference) cm.getTarget()).getReference());
|
||||
// if (vsr != null)
|
||||
// url = (String) vsr.getUserData("filename");
|
||||
// mymaps.put(cm, url);
|
||||
|
@ -165,7 +148,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
return vs.hasUrl() && source != null && vs.getUrl().equals(source.primitiveValue());
|
||||
}
|
||||
|
||||
private boolean generateExpansion(XhtmlNode x, ValueSet vs, ValueSet src, boolean header, List<UsedConceptMap> maps) throws FHIRFormatError, DefinitionException, IOException {
|
||||
private boolean generateExpansion(XhtmlNode x, ValueSet vs, boolean header, List<UsedConceptMap> maps) throws FHIRFormatError, DefinitionException, IOException {
|
||||
boolean hasExtensions = false;
|
||||
List<String> langs = new ArrayList<String>();
|
||||
|
||||
|
@ -183,9 +166,9 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
boolean other = false;
|
||||
for (Extension ex : exl) {
|
||||
if (ex.getValue() instanceof BooleanType) {
|
||||
x.para().style("border: maroon 1px solid; background-color: #FFCCCC; font-weight: bold; padding: 8px").addText(vs.getExpansion().getContains().isEmpty() ? tooCostlyNoteEmpty : tooCostlyNoteNotEmpty );
|
||||
x.para().style("border: maroon 1px solid; background-color: #FFCCCC; font-weight: bold; padding: 8px").addText(vs.getExpansion().getContains().isEmpty() ? getContext().getTooCostlyNoteEmpty() : getContext().getTooCostlyNoteNotEmpty());
|
||||
} else if (!other) {
|
||||
x.para().style("border: maroon 1px solid; background-color: #FFCCCC; font-weight: bold; padding: 8px").addText(vs.getExpansion().getContains().isEmpty() ? tooCostlyNoteEmptyDependent : tooCostlyNoteNotEmptyDependent );
|
||||
x.para().style("border: maroon 1px solid; background-color: #FFCCCC; font-weight: bold; padding: 8px").addText(vs.getExpansion().getContains().isEmpty() ? getContext().getTooCostlyNoteEmptyDependent() : getContext().getTooCostlyNoteNotEmptyDependent());
|
||||
other = true;
|
||||
}
|
||||
}
|
||||
|
@ -230,14 +213,14 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
doSystem = false;
|
||||
XhtmlNode p = x.para();
|
||||
p.tx("All codes from system ");
|
||||
allCS = context.fetchCodeSystem(vs.getExpansion().getContains().get(0).getSystem());
|
||||
allCS = getContext().getWorker().fetchCodeSystem(vs.getExpansion().getContains().get(0).getSystem());
|
||||
String ref = null;
|
||||
if (allCS != null)
|
||||
ref = getCsRef(allCS);
|
||||
if (ref == null)
|
||||
p.code(vs.getExpansion().getContains().get(0).getSystem());
|
||||
else
|
||||
p.ah(prefix+ref).code(vs.getExpansion().getContains().get(0).getSystem());
|
||||
p.ah(getContext().getPrefix()+ref).code(vs.getExpansion().getContains().get(0).getSystem());
|
||||
}
|
||||
XhtmlNode t = x.table( "codes");
|
||||
XhtmlNode tr = t.tr();
|
||||
|
@ -319,7 +302,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
if (vs.hasCompose()) {
|
||||
if (vs.getCompose().hasExclude()) {
|
||||
try {
|
||||
ValueSetExpansionOutcome vse = context.expandVS(vs, true, false);
|
||||
ValueSetExpansionOutcome vse = getContext().getWorker().expandVS(vs, true, false);
|
||||
count = 0;
|
||||
count += conceptCount(vse.getValueset().getExpansion().getContains());
|
||||
return count;
|
||||
|
@ -350,7 +333,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
}
|
||||
|
||||
private void addCSRef(XhtmlNode x, String url) {
|
||||
CodeSystem cs = context.fetchCodeSystem(url);
|
||||
CodeSystem cs = getContext().getWorker().fetchCodeSystem(url);
|
||||
if (cs == null) {
|
||||
x.code(url);
|
||||
} else if (cs.hasUserData("path")) {
|
||||
|
@ -419,7 +402,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
x.tx("Loinc v"+v);
|
||||
}
|
||||
} else {
|
||||
CanonicalResource cr = (CanonicalResource) context.fetchResource(Resource.class, u+"|"+v);
|
||||
CanonicalResource cr = (CanonicalResource) getContext().getWorker().fetchResource(Resource.class, u+"|"+v);
|
||||
if (cr != null) {
|
||||
if (cr.hasUserData("path")) {
|
||||
x.ah(cr.getUserString("path")).tx(cr.present()+" v"+v+" ("+cr.fhirType()+")");
|
||||
|
@ -548,7 +531,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
|
||||
private boolean checkDoDefinition(List<ValueSetExpansionContainsComponent> contains) {
|
||||
for (ValueSetExpansionContainsComponent c : contains) {
|
||||
CodeSystem cs = context.fetchCodeSystem(c.getSystem());
|
||||
CodeSystem cs = getContext().getWorker().fetchCodeSystem(c.getSystem());
|
||||
if (cs != null)
|
||||
return true;
|
||||
if (checkDoDefinition(c.getContains()))
|
||||
|
@ -570,7 +553,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
}
|
||||
|
||||
private String getCsRef(String system) {
|
||||
CodeSystem cs = context.fetchCodeSystem(system);
|
||||
CodeSystem cs = getContext().getWorker().fetchCodeSystem(system);
|
||||
return getCsRef(cs);
|
||||
}
|
||||
|
||||
|
@ -610,7 +593,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
if (doDefinition) {
|
||||
CodeSystem cs = allCS;
|
||||
if (cs == null)
|
||||
cs = context.fetchCodeSystem(c.getSystem());
|
||||
cs = getContext().getWorker().fetchCodeSystem(c.getSystem());
|
||||
td = tr.td();
|
||||
if (cs != null)
|
||||
td.addText(CodeSystemUtilities.getCodeDefinition(cs, c.getCode()));
|
||||
|
@ -657,7 +640,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
}
|
||||
|
||||
private void addCodeToTable(boolean isAbstract, String system, String code, String display, XhtmlNode td) {
|
||||
CodeSystem e = context.fetchCodeSystem(system);
|
||||
CodeSystem e = getContext().getWorker().fetchCodeSystem(system);
|
||||
if (e == null || e.getContent() != org.hl7.fhir.r5.model.CodeSystem.CodeSystemContentMode.COMPLETE) {
|
||||
if (isAbstract)
|
||||
td.i().setAttribute("title", ABSTRACT_CODE_HINT).addText(code);
|
||||
|
@ -668,7 +651,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
} else
|
||||
td.addText(code);
|
||||
} else {
|
||||
String href = prefix+getCsRef(e);
|
||||
String href = getContext().getPrefix()+getCsRef(e);
|
||||
if (href.contains("#"))
|
||||
href = href + "-"+Utilities.nmtokenize(code);
|
||||
else
|
||||
|
@ -688,17 +671,17 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
}
|
||||
|
||||
private void addRefToCode(XhtmlNode td, String target, String vslink, String code) {
|
||||
CodeSystem cs = context.fetchCodeSystem(target);
|
||||
CodeSystem cs = getContext().getWorker().fetchCodeSystem(target);
|
||||
String cslink = getCsRef(cs);
|
||||
XhtmlNode a = null;
|
||||
if (cslink != null)
|
||||
a = td.ah(prefix+cslink+"#"+cs.getId()+"-"+code);
|
||||
a = td.ah(getContext().getPrefix()+cslink+"#"+cs.getId()+"-"+code);
|
||||
else
|
||||
a = td.ah(prefix+vslink+"#"+code);
|
||||
a = td.ah(getContext().getPrefix()+vslink+"#"+code);
|
||||
a.addText(code);
|
||||
}
|
||||
|
||||
private boolean generateComposition(ResourceContext rcontext, XhtmlNode x, ValueSet vs, boolean header, List<UsedConceptMap> maps) throws FHIRException, IOException {
|
||||
private boolean generateComposition(XhtmlNode x, ValueSet vs, boolean header, List<UsedConceptMap> maps) throws FHIRException, IOException {
|
||||
boolean hasExtensions = false;
|
||||
List<String> langs = new ArrayList<String>();
|
||||
|
||||
|
@ -711,17 +694,17 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
}
|
||||
XhtmlNode ul = x.ul();
|
||||
if (vs.getCompose().getInclude().size() == 1 && vs.getCompose().getExclude().size() == 0) {
|
||||
hasExtensions = genInclude(rcontext, ul, vs.getCompose().getInclude().get(0), "Include", langs, maps) || hasExtensions;
|
||||
hasExtensions = genInclude(ul, vs.getCompose().getInclude().get(0), "Include", langs, maps) || hasExtensions;
|
||||
} else {
|
||||
XhtmlNode p = x.para();
|
||||
p.tx("This value set includes codes based on the following rules:");
|
||||
|
||||
XhtmlNode li;
|
||||
for (ConceptSetComponent inc : vs.getCompose().getInclude()) {
|
||||
hasExtensions = genInclude(rcontext, ul, inc, "Include", langs, maps) || hasExtensions;
|
||||
hasExtensions = genInclude(ul, inc, "Include", langs, maps) || hasExtensions;
|
||||
}
|
||||
for (ConceptSetComponent exc : vs.getCompose().getExclude()) {
|
||||
hasExtensions = genInclude(rcontext, ul, exc, "Exclude", langs, maps) || hasExtensions;
|
||||
hasExtensions = genInclude(ul, exc, "Exclude", langs, maps) || hasExtensions;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -745,11 +728,11 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
return hasExtensions;
|
||||
}
|
||||
|
||||
private boolean genInclude(ResourceContext rcontext, XhtmlNode ul, ConceptSetComponent inc, String type, List<String> langs, List<UsedConceptMap> maps) throws FHIRException, IOException {
|
||||
private boolean genInclude(XhtmlNode ul, ConceptSetComponent inc, String type, List<String> langs, List<UsedConceptMap> maps) throws FHIRException, IOException {
|
||||
boolean hasExtensions = false;
|
||||
XhtmlNode li;
|
||||
li = ul.li();
|
||||
CodeSystem e = context.fetchCodeSystem(inc.getSystem());
|
||||
CodeSystem e = getContext().getWorker().fetchCodeSystem(inc.getSystem());
|
||||
|
||||
if (inc.hasSystem()) {
|
||||
if (inc.getConcept().size() == 0 && inc.getFilter().size() == 0) {
|
||||
|
@ -823,7 +806,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
} else {
|
||||
li.tx(f.getProperty()+" "+describe(f.getOp())+" ");
|
||||
if (e != null && codeExistsInValueSet(e, f.getValue())) {
|
||||
String href = prefix+getCsRef(e);
|
||||
String href = getContext().getPrefix()+getCsRef(e);
|
||||
if (href.contains("#"))
|
||||
href = href + "-"+Utilities.nmtokenize(f.getValue());
|
||||
else
|
||||
|
@ -831,7 +814,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
li.ah(href).addText(f.getValue());
|
||||
} else if ("concept".equals(f.getProperty()) && inc.hasSystem()) {
|
||||
li.addText(f.getValue());
|
||||
ValidationResult vr = context.validateCode(terminologyServiceOptions, inc.getSystem(), f.getValue(), null);
|
||||
ValidationResult vr = getContext().getWorker().validateCode(getContext().getTerminologyServiceOptions(), inc.getSystem(), f.getValue(), null);
|
||||
if (vr.isOk()) {
|
||||
li.tx(" ("+vr.getDisplay()+")");
|
||||
}
|
||||
|
@ -853,7 +836,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
first = false;
|
||||
else
|
||||
li.tx(", ");
|
||||
AddVsRef(rcontext, vs.asStringValue(), li);
|
||||
AddVsRef(vs.asStringValue(), li);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -864,7 +847,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
first = false;
|
||||
else
|
||||
li.tx(", ");
|
||||
AddVsRef(rcontext, vs.asStringValue(), li);
|
||||
AddVsRef(vs.asStringValue(), li);
|
||||
}
|
||||
}
|
||||
return hasExtensions;
|
||||
|
@ -877,7 +860,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
}
|
||||
// first, look in the code systems
|
||||
if (e == null)
|
||||
e = context.fetchCodeSystem(inc.getSystem());
|
||||
e = getContext().getWorker().fetchCodeSystem(inc.getSystem());
|
||||
if (e != null) {
|
||||
ConceptDefinitionComponent v = getConceptForCode(e.getConcept(), code);
|
||||
if (v != null)
|
||||
|
@ -887,10 +870,10 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
if (noSlowLookup)
|
||||
return null;
|
||||
|
||||
if (!context.hasCache()) {
|
||||
if (!getContext().getWorker().hasCache()) {
|
||||
ValueSetExpansionComponent vse;
|
||||
try {
|
||||
ValueSetExpansionOutcome vso = context.expandVS(inc, false);
|
||||
ValueSetExpansionOutcome vso = getContext().getWorker().expandVS(inc, false);
|
||||
ValueSet valueset = vso.getValueset();
|
||||
if (valueset == null)
|
||||
throw new TerminologyServiceException("Error Expanding ValueSet: "+vso.getError());
|
||||
|
@ -906,7 +889,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
return context.validateCode(terminologyServiceOptions, inc.getSystem(), code, null).asConceptDefinition();
|
||||
return getContext().getWorker().validateCode(getContext().getTerminologyServiceOptions(), inc.getSystem(), code, null).asConceptDefinition();
|
||||
}
|
||||
|
||||
private ConceptDefinitionComponent getConceptForCode(List<ConceptDefinitionComponent> list, String code) {
|
|
@ -0,0 +1,116 @@
|
|||
package org.hl7.fhir.r5.renderers.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.renderers.ResourceRenderer;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.RendererWrapper;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
public class BaseWrappers {
|
||||
|
||||
public interface RendererWrapper {
|
||||
public ResourceRenderer getRenderer();
|
||||
}
|
||||
|
||||
public interface PropertyWrapper extends RendererWrapper {
|
||||
public String getName();
|
||||
public boolean hasValues();
|
||||
public List<BaseWrapper> getValues();
|
||||
public String getTypeCode();
|
||||
public String getDefinition();
|
||||
public int getMinCardinality();
|
||||
public int getMaxCardinality();
|
||||
public StructureDefinition getStructure();
|
||||
public BaseWrapper value();
|
||||
}
|
||||
|
||||
public interface WrapperBase extends RendererWrapper {
|
||||
public boolean has(String name);
|
||||
public Base get(String name) throws UnsupportedEncodingException, FHIRException, IOException;
|
||||
public List<BaseWrapper> children(String name) throws UnsupportedEncodingException, FHIRException, IOException;
|
||||
public List<PropertyWrapper> children();
|
||||
}
|
||||
|
||||
public interface ResourceWrapper extends WrapperBase {
|
||||
public List<ResourceWrapper> getContained();
|
||||
public String getId();
|
||||
public XhtmlNode getNarrative() throws FHIRFormatError, IOException, FHIRException;
|
||||
public String getName();
|
||||
public void describe(XhtmlNode x);
|
||||
}
|
||||
|
||||
public interface BaseWrapper extends WrapperBase {
|
||||
public Base getBase() throws UnsupportedEncodingException, IOException, FHIRException;
|
||||
public PropertyWrapper getChildByName(String tail);
|
||||
}
|
||||
|
||||
public static abstract class RendererWrapperImpl implements RendererWrapper {
|
||||
protected ResourceRenderer renderer;
|
||||
|
||||
public RendererWrapperImpl(ResourceRenderer renderer) {
|
||||
super();
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
public ResourceRenderer getRenderer() {
|
||||
return renderer;
|
||||
}
|
||||
|
||||
protected String tail(String path) {
|
||||
return path.substring(path.lastIndexOf(".")+1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static abstract class WrapperBaseImpl extends RendererWrapperImpl implements WrapperBase {
|
||||
|
||||
public WrapperBaseImpl(ResourceRenderer renderer) {
|
||||
super(renderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(String name) {
|
||||
for (PropertyWrapper p : children()) {
|
||||
if (p.getName().equals(name)) {
|
||||
return p.hasValues();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base get(String name) throws UnsupportedEncodingException, FHIRException, IOException {
|
||||
for (PropertyWrapper p : children()) {
|
||||
if (p.getName().equals(name)) {
|
||||
if (p.hasValues()) {
|
||||
return p.getValues().get(0).getBase();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BaseWrapper> children(String name) throws UnsupportedEncodingException, FHIRException, IOException {
|
||||
for (PropertyWrapper p : children()) {
|
||||
if (p.getName().equals(name)) {
|
||||
List<BaseWrapper> res = new ArrayList<>();
|
||||
for (BaseWrapper b : p.getValues()) {
|
||||
res.add(b);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,258 @@
|
|||
package org.hl7.fhir.r5.renderers.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r5.renderers.ResourceRenderer;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.PropertyWrapper;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.RendererWrapperImpl;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.WrapperBaseImpl;
|
||||
import org.hl7.fhir.r5.utils.NarrativeGenerator;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlParser;
|
||||
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||
import org.hl7.fhir.utilities.xml.XmlGenerator;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
public class DOMWrappers {
|
||||
|
||||
|
||||
public static class BaseWrapperElement extends WrapperBaseImpl implements BaseWrapper {
|
||||
private Element element;
|
||||
private String type;
|
||||
private StructureDefinition structure;
|
||||
private ElementDefinition definition;
|
||||
private List<ElementDefinition> children;
|
||||
private List<PropertyWrapper> list;
|
||||
|
||||
public BaseWrapperElement(ResourceRenderer renderer, Element element, String type, StructureDefinition structure, ElementDefinition definition) {
|
||||
super(renderer);
|
||||
this.element = element;
|
||||
this.type = type;
|
||||
this.structure = structure;
|
||||
this.definition = definition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base getBase() throws UnsupportedEncodingException, IOException, FHIRException {
|
||||
if (type == null || type.equals("Resource") || type.equals("BackboneElement") || type.equals("Element"))
|
||||
return null;
|
||||
|
||||
String xml;
|
||||
try {
|
||||
xml = new XmlGenerator().generate(element);
|
||||
} catch (org.hl7.fhir.exceptions.FHIRException e) {
|
||||
throw new FHIRException(e.getMessage(), e);
|
||||
}
|
||||
return renderer.parseType(xml, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PropertyWrapper> children() {
|
||||
if (list == null) {
|
||||
children = renderer.getContext().getProfileUtilities().getChildList(structure, definition);
|
||||
list = new ArrayList<PropertyWrapper>();
|
||||
for (ElementDefinition child : children) {
|
||||
List<Element> elements = new ArrayList<Element>();
|
||||
XMLUtil.getNamedChildrenWithWildcard(element, tail(child.getPath()), elements);
|
||||
list.add(new PropertyWrapperElement(renderer, structure, child, elements));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyWrapper getChildByName(String name) {
|
||||
for (PropertyWrapper p : children())
|
||||
if (p.getName().equals(name))
|
||||
return p;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class PropertyWrapperElement extends RendererWrapperImpl implements PropertyWrapper {
|
||||
|
||||
private StructureDefinition structure;
|
||||
private ElementDefinition definition;
|
||||
private List<Element> values;
|
||||
private List<BaseWrapper> list;
|
||||
|
||||
public PropertyWrapperElement(ResourceRenderer renderer, StructureDefinition structure, ElementDefinition definition, List<Element> values) {
|
||||
super(renderer);
|
||||
this.structure = structure;
|
||||
this.definition = definition;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return tail(definition.getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasValues() {
|
||||
return values.size() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BaseWrapper> getValues() {
|
||||
if (list == null) {
|
||||
list = new ArrayList<BaseWrapper>();
|
||||
for (Element e : values)
|
||||
list.add(new BaseWrapperElement(renderer, e, determineType(e), structure, definition));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
private String determineType(Element e) {
|
||||
if (definition.getType().isEmpty())
|
||||
return null;
|
||||
if (definition.getType().size() == 1) {
|
||||
if (definition.getType().get(0).getWorkingCode().equals("Element") || definition.getType().get(0).getWorkingCode().equals("BackboneElement"))
|
||||
return null;
|
||||
return definition.getType().get(0).getWorkingCode();
|
||||
}
|
||||
String t = e.getNodeName().substring(tail(definition.getPath()).length()-3);
|
||||
|
||||
if (isPrimitive(Utilities.uncapitalize(t)))
|
||||
return Utilities.uncapitalize(t);
|
||||
else
|
||||
return t;
|
||||
}
|
||||
|
||||
private boolean isPrimitive(String code) {
|
||||
StructureDefinition sd = renderer.getContext().getWorker().fetchTypeDefinition(code);
|
||||
return sd != null && sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeCode() {
|
||||
if (definition == null || definition.getType().size() != 1)
|
||||
throw new Error("not handled");
|
||||
return definition.getType().get(0).getWorkingCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefinition() {
|
||||
if (definition == null)
|
||||
throw new Error("not handled");
|
||||
return definition.getDefinition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinCardinality() {
|
||||
if (definition == null)
|
||||
throw new Error("not handled");
|
||||
return definition.getMin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxCardinality() {
|
||||
if (definition == null)
|
||||
throw new Error("not handled");
|
||||
return definition.getMax().equals("*") ? Integer.MAX_VALUE : Integer.parseInt(definition.getMax());
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructureDefinition getStructure() {
|
||||
return structure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseWrapper value() {
|
||||
if (getValues().size() != 1)
|
||||
throw new Error("Access single value, but value count is "+getValues().size());
|
||||
return getValues().get(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ResourceWrapperElement extends WrapperBaseImpl implements ResourceWrapper {
|
||||
|
||||
private Element wrapped;
|
||||
private StructureDefinition definition;
|
||||
private List<ResourceWrapper> list;
|
||||
private List<PropertyWrapper> list2;
|
||||
|
||||
public ResourceWrapperElement(ResourceRenderer renderer, Element wrapped, StructureDefinition definition) {
|
||||
super(renderer);
|
||||
this.wrapped = wrapped;
|
||||
this.definition = definition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceWrapper> getContained() {
|
||||
if (list == null) {
|
||||
List<Element> children = new ArrayList<Element>();
|
||||
XMLUtil.getNamedChildren(wrapped, "contained", children);
|
||||
list = new ArrayList<ResourceWrapper>();
|
||||
for (Element e : children) {
|
||||
Element c = XMLUtil.getFirstChild(e);
|
||||
list.add(new ResourceWrapperElement(renderer, c, renderer.getContext().getWorker().fetchTypeDefinition(c.getNodeName())));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return XMLUtil.getNamedChildValue(wrapped, "id");
|
||||
}
|
||||
|
||||
@Override
|
||||
public XhtmlNode getNarrative() throws FHIRFormatError, IOException, FHIRException {
|
||||
Element txt = XMLUtil.getNamedChild(wrapped, "text");
|
||||
if (txt == null)
|
||||
return null;
|
||||
Element div = XMLUtil.getNamedChild(txt, "div");
|
||||
if (div == null)
|
||||
return null;
|
||||
try {
|
||||
return new XhtmlParser().parse(new XmlGenerator().generate(div), "div");
|
||||
} catch (org.hl7.fhir.exceptions.FHIRFormatError e) {
|
||||
throw new FHIRFormatError(e.getMessage(), e);
|
||||
} catch (org.hl7.fhir.exceptions.FHIRException e) {
|
||||
throw new FHIRException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return wrapped.getNodeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PropertyWrapper> children() {
|
||||
if (list2 == null) {
|
||||
List<ElementDefinition> children = renderer.getContext().getProfileUtilities().getChildList(definition, definition.getSnapshot().getElement().get(0));
|
||||
list2 = new ArrayList<PropertyWrapper>();
|
||||
for (ElementDefinition child : children) {
|
||||
List<Element> elements = new ArrayList<Element>();
|
||||
XMLUtil.getNamedChildrenWithWildcard(wrapped, tail(child.getPath()), elements);
|
||||
list2.add(new PropertyWrapperElement(renderer, definition, child, elements));
|
||||
}
|
||||
}
|
||||
return list2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void describe(XhtmlNode x) {
|
||||
throw new Error("Not done yet");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
package org.hl7.fhir.r5.renderers.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Encounter;
|
||||
import org.hl7.fhir.r5.model.Patient;
|
||||
import org.hl7.fhir.r5.model.Property;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.renderers.EncounterRenderer;
|
||||
import org.hl7.fhir.r5.renderers.PatientRenderer;
|
||||
import org.hl7.fhir.r5.renderers.ResourceRenderer;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.PropertyWrapper;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.RendererWrapperImpl;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.WrapperBaseImpl;
|
||||
import org.hl7.fhir.r5.utils.NarrativeGenerator;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
public class DirectWrappers {
|
||||
|
||||
public static class PropertyWrapperDirect extends RendererWrapperImpl implements PropertyWrapper {
|
||||
private Property wrapped;
|
||||
private List<BaseWrapper> list;
|
||||
|
||||
public PropertyWrapperDirect(ResourceRenderer renderer, Property wrapped) {
|
||||
super(renderer);
|
||||
if (wrapped == null)
|
||||
throw new Error("wrapped == null");
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return wrapped.getName();
|
||||
}
|
||||
|
||||
public Property getWrapped() {
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasValues() {
|
||||
return wrapped.hasValues();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BaseWrapper> getValues() {
|
||||
if (list == null) {
|
||||
list = new ArrayList<BaseWrapper>();
|
||||
for (Base b : wrapped.getValues())
|
||||
list.add(b == null ? null : new BaseWrapperDirect(renderer, b));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeCode() {
|
||||
return wrapped.getTypeCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefinition() {
|
||||
return wrapped.getDefinition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinCardinality() {
|
||||
return wrapped.getMinCardinality();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxCardinality() {
|
||||
return wrapped.getMinCardinality();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructureDefinition getStructure() {
|
||||
return wrapped.getStructure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseWrapper value() {
|
||||
if (getValues().size() != 1)
|
||||
throw new Error("Access single value, but value count is "+getValues().size());
|
||||
return getValues().get(0);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "#."+wrapped.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class BaseWrapperDirect extends WrapperBaseImpl implements BaseWrapper {
|
||||
private Base wrapped;
|
||||
private List<PropertyWrapper> list;
|
||||
|
||||
public BaseWrapperDirect(ResourceRenderer renderer, Base wrapped) {
|
||||
super(renderer);
|
||||
if (wrapped == null)
|
||||
throw new Error("wrapped == null");
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base getBase() {
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PropertyWrapper> children() {
|
||||
if (list == null) {
|
||||
list = new ArrayList<PropertyWrapper>();
|
||||
for (Property p : wrapped.children())
|
||||
list.add(new PropertyWrapperDirect(renderer, p));
|
||||
}
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyWrapper getChildByName(String name) {
|
||||
Property p = wrapped.getChildByName(name);
|
||||
if (p == null)
|
||||
return null;
|
||||
else
|
||||
return new PropertyWrapperDirect(renderer, p);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ResourceWrapperDirect extends WrapperBaseImpl implements ResourceWrapper {
|
||||
private Resource wrapped;
|
||||
|
||||
public ResourceWrapperDirect(ResourceRenderer renderer, Resource wrapped) {
|
||||
super(renderer);
|
||||
if (wrapped == null)
|
||||
throw new Error("wrapped == null");
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceWrapper> getContained() {
|
||||
List<ResourceWrapper> list = new ArrayList<ResourceWrapper>();
|
||||
if (wrapped instanceof DomainResource) {
|
||||
DomainResource dr = (DomainResource) wrapped;
|
||||
for (Resource c : dr.getContained()) {
|
||||
list.add(new ResourceWrapperDirect(renderer, c));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return wrapped.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public XhtmlNode getNarrative() {
|
||||
if (wrapped instanceof DomainResource) {
|
||||
DomainResource dr = (DomainResource) wrapped;
|
||||
if (dr.hasText() && dr.getText().hasDiv())
|
||||
return dr.getText().getDiv();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return wrapped.getResourceType().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PropertyWrapper> children() {
|
||||
List<PropertyWrapper> list = new ArrayList<PropertyWrapper>();
|
||||
if (wrapped.children() != null) {
|
||||
for (Property c : wrapped.children())
|
||||
list.add(new PropertyWrapperDirect(renderer, c));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describe(XhtmlNode x) {
|
||||
if (wrapped instanceof CanonicalResource) {
|
||||
x.tx(((CanonicalResource) wrapped).present());
|
||||
} else if (wrapped instanceof Patient) {
|
||||
new PatientRenderer(getRenderer().getContext()).describe(x, (Patient) wrapped);
|
||||
} else if (wrapped instanceof Encounter) {
|
||||
new EncounterRenderer(getRenderer().getContext()).describe(x, (Encounter) wrapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,230 @@
|
|||
package org.hl7.fhir.r5.renderers.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.output.ByteArrayOutputStream;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.elementmodel.Element;
|
||||
import org.hl7.fhir.r5.elementmodel.XmlParser;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.renderers.ResourceRenderer;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.PropertyWrapper;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.RendererWrapperImpl;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.WrapperBaseImpl;
|
||||
import org.hl7.fhir.r5.utils.NarrativeGenerator;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
public class ElementWrappers {
|
||||
|
||||
public static class BaseWrapperMetaElement extends WrapperBaseImpl implements BaseWrapper {
|
||||
private Element element;
|
||||
private String type;
|
||||
private StructureDefinition structure;
|
||||
private ElementDefinition definition;
|
||||
private List<ElementDefinition> children;
|
||||
private List<PropertyWrapper> list;
|
||||
|
||||
public BaseWrapperMetaElement(ResourceRenderer renderer, Element element, String type, StructureDefinition structure, ElementDefinition definition) {
|
||||
super(renderer);
|
||||
this.element = element;
|
||||
this.type = type;
|
||||
this.structure = structure;
|
||||
this.definition = definition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base getBase() throws UnsupportedEncodingException, IOException, FHIRException {
|
||||
if (type == null || type.equals("Resource") || type.equals("BackboneElement") || type.equals("Element"))
|
||||
return null;
|
||||
|
||||
if (element.hasElementProperty())
|
||||
return null;
|
||||
ByteArrayOutputStream xml = new ByteArrayOutputStream();
|
||||
try {
|
||||
new XmlParser(renderer.getContext().getWorker()).compose(element, xml, OutputStyle.PRETTY, null);
|
||||
} catch (Exception e) {
|
||||
throw new FHIRException(e.getMessage(), e);
|
||||
}
|
||||
return renderer.parseType(xml.toString(), type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PropertyWrapper> children() {
|
||||
if (list == null) {
|
||||
children = renderer.getContext().getProfileUtilities().getChildList(structure, definition);
|
||||
list = new ArrayList<PropertyWrapper>();
|
||||
for (ElementDefinition child : children) {
|
||||
List<Element> elements = new ArrayList<Element>();
|
||||
String name = tail(child.getPath());
|
||||
if (name.endsWith("[x]"))
|
||||
element.getNamedChildrenWithWildcard(name, elements);
|
||||
else
|
||||
element.getNamedChildren(name, elements);
|
||||
list.add(new PropertyWrapperMetaElement(renderer, structure, child, elements));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyWrapper getChildByName(String name) {
|
||||
for (PropertyWrapper p : children())
|
||||
if (p.getName().equals(name))
|
||||
return p;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ResourceWrapperMetaElement extends WrapperBaseImpl implements ResourceWrapper {
|
||||
private Element wrapped;
|
||||
private List<ResourceWrapper> list;
|
||||
private List<PropertyWrapper> list2;
|
||||
private StructureDefinition definition;
|
||||
public ResourceWrapperMetaElement(ResourceRenderer renderer, Element wrapped) {
|
||||
super(renderer);
|
||||
this.wrapped = wrapped;
|
||||
this.definition = wrapped.getProperty().getStructure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourceWrapper> getContained() {
|
||||
if (list == null) {
|
||||
List<Element> children = wrapped.getChildrenByName("contained");
|
||||
list = new ArrayList<ResourceWrapper>();
|
||||
for (Element e : children) {
|
||||
list.add(new ResourceWrapperMetaElement(renderer, e));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return wrapped.getNamedChildValue("id");
|
||||
}
|
||||
|
||||
@Override
|
||||
public XhtmlNode getNarrative() throws FHIRFormatError, IOException, FHIRException {
|
||||
Element txt = wrapped.getNamedChild("text");
|
||||
if (txt == null)
|
||||
return null;
|
||||
Element div = txt.getNamedChild("div");
|
||||
if (div == null)
|
||||
return null;
|
||||
else
|
||||
return div.getXhtml();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return wrapped.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PropertyWrapper> children() {
|
||||
if (list2 == null) {
|
||||
List<ElementDefinition> children = renderer.getContext().getProfileUtilities().getChildList(definition, definition.getSnapshot().getElement().get(0));
|
||||
list2 = new ArrayList<PropertyWrapper>();
|
||||
for (ElementDefinition child : children) {
|
||||
List<Element> elements = new ArrayList<Element>();
|
||||
if (child.getPath().endsWith("[x]"))
|
||||
wrapped.getNamedChildrenWithWildcard(tail(child.getPath()), elements);
|
||||
else
|
||||
wrapped.getNamedChildren(tail(child.getPath()), elements);
|
||||
list2.add(new PropertyWrapperMetaElement(renderer, definition, child, elements));
|
||||
}
|
||||
}
|
||||
return list2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describe(XhtmlNode x) {
|
||||
if (wrapped.hasChild("title") && wrapped.getChildValue("title") != null) {
|
||||
x.tx(wrapped.getChildValue("title"));
|
||||
} else if (wrapped.hasChild("name") && wrapped.getChildValue("name") != null) {
|
||||
x.tx(wrapped.getChildValue("name"));
|
||||
} else {
|
||||
x.tx("?ngen-1?");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class PropertyWrapperMetaElement extends RendererWrapperImpl implements PropertyWrapper {
|
||||
|
||||
private StructureDefinition structure;
|
||||
private ElementDefinition definition;
|
||||
private List<Element> values;
|
||||
private List<BaseWrapper> list;
|
||||
|
||||
public PropertyWrapperMetaElement(ResourceRenderer renderer, StructureDefinition structure, ElementDefinition definition, List<Element> values) {
|
||||
super(renderer);
|
||||
this.structure = structure;
|
||||
this.definition = definition;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return tail(definition.getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasValues() {
|
||||
return values.size() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BaseWrapper> getValues() {
|
||||
if (list == null) {
|
||||
list = new ArrayList<BaseWrapper>();
|
||||
for (Element e : values)
|
||||
list.add(new BaseWrapperMetaElement(renderer, e, e.fhirType(), structure, definition));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeCode() {
|
||||
return definition.typeSummary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefinition() {
|
||||
return definition.getDefinition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinCardinality() {
|
||||
return definition.getMin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxCardinality() {
|
||||
return "*".equals(definition.getMax()) ? Integer.MAX_VALUE : Integer.valueOf(definition.getMax());
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructureDefinition getStructure() {
|
||||
return structure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseWrapper value() {
|
||||
if (getValues().size() != 1)
|
||||
throw new Error("Access single value, but value count is "+getValues().size());
|
||||
return getValues().get(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
package org.hl7.fhir.r5.renderers.utils;
|
||||
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.IReferenceResolver;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
|
||||
public class RenderingContext {
|
||||
|
||||
public enum ResourceRendererMode{
|
||||
RESOURCE, IG
|
||||
}
|
||||
|
||||
protected IWorkerContext worker;
|
||||
protected MarkDownProcessor markdown;
|
||||
protected String lang;
|
||||
protected String prefix;
|
||||
protected ValidationOptions terminologyServiceOptions;
|
||||
protected ProfileUtilities profileUtilities;
|
||||
private boolean canonicalUrlsAsLinks;
|
||||
protected ResourceRendererMode mode;
|
||||
private IReferenceResolver resolver;
|
||||
private int headerLevelContext;
|
||||
private String tooCostlyNoteEmpty;
|
||||
private String tooCostlyNoteNotEmpty;
|
||||
private String tooCostlyNoteEmptyDependent;
|
||||
private String tooCostlyNoteNotEmptyDependent;
|
||||
/**
|
||||
*
|
||||
* @param context - access to all related resources that might be needed
|
||||
* @param markdown - appropriate markdown processing engine
|
||||
* @param terminologyServiceOptions - options to use when looking up codes
|
||||
* @param prefix - path to FHIR specification
|
||||
* @param lang - langauage to render in
|
||||
*/
|
||||
public RenderingContext(IWorkerContext worker, MarkDownProcessor markdown, ValidationOptions terminologyServiceOptions, String prefix, String lang, ResourceRendererMode mode) {
|
||||
super();
|
||||
this.worker = worker;
|
||||
this.markdown = markdown;
|
||||
this.lang = lang;
|
||||
this.prefix = prefix;
|
||||
this.mode = mode;
|
||||
this.terminologyServiceOptions = terminologyServiceOptions;
|
||||
profileUtilities = new ProfileUtilities(worker, null, null);
|
||||
}
|
||||
|
||||
public IWorkerContext getContext() {
|
||||
return worker;
|
||||
}
|
||||
|
||||
// -- 2. Markdown support -------------------------------------------------------
|
||||
|
||||
public ProfileUtilities getProfileUtilities() {
|
||||
return profileUtilities;
|
||||
}
|
||||
|
||||
public IWorkerContext getWorker() {
|
||||
return worker;
|
||||
}
|
||||
|
||||
public boolean isCanonicalUrlsAsLinks() {
|
||||
return canonicalUrlsAsLinks;
|
||||
}
|
||||
|
||||
public void setCanonicalUrlsAsLinks(boolean canonicalUrlsAsLinks) {
|
||||
this.canonicalUrlsAsLinks = canonicalUrlsAsLinks;
|
||||
}
|
||||
|
||||
public MarkDownProcessor getMarkdown() {
|
||||
return markdown;
|
||||
}
|
||||
|
||||
public String getLang() {
|
||||
return lang;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public ValidationOptions getTerminologyServiceOptions() {
|
||||
return terminologyServiceOptions;
|
||||
}
|
||||
|
||||
|
||||
public String getTooCostlyNoteEmpty() {
|
||||
return tooCostlyNoteEmpty;
|
||||
}
|
||||
|
||||
public void setTooCostlyNoteEmpty(String tooCostlyNoteEmpty) {
|
||||
this.tooCostlyNoteEmpty = tooCostlyNoteEmpty;
|
||||
}
|
||||
|
||||
public String getTooCostlyNoteNotEmpty() {
|
||||
return tooCostlyNoteNotEmpty;
|
||||
}
|
||||
|
||||
public void setTooCostlyNoteNotEmpty(String tooCostlyNoteNotEmpty) {
|
||||
this.tooCostlyNoteNotEmpty = tooCostlyNoteNotEmpty;
|
||||
}
|
||||
|
||||
public String getTooCostlyNoteEmptyDependent() {
|
||||
return tooCostlyNoteEmptyDependent;
|
||||
}
|
||||
|
||||
public void setTooCostlyNoteEmptyDependent(String tooCostlyNoteEmptyDependent) {
|
||||
this.tooCostlyNoteEmptyDependent = tooCostlyNoteEmptyDependent;
|
||||
}
|
||||
|
||||
public String getTooCostlyNoteNotEmptyDependent() {
|
||||
return tooCostlyNoteNotEmptyDependent;
|
||||
}
|
||||
|
||||
public void setTooCostlyNoteNotEmptyDependent(String tooCostlyNoteNotEmptyDependent) {
|
||||
this.tooCostlyNoteNotEmptyDependent = tooCostlyNoteNotEmptyDependent;
|
||||
}
|
||||
|
||||
public int getHeaderLevelContext() {
|
||||
return headerLevelContext;
|
||||
}
|
||||
|
||||
public void setHeaderLevelContext(int headerLevelContext) {
|
||||
this.headerLevelContext = headerLevelContext;
|
||||
}
|
||||
|
||||
public IReferenceResolver getResolver() {
|
||||
return resolver;
|
||||
}
|
||||
|
||||
public void setResolver(IReferenceResolver resolver) {
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
public void setTerminologyServiceOptions(ValidationOptions terminologyServiceOptions) {
|
||||
this.terminologyServiceOptions = terminologyServiceOptions;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
package org.hl7.fhir.r5.renderers.utils;
|
||||
|
||||
import org.hl7.fhir.r5.model.Bundle;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
public class Resolver {
|
||||
|
||||
public interface IReferenceResolver {
|
||||
ResourceWithReference resolve(String url);
|
||||
}
|
||||
|
||||
public static class ResourceContext {
|
||||
Bundle bundleResource;
|
||||
org.hl7.fhir.r5.elementmodel.Element bundleElement;
|
||||
|
||||
DomainResource resourceResource;
|
||||
org.hl7.fhir.r5.elementmodel.Element resourceElement;
|
||||
|
||||
public ResourceContext(Bundle bundle, DomainResource dr) {
|
||||
super();
|
||||
this.bundleResource = bundle;
|
||||
this.resourceResource = dr;
|
||||
}
|
||||
|
||||
public ResourceContext(org.hl7.fhir.r5.elementmodel.Element bundle, org.hl7.fhir.r5.elementmodel.Element dr) {
|
||||
this.bundleElement = bundle;
|
||||
this.resourceElement = dr;
|
||||
}
|
||||
|
||||
public ResourceContext(Object bundle, Element doc) {
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public Bundle getBundleResource() {
|
||||
return bundleResource;
|
||||
}
|
||||
|
||||
public org.hl7.fhir.r5.elementmodel.Element getBundleElement() {
|
||||
return bundleElement;
|
||||
}
|
||||
|
||||
public DomainResource getResourceResource() {
|
||||
return resourceResource;
|
||||
}
|
||||
|
||||
public org.hl7.fhir.r5.elementmodel.Element getResourceElement() {
|
||||
return resourceElement;
|
||||
}
|
||||
|
||||
public BundleEntryComponent resolve(String value) {
|
||||
if (value.startsWith("#")) {
|
||||
if (resourceResource != null) {
|
||||
for (Resource r : resourceResource.getContained()) {
|
||||
if (r.getId().equals(value.substring(1))) {
|
||||
BundleEntryComponent be = new BundleEntryComponent();
|
||||
be.setResource(r);
|
||||
return be;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (bundleResource != null) {
|
||||
for (BundleEntryComponent be : bundleResource.getEntry()) {
|
||||
if (be.getFullUrl().equals(value))
|
||||
return be;
|
||||
if (value.equals(be.getResource().fhirType()+"/"+be.getResource().getId()))
|
||||
return be;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public org.hl7.fhir.r5.elementmodel.Element resolveElement(String value) {
|
||||
if (value.startsWith("#")) {
|
||||
if (resourceElement != null) {
|
||||
for (org.hl7.fhir.r5.elementmodel.Element r : resourceElement.getChildrenByName("contained")) {
|
||||
if (r.getChildValue("id").equals(value.substring(1)))
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (bundleElement != null) {
|
||||
for (org.hl7.fhir.r5.elementmodel.Element be : bundleElement.getChildren("entry")) {
|
||||
org.hl7.fhir.r5.elementmodel.Element res = be.getNamedChild("resource");
|
||||
if (value.equals(be.getChildValue("fullUrl")))
|
||||
return be;
|
||||
if (value.equals(res.fhirType()+"/"+res.getChildValue("id")))
|
||||
return be;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ResourceWithReference {
|
||||
|
||||
private String reference;
|
||||
private ResourceWrapper resource;
|
||||
|
||||
public ResourceWithReference(String reference, ResourceWrapper resource) {
|
||||
this.reference = reference;
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
public String getReference() {
|
||||
return reference;
|
||||
}
|
||||
|
||||
public ResourceWrapper getResource() {
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -22,39 +22,13 @@ package org.hl7.fhir.r5.utils;
|
|||
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
@ -65,7 +39,6 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.io.output.ByteArrayOutputStream;
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
|
@ -184,18 +157,12 @@ import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent;
|
|||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemRenderer;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities.CodeSystemNavigator;
|
||||
import org.hl7.fhir.r5.terminologies.ConceptMapRenderer;
|
||||
import org.hl7.fhir.r5.terminologies.TerminologyRenderer;
|
||||
import org.hl7.fhir.r5.terminologies.TerminologyRenderer.ConceptMapRenderInstructions;
|
||||
import org.hl7.fhir.r5.terminologies.TerminologyRenderer.TerminologyRendererMode;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetRenderer;
|
||||
import org.hl7.fhir.r5.renderers.CodeSystemRenderer;
|
||||
import org.hl7.fhir.r5.renderers.ConceptMapRenderer;
|
||||
import org.hl7.fhir.r5.renderers.TerminologyRenderer;
|
||||
import org.hl7.fhir.r5.renderers.ValueSetRenderer;
|
||||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
||||
import org.hl7.fhir.r5.utils.LiquidEngine.LiquidDocument;
|
||||
import org.hl7.fhir.r5.utils.NarrativeGenerator.ResourceContext;
|
||||
import org.hl7.fhir.r5.utils.XVerExtensionManager.XVerExtensionStatus;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
|
@ -222,75 +189,6 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
Base parseType(String xml, String type) throws FHIRFormatError, IOException, FHIRException ;
|
||||
}
|
||||
|
||||
public static class ResourceContext {
|
||||
Bundle bundleResource;
|
||||
org.hl7.fhir.r5.elementmodel.Element bundleElement;
|
||||
|
||||
DomainResource resourceResource;
|
||||
org.hl7.fhir.r5.elementmodel.Element resourceElement;
|
||||
|
||||
public ResourceContext(Bundle bundle, DomainResource dr) {
|
||||
super();
|
||||
this.bundleResource = bundle;
|
||||
this.resourceResource = dr;
|
||||
}
|
||||
|
||||
public ResourceContext(org.hl7.fhir.r5.elementmodel.Element bundle, org.hl7.fhir.r5.elementmodel.Element dr) {
|
||||
this.bundleElement = bundle;
|
||||
this.resourceElement = dr;
|
||||
}
|
||||
|
||||
public ResourceContext(Object bundle, Element doc) {
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public BundleEntryComponent resolve(String value) {
|
||||
if (value.startsWith("#")) {
|
||||
if (resourceResource != null) {
|
||||
for (Resource r : resourceResource.getContained()) {
|
||||
if (r.getId().equals(value.substring(1))) {
|
||||
BundleEntryComponent be = new BundleEntryComponent();
|
||||
be.setResource(r);
|
||||
return be;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (bundleResource != null) {
|
||||
for (BundleEntryComponent be : bundleResource.getEntry()) {
|
||||
if (be.getFullUrl().equals(value))
|
||||
return be;
|
||||
if (value.equals(be.getResource().fhirType()+"/"+be.getResource().getId()))
|
||||
return be;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public org.hl7.fhir.r5.elementmodel.Element resolveElement(String value) {
|
||||
if (value.startsWith("#")) {
|
||||
if (resourceElement != null) {
|
||||
for (org.hl7.fhir.r5.elementmodel.Element r : resourceElement.getChildrenByName("contained")) {
|
||||
if (r.getChildValue("id").equals(value.substring(1)))
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (bundleElement != null) {
|
||||
for (org.hl7.fhir.r5.elementmodel.Element be : bundleElement.getChildren("entry")) {
|
||||
org.hl7.fhir.r5.elementmodel.Element res = be.getNamedChild("resource");
|
||||
if (value.equals(be.getChildValue("fullUrl")))
|
||||
return be;
|
||||
if (value.equals(res.fhirType()+"/"+res.getChildValue("id")))
|
||||
return be;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public interface IReferenceResolver {
|
||||
ResourceWithReference resolve(String url);
|
||||
}
|
||||
|
@ -1225,12 +1123,12 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
x.para().b().tx("Generated Narrative"+(showCodeDetails ? " with Details" : ""));
|
||||
try {
|
||||
generateByProfile(rc.resourceResource, profile, rc.resourceResource, profile.getSnapshot().getElement(), profile.getSnapshot().getElement().get(0), getChildrenForPath(profile.getSnapshot().getElement(), rc.resourceResource.getResourceType().toString()), x, rc.resourceResource.getResourceType().toString(), showCodeDetails, rc);
|
||||
generateByProfile(rc.getResourceResource(), profile, rc.getResourceResource(), profile.getSnapshot().getElement(), profile.getSnapshot().getElement().get(0), getChildrenForPath(profile.getSnapshot().getElement(), rc.getResourceResource().getResourceType().toString()), x, rc.getResourceResource().getResourceType().toString(), showCodeDetails, rc);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
x.para().b().style("color: maroon").tx("Exception generating Narrative: "+e.getMessage());
|
||||
}
|
||||
inject(rc.resourceResource, x, NarrativeStatus.GENERATED);
|
||||
inject(rc.getResourceResource(), x, NarrativeStatus.GENERATED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1557,7 +1455,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
renderContactPoint(c, x);
|
||||
}
|
||||
} else if (e instanceof UriType) {
|
||||
renderUri((UriType) e, x, defn.getPath(), rc != null && rc.resourceResource != null ? rc.resourceResource.getId() : null);
|
||||
renderUri((UriType) e, x, defn.getPath(), rc != null && rc.getResourceResource() != null ? rc.getResourceResource().getId() : null);
|
||||
} else if (e instanceof Timing) {
|
||||
renderTiming((Timing) e, x);
|
||||
} else if (e instanceof Range) {
|
||||
|
@ -2420,8 +2318,8 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
|
||||
public boolean generate(ResourceContext rcontext, ConceptMap cm) throws FHIRFormatError, DefinitionException, IOException {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
ConceptMapRenderer renderer = new ConceptMapRenderer(TerminologyRendererMode.RESOURCE, context, markdown, prefix, null);
|
||||
boolean res = renderer.generate(rcontext, cm, x);
|
||||
ConceptMapRenderer renderer = new ConceptMapRenderer(new RenderingContext(context, markdown, terminologyServiceOptions, prefix, null, ResourceRendererMode.RESOURCE), rcontext);
|
||||
boolean res = renderer.render(x, cm);
|
||||
inject(cm, x, NarrativeStatus.GENERATED);
|
||||
return res;
|
||||
}
|
||||
|
@ -2545,11 +2443,11 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
*/
|
||||
public boolean generate(ResourceContext rcontext, CodeSystem cs, boolean header, String lang) throws FHIRFormatError, DefinitionException, IOException {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
CodeSystemRenderer renderer = new CodeSystemRenderer(TerminologyRendererMode.RESOURCE, context, markdown, prefix, lang);
|
||||
CodeSystemRenderer renderer = new CodeSystemRenderer(new RenderingContext(context, markdown, terminologyServiceOptions, prefix, lang, ResourceRendererMode.RESOURCE), rcontext);
|
||||
renderer.getCodeSystemPropList().addAll(getCodeSystemPropList());
|
||||
renderer.setHeaderLevelContext(headerLevelContext);
|
||||
renderer.setTerminologyServiceOptions(terminologyServiceOptions);
|
||||
boolean hasExtensions = renderer.generate(x, cs, header);
|
||||
renderer.getContext().setHeaderLevelContext(headerLevelContext);
|
||||
renderer.getContext().setTerminologyServiceOptions(terminologyServiceOptions);
|
||||
boolean hasExtensions = renderer.render(x, cs, header);
|
||||
inject(cs, x, hasExtensions ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
|
||||
return true;
|
||||
}
|
||||
|
@ -2572,16 +2470,16 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
|
||||
public void generate(ResourceContext rcontext, ValueSet vs, ValueSet src, boolean header) throws FHIRException, IOException {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
ValueSetRenderer renderer = new ValueSetRenderer(TerminologyRendererMode.RESOURCE, context, markdown, prefix, null);
|
||||
renderer.setTooCostlyNoteEmpty(tooCostlyNoteEmpty);
|
||||
renderer.setTooCostlyNoteNotEmpty(tooCostlyNoteNotEmpty);
|
||||
renderer.setTooCostlyNoteEmptyDependent(tooCostlyNoteEmptyDependent);
|
||||
renderer.setTooCostlyNoteNotEmptyDependent(tooCostlyNoteNotEmptyDependent);
|
||||
ValueSetRenderer renderer = new ValueSetRenderer(new RenderingContext(context, markdown, terminologyServiceOptions, prefix, null, ResourceRendererMode.RESOURCE), rcontext);
|
||||
renderer.getContext().setTooCostlyNoteEmpty(tooCostlyNoteEmpty);
|
||||
renderer.getContext().setTooCostlyNoteNotEmpty(tooCostlyNoteNotEmpty);
|
||||
renderer.getContext().setTooCostlyNoteEmptyDependent(tooCostlyNoteEmptyDependent);
|
||||
renderer.getContext().setTooCostlyNoteNotEmptyDependent(tooCostlyNoteNotEmptyDependent);
|
||||
renderer.setNoSlowLookup(noSlowLookup);
|
||||
renderer.setHeaderLevelContext(headerLevelContext);
|
||||
renderer.setTerminologyServiceOptions(terminologyServiceOptions);
|
||||
renderer.getContext().setHeaderLevelContext(headerLevelContext);
|
||||
renderer.getContext().setTerminologyServiceOptions(terminologyServiceOptions);
|
||||
|
||||
boolean hasExtensions = renderer.render(rcontext, x, vs, src, header);
|
||||
boolean hasExtensions = renderer.render(x, vs, header);
|
||||
inject(vs, x, hasExtensions ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ import org.hl7.fhir.r5.model.TypeDetails.ProfiledType;
|
|||
import org.hl7.fhir.r5.model.UriType;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.r5.terminologies.TerminologyRenderer;
|
||||
import org.hl7.fhir.r5.renderers.TerminologyRenderer;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||
import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
|
||||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
||||
|
|
|
@ -518,8 +518,8 @@ public class SnapShotGenerationTests {
|
|||
pu.setThrowException(false);
|
||||
pu.setDebug(test.isDebug());
|
||||
pu.setIds(test.getSource(), false);
|
||||
if (!TestingUtilities.context().hasPackage("hl7.fhir.xver-extensions", "0.0.3")) {
|
||||
NpmPackage npm = new PackageCacheManager(true, ToolsVersion.TOOLS_VERSION).loadPackage("hl7.fhir.xver-extensions", "0.0.3");
|
||||
if (!TestingUtilities.context().hasPackage("hl7.fhir.xver-extensions", "0.0.4")) {
|
||||
NpmPackage npm = new PackageCacheManager(true, ToolsVersion.TOOLS_VERSION).loadPackage("hl7.fhir.xver-extensions", "0.0.4");
|
||||
TestingUtilities.context().loadFromPackage(npm, new TestLoader(new String[]{"StructureDefinition"}), new String[]{"StructureDefinition"});
|
||||
}
|
||||
pu.setXver(new XVerExtensionManager(TestingUtilities.context()));
|
||||
|
|
|
@ -342,7 +342,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
|||
context = SimpleWorkerContext.fromDefinitions(source, loaderForVersion(), new PackageVersion(src));
|
||||
context.setAllowLoadingDuplicates(true); // because of Forge
|
||||
context.setExpansionProfile(makeExpProfile());
|
||||
NpmPackage npm = pcm.loadPackage("hl7.fhir.xver-extensions", "0.0.3");
|
||||
NpmPackage npm = pcm.loadPackage("hl7.fhir.xver-extensions", "0.0.4");
|
||||
context.loadFromPackage(npm, null);
|
||||
grabNatives(source, "http://hl7.org/fhir");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue