From d63e66fa0bb94259ac356a9e3306b53507ad9b7e Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 9 May 2024 19:15:10 +1000 Subject: [PATCH 1/5] fix bug passing wrong type to tx server when using inferSystem --- .../org/hl7/fhir/r5/context/BaseWorkerContext.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java index e408f6b35..a192597a9 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java @@ -1483,9 +1483,11 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte protected Parameters constructParameters(ValidationOptions options, Coding coding) { Parameters pIn = new Parameters(); - pIn.addParameter().setName("coding").setValue(coding); if (options.isGuessSystem()) { pIn.addParameter().setName("inferSystem").setValue(new BooleanType(true)); + pIn.addParameter().setName("code").setValue(coding.getCodeElement()); + } else { + pIn.addParameter().setName("coding").setValue(coding); } setTerminologyOptions(options, pIn); return pIn; @@ -1500,9 +1502,11 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte protected Parameters constructParameters(ValidationOptions options, CodingValidationRequest codingValidationRequest, ValueSet valueSet) { Parameters pIn = new Parameters(); - pIn.addParameter().setName("coding").setValue(codingValidationRequest.getCoding()); if (options.isGuessSystem()) { pIn.addParameter().setName("inferSystem").setValue(new BooleanType(true)); + pIn.addParameter().setName("code").setValue(codingValidationRequest.getCoding().getCodeElement()); + } else { + pIn.addParameter().setName("coding").setValue(codingValidationRequest.getCoding()); } if (valueSet != null) { pIn.addParameter().setName("valueSet").setResource(valueSet); @@ -1514,9 +1518,11 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte protected Parameters constructParameters(ValidationOptions options, CodingValidationRequest codingValidationRequest, String vsUrl) { Parameters pIn = new Parameters(); - pIn.addParameter().setName("coding").setValue(codingValidationRequest.getCoding()); if (options.isGuessSystem()) { pIn.addParameter().setName("inferSystem").setValue(new BooleanType(true)); + pIn.addParameter().setName("code").setValue(codingValidationRequest.getCoding().getCodeElement()); + } else { + pIn.addParameter().setName("coding").setValue(codingValidationRequest.getCoding()); } if (vsUrl != null) { pIn.addParameter().setName("url").setValue(new CanonicalType(vsUrl)); From 256c494d91ba76e0ff4aa116814f4c2db30df8ae Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 9 May 2024 19:15:40 +1000 Subject: [PATCH 2/5] Fix bug using wrong message for value sets that are too costly to expand --- .../main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java | 4 ++-- .../org/hl7/fhir/utilities/i18n/RenderingI18nContext.java | 1 + .../src/main/resources/rendering-phrases.properties | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java index f7fd6fe29..a4a8d2552 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java @@ -207,7 +207,7 @@ public class ValueSetRenderer extends TerminologyRenderer { // } String msg = null; if (vs.getExpansion().getContains().isEmpty()) { - msg = context.formatMessage(RenderingContext.VALUE_SET_INF); // not sure that's true? + msg = context.formatMessage(RenderingContext.VALUE_SET_TOO_COSTLY); } else { msg = /*!#*/"This value set cannot be fully expanded, but a selection ("+countMembership(vs)+" codes) of the whole set of codes is shown here."; } @@ -487,7 +487,7 @@ public class ValueSetRenderer extends TerminologyRenderer { if (versions.size() == 1 && versions.get(s).size() == 1) { for (String v : versions.get(s)) { // though there'll only be one XhtmlNode p = x.para().style("border: black 1px dotted; background-color: #EEEEEE; padding: 8px; margin-bottom: 8px"); - p.tx(context.formatMessage(RenderingContext.VALUE_SET_EXPANSION)); + p.tx(context.formatMessage(RenderingContext.VALUE_SET_EXPANSION)+" "); expRef(p, s, v, vs); } } else { diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/RenderingI18nContext.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/RenderingI18nContext.java index 1bcb18ebe..23fd4a468 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/RenderingI18nContext.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/RenderingI18nContext.java @@ -575,6 +575,7 @@ public class RenderingI18nContext extends I18nBase { public static final String VALUE_SET_CONT = "VALUE_SET_CONT"; public static final String VALUE_SET_INF = "VALUE_SET_INF"; public static final String VALUE_SET_SEL = "VALUE_SET_SEL"; + public static final String VALUE_SET_TOO_COSTLY = "VALUE_SET_TOO_COSTLY"; public static final String VALUE_SET_LEVEL = "VALUE_SET_LEVEL"; public static final String VALUE_SET_CODE = "VALUE_SET_CODE"; public static final String VALUE_SET_SYSTEM = "VALUE_SET_SYSTEM"; diff --git a/org.hl7.fhir.utilities/src/main/resources/rendering-phrases.properties b/org.hl7.fhir.utilities/src/main/resources/rendering-phrases.properties index 0a2bd4bf6..83af7f3dc 100644 --- a/org.hl7.fhir.utilities/src/main/resources/rendering-phrases.properties +++ b/org.hl7.fhir.utilities/src/main/resources/rendering-phrases.properties @@ -582,6 +582,7 @@ TEST_PLAN_RESULT = Result VALUE_SET_CONT = Value Set Contents VALUE_SET_INF = This value set cannot be expanded because of the way it is defined - it has an infinite number of members. VALUE_SET_SEL = This value set has >1000 codes in it. In order to keep the publication size manageable, only a selection (1000 codes) of the whole set of codes is shown +VALUE_SET_TOO_COSTLY = This value set cannot be expanded because the terminology server(s) deemed it too costly to do so VALUE_SET_LEVEL = Level VALUE_SET_CODE = Code VALUE_SET_SYSTEM = System From 7be94402a5da35ec6f3606fecfe9fadcba9cbf97 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 9 May 2024 19:16:00 +1000 Subject: [PATCH 3/5] Fix bug calculating value set expansion size for multiple imports --- .../r5/terminologies/expansion/ValueSetExpander.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ValueSetExpander.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ValueSetExpander.java index 028ee4f3b..d7b168a01 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ValueSetExpander.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ValueSetExpander.java @@ -987,14 +987,19 @@ public class ValueSetExpander extends ValueSetProcessBase { } } - private void copyImportContains(List list, ValueSetExpansionContainsComponent parent, Parameters expParams, List filter, boolean noInactive, List vsProps, ValueSet vsSrc, ValueSetExpansionComponent exp) throws FHIRException, ETooCostly { + private int copyImportContains(List list, ValueSetExpansionContainsComponent parent, Parameters expParams, List filter, boolean noInactive, List vsProps, ValueSet vsSrc, ValueSetExpansionComponent exp) throws FHIRException, ETooCostly { + int count = 0; opContext.deadCheck(); for (ValueSetExpansionContainsComponent c : list) { c.checkNoModifiers("Imported Expansion in Code System", "expanding"); ValueSetExpansionContainsComponent np = addCode(dwc, c.getSystem(), c.getCode(), c.getDisplay(), vsSrc.getLanguage(), parent, null, expParams, c.getAbstract(), c.getInactive(), filter, noInactive, false, vsProps, makeCSProps(c.getExtensionString(ToolingExtensions.EXT_DEFINITION), null), null, c.getProperty(), null, c.getExtension(), exp, false); - copyImportContains(c.getContains(), np, expParams, filter, noInactive, vsProps, vsSrc, exp); + if (np != null) { + count++; + } + count = count + copyImportContains(c.getContains(), np, expParams, filter, noInactive, vsProps, vsSrc, exp); } + return count; } private void includeCodes(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, boolean heirarchical, boolean noInactive, List extensions, ValueSet valueSet) throws ETooCostly, FileNotFoundException, IOException, FHIRException, CodeSystemProviderExtension { @@ -1008,11 +1013,12 @@ public class ValueSetExpander extends ValueSetProcessBase { if (!inc.hasSystem()) { if (imports.isEmpty()) // though this is not supposed to be the case return; + dwc.resetTotal(); ValueSet base = imports.get(0); checkCanonical(exp, base, focus); imports.remove(0); base.checkNoModifiers("Imported ValueSet", "expanding"); - copyImportContains(base.getExpansion().getContains(), null, expParams, imports, noInactive, base.getExpansion().getProperty(), base, exp); + dwc.incTotal(copyImportContains(base.getExpansion().getContains(), null, expParams, imports, noInactive, base.getExpansion().getProperty(), base, exp)); } else { CodeSystem cs = context.fetchSupplementedCodeSystem(inc.getSystem()); if (ValueSetUtilities.isServerSide(inc.getSystem()) || (cs == null || (cs.getContent() != CodeSystemContentMode.COMPLETE && cs.getContent() != CodeSystemContentMode.FRAGMENT))) { From ba3dc458637f14a81a79550e018b6fe2efbef666 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 9 May 2024 19:16:33 +1000 Subject: [PATCH 4/5] Fix bug where some #refs are not resolved to the root of the resource in FHIRPath slicing evaluation --- .../expansion/WorkingContext.java | 4 ++ .../instance/InstanceValidator.java | 42 +++++++------------ 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/WorkingContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/WorkingContext.java index fafd0dc3b..235729288 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/WorkingContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/WorkingContext.java @@ -99,5 +99,9 @@ class WorkingContext { public void setNoTotal(boolean noTotal) { this.noTotal = noTotal; } + + public void resetTotal() { + total = 0; + } } \ 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 67212ab6e..a23d559f7 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 @@ -4644,57 +4644,47 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat private ResolvedReference localResolve(String ref, NodeStack stack, List errors, String path, Element rootResource, Element groupingResource, Element source, BooleanHolder bh) { if (ref.startsWith("#")) { - // work back through the parent list. + // work back through the parent list, tracking the stack as we go // really, there should only be one level for this (contained resources cannot contain // contained resources), but we'll leave that to some other code to worry about boolean wasContained = false; + Element focus = stack.getElement(); NodeStack nstack = stack; - while (nstack != null && nstack.getElement() != null) { - if (nstack.getElement().getProperty().isResource()) { + while (focus != null) { + if (focus.getProperty().isResource()) { // ok, we'll try to find the contained reference - if (ref.equals("#") && nstack.getElement().getSpecial() != SpecialElement.CONTAINED && wasContained) { + if (ref.equals("#") && focus.getSpecial() != SpecialElement.CONTAINED && wasContained) { ResolvedReference rr = new ResolvedReference(); - rr.setResource(nstack.getElement()); - rr.setFocus(nstack.getElement()); + rr.setResource(focus); + rr.setFocus(focus); rr.setExternal(false); rr.setStack(nstack); // rr.getStack().qualifyPath(".ofType("+nstack.getElement().fhirType()+")"); // System.out.println("-->"+nstack.getLiteralPath()); return rr; } - if (nstack.getElement().getSpecial() == SpecialElement.CONTAINED) { + if (focus.getSpecial() == SpecialElement.CONTAINED) { wasContained = true; } - IndexedElement res = getContainedById(nstack.getElement(), ref.substring(1)); + IndexedElement res = getContainedById(focus, ref.substring(1)); if (res != null) { ResolvedReference rr = new ResolvedReference(); - rr.setResource(nstack.getElement()); + rr.setResource(focus); rr.setFocus(res.getMatch()); rr.setExternal(false); rr.setStack(nstack.push(res.getMatch(), res.getIndex(), res.getMatch().getProperty().getDefinition(), res.getMatch().getProperty().getDefinition())); - rr.getStack().pathComment(nstack.getElement().fhirType()+"/"+stack.getElement().getIdBase()); + rr.getStack().pathComment(res.getMatch().fhirType()+"/"+res.getMatch().getIdBase()); return rr; } } - if (nstack.getElement().getSpecial() == SpecialElement.BUNDLE_ENTRY || nstack.getElement().getSpecial() == SpecialElement.PARAMETER) { + if (focus.getSpecial() == SpecialElement.BUNDLE_ENTRY || focus.getSpecial() == SpecialElement.PARAMETER) { return null; // we don't try to resolve contained references across this boundary } + focus = focus.getParentForValidator(); nstack = nstack.getParent(); - } - // try again, and work up the element parent list - if (ref.equals("#")) { - Element e = stack.getElement(); - while (e != null) { - if (e.getProperty().isResource() && (e.getSpecial() != SpecialElement.CONTAINED)) { - ResolvedReference rr = new ResolvedReference(); - rr.setResource(e); - rr.setFocus(e); - rr.setExternal(false); - rr.setStack(stack.push(e, -1, e.getProperty().getDefinition(), e.getProperty().getDefinition())); - rr.getStack().pathComment(e.fhirType()+"/"+e.getIdBase()); - return rr; - } - e = e.getParentForValidator(); + if (focus != null && nstack == null) { + // we have run off the bottom of the stack, need to fake something + nstack = new NodeStack(context, focus, focus.fhirType(), validationLanguage); } } return null; From e57ef59ee9e0d54e2d77521365f73097b29e146d Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 10 May 2024 08:09:03 +1000 Subject: [PATCH 5/5] Fix issue with unknown element rendering fixed value for Attachment --- .../StructureDefinitionRenderer.java | 214 +++++++++--------- 1 file changed, 113 insertions(+), 101 deletions(-) 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 300d429be..e534dec18 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 @@ -2237,112 +2237,114 @@ public class StructureDefinitionRenderer extends ResourceRenderer { StructureDefinition sd = context.getWorker().fetchTypeDefinition(value.fhirType()); for (org.hl7.fhir.r5.model.Property t : value.children()) { - if (t.getValues().size() > 0 || snapshot) { - ElementDefinition ed = findElementDefinition(sd, t.getName()); - if (t.getValues().size() == 0 || (t.getValues().size() == 1 && t.getValues().get(0).isEmpty())) { - if (!skipnoValue) { - Row row = gen.new Row(); - row.setId(ed.getPath()); - erow.getSubRows().add(row); - Cell c = gen.new Cell(); - row.getCells().add(c); - c.addPiece(gen.new Piece((ed.getBase().getPath().equals(ed.getPath()) ? ref+ed.getPath() : corePath+(VersionUtilities.isR5Plus(context.getWorker().getVersion()) ? "types-definitions.html#"+ed.getBase().getPath() : "element-definitions.html#"+ed.getBase().getPath())), t.getName(), null)); - c = gen.new Cell(); - row.getCells().add(c); - c.addPiece(gen.new Piece(null, null, null)); - c = gen.new Cell(); - row.getCells().add(c); - if (!pattern) { - c.addPiece(gen.new Piece(null, "0..0", null)); - row.setIcon("icon_fixed.gif", context.formatMessage(RenderingContext.STRUC_DEF_FIXED_VALUE) /*HierarchicalTableGenerator.TEXT_ICON_FIXED*/); - } else if (context.getContext().isPrimitiveType(t.getTypeCode())) { - row.setIcon("icon_primitive.png", HierarchicalTableGenerator.TEXT_ICON_PRIMITIVE); - c.addPiece(gen.new Piece(null, "0.."+(t.getMaxCardinality() == 2147483647 ? "*": Integer.toString(t.getMaxCardinality())), null)); - } else if (isReference(t.getTypeCode())) { - row.setIcon("icon_reference.png", HierarchicalTableGenerator.TEXT_ICON_REFERENCE); - c.addPiece(gen.new Piece(null, "0.."+(t.getMaxCardinality() == 2147483647 ? "*": Integer.toString(t.getMaxCardinality())), null)); - } else { - row.setIcon("icon_datatype.gif", HierarchicalTableGenerator.TEXT_ICON_DATATYPE); - c.addPiece(gen.new Piece(null, "0.."+(t.getMaxCardinality() == 2147483647 ? "*": Integer.toString(t.getMaxCardinality())), null)); - } - c = gen.new Cell(); - row.getCells().add(c); - if (t.getTypeCode().contains("(")) { - String tc = t.getTypeCode(); - String tn = tc.substring(0, tc.indexOf("(")); - c.addPiece(gen.new Piece(context.getPkp().getLinkFor(corePath, tn), tn, null)); - c.addPiece(gen.new Piece(null, "(", null)); - String[] p = tc.substring(tc.indexOf("(")+1, tc.indexOf(")")).split("\\|"); - for (String s : p) { - c.addPiece(gen.new Piece(context.getPkp().getLinkFor(corePath, s), s, null)); - } - c.addPiece(gen.new Piece(null, ")", null)); - } else { - c.addPiece(gen.new Piece(context.getPkp().getLinkFor(corePath, t.getTypeCode()), t.getTypeCode(), null)); - } - c = gen.new Cell(); - c.addPiece(gen.new Piece(null, ed.getShort(), null)); - row.getCells().add(c); - } - } else { - for (Base b : t.getValues()) { - Row row = gen.new Row(); - row.setId(ed.getPath()); - erow.getSubRows().add(row); - row.setIcon("icon_fixed.gif", context.formatMessage(RenderingContext.STRUC_DEF_FIXED) /*HierarchicalTableGenerator.TEXT_ICON_FIXED*/); - - Cell c = gen.new Cell(); - row.getCells().add(c); - c.addPiece(gen.new Piece((ed.getBase().getPath().equals(ed.getPath()) ? ref+ed.getPath() : (VersionUtilities.isR5Ver(context.getWorker().getVersion()) ? corePath+"types-definitions.html#"+ed.getBase().getPath() : corePath+"element-definitions.html#"+ed.getBase().getPath())), t.getName(), null)); - - c = gen.new Cell(); - row.getCells().add(c); - c.addPiece(gen.new Piece(null, null, null)); - - c = gen.new Cell(); - row.getCells().add(c); - if (pattern) - c.addPiece(gen.new Piece(null, "1.."+(t.getMaxCardinality() == 2147483647 ? "*" : Integer.toString(t.getMaxCardinality())), null)); - else - c.addPiece(gen.new Piece(null, "1..1", null)); - - c = gen.new Cell(); - row.getCells().add(c); - if (b.fhirType().contains("(")) { - String tc = b.fhirType(); - String tn = tc.substring(0, tc.indexOf("(")); - c.addPiece(gen.new Piece(context.getPkp().getLinkFor(corePath, tn), tn, null)); - c.addPiece(gen.new Piece(null, "(", null)); - String[] p = tc.substring(tc.indexOf("(")+1, tc.indexOf(")")).split("\\|"); - for (String s : p) { - c.addPiece(gen.new Piece(context.getPkp().getLinkFor(corePath, s), s, null)); - } - c.addPiece(gen.new Piece(null, ")", null)); - } else { - c.addPiece(gen.new Piece(context.getPkp().getLinkFor(corePath, b.fhirType()), b.fhirType(), null)); - } - - if (b.isPrimitive()) { + ElementDefinition ed = findElementDefinitionOrNull(sd, t.getName()); + if (ed != null) { // might be null because of added properties across versions + if (t.getValues().size() > 0 || snapshot) { + if (t.getValues().size() == 0 || (t.getValues().size() == 1 && t.getValues().get(0).isEmpty())) { + if (!skipnoValue) { + Row row = gen.new Row(); + row.setId(ed.getPath()); + erow.getSubRows().add(row); + Cell c = gen.new Cell(); + row.getCells().add(c); + c.addPiece(gen.new Piece((ed.getBase().getPath().equals(ed.getPath()) ? ref+ed.getPath() : corePath+(VersionUtilities.isR5Plus(context.getWorker().getVersion()) ? "types-definitions.html#"+ed.getBase().getPath() : "element-definitions.html#"+ed.getBase().getPath())), t.getName(), null)); c = gen.new Cell(); row.getCells().add(c); - c.addPiece(gen.new Piece(null, ed.getShort(), null)); - c.addPiece(gen.new Piece("br")); - c.getPieces().add(gen.new Piece(null, context.formatMessage(RenderingContext.STRUC_DEF_FIXED_VALUE)+" ", null).addStyle("font-weight: bold")); - String s = b.primitiveValue(); - // ok. let's see if we can find a relevant link for this - String link = null; - if (Utilities.isAbsoluteUrl(s)) { - link = context.getPkp().getLinkForUrl(corePath, s); - } - c.getPieces().add(gen.new Piece(link, s, null).addStyle("color: darkgreen")); - } else { + c.addPiece(gen.new Piece(null, null, null)); c = gen.new Cell(); row.getCells().add(c); + if (!pattern) { + c.addPiece(gen.new Piece(null, "0..0", null)); + row.setIcon("icon_fixed.gif", context.formatMessage(RenderingContext.STRUC_DEF_FIXED_VALUE) /*HierarchicalTableGenerator.TEXT_ICON_FIXED*/); + } else if (context.getContext().isPrimitiveType(t.getTypeCode())) { + row.setIcon("icon_primitive.png", HierarchicalTableGenerator.TEXT_ICON_PRIMITIVE); + c.addPiece(gen.new Piece(null, "0.."+(t.getMaxCardinality() == 2147483647 ? "*": Integer.toString(t.getMaxCardinality())), null)); + } else if (isReference(t.getTypeCode())) { + row.setIcon("icon_reference.png", HierarchicalTableGenerator.TEXT_ICON_REFERENCE); + c.addPiece(gen.new Piece(null, "0.."+(t.getMaxCardinality() == 2147483647 ? "*": Integer.toString(t.getMaxCardinality())), null)); + } else { + row.setIcon("icon_datatype.gif", HierarchicalTableGenerator.TEXT_ICON_DATATYPE); + c.addPiece(gen.new Piece(null, "0.."+(t.getMaxCardinality() == 2147483647 ? "*": Integer.toString(t.getMaxCardinality())), null)); + } + c = gen.new Cell(); + row.getCells().add(c); + if (t.getTypeCode().contains("(")) { + String tc = t.getTypeCode(); + String tn = tc.substring(0, tc.indexOf("(")); + c.addPiece(gen.new Piece(context.getPkp().getLinkFor(corePath, tn), tn, null)); + c.addPiece(gen.new Piece(null, "(", null)); + String[] p = tc.substring(tc.indexOf("(")+1, tc.indexOf(")")).split("\\|"); + for (String s : p) { + c.addPiece(gen.new Piece(context.getPkp().getLinkFor(corePath, s), s, null)); + } + c.addPiece(gen.new Piece(null, ")", null)); + } else { + c.addPiece(gen.new Piece(context.getPkp().getLinkFor(corePath, t.getTypeCode()), t.getTypeCode(), null)); + } + c = gen.new Cell(); c.addPiece(gen.new Piece(null, ed.getShort(), null)); - c.addPiece(gen.new Piece("br")); - c.getPieces().add(gen.new Piece(null, context.formatMessage(RenderingContext.STRUC_DEF_FIXED_VALUE)+" ", null).addStyle("font-weight: bold")); - c.getPieces().add(gen.new Piece(null, context.formatMessage(RenderingContext.STRUC_DEF_COMPLEXBRACK), null).addStyle("color: darkgreen")); - genFixedValue(gen, row, (DataType) b, snapshot, pattern, corePath, skipnoValue); + row.getCells().add(c); + } + } else { + for (Base b : t.getValues()) { + Row row = gen.new Row(); + row.setId(ed.getPath()); + erow.getSubRows().add(row); + row.setIcon("icon_fixed.gif", context.formatMessage(RenderingContext.STRUC_DEF_FIXED) /*HierarchicalTableGenerator.TEXT_ICON_FIXED*/); + + Cell c = gen.new Cell(); + row.getCells().add(c); + c.addPiece(gen.new Piece((ed.getBase().getPath().equals(ed.getPath()) ? ref+ed.getPath() : (VersionUtilities.isR5Ver(context.getWorker().getVersion()) ? corePath+"types-definitions.html#"+ed.getBase().getPath() : corePath+"element-definitions.html#"+ed.getBase().getPath())), t.getName(), null)); + + c = gen.new Cell(); + row.getCells().add(c); + c.addPiece(gen.new Piece(null, null, null)); + + c = gen.new Cell(); + row.getCells().add(c); + if (pattern) + c.addPiece(gen.new Piece(null, "1.."+(t.getMaxCardinality() == 2147483647 ? "*" : Integer.toString(t.getMaxCardinality())), null)); + else + c.addPiece(gen.new Piece(null, "1..1", null)); + + c = gen.new Cell(); + row.getCells().add(c); + if (b.fhirType().contains("(")) { + String tc = b.fhirType(); + String tn = tc.substring(0, tc.indexOf("(")); + c.addPiece(gen.new Piece(context.getPkp().getLinkFor(corePath, tn), tn, null)); + c.addPiece(gen.new Piece(null, "(", null)); + String[] p = tc.substring(tc.indexOf("(")+1, tc.indexOf(")")).split("\\|"); + for (String s : p) { + c.addPiece(gen.new Piece(context.getPkp().getLinkFor(corePath, s), s, null)); + } + c.addPiece(gen.new Piece(null, ")", null)); + } else { + c.addPiece(gen.new Piece(context.getPkp().getLinkFor(corePath, b.fhirType()), b.fhirType(), null)); + } + + if (b.isPrimitive()) { + c = gen.new Cell(); + row.getCells().add(c); + c.addPiece(gen.new Piece(null, ed.getShort(), null)); + c.addPiece(gen.new Piece("br")); + c.getPieces().add(gen.new Piece(null, context.formatMessage(RenderingContext.STRUC_DEF_FIXED_VALUE)+" ", null).addStyle("font-weight: bold")); + String s = b.primitiveValue(); + // ok. let's see if we can find a relevant link for this + String link = null; + if (Utilities.isAbsoluteUrl(s)) { + link = context.getPkp().getLinkForUrl(corePath, s); + } + c.getPieces().add(gen.new Piece(link, s, null).addStyle("color: darkgreen")); + } else { + c = gen.new Cell(); + row.getCells().add(c); + c.addPiece(gen.new Piece(null, ed.getShort(), null)); + c.addPiece(gen.new Piece("br")); + c.getPieces().add(gen.new Piece(null, context.formatMessage(RenderingContext.STRUC_DEF_FIXED_VALUE)+" ", null).addStyle("font-weight: bold")); + c.getPieces().add(gen.new Piece(null, context.formatMessage(RenderingContext.STRUC_DEF_COMPLEXBRACK), null).addStyle("color: darkgreen")); + genFixedValue(gen, row, (DataType) b, snapshot, pattern, corePath, skipnoValue); + } } } } @@ -2361,6 +2363,16 @@ public class StructureDefinitionRenderer extends ResourceRenderer { } + private ElementDefinition findElementDefinitionOrNull(StructureDefinition sd, String name) { + String path = sd.getTypeName()+"."+name; + for (ElementDefinition ed : sd.getSnapshot().getElement()) { + if (ed.getPath().equals(path)) + return ed; + } + return null; + } + + private String getFixedUrl(StructureDefinition sd) { for (ElementDefinition ed : sd.getSnapshot().getElement()) { if (ed.getPath().equals("Extension.url")) {