diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/BundleRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/BundleRenderer.java index dca727389..33fa539ff 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/BundleRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/BundleRenderer.java @@ -28,6 +28,7 @@ import org.hl7.fhir.utilities.xhtml.XhtmlNode; public class BundleRenderer extends ResourceRenderer { + public BundleRenderer(RenderingContext context, ResourceContext rcontext) { super(context, rcontext); } @@ -63,7 +64,7 @@ public class BundleRenderer extends ResourceRenderer { // nothing } else { 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; for (BaseWrapper be : entries) { i++; @@ -71,10 +72,14 @@ public class BundleRenderer extends ResourceRenderer { root.an(makeInternalLink(be.get("fullUrl").primitiveValue())); } 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.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()) // renderRequest(root, be.getRequest()); // if (be.hasSearch()) @@ -82,7 +87,7 @@ public class BundleRenderer extends ResourceRenderer { // if (be.hasResponse()) // renderResponse(root, be.getResponse()); 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(); 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 { 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"); + } Composition dr = (Composition) b.getEntryFirstRep().getResource(); return dr.getText().getDiv(); } else if ((b.getType() == BundleType.COLLECTION && allEntresAreHistoryProvenance(b))) { return null; } else { 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; for (BundleEntryComponent be : b.getEntry()) { i++; if (be.hasFullUrl()) root.an(makeInternalLink(be.getFullUrl())); 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.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()) renderRequest(root, be.getRequest()); if (be.hasSearch()) @@ -119,7 +129,7 @@ public class BundleRenderer extends ResourceRenderer { if (be.hasResponse()) renderResponse(root, be.getResponse()); 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) { DomainResource dr = (DomainResource) be.getResource(); if ( dr.getText().hasDiv()) @@ -178,45 +188,47 @@ public class BundleRenderer extends ResourceRenderer { private void renderSearch(XhtmlNode root, BundleEntrySearchComponent search) { StringBuilder b = new StringBuilder(); - b.append("Search: "); + b.append(formatMessage(RENDER_BUNDLE_SEARCH)); if (search.hasMode()) - b.append("mode = "+search.getMode().toCode()); + b.append(formatMessage(RENDER_BUNDLE_SEARCH_MODE, search.getMode().toCode())); if (search.hasScore()) { if (search.hasMode()) b.append(","); - b.append("score = "+search.getScore()); + b.append(formatMessage(RENDER_BUNDLE_SEARCH_SCORE, search.getScore())); } root.para().addText(b.toString()); } private void renderResponse(XhtmlNode root, BundleEntryResponseComponent response) { - root.para().addText("Response:"); + root.para().addText(formatMessage(RENDER_BUNDLE_RESPONSE)); StringBuilder b = new StringBuilder(); b.append(response.getStatus()+"\r\n"); if (response.hasLocation()) - b.append("Location: "+response.getLocation()+"\r\n"); + b.append(formatMessage(RENDER_BUNDLE_LOCATION, response.getLocation())+"\r\n"); if (response.hasEtag()) - b.append("E-Tag: "+response.getEtag()+"\r\n"); + b.append(formatMessage(RENDER_BUNDLE_ETAG, response.getEtag())+"\r\n"); 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()); } private void renderRequest(XhtmlNode root, BundleEntryRequestComponent request) { - root.para().addText("Request:"); + root.para().addText(formatMessage(RENDER_BUNDLE_REQUEST)); StringBuilder b = new StringBuilder(); b.append(request.getMethod()+" "+request.getUrl()+"\r\n"); 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()) - b.append("If-Modified-Since: "+request.getIfModifiedSince()+"\r\n"); + b.append(formatMessage(RENDER_BUNDLE_IF_MOD, request.getIfModifiedSince())+"\r\n"); 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()) - 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()); } + + private String makeInternalLink(String fullUrl) { return fullUrl.replace(":", "-"); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java index d3748aa42..be047566d 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java @@ -56,17 +56,13 @@ import org.hl7.fhir.utilities.xhtml.XhtmlParser; public class DataRenderer extends Renderer { // -- 1. context -------------------------------------------------------------- - - protected RenderingContext context; - + public DataRenderer(RenderingContext context) { - super(); - this.context = context; + super(context); } public DataRenderer(IWorkerContext worker) { - super(); - this.context = new RenderingContext(worker, new MarkDownProcessor(Dialect.COMMON_MARK), ValidationOptions.defaults(), "http://hl7.org/fhir/R4", "", null, ResourceRendererMode.RESOURCE); + super(worker); } // -- 2. Markdown support ------------------------------------------------------- diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ParametersRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ParametersRenderer.java index 0cbc2b635..fc8e6436b 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ParametersRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ParametersRenderer.java @@ -77,7 +77,7 @@ public class ParametersRenderer extends ResourceRenderer { td = tr.td(); XhtmlNode para = td.para(); 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(); if (x != null) { td.addChildren(x); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/Renderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/Renderer.java index fc1a1867c..fdab9eb80 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/Renderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/Renderer.java @@ -1,5 +1,11 @@ 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: @@ -20,4 +26,44 @@ package org.hl7.fhir.r5.renderers; */ 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); + } + } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ResourceRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ResourceRenderer.java index 4b2d5447a..1904b74cd 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ResourceRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ResourceRenderer.java @@ -220,7 +220,7 @@ public abstract class ResourceRenderer extends DataRenderer { if (rcontext != null) { BundleEntryComponent bundleResource = rcontext.resolve(url); 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())); } org.hl7.fhir.r5.elementmodel.Element bundleElement = rcontext.resolveElement(url); @@ -228,7 +228,7 @@ public abstract class ResourceRenderer extends DataRenderer { String bundleUrl = null; Element br = bundleElement.getNamedChild("resource"); if (br.getChildValue("id") != null) { - bundleUrl = "#" + br.fhirType().toLowerCase() + "_" + br.getChildValue("id"); + bundleUrl = "#" + br.fhirType() + "_" + br.getChildValue("id"); } else { bundleUrl = "#" +fullUrlToAnchor(bundleElement.getChildValue("fullUrl")); } diff --git a/org.hl7.fhir.utilities/src/main/resources/Messages.properties b/org.hl7.fhir.utilities/src/main/resources/Messages.properties index 8bd7307cf..243766cad 100644 --- a/org.hl7.fhir.utilities/src/main/resources/Messages.properties +++ b/org.hl7.fhir.utilities/src/main/resources/Messages.properties @@ -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_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}) +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}