add watch mode to validator

This commit is contained in:
Grahame Grieve 2023-06-19 22:43:54 +10:00
parent 394077c8ec
commit 2b8e61e2cb
7 changed files with 87 additions and 10 deletions

View File

@ -211,6 +211,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
@Getter @Setter private boolean showMessagesFromReferences;
@Getter @Setter private boolean doImplicitFHIRPathStringConversion;
@Getter @Setter private HtmlInMarkdownCheck htmlInMarkdownCheck;
@Getter @Setter private boolean allowDoubleQuotesInFHIRPath;
@Getter @Setter private Locale locale;
@Getter @Setter private List<ImplementationGuide> igs = new ArrayList<>();
@Getter @Setter private List<String> extensionDomains = new ArrayList<>();
@ -262,6 +263,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
showMessagesFromReferences = other.showMessagesFromReferences;
doImplicitFHIRPathStringConversion = other.doImplicitFHIRPathStringConversion;
htmlInMarkdownCheck = other.htmlInMarkdownCheck;
allowDoubleQuotesInFHIRPath = other.allowDoubleQuotesInFHIRPath;
locale = other.locale;
igs.addAll(other.igs);
extensionDomains.addAll(other.extensionDomains);
@ -471,6 +473,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
context.loadFromPackage(npmX, null);
this.fhirPathEngine = new FHIRPathEngine(context);
this.fhirPathEngine.setAllowDoubleQuotes(false);
}
private String getVersionFromPack(Map<String, byte[]> source) {
@ -839,6 +842,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
validator.setQuestionnaireMode(questionnaireMode);
validator.setLevel(level);
validator.setHtmlInMarkdownCheck(htmlInMarkdownCheck);
validator.setAllowDoubleQuotesInFHIRPath(allowDoubleQuotesInFHIRPath);
validator.setNoUnicodeBiDiControlChars(noUnicodeBiDiControlChars);
validator.setDoImplicitFHIRPathStringConversion(doImplicitFHIRPathStringConversion);
if (format == FhirFormat.SHC) {

View File

@ -12,6 +12,7 @@ import org.hl7.fhir.r5.utils.validation.BundleValidationRule;
import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.settings.FhirSettings;
import org.hl7.fhir.validation.cli.services.ValidatorWatchMode;
import org.hl7.fhir.validation.cli.utils.EngineMode;
import org.hl7.fhir.validation.cli.utils.QuestionnaireMode;
import org.hl7.fhir.validation.cli.utils.ValidationLevel;
@ -53,7 +54,8 @@ public class CliContext {
private boolean doImplicitFHIRPathStringConversion = false;
@JsonProperty("htmlInMarkdownCheck")
private HtmlInMarkdownCheck htmlInMarkdownCheck = HtmlInMarkdownCheck.WARNING;
@JsonProperty("allowDoubleQuotesInFHIRPath")
private boolean allowDoubleQuotesInFHIRPath = false;
@JsonProperty("langTransform")
private String langTransform = null;
@JsonProperty("map")
@ -139,6 +141,8 @@ public class CliContext {
@JsonProperty("fhirSettingsFile")
private String fhirSettingsFile;
@JsonProperty("watchMode")
private ValidatorWatchMode watchMode = ValidatorWatchMode.NONE;
@JsonProperty("map")
public String getMap() {
@ -294,6 +298,16 @@ public class CliContext {
this.htmlInMarkdownCheck = htmlInMarkdownCheck;
}
@JsonProperty("allowDoubleQuotesInFHIRPath")
public boolean isAllowDoubleQuotesInFHIRPath() {
return allowDoubleQuotesInFHIRPath;
}
@JsonProperty("allowDoubleQuotesInFHIRPath")
public void setAllowDoubleQuotesInFHIRPath(boolean allowDoubleQuotesInFHIRPath) {
this.allowDoubleQuotesInFHIRPath = allowDoubleQuotesInFHIRPath;
}
@JsonProperty("locale")
public String getLanguageCode() {
return locale;
@ -705,8 +719,10 @@ public class CliContext {
noInvariants == that.noInvariants &&
displayWarnings == that.displayWarnings &&
wantInvariantsInMessages == that.wantInvariantsInMessages &&
allowDoubleQuotesInFHIRPath == that.allowDoubleQuotesInFHIRPath &&
Objects.equals(extensions, that.extensions) &&
Objects.equals(map, that.map) &&
Objects.equals(htmlInMarkdownCheck, that.htmlInMarkdownCheck) &&
Objects.equals(output, that.output) &&
Objects.equals(outputSuffix, that.outputSuffix) &&
Objects.equals(htmlOutput, that.htmlOutput) &&
@ -727,21 +743,23 @@ public class CliContext {
Objects.equals(profiles, that.profiles) &&
Objects.equals(sources, that.sources) &&
Objects.equals(crumbTrails, that.crumbTrails) &&
Objects.equals(forPublication, that.forPublication) &&
Objects.equals(forPublication, that.forPublication)&&
Objects.equals(allowExampleUrls, that.allowExampleUrls) &&
Objects.equals(showTimes, that.showTimes) &&
mode == that.mode &&
Objects.equals(locale, that.locale) &&
Objects.equals(outputStyle, that.outputStyle) &&
Objects.equals(jurisdiction, that.jurisdiction) &&
Objects.equals(locations, that.locations);
Objects.equals(locations, that.locations) &&
Objects.equals(watchMode, that.watchMode) ;
}
@Override
public int hashCode() {
return Objects.hash(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);
targetVer, igs, questionnaireMode, level, profiles, sources, inputs, mode, locale, locations, crumbTrails, forPublication, showTimes, allowExampleUrls, outputStyle, jurisdiction, noUnicodeBiDiControlChars, watchMode,
htmlInMarkdownCheck, allowDoubleQuotesInFHIRPath);
}
@Override
@ -792,6 +810,9 @@ public class CliContext {
", locale='" + locale + '\'' +
", locations=" + locations +
", bundleValidationRules=" + bundleValidationRules +
", htmlInMarkdownCheck=" + htmlInMarkdownCheck +
", allowDoubleQuotesInFHIRPath=" + allowDoubleQuotesInFHIRPath +
", watchMode=" + watchMode +
'}';
}
@ -805,4 +826,17 @@ public class CliContext {
public String getFhirSettingsFile() {
return fhirSettingsFile;
}
@JsonProperty("watchMode")
public ValidatorWatchMode getWatchMode() {
return watchMode;
}
@JsonProperty("watchMode")
public CliContext setWatchMode(ValidatorWatchMode watchMode) {
this.watchMode = watchMode;
return this;
}
}

View File

@ -143,11 +143,10 @@ public class ValidationService {
return versions;
}
public void validateSources(CliContext cliContext, ValidationEngine validator) throws Exception {
public void validateSources(CliContext cliContext, ValidationEngine validator, ValidatorWatchMode watch) throws Exception {
if (cliContext.getProfiles().size() > 0) {
System.out.println(" Profiles: " + cliContext.getProfiles());
}
ValidatorWatchMode watch = ValidatorWatchMode.NONE;
IgLoader igLoader = new IgLoader(validator.getPcm(), validator.getContext(), validator.getVersion());
List<ValidationRecord> records = new ArrayList<>();
@ -467,6 +466,7 @@ public class ValidationService {
validationEngine.setShowMessagesFromReferences(cliContext.isShowMessagesFromReferences());
validationEngine.setDoImplicitFHIRPathStringConversion(cliContext.isDoImplicitFHIRPathStringConversion());
validationEngine.setHtmlInMarkdownCheck(cliContext.getHtmlInMarkdownCheck());
validationEngine.setAllowDoubleQuotesInFHIRPath(cliContext.isAllowDoubleQuotesInFHIRPath());
validationEngine.setNoExtensibleBindingMessages(cliContext.isNoExtensibleBindingMessages());
validationEngine.setNoUnicodeBiDiControlChars(cliContext.isNoUnicodeBiDiControlChars());
validationEngine.setNoInvariantChecks(cliContext.isNoInvariants());

View File

@ -7,6 +7,7 @@ import org.hl7.fhir.utilities.TimeTracker;
import org.hl7.fhir.validation.ValidationEngine;
import org.hl7.fhir.validation.cli.model.CliContext;
import org.hl7.fhir.validation.cli.services.ValidationService;
import org.hl7.fhir.validation.cli.services.ValidatorWatchMode;
import org.hl7.fhir.validation.cli.utils.Display;
import java.io.PrintStream;
@ -54,7 +55,7 @@ public class ValidateTask extends ValidationEngineTask {
}
System.out.println("Validating");
validationService.validateSources(cliContext, validationEngine);
validationService.validateSources(cliContext, validationEngine, cliContext.getWatchMode());
}
}

View File

@ -10,6 +10,7 @@ import org.hl7.fhir.r5.utils.validation.BundleValidationRule;
import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.validation.cli.model.CliContext;
import org.hl7.fhir.validation.cli.model.HtmlInMarkdownCheck;
import org.hl7.fhir.validation.cli.services.ValidatorWatchMode;
public class Params {
@ -83,6 +84,7 @@ public class Params {
public static final String HTML_IN_MARKDOWN = "-html-in-markdown";
public static final String SRC_LANG = "-src-lang";
public static final String TGT_LANG = "-tgt-lang";
public static final String ALLOW_DOUBLE_QUOTES = "-allow-double-quotes-in-fhirpath";
public static final String RUN_TESTS = "-run-tests";
@ -96,6 +98,7 @@ public class Params {
public static final String INPUT = "-input";
public static final String FILTER = "-filter";
private static final String FHIR_SETTINGS_PARAM = "-fhir-settings";
private static final String WATCH_MODE_PARAM = "-watch-mode";
/**
* Checks the list of passed in params to see if it contains the passed in param.
@ -240,6 +243,8 @@ public class Params {
cliContext.setNoInternalCaching(true);
} else if (args[i].equals(NO_EXTENSIBLE_BINDING_WARNINGS)) {
cliContext.setNoExtensibleBindingMessages(true);
} else if (args[i].equals(ALLOW_DOUBLE_QUOTES)) {
cliContext.setAllowDoubleQuotesInFHIRPath(true);
} else if (args[i].equals(NO_UNICODE_BIDI_CONTROL_CHARS)) {
cliContext.setNoUnicodeBiDiControlChars(true);
} else if (args[i].equals(NO_INVARIANTS)) {
@ -381,6 +386,12 @@ public class Params {
} else {
throw new Exception("Can only nominate a single -map parameter");
}
} else if (args[i].equals(WATCH_MODE_PARAM)) {
if (i + 1 == args.length) {
throw new Error("Specified -watch-mode without indicating mode value");
} else {
cliContext.setWatchMode(readWatchMode(args[++i]));
}
} else if (args[i].startsWith(X)) {
i++;
} else if (args[i].equals(CONVERT)) {
@ -402,6 +413,21 @@ public class Params {
return cliContext;
}
private static ValidatorWatchMode readWatchMode(String s) {
if (s == null) {
return ValidatorWatchMode.NONE;
}
switch (s.toLowerCase()) {
case "all" : return ValidatorWatchMode.ALL;
case "none" : return ValidatorWatchMode.NONE;
case "single" : return ValidatorWatchMode.SINGLE;
case "a" : return ValidatorWatchMode.ALL;
case "n" : return ValidatorWatchMode.NONE;
case "s" : return ValidatorWatchMode.SINGLE;
}
throw new Error("The watch mode ''"+s+"'' is not valid");
}
private static String processJurisdiction(String s) {
if (s.startsWith("urn:iso:std:iso:3166#") || s.startsWith("urn:iso:std:iso:3166:-2#") || s.startsWith("http://unstats.un.org/unsd/methods/m49/m49.htm#")) {
return s;

View File

@ -5,8 +5,8 @@ The validation tool compares a resource against the base definitions and any
profiles declared in the resource (Resource.meta.profile) or specified on the
command line
The FHIR validation tool validates a FHIR resource or bundle. Schema and
schematron checking is performed, then some additional checks are performed.
The FHIR validation tool validates a FHIR resource or bundle. Syntax and content is checked
against the specification and other profiles as specified.
* XML & Json (FHIR versions {{XML_AND_JSON_FHIR_VERSIONS}})
* Turtle (FHIR versions {{TURTLE_FHIR_VERSIONS}})
@ -72,6 +72,16 @@ The following parameters are supported:
Default: results are sent to the std out.
-outputSuffix [string]: used in -convert and -snapshot to deal with
one or more result files (where -output can only have one)
-watch-mode [mode]:
Specify that the validator remain running and re-validate when any
of the validated files changes. The validator has to be terminated with
ctrl-c etc in this mode.
This parameter can have one of the following values:
* none: the default - don't wait, just stop when finished
* single: when any of the validated files changes, re-validate it
* all: when any of the validated files changes, re-validate all of them
All is useful when the content includes internal dependencies e.g.
a profile and it's value sets.
-debug
Produce additional information about the loading/validation process
-recurse

View File

@ -3,6 +3,7 @@ package org.hl7.fhir.validation;
import org.hl7.fhir.utilities.TimeTracker;
import org.hl7.fhir.validation.cli.model.CliContext;
import org.hl7.fhir.validation.cli.services.ValidationService;
import org.hl7.fhir.validation.cli.services.ValidatorWatchMode;
import org.hl7.fhir.validation.cli.tasks.*;
import org.hl7.fhir.validation.cli.utils.Params;
@ -245,9 +246,10 @@ public class ValidatorCliTests {
final String[] args = new String[]{"dummyFile.json"};
CliContext cliContext = Params.loadCliContext(args);
ValidatorCli cli = mockValidatorCliWithService(cliContext);
ValidatorWatchMode watchMode = ValidatorWatchMode.NONE;
cli.readParamsAndExecuteTask(cliContext, args);
Mockito.verify(validationService).determineVersion(same(cliContext));
Mockito.verify(validationService).validateSources(same(cliContext), same(validationEngine));
Mockito.verify(validationService).validateSources(same(cliContext), same(validationEngine), same(watchMode));
}
@Test