* Rendering: add rendering for Parameters resources

* Rendering: refactor of resource resolution code to support Parameters
* General clean up of rendering consistency & implement additional details when rendering (including patient summary)
* Rendering: major overhaul of DiagnosticReport rendering
This commit is contained in:
Grahame Grieve 2020-08-03 17:36:32 +10:00
parent 137d04f68d
commit 7616b55213
25 changed files with 835 additions and 104 deletions

View File

@ -37,8 +37,8 @@ public class BundleRenderer extends ResourceRenderer {
}
@Override
public boolean render(XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
return false;
public boolean render(XhtmlNode x, Resource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
return render(x, (Bundle) r);
}
@Override
@ -46,6 +46,11 @@ public class BundleRenderer extends ResourceRenderer {
return null;
}
@Override
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
return null;
}
@Override
public boolean render(XhtmlNode x, ResourceWrapper b) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
List<BaseWrapper> entries = b.children("entry");

View File

@ -15,6 +15,7 @@ import org.hl7.fhir.r5.model.CapabilityStatement.SystemInteractionComponent;
import org.hl7.fhir.r5.model.CapabilityStatement.SystemRestfulInteraction;
import org.hl7.fhir.r5.model.CapabilityStatement.TypeRestfulInteraction;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.utilities.xhtml.NodeType;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
@ -29,7 +30,7 @@ public class CapabilityStatementRenderer extends ResourceRenderer {
super(context, rcontext);
}
public boolean render(XhtmlNode x, DomainResource dr) throws FHIRFormatError, DefinitionException, IOException {
public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException {
return render(x, (CapabilityStatement) dr);
}
@ -149,4 +150,14 @@ public class CapabilityStatementRenderer extends ResourceRenderer {
tr.td().addText(value);
}
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
if (r.has("title")) {
return r.children("title").get(0).getBase().primitiveValue();
}
if (r.has("name")) {
return r.children("name").get(0).getBase().primitiveValue();
}
return "??";
}
}

View File

@ -19,6 +19,7 @@ import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.Enumeration;
import org.hl7.fhir.r5.model.Extension;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
@ -38,7 +39,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
}
public boolean render(XhtmlNode x, DomainResource dr) throws FHIRFormatError, DefinitionException, IOException {
public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException {
return render(x, (CodeSystem) dr);
}

View File

@ -11,6 +11,7 @@ import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.CompartmentDefinition;
import org.hl7.fhir.r5.model.CompartmentDefinition.CompartmentDefinitionResourceComponent;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
@ -26,7 +27,7 @@ public class CompartmentDefinitionRenderer extends ResourceRenderer {
super(context, rcontext);
}
public boolean render(XhtmlNode x, DomainResource dr) throws FHIRFormatError, DefinitionException, IOException {
public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException {
return render(x, (CompartmentDefinition) dr);
}
@ -72,4 +73,14 @@ public class CompartmentDefinitionRenderer extends ResourceRenderer {
return ((CompartmentDefinition) r).present();
}
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
if (r.has("title")) {
return r.children("title").get(0).getBase().primitiveValue();
}
if (r.has("name")) {
return r.children("name").get(0).getBase().primitiveValue();
}
return "??";
}
}

View File

