Add note when extension is deprecated

This commit is contained in:
Grahame Grieve 2025-01-10 16:59:28 +11:00
parent 30daf09155
commit 696a359c11
10 changed files with 80 additions and 6 deletions

View File

@ -366,6 +366,16 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or
super.copyNewExtensions(src, urls);
}
public Base getExtensionValue(String... theUrls) {
for (Extension next : getModifierExtension()) {
if (Utilities.existsInList(next.getUrl(), theUrls)) {
return next.getValue();
}
}
return super.getExtensionValue(theUrls);
}
// end addition
}

View File

@ -440,6 +440,15 @@ public abstract class Element extends Base implements IBaseHasExtensions, IBaseE
return false;
}
public Base getExtensionValue(String... theUrls) {
for (Extension next : getExtension()) {
if (Utilities.existsInList(next.getUrl(), theUrls)) {
return next.getValue();
}
}
return null;
}
/**
* Returns an true if this element has an extension that matchs the given URL.

View File

@ -34,6 +34,7 @@ import org.hl7.fhir.utilities.FhirPublication;
import org.hl7.fhir.utilities.MarkDownProcessor;
import org.hl7.fhir.utilities.MarkDownProcessor.Dialect;
import org.hl7.fhir.utilities.StandardsStatus;
import org.hl7.fhir.utilities.StringPair;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.i18n.RenderingI18nContext;
import org.hl7.fhir.utilities.validation.ValidationOptions;
@ -295,7 +296,7 @@ public class RenderingContext extends RenderingI18nContext {
private List<String> files = new ArrayList<String>(); // files created as by-products in destDir
private Map<KnownLinkType, String> links = new HashMap<>();
private Map<String, String> namedLinks = new HashMap<>();
private Map<String, StringPair> namedLinks = new HashMap<>();
private boolean addName = false;
private Map<String, String> typeMap = new HashMap<>(); // type aliases that can be resolved in Markdown type links (mainly for cross-version usage)
private int base64Limit = 1024;
@ -781,7 +782,7 @@ public class RenderingContext extends RenderingI18nContext {
return this;
}
public Map<String, String> getNamedLinks() {
public Map<String, StringPair> getNamedLinks() {
return namedLinks;
}

View File

@ -1105,5 +1105,14 @@ public class CodeSystemUtilities extends TerminologyUtilities {
public static boolean isExemptFromMultipleVersionChecking(String url) {
return Utilities.existsInList(url, "http://snomed.info/sct", "http://loinc.org");
}
public static PropertyComponent getPropertyByUri(CodeSystem cs, String uri) {
for (PropertyComponent t : cs.getProperty()) {
if (uri.equals(t.getUri())) {
return t;
}
}
return null;
}
}

View File

@ -570,8 +570,14 @@ public class ToolingExtensions {
return ((BooleanType) ex.getValue()).getValue();
}
public static boolean readBoolExtension(DomainResource c, String uri) {
Extension ex = ExtensionHelper.getExtension(c, uri);
public static boolean readBoolExtension(DomainResource c, String... uris) {
Extension ex = null;
for (String uri : uris) {
ex = ExtensionHelper.getExtension(c, uri);
if (ex != null) {
break;
}
}
if (ex == null)
return false;
if (!(ex.getValue() instanceof BooleanType))
@ -785,6 +791,17 @@ public class ToolingExtensions {
element.getExtension().add(new Extension(uri).setValue(new CodeType(value)));
}
public static void setMarkdownExtension(DomainResource resource, String uri, String value) {
if (Utilities.noString(value))
return;
Extension ext = getExtension(resource, uri);
if (ext != null)
ext.setValue(new MarkdownType(value));
else
resource.getExtension().add(new Extension(uri).setValue(new MarkdownType(value)));
}
public static void setIntegerExtension(DomainResource resource, String uri, int value) {
Extension ext = getExtension(resource, uri);
if (ext != null)

View File

@ -41,6 +41,7 @@ import org.commonmark.ext.gfm.tables.TablesExtension;
import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlRenderer;
import org.commonmark.renderer.text.TextContentRenderer;
import com.github.rjeschke.txtmark.Configuration;
import com.github.rjeschke.txtmark.Processor;
@ -278,4 +279,15 @@ public class MarkDownProcessor {
return b.toString();
}
public static String markdownToPlainText(String source) {
if (source == null) {
return "";
}
Set<Extension> extensions = Collections.singleton(TablesExtension.create());
Parser parser = Parser.builder().extensions(extensions).build();
Node document = parser.parse(source);
TextContentRenderer renderer = TextContentRenderer.builder().stripNewlines(true).extensions(extensions).build();
String text = renderer.render(document);
return text;
}
}

View File

@ -674,6 +674,13 @@ public class Utilities {
return PathBuilder.getPathBuilder().buildPath(a);
}
public static String forcePath(String... args) throws IOException {
String path = path(args);
String folder = Utilities.getDirectoryForFile(path);
Utilities.createDirectory(folder);
return path;
}
/**
* Composes a path string using by concatenating the passed arguments.
*

View File

@ -413,6 +413,7 @@ public class I18nConstants {
public static final String MEASURE_SHAREABLE_MISSING_HL7 = "MEASURE_SHAREABLE_MISSING_HL7";
public static final String META_RES_SECURITY_DUPLICATE = "Meta_RES_Security_Duplicate";
public static final String MSG_DEPENDS_ON_DEPRECATED = "MSG_DEPENDS_ON_DEPRECATED";
public static final String MSG_DEPENDS_ON_DEPRECATED_NOTE = "MSG_DEPENDS_ON_DEPRECATED_NOTE";
public static final String MSG_DEPENDS_ON_DRAFT = "MSG_DEPENDS_ON_DRAFT";
public static final String MSG_DEPENDS_ON_EXPERIMENTAL = "MSG_DEPENDS_ON_EXPERIMENTAL";
public static final String MSG_DEPENDS_ON_EXTENSION = "MSG_DEPENDS_ON_EXTENSION";

View File

@ -416,6 +416,7 @@ MEASURE_SHAREABLE_EXTRA_MISSING_HL7 = Measures published by HL7 SHALL conform to
MEASURE_SHAREABLE_MISSING = Published measures SHOULD conform to the ShareableMeasure profile, which says that the element Measure.{0} is mandatory, but it is not present
MEASURE_SHAREABLE_MISSING_HL7 = Measures published by HL7 SHALL conform to the ShareableMeasure profile, which says that the element Measure.{0} is mandatory, but it is not present
MSG_DEPENDS_ON_DEPRECATED = The {0} {1} is deprecated
MSG_DEPENDS_ON_DEPRECATED_NOTE = The {0} {1} is deprecated with the note {2}
MSG_DEPENDS_ON_DRAFT = The {0} {1} is a draft resource
MSG_DEPENDS_ON_EXPERIMENTAL = The {0} {1} is an experimental resource
MSG_DEPENDS_ON_EXTENSION = extension
@ -1210,7 +1211,7 @@ VALUESET_INCLUDE_WRONG_VS_MANY = The system ''{0}'' is actually a value set, whi
CODESYSTEM_PROPERTY_URI_UNKNOWN = The property uri ''{0}'' is not known, so the property values can not be validated fully
CODESYSTEM_PROPERTY_URI_UNKNOWN_TYPE = The property uri ''{0}'' is not known, so the property values can not be validated fully; unless specified elsewhere, codes will be treated as internal references
CODESYSTEM_PROPERTY_URI_UNKNOWN_BASE = The base property uri ''{0}'' is not known for the property ''{1}'', so the property values can not be validated fully
CODESYSTEM_PROPERTY_URI_INVALID = The uri ''{3}'' for the property ''{4}'' implies the code ''{0}'' exists in the CodeSystem {2} for {1} but it does not exist
CODESYSTEM_PROPERTY_URI_INVALID = The uri ''{3}'' for the property ''{4}'' implies a property with that URI exists in the CodeSystem {2} for {1}, or the code ''{0}'' does, but neither were found
CODESYSTEM_PROPERTY_CODE_DEFAULT_WARNING = The type of property ''{0}'' is ''code'', but no ValueSet information was found, so the codes will be validated as internal codes
CODESYSTEM_PROPERTY_VALUESET_NOT_FOUND = The ValueSet {0} is unknown, so the property codes cannot be validated
CODESYSTEM_PROPERTY_BAD_INTERNAL_REFERENCE = The code ''{0}'' is not a valid code in this code system

View File

@ -58,6 +58,7 @@ import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.Constants;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.Extension;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.UsageContext;
import org.hl7.fhir.r5.model.ValueSet;
@ -77,6 +78,7 @@ import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.FhirPublication;
import org.hl7.fhir.utilities.MarkDownProcessor;
import org.hl7.fhir.utilities.StandardsStatus;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
@ -1563,10 +1565,15 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
String vurl = ex.getVersionedUrl();
StandardsStatus standardsStatus = ToolingExtensions.getStandardsStatus(ex);
Extension ext = ex.getExtensionByUrl(ToolingExtensions.EXT_STANDARDS_STATUS);
ext = ext == null || !ext.hasValue() ? null : ext.getValue().getExtensionByUrl(ToolingExtensions.EXT_STANDARDS_STATUS_REASON);
String note = ext == null || !ext.hasValue() ? null : MarkDownProcessor.markdownToPlainText(ext.getValue().primitiveValue());
if (standardsStatus == StandardsStatus.DEPRECATED) {
if (!statusWarnings.contains(vurl+":DEPRECATED")) {
statusWarnings.add(vurl+":DEPRECATED");
hint(errors, "2023-08-10", IssueType.BUSINESSRULE, element.line(), element.col(), path, false, I18nConstants.MSG_DEPENDS_ON_DEPRECATED, type, vurl);
hint(errors, "2023-08-10", IssueType.BUSINESSRULE, element.line(), element.col(), path, false,
Utilities.noString(note) ? I18nConstants.MSG_DEPENDS_ON_DEPRECATED : I18nConstants.MSG_DEPENDS_ON_DEPRECATED_NOTE, type, vurl, note);
}
} else if (standardsStatus == StandardsStatus.WITHDRAWN) {
if (!statusWarnings.contains(vurl+":WITHDRAWN")) {