fix for handling SD extensions when generating snapshots

+ don't remove extensions from types with characteristics = can-bind
This commit is contained in:
Grahame Grieve 2025-01-04 10:26:08 +11:00
parent 84d9df3ff7
commit 3d94ca9bfb

View File

@ -843,6 +843,9 @@ public class ProfileUtilities {
String msg = "No match found for "+e.getId()+" in the generated snapshot: check that the path and definitions are legal in the differential (including order)"; String msg = "No match found for "+e.getId()+" in the generated snapshot: check that the path and definitions are legal in the differential (including order)";
addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, "StructureDefinition.differential.element["+i+"]", msg, ValidationMessage.IssueSeverity.ERROR)); addMessage(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, "StructureDefinition.differential.element["+i+"]", msg, ValidationMessage.IssueSeverity.ERROR));
} }
} else {
ElementDefinition sed = (ElementDefinition) e.getUserData(UserDataNames.SNAPSHOT_GENERATED_IN_SNAPSHOT);
sed.setUserData(UserDataNames.SNAPSHOT_DERIVATION_DIFF, e); // note: this means diff/snapshot are cross-linked
} }
i++; i++;
} }
@ -1034,11 +1037,11 @@ public class ProfileUtilities {
} }
private void checkTypeParameters(StructureDefinition base, StructureDefinition derived) { private void checkTypeParameters(StructureDefinition base, StructureDefinition derived) {
String bt = ToolingExtensions.readStringExtension(base, ToolingExtensions.EXT_TYPE_PARAMETER); String bt = ToolingExtensions.readStringSubExtension(base, ToolingExtensions.EXT_TYPE_PARAMETER, "type");
if (!derived.hasExtension(ToolingExtensions.EXT_TYPE_PARAMETER)) { if (!derived.hasExtension(ToolingExtensions.EXT_TYPE_PARAMETER)) {
throw new DefinitionException(context.formatMessage(I18nConstants.SD_TYPE_PARAMETER_MISSING, base.getVersionedUrl(), bt, derived.getVersionedUrl())); throw new DefinitionException(context.formatMessage(I18nConstants.SD_TYPE_PARAMETER_MISSING, base.getVersionedUrl(), bt, derived.getVersionedUrl()));
} }
String dt = ToolingExtensions.readStringExtension(derived, ToolingExtensions.EXT_TYPE_PARAMETER); String dt = ToolingExtensions.readStringSubExtension(derived, ToolingExtensions.EXT_TYPE_PARAMETER, "type");
StructureDefinition bsd = context.fetchTypeDefinition(bt); StructureDefinition bsd = context.fetchTypeDefinition(bt);
StructureDefinition dsd = context.fetchTypeDefinition(dt); StructureDefinition dsd = context.fetchTypeDefinition(dt);
if (bsd == null) { if (bsd == null) {
@ -1101,20 +1104,39 @@ public class ProfileUtilities {
} }
} }
private void copyInheritedExtensions(StructureDefinition base, StructureDefinition derived, String webUrl) { private void copyInheritedExtensions(StructureDefinition base, StructureDefinition derived, String webUrl) {
for (Extension ext : base.getExtension()) { for (Extension ext : base.getExtension()) {
if (!Utilities.existsInList(ext.getUrl(), NON_INHERITED_ED_URLS) && !derived.hasExtension(ext.getUrl())) { if (!Utilities.existsInList(ext.getUrl(), NON_INHERITED_ED_URLS)) {
Extension next = ext.copy(); String action = getExtensionAction(ext.getUrl());
if (ext.hasValueMarkdownType()) { if (!"ignore".equals(action)) {
MarkdownType md = ext.getValueMarkdownType(); boolean exists = derived.hasExtension(ext.getUrl());
md.setValue(processRelativeUrls(md.getValue(), webUrl, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, false)); if ("add".equals(action) || !exists) {
Extension next = ext.copy();
if (next.hasValueMarkdownType()) {
MarkdownType md = next.getValueMarkdownType();
md.setValue(processRelativeUrls(md.getValue(), webUrl, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, false));
}
derived.getExtension().add(next);
} else if ("overwrite".equals(action)) {
Extension oext = derived.getExtensionByUrl(ext.getUrl());
Extension next = ext.copy();
if (next.hasValueMarkdownType()) {
MarkdownType md = next.getValueMarkdownType();
md.setValue(processRelativeUrls(md.getValue(), webUrl, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, false));
}
oext.setValue(next.getValue());
}
} }
derived.getExtension().add(next);
} }
} }
}
private String getExtensionAction(String url) {
StructureDefinition sd = context.fetchResource(StructureDefinition.class, url);
if (sd != null && sd.hasExtension(ToolingExtensions.EXT_SNAPSHOT_BEHAVIOR)) {
return ToolingExtensions.readStringExtension(sd, ToolingExtensions.EXT_SNAPSHOT_BEHAVIOR);
}
return "defer";
} }
private void addInheritedElementsForSpecialization(StructureDefinitionSnapshotComponent snapshot, ElementDefinition focus, String type, String path, String url, String weburl) { private void addInheritedElementsForSpecialization(StructureDefinitionSnapshotComponent snapshot, ElementDefinition focus, String type, String path, String url, String weburl) {
@ -1490,17 +1512,18 @@ public class ProfileUtilities {
} }
protected boolean isMatchingType(StructureDefinition sd, List<TypeRefComponent> types, String inner) { protected boolean isMatchingType(StructureDefinition sd, List<TypeRefComponent> types, String inner) {
while (sd != null) { StructureDefinition tsd = sd;
while (tsd != null) {
for (TypeRefComponent tr : types) { for (TypeRefComponent tr : types) {
if (sd.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition") && sd.getType().equals(tr.getCode())) { if (tsd.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition") && tsd.getType().equals(tr.getCode())) {
return true; return true;
} }
if (inner == null && sd.getUrl().equals(tr.getCode())) { if (inner == null && tsd.getUrl().equals(tr.getCode())) {
return true; return true;
} }
if (inner != null) { if (inner != null) {
ElementDefinition ed = null; ElementDefinition ed = null;
for (ElementDefinition t : sd.getSnapshot().getElement()) { for (ElementDefinition t : tsd.getSnapshot().getElement()) {
if (inner.equals(t.getId())) { if (inner.equals(t.getId())) {
ed = t; ed = t;
} }
@ -1510,7 +1533,7 @@ public class ProfileUtilities {
} }
} }
} }
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd); tsd = context.fetchResource(StructureDefinition.class, tsd.getBaseDefinition(), tsd);
} }
return false; return false;
} }
@ -2261,6 +2284,13 @@ public class ProfileUtilities {
return (e.hasSlicing() && e.hasMaxElement() && e.getMax().equals("1")); return (e.hasSlicing() && e.hasMaxElement() && e.getMax().equals("1"));
} }
protected boolean isTypeSlicing(ElementDefinition e) {
return (e.hasSlicing() && e.getSlicing().getDiscriminator().size() == 1 &&
e.getSlicing().getDiscriminatorFirstRep().getType() == DiscriminatorType.TYPE &&
"$this".equals(e.getSlicing().getDiscriminatorFirstRep().getPath()));
}
protected ElementDefinitionSlicingComponent makeExtensionSlicing() { protected ElementDefinitionSlicingComponent makeExtensionSlicing() {
ElementDefinitionSlicingComponent slice = new ElementDefinitionSlicingComponent(); ElementDefinitionSlicingComponent slice = new ElementDefinitionSlicingComponent();
slice.addDiscriminator().setPath("url").setType(DiscriminatorType.VALUE); slice.addDiscriminator().setPath("url").setType(DiscriminatorType.VALUE);
@ -3109,6 +3139,10 @@ public class ProfileUtilities {
if (sd != null && sd.hasExtension(ToolingExtensions.EXT_BINDING_STYLE)) { if (sd != null && sd.hasExtension(ToolingExtensions.EXT_BINDING_STYLE)) {
return true; return true;
} }
if (sd != null && sd.hasExtension(ToolingExtensions.EXT_TYPE_CHARACTERISTICS) &&
"can-bind".equals(ToolingExtensions.readStringExtension(sd, ToolingExtensions.EXT_TYPE_CHARACTERISTICS))) {
return true;
}
} }
return false; return false;
} }