Start Working on i18n for Rendering + Fix case bug rendering bundles and parameters

This commit is contained in:
Grahame Grieve 2020-08-06 22:37:27 +10:00
parent 8b3ce7b3cc
commit 879e5344b3
6 changed files with 101 additions and 31 deletions

View File

@ -28,6 +28,7 @@ import org.hl7.fhir.utilities.xhtml.XhtmlNode;
public class BundleRenderer extends ResourceRenderer { public class BundleRenderer extends ResourceRenderer {
public BundleRenderer(RenderingContext context, ResourceContext rcontext) { public BundleRenderer(RenderingContext context, ResourceContext rcontext) {
super(context, rcontext); super(context, rcontext);
} }
@ -63,7 +64,7 @@ public class BundleRenderer extends ResourceRenderer {
// nothing // nothing
} else { } else {
XhtmlNode root = new XhtmlNode(NodeType.Element, "div"); XhtmlNode root = new XhtmlNode(NodeType.Element, "div");
root.para().addText("Bundle "+b.getId()+" of type "+b.get("type").primitiveValue()); root.para().addText(formatMessage(RENDER_BUNDLE_HEADER_ROOT, b.getId(), b.get("type").primitiveValue()));
int i = 0; int i = 0;
for (BaseWrapper be : entries) { for (BaseWrapper be : entries) {
i++; i++;
@ -71,10 +72,14 @@ public class BundleRenderer extends ResourceRenderer {
root.an(makeInternalLink(be.get("fullUrl").primitiveValue())); root.an(makeInternalLink(be.get("fullUrl").primitiveValue()));
} }
if (be.has("resource") && be.getChildByName("resource").getValues().get(0).has("id")) { if (be.has("resource") && be.getChildByName("resource").getValues().get(0).has("id")) {
root.an(be.get("resource").fhirType().toLowerCase() + "_" + be.getChildByName("resource").getValues().get(0).get("id").primitiveValue()); root.an(be.get("resource").fhirType() + "_" + be.getChildByName("resource").getValues().get(0).get("id").primitiveValue());
} }
root.hr(); root.hr();
root.para().addText("Entry "+Integer.toString(i)+(be.has("fullUrl") ? " - Full URL = " + be.get("fullUrl").primitiveValue() : "")); if (be.has("fullUrl")) {
root.para().addText(formatMessage(RENDER_BUNDLE_HEADER_ENTRY_URL, Integer.toString(i), be.get("fullUrl").primitiveValue()));
} else {
root.para().addText(formatMessage(RENDER_BUNDLE_HEADER_ENTRY, Integer.toString(i)));
}
// if (be.hasRequest()) // if (be.hasRequest())
// renderRequest(root, be.getRequest()); // renderRequest(root, be.getRequest());
// if (be.hasSearch()) // if (be.hasSearch())
@ -82,7 +87,7 @@ public class BundleRenderer extends ResourceRenderer {
// if (be.hasResponse()) // if (be.hasResponse())
// renderResponse(root, be.getResponse()); // renderResponse(root, be.getResponse());
if (be.has("resource")) { if (be.has("resource")) {
root.para().addText("Resource "+be.get("resource").fhirType()+":"); root.para().addText(formatMessage(RENDER_BUNDLE_RESOURCE, be.get("resource").fhirType()));
ResourceWrapper rw = be.getChildByName("resource").getAsResource(); ResourceWrapper rw = be.getChildByName("resource").getAsResource();
root.blockquote().addChildren(rw.getNarrative()); root.blockquote().addChildren(rw.getNarrative());
} }
@ -94,24 +99,29 @@ public class BundleRenderer extends ResourceRenderer {
public XhtmlNode render(Bundle b) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome { public XhtmlNode render(Bundle b) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
if (b.getType() == BundleType.DOCUMENT) { if (b.getType() == BundleType.DOCUMENT) {
if (!b.hasEntry() || !(b.getEntryFirstRep().hasResource() && b.getEntryFirstRep().getResource() instanceof Composition)) if (!b.hasEntry() || !(b.getEntryFirstRep().hasResource() && b.getEntryFirstRep().getResource() instanceof Composition)) {
throw new FHIRException("Invalid document - first entry is not a Composition"); throw new FHIRException("Invalid document - first entry is not a Composition");
}
Composition dr = (Composition) b.getEntryFirstRep().getResource(); Composition dr = (Composition) b.getEntryFirstRep().getResource();
return dr.getText().getDiv(); return dr.getText().getDiv();
} else if ((b.getType() == BundleType.COLLECTION && allEntresAreHistoryProvenance(b))) { } else if ((b.getType() == BundleType.COLLECTION && allEntresAreHistoryProvenance(b))) {
return null; return null;
} else { } else {
XhtmlNode root = new XhtmlNode(NodeType.Element, "div"); XhtmlNode root = new XhtmlNode(NodeType.Element, "div");
root.para().addText("Bundle "+b.getId()+" of type "+b.getType().toCode()); root.para().addText(formatMessage(RENDER_BUNDLE_HEADER_ROOT, b.getId(), b.getType().toCode()));
int i = 0; int i = 0;
for (BundleEntryComponent be : b.getEntry()) { for (BundleEntryComponent be : b.getEntry()) {
i++; i++;
if (be.hasFullUrl()) if (be.hasFullUrl())
root.an(makeInternalLink(be.getFullUrl())); root.an(makeInternalLink(be.getFullUrl()));
if (be.hasResource() && be.getResource().hasId()) if (be.hasResource() && be.getResource().hasId())
root.an(be.getResource().getResourceType().name().toLowerCase() + "_" + be.getResource().getId()); root.an(be.getResource().getResourceType().name() + "_" + be.getResource().getId());
root.hr(); root.hr();
root.para().addText("Entry "+Integer.toString(i)+(be.hasFullUrl() ? " - Full URL = " + be.getFullUrl() : "")); if (be.hasFullUrl()) {
root.para().addText(formatMessage(RENDER_BUNDLE_HEADER_ENTRY_URL, Integer.toString(i), be.getFullUrl()));
} else {
root.para().addText(formatMessage(RENDER_BUNDLE_HEADER_ENTRY, Integer.toString(i)));
}
if (be.hasRequest()) if (be.hasRequest())
renderRequest(root, be.getRequest()); renderRequest(root, be.getRequest());
if (be.hasSearch()) if (be.hasSearch())
@ -119,7 +129,7 @@ public class BundleRenderer extends ResourceRenderer {
if (be.hasResponse()) if (be.hasResponse())
renderResponse(root, be.getResponse()); renderResponse(root, be.getResponse());
if (be.hasResource()) { if (be.hasResource()) {
root.para().addText("Resource "+be.getResource().fhirType()+":"); root.para().addText(formatMessage(RENDER_BUNDLE_RESOURCE, be.getResource().fhirType()));
if (be.hasResource() && be.getResource() instanceof DomainResource) { if (be.hasResource() && be.getResource() instanceof DomainResource) {
DomainResource dr = (DomainResource) be.getResource(); DomainResource dr = (DomainResource) be.getResource();
if ( dr.getText().hasDiv()) if ( dr.getText().hasDiv())
@ -178,45 +188,47 @@ public class BundleRenderer extends ResourceRenderer {
private void renderSearch(XhtmlNode root, BundleEntrySearchComponent search) { private void renderSearch(XhtmlNode root, BundleEntrySearchComponent search) {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
b.append("Search: "); b.append(formatMessage(RENDER_BUNDLE_SEARCH));
if (search.hasMode()) if (search.hasMode())
b.append("mode = "+search.getMode().toCode()); b.append(formatMessage(RENDER_BUNDLE_SEARCH_MODE, search.getMode().toCode()));
if (search.hasScore()) { if (search.hasScore()) {
if (search.hasMode()) if (search.hasMode())
b.append(","); b.append(",");
b.append("score = "+search.getScore()); b.append(formatMessage(RENDER_BUNDLE_SEARCH_SCORE, search.getScore()));
} }
root.para().addText(b.toString()); root.para().addText(b.toString());
} }
private void renderResponse(XhtmlNode root, BundleEntryResponseComponent response) { private void renderResponse(XhtmlNode root, BundleEntryResponseComponent response) {
root.para().addText("Response:"); root.para().addText(formatMessage(RENDER_BUNDLE_RESPONSE));
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
b.append(response.getStatus()+"\r\n"); b.append(response.getStatus()+"\r\n");
if (response.hasLocation()) if (response.hasLocation())
b.append("Location: "+response.getLocation()+"\r\n"); b.append(formatMessage(RENDER_BUNDLE_LOCATION, response.getLocation())+"\r\n");
if (response.hasEtag()) if (response.hasEtag())
b.append("E-Tag: "+response.getEtag()+"\r\n"); b.append(formatMessage(RENDER_BUNDLE_ETAG, response.getEtag())+"\r\n");
if (response.hasLastModified()) if (response.hasLastModified())
b.append("LastModified: "+response.getEtag()+"\r\n"); b.append(formatMessage(RENDER_BUNDLE_LAST_MOD, response.getEtag())+"\r\n");
root.pre().addText(b.toString()); root.pre().addText(b.toString());
} }
private void renderRequest(XhtmlNode root, BundleEntryRequestComponent request) { private void renderRequest(XhtmlNode root, BundleEntryRequestComponent request) {
root.para().addText("Request:"); root.para().addText(formatMessage(RENDER_BUNDLE_REQUEST));
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
b.append(request.getMethod()+" "+request.getUrl()+"\r\n"); b.append(request.getMethod()+" "+request.getUrl()+"\r\n");
if (request.hasIfNoneMatch()) if (request.hasIfNoneMatch())
b.append("If-None-Match: "+request.getIfNoneMatch()+"\r\n"); b.append(formatMessage(RENDER_BUNDLE_IF_NON_MATCH, request.getIfNoneMatch())+"\r\n");
if (request.hasIfModifiedSince()) if (request.hasIfModifiedSince())
b.append("If-Modified-Since: "+request.getIfModifiedSince()+"\r\n"); b.append(formatMessage(RENDER_BUNDLE_IF_MOD, request.getIfModifiedSince())+"\r\n");
if (request.hasIfMatch()) if (request.hasIfMatch())
b.append("If-Match: "+request.getIfMatch()+"\r\n"); b.append(formatMessage(RENDER_BUNDLE_IF_MATCH, request.getIfMatch())+"\r\n");
if (request.hasIfNoneExist()) if (request.hasIfNoneExist())
b.append("If-None-Exist: "+request.getIfNoneExist()+"\r\n"); b.append(formatMessage(RENDER_BUNDLE_IF_NONE, request.getIfNoneExist())+"\r\n");
root.pre().addText(b.toString()); root.pre().addText(b.toString());
} }
private String makeInternalLink(String fullUrl) { private String makeInternalLink(String fullUrl) {
return fullUrl.replace(":", "-"); return fullUrl.replace(":", "-");
} }

View File

@ -57,16 +57,12 @@ public class DataRenderer extends Renderer {
// -- 1. context -------------------------------------------------------------- // -- 1. context --------------------------------------------------------------
protected RenderingContext context;
public DataRenderer(RenderingContext context) { public DataRenderer(RenderingContext context) {
super(); super(context);
this.context = context;
} }
public DataRenderer(IWorkerContext worker) { public DataRenderer(IWorkerContext worker) {
super(); super(worker);
this.context = new RenderingContext(worker, new MarkDownProcessor(Dialect.COMMON_MARK), ValidationOptions.defaults(), "http://hl7.org/fhir/R4", "", null, ResourceRendererMode.RESOURCE);
} }
// -- 2. Markdown support ------------------------------------------------------- // -- 2. Markdown support -------------------------------------------------------

View File

@ -77,7 +77,7 @@ public class ParametersRenderer extends ResourceRenderer {
td = tr.td(); td = tr.td();
XhtmlNode para = td.para(); XhtmlNode para = td.para();
para.tx(rw.fhirType()+"/"+rw.getId()); para.tx(rw.fhirType()+"/"+rw.getId());
para.an(rw.fhirType().toLowerCase()+"_"+rw.getId()).tx(" "); para.an(rw.fhirType()+"_"+rw.getId()).tx(" ");
XhtmlNode x = rw.getNarrative(); XhtmlNode x = rw.getNarrative();
if (x != null) { if (x != null) {
td.addChildren(x); td.addChildren(x);

View File

@ -1,5 +1,11 @@
package org.hl7.fhir.r5.renderers; package org.hl7.fhir.r5.renderers;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
import org.hl7.fhir.utilities.MarkDownProcessor;
import org.hl7.fhir.utilities.MarkDownProcessor.Dialect;
import org.hl7.fhir.utilities.validation.ValidationOptions;
/** /**
* Rendering framework: * Rendering framework:
@ -20,4 +26,44 @@ package org.hl7.fhir.r5.renderers;
*/ */
public class Renderer { public class Renderer {
protected RenderingContext context;
public Renderer(RenderingContext context) {
this.context = context;
}
public Renderer(IWorkerContext worker) {
this.context = new RenderingContext(worker, new MarkDownProcessor(Dialect.COMMON_MARK), ValidationOptions.defaults(), "http://hl7.org/fhir/R5", "", null, ResourceRendererMode.RESOURCE);
}
protected static final String RENDER_BUNDLE_HEADER_ROOT = "RENDER_BUNDLE_HEADER_ROOT";
protected static final String RENDER_BUNDLE_HEADER_ENTRY = "RENDER_BUNDLE_HEADER_ENTRY";
protected static final String RENDER_BUNDLE_HEADER_ENTRY_URL = "RENDER_BUNDLE_HEADER_ENTRY_URL";
protected static final String RENDER_BUNDLE_RESOURCE = "RENDER_BUNDLE_RESOURCE";
protected static final String RENDER_BUNDLE_SEARCH = "RENDER_BUNDLE_SEARCH";
protected static final String RENDER_BUNDLE_SEARCH_MODE = "RENDER_BUNDLE_SEARCH_MODE";
protected static final String RENDER_BUNDLE_SEARCH_SCORE = "RENDER_BUNDLE_SEARCH_SCORE";
protected static final String RENDER_BUNDLE_RESPONSE = "RENDER_BUNDLE_RESPONSE";
protected static final String RENDER_BUNDLE_LOCATION = "RENDER_BUNDLE_LOCATION";
protected static final String RENDER_BUNDLE_ETAG = "RENDER_BUNDLE_ETAG";
protected static final String RENDER_BUNDLE_LAST_MOD = "RENDER_BUNDLE_LAST_MOD";
protected static final String RENDER_BUNDLE_REQUEST = "RENDER_BUNDLE_REQUEST";
protected static final String RENDER_BUNDLE_IF_NON_MATCH = "RENDER_BUNDLE_IF_NON_MATCH";
protected static final String RENDER_BUNDLE_IF_MOD = "RENDER_BUNDLE_IF_MOD";
protected static final String RENDER_BUNDLE_IF_MATCH = "RENDER_BUNDLE_IF_MATCH";
protected static final String RENDER_BUNDLE_IF_NONE = "RENDER_BUNDLE_IF_NONE";
/** the plan here is to make this have it's own implementation of messages, rather than using the
* validator messages, for better alignment with publisher I18n strategy
*
* @param theMessage
* @param theMessageArguments
* @return
*/
protected String formatMessage(String theMessage, Object... theMessageArguments) {
return context.getWorker().formatMessage(theMessage, theMessageArguments);
}
} }

View File

@ -220,7 +220,7 @@ public abstract class ResourceRenderer extends DataRenderer {
if (rcontext != null) { if (rcontext != null) {
BundleEntryComponent bundleResource = rcontext.resolve(url); BundleEntryComponent bundleResource = rcontext.resolve(url);
if (bundleResource != null) { if (bundleResource != null) {
String bundleUrl = "#" + bundleResource.getResource().getResourceType().name().toLowerCase() + "_" + bundleResource.getResource().getId(); String bundleUrl = "#" + bundleResource.getResource().getResourceType().name() + "_" + bundleResource.getResource().getId();
return new ResourceWithReference(bundleUrl, new ResourceWrapperDirect(this.context, bundleResource.getResource())); return new ResourceWithReference(bundleUrl, new ResourceWrapperDirect(this.context, bundleResource.getResource()));
} }
org.hl7.fhir.r5.elementmodel.Element bundleElement = rcontext.resolveElement(url); org.hl7.fhir.r5.elementmodel.Element bundleElement = rcontext.resolveElement(url);
@ -228,7 +228,7 @@ public abstract class ResourceRenderer extends DataRenderer {
String bundleUrl = null; String bundleUrl = null;
Element br = bundleElement.getNamedChild("resource"); Element br = bundleElement.getNamedChild("resource");
if (br.getChildValue("id") != null) { if (br.getChildValue("id") != null) {
bundleUrl = "#" + br.fhirType().toLowerCase() + "_" + br.getChildValue("id"); bundleUrl = "#" + br.fhirType() + "_" + br.getChildValue("id");
} else { } else {
bundleUrl = "#" +fullUrlToAnchor(bundleElement.getChildValue("fullUrl")); bundleUrl = "#" +fullUrlToAnchor(bundleElement.getChildValue("fullUrl"));
} }

View File

@ -575,3 +575,19 @@ VALIDATION_VAL_PROFILE_OTHER_VERSION = Profile is for a different version of FHI
VALIDATION_VAL_PROFILE_THIS_VERSION_OK = Profile for this version of FHIR - all OK VALIDATION_VAL_PROFILE_THIS_VERSION_OK = Profile for this version of FHIR - all OK
VALIDATION_VAL_PROFILE_THIS_VERSION_OTHER = Profile is for this version of FHIR, but is an invalid type {0} VALIDATION_VAL_PROFILE_THIS_VERSION_OTHER = Profile is for this version of FHIR, but is an invalid type {0}
BUNDLE_BUNDLE_ENTRY_MULTIPLE_PROFILES = Multiple profiles found for contained resource. This is not supported at this time. (Type {0}: {1}) BUNDLE_BUNDLE_ENTRY_MULTIPLE_PROFILES = Multiple profiles found for contained resource. This is not supported at this time. (Type {0}: {1})
RENDER_BUNDLE_HEADER_ROOT = Bundle {0} of type {1}
RENDER_BUNDLE_HEADER_ENTRY = Entry {0}
RENDER_BUNDLE_HEADER_ENTRY_URL = Entry {0} - Full URL = {1}
RENDER_BUNDLE_RESOURCE = Resource {0}:
RENDER_BUNDLE_SEARCH = Search:
RENDER_BUNDLE_SEARCH_MODE = mode = {0}
RENDER_BUNDLE_SEARCH_SCORE = score = {0}
RENDER_BUNDLE_RESPONSE = Response:
RENDER_BUNDLE_LOCATION = Location = {0}
RENDER_BUNDLE_ETAG = ETag = {0}
RENDER_BUNDLE_LAST_MOD = LastModified = {0}
RENDER_BUNDLE_REQUEST = Request:
RENDER_BUNDLE_IF_NON_MATCH = If-None-Match = {0}
RENDER_BUNDLE_IF_MOD = If-Modified-Since = {0}
RENDER_BUNDLE_IF_MATCH = If-Match = {0}
RENDER_BUNDLE_IF_NONE = If-None-Exist = {0}