WIP: rewrite of rendering framework
This commit is contained in:
parent
7d0c63611f
commit
506dad8752
File diff suppressed because it is too large
Load Diff
|
@ -150,6 +150,11 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
|
|||
public boolean render(XhtmlNode x, DiagnosticReport dr) throws IOException, FHIRException, EOperationOutcome {
|
||||
render(x, new DirectWrappers.ResourceWrapperDirect(this.context, dr));
|
||||
|
||||
for (Resource resource : dr.getContained()) {
|
||||
x.hr();
|
||||
RendererFactory.factory(resource, context).render(x, resource);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -461,7 +466,9 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
|
|||
td = tr.td();
|
||||
pw = getProperty(obs, "note");
|
||||
if (valued(pw)) {
|
||||
render(td, pw.value());
|
||||
for (BaseWrapper b : pw.getValues()) {
|
||||
render(td, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (effectiveTime) {
|
||||
|
|
|
@ -73,7 +73,6 @@ import org.hl7.fhir.r5.renderers.utils.DirectWrappers.PropertyWrapperDirect;
|
|||
import org.hl7.fhir.r5.renderers.utils.DirectWrappers.ResourceWrapperDirect;
|
||||
import org.hl7.fhir.r5.renderers.utils.ElementWrappers;
|
||||
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.r5.utils.ToolingExtensions;
|
||||
|
@ -286,7 +285,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
|||
//
|
||||
|
||||
|
||||
public void generateResourceSummary(XhtmlNode x, ResourceWrapper res, boolean textAlready, boolean showCodeDetails, boolean canLink) throws FHIRException, UnsupportedEncodingException, IOException {
|
||||
public void generateResourceSummary(XhtmlNode x, ResourceElement res, boolean textAlready, boolean showCodeDetails, boolean canLink) throws FHIRException, UnsupportedEncodingException, IOException {
|
||||
if (!textAlready) {
|
||||
XhtmlNode div = res.getNarrative();
|
||||
if (div != null) {
|
||||
|
|
|
@ -37,6 +37,18 @@ import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
|||
*/
|
||||
public class Renderer {
|
||||
|
||||
public static class RenderingStatus {
|
||||
private boolean extensions;
|
||||
|
||||
public void setExtensions(boolean b) {
|
||||
extensions = b;
|
||||
}
|
||||
|
||||
public boolean getExtensions() {
|
||||
return extensions;
|
||||
}
|
||||
|
||||
}
|
||||
protected RenderingContext context;
|
||||
|
||||
public Renderer(RenderingContext context) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import org.hl7.fhir.r5.model.DomainResource;
|
|||
import org.hl7.fhir.r5.model.Resource;
|
||||
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.renderers.utils.ResourceElement;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class RendererFactory {
|
||||
|
@ -62,14 +62,14 @@ public class RendererFactory {
|
|||
}
|
||||
|
||||
|
||||
public static ResourceRenderer factory(ResourceWrapper resource, RenderingContext context, ResourceContext resourceContext) {
|
||||
public static ResourceRenderer factory(ResourceElement resource, RenderingContext context) {
|
||||
if (context.getTemplateProvider() != null) {
|
||||
String liquidTemplate = context.getTemplateProvider().findTemplate(context, resource.getName());
|
||||
String liquidTemplate = context.getTemplateProvider().findTemplate(context, resource.fhirType());
|
||||
if (liquidTemplate != null) {
|
||||
return new LiquidRenderer(context, liquidTemplate);
|
||||
}
|
||||
}
|
||||
switch (resource.getName()) {
|
||||
switch (resource.fhirType()) {
|
||||
case "DiagnosticReport": return new DiagnosticReportRenderer(context);
|
||||
case "Library": return new LibraryRenderer(context);
|
||||
case "List": return new ListRenderer(context);
|
||||
|
@ -77,11 +77,11 @@ public class RendererFactory {
|
|||
case "QuestionnaireResponse": return new QuestionnaireResponseRenderer(context);
|
||||
}
|
||||
|
||||
return new ProfileDrivenRenderer(context, resourceContext);
|
||||
return new ProfileDrivenRenderer(context);
|
||||
}
|
||||
|
||||
public static ResourceRenderer factory(ResourceWrapper rw, RenderingContext lrc) {
|
||||
return factory(rw, lrc, null);
|
||||
return factory(rw, lrc);
|
||||
}
|
||||
|
||||
public static boolean hasSpecificRenderer(String rt) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.hl7.fhir.r5.renderers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
|
@ -24,6 +25,7 @@ import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
|
|||
import org.hl7.fhir.r5.model.Extension;
|
||||
import org.hl7.fhir.r5.model.Narrative;
|
||||
import org.hl7.fhir.r5.model.PrimitiveType;
|
||||
import org.hl7.fhir.r5.model.Property;
|
||||
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
|
||||
import org.hl7.fhir.r5.model.Reference;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
|
@ -34,9 +36,9 @@ import org.hl7.fhir.r5.renderers.utils.DirectWrappers.ResourceWrapperDirect;
|
|||
import org.hl7.fhir.r5.renderers.utils.ElementWrappers.ResourceWrapperMetaElement;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceReferenceKind;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference;
|
||||
import org.hl7.fhir.r5.renderers.utils.ResourceElement;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
||||
import org.hl7.fhir.r5.utils.EOperationOutcome;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
|
@ -54,7 +56,6 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
|
||||
}
|
||||
|
||||
protected ResourceContext rcontext;
|
||||
protected XVerExtensionManager xverManager;
|
||||
protected boolean multiLangMode;
|
||||
|
||||
|
@ -63,21 +64,6 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
super(context);
|
||||
}
|
||||
|
||||
public ResourceRenderer(RenderingContext context, ResourceContext rcontext) {
|
||||
super(context);
|
||||
this.rcontext = rcontext;
|
||||
}
|
||||
|
||||
public ResourceContext getRcontext() {
|
||||
return rcontext;
|
||||
}
|
||||
|
||||
public ResourceRenderer setRcontext(ResourceContext rcontext) {
|
||||
this.rcontext = rcontext;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public boolean isMultiLangMode() {
|
||||
return multiLangMode;
|
||||
}
|
||||
|
@ -87,13 +73,16 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
return this;
|
||||
}
|
||||
|
||||
public XhtmlNode build(Resource dr) throws FHIRFormatError, DefinitionException, FHIRException, IOException, EOperationOutcome {
|
||||
public XhtmlNode build(ResourceElement dr) throws FHIRFormatError, DefinitionException, FHIRException, IOException, EOperationOutcome {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
render(x, dr);
|
||||
renderResource(new RenderingStatus(), x, dr);
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* given a resource, update it's narrative with the best rendering available
|
||||
* given a resource, update it's narrative with the best rendering available.
|
||||
*
|
||||
* Explanation about native vs wrapped
|
||||
*
|
||||
* @param r - the domain resource in question
|
||||
*
|
||||
|
@ -101,39 +90,33 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
* @throws EOperationOutcome
|
||||
* @throws FHIRException
|
||||
*/
|
||||
|
||||
public void render(DomainResource r) throws IOException, FHIRException, EOperationOutcome {
|
||||
public void renderResource(DomainResource r) throws IOException, FHIRException, EOperationOutcome {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
boolean hasExtensions;
|
||||
hasExtensions = render(x, r);
|
||||
RenderingStatus status = new RenderingStatus();
|
||||
renderResource(status, x, r);
|
||||
String an = r.fhirType()+"_"+r.getId();
|
||||
if (context.isAddName()) {
|
||||
if (!hasAnchorName(x, an)) {
|
||||
injectAnchorName(x, an);
|
||||
}
|
||||
}
|
||||
inject(r, x, hasExtensions ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
|
||||
inject(r, x, status.getExtensions() ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
|
||||
}
|
||||
|
||||
public XhtmlNode render(ResourceWrapper r) throws IOException, FHIRException, EOperationOutcome {
|
||||
assert r.getContext() == context;
|
||||
public void renderResource(ResourceElement r) throws IOException, FHIRException, EOperationOutcome {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
boolean hasExtensions = render(x, r);
|
||||
|
||||
RenderingStatus status = new RenderingStatus();
|
||||
renderResource(status, x, r);
|
||||
String an = r.fhirType()+"_"+r.getId();
|
||||
if (context.isAddName()) {
|
||||
if (!hasAnchorName(x, an)) {
|
||||
injectAnchorName(x, an);
|
||||
}
|
||||
}
|
||||
if (r.hasNarrative()) {
|
||||
r.injectNarrative(this, x, hasExtensions ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
|
||||
}
|
||||
return x;
|
||||
inject(r, x, status.getExtensions() ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
|
||||
}
|
||||
|
||||
public XhtmlNode checkNarrative(ResourceWrapper r) throws IOException, FHIRException, EOperationOutcome {
|
||||
assert r.getContext() == context;
|
||||
public XhtmlNode checkNarrative(ResourceElement r) throws IOException, FHIRException, EOperationOutcome {
|
||||
XhtmlNode x = r.getNarrative();
|
||||
String an = r.fhirType()+"_"+r.getId();
|
||||
if (context.isAddName()) {
|
||||
|
@ -166,24 +149,35 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
return false;
|
||||
}
|
||||
|
||||
public abstract boolean render(XhtmlNode x, Resource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome;
|
||||
// these three are what the descendants of this class override
|
||||
public abstract void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome;
|
||||
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
|
||||
renderResource(status, x, new ResourceElement(context.getContextUtilities(), context.getProfileUtilities(), r));
|
||||
}
|
||||
public abstract String displayResource(ResourceElement r) throws UnsupportedEncodingException, IOException;
|
||||
|
||||
public boolean render(XhtmlNode x, ResourceWrapper r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
|
||||
ProfileDrivenRenderer pr = new ProfileDrivenRenderer(context);
|
||||
return pr.render(x, r);
|
||||
|
||||
public String canonicalTitle(ResourceElement r) {
|
||||
if (r.has("title")) {
|
||||
return r.primitiveValue("title");
|
||||
}
|
||||
if (r.has("name")) {
|
||||
return r.primitiveValue("name");
|
||||
}
|
||||
if (r.has("id")) {
|
||||
return r.primitiveValue("id");
|
||||
}
|
||||
return "??";
|
||||
}
|
||||
|
||||
public void describe(XhtmlNode x, Resource r) throws UnsupportedEncodingException, IOException {
|
||||
x.tx(display(r));
|
||||
public void describe(XhtmlNode x, ResourceElement r) throws UnsupportedEncodingException, IOException {
|
||||
x.tx(displayDataType(r));
|
||||
}
|
||||
|
||||
public void describe(XhtmlNode x, ResourceWrapper r) throws UnsupportedEncodingException, IOException {
|
||||
x.tx(display(r));
|
||||
public void inject(ResourceElement r, XhtmlNode x, NarrativeStatus status) {
|
||||
r.setNarrative(x, status.toCode(), multiLangMode, context.getLocale());
|
||||
}
|
||||
|
||||
public abstract String display(Resource r) throws UnsupportedEncodingException, IOException;
|
||||
public abstract String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException;
|
||||
|
||||
public void inject(DomainResource r, XhtmlNode x, NarrativeStatus status) {
|
||||
r.getText().setUserData("renderer.generated", true);
|
||||
if (!r.hasText() || !r.getText().hasDiv()) {
|
||||
|
@ -212,20 +206,23 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
public void renderCanonical(Resource res, XhtmlNode x, String url) throws UnsupportedEncodingException, IOException {
|
||||
ResourceWrapper rw = new ResourceWrapperDirect(this.context, res);
|
||||
renderCanonical(rw, x, url);
|
||||
public void markLanguage(XhtmlNode x) {
|
||||
x.setAttribute("lang", context.getLocale().toString());
|
||||
x.setAttribute("xml:lang", context.getLocale().toString());
|
||||
x.addTag(0, "hr");
|
||||
x.addTag(0, "p").b().tx(context.getLocale().getDisplayName());
|
||||
x.addTag(0, "hr");
|
||||
}
|
||||
|
||||
public void renderCanonical(ResourceWrapper rw, XhtmlNode x, String url) throws UnsupportedEncodingException, IOException {
|
||||
renderCanonical(rw, x, url, true, rw.getResource());
|
||||
public void renderCanonical(ResourceElement res, XhtmlNode x, String url) throws UnsupportedEncodingException, IOException {
|
||||
renderCanonical(res, x, url, true, res);
|
||||
}
|
||||
|
||||
public void renderCanonical(ResourceWrapper rw, XhtmlNode x, String url, boolean allowLinks, Resource src) throws UnsupportedEncodingException, IOException {
|
||||
public void renderCanonical(ResourceElement rw, XhtmlNode x, String url, boolean allowLinks, ResourceElement src) throws UnsupportedEncodingException, IOException {
|
||||
if (url == null) {
|
||||
return;
|
||||
}
|
||||
Resource target = context.getWorker().fetchResource(Resource.class, url, src);
|
||||
Resource target = context.getWorker().fetchResource(Resource.class, url, src.getResource());
|
||||
if (target == null || !(target instanceof CanonicalResource)) {
|
||||
x.code().tx(url);
|
||||
} else {
|
||||
|
@ -249,56 +246,65 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
public void render(Resource res, XhtmlNode x, DataType type) throws FHIRFormatError, DefinitionException, IOException {
|
||||
if (type instanceof Reference) {
|
||||
renderReference(res, x, (Reference) type);
|
||||
} else if (type instanceof CodeableReference) {
|
||||
CodeableReference cr = (CodeableReference) type;
|
||||
if (cr.hasReference()) {
|
||||
renderReference(res, x, cr.getReference());
|
||||
public void renderReference(RenderingStatus status, ResourceElement res, XhtmlNode x, ResourceElement type) throws FHIRFormatError, DefinitionException, IOException {
|
||||
if (type.fhirType().equals("Reference")) {
|
||||
renderReference(status, res, x, type);
|
||||
} else if (type.fhirType().equals("CodeableReference")) {
|
||||
if (type.has("reference")) {
|
||||
renderReference(status, res, x, type, true);
|
||||
} else {
|
||||
render(x, type);
|
||||
renderDataType(status, x, type);
|
||||
}
|
||||
} else {
|
||||
render(x, type);
|
||||
renderDataType(status, x, type);
|
||||
}
|
||||
}
|
||||
|
||||
public void render(ResourceWrapper res, XhtmlNode x, DataType type) throws FHIRFormatError, DefinitionException, IOException {
|
||||
if (type instanceof Reference) {
|
||||
renderReference(res, x, (Reference) type);
|
||||
} else if (type instanceof CodeableReference) {
|
||||
CodeableReference cr = (CodeableReference) type;
|
||||
if (cr.hasReference()) {
|
||||
renderReference(res, x, cr.getReference());
|
||||
/*
|
||||
* } else if (ew.fhirType().equals("Reference")) {
|
||||
Reference r = (Reference) e;
|
||||
if (r.getReference() != null && r.getReference().contains("#")) {
|
||||
if (containedIds.contains(r.getReference().substring(1))) {
|
||||
x.ah("#hc"+r.getReference().substring(1)).tx("See "+r.getReference());
|
||||
} else {
|
||||
render(x, type);
|
||||
// in this case, we render the resource in line
|
||||
ResourceWrapper rw = null;
|
||||
for (ResourceWrapper t : res.getContained()) {
|
||||
if (r.getReference().substring(1).equals(t.getId())) {
|
||||
rw = t;
|
||||
}
|
||||
}
|
||||
if (rw == null) {
|
||||
renderReference(res, x, r);
|
||||
} else {
|
||||
String ref = context.getResolver() != null ?context.getResolver().urlForContained(context, res.fhirType(), res.getId(), rw.fhirType(), rw.getId()) : null;
|
||||
if (ref == null) {
|
||||
x.an("hc"+rw.getId());
|
||||
RenderingContext ctxtc = context.copy();
|
||||
ctxtc.setAddGeneratedNarrativeHeader(false);
|
||||
ctxtc.setContained(true);
|
||||
ResourceRenderer rr = RendererFactory.factory(rw, ctxtc);
|
||||
rr.setRcontext(new ResourceContext(rcontext, rw));
|
||||
rr.render(parent.blockquote(), rw);
|
||||
} else {
|
||||
x.ah(ref).tx("See "+rw.fhirType());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
render(x, type);
|
||||
renderReference(res, x, r);
|
||||
}
|
||||
}
|
||||
|
||||
public void renderReference(Resource res, XhtmlNode x, Reference r) throws UnsupportedEncodingException, IOException {
|
||||
ResourceWrapper rw = new ResourceWrapperDirect(this.context, res);
|
||||
renderReference(rw, x, r);
|
||||
}
|
||||
|
||||
public void renderReference(ResourceWrapper rw, XhtmlNode x, Reference r) throws UnsupportedEncodingException, IOException {
|
||||
renderReference(rw, x, r, true);
|
||||
}
|
||||
|
||||
*/
|
||||
public void renderReference(Resource res, HierarchicalTableGenerator gen, List<Piece> pieces, Reference r, boolean allowLinks) throws UnsupportedEncodingException, IOException {
|
||||
if (r == null) {
|
||||
pieces.add(gen.new Piece(null, "null!", null));
|
||||
return;
|
||||
}
|
||||
ResourceWrapper rw = new ResourceWrapperDirect(this.context, res);
|
||||
ResourceWithReference tr = null;
|
||||
String link = null;
|
||||
StringBuilder text = new StringBuilder();
|
||||
if (r.hasReferenceElement() && allowLinks) {
|
||||
tr = resolveReference(rw, r.getReference());
|
||||
tr = resolveReference(new ResourceElement(context.getContextUtilities(), context.getProfileUtilities(), res), r.getReference());
|
||||
|
||||
if (!r.getReference().startsWith("#")) {
|
||||
if (tr != null && tr.getReference() != null) {
|
||||
|
@ -315,13 +321,13 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
}
|
||||
// what to display: if text is provided, then that. if the reference was resolved, then show the name, or the generated narrative
|
||||
String display = r.hasDisplayElement() ? r.getDisplay() : null;
|
||||
String name = tr != null && tr.getResource() != null ? tr.getResource().getNameFromResource() : null;
|
||||
String name = tr != null && tr.getResource() != null ? getNameForResource(tr.getResource()) : null;
|
||||
|
||||
if (display == null && (tr == null || tr.getResource() == null)) {
|
||||
if (!Utilities.noString(r.getReference())) {
|
||||
text.append(r.getReference());
|
||||
} else if (r.hasIdentifier()) {
|
||||
text.append(displayIdentifier(r.getIdentifier()));
|
||||
text.append(displayIdentifier(new ResourceElement(context.getContextUtilities(), context.getProfileUtilities(), r.getIdentifier())));
|
||||
} else {
|
||||
text.append("??");
|
||||
}
|
||||
|
@ -364,7 +370,31 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
pieces.add(gen.new Piece(link,text.toString(), null));
|
||||
}
|
||||
|
||||
public void renderReference(ResourceWrapper rw, XhtmlNode x, Reference r, boolean allowLinks) throws UnsupportedEncodingException, IOException {
|
||||
private String getNameForResource(ResourceElement resource) {
|
||||
ResourceElement name = resource.firstChild("name");
|
||||
if (name != null && !name.isEmpty()) {
|
||||
if (name.isPrimitive()) {
|
||||
return name.primitiveValue();
|
||||
} else if (name.fhirType().equals("HumanName")) {
|
||||
String family = name.primitiveValue("family");
|
||||
String given = name.firstPrimitiveValue("given");
|
||||
return (family == null) ? given : given == null ? family : family+" "+given;
|
||||
} else {
|
||||
String n = name.primitiveValueMN("name", "text", "value");
|
||||
if (n != null) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
}
|
||||
String n = resource.primitiveValue("productName");
|
||||
if (n == null) {
|
||||
throw new Error("What to render for 'name'? Type is "+resource.fhirType());
|
||||
} else {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
public void renderReference(RenderingStatus status, ResourceElement rw, XhtmlNode x, ResourceElement r, boolean allowLinks) throws UnsupportedEncodingException, IOException {
|
||||
if (r == null) {
|
||||
x.tx("null!");
|
||||
return;
|
||||
|
@ -372,10 +402,11 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
XhtmlNode c = null;
|
||||
ResourceWithReference tr = null;
|
||||
boolean onPage = false;
|
||||
if (r.hasReferenceElement() && allowLinks) {
|
||||
tr = resolveReference(rw, r.getReference());
|
||||
String rref = r.primitiveValue("reference");
|
||||
if (r.has("reference") && allowLinks) {
|
||||
tr = resolveReference(rw, r.primitiveValue("reference"));
|
||||
|
||||
if (!r.getReference().startsWith("#")) {
|
||||
if (!rref.startsWith("#")) {
|
||||
if (tr != null && tr.getReference() != null) {
|
||||
if (tr.getReference().startsWith("#")) {
|
||||
onPage = true;
|
||||
|
@ -387,16 +418,16 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
} else {
|
||||
c = x.ah(tr.getReference());
|
||||
}
|
||||
} else if (r.getReference().contains("?")) {
|
||||
} else if (rref.contains("?")) {
|
||||
x.tx(context.formatPhrase(RenderingContext.RES_REND_COND_REF)+" ");
|
||||
c = x.code("");
|
||||
} else {
|
||||
c = x.ah(r.getReference());
|
||||
c = x.ah(rref);
|
||||
}
|
||||
} else if ("#".equals(r.getReference())) {
|
||||
} else if ("#".equals(rref)) {
|
||||
c = x.ah("#");
|
||||
} else if (context.getRules() == GenerationRules.IG_PUBLISHER || (tr != null && tr.getKind() != ResourceReferenceKind.BUNDLE)) {
|
||||
c = x.ah("#hc"+r.getReference().substring(1));
|
||||
c = x.ah("#hc"+rref.substring(1));
|
||||
onPage = true;
|
||||
} else {
|
||||
c = x;
|
||||
|
@ -408,19 +439,19 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
c.tx(context.formatPhrase(RenderingContext.RES_REND_SEE_ON_THIS_PAGE)+" ");
|
||||
}
|
||||
// what to display: if text is provided, then that. if the reference was resolved, then show the name, or the generated narrative
|
||||
String display = r.hasDisplayElement() ? r.getDisplay() : null;
|
||||
String name = tr != null && tr.getResource() != null ? tr.getResource().getNameFromResource() : null;
|
||||
String display = r.has("display") ? r.primitiveValue("display") : null;
|
||||
String name = tr != null && tr.getResource() != null ? getNameForResource(tr.getResource()) : null;
|
||||
|
||||
if (display == null && (tr == null || tr.getResource() == null)) {
|
||||
if (!Utilities.noString(r.getReference())) {
|
||||
c.addText(r.getReference());
|
||||
} else if (r.hasIdentifier()) {
|
||||
renderIdentifier(c, r.getIdentifier());
|
||||
if (!Utilities.noString(rref)) {
|
||||
c.addText(rref);
|
||||
} else if (r.has("identifier")) {
|
||||
renderIdentifier(status, c, r.child("identifier"));
|
||||
} else {
|
||||
c.addText("??");
|
||||
}
|
||||
} else if (context.isTechnicalMode()) {
|
||||
c.addText(r.getReference());
|
||||
c.addText(rref);
|
||||
if (display != null) {
|
||||
c.addText(": "+display);
|
||||
}
|
||||
|
@ -429,16 +460,16 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
}
|
||||
if (r.hasExtension(ToolingExtensions.EXT_TARGET_ID) || r.hasExtension(ToolingExtensions.EXT_TARGET_PATH)) {
|
||||
x.addText("(");
|
||||
for (Extension ex : r.getExtensionsByUrl(ToolingExtensions.EXT_TARGET_ID)) {
|
||||
if (ex.hasValue()) {
|
||||
for (ResourceElement ex : r.extensions(ToolingExtensions.EXT_TARGET_ID)) {
|
||||
if (ex.has("value")) {
|
||||
x.sep(", ");
|
||||
x.addText("#"+ex.getValue().primitiveValue());
|
||||
x.addText("#"+ex.primitiveValue("value"));
|
||||
}
|
||||
}
|
||||
for (Extension ex : r.getExtensionsByUrl(ToolingExtensions.EXT_TARGET_PATH)) {
|
||||
if (ex.hasValue()) {
|
||||
for (ResourceElement ex : r.extensions(ToolingExtensions.EXT_TARGET_PATH)) {
|
||||
if (ex.has("value")) {
|
||||
x.sep(", ");
|
||||
x.addText("/#"+ex.getValue().primitiveValue());
|
||||
x.addText("/#"+ex.primitiveValue("value"));
|
||||
}
|
||||
}
|
||||
x.addText(")");
|
||||
|
@ -451,48 +482,48 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
} else {
|
||||
c.tx(context.formatPhrase(RenderingContext.RES_REND_GEN_SUM)+" ");
|
||||
if (tr != null) {
|
||||
new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), true, r.getReference().startsWith("#"), true);
|
||||
new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), true, rref.startsWith("#"), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// public void renderReference(ResourceWrapper rw, XhtmlNode x, BaseWrapper r) throws UnsupportedEncodingException, IOException {
|
||||
// XhtmlNode c = x;
|
||||
// ResourceWithReference tr = null;
|
||||
// String v;
|
||||
// if (r.has("reference")) {
|
||||
// v = r.get("reference").primitiveValue();
|
||||
// tr = resolveReference(rw, v);
|
||||
//
|
||||
// if (!v.startsWith("#")) {
|
||||
// if (tr != null && tr.getReference() != null)
|
||||
// c = x.ah(tr.getReference());
|
||||
// else
|
||||
// c = x.ah(v);
|
||||
// }
|
||||
// } else {
|
||||
// v = "";
|
||||
// }
|
||||
// // what to display: if text is provided, then that. if the reference was resolved, then show the generated narrative
|
||||
// if (r.has("display")) {
|
||||
// c.addText(r.get("display").primitiveValue());
|
||||
// if (tr != null && tr.getResource() != null) {
|
||||
// c.tx(context.formatPhrase(RenderingContext.RES_REND_GEN_SUM)+" ");
|
||||
// new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), true, v.startsWith("#"), false);
|
||||
// }
|
||||
// } else if (tr != null && tr.getResource() != null) {
|
||||
// new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), v.startsWith("#"), v.startsWith("#"), false);
|
||||
// } else {
|
||||
// c.addText(v);
|
||||
// }
|
||||
// }
|
||||
|
||||
public void renderReference(ResourceWrapper rw, XhtmlNode x, BaseWrapper r) throws UnsupportedEncodingException, IOException {
|
||||
XhtmlNode c = x;
|
||||
ResourceWithReference tr = null;
|
||||
String v;
|
||||
if (r.has("reference")) {
|
||||
v = r.get("reference").primitiveValue();
|
||||
tr = resolveReference(rw, v);
|
||||
|
||||
if (!v.startsWith("#")) {
|
||||
if (tr != null && tr.getReference() != null)
|
||||
c = x.ah(tr.getReference());
|
||||
else
|
||||
c = x.ah(v);
|
||||
}
|
||||
} else {
|
||||
v = "";
|
||||
}
|
||||
// what to display: if text is provided, then that. if the reference was resolved, then show the generated narrative
|
||||
if (r.has("display")) {
|
||||
c.addText(r.get("display").primitiveValue());
|
||||
if (tr != null && tr.getResource() != null) {
|
||||
c.tx(context.formatPhrase(RenderingContext.RES_REND_GEN_SUM)+" ");
|
||||
new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), true, v.startsWith("#"), false);
|
||||
}
|
||||
} else if (tr != null && tr.getResource() != null) {
|
||||
new ProfileDrivenRenderer(context).generateResourceSummary(c, tr.getResource(), v.startsWith("#"), v.startsWith("#"), false);
|
||||
} else {
|
||||
c.addText(v);
|
||||
}
|
||||
}
|
||||
|
||||
protected ResourceWithReference resolveReference(ResourceWrapper res, String url) {
|
||||
protected ResourceWithReference resolveReference(ResourceElement res, String url) {
|
||||
if (url == null)
|
||||
return null;
|
||||
if (url.startsWith("#") && res != null) {
|
||||
for (ResourceWrapper r : res.getContained()) {
|
||||
for (ResourceElement r : res.children("contained")) {
|
||||
if (r.getId().equals(url.substring(1)))
|
||||
return new ResourceWithReference(ResourceReferenceKind.CONTAINED, url, r);
|
||||
}
|
||||
|
@ -503,7 +534,7 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
version = url.substring(url.indexOf("/_history/")+10);
|
||||
url = url.substring(0, url.indexOf("/_history/"));
|
||||
}
|
||||
|
||||
/*
|
||||
if (rcontext != null) {
|
||||
BundleEntryComponent bundleResource = rcontext.resolve(url);
|
||||
if (bundleResource != null) {
|
||||
|
@ -512,7 +543,7 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
id = makeIdFromBundleEntry(bundleResource.getFullUrl());
|
||||
}
|
||||
String bundleUrl = "#" + bundleResource.getResource().getResourceType().name() + "_" + id;
|
||||
return new ResourceWithReference(ResourceReferenceKind.BUNDLE, bundleUrl, new ResourceWrapperDirect(this.context, bundleResource.getResource()));
|
||||
return new ResourceWithReference(ResourceReferenceKind.BUNDLE, bundleUrl, new ResourceElement(this.context.getContextUtilities(), bundleResource.getResource()));
|
||||
}
|
||||
org.hl7.fhir.r5.elementmodel.Element bundleElement = rcontext.resolveElement(url, version);
|
||||
if (bundleElement != null) {
|
||||
|
@ -527,13 +558,13 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
} else {
|
||||
bundleUrl = "#" +fullUrlToAnchor(bundleElement.getChildValue("fullUrl"));
|
||||
}
|
||||
return new ResourceWithReference(ResourceReferenceKind.BUNDLE, bundleUrl, new ResourceWrapperMetaElement(this.context, br));
|
||||
return new ResourceWithReference(ResourceReferenceKind.BUNDLE, bundleUrl, new ResourceElement(this.context.getContextUtilities(), br));
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
Resource ae = getContext().getWorker().fetchResource(null, url, version);
|
||||
if (ae != null)
|
||||
return new ResourceWithReference(ResourceReferenceKind.EXTERNAL, url, new ResourceWrapperDirect(this.context, ae));
|
||||
return new ResourceWithReference(ResourceReferenceKind.EXTERNAL, url, new ResourceElement(this.context.getContextUtilities(), this.context.getProfileUtilities(), ae));
|
||||
else if (context.getResolver() != null) {
|
||||
return context.getResolver().resolve(context, url);
|
||||
} else
|
||||
|
@ -570,14 +601,6 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
return null;
|
||||
}
|
||||
|
||||
protected PropertyWrapper getProperty(ResourceWrapper res, String name) {
|
||||
for (PropertyWrapper t : res.children()) {
|
||||
if (t.getName().equals(name))
|
||||
return t;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected PropertyWrapper getProperty(BaseWrapper res, String name) {
|
||||
for (PropertyWrapper t : res.children()) {
|
||||
if (t.getName().equals(name))
|
||||
|
@ -591,18 +614,18 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
}
|
||||
|
||||
|
||||
protected ResourceWrapper fetchResource(BaseWrapper subject) throws UnsupportedEncodingException, FHIRException, IOException {
|
||||
if (context.getResolver() == null)
|
||||
return null;
|
||||
|
||||
PropertyWrapper ref = subject.getChildByName("reference");
|
||||
if (ref == null || !ref.hasValues()) {
|
||||
return null;
|
||||
}
|
||||
String url = ref.value().getBase().primitiveValue();
|
||||
ResourceWithReference rr = context.getResolver().resolve(context, url);
|
||||
return rr == null ? null : rr.getResource();
|
||||
}
|
||||
// protected ResourceElement fetchResource(BaseWrapper subject) throws UnsupportedEncodingException, FHIRException, IOException {
|
||||
// if (context.getResolver() == null)
|
||||
// return null;
|
||||
//
|
||||
// PropertyWrapper ref = subject.getChildByName("reference");
|
||||
// if (ref == null || !ref.hasValues()) {
|
||||
// return null;
|
||||
// }
|
||||
// String url = ref.value().getBase().primitiveValue();
|
||||
// ResourceWithReference rr = context.getResolver().resolve(context, url);
|
||||
// return rr == null ? null : rr.getResource();
|
||||
// }
|
||||
|
||||
|
||||
protected String describeStatus(PublicationStatus status, boolean experimental) {
|
||||
|
@ -637,22 +660,23 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
return true;
|
||||
}
|
||||
|
||||
protected void renderResourceHeader(ResourceWrapper r, XhtmlNode x, boolean doId) throws UnsupportedEncodingException, FHIRException, IOException {
|
||||
protected void renderResourceHeader(ResourceElement r, XhtmlNode x, boolean doId) throws UnsupportedEncodingException, FHIRException, IOException {
|
||||
XhtmlNode div = x.div().style("display: inline-block").style("background-color: #d9e0e7").style("padding: 6px")
|
||||
.style("margin: 4px").style("border: 1px solid #8da1b4")
|
||||
.style("border-radius: 5px").style("line-height: 60%");
|
||||
|
||||
String id = getPrimitiveValue(r, "id");
|
||||
RenderingStatus status = new RenderingStatus();
|
||||
String id = r.primitiveValue("id");
|
||||
if (doId) {
|
||||
div.an("hc"+id);
|
||||
}
|
||||
|
||||
String lang = getPrimitiveValue(r, "language");
|
||||
String ir = getPrimitiveValue(r, "implicitRules");
|
||||
BaseWrapper meta = r.getChildByName("meta").hasValues() ? r.getChildByName("meta").getValues().get(0) : null;
|
||||
String versionId = getPrimitiveValue(meta, "versionId");
|
||||
String lastUpdated = getPrimitiveValue(meta, "lastUpdated");
|
||||
String source = getPrimitiveValue(meta, "source");
|
||||
String lang = r.primitiveValue("language");
|
||||
String ir = r.primitiveValue("implicitRules");
|
||||
ResourceElement meta = r.has("meta") && r.child("meta").isEmpty() ? r.child("meta") : null;
|
||||
ResourceElement versionId = meta == null ? null : meta.child("versionId");
|
||||
ResourceElement lastUpdated = meta == null ? null : meta.child("lastUpdated");
|
||||
ResourceElement source = meta == null ? null : meta.child("source");
|
||||
|
||||
if (id != null || lang != null || versionId != null || lastUpdated != null) {
|
||||
XhtmlNode p = plateStyle(div.para());
|
||||
|
@ -667,7 +691,7 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
}
|
||||
if (lastUpdated != null) {
|
||||
p.tx(context.formatPhrase(RenderingContext.RES_REND_UPDATED) + "\"");
|
||||
renderDateTime(p, lastUpdated);
|
||||
renderDataType(status, p, lastUpdated);
|
||||
p.tx("\" ");
|
||||
}
|
||||
if (lang != null) {
|
||||
|
@ -681,42 +705,34 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
plateStyle(div.para()).tx(context.formatPhrase(RenderingContext.RES_REND_INFO_SOURCE) + " "+source+"!");
|
||||
}
|
||||
if (meta != null) {
|
||||
PropertyWrapper pl = meta.getChildByName("profile");
|
||||
if (pl.hasValues()) {
|
||||
List<ResourceElement> items = meta.children("profile");
|
||||
if (!items.isEmpty()) {
|
||||
XhtmlNode p = plateStyle(div.para());
|
||||
p.tx(Utilities.pluralize(context.formatPhrase(RenderingContext.GENERAL_PROF), pl.getValues().size())+": ");
|
||||
p.tx(Utilities.pluralize(context.formatPhrase(RenderingContext.GENERAL_PROF), items.size())+": ");
|
||||
boolean first = true;
|
||||
for (BaseWrapper bw : pl.getValues()) {
|
||||
for (ResourceElement bw : items) {
|
||||
if (first) first = false; else p.tx(", ");
|
||||
renderCanonical(r, p, bw.getBase().primitiveValue());
|
||||
renderCanonical(r, p, bw.primitiveValue());
|
||||
}
|
||||
}
|
||||
PropertyWrapper tl = meta.getChildByName("tag");
|
||||
if (tl.hasValues()) {
|
||||
items = meta.children("tag");
|
||||
if (!items.isEmpty()) {
|
||||
XhtmlNode p = plateStyle(div.para());
|
||||
p.tx(Utilities.pluralize(context.formatPhrase(RenderingContext.RES_REND_TAG), tl.getValues().size())+": ");
|
||||
p.tx(Utilities.pluralize(context.formatPhrase(RenderingContext.RES_REND_TAG), items.size())+": ");
|
||||
boolean first = true;
|
||||
for (BaseWrapper bw : tl.getValues()) {
|
||||
for (ResourceElement bw : items) {
|
||||
if (first) first = false; else p.tx(", ");
|
||||
String system = getPrimitiveValue(bw, "system");
|
||||
String version = getPrimitiveValue(bw, "version");
|
||||
String code = getPrimitiveValue(bw, "system");
|
||||
String display = getPrimitiveValue(bw, "system");
|
||||
renderCoding(p, new Coding(system, version, code, display));
|
||||
renderCoding(status, p, bw);
|
||||
}
|
||||
}
|
||||
PropertyWrapper sl = meta.getChildByName("security");
|
||||
if (sl.hasValues()) {
|
||||
items = meta.children("security");
|
||||
if (!items.isEmpty()) {
|
||||
XhtmlNode p = plateStyle(div.para());
|
||||
p.tx(Utilities.pluralize(context.formatPhrase(RenderingContext.GENERAL_SECURITY_LABEL), tl.getValues().size())+": ");
|
||||
p.tx(Utilities.pluralize(context.formatPhrase(RenderingContext.GENERAL_SECURITY_LABEL), items.size())+": ");
|
||||
boolean first = true;
|
||||
for (BaseWrapper bw : sl.getValues()) {
|
||||
for (ResourceElement bw : items) {
|
||||
if (first) first = false; else p.tx(", ");
|
||||
String system = getPrimitiveValue(bw, "system");
|
||||
String version = getPrimitiveValue(bw, "version");
|
||||
String code = getPrimitiveValue(bw, "system");
|
||||
String display = getPrimitiveValue(bw, "system");
|
||||
renderCoding(p, new Coding(system, version, code, display));
|
||||
renderCoding(status, p, bw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -735,27 +751,27 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
return r.has(name) && r.getChildByName(name).hasValues() ? r.getChildByName(name).getValues().get(0).getBase().primitiveValue() : null;
|
||||
}
|
||||
|
||||
public void renderOrError(DomainResource dr) {
|
||||
try {
|
||||
render(dr);
|
||||
} catch (Exception e) {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
x.para().tx(context.formatPhrase(RenderingContext.RES_REND_ERROR, e.getMessage())+" ");
|
||||
dr.setText(null);
|
||||
inject(dr, x, NarrativeStatus.GENERATED);
|
||||
}
|
||||
|
||||
}
|
||||
// public void renderOrError(DomainResource dr) {
|
||||
// try {
|
||||
// render(dr);
|
||||
// } catch (Exception e) {
|
||||
// XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
// x.para().tx(context.formatPhrase(RenderingContext.RES_REND_ERROR, e.getMessage())+" ");
|
||||
// dr.setText(null);
|
||||
// inject(dr, x, NarrativeStatus.GENERATED);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
public RendererType getRendererType() {
|
||||
return RendererType.NATIVE;
|
||||
}
|
||||
|
||||
public class TableRowData {
|
||||
private Map<String, List<DataType>> cols = new HashMap<>();
|
||||
private Map<String, List<ResourceElement>> cols = new HashMap<>();
|
||||
private TableData data;
|
||||
|
||||
public void value(String name, DataType value) {
|
||||
public void value(String name, ResourceElement value) {
|
||||
if (!cols.containsKey(name)) {
|
||||
cols.put(name, new ArrayList<>());
|
||||
}
|
||||
|
@ -769,7 +785,7 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
return cols.containsKey(name);
|
||||
}
|
||||
|
||||
public List<DataType> get(String name) {
|
||||
public List<ResourceElement> get(String name) {
|
||||
return cols.get(name);
|
||||
}
|
||||
|
||||
|
@ -802,7 +818,7 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
}
|
||||
|
||||
|
||||
public void renderTable(TableData provider, XhtmlNode x) throws FHIRFormatError, DefinitionException, IOException {
|
||||
public void renderTable(RenderingStatus status, TableData provider, XhtmlNode x) throws FHIRFormatError, DefinitionException, IOException {
|
||||
List<String> columns = new ArrayList<>();
|
||||
for (String name : provider.getColumns()) {
|
||||
boolean hasData = false;
|
||||
|
@ -830,11 +846,11 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
for (String col : columns) {
|
||||
XhtmlNode td = tr.td();
|
||||
boolean first = true;
|
||||
List<DataType> list = row.get(col);
|
||||
List<ResourceElement> list = row.get(col);
|
||||
if (list != null) {
|
||||
for (DataType value : list) {
|
||||
for (ResourceElement value : list) {
|
||||
if (first) first = false; else td.tx(", ");
|
||||
render(td, value);
|
||||
renderDataType(status, td, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -842,13 +858,4 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
public void markLanguage(XhtmlNode x) {
|
||||
x.setAttribute("lang", context.getLocale().toString());
|
||||
x.setAttribute("xml:lang", context.getLocale().toString());
|
||||
x.addTag(0, "hr");
|
||||
x.addTag(0, "p").b().tx(context.getLocale().getDisplayName());
|
||||
x.addTag(0, "hr");
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -35,6 +35,7 @@ import org.hl7.fhir.r5.model.CodeableConcept;
|
|||
import org.hl7.fhir.r5.model.Coding;
|
||||
import org.hl7.fhir.r5.model.DataType;
|
||||
import org.hl7.fhir.r5.model.DecimalType;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Element;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.AdditionalBindingPurposeVS;
|
||||
|
@ -71,12 +72,14 @@ import org.hl7.fhir.r5.renderers.StructureDefinitionRenderer.InternalMarkdownPro
|
|||
import org.hl7.fhir.r5.renderers.StructureDefinitionRenderer.RenderStyle;
|
||||
import org.hl7.fhir.r5.renderers.StructureDefinitionRenderer.SourcedElementDefinition;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.ResourceElement;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.FixedValueFormat;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.KnownLinkType;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.StructureDefinitionRendererMode;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
import org.hl7.fhir.r5.renderers2.Renderer.RenderingStatus;
|
||||
import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
|
||||
import org.hl7.fhir.r5.utils.EOperationOutcome;
|
||||
import org.hl7.fhir.r5.utils.PublicationHacker;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
|
@ -101,6 +104,27 @@ import org.hl7.fhir.utilities.xhtml.XhtmlParser;
|
|||
|
||||
public class StructureDefinitionRenderer extends ResourceRenderer {
|
||||
|
||||
public StructureDefinitionRenderer(RenderingContext context) {
|
||||
super(context);
|
||||
hostMd = new InternalMarkdownProcessor();
|
||||
corePath = context.getContext().getSpecUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderResource(RenderingStatus status, XhtmlNode x, ResourceElement r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
|
||||
throw new Error("StructureDefinitionRenderer only renders native resources directly");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderResource(RenderingStatus status, XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
|
||||
render(status, x, (StructureDefinition) r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayResource(ResourceElement r) throws UnsupportedEncodingException, IOException {
|
||||
return canonicalTitle(r);
|
||||
}
|
||||
|
||||
public enum RenderStyle {
|
||||
|
||||
}
|
||||
|
@ -302,16 +326,6 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
|||
private Map<String, Map<String, ElementDefinition>> sdMapCache = new HashMap<>();
|
||||
private IMarkdownProcessor hostMd;
|
||||
|
||||
public StructureDefinitionRenderer(RenderingContext context) {
|
||||
super(context);
|
||||
hostMd = new InternalMarkdownProcessor();
|
||||
corePath = context.getContext().getSpecUrl();
|
||||
}
|
||||
|
||||
public StructureDefinitionRenderer(RenderingContext context, ResourceContext rcontext) {
|
||||
super(context, rcontext);
|
||||
}
|
||||
|
||||
|
||||
public Map<String, Map<String, ElementDefinition>> getSdMapCache() {
|
||||
return sdMapCache;
|
||||
|
@ -329,18 +343,15 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
|||
this.hostMd = hostMd;
|
||||
}
|
||||
|
||||
public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException {
|
||||
return render(x, (StructureDefinition) dr);
|
||||
}
|
||||
|
||||
public boolean render(XhtmlNode x, StructureDefinition sd) throws FHIRFormatError, DefinitionException, IOException {
|
||||
public void render(RenderingStatus status, XhtmlNode x, StructureDefinition sd) throws FHIRFormatError, DefinitionException, IOException {
|
||||
if (context.getStructureMode() == StructureDefinitionRendererMode.DATA_DICT) {
|
||||
renderDict(sd, sd.getDifferential().getElement(), x.table("dict"), false, GEN_MODE_DIFF, "");
|
||||
} else {
|
||||
x.getChildNodes().add(generateTable(context.getDefinitionsTarget(), sd, true, context.getDestDir(), false, sd.getId(), false,
|
||||
context.getLink(KnownLinkType.SPEC), "", sd.getKind() == StructureDefinitionKind.LOGICAL, false, null, false, context, ""));
|
||||
}
|
||||
return true;
|
||||
status.setExtensions(true);
|
||||
}
|
||||
|
||||
public void describe(XhtmlNode x, StructureDefinition sd) {
|
||||
|
@ -351,10 +362,6 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
|||
return sd.present();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String display(Resource r) throws UnsupportedEncodingException, IOException {
|
||||
return ((StructureDefinition) r).present();
|
||||
}
|
||||
|
||||
public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
|
||||
if (r.has("title")) {
|
||||
|
|
|
@ -28,6 +28,7 @@ public class Resolver {
|
|||
String resolveUri(RenderingContext context, String uri);
|
||||
}
|
||||
|
||||
/*
|
||||
public static class ResourceContext {
|
||||
private ResourceContext container;
|
||||
|
||||
|
@ -183,7 +184,7 @@ public class Resolver {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
public enum ResourceReferenceKind {
|
||||
CONTAINED, BUNDLE, EXTERNAL, UNKNOWN
|
||||
|
@ -194,9 +195,9 @@ public class Resolver {
|
|||
|
||||
private ResourceReferenceKind kind;
|
||||
private String reference;
|
||||
private ResourceWrapper resource;
|
||||
private ResourceElement resource;
|
||||
|
||||
public ResourceWithReference(ResourceReferenceKind kind, String reference, ResourceWrapper resource) {
|
||||
public ResourceWithReference(ResourceReferenceKind kind, String reference, ResourceElement resource) {
|
||||
super();
|
||||
this.kind = kind;
|
||||
this.reference = reference;
|
||||
|
@ -211,7 +212,7 @@ public class Resolver {
|
|||
return reference;
|
||||
}
|
||||
|
||||
public ResourceWrapper getResource() {
|
||||
public ResourceElement getResource() {
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,16 +6,18 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.SourcedChildDefinitions;
|
||||
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||
import org.hl7.fhir.r5.elementmodel.Element;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.DataType;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.Narrative;
|
||||
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.utils.client.network.FhirRequestBuilder;
|
||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
|
@ -35,46 +37,77 @@ public class ResourceElement {
|
|||
IndependentResource
|
||||
}
|
||||
|
||||
private ContextUtilities context;
|
||||
public static class NamedResourceElementList {
|
||||
private String name;
|
||||
private List<ResourceElement> values = new ArrayList<ResourceElement>();
|
||||
|
||||
public NamedResourceElementList(String name) {
|
||||
super();
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public List<ResourceElement> getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ContextUtilities contextUtils;
|
||||
private ProfileUtilities profileUtils;
|
||||
private ResourceElement parent;
|
||||
private String name; // null at root
|
||||
private int index; // -1 if not repeating
|
||||
private ElementKind kind;
|
||||
private StructureDefinition classDefinition;
|
||||
private ElementDefinition propertyDefinition;
|
||||
|
||||
private Base element;
|
||||
private Element model;
|
||||
|
||||
private List<ResourceElement> children;
|
||||
|
||||
public ResourceElement(ContextUtilities context, Resource resource) {
|
||||
this.context = context;
|
||||
public ResourceElement(ContextUtilities contextUtils, ProfileUtilities profileUtils, Resource resource) {
|
||||
this.contextUtils = contextUtils;
|
||||
this.profileUtils = profileUtils;
|
||||
this.parent = null;
|
||||
this.name = null;
|
||||
this.index = -1;
|
||||
this.kind = ElementKind.IndependentResource;
|
||||
this.element = resource;
|
||||
this.classDefinition = profileUtils.getContext().fetchTypeDefinition(resource.fhirType());
|
||||
this.propertyDefinition = this.classDefinition.getSnapshot().getElementFirstRep();
|
||||
}
|
||||
|
||||
public ResourceElement(ContextUtilities context, DataType type) {
|
||||
this.context = context;
|
||||
public ResourceElement(ContextUtilities contextUtils, ProfileUtilities profileUtils, DataType type) {
|
||||
this.contextUtils = contextUtils;
|
||||
this.profileUtils = profileUtils;
|
||||
this.parent = null;
|
||||
this.name = null;
|
||||
this.index = -1;
|
||||
this.kind = null;
|
||||
this.element = type;
|
||||
this.classDefinition = profileUtils.getContext().fetchTypeDefinition(type.fhirType());
|
||||
this.propertyDefinition = this.classDefinition.getSnapshot().getElementFirstRep();
|
||||
}
|
||||
|
||||
public ResourceElement(ContextUtilities context, ResourceElement parent, String name, int index, ElementKind kind, Base element) {
|
||||
this.context = context;
|
||||
public ResourceElement(ContextUtilities contextUtils, ProfileUtilities profileUtils, ResourceElement parent, String name, int index, ElementKind kind, Base element, StructureDefinition classDefinition, ElementDefinition propertyDefinition) {
|
||||
this.contextUtils = contextUtils;
|
||||
this.profileUtils = profileUtils;
|
||||
this.parent = parent;
|
||||
this.name = name;
|
||||
this.index = index;
|
||||
this.kind = kind;
|
||||
this.element = element;
|
||||
this.classDefinition = classDefinition;
|
||||
this.propertyDefinition = propertyDefinition;
|
||||
}
|
||||
|
||||
public ResourceElement(ContextUtilities context, Element resource) {
|
||||
this.context = context;
|
||||
public ResourceElement(ContextUtilities contextUtils, ProfileUtilities profileUtils, Element resource) {
|
||||
this.contextUtils = contextUtils;
|
||||
this.profileUtils = profileUtils;
|
||||
this.parent = null;
|
||||
this.name = null;
|
||||
this.index = -1;
|
||||
|
@ -82,13 +115,16 @@ public class ResourceElement {
|
|||
this.model = resource;
|
||||
}
|
||||
|
||||
public ResourceElement(ContextUtilities context, ResourceElement parent, String name, int index, ElementKind kind, Element em) {
|
||||
this.context = context;
|
||||
public ResourceElement(ContextUtilities contextUtils, ProfileUtilities profileUtils, ResourceElement parent, String name, int index, ElementKind kind, Element em) {
|
||||
this.contextUtils = contextUtils;
|
||||
this.profileUtils = profileUtils;
|
||||
this.parent = parent;
|
||||
this.name = name;
|
||||
this.index = index;
|
||||
this.kind = kind;
|
||||
this.model = em;
|
||||
this.classDefinition = em.getProperty().getStructure();
|
||||
this.propertyDefinition = em.getProperty().getDefinition();
|
||||
}
|
||||
|
||||
public String fhirVersion() {
|
||||
|
@ -201,7 +237,7 @@ public class ResourceElement {
|
|||
String name = child.getProperty().isChoice() ? child.getProperty().getName() : child.getName();
|
||||
int index = child.isList() ? child.getIndex() : -1;
|
||||
ElementKind kind = determineModelKind(child);
|
||||
children.add(new ResourceElement(context, this, name, index, kind, child));
|
||||
children.add(new ResourceElement(contextUtils, profileUtils, this, name, index, kind, child));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,13 +269,29 @@ public class ResourceElement {
|
|||
}
|
||||
|
||||
private void loadElementChildren() {
|
||||
SourcedChildDefinitions childDefs = propertyDefinition == null ? null : profileUtils.getChildMap(classDefinition, propertyDefinition);
|
||||
for (Property p : element.children()) {
|
||||
String name = p.getName();
|
||||
int i = 0;
|
||||
for (Base v : p.getValues()) {
|
||||
ElementKind kind = determineModelKind(p, v);
|
||||
int index = p.isList() ? i : -1;
|
||||
children.add(new ResourceElement(context, this, name, index, kind, v));
|
||||
ElementDefinition ed = null;
|
||||
if (childDefs != null) {
|
||||
for (ElementDefinition t : childDefs.getList()) {
|
||||
if (t.getName().equals(name)) {
|
||||
ed = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ed != null) {
|
||||
children.add(new ResourceElement(contextUtils, profileUtils, this, name, index, kind, v, childDefs.getSource(), ed));
|
||||
} else {
|
||||
StructureDefinition sd = profileUtils.getContext().fetchTypeDefinition(v.fhirType());
|
||||
ElementDefinition ted = sd.getSnapshot().getElementFirstRep();
|
||||
children.add(new ResourceElement(contextUtils, profileUtils, this, name, index, kind, v, sd, ted));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
@ -248,7 +300,7 @@ public class ResourceElement {
|
|||
private ElementKind determineModelKind(Property p, Base v) {
|
||||
if (v.isPrimitive()) {
|
||||
return ElementKind.PrimitiveType;
|
||||
} else if (context.isDatatype(v.fhirType())) {
|
||||
} else if (contextUtils.isDatatype(v.fhirType())) {
|
||||
return ElementKind.DataType;
|
||||
} else if (!v.isResource()) {
|
||||
return ElementKind.BackboneElement;
|
||||
|
@ -272,6 +324,25 @@ public class ResourceElement {
|
|||
return children;
|
||||
}
|
||||
|
||||
public List<NamedResourceElementList> childrenInGroups() {
|
||||
loadChildren();
|
||||
List<NamedResourceElementList> list = new ArrayList<ResourceElement.NamedResourceElementList>();
|
||||
for (ResourceElement e : children) {
|
||||
NamedResourceElementList nl = null;
|
||||
for (NamedResourceElementList t : list) {
|
||||
if (t.name.equals(e.name())) {
|
||||
nl = t;
|
||||
}
|
||||
}
|
||||
if (nl == null) {
|
||||
nl = new NamedResourceElementList(e.name());
|
||||
list.add(nl);
|
||||
}
|
||||
nl.values.add(e);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<ResourceElement> children(String name) {
|
||||
loadChildren();
|
||||
List<ResourceElement> list = new ArrayList<ResourceElement>();
|
||||
|
@ -454,7 +525,7 @@ public class ResourceElement {
|
|||
if (element != null) {
|
||||
return element instanceof DomainResource;
|
||||
} else {
|
||||
return context.isDomainResource(fhirType());
|
||||
return contextUtils.isDomainResource(fhirType());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -582,7 +653,7 @@ public class ResourceElement {
|
|||
}
|
||||
|
||||
public ContextUtilities getContextUtilities() {
|
||||
return context;
|
||||
return contextUtils;
|
||||
}
|
||||
|
||||
public boolean hasFormatComment() {
|
||||
|
@ -601,5 +672,13 @@ public class ResourceElement {
|
|||
}
|
||||
}
|
||||
|
||||
public StructureDefinition getClassDefinition() {
|
||||
return classDefinition;
|
||||
}
|
||||
|
||||
public ElementDefinition getPropertyDefinition() {
|
||||
return propertyDefinition;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -7,6 +7,7 @@ import java.io.IOException;
|
|||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||
|
@ -26,7 +27,7 @@ public class ResourceElementTests {
|
|||
public void testDirect() throws FHIRFormatError, IOException {
|
||||
IWorkerContext worker = TestingUtilities.getSharedWorkerContext();
|
||||
Resource res = new XmlParser().parse(TestingUtilities.loadTestResource("r5", "bundle-resource-element-test.xml"));
|
||||
ResourceElement re = new ResourceElement(new ContextUtilities(worker), res);
|
||||
ResourceElement re = new ResourceElement(new ContextUtilities(worker), new ProfileUtilities(worker, null, null), res);
|
||||
checkTree(re);
|
||||
}
|
||||
|
||||
|
@ -34,7 +35,7 @@ public class ResourceElementTests {
|
|||
public void testIndirect() throws FHIRFormatError, IOException {
|
||||
IWorkerContext worker = TestingUtilities.getSharedWorkerContext();
|
||||
List<ValidatedFragment> res = Manager.parse(worker, TestingUtilities.loadTestResourceStream("r5", "bundle-resource-element-test.xml"), FhirFormat.XML);
|
||||
ResourceElement re = new ResourceElement(new ContextUtilities(worker), res.get(0).getElement());
|
||||
ResourceElement re = new ResourceElement(new ContextUtilities(worker), new ProfileUtilities(worker, null, null), res.get(0).getElement());
|
||||
checkTree(re);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue