Merge pull request #1744 from hapifhir/2024-09-gg-logical-json

2024 09 gg logical json
This commit is contained in:
Grahame Grieve 2024-09-12 14:07:06 +08:00 committed by GitHub
commit bfed8a15d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 51 additions and 33 deletions

View File

@ -1,7 +1,18 @@
## Validator Changes
* no changes
* Fix expression for con-3 properly (fix validation problem on some condition resources)
* Fix FHIRPath bug using wrong type on simple elements when checking FHIRPath types
* FHIRPath: Allow _ in constant names (per FHIRPath spec)
* Fix value set rendering creating wrong references
* Fix bug processing value set includes / excludes that are just value sets (no system value)
* Alter processing of unknown code systems per discussion at ,https://chat.fhir.org/#narrow/stream/179252-IG-creation/topic/Don't.20error.20when.20you.20can't.20find.20code.20system and implement unknown-codesystems-cause-errors
* Improve message for when elements are out of order in profile differentials
## Other code changes
* no changes
* fix problem where profile rendering had spurious 'slices for' nodes everywhere
* Update SQL-On-FHIR implementation for latest cases, and clone test cases to general test care repository
* Fix problem generating value set spreadsheets
* fix concurrent modification error processing language translations
* Check for null fetcher processing ConceptMaps (#1728)

View File

@ -289,7 +289,7 @@ public class ProfilePathProcessor {
start++;
} else {
// we're just going to accept the differential slicing at face value
ElementDefinition outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), currentBase.copy());
ElementDefinition outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), currentBase.copy(), true);
outcome.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), outcome.getPath(), getRedirector(), getContextPathSource()));
profileUtilities.updateFromBase(outcome, currentBase, getSourceStructureDefinition().getUrl());
@ -667,14 +667,14 @@ public class ProfilePathProcessor {
// some of what's in currentBase overrides template
template = profileUtilities.fillOutFromBase(template, currentBase);
ElementDefinition outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), template);
ElementDefinition outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), template, true);
outcome.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), outcome.getPath(), getRedirector(), getContextPathSource()));
res = outcome;
profileUtilities.updateFromBase(outcome, currentBase, getSourceStructureDefinition().getUrl());
if (diffMatches.get(0).hasSliceName()) {
template = currentBase.copy();
template = profileUtilities.updateURLs(getUrl(), getWebUrl(), template);
template = profileUtilities.updateURLs(getUrl(), getWebUrl(), template, true);
template.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), template.getPath(), getRedirector(), getContextPathSource()));
checkToSeeIfSlicingExists(diffMatches.get(0), template);
@ -866,13 +866,13 @@ public class ProfilePathProcessor {
private void processSimplePathWithEmptyDiffMatches(ElementDefinition currentBase, String currentBasePath, List<ElementDefinition> diffMatches, ProfilePathProcessorState cursors, MappingAssistant mapHelper) {
ElementDefinition outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), currentBase.copy());
ElementDefinition outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), currentBase.copy(), true);
outcome.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), outcome.getPath(), getRedirector(), getContextPathSource()));
profileUtilities.updateFromBase(outcome, currentBase, getSourceStructureDefinition().getUrl());
profileUtilities.updateConstraintSources(outcome, getSourceStructureDefinition().getUrl());
profileUtilities.checkExtensions(outcome);
profileUtilities.updateFromObligationProfiles(outcome);
profileUtilities.updateURLs(url, webUrl, outcome);
profileUtilities.updateURLs(url, webUrl, outcome, true);
profileUtilities.markDerived(outcome);
if (cursors.resultPathBase == null)
cursors.resultPathBase = outcome.getPath();
@ -1033,7 +1033,7 @@ public class ProfilePathProcessor {
if (!currentBase.isChoice() && !profileUtilities.ruleMatches(dSlice.getRules(), bSlice.getRules()))
throw new DefinitionException(profileUtilities.getContext().formatMessage(I18nConstants.SLICING_RULES_ON_DIFFERENTIAL__DO_NOT_MATCH_THOSE_ON_BASE___RULE___, profileUtilities.summarizeSlicing(dSlice), profileUtilities.summarizeSlicing(bSlice), path, cursors.contextName));
}
ElementDefinition outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), currentBase.copy());
ElementDefinition outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), currentBase.copy(), true);
outcome.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), outcome.getPath(), getRedirector(), getContextPathSource()));
profileUtilities.updateFromBase(outcome, currentBase, getSourceStructureDefinition().getUrl());
if (diffMatches.get(0).hasSlicing() || !diffMatches.get(0).hasSliceName()) {
@ -1095,7 +1095,7 @@ public class ProfilePathProcessor {
// We need to copy children of the backbone element before we start messing around with slices
int newBaseLimit = profileUtilities.findEndOfElement(cursors.base, cursors.baseCursor);
for (int i = cursors.baseCursor + 1; i <= newBaseLimit; i++) {
outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), cursors.base.getElement().get(i).copy());
outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), cursors.base.getElement().get(i).copy(), true);
outcome.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), outcome.getPath(), getRedirector(), getContextPathSource()));
debugCheck(outcome);
getResult().getElement().add(outcome);
@ -1106,7 +1106,7 @@ public class ProfilePathProcessor {
List<ElementDefinition> baseMatches = profileUtilities.getSiblings(cursors.base.getElement(), currentBase);
for (ElementDefinition baseItem : baseMatches) {
cursors.baseCursor = cursors.base.getElement().indexOf(baseItem);
outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), baseItem.copy());
outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), baseItem.copy(), true);
profileUtilities.updateFromBase(outcome, currentBase, getSourceStructureDefinition().getUrl());
outcome.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), outcome.getPath(), getRedirector(), getContextPathSource()));
outcome.setSlicing(null);
@ -1139,7 +1139,7 @@ public class ProfilePathProcessor {
cursors.baseCursor++;
// just copy any children on the base
while (cursors.baseCursor < cursors.base.getElement().size() && cursors.base.getElement().get(cursors.baseCursor).getPath().startsWith(path) && !cursors.base.getElement().get(cursors.baseCursor).getPath().equals(path)) {
outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), cursors.base.getElement().get(cursors.baseCursor).copy());
outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), cursors.base.getElement().get(cursors.baseCursor).copy(), true);
outcome.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), outcome.getPath(), getRedirector(), getContextPathSource()));
if (!outcome.getPath().startsWith(cursors.resultPathBase))
throw new DefinitionException(profileUtilities.getContext().formatMessage(I18nConstants.ADDING_WRONG_PATH));
@ -1166,7 +1166,7 @@ public class ProfilePathProcessor {
for (ElementDefinition baseItem : baseMatches)
if (baseItem.getSliceName().equals(diffItem.getSliceName()))
throw new DefinitionException(profileUtilities.getContext().formatMessage(I18nConstants.NAMED_ITEMS_ARE_OUT_OF_ORDER_IN_THE_SLICE));
outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), currentBase.copy());
outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), currentBase.copy(), true);
// outcome = updateURLs(url, diffItem.copy());
outcome.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), outcome.getPath(), getRedirector(), getContextPathSource()));
profileUtilities.updateFromBase(outcome, currentBase, getSourceStructureDefinition().getUrl());
@ -1409,7 +1409,7 @@ public class ProfilePathProcessor {
private void processPathWithSlicedBaseAndEmptyDiffMatches(ElementDefinition currentBase, String currentBasePath, List<ElementDefinition> diffMatches, ProfilePathProcessorState cursors, String path, MappingAssistant mapHelper) {
if (profileUtilities.hasInnerDiffMatches(getDifferential(), path, cursors.diffCursor, getDiffLimit(), cursors.base.getElement(), true)) {
// so we just copy it in
ElementDefinition outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), currentBase.copy());
ElementDefinition outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), currentBase.copy(), true);
outcome.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), outcome.getPath(), getRedirector(), getContextPathSource()));
profileUtilities.updateFromBase(outcome, currentBase, getSourceStructureDefinition().getUrl());
profileUtilities.markDerived(outcome);
@ -1457,7 +1457,7 @@ public class ProfilePathProcessor {
// the differential doesn't say anything about this item
// copy across the currentbase, and all of its children and siblings
while (cursors.baseCursor < cursors.base.getElement().size() && cursors.base.getElement().get(cursors.baseCursor).getPath().startsWith(path)) {
ElementDefinition outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), cursors.base.getElement().get(cursors.baseCursor).copy());
ElementDefinition outcome = profileUtilities.updateURLs(getUrl(), getWebUrl(), cursors.base.getElement().get(cursors.baseCursor).copy(), true);
outcome.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), outcome.getPath(), getRedirector(), getContextPathSource()));
if (!outcome.getPath().startsWith(cursors.resultPathBase))
throw new DefinitionException(profileUtilities.getContext().formatMessage(I18nConstants.ADDING_WRONG_PATH_IN_PROFILE___VS_, getProfileName(), outcome.getPath(), cursors.resultPathBase));

