Merge pull request #1383 from hapifhir/2023-08-gg-inactive-codes
2023 08 gg inactive codes
This commit is contained in:
commit
5b738925fe
|
@ -192,13 +192,17 @@ public class R5ExtensionsLoader {
|
|||
for (CanonicalType t : inc.getValueSet()) {
|
||||
loadValueSet(t.asStringValue(), context, valueSets, codeSystems);
|
||||
}
|
||||
if (inc.hasSystem() && !inc.hasVersion()) {
|
||||
if (codeSystems.containsKey(inc.getSystem())) {
|
||||
CodeSystem cs = codeSystems.get(inc.getSystem()).getResource();
|
||||
inc.setVersion(cs.getVersion());
|
||||
context.cacheResourceFromPackage(cs, cs.getSourcePackage());
|
||||
} else if (!context.hasResource(CodeSystem.class, inc.getSystem()) && codeSystems.containsKey(inc.getSystem())) {
|
||||
CodeSystem cs1 = codeSystems.get(inc.getSystem()).getResource();
|
||||
if (inc.hasSystem()) {
|
||||
if (!inc.hasVersion()) {
|
||||
if (codeSystems.containsKey(inc.getSystem())) {
|
||||
CodeSystem cs = codeSystems.get(inc.getSystem()).getResource();
|
||||
CodeSystem csAlready = context.fetchCodeSystem(inc.getSystem());
|
||||
if (csAlready == null) {
|
||||
context.cacheResourceFromPackage(cs, cs.getSourcePackage());
|
||||
}
|
||||
}
|
||||
} else if (context.fetchResource(CodeSystem.class, inc.getSystem(), inc.getVersion()) == null && codeSystems.containsKey(inc.getSystem()+"|"+inc.getVersion())) {
|
||||
CodeSystem cs1 = codeSystems.get(inc.getSystem()+"|"+inc.getVersion()).getResource();
|
||||
context.cacheResourceFromPackage(cs1, cs1.getSourcePackage());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2857,13 +2857,14 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
}
|
||||
// work around for old badly generated SDs
|
||||
if (DONT_DO_THIS && Utilities.existsInList(tt, "Extension", "uri", "string", "Element")) {
|
||||
matchType = true;
|
||||
}
|
||||
if (DONT_DO_THIS && Utilities.existsInList(tt, "Resource","DomainResource") && pkp.isResource(t)) {
|
||||
matchType = true;
|
||||
}
|
||||
// if (DONT_DO_THIS && Utilities.existsInList(tt, "Extension", "uri", "string", "Element")) {
|
||||
// matchType = true;
|
||||
// }
|
||||
// if (DONT_DO_THIS && Utilities.existsInList(tt, "Resource","DomainResource") && pkp.isResource(t)) {
|
||||
// matchType = true;
|
||||
// }
|
||||
if (matchType) {
|
||||
ts.copyExtensions(td, "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support", "http://hl7.org/fhir/StructureDefinition/elementdefinition-pattern", "http://hl7.org/fhir/StructureDefinition/obligation");
|
||||
if (ts.hasTargetProfile()) {
|
||||
// check that any derived target has a reference chain back to one of the base target profiles
|
||||
for (UriType u : ts.getTargetProfile()) {
|
||||
|
@ -2882,9 +2883,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
tgtOk = td.hasTargetProfile(url);
|
||||
}
|
||||
}
|
||||
if (tgtOk)
|
||||
if (tgtOk) {
|
||||
ok = true;
|
||||
else {
|
||||
} else {
|
||||
if (messages == null) {
|
||||
throw new FHIRException(context.formatMessage(I18nConstants.ERROR_AT__THE_TARGET_PROFILE__IS_NOT__VALID_CONSTRAINT_ON_THE_BASE_, purl, derived.getPath(), url, td.getTargetProfile()));
|
||||
} else {
|
||||
|
|
|
@ -544,8 +544,9 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
if (s.startsWith("version=")) {
|
||||
if (version == null)
|
||||
version = s.substring(8);
|
||||
else if (!version.equals(s.substring(8)))
|
||||
else if (!version.equals(s.substring(8))) {
|
||||
throw new DefinitionException(formatMessage(I18nConstants.VERSION_MISMATCH_THE_CONTEXT_HAS_VERSION__LOADED_AND_THE_NEW_CONTENT_BEING_LOADED_IS_VERSION_, version, s.substring(8)));
|
||||
}
|
||||
}
|
||||
if (s.startsWith("revision="))
|
||||
revision = s.substring(9);
|
||||
|
|
|
@ -498,6 +498,14 @@ public abstract class Element extends Base implements IBaseHasExtensions, IBaseE
|
|||
}
|
||||
}
|
||||
|
||||
public void copyNewExtensions(org.hl7.fhir.r5.model.Element src, String... urls) {
|
||||
for (Extension e : src.getExtension()) {
|
||||
if (Utilities.existsInList(e.getUrl(), urls) && !!hasExtension(e.getUrl())) {
|
||||
addExtension(e.copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// end addition
|
||||
|
||||
|
|
|
@ -369,6 +369,10 @@ public class CodeSystemUtilities {
|
|||
if ("inactive".equals(p.getCode()) && p.hasValueBooleanType()) {
|
||||
return p.getValueBooleanType().getValue();
|
||||
}
|
||||
if ("inactive".equals(p.getCode()) && p.hasValueCodeType()) {
|
||||
String code = p.getValueCodeType().primitiveValue();
|
||||
return "true".equals(code);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ public class ValidationProcessInfo {
|
|||
return issues;
|
||||
}
|
||||
public void addIssue(List<OperationOutcomeIssueComponent> issues) {
|
||||
issues.addAll(issues);
|
||||
this.issues.addAll(issues);
|
||||
|
||||
}
|
||||
public boolean hasErrors() {
|
||||
|
|
|
@ -214,7 +214,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
|||
}
|
||||
} else {
|
||||
c.setUserData("cs", cs);
|
||||
res = validateCode(path+".coding["+i+"]", c, cs, vcc);
|
||||
res = validateCode(path+".coding["+i+"]", c, cs, vcc, info);
|
||||
}
|
||||
info.getIssues().addAll(res.getIssues());
|
||||
i++;
|
||||
|
@ -349,6 +349,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
|||
boolean inExpansion = false;
|
||||
boolean inInclude = false;
|
||||
List<OperationOutcomeIssueComponent> issues = new ArrayList<>();
|
||||
ValidationProcessInfo info = new ValidationProcessInfo(issues);
|
||||
VersionInfo vi = new VersionInfo(this);
|
||||
checkCanonical(issues, path, valueset);
|
||||
|
||||
|
@ -439,7 +440,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
|||
// we can't validate that here.
|
||||
throw new FHIRException("Unable to evaluate based on empty code system");
|
||||
}
|
||||
res = validateCode(path, code, cs, null);
|
||||
res = validateCode(path, code, cs, null, info);
|
||||
res.setIssues(issues);
|
||||
} else if (cs == null && valueset.hasExpansion() && inExpansion) {
|
||||
// we just take the value set as face value then
|
||||
|
@ -460,7 +461,6 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
|||
}
|
||||
String wv = vi.getVersion(system, code.getVersion());
|
||||
|
||||
ValidationProcessInfo info = new ValidationProcessInfo(issues);
|
||||
|
||||
// then, if we have a value set, we check it's in the value set
|
||||
if (valueset != null && options.getValueSetMode() != ValueSetMode.NO_MEMBERSHIP_CHECK) {
|
||||
|
@ -633,7 +633,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
|||
return false;
|
||||
}
|
||||
|
||||
private ValidationResult validateCode(String path, Coding code, CodeSystem cs, CodeableConcept vcc) {
|
||||
private ValidationResult validateCode(String path, Coding code, CodeSystem cs, CodeableConcept vcc, ValidationProcessInfo info) {
|
||||
ConceptDefinitionComponent cc = cs.hasUserData("tx.cs.special") ? ((SpecialCodeSystem) cs.getUserData("tx.cs.special")).findConcept(code) : findCodeInConcept(cs.getConcept(), code.getCode(), allAltCodes);
|
||||
if (cc == null) {
|
||||
if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
|
||||
|
@ -648,6 +648,9 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
|||
if (vcc != null) {
|
||||
vcc.addCoding(vc);
|
||||
}
|
||||
if (CodeSystemUtilities.isInactive(cs, cc)) {
|
||||
info.addIssue(makeIssue(IssueSeverity.WARNING, IssueType.EXPIRED, path, context.formatMessage(I18nConstants.INACTIVE_CODE_WARNING, cc.getCode())));
|
||||
}
|
||||
boolean ws = false;
|
||||
if (code.getDisplay() == null) {
|
||||
return new ValidationResult(code.getSystem(), cs.getVersion(), cc, vc.getDisplay());
|
||||
|
@ -1081,6 +1084,12 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
|||
}
|
||||
} else {
|
||||
checkCanonical(info.getIssues(), path, cs);
|
||||
if (valueset.getCompose().hasInactive() && !valueset.getCompose().getInactive()) {
|
||||
if (CodeSystemUtilities.isInactive(cs, code)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (vsi.hasFilter()) {
|
||||
ok = true;
|
||||
for (ConceptSetFilterComponent f : vsi.getFilter()) {
|
||||
|
|
|
@ -286,34 +286,4 @@ public class XVerExtensionManager {
|
|||
}
|
||||
}
|
||||
|
||||
public String getReference(String url) {
|
||||
String version = getVersion(url);
|
||||
String base = VersionUtilities.getSpecUrl(version);
|
||||
if (base == null) {
|
||||
return null;
|
||||
} else {
|
||||
String path = url.substring(url.indexOf("-")+1);
|
||||
if (!path.contains(".")) {
|
||||
return null;
|
||||
}
|
||||
String type = path.substring(0, path.indexOf("."));
|
||||
if (Utilities.existsInList(type, "Annotation", "Attachment", "Identifier", "CodeableConcept", "Coding", "Quantity", "Duration", "Range", "Period", "Ratio", "RatioRange", "SampledData", "Signature", "HumanName", "Address", "ContactPoint", "Timing")) {
|
||||
return Utilities.pathURL(base, "datatypes-definitions.html#"+path+"|"+VersionUtilities.getNameForVersion(version)+" "+path);
|
||||
}
|
||||
if (Utilities.existsInList(type, "Element", "BackboneElement", "BackboneType", "PrimitiveType", "DataType", "Base")) {
|
||||
return Utilities.pathURL(base, "types-definitions.html#"+path+"|"+VersionUtilities.getNameForVersion(version)+" "+path);
|
||||
}
|
||||
if (Utilities.existsInList(type, "UsageContext", "RelatedArtifact", "DataRequirement", "ParameterDefinition", "TriggerDefinition", "Expression", "ContactDetail", "ExtendedContactDetail", "VirtualServiceDetail", "Availability", "MonetaryComponent", "Contributor")) {
|
||||
return Utilities.pathURL(base, "metadatatypes-definitions.html#"+path+"|"+VersionUtilities.getNameForVersion(version)+" "+path);
|
||||
}
|
||||
if (Utilities.existsInList(type, "Reference", "CodeableReference")) {
|
||||
return Utilities.pathURL(base, "references-definitions.html#"+path+"|"+VersionUtilities.getNameForVersion(version)+" "+path);
|
||||
}
|
||||
if (Utilities.existsInList(type, "Meta")) {
|
||||
return Utilities.pathURL(base, "resource-definitions.html#"+path+"|"+VersionUtilities.getNameForVersion(version)+" "+path);
|
||||
}
|
||||
return Utilities.pathURL(base, type.toLowerCase()+"-definitions.html#"+path+"|"+VersionUtilities.getNameForVersion(version)+" "+path);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -954,9 +954,7 @@ public class I18nConstants {
|
|||
public static final String MSG_DEPRECATED = "MSG_DEPRECATED";
|
||||
public static final String MSG_WITHDRAWN = "MSG_WITHDRAWN";
|
||||
public static final String MSG_RETIRED = "MSG_RETIRED";
|
||||
|
||||
|
||||
|
||||
public static final String INACTIVE_CODE_WARNING = "INACTIVE_CODE_WARNING";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -297,6 +297,7 @@ public class NpmPackage {
|
|||
private Map<String, Object> userData;
|
||||
private boolean minimalMemory;
|
||||
private int size;
|
||||
private boolean warned = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -1375,4 +1376,13 @@ public class NpmPackage {
|
|||
this.size = size;
|
||||
}
|
||||
|
||||
public boolean isWarned() {
|
||||
return warned;
|
||||
}
|
||||
|
||||
public void setWarned(boolean warned) {
|
||||
this.warned = warned;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -171,7 +171,7 @@ Terminology_TX_NoValid_13 = The Coding provided ({2}) is not in the value set {0
|
|||
Terminology_TX_NoValid_14 = The Coding provided ({2}) is not in the value set {0}, and a code is recommended to come from this value set. {1}
|
||||
Terminology_TX_NoValid_15 = The value provided (''{0}'') could not be validated in the absence of a terminology server
|
||||
Terminology_TX_NoValid_15A = The value provided (''{0}'') could not be validated because the code system {1} is not known
|
||||
Terminology_TX_NoValid_16 = The value provided (''{0}'') is not in the value set {1}, and a code is required from this value set){2}
|
||||
Terminology_TX_NoValid_16 = The value provided (''{0}'') is not in the value set {1}, and a code is required from this value set {2}
|
||||
Terminology_TX_NoValid_17 = The value provided (''{0}'') is not in the value set {1}, and a code should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable) {2}
|
||||
Terminology_TX_NoValid_18 = The value provided (''{0}'') is not in the value set {1}, and a code is recommended to come from this value set){2}
|
||||
Terminology_TX_NoValid_2_CC = None of the codings provided are in the value set {0}, and a coding should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable) (codes = {1})
|
||||
|
@ -1011,3 +1011,4 @@ SD_EXTENSION_URL_MISMATCH = The fixed value for the extension URL is {1} which d
|
|||
MSG_DEPRECATED = Reference to deprecated item {0}
|
||||
MSG_WITHDRAWN = Reference to withdrawn item {0}
|
||||
MSG_RETIRED = Reference to retired item {0}
|
||||
INACTIVE_CODE_WARNING = The code ''{0}'' is valid but is not active
|
||||
|
|
|
@ -46,9 +46,9 @@ public class ExternalTerminologyServiceTests implements ITxTesterLoader {
|
|||
private JsonObject test;
|
||||
}
|
||||
|
||||
private static final String SERVER = FhirSettings.getTxFhirDevelopment();
|
||||
// private static final String SERVER = FhirSettings.getTxFhirLocal();
|
||||
// private static final String SERVER = "https://r4.ontoserver.csiro.au/fhir";
|
||||
private static final String SERVER = FhirSettings.getTxFhirDevelopment();
|
||||
// private static final String SERVER = FhirSettings.getTxFhirLocal();
|
||||
// private static final String SERVER = "https://r4.ontoserver.csiro.au/fhir";
|
||||
|
||||
|
||||
@Parameters(name = "{index}: id {0}")
|
||||
|
|
Loading…
Reference in New Issue