@ -18,6 +18,7 @@ import org.hl7.fhir.r5.model.ContactDetail;
import org.hl7.fhir.r5.model.ContactPoint;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.Enumerations.ConceptMapRelationship;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.r5.utils.ToolingExtensions;
@ -34,7 +35,7 @@ public class ConceptMapRenderer extends TerminologyRenderer {
super(context, rcontext);
}
public boolean render(XhtmlNode x, DomainResource dr) throws FHIRFormatError, DefinitionException, IOException {
public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException {
return render(x, (ConceptMap) dr);
}

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.r5.renderers;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.hl7.fhir.exceptions.DefinitionException;
@ -11,6 +12,7 @@ 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.BaseDateTimeType;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.CodeableConcept;
@ -23,6 +25,7 @@ import org.hl7.fhir.r5.model.Enumeration;
import org.hl7.fhir.r5.model.HumanName;
import org.hl7.fhir.r5.model.HumanName.NameUse;
import org.hl7.fhir.r5.model.Identifier;
import org.hl7.fhir.r5.model.InstantType;
import org.hl7.fhir.r5.model.Period;
import org.hl7.fhir.r5.model.PrimitiveType;
import org.hl7.fhir.r5.model.Quantity;
@ -50,7 +53,7 @@ import org.hl7.fhir.utilities.validation.ValidationOptions;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.hl7.fhir.utilities.xhtml.XhtmlParser;
public class DataRenderer {
public class DataRenderer extends Renderer {
// -- 1. context --------------------------------------------------------------
@ -193,7 +196,6 @@ public class DataRenderer {
return lang;
}
private boolean isCanonical(String path) {
if (!path.endsWith(".url"))
return false;
@ -269,8 +271,19 @@ public class DataRenderer {
return "to do";
}
public void render(XhtmlNode x, BaseWrapper type) {
x.tx("to do");
public void render(XhtmlNode x, BaseWrapper type) {
Base base = null;
try {
base = type.getBase();
} catch (FHIRException | IOException e) {
x.tx("Error: " + e.getMessage()); // this shouldn't happen - it's an error in the library itself
return;
}
if (base instanceof DataType) {
render(x, (DataType) base);
} else {
x.tx("to do: "+base.fhirType());
}
}
public void renderBase(XhtmlNode x, Base b) {
@ -312,6 +325,10 @@ public class DataRenderer {
renderSampledData(x, (SampledData) type);
} else if (type instanceof Reference) {
renderReference(x, (Reference) type);
} else if (type instanceof InstantType) {
x.tx(((InstantType) type).toHumanDisplay());
} else if (type instanceof BaseDateTimeType) {
x.tx(((BaseDateTimeType) type).toHumanDisplay());
} else if (type.isPrimitive()) {
x.tx(type.primitiveValue());
} else {
@ -367,31 +384,37 @@ public class DataRenderer {
}
protected void renderAnnotation(XhtmlNode x, Annotation a, boolean showCodeDetails) throws FHIRException {
StringBuilder s = new StringBuilder();
if (a.hasAuthor()) {
s.append("Author: ");
StringBuilder b = new StringBuilder();
if (a.hasText()) {
b.append(a.getText());
}
if (a.hasAuthorReference())
s.append(a.getAuthorReference().getReference());
else if (a.hasAuthorStringType())
s.append(a.getAuthorStringType().getValue());
if (a.hasText() && (a.hasAuthor() || a.hasTimeElement())) {
b.append(" (");
}
if (a.hasAuthor()) {
b.append("By ");
if (a.hasAuthorReference()) {
b.append(a.getAuthorReference().getReference());
} else if (a.hasAuthorStringType()) {
b.append(a.getAuthorStringType().getValue());
}
}
if (a.hasTimeElement()) {
if (s.length() > 0)
s.append("; ");
s.append("Made: ").append(a.getTimeElement().toHumanDisplay());
if (b.length() > 0) {
b.append(" ");
}
b.append("@").append(a.getTimeElement().toHumanDisplay());
}
if (a.hasText() && (a.hasAuthor() || a.hasTimeElement())) {
b.append(")");
}
if (a.hasText()) {
if (s.length() > 0)
s.append("; ");
s.append("Annotation: ").append(a.getText());
}
x.addText(s.toString());
x.addText(b.toString());
}
public String displayCoding(Coding c) {
@ -563,11 +586,13 @@ public class DataRenderer {
if (ii.hasType()) {
if (ii.getType().hasText())
s = ii.getType().getText()+" = "+s;
s = ii.getType().getText()+": "+s;
else if (ii.getType().hasCoding() && ii.getType().getCoding().get(0).hasDisplay())
s = ii.getType().getCoding().get(0).getDisplay()+" = "+s;
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;
s = lookupCode(ii.getType().getCoding().get(0).getSystem(), ii.getType().getCoding().get(0).getCode())+": "+s;
} else {
s = "id: "+s;
}
if (ii.hasUse())

View File

@ -10,6 +10,8 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.DataType;
import org.hl7.fhir.r5.model.DiagnosticReport;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.PropertyWrapper;
@ -18,6 +20,7 @@ import org.hl7.fhir.r5.renderers.utils.DirectWrappers;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
@ -38,11 +41,11 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
super(context, rcontext);
}
public boolean render(XhtmlNode x, DomainResource dr) throws FHIRFormatError, DefinitionException, IOException {
public boolean render(XhtmlNode x, Resource dr) throws IOException, FHIRException, EOperationOutcome {
return render(x, (DiagnosticReport) dr);
}
public boolean render(XhtmlNode x, ResourceWrapper dr) throws FHIRFormatError, DefinitionException, IOException {
public boolean render(XhtmlNode x, ResourceWrapper dr) throws IOException, FHIRException, EOperationOutcome {
XhtmlNode h2 = x.h2();
render(h2, getProperty(dr, "code").value());
h2.tx(" ");
@ -56,40 +59,55 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
}
h2.tx(") ");
}
XhtmlNode tbl = x.table("grid");
XhtmlNode tr;
if (dr.has("subject")) {
tr = tbl.tr();
tr.td().tx("Subject");
populateSubjectSummary(tr.td(), getProperty(dr, "subject").value());
}
DataType eff = null;
DataType iss = null;
if (dr.has("effective[x]")) {
tr = tbl.tr();
tr.td().tx("When For");
eff = (DataType) getProperty(dr, "effective[x]").value().getBase();
render(tr.td(), eff);
}
if (dr.has("issued")) {
render(h2, getProperty(dr, "issued").value());
tr = tbl.tr();
tr.td().tx("Reported");
eff = (DataType) getProperty(dr, "effective[x]").value().getBase();
render(tr.td(), getProperty(dr, "issued").value());
}
XhtmlNode tbl = x.table("grid");
XhtmlNode tr = tbl.tr();
XhtmlNode tdl = tr.td();
XhtmlNode tdr = tr.td();
if (dr.has("subject")) {
populateSubjectSummary(tdl, getProperty(dr, "subject").value());
}
tdr.b().tx("Report Details");
tdr.br();
pw = getProperty(dr, "perfomer");
if (valued(pw)) {
tdr.addText(Utilities.pluralize("Performer", pw.getValues().size())+":");
tr = tbl.tr();
tr.td().tx(Utilities.pluralize("Performer", pw.getValues().size()));
XhtmlNode tdr = tr.td();
for (BaseWrapper v : pw.getValues()) {
tdr.tx(" ");
render(tdr, v);
}
tdr.br();
}
pw = getProperty(dr, "identifier");
if (valued(pw)) {
tdr.addText(Utilities.pluralize("Identifier", pw.getValues().size())+":");
tr = tbl.tr();
tr.td().tx(Utilities.pluralize("Identifier", pw.getValues().size())+":");
XhtmlNode tdr = tr.td();
for (BaseWrapper v : pw.getValues()) {
tdr.tx(" ");
render(tdr, v);
}
tdr.br();
}
pw = getProperty(dr, "request");
if (valued(pw)) {
tdr.addText(Utilities.pluralize("Request", pw.getValues().size())+":");
tr = tbl.tr();
tr.td().tx(Utilities.pluralize("Request", pw.getValues().size())+":");
XhtmlNode tdr = tr.td();
for (BaseWrapper v : pw.getValues()) {
tdr.tx(" ");
render(tdr, v);
@ -97,29 +115,35 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
tdr.br();
}
x.para().b().tx("Report Details");
pw = getProperty(dr, "result");
if (valued(pw)) {
List<ObservationNode> observations = fetchObservations(pw.getValues(), dr);
buildObservationsTable(x, observations);
buildObservationsTable(x, observations, eff, iss);
}
pw = getProperty(dr, "conclusion");
if (valued(pw))
render(x.para(), pw.value());
pw = getProperty(dr, "result");
pw = getProperty(dr, "conclusionCode");
if (!valued(pw)) {
pw = getProperty(dr, "codedDiagnosis");
}
if (valued(pw)) {
XhtmlNode p = x.para();
p.b().tx("Coded Diagnoses :");
p.b().tx("Coded Conclusions :");
XhtmlNode ul = x.ul();
for (BaseWrapper v : pw.getValues()) {
tdr.tx(" ");
render(tdr, v);
render(ul.li(), v);
}
}
return false;
}
public boolean render(XhtmlNode x, DiagnosticReport dr) throws FHIRFormatError, DefinitionException, IOException {
public boolean render(XhtmlNode x, DiagnosticReport dr) throws IOException, FHIRException, EOperationOutcome {
render(x, new DirectWrappers.ResourceWrapperDirect(this.context, dr));
return true;
@ -138,7 +162,12 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
return display((DiagnosticReport) r);
}
private void populateSubjectSummary(XhtmlNode container, BaseWrapper subject) throws UnsupportedEncodingException, FHIRException, IOException {
@Override
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
return "Not done yet";
}
private void populateSubjectSummary(XhtmlNode container, BaseWrapper subject) throws UnsupportedEncodingException, FHIRException, IOException, EOperationOutcome {
ResourceWrapper r = fetchResource(subject);
if (r == null)
container.tx("Unable to get Patient Details");
@ -148,8 +177,8 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
container.tx("Not done yet");
}
private void generatePatientSummary(XhtmlNode c, ResourceWrapper r) {
c.tx("to do");
private void generatePatientSummary(XhtmlNode c, ResourceWrapper r) throws FHIRFormatError, DefinitionException, FHIRException, IOException, EOperationOutcome {
new PatientRenderer(context).describe(c, r);
}
private List<ObservationNode> fetchObservations(List<BaseWrapper> list, ResourceWrapper rw) throws UnsupportedEncodingException, FHIRException, IOException {
@ -171,40 +200,165 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
return res;
}
private void buildObservationsTable(XhtmlNode root, List<ObservationNode> observations) {
XhtmlNode tbl = root.table( "none");
private void buildObservationsTable(XhtmlNode root, List<ObservationNode> observations, DataType eff, DataType iss) throws UnsupportedEncodingException, FHIRException, IOException {
XhtmlNode tbl = root.table("grid");
boolean refRange = scanObsForRefRange(observations);
boolean flags = scanObsForFlags(observations);
boolean note = scanObsForNote(observations);
boolean effectiveTime = scanObsForEffective(observations, eff);
boolean issued = scanObsForIssued(observations, iss);
int cs = 2;
if (refRange) cs++;
if (flags) cs++;
if (note) cs++;
if (issued) cs++;
if (effectiveTime) cs++;
XhtmlNode tr = tbl.tr();
tr.td().b().tx("Code");
tr.td().b().tx("Value");
if (refRange) {
tr.td().b().tx("Reference Range");
}
if (flags) {
tr.td().b().tx("Flags");
}
if (note) {
tr.td().b().tx("Note");
}
if (effectiveTime) {
tr.td().b().tx("When For");
}
if (issued) {
tr.td().b().tx("Reported");
}
for (ObservationNode o : observations) {
addObservationToTable(tbl, o, 0);
addObservationToTable(tbl, o, 0, Integer.toString(cs), refRange, flags, note, effectiveTime, issued, eff, iss);
}
}
private void addObservationToTable(XhtmlNode tbl, ObservationNode o, int i) {
private boolean scanObsForRefRange(List<ObservationNode> observations) {
for (ObservationNode o : observations) {
if (o.obs.getResource() != null) {
PropertyWrapper pw = getProperty(o.obs.getResource(), "referenceRange");
if (valued(pw)) {
return true;
}
}
if (o.contained != null) {
if (scanObsForRefRange(o.contained)) {
return true;
}
}
}
return false;
}
private boolean scanObsForNote(List<ObservationNode> observations) {
for (ObservationNode o : observations) {
if (o.obs.getResource() != null) {
PropertyWrapper pw = getProperty(o.obs.getResource(), "note");
if (valued(pw)) {
return true;
}
}
if (o.contained != null) {
if (scanObsForNote(o.contained)) {
return true;
}
}
}
return false;
}
private boolean scanObsForIssued(List<ObservationNode> observations, DataType iss) throws UnsupportedEncodingException, FHIRException, IOException {
for (ObservationNode o : observations) {
if (o.obs.getResource() != null) {
PropertyWrapper pw = getProperty(o.obs.getResource(), "issued");
if (valued(pw)) {
if (!Base.compareDeep(pw.value().getBase(), iss, true)) {
return true;
}
}
}
if (o.contained != null) {
if (scanObsForIssued(o.contained, iss)) {
return true;
}
}
}
return false;
}
private boolean scanObsForEffective(List<ObservationNode> observations, DataType eff) throws UnsupportedEncodingException, FHIRException, IOException {
for (ObservationNode o : observations) {
if (o.obs.getResource() != null) {
PropertyWrapper pw = getProperty(o.obs.getResource(), "effective[x]");
if (valued(pw)) {
if (!Base.compareDeep(pw.value().getBase(), eff, true)) {
return true;
}
}
}
if (o.contained != null) {
if (scanObsForEffective(o.contained, eff)) {
return true;
}
}
}
return false;
}
private boolean scanObsForFlags(List<ObservationNode> observations) throws UnsupportedEncodingException, FHIRException, IOException {
for (ObservationNode o : observations) {
if (o.obs.getResource() != null) {
PropertyWrapper pw = getProperty(o.obs.getResource(), "interpretation");
if (valued(pw)) {
return true;
}
pw = getProperty(o.obs.getResource(), "status");
if (valued(pw)) {
if (!pw.value().getBase().primitiveValue().equals("final")) {
return true;
}
}
}
if (o.contained != null) {
if (scanObsForFlags(o.contained)) {
return true;
}
}
}
return false;
}
private void addObservationToTable(XhtmlNode tbl, ObservationNode o, int i, String cs, boolean refRange, boolean flags, boolean note, boolean effectiveTime, boolean issued, DataType eff, DataType iss) throws UnsupportedEncodingException, FHIRException, IOException {
XhtmlNode tr = tbl.tr();
if (o.obs.getReference() == null) {
XhtmlNode td = tr.td().colspan("6");
XhtmlNode td = tr.td().colspan(cs);
td.i().tx("This Observation could not be resolved");
} else {
if (o.obs.getResource() != null) {
addObservationToTable(tr, o.obs.getResource(), i);
addObservationToTable(tr, o.obs.getResource(), i, o.obs.getReference(), refRange, flags, note, effectiveTime, issued, eff, iss);
} else {
tr.td().tx("Unable to resolve Observation: "+o.obs.getReference());
XhtmlNode td = tr.td().colspan(cs);
td.i().ah(o.obs.getReference()).tx("Observation");
}
if (o.contained != null) {
for (ObservationNode c : o.contained) {
addObservationToTable(tbl, c, i+1);
addObservationToTable(tbl, c, i+1, cs, refRange, flags, note, effectiveTime, issued, eff, iss);
}
}
}
}
private void addObservationToTable(XhtmlNode tr, ResourceWrapper obs, int i) {
// TODO Auto-generated method stub
private void addObservationToTable(XhtmlNode tr, ResourceWrapper obs, int i, String ref, boolean refRange, boolean flags, boolean note, boolean effectiveTime, boolean issued, DataType eff, DataType iss) throws UnsupportedEncodingException, FHIRException, IOException {
// code (+bodysite)
XhtmlNode td = tr.td();
PropertyWrapper pw = getProperty(obs, "code");
if (valued(pw)) {
render(td, pw.value());
render(td.ah(ref), pw.value());
}
pw = getProperty(obs, "bodySite");
if (valued(pw)) {
@ -218,23 +372,113 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
pw = getProperty(obs, "value[x]");
if (valued(pw)) {
render(td, pw.value());
} else {
pw = getProperty(obs, "dataAbsentReason");
if (valued(pw)) {
XhtmlNode span = td.span("color: maroon", "Error");
span.tx("Error: ");
render(span.b(), pw.value());
}
}
if (refRange) {
// reference range
td = tr.td();
pw = getProperty(obs, "referenceRange");
if (valued(pw)) {
boolean first = true;
for (BaseWrapper v : pw.getValues()) {
if (first) first = false; else td.br();
PropertyWrapper pwr = getProperty(v, "type");
if (valued(pwr)) {
render(td, pwr.value());
td.tx(": ");
}
PropertyWrapper pwt = getProperty(v, "text");
if (valued(pwt)) {
render(td, pwt.value());
} else {
PropertyWrapper pwl = getProperty(v, "low");
PropertyWrapper pwh = getProperty(v, "high");
if (valued(pwl) && valued(pwh)) {
render(td, pwl.value());
td.tx(" - ");
render(td, pwh.value());
} else if (valued(pwl)) {
td.tx(">");
render(td, pwl.value());
} else if (valued(pwh)) {
td.tx("<");
render(td, pwh.value());
} else {
td.tx("??");
}
}
pwr = getProperty(v, "appliesTo");
PropertyWrapper pwrA = getProperty(v, "age");
if (valued(pwr) || valued(pwrA)) {
boolean firstA = true;
td.tx(" for ");
if (valued(pwr)) {
for (BaseWrapper va : pwr.getValues()) {
if (firstA) firstA = false; else td.tx(", ");
render(td, va);
}
}
if (valued(pwrA)) {
if (firstA) firstA = false; else td.tx(", ");
td.tx("Age ");
render(td, pwrA.value());
}
}
}
}
}
if (flags) {
// flags (status other than F, interpretation, )
td = tr.td();
boolean first = true;
pw = getProperty(obs, "status");
if (valued(pw)) {
if (!pw.value().getBase().primitiveValue().equals("final")) {
if (first) first = false; else td.br();
render(td, pw.value());
}
}
pw = getProperty(obs, "interpretation");
if (valued(pw)) {
for (BaseWrapper v : pw.getValues()) {
if (first) first = false; else td.br();
render(td, v);
}
}
}
// units
td = tr.td();
td.tx("to do");
// reference range
td = tr.td();
td.tx("to do");
// flags (status other than F, interpretation, )
td = tr.td();
td.tx("to do");
// issued if different to DR
td = tr.td();
td.tx("to do");
if (note) {
td = tr.td();
pw = getProperty(obs, "note");
if (valued(pw)) {
render(td, pw.value());
}
}
if (effectiveTime) {
// effective if different to DR
td = tr.td();
pw = getProperty(obs, "effective[x]");
if (valued(pw)) {
if (!Base.compareDeep(pw.value().getBase(), eff, true)) {
render(td, pw.value());
}
}
}
if (issued) {
// issued if different to DR
td = tr.td();
pw = getProperty(obs, "issued");
if (valued(pw)) {
if (!Base.compareDeep(pw.value().getBase(), eff, true)) {
render(td, pw.value());
}
}
}
}
}

View File

@ -6,6 +6,7 @@ import java.io.UnsupportedEncodingException;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
public class EncounterRenderer extends ResourceRenderer {
@ -15,7 +16,7 @@ public class EncounterRenderer extends ResourceRenderer {
super(context);
}
public boolean render(XhtmlNode x, DomainResource dr) throws UnsupportedEncodingException, IOException {
public boolean render(XhtmlNode x, Resource dr) throws UnsupportedEncodingException, IOException {
describe(x, dr);
return false;
}
@ -24,4 +25,10 @@ public class EncounterRenderer extends ResourceRenderer {
return "Not done yet";
}
@Override
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
return "Not done yet";
}
}

View File

@ -9,6 +9,7 @@ import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.ImplementationGuide;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
@ -22,7 +23,7 @@ public class ImplementationGuideRenderer extends ResourceRenderer {
super(context, rcontext);
}
public boolean render(XhtmlNode x, DomainResource dr) throws FHIRFormatError, DefinitionException, IOException {
public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException {
return render(x, (ImplementationGuide) dr);
}
@ -47,4 +48,14 @@ public class ImplementationGuideRenderer extends ResourceRenderer {
return ((ImplementationGuide) r).present();
}
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
if (r.has("title")) {
return r.children("title").get(0).getBase().primitiveValue();
}
if (r.has("name")) {
return r.children("name").get(0).getBase().primitiveValue();
}
return "??";
}
}

View File

@ -34,7 +34,7 @@ public class LiquidRenderer extends ResourceRenderer {
}
@Override
public boolean render(XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
public boolean render(XhtmlNode x, Resource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
LiquidEngine engine = new LiquidEngine(context.getWorker(), context.getServices());
XhtmlNode xn;
try {
@ -56,6 +56,16 @@ public class LiquidRenderer extends ResourceRenderer {
return "not done yet";
}
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
if (r.has("title")) {
return r.children("title").get(0).getBase().primitiveValue();
}
if (r.has("name")) {
return r.children("name").get(0).getBase().primitiveValue();
}
return "??";
}
@Override
public boolean render(XhtmlNode x, ResourceWrapper r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
LiquidEngine engine = new LiquidEngine(context.getWorker(), context.getServices());

View File

@ -29,7 +29,7 @@ public class ListRenderer extends ResourceRenderer {
super(context, rcontext);
}
public boolean render(XhtmlNode x, DomainResource dr) throws FHIRFormatError, DefinitionException, IOException {
public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException {
return render(x, (ListResource) dr);
}
@ -189,6 +189,14 @@ public class ListRenderer extends ResourceRenderer {
return ((ListResource) r).getTitle();
}
@Override
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
if (r.has("title")) {
return r.children("title").get(0).getBase().primitiveValue();
}
return "??";
}
private void shortForRef(XhtmlNode x, Reference ref) throws UnsupportedEncodingException, IOException {
ResourceWithReference r = context.getResolver().resolve(context, ref.getReference());
if (r == null) {

View File

@ -12,6 +12,7 @@ import org.hl7.fhir.r5.model.PrimitiveType;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
import org.hl7.fhir.r5.utils.ToolingExtensions;
@ -28,7 +29,7 @@ public class NamingSystemRenderer extends ResourceRenderer {
super(context, rcontext);
}
public boolean render(XhtmlNode x, DomainResource dr) throws FHIRFormatError, DefinitionException, IOException {
public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException {
return render(x, (NamingSystem) dr);
}
@ -125,4 +126,14 @@ public class NamingSystemRenderer extends ResourceRenderer {
return ((NamingSystem) r).present();
}
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
if (r.has("title")) {
return r.children("title").get(0).getBase().primitiveValue();
}
if (r.has("name")) {
return r.children("name").get(0).getBase().primitiveValue();
}
return "??";
}
}

View File

@ -30,7 +30,7 @@ public class OperationDefinitionRenderer extends TerminologyRenderer {
super(context, rcontext);
}
public boolean render(XhtmlNode x, DomainResource dr) throws IOException, FHIRException, EOperationOutcome {
public boolean render(XhtmlNode x, Resource dr) throws IOException, FHIRException, EOperationOutcome {
return render(x, (OperationDefinition) dr);
}

View File

@ -14,6 +14,7 @@ import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
@ -29,7 +30,7 @@ public class OperationOutcomeRenderer extends ResourceRenderer {
super(context, rcontext);
}
public boolean render(XhtmlNode x, DomainResource dr) throws FHIRFormatError, DefinitionException, IOException {
public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException {
return render(x, (OperationOutcome) dr);
}
@ -85,6 +86,11 @@ public class OperationOutcomeRenderer extends ResourceRenderer {
return "todo";
}
@Override
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
return "Not done yet";
}
@Override
public String display(Resource r) throws UnsupportedEncodingException, IOException {
return display((OperationOutcome) r);

View File

@ -0,0 +1,124 @@
package org.hl7.fhir.r5.renderers;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.model.Bundle;
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r5.model.Bundle.BundleEntryRequestComponent;
import org.hl7.fhir.r5.model.Bundle.BundleEntryResponseComponent;
import org.hl7.fhir.r5.model.Bundle.BundleEntrySearchComponent;
import org.hl7.fhir.r5.model.Bundle.BundleType;
import org.hl7.fhir.r5.model.Composition;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.r5.model.Provenance;
import org.hl7.fhir.r5.model.Resource;
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.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.utilities.xhtml.NodeType;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
public class ParametersRenderer extends ResourceRenderer {
public ParametersRenderer(RenderingContext context, ResourceContext rcontext) {
super(context, rcontext);
}
@Override
public boolean render(XhtmlNode x, Resource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
return false;
}
@Override
public String display(Resource r) throws UnsupportedEncodingException, IOException {
return null;
}
@Override
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
return null;
}
@Override
public boolean render(XhtmlNode x, ResourceWrapper params) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
x.h2().tx("Parameters");
XhtmlNode tbl = x.table("grid");
PropertyWrapper pw = getProperty(params, "parameter");
if (valued(pw)) {
paramsW(tbl, pw.getValues(), 0);
}
return false;
}
private void paramsW(XhtmlNode tbl, List<BaseWrapper> list, int indent) throws FHIRFormatError, DefinitionException, FHIRException, IOException, EOperationOutcome {
for (BaseWrapper p : list) {
XhtmlNode tr = tbl.tr();
XhtmlNode td = tr.td();
for (int i = 0; i < indent; i++) {
td.tx(XhtmlNode.NBSP);
}
td.tx(p.get("name").primitiveValue());
if (p.has("value")) {
renderBase(tr.td(), p.get("value"));
} else if (p.has("resource")) {
ResourceWrapper rw = p.getChildByName("resource").getAsResource();
td = tr.td();
XhtmlNode para = td.para();
para.tx(rw.fhirType()+"/"+rw.getId());
para.an(rw.fhirType().toLowerCase()+"_"+rw.getId()).tx(" ");
XhtmlNode x = rw.getNarrative();
if (x != null) {
td.addChildren(x);
} else {
ResourceRenderer rr = RendererFactory.factory(rw, context, rcontext);
rr.render(td, rw);
}
} else if (p.has("part")) {
tr.td();
PropertyWrapper pw = getProperty(p, "parameter");
paramsW(tbl, pw.getValues(), 1);
}
}
}
public XhtmlNode render(Parameters params) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
XhtmlNode div = new XhtmlNode(NodeType.Element, "div");
div.h2().tx("Parameters");
XhtmlNode tbl = div.table("grid");
params(tbl, params.getParameter(), 0);
return div;
}
private void params(XhtmlNode tbl, List<ParametersParameterComponent> list, int indent) throws FHIRFormatError, DefinitionException, FHIRException, IOException, EOperationOutcome {
for (ParametersParameterComponent p : list) {
XhtmlNode tr = tbl.tr();
XhtmlNode td = tr.td();
for (int i = 0; i < indent; i++) {
td.tx(XhtmlNode.NBSP);
}
td.tx(p.getName());
if (p.hasValue()) {
render(tr.td(), p.getValue());
} else if (p.hasResource()) {
ResourceRenderer rr = RendererFactory.factory(p.getResource(), context);
rr.render(tr.td(), p.getResource());
} else if (p.hasPart()) {
tr.td();
params(tbl, p.getPart(), 1);
}
}
}
}

View File

@ -3,9 +3,20 @@ package org.hl7.fhir.r5.renderers;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.poi.hssf.record.chart.DatRecord;
import org.hl7.fhir.r5.model.DateTimeType;
import org.hl7.fhir.r5.model.DateType;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.HumanName;
import org.hl7.fhir.r5.model.HumanName.NameUse;
import org.hl7.fhir.r5.model.Identifier;
import org.hl7.fhir.r5.model.Identifier.IdentifierUse;
import org.hl7.fhir.r5.model.Patient;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
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.utilities.xhtml.XhtmlNode;
public class PatientRenderer extends ResourceRenderer {
@ -16,13 +27,179 @@ public class PatientRenderer extends ResourceRenderer {
super(context);
}
public boolean render(XhtmlNode x, DomainResource dr) throws UnsupportedEncodingException, IOException {
public boolean render(XhtmlNode x, Resource dr) throws UnsupportedEncodingException, IOException {
describe(x, dr);
return false;
}
// name gender DoB (MRN)
public String display(Resource dr) {
return "Not done yet";
Patient pat = (Patient) dr;
Identifier id = null;
for (Identifier t : pat.getIdentifier()) {
id = chooseId(id, t);
}
HumanName n = null;
for (HumanName t : pat.getName()) {
n = chooseName(n, t);
}
return display(n, pat.getGender().getDisplay(), pat.getBirthDateElement(), id);
}
private Identifier chooseId(Identifier oldId, Identifier newId) {
if (oldId == null) {
return newId;
}
if (newId == null) {
return oldId;
}
return isPreferred(newId.getUse(), oldId.getUse()) ? newId : oldId;
}
private boolean isPreferred(IdentifierUse newUse, IdentifierUse oldUse) {
if (newUse == null && oldUse == null || newUse == oldUse) {
return false;
}
if (newUse == null) {
return true;
}
switch (newUse) {
case NULL: return !existsInList(oldUse, IdentifierUse.OFFICIAL, IdentifierUse.USUAL);
case OFFICIAL: return !existsInList(oldUse, IdentifierUse.USUAL);
case OLD: return !existsInList(oldUse, IdentifierUse.OFFICIAL, IdentifierUse.SECONDARY, IdentifierUse.USUAL);
case SECONDARY: return !existsInList(oldUse, IdentifierUse.OFFICIAL, IdentifierUse.USUAL);
case TEMP: return !existsInList(oldUse, IdentifierUse.OFFICIAL, IdentifierUse.SECONDARY, IdentifierUse.USUAL);
case USUAL: return true;
default: return false;
}
}
private boolean existsInList(IdentifierUse oldUse, IdentifierUse... values) {
for (IdentifierUse value : values) {
if (value == oldUse) {
return true;
}
}
return false;
}
private HumanName chooseName(HumanName oldName, HumanName newName) {
if (oldName == null) {
return newName;
}
if (newName == null) {
return oldName;
}
return isPreferred(newName.getUse(), oldName.getUse()) ? newName : oldName;
}
private boolean isPreferred(NameUse newUse, NameUse oldUse) {
if (newUse == null && oldUse == null || newUse == oldUse) {
return false;
}
if (newUse == null) {
return true;
}
switch (oldUse) {
case ANONYMOUS: return existsInList(newUse, NameUse.OFFICIAL, NameUse.USUAL);
case MAIDEN: return existsInList(newUse, NameUse.OFFICIAL, NameUse.USUAL);
case NICKNAME: return existsInList(newUse, NameUse.OFFICIAL, NameUse.USUAL);
case NULL: return existsInList(newUse, NameUse.OFFICIAL, NameUse.USUAL);
case OFFICIAL: return existsInList(newUse, NameUse.USUAL);
case OLD: return existsInList(newUse, NameUse.OFFICIAL, NameUse.USUAL);
case TEMP: return existsInList(newUse, NameUse.OFFICIAL, NameUse.USUAL);
case USUAL: return false;
}
return false;
}
private boolean existsInList(NameUse oldUse, NameUse... values) {
for (NameUse value : values) {
if (value == oldUse) {
return true;
}
}
return false;
}
@Override
public String display(ResourceWrapper pat) throws UnsupportedEncodingException, IOException {
Identifier id = null;
PropertyWrapper pw = getProperty(pat, "identifier");
for (BaseWrapper t : pw.getValues()) {
id = chooseId(id, (Identifier) t.getBase());
}
pw = getProperty(pat, "name");
HumanName n = null;
for (BaseWrapper t : pw.getValues()) {
n = chooseName(n, (HumanName) t);
}
String gender = null;
pw = getProperty(pat, "gender");
if (valued(pw)) {
pw.value().getBase().primitiveValue();
}
DateType dt = null;
pw = getProperty(pat, "birthDate");
if (valued(pw)) {
dt = (DateType) pw.value().getBase();
}
return display(n, gender, dt, id);
}
public void describe(XhtmlNode x, ResourceWrapper pat) throws UnsupportedEncodingException, IOException {
Identifier id = null;
PropertyWrapper pw = getProperty(pat, "identifier");
for (BaseWrapper t : pw.getValues()) {
id = chooseId(id, (Identifier) t.getBase());
}
pw = getProperty(pat, "name");
HumanName n = null;
for (BaseWrapper t : pw.getValues()) {
n = chooseName(n, (HumanName) t.getBase());
}
String gender = null;
pw = getProperty(pat, "gender");
if (valued(pw)) {
pw.value().getBase().primitiveValue();
}
DateType dt = null;
pw = getProperty(pat, "birthDate");
if (valued(pw)) {
dt = (DateType) pw.value().getBase();
}
describe(x, n, gender, dt, id);
}
private String display(HumanName name, String gender, DateType dob, Identifier id) {
StringBuilder b = new StringBuilder();
b.append(display(name));
b.append(" ");
b.append(gender);
b.append(" ");
b.append(display(dob));
if (id != null) {
b.append(" ( ");
b.append(display(id));
b.append(")");
}
return b.toString();
}
public void describe(XhtmlNode x, HumanName name, String gender, DateType dob, Identifier id) throws UnsupportedEncodingException, IOException {
render(x.b(), name);
x.tx(" ");
x.tx(gender);
x.tx(" ");
render(x, dob);
if (id != null) {
x.tx(" ( ");
render(x, id);
x.tx(")");
}
}
}

View File

@ -92,7 +92,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
}
@Override
public boolean render(XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException {
public boolean render(XhtmlNode x, Resource r) throws FHIRFormatError, DefinitionException, IOException {
return render(x, new DirectWrappers.ResourceWrapperDirect(context, r));
}
@ -109,7 +109,6 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
}
containedIds.clear();
generateByProfile(r, sd, r.root(), sd.getSnapshot().getElement(), ed, context.getProfileUtilities().getChildList(sd, ed), x, r.fhirType(), false, 0);
} catch (Exception e) {
e.printStackTrace();
x.para().b().style("color: maroon").tx("Exception generating Narrative: "+e.getMessage());
@ -121,6 +120,12 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
public String display(Resource r) throws UnsupportedEncodingException, IOException {
return "todo";
}
@Override
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
return "Not done yet";
}
//
// public void inject(Element er, XhtmlNode x, NarrativeStatus status, boolean pretty) {
// if (!x.hasAttribute("xmlns"))

View File

@ -11,6 +11,7 @@ import org.hl7.fhir.r5.model.Reference;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
public class ProvenanceRenderer extends ResourceRenderer {
@ -19,7 +20,7 @@ public class ProvenanceRenderer extends ResourceRenderer {
super(context);
}
public boolean render(XhtmlNode x, DomainResource prv) throws UnsupportedEncodingException, IOException {
public boolean render(XhtmlNode x, Resource prv) throws UnsupportedEncodingException, IOException {
return render(x, (Provenance) prv);
}
@ -149,5 +150,10 @@ public class ProvenanceRenderer extends ResourceRenderer {
public String display(Provenance prv) throws UnsupportedEncodingException, IOException {
return "Provenance for "+displayReference(prv, prv.getTargetFirstRep());
}
@Override
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
return "Not done yet";
}
}

View File

@ -42,7 +42,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
super(context);
}
public boolean render(XhtmlNode x, DomainResource q) throws UnsupportedEncodingException, IOException {
public boolean render(XhtmlNode x, Resource q) throws UnsupportedEncodingException, IOException {
return render(x, (Questionnaire) q);
}

View File

@ -44,7 +44,7 @@ public class QuestionnaireResponseRenderer extends ResourceRenderer {
super(context);
}
public boolean render(XhtmlNode x, DomainResource q) throws UnsupportedEncodingException, IOException {
public boolean render(XhtmlNode x, Resource q) throws UnsupportedEncodingException, IOException {
return render(x, (QuestionnaireResponse) q);
}
@ -850,4 +850,9 @@ public class QuestionnaireResponseRenderer extends ResourceRenderer {
return "todo";
}
@Override
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
return "Not done yet";
}
}

View File

@ -0,0 +1,23 @@
package org.hl7.fhir.r5.renderers;
/**
* Rendering framework:
*
* * boolean render(DomainResource) : produce an HTML representation suitable for runtime / documentation, and insert it into the resource. Return true of any extensions encountered
* * boolean render(XhtmlNode, Resource: produce an HTML representation, and fill out the provided node with it. Return true of any extensions encountered
* * XhtmlNode build(DomainResource): same as render(DomainResource) but also return the XHtmlNode
*
* * String display(Base) : produce a plan text concise representation that serves to describe the resource
* * void display(XhtmlNode, Base) : produce a plan text concise representation that serves to describe the resource
*
* * void describe(XhtmlNode, Resource) : produce a short summary of the resource with key details presented (potentially more verbose than display, but still suitable for a single line)
*
* if not specific code for rendering a resource has been provided, and there's no liquid script to guide it, a generic rendering based onthe profile will be performed
*
* @author graha
*
*/
public class Renderer {
}

View File

@ -81,18 +81,23 @@ public abstract class ResourceRenderer extends DataRenderer {
return x;
}
public abstract boolean render(XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome;
public abstract boolean render(XhtmlNode x, Resource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome;
public boolean render(XhtmlNode x, ResourceWrapper r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
ProfileDrivenRenderer pr = new ProfileDrivenRenderer(context);
return pr.render(x, r);
}
public void describe(XhtmlNode x, DomainResource r) throws UnsupportedEncodingException, IOException {
public void describe(XhtmlNode x, Resource r) throws UnsupportedEncodingException, IOException {
x.tx(display(r));
}
public void describe(XhtmlNode x, ResourceWrapper r) throws UnsupportedEncodingException, IOException {
x.tx(display(r));
}
public abstract String display(Resource r) throws UnsupportedEncodingException, IOException;
public abstract String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException;
public static void inject(DomainResource r, XhtmlNode x, NarrativeStatus status) {
if (!x.hasAttribute("xmlns"))
@ -152,7 +157,12 @@ public abstract class ResourceRenderer extends DataRenderer {
new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), true, r.getReference().startsWith("#"));
}
} else if (tr != null && tr.getResource() != null) {
new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), r.getReference().startsWith("#"), r.getReference().startsWith("#"));
if (tr.getReference().startsWith("#")) {
// we already rendered this in this page
c.tx("See above ("+tr.getResource().fhirType()+"/"+tr.getResource().getId()+")");
} else {
new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), r.getReference().startsWith("#"), r.getReference().startsWith("#"));
}
} else {
c.addText(r.getReference());
}
@ -215,7 +225,7 @@ public abstract class ResourceRenderer extends DataRenderer {
} else {
bundleUrl = "#" +fullUrlToAnchor(bundleElement.getChildValue("fullUrl"));
}
return new ResourceWithReference(bundleUrl, new ResourceWrapperMetaElement(this.context, bundleElement));
return new ResourceWithReference(bundleUrl, new ResourceWrapperMetaElement(this.context, br));
}
}
@ -256,6 +266,14 @@ public abstract class ResourceRenderer extends DataRenderer {
return null;
}
protected PropertyWrapper getProperty(BaseWrapper res, String name) {
for (PropertyWrapper t : res.children()) {
if (t.getName().equals(name))
return t;
}
return null;
}
protected boolean valued(PropertyWrapper pw) {
return pw != null && pw.hasValues();
}

View File

@ -9,6 +9,7 @@ import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
@ -22,7 +23,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
super(context, rcontext);
}
public boolean render(XhtmlNode x, DomainResource dr) throws FHIRFormatError, DefinitionException, IOException {
public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException {
return render(x, (StructureDefinition) dr);
}
@ -44,4 +45,14 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
return ((StructureDefinition) r).present();
}
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
if (r.has("title")) {
return r.children("title").get(0).getBase().primitiveValue();
}
if (r.has("name")) {
return r.children("name").get(0).getBase().primitiveValue();
}
return "??";
}
}

View File

@ -23,6 +23,7 @@ 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.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
@ -44,6 +45,16 @@ public abstract class TerminologyRenderer extends ResourceRenderer {
return ((CanonicalResource) r).present();
}
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
if (r.has("title")) {
return r.children("title").get(0).getBase().primitiveValue();
}
if (r.has("name")) {
return r.children("name").get(0).getBase().primitiveValue();
}
return "??";
}
protected class TargetElementComponentWrapper {
protected ConceptMapGroupComponent group;
protected TargetElementComponent comp;

View File

@ -59,7 +59,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
private List<ConceptMapRenderInstructions> renderingMaps = new ArrayList<ConceptMapRenderInstructions>();
public boolean render(XhtmlNode x, DomainResource dr) throws FHIRFormatError, DefinitionException, IOException {
public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException {
return render(x, (ValueSet) dr, false);
}