View File

@ -739,7 +739,7 @@ public class ProfileUtilities {
if (existing != null) {
updateFromDefinition(existing, e, profileName, false, url, base, derived, "StructureDefinition.differential.element["+i+"]", mappingDetails);
} else {
ElementDefinition outcome = updateURLs(url, webUrl, e.copy());
ElementDefinition outcome = updateURLs(url, webUrl, e.copy(), true);
e.setUserData(UD_GENERATED_IN_SNAPSHOT, outcome);
derived.getSnapshot().addElement(outcome);
if (walksInto(diff.getElement(), e)) {
@ -1042,7 +1042,7 @@ public class ProfileUtilities {
// don't do this. should already be in snapshot ... addInheritedElementsForSpecialization(snapshot, focus, sd.getBaseDefinition(), path, url, weburl);
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
if (ed.getPath().contains(".")) {
ElementDefinition outcome = updateURLs(url, weburl, ed.copy());
ElementDefinition outcome = updateURLs(url, weburl, ed.copy(), true);
outcome.setPath(outcome.getPath().replace(sd.getTypeName(), path));
snapshot.getElement().add(outcome);
} else {
@ -1548,7 +1548,6 @@ public class ProfileUtilities {
protected void removeStatusExtensions(ElementDefinition outcome) {
outcome.removeExtension(ToolingExtensions.EXT_FMM_LEVEL);
outcome.removeExtension(ToolingExtensions.EXT_FMM_SUPPORT);
outcome.removeExtension(ToolingExtensions.EXT_FMM_DERIVED);
outcome.removeExtension(ToolingExtensions.EXT_STANDARDS_STATUS);
outcome.removeExtension(ToolingExtensions.EXT_NORMATIVE_VERSION);
outcome.removeExtension(ToolingExtensions.EXT_WORKGROUP);
@ -1911,7 +1910,7 @@ public class ProfileUtilities {
* @param element - the Element to update
* @return - the updated Element
*/
public ElementDefinition updateURLs(String url, String webUrl, ElementDefinition element) {
public ElementDefinition updateURLs(String url, String webUrl, ElementDefinition element, boolean processRelatives) {
if (element != null) {
ElementDefinition defn = element;
if (defn.hasBinding() && defn.getBinding().hasValueSet() && defn.getBinding().getValueSet().startsWith("#"))
@ -1929,24 +1928,24 @@ public class ProfileUtilities {
if (webUrl != null) {
// also, must touch up the markdown
if (element.hasDefinition()) {
element.setDefinition(processRelativeUrls(element.getDefinition(), webUrl, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, false));
element.setDefinition(processRelativeUrls(element.getDefinition(), webUrl, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, processRelatives));
}
if (element.hasComment()) {
element.setComment(processRelativeUrls(element.getComment(), webUrl, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, false));
element.setComment(processRelativeUrls(element.getComment(), webUrl, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, processRelatives));
}
if (element.hasRequirements()) {
element.setRequirements(processRelativeUrls(element.getRequirements(), webUrl, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, false));
element.setRequirements(processRelativeUrls(element.getRequirements(), webUrl, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, processRelatives));
}
if (element.hasMeaningWhenMissing()) {
element.setMeaningWhenMissing(processRelativeUrls(element.getMeaningWhenMissing(), webUrl, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, false));
element.setMeaningWhenMissing(processRelativeUrls(element.getMeaningWhenMissing(), webUrl, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, processRelatives));
}
if (element.hasBinding() && element.getBinding().hasDescription()) {
element.getBinding().setDescription(processRelativeUrls(element.getBinding().getDescription(), webUrl, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, false));
element.getBinding().setDescription(processRelativeUrls(element.getBinding().getDescription(), webUrl, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, processRelatives));
}
for (Extension ext : element.getExtension()) {
if (ext.hasValueMarkdownType()) {
MarkdownType md = ext.getValueMarkdownType();
md.setValue(processRelativeUrls(md.getValue(), webUrl, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, false));
md.setValue(processRelativeUrls(md.getValue(), webUrl, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, processRelatives));
}
}
}
@ -2371,7 +2370,6 @@ public class ProfileUtilities {
if (elist.size() == 2) {
dest.getExtension().remove(elist.get(1));
}
updateExtensionsFromDefinition(dest, source);
for (ElementDefinition ed : obligationProfileElements) {
@ -2423,6 +2421,9 @@ public class ProfileUtilities {
if (e.hasDefinition()) {
base.setDefinition(processRelativeUrls(e.getDefinition(), webroot, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, true));
}
if (e.getBinding().hasDescription()) {
base.getBinding().setDescription(processRelativeUrls(e.getBinding().getDescription(), webroot, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, true));
}
base.setShort(e.getShort());
if (e.hasCommentElement())
base.setCommentElement(e.getCommentElement());
@ -2466,9 +2467,9 @@ public class ProfileUtilities {
if (derived.hasDefinitionElement()) {
if (derived.getDefinition().startsWith("..."))
base.setDefinition(Utilities.appendDerivedTextToBase(base.getDefinition(), derived.getDefinition()));
else if (!Base.compareDeep(derived.getDefinitionElement(), base.getDefinitionElement(), false))
else if (!Base.compareDeep(derived.getDefinitionElement(), base.getDefinitionElement(), false)) {
base.setDefinitionElement(derived.getDefinitionElement().copy());
else if (trimDifferential)
} else if (trimDifferential)
derived.setDefinitionElement(null);
else if (derived.hasDefinitionElement())
derived.getDefinitionElement().setUserData(UD_DERIVATION_EQUALS, true);

View File

@ -366,7 +366,11 @@ public class ContextUtilities implements ProfileKnowledgeProvider {
public StructureDefinition fetchByJsonName(String key) {
for (StructureDefinition sd : context.fetchResourcesByType(StructureDefinition.class)) {
ElementDefinition ed = sd.getSnapshot().getElementFirstRep();
if (sd.getKind() == StructureDefinitionKind.LOGICAL && ed != null && ed.hasExtension(ToolingExtensions.EXT_JSON_NAME, ToolingExtensions.EXT_JSON_NAME_DEPRECATED) &&
if (/*sd.getKind() == StructureDefinitionKind.LOGICAL && */
// this is turned off because it's valid to use a FHIR type directly in
// an extension of this kind, and that can't be a logical model. Any profile on
// a type is acceptable as long as it has the json name on it
ed != null && ed.hasExtension(ToolingExtensions.EXT_JSON_NAME, ToolingExtensions.EXT_JSON_NAME_DEPRECATED) &&
key.equals(ToolingExtensions.readStringExtension(ed, ToolingExtensions.EXT_JSON_NAME, ToolingExtensions.EXT_JSON_NAME_DEPRECATED))) {
return sd;
}

View File

@ -3431,7 +3431,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
sdMapCache.put(url, sdCache);
String webroot = sd.getUserString("webroot");
for (ElementDefinition e : sd.getSnapshot().getElement()) {
context.getProfileUtilities().updateURLs(sd.getUrl(), webroot, e);
context.getProfileUtilities().updateURLs(sd.getUrl(), webroot, e, false);
sdCache.put(e.getId(), e);
}
}

View File

@ -237,9 +237,11 @@ public class NpmPackage {
public List<String> listFiles() {
List<String> res = new ArrayList<>();
if (folder != null) {
for (File f : folder.listFiles()) {
if (!f.isDirectory() && !Utilities.existsInList(f.getName(), "package.json", ".index.json", ".index.db", ".oids.json", ".oids.db")) {
res.add(f.getName());
if (folder.exists()) {
for (File f : folder.listFiles()) {
if (!f.isDirectory() && !Utilities.existsInList(f.getName(), "package.json", ".index.json", ".index.db", ".oids.json", ".oids.db")) {
res.add(f.getName());
}
}
}
} else {

View File

@ -21,7 +21,7 @@
<commons_compress_version>1.26.0</commons_compress_version>
<guava_version>32.0.1-jre</guava_version>
<hapi_fhir_version>6.4.1</hapi_fhir_version>
<validator_test_case_version>1.5.21</validator_test_case_version>
<validator_test_case_version>1.5.22-SNAPSHOT</validator_test_case_version>
<jackson_version>2.17.0</jackson_version>
<junit_jupiter_version>5.9.2</junit_jupiter_version>
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>