Validation of experimental property
This commit is contained in:
parent
0d8c5942e7
commit
11efed6635
|
@ -1108,4 +1108,7 @@ public class I18nConstants {
|
|||
public static final String SM_TARGET_TYPE_UNKNOWN = "SM_TARGET_TYPE_UNKNOWN";
|
||||
public static final String XHTML_XHTML_ATTRIBUTE_XML_SPACE = "XHTML_XHTML_ATTRIBUTE_XML_SPACE";
|
||||
public static final String VALIDATION_HL7_PUBLISHER_MULTIPLE_WGS = "VALIDATION_HL7_PUBLISHER_MULTIPLE_WGS";
|
||||
public static final String SD_BASE_EXPERIMENTAL = "SD_BASE_EXPERIMENTAL";
|
||||
public static final String SD_ED_EXPERIMENTAL_BINDING = "SD_ED_EXPERIMENTAL_BINDING";
|
||||
public static final String VALIDATION_NO_EXPERIMENTAL_CONTENT = "VALIDATION_NO_EXPERIMENTAL_CONTENT";
|
||||
}
|
||||
|
|
|
@ -1140,4 +1140,6 @@ XHTML_XHTML_ATTRIBUTE_XML_SPACE = The attribute 'xml:space' is legal but has a f
|
|||
VALIDATION_HL7_PUBLISHER_MULTIPLE_WGS = This resource has more than workgroup extension (http://hl7.org/fhir/StructureDefinition/structuredefinition-wg)
|
||||
NO_VALID_DISPLAY_FOUND_NONE_FOR_LANG = Wrong Display Name ''{0}'' for {1}#{2}. There are no valid display names found for language(s) ''{3}''. Default display is ''{4}''
|
||||
NO_VALID_DISPLAY_AT_ALL = Cannot validate display Name ''{0}'' for {1}#{2}: No displays are known
|
||||
|
||||
SD_BASE_EXPERIMENTAL = The definition builds on ''{0}'' which is experimental, but this definition is not labeled as experimental
|
||||
SD_ED_EXPERIMENTAL_BINDING = The definition for the element ''{0}'' binds to the value set ''{1}'' which is experimental, but this structure is not labeled as experimental
|
||||
VALIDATION_NO_EXPERIMENTAL_CONTENT = Experimental content is not allowed in this context
|
||||
|
|
|
@ -227,6 +227,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
@Getter @Setter private boolean checkIPSCodes;
|
||||
@Getter @Setter private BestPracticeWarningLevel bestPracticeLevel;
|
||||
@Getter @Setter private boolean unknownCodeSystemsCauseErrors;
|
||||
@Getter @Setter private boolean noExperimentalContent;
|
||||
@Getter @Setter private Locale locale;
|
||||
@Getter @Setter private List<ImplementationGuide> igs = new ArrayList<>();
|
||||
@Getter @Setter private List<String> extensionDomains = new ArrayList<>();
|
||||
|
@ -909,6 +910,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
validator.setPolicyAdvisor(policyAdvisor);
|
||||
}
|
||||
validator.setUnknownCodeSystemsCauseErrors(unknownCodeSystemsCauseErrors);
|
||||
validator.setNoExperimentalContent(noExperimentalContent);
|
||||
return validator;
|
||||
}
|
||||
|
||||
|
|
|
@ -166,6 +166,9 @@ public class CliContext {
|
|||
@JsonProperty("unknownCodeSystemsCauseErrors")
|
||||
private boolean unknownCodeSystemsCauseErrors;
|
||||
|
||||
@JsonProperty("noExperimentalContent")
|
||||
private boolean noExperimentalContent;
|
||||
|
||||
@JsonProperty("baseEngine")
|
||||
public String getBaseEngine() {
|
||||
return baseEngine;
|
||||
|
@ -836,6 +839,7 @@ public class CliContext {
|
|||
Objects.equals(bestPracticeLevel, that.bestPracticeLevel) &&
|
||||
Objects.equals(watchScanDelay, that.watchScanDelay) &&
|
||||
Objects.equals(unknownCodeSystemsCauseErrors, that.unknownCodeSystemsCauseErrors) &&
|
||||
Objects.equals(noExperimentalContent, that.noExperimentalContent) &&
|
||||
Objects.equals(watchSettleTime, that.watchSettleTime) ;
|
||||
}
|
||||
|
||||
|
@ -844,7 +848,7 @@ public class CliContext {
|
|||
return Objects.hash(baseEngine, doNative, extensions, hintAboutNonMustSupport, recursive, doDebug, assumeValidRestReferences, canDoNative, noInternalCaching,
|
||||
noExtensibleBindingMessages, noInvariants, displayWarnings, wantInvariantsInMessages, map, output, outputSuffix, htmlOutput, txServer, sv, txLog, txCache, mapLog, lang, srcLang, tgtLang, fhirpath, snomedCT,
|
||||
targetVer, igs, questionnaireMode, level, profiles, sources, inputs, mode, locale, locations, crumbTrails, forPublication, showTimes, allowExampleUrls, outputStyle, jurisdiction, noUnicodeBiDiControlChars,
|
||||
watchMode, watchScanDelay, watchSettleTime, bestPracticeLevel, unknownCodeSystemsCauseErrors, htmlInMarkdownCheck, allowDoubleQuotesInFHIRPath, checkIPSCodes);
|
||||
watchMode, watchScanDelay, watchSettleTime, bestPracticeLevel, unknownCodeSystemsCauseErrors, noExperimentalContent, htmlInMarkdownCheck, allowDoubleQuotesInFHIRPath, checkIPSCodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -904,6 +908,7 @@ public class CliContext {
|
|||
", watchSettleTime=" + watchSettleTime +
|
||||
", watchScanDelay=" + watchScanDelay +
|
||||
", unknownCodeSystemsCauseErrors=" + unknownCodeSystemsCauseErrors +
|
||||
", noExperimentalContent=" + noExperimentalContent +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
@ -973,5 +978,16 @@ public class CliContext {
|
|||
this.unknownCodeSystemsCauseErrors = unknownCodeSystemsCauseErrors;
|
||||
}
|
||||
|
||||
@JsonProperty("noExperimentalContent")
|
||||
public boolean isNoExperimentalContent() {
|
||||
return noExperimentalContent;
|
||||
}
|
||||
|
||||
|
||||
@JsonProperty("noExperimentalContent")
|
||||
public void setNoExperimentalContent(boolean noExperimentalContent) {
|
||||
this.noExperimentalContent = noExperimentalContent;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -582,6 +582,7 @@ public class ValidationService {
|
|||
validationEngine.getBundleValidationRules().addAll(cliContext.getBundleValidationRules());
|
||||
validationEngine.setJurisdiction(CodeSystemUtilities.readCoding(cliContext.getJurisdiction()));
|
||||
validationEngine.setUnknownCodeSystemsCauseErrors(cliContext.isUnknownCodeSystemsCauseErrors());
|
||||
validationEngine.setNoExperimentalContent(cliContext.isNoExperimentalContent());
|
||||
TerminologyCache.setNoCaching(cliContext.isNoInternalCaching());
|
||||
validationEngine.prepare(); // generate any missing snapshots
|
||||
System.out.println(" go (" + timeTracker.milestone() + ")");
|
||||
|
|
|
@ -95,6 +95,7 @@ public class Params {
|
|||
public static final String CHECK_IPS_CODES = "-check-ips-codes";
|
||||
public static final String BEST_PRACTICE = "-best-practice";
|
||||
public static final String UNKNOWN_CODESYSTEMS_CAUSE_ERROR = "-unknown-codesystems-cause-errors";
|
||||
public static final String NO_EXPERIMENTAL_CONTENT = "-no-experimental-content";
|
||||
|
||||
public static final String RUN_TESTS = "-run-tests";
|
||||
|
||||
|
@ -321,6 +322,8 @@ public class Params {
|
|||
cliContext.setForPublication(true);
|
||||
} else if (args[i].equals(UNKNOWN_CODESYSTEMS_CAUSE_ERROR)) {
|
||||
cliContext.setUnknownCodeSystemsCauseErrors(true);
|
||||
} else if (args[i].equals(NO_EXPERIMENTAL_CONTENT)) {
|
||||
cliContext.setNoExperimentalContent(true);
|
||||
} else if (args[i].equals(VERBOSE)) {
|
||||
cliContext.setCrumbTrails(true);
|
||||
} else if (args[i].equals(ALLOW_EXAMPLE_URLS)) {
|
||||
|
|
|
@ -599,6 +599,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
private IDigitalSignatureServices signatureServices;
|
||||
private ContextUtilities cu;
|
||||
private boolean unknownCodeSystemsCauseErrors;
|
||||
private boolean noExperimentalContent;
|
||||
|
||||
public InstanceValidator(@Nonnull IWorkerContext theContext, @Nonnull IEvaluationContext hostServices, @Nonnull XVerExtensionManager xverManager) {
|
||||
super(theContext, xverManager, false);
|
||||
|
@ -5718,6 +5719,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
hint(errors, "2023-08-14", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), statusCodesDeeplyConsistent(status, standardsStatus), I18nConstants.VALIDATION_VAL_STATUS_INCONSISTENT_HINT, status, standardsStatus);
|
||||
}
|
||||
}
|
||||
if (noExperimentalContent) {
|
||||
String exp = element.getNamedChildValue("experimental");
|
||||
ok = rule(errors, "2024-09-17", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), !"true".equals(exp), I18nConstants.VALIDATION_NO_EXPERIMENTAL_CONTENT) && ok;
|
||||
}
|
||||
|
||||
if (isHL7Core(element) && !isExample()) {
|
||||
ok = checkPublisherConsistency(valContext, errors, element, stack, contained) && ok;
|
||||
|
@ -7840,5 +7845,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
this.unknownCodeSystemsCauseErrors = unknownCodeSystemsCauseErrors;
|
||||
}
|
||||
|
||||
public boolean isNoExperimentalContent() {
|
||||
return noExperimentalContent;
|
||||
}
|
||||
|
||||
public void setNoExperimentalContent(boolean noExperimentalContent) {
|
||||
this.noExperimentalContent = noExperimentalContent;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
List<ElementDefinition> snapshot = sd.getSnapshot().getElement();
|
||||
sd.setSnapshot(null);
|
||||
typeName = sd.getTypeName();
|
||||
boolean experimental = "true".equals(src.getNamedChildValue("experimental", false));
|
||||
StructureDefinition base = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
if (warning(errors, NO_RULE_DATE, IssueType.NOTFOUND, stack.getLiteralPath(), base != null, I18nConstants.UNABLE_TO_FIND_BASE__FOR_, sd.getBaseDefinition(), "StructureDefinition, so can't check the differential")) {
|
||||
if (rule(errors, NO_RULE_DATE, IssueType.NOTFOUND, stack.getLiteralPath(), sd.hasDerivation(), I18nConstants.SD_MUST_HAVE_DERIVATION, sd.getUrl())) {
|
||||
|
@ -129,6 +130,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
ok = rule(errors, "2022-11-02", IssueType.NOTFOUND, stack.getLiteralPath(), base.getKindElement().primitiveValue().equals(src.getChildValue("kind")),
|
||||
I18nConstants.SD_DERIVATION_KIND_MISMATCH, base.getKindElement().primitiveValue(), src.getChildValue("kind")) && ok;
|
||||
}
|
||||
warning(errors, "2024-09-17", IssueType.BUSINESSRULE, stack.getLiteralPath(), !base.getExperimental() || experimental, I18nConstants.SD_BASE_EXPERIMENTAL, sd.getBaseDefinition());
|
||||
}
|
||||
|
||||
List<Element> differentials = src.getChildrenByName("differential");
|
||||
|
@ -136,10 +138,10 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
boolean logical = "logical".equals(src.getNamedChildValue("kind", false));
|
||||
boolean constraint = "constraint".equals(src.getNamedChildValue("derivation", false));
|
||||
for (Element differential : differentials) {
|
||||
ok = validateElementList(errors, differential, stack.push(differential, -1, null, null), false, snapshots.size() > 0, sd, typeName, logical, constraint, src.getNamedChildValue("type", false), src.getNamedChildValue("url", false), src.getNamedChildValue("type", false), base) && ok;
|
||||
ok = validateElementList(errors, differential, stack.push(differential, -1, null, null), false, snapshots.size() > 0, sd, typeName, logical, constraint, src.getNamedChildValue("type", false), src.getNamedChildValue("url", false), src.getNamedChildValue("type", false), base, experimental) && ok;
|
||||
}
|
||||
for (Element snapshotE : snapshots) {
|
||||
ok = validateElementList(errors, snapshotE, stack.push(snapshotE, -1, null, null), true, true, sd, typeName, logical, constraint, src.getNamedChildValue("type", false), src.getNamedChildValue("url", false), src.getNamedChildValue("type", false), base) && ok;
|
||||
ok = validateElementList(errors, snapshotE, stack.push(snapshotE, -1, null, null), true, true, sd, typeName, logical, constraint, src.getNamedChildValue("type", false), src.getNamedChildValue("url", false), src.getNamedChildValue("type", false), base, experimental) && ok;
|
||||
}
|
||||
|
||||
// obligation profile support
|
||||
|
@ -189,6 +191,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
rule(errors, NO_RULE_DATE, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.ERROR_GENERATING_SNAPSHOT, e.getMessage());
|
||||
ok = false;
|
||||
}
|
||||
|
@ -409,19 +412,19 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean validateElementList(List<ValidationMessage> errors, Element elementList, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical, boolean constraint, String rootPath, String profileUrl, String profileType, StructureDefinition base) {
|
||||
private boolean validateElementList(List<ValidationMessage> errors, Element elementList, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical, boolean constraint, String rootPath, String profileUrl, String profileType, StructureDefinition base, boolean experimental) {
|
||||
Map<String, String> invariantMap = new HashMap<>();
|
||||
boolean ok = true;
|
||||
List<Element> elements = elementList.getChildrenByName("element");
|
||||
int cc = 0;
|
||||
for (Element element : elements) {
|
||||
ok = validateElementDefinition(errors, elements, element, stack.push(element, cc, null, null), snapshot, hasSnapshot, sd, typeName, logical, constraint, invariantMap, rootPath, profileUrl, profileType, base) && ok;
|
||||
ok = validateElementDefinition(errors, elements, element, stack.push(element, cc, null, null), snapshot, hasSnapshot, sd, typeName, logical, constraint, invariantMap, rootPath, profileUrl, profileType, base, experimental) && ok;
|
||||
cc++;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
private boolean validateElementDefinition(List<ValidationMessage> errors, List<Element> elements, Element element, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical, boolean constraint, Map<String, String> invariantMap, String rootPath, String profileUrl, String profileType, StructureDefinition base) {
|
||||
private boolean validateElementDefinition(List<ValidationMessage> errors, List<Element> elements, Element element, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd, String typeName, boolean logical, boolean constraint, Map<String, String> invariantMap, String rootPath, String profileUrl, String profileType, StructureDefinition base, boolean experimental) {
|
||||
boolean ok = true;
|
||||
boolean typeMustSupport = false;
|
||||
String path = element.getNamedChildValue("path", false);
|
||||
|
@ -522,7 +525,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
ok = rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), characteristics.contains("can-bind") , I18nConstants.SD_ILLEGAL_CHARACTERISTICS, "Binding", typeCodes) && ok;
|
||||
}
|
||||
Element binding = element.getNamedChild("binding", false);
|
||||
ok = validateBinding(errors, binding, stack.push(binding, -1, null, null), typeCodes, snapshot, path) && ok;
|
||||
ok = validateBinding(errors, binding, stack.push(binding, -1, null, null), typeCodes, snapshot, path, experimental) && ok;
|
||||
} else {
|
||||
// this is a good idea but there's plenty of cases where the rule isn't met; maybe one day it's worth investing the time to exclude these cases and bring this rule back
|
||||
// String bt = boundType(typeCodes);
|
||||
|
@ -986,7 +989,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
return null;
|
||||
}
|
||||
|
||||
private boolean validateBinding(List<ValidationMessage> errors, Element binding, NodeStack stack, Set<String> typeCodes, boolean snapshot, String path) {
|
||||
private boolean validateBinding(List<ValidationMessage> errors, Element binding, NodeStack stack, Set<String> typeCodes, boolean snapshot, String path, boolean experimental) {
|
||||
boolean ok = true;
|
||||
if (bindableType(typeCodes) == null) {
|
||||
ok = rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), !snapshot, I18nConstants.SD_ED_BIND_NO_BINDABLE, path, typeCodes.toString()) && ok;
|
||||
|
@ -1006,7 +1009,12 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
|
||||
if (warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs != null || serverSupportsValueSet(ref), I18nConstants.SD_ED_BIND_UNKNOWN_VS, path, ref)) {
|
||||
if (vs != null) {
|
||||
ok = rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs instanceof ValueSet, I18nConstants.SD_ED_BIND_NOT_VS, path, ref, vs.fhirType()) && ok;
|
||||
if (rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs instanceof ValueSet, I18nConstants.SD_ED_BIND_NOT_VS, path, ref, vs.fhirType())) {
|
||||
ValueSet vsr = (ValueSet) vs;
|
||||
warning(errors, "2024-09-17", IssueType.BUSINESSRULE, stack.getLiteralPath(), !vsr.getExperimental() || experimental, I18nConstants.SD_ED_EXPERIMENTAL_BINDING, path, ref);
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -362,6 +362,9 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
|
|||
if (content.has("security-checks")) {
|
||||
val.setSecurityChecks(content.get("security-checks").getAsBoolean());
|
||||
}
|
||||
if (content.has("no-experimental-content")) {
|
||||
val.setNoExperimentalContent(content.get("no-experimental-content").getAsBoolean());
|
||||
}
|
||||
if (content.has("noHtmlInMarkdown")) {
|
||||
val.setHtmlInMarkdownCheck(HtmlInMarkdownCheck.ERROR);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue