diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/wrapper/ResourceWrapperR4.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/wrapper/ResourceWrapperR4.java index fcb295067..a59ea0b89 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/wrapper/ResourceWrapperR4.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/wrapper/ResourceWrapperR4.java @@ -15,8 +15,18 @@ import org.hl7.fhir.utilities.xhtml.NodeType; import org.hl7.fhir.utilities.xhtml.XhtmlNode; /** - * This class is used to walk through the resources when rendering, whether - * the resource is a native resource or loaded by the element model + * An R4 wrapper for the R5 rendering framework - use this to feed R4 resources directly + * into the R5 framework. + * + * The R5 framework is fine to render R4 resources, and has R4 (etc) specific code where + * appropriate (or will be modified to do so). + * + * Note that in order to use this, you need an R5 IWorkerContext. You can create a + * R5 SimpleWorkerContext and load it with all the definitions from R4 (that's how the + * validator works internally, so this is well tested code). But you only need to set + * up the R5 context once; then you can create instances of these to wrap the objects you + * want rendered on the fly. (is thread safe) + * */ public class ResourceWrapperR4 extends ResourceWrapper { diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/wrapper/ResourceWrapperR4B.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/wrapper/ResourceWrapperR4B.java index a6f474f4c..df1179bfa 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/wrapper/ResourceWrapperR4B.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/wrapper/ResourceWrapperR4B.java @@ -15,8 +15,18 @@ import org.hl7.fhir.utilities.xhtml.NodeType; import org.hl7.fhir.utilities.xhtml.XhtmlNode; /** - * This class is used to walk through the resources when rendering, whether - * the resource is a native resource or loaded by the element model + * An R4 wrapper for the R5 rendering framework - use this to feed R4 resources directly + * into the R5 framework. + * + * The R5 framework is fine to render R4 resources, and has R4 (etc) specific code where + * appropriate (or will be modified to do so). + * + * Note that in order to use this, you need an R5 IWorkerContext. You can create a + * R5 SimpleWorkerContext and load it with all the definitions from R4 (that's how the + * validator works internally, so this is well tested code). But you only need to set + * up the R5 context once; then you can create instances of these to wrap the objects you + * want rendered on the fly. (is thread safe) + * */ public class ResourceWrapperR4B extends ResourceWrapper { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java index 5fcb7646f..4088d41e9 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java @@ -343,6 +343,24 @@ public class Element extends Base implements NamedItem { } } + public void setChildValue(String name, Base value) { + if (children == null) + children = new NamedItemList(); + for (Element child : children) { + if (name.equals(child.getName())) { + if (!child.isPrimitive()) + throw new Error("Cannot set a value of a non-primitive type ("+name+" on "+this.getName()+")"); + child.setValue(value.primitiveValue()); + } + } + + try { + setProperty(name.hashCode(), name, value); + } catch (FHIRException e) { + throw new Error(e); + } + } + public List getChildren(String name) { List res = new ArrayList(); if (children.size() > 20) { @@ -478,6 +496,11 @@ public class Element extends Base implements NamedItem { children.add(i, ne); childForValue = ne; break; + } else if (p.getName().endsWith("[x]") && name.startsWith(p.getName().replace("[x]", ""))) { + Element ne = new Element(p.getName(), p).setFormat(format); + children.add(i, ne); + childForValue = ne; + break; } } @@ -485,7 +508,7 @@ public class Element extends Base implements NamedItem { throw new Error("Cannot set property "+name+" on "+this.name); else if (value.isPrimitive()) { if (childForValue.property.getName().endsWith("[x]")) - childForValue.name = name+Utilities.capitalize(value.fhirType()); + childForValue.name = childForValue.name.replace("[x]", "")+Utilities.capitalize(value.fhirType()); childForValue.setValue(value.primitiveValue()); } else { Element ve = (Element) value; @@ -693,6 +716,7 @@ public class Element extends Base implements NamedItem { public Element getNamedChild(String name) { return getNamedChild(name, true); } + public Element getNamedChild(String name, boolean exception) { if (children == null) return null; @@ -1163,7 +1187,9 @@ public class Element extends Base implements NamedItem { } public void removeChild(String name) { - children.removeIf(n -> name.equals(n.getName())); + if (children.removeIf(n -> name.equals(n.getName()))) { + children.clearMap(); + } } public boolean isProhibited() { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Property.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Property.java index 6a5e8a22a..4440ca536 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Property.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Property.java @@ -641,7 +641,7 @@ public class Property { public boolean isTranslatable() { boolean ok = ToolingExtensions.readBoolExtension(definition, ToolingExtensions.EXT_TRANSLATABLE); - if (!ok && !definition.getPath().endsWith(".id") && !Utilities.existsInList(definition.getBase().getPath(), "Resource.id", "Reference.reference", "Coding.version", "Identifier.value", "SampledData.offsets", "SampledData.data", "ContactPoint.value")) { + if (!ok && !definition.getPath().endsWith(".id") && !definition.getPath().endsWith(".linkId") && !Utilities.existsInList(definition.getBase().getPath(), "Resource.id", "Reference.reference", "Coding.version", "Identifier.value", "SampledData.offsets", "SampledData.data", "ContactPoint.value")) { String t = getType(); ok = Utilities.existsInList(t, "string", "markdown"); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ActorDefinitionRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ActorDefinitionRenderer.java index dbfd7750f..099ad485f 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ActorDefinitionRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ActorDefinitionRenderer.java @@ -24,13 +24,9 @@ public class ActorDefinitionRenderer extends ResourceRenderer { @Override public void buildNarrative(RenderingStatus status, XhtmlNode x, ResourceWrapper r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome { - if (r.isDirect()) { - renderResourceTechDetails(r, x); - genSummaryTable(status, x, (ActorDefinition) r.getBase()); - render(status, x, (ActorDefinition) r.getBase(), r); - } else { - throw new Error("ActorDefinitionRenderer only renders native resources directly"); - } + renderResourceTechDetails(r, x); + genSummaryTable(status, x, r); + render(status, x, r); } @Override @@ -38,35 +34,35 @@ public class ActorDefinitionRenderer extends ResourceRenderer { return canonicalTitle(r); } - public void render(RenderingStatus status, XhtmlNode x, ActorDefinition acd, ResourceWrapper r) throws FHIRFormatError, DefinitionException, IOException { + public void render(RenderingStatus status, XhtmlNode x, ResourceWrapper acd) throws FHIRFormatError, DefinitionException, IOException { XhtmlNode tbl = x.table("grid"); XhtmlNode tr = tbl.tr(); - tr.td().b().tx(context.formatPhrase(RenderingContext.ACTOR_DEF_ACT, acd.getName()) + " "); - tr.td().tx(acd.getTitle()); - tr.td().tx(context.formatPhrase(RenderingContext.ACTOR_DEF_TYP, acd.getType().toCode()) + " "); + tr.td().b().tx(context.formatPhrase(RenderingContext.ACTOR_DEF_ACT, context.getTranslated(acd.child("name"))) + " "); + tr.td().tx(context.getTranslated(acd.child("title"))); + tr.td().tx(context.formatPhrase(RenderingContext.ACTOR_DEF_TYP, acd.primitiveValue("type")) + " "); XhtmlNode td = tbl.tr().td().colspan("3"); - addMarkdown(td, acd.getDocumentation()); - if (acd.hasReference()) { + addMarkdown(td, context.getTranslated(acd.child("documentation"))); + if (acd.has("reference")) { tbl.tr().td().tx(context.formatPhrase(RenderingContext.GENERAL_REFS)); td = tr.td().colspan("2"); boolean first = true; - for (UrlType t : acd.getReference()) { + for (ResourceWrapper t : acd.children("reference")) { if (first) first = false; else x.br(); - renderUri(status, td, wrapWC(r, t)); + renderUri(status, td, t); } } - if (acd.hasCapabilities()) { + if (acd.has("capabilities")) { tbl.tr().td().tx(context.formatPhrase(RenderingContext.ACTOR_DEF_CAP)); td = tr.td().colspan("2"); - renderCanonical(status, r, td, CapabilityStatement.class, acd.getCapabilitiesElement()); + renderCanonical(status, td, acd.child("capabilities")); } - if (acd.hasDerivedFrom()) { + if (acd.has("derivedFrom")) { tbl.tr().td().tx(context.formatPhrase(RenderingContext.ACTOR_DEF_DER)); td = tr.td().colspan("2"); boolean first = true; - for (UrlType t : acd.getReference()) { + for (ResourceWrapper t : acd.children("reference")) { if (first) first = false; else x.br(); - renderUri(status, r, td, t); + renderUri(status, td, t); } } } 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 09eff7d09..af14999d7 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 @@ -69,7 +69,11 @@ public class BundleRenderer extends ResourceRenderer { if (id != null && !context.hasAnchor(anchor)) { context.addAnchor(anchor); root.an(context.prefixAnchor(anchor)); - root.an(context.prefixAnchor("hc"+anchor)); + } + anchor = "hc"+anchor; + if (id != null && !context.hasAnchor(anchor)) { + context.addAnchor(anchor); + root.an(context.prefixAnchor(anchor)); } } root.hr(); @@ -100,8 +104,10 @@ public class BundleRenderer extends ResourceRenderer { xn = new XhtmlNode(); xn.para().b().tx(context.formatPhrase(RenderingContext.BUNDLE_REV_EXCP, e.getMessage()) + " "); } + } else { + xn.stripAnchorsByName(context.getAnchors()); } - root.blockquote().para().addChildren(xn); + root.blockquote().addChildren(xn); } if (be.has("request")) { renderRequest(x, be.child("request")); 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 ff2490492..8b38a82b8 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 @@ -1830,7 +1830,7 @@ public class DataRenderer extends Renderer implements CodeResolver { x.addText(q.child("high").primitiveValue("value").toString()); else x.tx("?"); - if (q.child("low").has("unit")) + if (q.has("low") && q.child("low").has("unit")) x.tx(" "+q.child("low").child("unit")); } @@ -2071,7 +2071,7 @@ public class DataRenderer extends Renderer implements CodeResolver { private boolean renderExpression(CommaSeparatedStringBuilder c, ResourceWrapper p) { ResourceWrapper exp = p.extensionValue("http://hl7.org/fhir/StructureDefinition/cqf-expression"); - if (exp == null) { + if (exp == null || !exp.has("value")) { return false; } c.append(exp.child("value").primitiveValue("expression")); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ProfileDrivenRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ProfileDrivenRenderer.java index 7d433e3d9..68b702c2a 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ProfileDrivenRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ProfileDrivenRenderer.java @@ -52,8 +52,10 @@ public class ProfileDrivenRenderer extends ResourceRenderer { generateByProfile(status, r, sd, r, sd.getSnapshot().getElement(), ed, context.getProfileUtilities().getChildList(sd, ed), x, r.fhirType(), context.isTechnicalMode(), 0); } } catch (Exception e) { - System.out.println(context.formatPhrase(RenderingContext.PROF_DRIV_ERR_GEN_NARR) +r.fhirType()+"/"+r.getId()+": "+e.getMessage()); - e.printStackTrace(); + if (DEBUG) { + System.out.println(context.formatPhrase(RenderingContext.PROF_DRIV_ERR_GEN_NARR) +r.fhirType()+"/"+r.getId()+": "+e.getMessage()); + e.printStackTrace(); + } x.para().b().style("color: maroon").tx(context.formatPhrase(RenderingContext.PROF_DRIV_EXCP, e.getMessage())+" "); } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/QuestionnaireRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/QuestionnaireRenderer.java index c685ebde2..82e5c3c0f 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/QuestionnaireRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/QuestionnaireRenderer.java @@ -362,7 +362,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer { defn.getPieces().add(gen.new Piece(null, (context.formatPhrase(RenderingContext.QUEST_OPTIONS)+" "), null)); if (context.getDefinitionsTarget() == null) { // if we don't have a definitions target, we'll add them below. - defn.getPieces().add(gen.new Piece("#opt-item."+i.primitiveValue("linkId"), Integer.toString(i.children("answerOption").size())+" "+Utilities.pluralize("option", i.children("answerOption").size()), null)); + defn.getPieces().add(gen.new Piece("#"+context.prefixAnchor("opt-item."+i.primitiveValue("linkId")), Integer.toString(i.children("answerOption").size())+" "+Utilities.pluralize("option", i.children("answerOption").size()), null)); } else { defn.getPieces().add(gen.new Piece(context.getDefinitionsTarget()+"#item."+i.primitiveValue("linkId"), Integer.toString(i.children("answerOption").size())+" "+Utilities.pluralize("option", i.children("answerOption").size()), null)); } 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 9b885e533..45f1de84f 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 @@ -40,6 +40,8 @@ import org.hl7.fhir.utilities.xhtml.XhtmlNode; */ public class Renderer { + protected static final boolean DEBUG = false; + public static class RenderingStatus { private boolean extensions; 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 bddedcdcb..4241bdadb 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 @@ -245,7 +245,6 @@ public abstract class ResourceRenderer extends DataRenderer { actual = type; } if (actual != null && actual.hasPrimitiveValue()) { - System.out.println("displayReference: "+actual); if ("#".equals(actual.primitiveValue())) { return "this resource"; } else { @@ -344,9 +343,12 @@ public abstract class ResourceRenderer extends DataRenderer { } else if (rr.getResource() == null) { String disp = display != null && display.hasPrimitiveValue() ? displayDataType(display) : "??"; x.ah(context.prefixLocalHref(rr.getWebPath())).tx(disp); - } else { + } else if (rr.getResource() != null) { String disp = display != null && display.hasPrimitiveValue() ? displayDataType(display) : RendererFactory.factory(rr.getResource(), context.forContained()).buildSummary(rr.getResource()); x.ah(context.prefixLocalHref(rr.getWebPath())).tx(disp); + } else { + String disp = display != null && display.hasPrimitiveValue() ? displayDataType(display) : "??"; + x.ah(context.prefixLocalHref(rr.getWebPath())).tx(disp); } } else if (display != null && id != null) { renderDataType(status, x, display); @@ -829,12 +831,24 @@ public abstract class ResourceRenderer extends DataRenderer { // first thing we do is lay down the resource anchors. if (!Utilities.noString(r.getId())) { if (!context.isSecondaryLang()) { - x.an(context.prefixAnchor(r.getScopedId())); - x.an(context.prefixAnchor("hc"+r.getScopedId())); + String sid = r.getScopedId(); + if (!context.hasAnchor(sid)) { + context.addAnchor(sid); + x.an(context.prefixAnchor(sid)); + } + sid = "hc"+sid; + if (!context.hasAnchor(sid)) { + context.addAnchor(sid); + x.an(context.prefixAnchor(sid)); + } } if (context.getLocale() != null) { String langSuffix = "-"+context.getLocale().toLanguageTag(); - x.an(context.prefixAnchor("hc"+r.getScopedId()+langSuffix)); + String sid = r.getScopedId()+langSuffix; + if (!context.hasAnchor(sid)) { + context.addAnchor(sid); + x.an(context.prefixAnchor(sid)); + } } } @@ -1050,6 +1064,99 @@ public abstract class ResourceRenderer extends DataRenderer { } } + + public void genSummaryTable(RenderingStatus status, XhtmlNode x, ResourceWrapper cr) throws IOException { + if (context.isShowSummaryTable() && cr != null) { + XhtmlNode tbl = x.table("grid"); + genSummaryTableContent(status, tbl, cr); + } + } + + + protected void genSummaryTableContent(RenderingStatus status, XhtmlNode tbl, ResourceWrapper cr) throws IOException { + XhtmlNode tr; + if (cr.has("url")) { + tr = tbl.tr(); + tr.td().tx(context.formatPhrase(RenderingContext.GENERAL_DEFINING_URL)+":"); + tr.td().code().tx(cr.primitiveValue("url")); + } else if (cr.hasExtension("http://hl7.org/fhir/5.0/StructureDefinition/extension-NamingSystem.url")) { + status.setExtensions(true); + tr = tbl.tr(); + tr.td().tx(context.formatPhrase(RenderingContext.GENERAL_DEFINING_URL)+":"); + tr.td().code().tx(cr.extensionString("http://hl7.org/fhir/5.0/StructureDefinition/extension-NamingSystem.url")); + } else if (!context.isContained()) { + tr = tbl.tr(); + tr.td().tx(context.formatPhrase(RenderingContext.GENERAL_DEFINING_URL)); + tr.td(); + } + if (cr.has("version")) { + tr = tbl.tr(); + tr.td().tx(context.formatPhrase(RenderingContext.GENERAL_VER)+":"); + renderDataType(status, tr.td(), cr.child("version")); + } else if (cr.hasExtension("http://terminology.hl7.org/StructureDefinition/ext-namingsystem-version")) { + status.setExtensions(true); + tr = tbl.tr(); + tr.td().tx(context.formatPhrase(RenderingContext.GENERAL_VER)+":"); + renderDataType(status, tr.td(), cr.extensionValue("http://hl7.org/fhir/5.0/StructureDefinition/extension-NamingSystem.version")); + } + + String name = context.getTranslated(cr.child("name")); + String title = context.getTranslated(cr.child("title")); + + if (name != null) { + tr = tbl.tr(); + tr.td().tx(context.formatPhrase(RenderingContext.GENERAL_NAME)+":"); + tr.td().tx(name); + } + + if (title != null && !title.equalsIgnoreCase(name)) { + tr = tbl.tr(); + tr.td().tx(context.formatPhrase(RenderingContext.GENERAL_TITLE)+":"); + tr.td().tx(title); + } + + if (cr.has("status") && !context.isContained()) { + tr = tbl.tr(); + tr.td().tx(context.formatPhrase(RenderingContext.GENERAL_STATUS)+":"); + tr.td().tx(describeStatus(status, cr)); + } + + if (cr.has("description")) { + tr = tbl.tr(); + tr.td().tx(context.formatPhrase(RenderingContext.GENERAL_DEFINITION)+":"); + tr.td().markdown(context.getTranslated(cr.child("description")), "description"); + } + + if (cr.has("publisher")) { + tr = tbl.tr(); + tr.td().tx(context.formatPhrase(RenderingContext.CANON_REND_PUBLISHER)+":"); + buildPublisherLinks( tr.td(), cr); + } + + if (cr.hasExtension(ToolingExtensions.EXT_WORKGROUP)) { + status.setExtensions(true); + tr = tbl.tr(); + tr.td().tx(context.formatPhrase(RenderingContext.CANON_REND_COMMITTEE)+":"); + renderCommitteeLink(tr.td(), cr); + } + + if (cr.has("copyright")) { + tr = tbl.tr(); + tr.td().tx(context.formatPhrase(RenderingContext.GENERAL_COPYRIGHT)+":"); + tr.td().markdown(context.getTranslated(cr.child("copyright")), "copyright"); + } + + if (cr.hasExtension(ToolingExtensions.EXT_FMM_LEVEL)) { + status.setExtensions(true); + // Use hard-coded spec link to point to current spec because DSTU2 had maturity listed on a different page + tr = tbl.tr(); + tr.td().ah("http://hl7.org/fhir/versions.html#maturity", "Maturity Level").attribute("class", "fmm").tx(context.formatPhrase(RenderingContext.CANON_REND_COMMITTEE)+":"); + renderDataType(status, tr.td(), cr.extensionValue(ToolingExtensions.EXT_FMM_LEVEL)); + } + } + + + public void genSummaryTable(RenderingStatus status, XhtmlNode x, CanonicalResource cr) throws IOException { if (context.isShowSummaryTable() && cr != null) { XhtmlNode tbl = x.table("grid"); @@ -1063,12 +1170,12 @@ public abstract class ResourceRenderer extends DataRenderer { if (cr.hasUrl()) { tr = tbl.tr(); tr.td().tx(context.formatPhrase(RenderingContext.GENERAL_DEFINING_URL)+":"); - tr.td().tx(cr.getUrl()); + tr.td().code().tx(cr.getUrl()); } else if (cr.hasExtension("http://hl7.org/fhir/5.0/StructureDefinition/extension-NamingSystem.url")) { status.setExtensions(true); tr = tbl.tr(); tr.td().tx(context.formatPhrase(RenderingContext.GENERAL_DEFINING_URL)); - tr.td().tx(ToolingExtensions.readStringExtension(cr, "http://hl7.org/fhir/5.0/StructureDefinition/extension-NamingSystem.url")+":"); + tr.td().code().tx(ToolingExtensions.readStringExtension(cr, "http://hl7.org/fhir/5.0/StructureDefinition/extension-NamingSystem.url")+":"); } else if (!context.isContained()) { tr = tbl.tr(); tr.td().tx(context.formatPhrase(RenderingContext.GENERAL_DEFINING_URL)); @@ -1115,14 +1222,14 @@ public abstract class ResourceRenderer extends DataRenderer { if (cr.hasPublisher()) { tr = tbl.tr(); tr.td().tx(context.formatPhrase(RenderingContext.CANON_REND_PUBLISHER)+":"); - tr.td().tx(buildPublisherLinks(cr)); + buildPublisherLinks(tr.td(), cr); } if (cr.hasExtension(ToolingExtensions.EXT_WORKGROUP)) { status.setExtensions(true); tr = tbl.tr(); tr.td().tx(context.formatPhrase(RenderingContext.CANON_REND_COMMITTEE)+":"); - tr.td().tx(renderCommitteeLink(cr)); + renderCommitteeLink(tr.td(), cr); } if (cr.hasCopyright()) { @@ -1141,68 +1248,137 @@ public abstract class ResourceRenderer extends DataRenderer { } - protected String renderCommitteeLink(CanonicalResource cr) { - String code = ToolingExtensions.readStringExtension(cr, ToolingExtensions.EXT_WORKGROUP); + protected void renderCommitteeLink(XhtmlNode x, ResourceWrapper cr) { + String code = cr.extensionString(ToolingExtensions.EXT_WORKGROUP); CodeSystem cs = context.getContext().fetchCodeSystem("http://terminology.hl7.org/CodeSystem/hl7-work-group"); if (cs == null || !cs.hasWebPath()) - return code; + x.tx(code); else { ConceptDefinitionComponent cd = CodeSystemUtilities.findCode(cs.getConcept(), code); if (cd == null) { - return code; + x.tx(code); } else { - return ""+cd.getDisplay()+""; + x.ah(cs.getWebPath()+"#"+cs.getId()+"-"+cd.getCode()).tx(cd.getDisplay()); } } } - private String buildPublisherLinks(CanonicalResource cr) { - CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(". "); + private void buildPublisherLinks(XhtmlNode x, CanonicalResource cr) { boolean useName = false; for (ContactDetail cd : cr.getContact()) { if (!cd.hasName()) { useName = true; } } + boolean first = true; if (!useName) { - b.append(Utilities.escapeXml(cr.getPublisher())); + x.tx(Utilities.escapeXml(cr.getPublisher())); + first = false; } for (ContactDetail cd : cr.getContact()) { String name = cd.hasName() ? cd.getName() : cr.getPublisher(); - b.append(renderContact(name, cd.getTelecom())); + if (cd.hasTelecom()) { + if (first) first = false; else x.tx(". "); + renderContact(x, name, cd.getTelecom()); + } } - return b.toString(); } - private String renderContact(String name, List telecom) { + private void buildPublisherLinks(XhtmlNode x, ResourceWrapper cr) { + boolean useName = false; + for (ResourceWrapper cd : cr.children("contact")) { + if (!cd.has("name")) { + useName = true; + } + } + boolean first = true; + if (!useName) { + x.tx(Utilities.escapeXml(cr.primitiveValue("publisher"))); + first = false; + } + for (ResourceWrapper cd : cr.children("contact")) { + String name = cd.has("name") ? cd.primitiveValue("name") : cr.primitiveValue("publisher"); + if (cd.has("telecom")) { + if (first) first = false; else x.tx(". "); + renderContactW(x, name, cd.children("telecom")); + } + } + } + + + private void renderContactW(XhtmlNode x, String name, List telecom) { + List urls = new ArrayList<>(); + for (ResourceWrapper t : telecom) { + if ("url".equals(t.primitiveValue()) && t.has("value")) { + urls.add(t.primitiveValue("value")); + } + } + if (urls.size() == 1) { + x.ah(urls.get(0)).tx(name); + } else { // if (urls.size() == 0) { + x.tx(name); + } + for (ResourceWrapper t : telecom) { + String system = t.primitiveValue("system"); + String value = t.primitiveValue("value"); + if ("url".equals(system) && value != null && urls.size() != 1) { + x.tx(", "); + x.ah(t.primitiveValue("value")).tx("Link"); + } + if ("email".equals(system) && value != null) { + x.tx(", "); + x.ah("mailto:"+t.primitiveValue("value")).tx("Email"); + } + if ("phone".equals(system) && value != null) { + x.tx(", "); + x.tx(t.primitiveValue("value")); + } + if ("fax".equals(system) && value != null) { + x.tx(", "); + x.tx("Fax:"+t.primitiveValue("value")); + } + } + } + + private void renderContact(XhtmlNode x, String name, List telecom) { List urls = new ArrayList<>(); for (ContactPoint t : telecom) { if (t.getSystem() == ContactPointSystem.URL && t.hasValue()) { urls.add(t.getValue()); } } - StringBuilder b = new StringBuilder(); if (urls.size() == 1) { - b.append(""+Utilities.escapeXml(name)+""); - } else if (urls.size() == 1) { - b.append(Utilities.escapeXml(name)); + x.ah(urls.get(0)).tx(name); + } else { // if (urls.size() == 0) { + x.tx(name); } for (ContactPoint t : telecom) { - b.append(", "); - if (t.getSystem() == ContactPointSystem.URL && t.hasValue() && urls.size() > 1) { - b.append("Link"); + if (t.getSystem() == ContactPointSystem.URL && t.hasValue() && urls.size() != 1) { + x.tx(", "); + x.ah(t.getValue()).tx("Link"); } if (t.getSystem() == ContactPointSystem.EMAIL && t.hasValue()) { - b.append("Email"); + x.tx(", "); + x.ah("mailto:"+t.getValue()).tx("Email"); } if (t.getSystem() == ContactPointSystem.PHONE && t.hasValue()) { - b.append(Utilities.escapeXml(t.getValue())); + x.tx(", "); + x.tx(t.getValue()); } if (t.getSystem() == ContactPointSystem.FAX && t.hasValue()) { - b.append("Fax:"+Utilities.escapeXml(t.getValue())); + x.tx(", "); + x.tx("Fax:"+t.getValue()); } } - return b.toString(); + } + + protected String describeStatus(RenderingStatus status, ResourceWrapper cr) { + String s = describeStatus(cr.primitiveValue("status"), cr.primitiveValue("experimental"), cr.child("date"), cr.extensionString("http://hl7.org/fhir/StructureDefinition/valueset-deprecated")); + if (cr.hasExtension(ToolingExtensions.EXT_STANDARDS_STATUS)) { + status.setExtensions(true); + s = s + presentStandardsStatus(cr.extensionString(ToolingExtensions.EXT_STANDARDS_STATUS)); + } + return s; } protected String describeStatus(RenderingStatus status, CanonicalResource cr) { @@ -1245,4 +1421,21 @@ public abstract class ResourceRenderer extends DataRenderer { } } + protected String describeStatus(String status, String experimental, ResourceWrapper dt, String deprecated) { + String sfx = dt != null ? " as of "+displayDataType(dt) : ""; + if ("true".equals(deprecated)) { + if ("retired".equals(status)) { + return "Deprecated + Retired"+sfx; + } else { + return "Deprecated"+sfx; + } + } else { + switch (status) { + case "active": return ("true".equals(experimental) ? "Experimental" : "Active")+sfx; + case "draft": return "Draft"+sfx; + case "retired": return "Retired"+sfx; + default: return "Unknown"+sfx; + } + } + } } \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/StructureDefinitionRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/StructureDefinitionRenderer.java index ef6dcf2ca..905e07319 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/StructureDefinitionRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/StructureDefinitionRenderer.java @@ -2779,7 +2779,9 @@ public class StructureDefinitionRenderer extends ResourceRenderer { } else { StructureDefinition sd = context.getWorker().fetchTypeDefinition(t); if (sd == null) { - System.out.println("Unable to find "+t); + if (DEBUG) { + System.out.println("Unable to find "+t); + } sd = context.getWorker().fetchTypeDefinition(t); } else if (sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE) { used = true; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/TerminologyRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/TerminologyRenderer.java index 4f19db591..1fcd82325 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/TerminologyRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/TerminologyRenderer.java @@ -31,7 +31,6 @@ import org.hl7.fhir.utilities.xhtml.XhtmlNode; public abstract class TerminologyRenderer extends ResourceRenderer { - private static final boolean DEBUG = false; public TerminologyRenderer(RenderingContext context) { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/RenderingContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/RenderingContext.java index 2e02f04a5..aac77792f 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/RenderingContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/RenderingContext.java @@ -1012,4 +1012,8 @@ public class RenderingContext extends RenderingI18nContext { public void addAnchor(String anchor) { anchors.add(anchor); } + + public Set getAnchors() { + return anchors; + } } \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/CanonicalResourceUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/CanonicalResourceUtilities.java index af7fd9853..d7e6b9635 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/CanonicalResourceUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/CanonicalResourceUtilities.java @@ -4,6 +4,7 @@ import java.util.List; import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.model.CanonicalResource; +import org.hl7.fhir.r5.model.CodeType; import org.hl7.fhir.r5.model.CompartmentDefinition; import org.hl7.fhir.r5.model.Constants; import org.hl7.fhir.r5.model.ContactDetail; @@ -71,9 +72,9 @@ public class CanonicalResourceUtilities { ext = res.addElement("extension"); ext.setChildValue("url", ToolingExtensions.EXT_WORKGROUP); } - ext.setChildValue("valueCode", code); + ext.setChildValue("valueCode", new CodeType(code)); res.setChildValue("publisher", "HL7 International / "+wg.getName()); - while (res.hasChild("contact")) { + while (res.hasChildren("contact")) { res.removeChild("contact"); } Element c = res.addElement("contact"); @@ -82,96 +83,96 @@ public class CanonicalResourceUtilities { t.setChildValue("value", wg.getLink()); } } - - /** - * for use in the core build where the context is not fully populated. Only known safe for R6 resources - * - * @param res - * @param code - */ - public static void setHl7WG(org.w3c.dom.Element res, String code) { - String rt = res.getNodeName(); - if (VersionUtilities.getExtendedCanonicalResourceNames("5.0.0").contains(rt)) { - var wg = HL7WorkGroups.find(code); - if (wg == null) { - throw new Error("Unknown WG "+code); - } - - List extensions = XMLUtil.getNamedChildren(res, "extension"); - org.w3c.dom.Element wgext = null; - for (org.w3c.dom.Element ext : extensions) { - String url = ext.getAttribute("url"); - if (ToolingExtensions.EXT_WORKGROUP.equals(url)) { - wgext = ext; - } - } - if (wgext == null) { - wgext = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "extension"); - wgext.setAttribute("url", ToolingExtensions.EXT_WORKGROUP); - org.w3c.dom.Element after = XMLUtil.getLastChild(res, "id", "meta", "text", "implicitRules", "language", "text", "contained"); - if (after != null) { - after = XMLUtil.getNextSibling(after); - } - res.insertBefore(wgext, after); - res.insertBefore(res.getOwnerDocument().createTextNode("\n "), after); - } - XMLUtil.clearChildren(wgext); - org.w3c.dom.Element valueCode = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "valueCode"); - wgext.appendChild(valueCode); - valueCode.setAttribute("value", code); - - org.w3c.dom.Element pub = XMLUtil.getNamedChild(res, "publisher"); - if (pub == null) { - pub = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "publisher"); - org.w3c.dom.Element after = XMLUtil.getLastChild(res, "id", "meta", "text", "implicitRules", "language", "text", "contained", "extension", "modifierExtension", - "url", "identifier", "version", "versionAlgorithmString", "versionAlgorithmCoding", "name", "title", "status", "experimental", "date", ("EvidenceReport".equals(rt) ? "subject" : "xx")); - if (after != null) { - after = XMLUtil.getNextSibling(after); - } - res.insertBefore(pub, after); - res.insertBefore(res.getOwnerDocument().createTextNode("\n "), after); - } - pub.setAttribute("value", "HL7 International / "+wg.getName()); - - org.w3c.dom.Element contact = XMLUtil.getNamedChild(res, "contact"); - if (contact == null) { - contact = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "contact"); - res.insertBefore(contact, XMLUtil.getNextSibling(pub)); - res.insertBefore(res.getOwnerDocument().createTextNode("\n "), contact.getNextSibling()); - } - - org.w3c.dom.Element telecom = XMLUtil.getNamedChild(contact, "telecom"); - if (telecom == null) { - contact.appendChild(res.getOwnerDocument().createTextNode("\n ")); - telecom = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "telecom"); - contact.appendChild(telecom); - contact.appendChild(res.getOwnerDocument().createTextNode("\n ")); - } - - org.w3c.dom.Element system = XMLUtil.getNamedChild(telecom, "system"); - if (system == null) { - system = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "system"); - org.w3c.dom.Element after = XMLUtil.getLastChild(telecom, "id", "extension"); - if (after != null) { - after = XMLUtil.getNextSibling(after); - } - telecom.insertBefore(system, after); - telecom.insertBefore(res.getOwnerDocument().createTextNode("\n "), after); - } - system.setAttribute("value", "url"); - - - org.w3c.dom.Element value = XMLUtil.getNamedChild(telecom, "value"); - if (value == null) { - value = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "value"); - org.w3c.dom.Element after = XMLUtil.getLastChild(telecom, "id", "extension", "system"); - if (after != null) { - after = XMLUtil.getNextSibling(after); - } - telecom.insertBefore(system, after); - telecom.insertBefore(res.getOwnerDocument().createTextNode("\n "), after); - } - value.setAttribute("value", wg.getLink()); - } - } +// +// /** +// * for use in the core build where the context is not fully populated. Only known safe for R6 resources +// * +// * @param res +// * @param code +// */ +// public static void setHl7WG(org.w3c.dom.Element res, String code) { +// String rt = res.getNodeName(); +// if (VersionUtilities.getExtendedCanonicalResourceNames("5.0.0").contains(rt)) { +// var wg = HL7WorkGroups.find(code); +// if (wg == null) { +// throw new Error("Unknown WG "+code); +// } +// +// List extensions = XMLUtil.getNamedChildren(res, "extension"); +// org.w3c.dom.Element wgext = null; +// for (org.w3c.dom.Element ext : extensions) { +// String url = ext.getAttribute("url"); +// if (ToolingExtensions.EXT_WORKGROUP.equals(url)) { +// wgext = ext; +// } +// } +// if (wgext == null) { +// wgext = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "extension"); +// wgext.setAttribute("url", ToolingExtensions.EXT_WORKGROUP); +// org.w3c.dom.Element after = XMLUtil.getLastChild(res, "id", "meta", "text", "implicitRules", "language", "text", "contained"); +// if (after != null) { +// after = XMLUtil.getNextSibling(after); +// } +// res.insertBefore(wgext, after); +// res.insertBefore(res.getOwnerDocument().createTextNode("\n "), after); +// } +// XMLUtil.clearChildren(wgext); +// org.w3c.dom.Element valueCode = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "valueCode"); +// wgext.appendChild(valueCode); +// valueCode.setAttribute("value", code); +// +// org.w3c.dom.Element pub = XMLUtil.getNamedChild(res, "publisher"); +// if (pub == null) { +// pub = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "publisher"); +// org.w3c.dom.Element after = XMLUtil.getLastChild(res, "id", "meta", "text", "implicitRules", "language", "text", "contained", "extension", "modifierExtension", +// "url", "identifier", "version", "versionAlgorithmString", "versionAlgorithmCoding", "name", "title", "status", "experimental", "date", ("EvidenceReport".equals(rt) ? "subject" : "xx")); +// if (after != null) { +// after = XMLUtil.getNextSibling(after); +// } +// res.insertBefore(pub, after); +// res.insertBefore(res.getOwnerDocument().createTextNode("\n "), after); +// } +// pub.setAttribute("value", "HL7 International / "+wg.getName()); +// +// org.w3c.dom.Element contact = XMLUtil.getNamedChild(res, "contact"); +// if (contact == null) { +// contact = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "contact"); +// res.insertBefore(contact, XMLUtil.getNextSibling(pub)); +// res.insertBefore(res.getOwnerDocument().createTextNode("\n "), contact.getNextSibling()); +// } +// +// org.w3c.dom.Element telecom = XMLUtil.getNamedChild(contact, "telecom"); +// if (telecom == null) { +// contact.appendChild(res.getOwnerDocument().createTextNode("\n ")); +// telecom = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "telecom"); +// contact.appendChild(telecom); +// contact.appendChild(res.getOwnerDocument().createTextNode("\n ")); +// } +// +// org.w3c.dom.Element system = XMLUtil.getNamedChild(telecom, "system"); +// if (system == null) { +// system = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "system"); +// org.w3c.dom.Element after = XMLUtil.getLastChild(telecom, "id", "extension"); +// if (after != null) { +// after = XMLUtil.getNextSibling(after); +// } +// telecom.insertBefore(system, after); +// telecom.insertBefore(res.getOwnerDocument().createTextNode("\n "), after); +// } +// system.setAttribute("value", "url"); +// +// +// org.w3c.dom.Element value = XMLUtil.getNamedChild(telecom, "value"); +// if (value == null) { +// value = res.getOwnerDocument().createElementNS(Constants.NS_FHIR_ROOT, "value"); +// org.w3c.dom.Element after = XMLUtil.getLastChild(telecom, "id", "extension", "system"); +// if (after != null) { +// after = XMLUtil.getNextSibling(after); +// } +// telecom.insertBefore(system, after); +// telecom.insertBefore(res.getOwnerDocument().createTextNode("\n "), after); +// } +// value.setAttribute("value", wg.getLink()); +// } +// } } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/NamedItemList.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/NamedItemList.java index 8d005bd22..b0815810b 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/NamedItemList.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/NamedItemList.java @@ -137,4 +137,7 @@ public class NamedItemList v2l) { + for (String v2 : v2l) { + if (versionsMatch(v1, v2)) { + return true; + } + } + return false; + } public static boolean isR5VerOrLater(String version) { if (version == null) { diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java index 811985d82..15dfc7741 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java @@ -1085,6 +1085,7 @@ public class I18nConstants { public static final String IG_DEPENDENCY_CLASH_PACKAGEID = "IG_DEPENDENCY_CLASH_PACKAGEID"; public static final String IG_DEPENDENCY_CLASH_CANONICAL = "IG_DEPENDENCY_CLASH_CANONICAL"; public static final String IG_DEPENDENCY_NO_PACKAGE = "IG_DEPENDENCY_NO_PACKAGE"; + public static final String IG_NO_VERSION = "IG_NO_VERSION"; public static final String IG_DEPENDENCY_NO_VERSION = "IG_DEPENDENCY_NO_VERSION"; public static final String IG_DEPENDENCY_INVALID_PACKAGE_VERSION = "IG_DEPENDENCY_INVALID_PACKAGE_VERSION"; public static final String IG_DEPENDENCY_VERSION_ERROR = "IG_DEPENDENCY_VERSION_ERROR"; diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/POGenerator.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/POGenerator.java index 8975bd705..2a9d04c19 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/POGenerator.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/POGenerator.java @@ -87,6 +87,7 @@ public class POGenerator { } private List prefixes = new ArrayList<>(); + private int noTrans = 0; private void execute(String core, String igpub, String pascal) throws IOException { String source = Utilities.path(core, "/org.hl7.fhir.utilities/src/main/resources"); @@ -409,7 +410,7 @@ public class POGenerator { if (o.duplicate) { b.append("msgctxt \""+o.id+"\"\r\n"); } - String m = tfxMode && Utilities.noString(o.msgid) ? "-- no content: do not translate --" : o.msgid; + String m = tfxMode && Utilities.noString(o.msgid) ? "-- no content: do not translate #"+(++noTrans )+" --" : o.msgid; b.append("msgid \""+wrapQuotes(m)+"\"\r\n"); if (o.msgidPlural != null) { b.append("msgid_plural \""+wrapQuotes(o.msgidPlural)+"\"\r\n"); @@ -417,7 +418,11 @@ public class POGenerator { o.msgstr.add(""); } for (int i = 0; i < o.msgstr.size(); i++) { - b.append("msgstr["+i+"] \""+wrapQuotes(o.msgstr.get(i))+"\"\r\n"); + String s = o.msgstr.get(i); +// if (tfxMode && Utilities.noString(s)) { +// s = Utilities.noString(i == 0 ? o.msgid : o.msgidPlural) ? "-- no content: do not translate --" : ""; +// } + b.append("msgstr["+i+"] \""+wrapQuotes(s)+"\"\r\n"); } } else { if (o.msgstr.size() == 0) { diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java index eb5ef8dbc..4ca4eee00 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java @@ -1168,11 +1168,11 @@ public class HierarchicalTableGenerator { } public String prefixAnchor(String anchor) { - return uniqueLocalPrefix == null ? anchor : uniqueLocalPrefix+"-" + anchor; + return Utilities.noString(uniqueLocalPrefix) ? anchor : uniqueLocalPrefix+"-" + anchor; } public String prefixLocalHref(String url) { - if (url == null || uniqueLocalPrefix == null || !url.startsWith("#")) { + if (url == null || Utilities.noString(uniqueLocalPrefix) || !url.startsWith("#")) { return url; } return "#"+uniqueLocalPrefix+"-"+url.substring(1); diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java index cccc018a3..1826e480f 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java @@ -39,6 +39,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.instance.model.api.IBaseXhtml; @@ -1127,4 +1128,15 @@ public class XhtmlNode extends XhtmlFluent implements IBaseXhtml { default: return 0; } } + + + public void stripAnchorsByName(Set anchors) { + if (hasChildren()) { + childNodes.removeIf(n -> "a".equals(n.getName()) && anchors.contains(n.getAttribute("name"))); + for (XhtmlNode c : childNodes) { + c.stripAnchorsByName(anchors); + } + } + } + } \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java index d21b848df..e0ec55f35 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java @@ -1137,7 +1137,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat timeTracker.tx(t, "vc "+system+"#"+code+" '"+display+"'"); if (s == null) return true; - ok = processTxIssues(errors, s, element, path, null, false, null) & ok; + ok = processTxIssues(errors, s, element, path, null, "no binding on code", false, null) & ok; if (s.isOk()) { if (s.getMessage() != null && !s.messageIsInIssues()) { @@ -1393,7 +1393,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (cc.hasCoding()) { long t = System.nanoTime(); ValidationResult vr = checkCodeOnServer(stack, null, cc); - bh.see(processTxIssues(errors, vr, element, path, org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.INFORMATION, false, null)); + bh.see(processTxIssues(errors, vr, element, path, org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.INFORMATION, null, false, null)); timeTracker.tx(t, "vc " + cc.toString()); } } catch (CheckCodeOnServerException e) { @@ -1477,7 +1477,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } else { checked.set(true); ValidationResult vr = checkCodeOnServer(stack, valueset, cc); - bh.see(processTxIssues(errors, vr, element, path, notFoundSeverityForBinding(strength), false, vsRef)); + bh.see(processTxIssues(errors, vr, element, path, notFoundSeverityForBinding(strength), notFoundSeverityNoteForBinding(strength), false, vsRef)); if (!vr.isOk()) { bindingsOk = false; if (vr.getErrorClass() != null && vr.getErrorClass() == TerminologyServiceErrorClass.NOSERVICE) { @@ -1545,6 +1545,14 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat return checkDisp; } + private String notFoundSeverityNoteForBinding(BindingStrength strength) { + if (strength == BindingStrength.REQUIRED) { + return "error because this is a required binding"; + } else { + return null; + } + } + /** * The terminology server will report an error for an unknown code system or version, or a dependent valueset * @@ -1563,7 +1571,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } private boolean processTxIssues(List errors, ValidationResult vr, Element element, String path, - org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity notFoundLevel, boolean ignoreCantInfer, String vsurl) { + org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity notFoundLevel, String notFoundNote, boolean ignoreCantInfer, String vsurl) { boolean ok = true; if (vr != null) { for (OperationOutcomeIssueComponent iss : vr.getIssues()) { @@ -1571,9 +1579,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat && !iss.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "this-code-not-in-vs") && !(ignoreCantInfer || iss.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "cannot-infer"))) { OperationOutcomeIssueComponent i = iss.copy(); - if (notFoundLevel != null && i.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "not-found")) { - if (i.getSeverity().isHigherThan(notFoundLevel) || (vsurl != null && i.getDetails().getText().contains(vsurl))) { - i.setSeverity(notFoundLevel); + if (i.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "not-found")) { + if (notFoundLevel != null && i.getSeverity().isHigherThan(notFoundLevel) || (vsurl != null && i.getDetails().getText().contains(vsurl))) { + i.setSeverity(notFoundLevel); + } + if (notFoundNote != null) { + i.getDetails().setText(i.getDetails().getText()+" ("+notFoundNote+")"); } } if (baseOptions.isDisplayWarningMode() && i.getSeverity() == org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.ERROR && i.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "invalid-display")) { @@ -1593,7 +1604,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat boolean ok = true; if (isNotBlank(nextCoding.getCode()) && isNotBlank(nextCoding.getSystem()) && context.supportsSystem(nextCoding.getSystem(), baseOptions.getFhirVersion())) { ValidationResult vr = checkCodeOnServer(stack, valueset, nextCoding); - ok = processTxIssues(errors, vr, element, path, null, false, null) && ok; + ok = processTxIssues(errors, vr, element, path, null, "ex-checkBindings", false, null) && ok; if (vr.getSeverity() != null && !vr.messageIsInIssues()) { if (vr.getSeverity() == IssueSeverity.INFORMATION) { @@ -1722,7 +1733,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (strength == BindingStrength.REQUIRED) { removeTrackedMessagesForLocation(errors, element, path); } - ok = processTxIssues(errors, vr, element, path, notFoundSeverityForBinding(strength), false, vsRef) && ok; + ok = processTxIssues(errors, vr, element, path, notFoundSeverityForBinding(strength), notFoundSeverityNoteForBinding(strength), false, vsRef) && ok; timeTracker.tx(t, "vc "+system+"#"+code+" '"+display+"'"); if (vr != null && !vr.isOk()) { if (vr.IsNoService()) @@ -1852,7 +1863,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat try { long t = System.nanoTime(); ValidationResult vr = checkCodeOnServer(stack, valueset, cc); - ok = processTxIssues(errors, vr, element, path, null, false, maxVSUrl) && ok; + ok = processTxIssues(errors, vr, element, path, null, "ex-checkMaxValueSet", false, maxVSUrl) && ok; timeTracker.tx(t, "vc "+cc.toString()); if (!vr.isOk()) { if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) @@ -1891,7 +1902,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat try { long t = System.nanoTime(); ValidationResult vr = checkCodeOnServer(stack, valueset, c); - ok = processTxIssues(errors, vr, element, path, null, false, maxVSUrl) && ok; + ok = processTxIssues(errors, vr, element, path, null, "ex-checkMaxValueSet-2", false, maxVSUrl) && ok; timeTracker.tx(t, "vc "+c.getSystem()+"#"+c.getCode()+" '"+c.getDisplay()+"'"); if (!vr.isOk()) { @@ -1922,7 +1933,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat try { long t = System.nanoTime(); ValidationResult vr = checkCodeOnServer(stack, valueset, value, baseOptions.withLanguage(stack.getWorkingLang())); - ok = processTxIssues(errors, vr, element, path, null, false, maxVSUrl) && ok; + ok = processTxIssues(errors, vr, element, path, null, "ex-checkMaxValueSet-3", false, maxVSUrl) && ok; timeTracker.tx(t, "vc "+value); if (!vr.isOk()) { if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) @@ -2046,7 +2057,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat checked.set(true); vr = checkCodeOnServer(stack, valueset, c); } - ok = processTxIssues(errors, vr, element, path, notFoundSeverityForBinding(strength), strength == BindingStrength.EXTENSIBLE, vsRef) && ok; + ok = processTxIssues(errors, vr, element, path, notFoundSeverityForBinding(strength), notFoundSeverityNoteForBinding(strength), strength == BindingStrength.EXTENSIBLE, vsRef) && ok; timeTracker.tx(t, "vc "+c.getSystem()+"#"+c.getCode()+" '"+c.getDisplay()+"'"); if (strength == BindingStrength.REQUIRED) { @@ -3482,7 +3493,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } vr = checkCodeOnServer(stack, vs, value, options); } - ok = processTxIssues(errors, vr, element, path, notFoundSeverityForBinding(binding.getStrength()), binding.getStrength() != BindingStrength.REQUIRED, binding.getValueSet()) && ok; + ok = processTxIssues(errors, vr, element, path, notFoundSeverityForBinding(binding.getStrength()), notFoundSeverityNoteForBinding(binding.getStrength()), binding.getStrength() != BindingStrength.REQUIRED, binding.getValueSet()) && ok; timeTracker.tx(t, "vc "+value+""); if (binding.getStrength() == BindingStrength.REQUIRED) { @@ -4608,7 +4619,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat String fullUrl = null; // we're going to try to work this out as we go up while (focus != null) { // track the stack while we can - if (focus.getSpecial() == SpecialElement.BUNDLE_ENTRY && fullUrl == null && focus != null && focus.getParentForValidator().getName().equals(ENTRY)) { + if (focus.getSpecial() == SpecialElement.BUNDLE_ENTRY && fullUrl == null && focus != null && focus.getParentForValidator() != null && focus.getParentForValidator().getName().equals(ENTRY)) { String type = focus.getParentForValidator().getChildValue(TYPE); fullUrl = focus.getParentForValidator().getChildValue(FULL_URL); // we don't try to resolve contained references across this boundary if (fullUrl == null) diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ImplementationGuideValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ImplementationGuideValidator.java index e0f86f923..c7a7081a8 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ImplementationGuideValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ImplementationGuideValidator.java @@ -59,18 +59,24 @@ public class ImplementationGuideValidator extends BaseValidator { public boolean validateImplementationGuide(ValidationContext valContext, List errors, Element ig, NodeStack stack) { boolean ok = true; - String fver = ig.getNamedChildValue("fhirVersion"); - + List el = ig.getChildren("fhirVersion"); + List fvl = new ArrayList(); + for (Element e : el) { + String fver = e.primitiveValue(); + fvl.add(fver); + } + warning(errors, "2024-06-13", IssueType.BUSINESSRULE, ig.line(), ig.col(), stack.getLiteralPath(), !fvl.isEmpty(), I18nConstants.IG_NO_VERSION); List dependencies = ig.getChildrenByName("dependsOn"); int i = 0; for (Element dependency : dependencies) { - ok = checkDependency(errors, ig, stack.push(dependency, i, null, null), dependency, fver) && ok; + ok = checkDependency(errors, ig, stack.push(dependency, i, null, null), dependency, fvl) && ok; i++; } + return ok; } - private boolean checkDependency(List errors, Element ig, NodeStack stack, Element dependency, String fver) { + private boolean checkDependency(List errors, Element ig, NodeStack stack, Element dependency, List fvl) { boolean ok = true; String url = dependency.getNamedChildValue("url"); String packageId = dependency.getNamedChildValue("packageId"); @@ -95,13 +101,15 @@ public class ImplementationGuideValidator extends BaseValidator { ok = rule(errors, "2024-06-13", IssueType.BUSINESSRULE, dependency.line(), dependency.col(), stack.getLiteralPath(), (packageId+"#"+version).matches(FilesystemPackageCacheManager.PACKAGE_VERSION_REGEX), I18nConstants.IG_DEPENDENCY_INVALID_PACKAGE_VERSION, version) && ok; NpmPackage npm = pcm.loadPackage(packageId, version); if (warning(errors, "2024-06-13", IssueType.BUSINESSRULE, dependency.line(), dependency.col(), stack.getLiteralPath(), npm != null, I18nConstants.IG_DEPENDENCY_PACKAGE_UNKNOWN, packageId+"#"+version)) { - String pver = npm.fhirVersion(); - if (!VersionUtilities.versionsMatch(pver, fver)) { - if ("hl7.fhir.uv.extensions".equals(packageId)) { - ok = rule(errors, "2024-06-13", IssueType.BUSINESSRULE, dependency.line(), dependency.col(), stack.getLiteralPath(), false, I18nConstants.IG_DEPENDENCY_VERSION_ERROR, fver, packageId+"#"+version, pver, - "hl7.fhir.uv.extensions."+VersionUtilities.getNameForVersion(fver).toLowerCase()) && ok; - } else { - warning(errors, "2024-06-13", IssueType.BUSINESSRULE, dependency.line(), dependency.col(), stack.getLiteralPath(), false, I18nConstants.IG_DEPENDENCY_VERSION_WARNING, fver, packageId+"#"+version, pver); + if (fvl.isEmpty()) { + String pver = npm.fhirVersion(); + if (!VersionUtilities.versionsMatch(pver, fvl)) { + if ("hl7.fhir.uv.extensions".equals(packageId)) { + ok = rule(errors, "2024-06-13", IssueType.BUSINESSRULE, dependency.line(), dependency.col(), stack.getLiteralPath(), false, I18nConstants.IG_DEPENDENCY_VERSION_ERROR, CommaSeparatedStringBuilder.join(",", fvl), packageId+"#"+version, pver, + "hl7.fhir.uv.extensions."+VersionUtilities.getNameForVersion(fvl.get(0)).toLowerCase()) && ok; + } else { + warning(errors, "2024-06-13", IssueType.BUSINESSRULE, dependency.line(), dependency.col(), stack.getLiteralPath(), false, I18nConstants.IG_DEPENDENCY_VERSION_WARNING, CommaSeparatedStringBuilder.join(",", fvl), packageId+"#"+version, pver); + } } } } diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/all-systems.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/all-systems.cache index e570a0682..c611af8ff 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/all-systems.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/all-systems.cache @@ -3547,7 +3547,6 @@ v: { "code" : "image/png", "system" : "urn:ietf:bcp:13", "server" : "http://tx-dev.fhir.org/r4", - "unknown-systems" : "", "issues" : { "resourceType" : "OperationOutcome" } @@ -3568,6 +3567,26 @@ v: { "code" : "image/png", "system" : "urn:ietf:bcp:13", "server" : "http://tx-dev.fhir.org/r4", + "issues" : { + "resourceType" : "OperationOutcome" +} + +} +------------------------------------------------------------------------------------- +{"code" : { + "code" : "en-AU" +}, "url": "http://hl7.org/fhir/ValueSet/languages", "version": "4.0.1", "langs":"en-AU", "useServer":"true", "useClient":"true", "guessSystem":"true", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"true", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "English (Australia)", + "code" : "en-AU", + "system" : "urn:ietf:bcp:47", + "server" : "http://tx-dev.fhir.org/r4", "unknown-systems" : "", "issues" : { "resourceType" : "OperationOutcome" diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/loinc.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/loinc.cache index 3c8f154c2..509af9203 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/loinc.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/loinc.cache @@ -7522,6 +7522,29 @@ v: { "system" : "http://loinc.org", "version" : "2.77", "server" : "http://tx-dev.fhir.org/r4", + "issues" : { + "resourceType" : "OperationOutcome" +} + +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "3150-0", + "display" : "Inhaled oxygen concentration" +}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"false", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Inhaled oxygen concentration", + "code" : "3150-0", + "system" : "http://loinc.org", + "version" : "2.77", + "server" : "http://tx-dev.fhir.org/r4", "unknown-systems" : "", "issues" : { "resourceType" : "OperationOutcome" diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/snomed.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/snomed.cache index e730fd454..134a910a9 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/snomed.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/snomed.cache @@ -511,6 +511,23 @@ v: { "location" : ["CodeableConcept.coding[0].code"], "expression" : ["CodeableConcept.coding[0].code"] }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server", + "valueUrl" : "http://tx-dev.fhir.org/r4" + }], + "severity" : "information", + "code" : "invalid", + "details" : { + "coding" : [{ + "system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", + "code" : "code-rule" + }], + "text" : "The code '1419004' is valid but is not active" + }, + "location" : ["CodeableConcept.coding[0].code"], + "expression" : ["CodeableConcept.coding[0].code"] + }, { "extension" : [{ "url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server", @@ -867,6 +884,23 @@ v: { "location" : ["CodeableConcept.coding[0].code"], "expression" : ["CodeableConcept.coding[0].code"] }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server", + "valueUrl" : "http://tx-dev.fhir.org/r4" + }], + "severity" : "information", + "code" : "invalid", + "details" : { + "coding" : [{ + "system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", + "code" : "code-rule" + }], + "text" : "The code '324252006' is valid but is not active" + }, + "location" : ["CodeableConcept.coding[0].code"], + "expression" : ["CodeableConcept.coding[0].code"] + }, { "extension" : [{ "url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server", @@ -1126,6 +1160,23 @@ v: { "location" : ["CodeableConcept.coding[0].code"], "expression" : ["CodeableConcept.coding[0].code"] }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server", + "valueUrl" : "http://tx-dev.fhir.org/r4" + }], + "severity" : "information", + "code" : "invalid", + "details" : { + "coding" : [{ + "system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", + "code" : "code-rule" + }], + "text" : "The code '602001' is valid but is not active" + }, + "location" : ["CodeableConcept.coding[0].code"], + "expression" : ["CodeableConcept.coding[0].code"] + }, { "extension" : [{ "url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server", @@ -1707,6 +1758,23 @@ v: { "location" : ["CodeableConcept.coding[0].code"], "expression" : ["CodeableConcept.coding[0].code"] }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server", + "valueUrl" : "http://tx-dev.fhir.org/r4" + }], + "severity" : "information", + "code" : "invalid", + "details" : { + "coding" : [{ + "system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", + "code" : "code-rule" + }], + "text" : "The code '1419004' is valid but is not active" + }, + "location" : ["CodeableConcept.coding[0].code"], + "expression" : ["CodeableConcept.coding[0].code"] + }, { "extension" : [{ "url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server", @@ -8395,7 +8463,6 @@ v: { "system" : "http://snomed.info/sct", "version" : "http://snomed.info/sct/900000000000207008/version/20240201", "server" : "http://tx-dev.fhir.org/r4", - "unknown-systems" : "", "issues" : { "resourceType" : "OperationOutcome" } @@ -8418,6 +8485,77 @@ v: { "system" : "http://snomed.info/sct", "version" : "http://snomed.info/sct/900000000000207008/version/20240201", "server" : "http://tx-dev.fhir.org/r4", + "issues" : { + "resourceType" : "OperationOutcome" +} + +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://snomed.info/sct", + "code" : "442476006", + "display" : "Arterial oxygen saturation" +}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"false", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Arterial oxygen saturation", + "code" : "442476006", + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20240201", + "server" : "http://tx-dev.fhir.org/r4", + "unknown-systems" : "", + "issues" : { + "resourceType" : "OperationOutcome" +} + +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://snomed.info/sct", + "code" : "427081008", + "display" : "Delivered oxygen flow rate" +}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"false", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Delivered oxygen flow rate (observable entity)", + "code" : "427081008", + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20240201", + "server" : "http://tx-dev.fhir.org/r4", + "unknown-systems" : "", + "issues" : { + "resourceType" : "OperationOutcome" +} + +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://snomed.info/sct", + "code" : "250774007", + "display" : "Inspired oxygen concentration" +}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"false", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Inspired oxygen concentration", + "code" : "250774007", + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20240201", + "server" : "http://tx-dev.fhir.org/r4", "unknown-systems" : "", "issues" : { "resourceType" : "OperationOutcome" diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/ucum.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/ucum.cache index ba21c2ac7..bc099eeb9 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/ucum.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/ucum.cache @@ -1272,7 +1272,6 @@ v: { "system" : "http://unitsofmeasure.org", "version" : "2.0.1", "server" : "http://tx-dev.fhir.org/r4", - "unknown-systems" : "", "issues" : { "resourceType" : "OperationOutcome" } @@ -1295,7 +1294,6 @@ v: { "system" : "http://unitsofmeasure.org", "version" : "2.0.1", "server" : "http://tx-dev.fhir.org/r4", - "unknown-systems" : "", "issues" : { "resourceType" : "OperationOutcome" } @@ -1318,7 +1316,6 @@ v: { "system" : "http://unitsofmeasure.org", "version" : "2.0.1", "server" : "http://tx-dev.fhir.org/r4", - "unknown-systems" : "", "issues" : { "resourceType" : "OperationOutcome" } @@ -1341,7 +1338,6 @@ v: { "system" : "http://unitsofmeasure.org", "version" : "2.0.1", "server" : "http://tx-dev.fhir.org/r4", - "unknown-systems" : "", "issues" : { "resourceType" : "OperationOutcome" } @@ -1364,7 +1360,6 @@ v: { "system" : "http://unitsofmeasure.org", "version" : "2.0.1", "server" : "http://tx-dev.fhir.org/r4", - "unknown-systems" : "", "issues" : { "resourceType" : "OperationOutcome" } @@ -1387,7 +1382,6 @@ v: { "system" : "http://unitsofmeasure.org", "version" : "2.0.1", "server" : "http://tx-dev.fhir.org/r4", - "unknown-systems" : "", "issues" : { "resourceType" : "OperationOutcome" } @@ -1410,7 +1404,6 @@ v: { "system" : "http://unitsofmeasure.org", "version" : "2.0.1", "server" : "http://tx-dev.fhir.org/r4", - "unknown-systems" : "", "issues" : { "resourceType" : "OperationOutcome" } @@ -1433,6 +1426,28 @@ v: { "system" : "http://unitsofmeasure.org", "version" : "2.0.1", "server" : "http://tx-dev.fhir.org/r4", + "issues" : { + "resourceType" : "OperationOutcome" +} + +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://unitsofmeasure.org", + "code" : "%" +}, "url": "http://hl7.org/fhir/test/ValueSet/UcumVitalsCommonDE", "version": "1.5.0", "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "%", + "code" : "%", + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1", + "server" : "http://tx-dev.fhir.org/r4", "unknown-systems" : "", "issues" : { "resourceType" : "OperationOutcome"