Merge pull request #1617 from hapifhir/2024-05-gg-misc2

2024 05 gg misc2
This commit is contained in:
Grahame Grieve 2024-05-09 23:06:24 +00:00 committed by GitHub
commit ffec50c71b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 155 additions and 135 deletions

View File

@ -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));

View File

@ -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")) {

View File

@ -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 {

View File

@ -987,14 +987,19 @@ public class ValueSetExpander extends ValueSetProcessBase {
}
}
private void copyImportContains(List<ValueSetExpansionContainsComponent> list, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filter, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps, ValueSet vsSrc, ValueSetExpansionComponent exp) throws FHIRException, ETooCostly {
private int copyImportContains(List<ValueSetExpansionContainsComponent> list, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filter, boolean noInactive, List<ValueSetExpansionPropertyComponent> 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<Extension> 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))) {

View File

@ -99,5 +99,9 @@ class WorkingContext {
public void setNoTotal(boolean noTotal) {
this.noTotal = noTotal;
}
public void resetTotal() {
total = 0;
}
}

View File

@ -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";

View File

@ -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

View File

@ -4649,57 +4649,47 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
private ResolvedReference localResolve(String ref, NodeStack stack, List<ValidationMessage> 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;