Add help text for each visible task

This commit is contained in:
dotasek 2023-06-05 16:39:45 -04:00
parent 88883fc5d8
commit 19d557788c
23 changed files with 316 additions and 46 deletions

View File

@ -64,6 +64,7 @@ POSSIBILITY OF SUCH DAMAGE.
*/
import org.apache.commons.text.WordUtils;
import org.hl7.fhir.r5.terminologies.JurisdictionUtilities;
import org.hl7.fhir.utilities.FileFormat;
import org.hl7.fhir.utilities.TimeTracker;
@ -142,8 +143,8 @@ public class ValidatorCli {
args = addAdditionalParamsForIpsParam(args);
setJavaSystemProxyParamsFromParams(args);
Display.displayVersion();
Display.displaySystemInfo();
Display.displayVersion(System.out);
Display.displaySystemInfo(System.out);
if (cliContext.getFhirSettingsFile() != null) {
FhirSettings.setExplicitFilePath(cliContext.getFhirSettingsFile());
@ -152,15 +153,49 @@ public class ValidatorCli {
FileFormat.checkCharsetAndWarnIfNotUTF8(System.out);
if (shouldDisplayHelpToUser(args)) {
String helpTarget = Params.getParam(args, Params.HELP);
Display.displayHelpDetails("help.txt");
return;
String helpTarget = Params.getParam(args, "-" + Params.HELP);
if (helpTarget != null) {
cliTasks.stream()
.filter(task -> helpTarget.equals(task.getName()))
.findFirst()
.ifPresent(cliTask -> {
displayHelpForTask(cliTask);
});
} else {
displayHelpForDefaultTask();
}return;
}
readParamsAndExecuteTask(tt, tts, cliContext, args);
}
private void displayHelpForDefaultTask() {
System.out.println();
System.out.println(WordUtils.wrap("This is the help text for default usage of the validator. Help for other modes of operation is available by using the parameter '-help [mode]' for one of the following modes:", 80));
System.out.println();
for (CliTask cliTask : cliTasks) {
if (!cliTask.isHidden()) {
System.out.println(" " + cliTask.getName());
}
}
System.out.println();
System.out.println(defaultCliTask.getDisplayName() + " (default usage)");
System.out.println("=".repeat(defaultCliTask.getDisplayName().length()));
System.out.println();
defaultCliTask.printHelp(System.out);
}
private void displayHelpForTask(CliTask cliTask) {
System.out.println();
System.out.println("This is the help text for '" + cliTask.getName() + "'. To display all available help options, use the '-help' or 'help' parameter.");
System.out.println();
System.out.println(cliTask.getDisplayName());
System.out.println("=".repeat(cliTask.getDisplayName().length()));
System.out.println();
cliTask.printHelp(System.out);
}
public static void main(String[] args) throws Exception {
final ValidatorCli validatorCli = new ValidatorCli(validationService);
final CliContext cliContext = Params.loadCliContext(args);
@ -247,9 +282,10 @@ public class ValidatorCli {
private static boolean shouldDisplayHelpToUser(String[] args) {
private boolean shouldDisplayHelpToUser(String[] args) {
return (args.length == 0
|| Params.hasParam(args, Params.HELP)
|| Params.hasParam(args, "-" + Params.HELP)
|| Params.hasParam(args, "?")
|| Params.hasParam(args, "-?")
|| Params.hasParam(args, "/?"));
@ -258,13 +294,14 @@ public class ValidatorCli {
private void readParamsAndExecuteTask(TimeTracker tt, TimeTracker.Session tts, CliContext cliContext, String[] params) throws Exception {
Display.printCliParamsAndInfo(params);
if (cliContext.getSv() == null) {
cliContext.setSv(myValidationService.determineVersion(cliContext));
}
final CliTask cliTask = selectCliTask(cliContext, params);
if (cliTask instanceof ValidationServiceTask) {
if (cliContext.getSv() == null) {
cliContext.setSv(myValidationService.determineVersion(cliContext));
}
ValidationEngine validationEngine = getValidationEngine(tt, cliContext);
tts.end();
((ValidationServiceTask) cliTask).executeTask(myValidationService, validationEngine, cliContext, params, tt, tts);

View File

@ -36,7 +36,7 @@ public class CompareTask extends ValidationServiceTask{
@Override
public void printHelp(PrintStream out) {
Display.displayHelpDetails(out,"help/compare.txt");
}
@Override

View File

@ -4,6 +4,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.utils.Display;
import org.hl7.fhir.validation.cli.utils.EngineMode;
import java.io.PrintStream;
@ -32,7 +33,7 @@ public class ConvertTask extends ValidationServiceTask {
@Override
public void printHelp(PrintStream out) {
Display.displayHelpDetails(out,"help/convert.txt");
}
@Override

View File

@ -4,6 +4,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.utils.Display;
import org.hl7.fhir.validation.cli.utils.EngineMode;
import java.io.PrintStream;
@ -32,7 +33,7 @@ public class FhirpathTask extends ValidationServiceTask {
@Override
public void printHelp(PrintStream out) {
Display.displayHelpDetails(out,"help/fhirpath.txt");
}
@Override

View File

@ -4,6 +4,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.utils.Display;
import org.hl7.fhir.validation.cli.utils.EngineMode;
import java.io.PrintStream;
@ -32,7 +33,7 @@ public class NarrativeTask extends ValidationServiceTask {
@Override
public void printHelp(PrintStream out) {
Display.displayHelpDetails(out,"help/narrative.txt");
}
@Override

View File

@ -4,6 +4,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.utils.Display;
import org.hl7.fhir.validation.cli.utils.EngineMode;
import java.io.PrintStream;
@ -32,7 +33,7 @@ public class SnapshotTask extends ValidationServiceTask {
@Override
public void printHelp(PrintStream out) {
Display.displayHelpDetails(out,"help/snapshot.txt");
}
@Override

View File

@ -2,6 +2,7 @@ package org.hl7.fhir.validation.cli.tasks;
import org.hl7.fhir.utilities.TimeTracker;
import org.hl7.fhir.validation.cli.model.CliContext;
import org.hl7.fhir.validation.cli.utils.Display;
import org.hl7.fhir.validation.cli.utils.Params;
import org.hl7.fhir.validation.special.R4R5MapTester;
import org.hl7.fhir.validation.special.TxTester;
@ -34,7 +35,7 @@ public class TestsTask extends StandaloneTask{
@Override
public void printHelp(PrintStream out) {
Display.displayHelpDetails(out,"help/tests.txt");
}
@Override

View File

@ -4,6 +4,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.utils.Display;
import org.hl7.fhir.validation.cli.utils.EngineMode;
import java.io.PrintStream;
@ -32,7 +33,7 @@ public class TransformTask extends ValidationServiceTask {
@Override
public void printHelp(PrintStream out) {
Display.displayHelpDetails(out,"help/transform.txt");
}
@Override

View File

@ -1,16 +1,22 @@
package org.hl7.fhir.validation.cli.tasks;
import org.hl7.fhir.r5.model.Constants;
import org.hl7.fhir.r5.model.ImplementationGuide;
import org.hl7.fhir.r5.model.StructureDefinition;
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.utils.Display;
import java.io.PrintStream;
public class ValidateTask extends ValidationServiceTask {
final static String[][] PLACEHOLDERS = {
{ "XML_AND_JSON_FHIR_VERSIONS", "1.0, 1.4, 3.0, 4.0, " + Constants.VERSION_MM },
{ "TURTLE_FHIR_VERSIONS", "3.0, 4.0, " + Constants.VERSION_MM },
};
@Override
public String getName() {
return "validate";
@ -35,7 +41,7 @@ public class ValidateTask extends ValidationServiceTask {
@Override
public void printHelp(PrintStream out) {
Display.displayHelpDetails(out,"help/validate.txt", PLACEHOLDERS);
}
@Override

View File

@ -4,6 +4,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.utils.Display;
import org.hl7.fhir.validation.cli.utils.EngineMode;
import java.io.PrintStream;
@ -32,7 +33,7 @@ public class VersionTask extends ValidationServiceTask {
@Override
public void printHelp(PrintStream out) {
Display.displayHelpDetails(out,"help/version.txt");
}
@Override

View File

@ -2,6 +2,7 @@ package org.hl7.fhir.validation.cli.utils;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.r5.model.Constants;
@ -35,30 +36,30 @@ public class Display {
return CURLY_START + string + CURLY_END;
}
final static String[][] PLACEHOLDERS = {
{ getMoustacheString("XML_AND_JSON_FHIR_VERSIONS"), "1.0, 1.4, 3.0, 4.0," + Constants.VERSION_MM },
{ getMoustacheString("TURTLE_FHIR_VERSIONS"), "3.0, 4.0, " + Constants.VERSION_MM },
};
final static String replacePlaceholders(final String input, final String[][] placeholders) {
String output = input;
for (String[] placeholder : placeholders) {
output = output.replaceAll(placeholder[0], placeholder[1]);
output = output.replaceAll(getMoustacheString(placeholder[0]), placeholder[1]);
}
return output;
}
public static void displayHelpDetails(PrintStream out, String file) {
displayHelpDetails(out, file, new String[][]{});
}
/**
* Loads the help details from resources/help.txt, and displays them on the command line to the user.
* Loads the help details from a file, and displays them on the out stream.
* @param file
*/
public static void displayHelpDetails(String file) {
public static void displayHelpDetails(PrintStream out, String file, final String[][] placeholders) {
ClassLoader classLoader = Display.class.getClassLoader();
InputStream help = classLoader.getResourceAsStream(file);
try {
String data = IOUtils.toString(help, "UTF-8");
System.out.println(replacePlaceholders(data, PLACEHOLDERS));
out.println(replacePlaceholders(data, placeholders));
} catch (IOException e) {
e.printStackTrace();
}
@ -69,8 +70,8 @@ public class Display {
/**
* Prints out system info to the command line.
*/
public static void displaySystemInfo() {
System.out.println(" Java: " + System.getProperty("java.version")
public static void displaySystemInfo(PrintStream out) {
out.println(" Java: " + System.getProperty("java.version")
+ " from " + System.getProperty("java.home")
+ " on " + System.getProperty("os.arch")
+ " (" + System.getProperty("sun.arch.data.model") + "bit). "
@ -80,7 +81,7 @@ public class Display {
/**
* Prints current version of the validator.
*/
public static void displayVersion() {
System.out.println("FHIR Validation tool " + VersionUtil.getVersionString());
public static void displayVersion(PrintStream out) {
out.println("FHIR Validation tool " + VersionUtil.getVersionString());
}
}

View File

@ -30,11 +30,12 @@ public class TestExecutorParams {
}
public static boolean isValidClassnameFilterParam(String param) {
if (param == null) return true;
try {
Pattern.compile(param);
return true;
return true;
} catch (PatternSyntaxException e) {
return false;
return false;
}
}
}

View File

@ -0,0 +1,13 @@
The validator can compare profiles. To compare profiles, use the following parameters:
java -jar validator_cli.jar -compare -dest /home/user/work/ig-comparison -version 4.0
-ig hl7.fhir.us.carin-bb#1.1.0 -ig hl7.fhir.us.davinci-crd#1.0.0
-left http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-Patient -right http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-patient
Parameters:
-compare: tell the validator to run the comparison logic
-dest: folder in which to produce the output. This must exist, and the validator will overwrite existing content if it needs to. The output isn't simple - see below
-version Maj.Min - the version to use. You can leave this out and let the validator infer this, but it's there so that you can compare profiles across versions. E.g. if you specify -version 4.0, the profiles will both be treated as R4 profiles, even if they aren't
-ig - a repeating parameter that specifies the packages to load, that contain the profiles you want to compare
-left and -right - the two profiles to compare. There's no functional difference between left and right, except that the comparison will keep to left and right consistently

View File

@ -0,0 +1,13 @@
You can use the validator to convert a resource or logical model. To do this,
you must provide a specific parameter:
-convert
-convert requires the parameters -source and one of {-output, -outputSuffix}.
-ig may be used to provide a logical model.
If the -source maps to one or more resources, e.g. when using a wildcard,
use -outputSuffix <suffix>, to obtain multiple result files with a
`<sourcefilename>.<suffix>` filename.
Example: `-source *.xml -convert -outputSuffix convert.json` outputs:
`source1.xml.convert.json`, `source2.xml.convert.json`, etc. .

View File

@ -0,0 +1,9 @@
You can use the validator to evaluate a FHIRPath expression on a resource or
logical model. To do this, you must provide a specific parameter:
-fhirpath [FHIRPath]
* [FHIRPath] the FHIRPath expression to evaluate
-fhirpath requires the parameters -source. ig may be used to provide a logical
model

View File

@ -0,0 +1,7 @@
You can use the validator to generate narrative for a resource. To do this, you
must provide a specific parameter:
-narrative
-narrative requires the parameters -defn, -txserver, -source, and -output. ig
and profile may be used

View File

@ -0,0 +1,16 @@
You can use the validator to generate a snapshot for a profile. To do this, you
must provide a specific parameter:
-snapshot
-snapshot requires the parameters -defn, -txserver, -source, and
one of {-output, -outputSuffix}.
-ig may be used to provide necessary base profiles.
The -output/-outputSuffic filetype (xml, json) may imply a conversion.
If the -source maps to one or more profiles, e.g. when using a wildcard,
use -outputSuffix <suffix>, to obtain multiple result files with a
`<sourcefilename>.<suffix>` filename.
Example: `-source *.xml -snapshot -outputSuffix snapshot.json` outputs:
`source1.xml.snapshot.json`, `source2.xml.snapshot.json`, etc. .

View File

@ -0,0 +1,24 @@
The validator can be run in test mode, which executes all JUnit tests for the
FHIR core library against a set of test cases in a local directory. To do this,
you must provide a specific parameter with a directory value:
-test [directory]
The directory must follow the same conventions as the reference test cases found
at https://github.com/FHIR/fhir-test-cases. This mode must also be executed with
the Java property java.locale.providers set to COMPAT as below:
java -Djava.locale.providers=COMPAT -jar validator_cli.jar -tests
./my/path/to/fhir-test-cases
This parameter is compatible with -txCache, -test-modules, and
-test-classname-filter parameters.
The following test-specific parameters can be used to limit which tests are run:
-test-modules [module-names] A comma delimited list of Java module names for
which to run JUnit tests. By default, all modules are used to run tests.
Example: -test-modules org.hl7.fhir.dstu2,org.hl7.fhir.dstu2016may
-test-classname-filter [regex] A regex filter applied to test Java class names
for selecting which JUnit tests to run. By default, all tests are run.
Example: -test-classname-filter .*ShexGeneratorTests

View File

@ -0,0 +1,11 @@
You can use the validator to execute a transformation as described by a
structure map. To do this, you must provide some additional parameters:
-transform [map]
* [map] the URI of the map that the transform starts with
Any other dependency maps have to be loaded through an -ig reference
-transform uses the parameters -defn, -txserver, -ig (at least one with the map
files), and -output

View File

@ -0,0 +1,114 @@
Usage: java -jar [validator].jar (parameters)
The FHIR validation tool validates a FHIR resource or bundle.
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.
* XML & Json (FHIR versions {{XML_AND_JSON_FHIR_VERSIONS}})
* Turtle (FHIR versions {{TURTLE_FHIR_VERSIONS}})
If requested, instances will also be verified against the appropriate schema W3C
XML Schema, JSON schema or ShEx, as appropriate
The following parameters are supported:
[source]: a file, url, directory or pattern for resources to validate.
At least one source must be declared. If there is more than one source or
if the source is other than a single file or url and the output parameter is
used, results will be provided as a Bundle.
Patterns are limited to a directory followed by a filename with an
embedded asterisk. E.g. foo*-examples.xml or someresource.*, etc.
-version [ver]: The FHIR version to use.
This can only appear once.
valid values {{FHIR_MAJOR_VERSIONS}} or {{FHIR_MINOR_VERSIONS}}
Default value is {{FHIR_CURRENT_VERSION}}
-ig [package|file|folder|url]: an IG or profile definition to load.
Can be the URL of an implementation guide or a package ([id]-[ver]) for a
built implementation guide or a local folder that contains a set of
conformance resources.
If you would like to load the latest unreleased version of the
implementation guide or package, please define the version as '#current'.
If no version is provided, the latest version in the package cache will
be used, or if no such cached package is available, the PackageCacheManager
will load the latest from the the online package repo.
If you want the implementation guide to be loaded for a specific version
of FHIR, you can prefix the IG with the appropriate version in square
brackets ([[fhirVer]][id]-[igVer]).
No default value. This parameter can appear any number of times
-tx [url]: the [base] url of a FHIR terminology service
Default value is http://tx.fhir.org. This parameter can appear once
To run without terminology value, specific n/a as the URL
-txLog [file]: Produce a log of the terminology server operations in [file]
Default value is not to produce a log
-profile [url]: the canonical URL to validate against (same as if it was
specified in Resource.meta.profile).
If no profile is specified, the resource is validated against the base
specification. This parameter can appear any number of times.
Note: the profile (and it's dependencies) have to be made available
through one of the -ig parameters. Note that package dependencies will
automatically be resolved
-showReferenceMessages
Includes validation messages resulting from validating target resources
against profiles defined on a reference. This increases the volume of
validation messages, but may allow easier debugging. If not specified,
then only a high-level message indicating that the referenced item wasn't
valid against the listed profile(s) will be provided.
-questionnaire mode: what to do when validating QuestionnaireResponse resources
* none (default): just ignore the questionnaire reference
* required: check that the QuestionnaireResponse has a questionnaire and
validate against it
* check: if the QuestionnaireResponse has a questionnaire, validate
against it
The questionnaire must be loaded using the -ig parameter
which specifies the location of a questionnaire. If provided, then the
validator will validate any QuestionnaireResponse that claims to match the
Questionnaire against it no default value. This parameter can appear any
number of times
-output [file]: a filename for the results (OperationOutcome)
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)
-debug
Produce additional information about the loading/validation process
-recurse
Look in subfolders when -ig refers to a folder
-locale
Specifies the locale/language of the validation result messages (eg.:
de-DE
-sct
Specify the edition of SNOMED CT to use. Valid Choices:
intl | us | uk | au | nl | ca | se | dk | es
tx.fhir.org only supports a subset. To add to this list or tx.fhir.org ask
on https://chat.fhir.org/#narrow/stream/179202-terminology
-native: use schema for validation as well
* XML: w3c schema+schematron
* JSON: json.schema
* RDF: SHEX
Default: false
-language: [lang] The language to use when validating coding displays - same
value as for xml:lang
Not used if the resource specifies language
Default: no specified language
-extension: Controls how extensions are validated by the validator. The value
for this parameter is a URL for a domain from which extensions will be
allowed. By default, unknown extensions are prohibited, but can be allowed
by using the value 'any' (e.g. -extension any). This parameter can repeat
any number of times.
-hintAboutNonMustSupport: If present, raise hints if the instance contains data
elements that are not marked as mustSupport=true. Useful to identify
elements included that may be ignored by recipients
-assumeValidRestReferences: If present, assume that URLs that reference
resources follow the RESTful URI pattern and it is safe to infer the type
from the URL
-security-checks: If present, check that string content doesn't include any html
-like tags that might create problems downstream (though all external input
must always be santized by escaping for either html or sql)
The validator also supports the param -proxy=[address]:[port] for if you use a
proxy
Parameters can appear in any order

View File

@ -0,0 +1,12 @@
The validator can convert between versions of FHIR (r2, r3, and r4). To use the validator to convert versions, provide the following parameters:
java -jar validator_cli.jar c:\temp\observation.xml -version 3.0 -to-version 4.0 -output c:\temp\observation4.json
The key parameter is "-to-version" which causes the validator to invoke the version conversion routine.
Technical notes:
the validator can use either it's own internal routines, or the structure maps found at https://github.com/FHIR/packages/tree/master/interversion.
By default, the internal routines will be used for resources with a canonical URL (e.g. code system etc) and the structure maps will be used otherwise
If the internal routines fail, the structure maps will be used anyway
you can use the parameter -do-native to get the validator to try the internal routines first for any resource, and the parameter -no-native to tell it not to try them at all
Issues with the structure maps should be discussed on the chat.fhir.org implementers channel, or submitted as PRs against the github repo above

View File

@ -1,5 +1,7 @@
package org.hl7.fhir.validation.cli.utils;
import org.hl7.fhir.r5.model.Constants;
import org.hl7.fhir.validation.cli.tasks.ValidateTask;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@ -10,32 +12,29 @@ import static org.junit.jupiter.api.Assertions.*;
public class DisplayTests {
final static String[][] PLACEHOLDERS = {
{ "XML_AND_JSON_FHIR_VERSIONS", "1.0, 1.4, 3.0, 4.0, " + Constants.VERSION_MM },
{ "TURTLE_FHIR_VERSIONS", "3.0, 4.0, " + Constants.VERSION_MM },
};
@Test
@DisplayName("Check for placeholder replacement in help output")
public void displayHelpDetails() {
final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
final PrintStream originalOut = System.out;
final PrintStream originalErr = System.err;
PrintStream out = new PrintStream(outContent);
PrintStream err = new PrintStream(errContent);
System.setOut(new PrintStream(outContent));
System.setErr(new PrintStream(errContent));
try {
Display.displayHelpDetails("help.txt");
Display.displayHelpDetails(out, "help/validate.txt", PLACEHOLDERS);
String output = outContent.toString();
for (String[] placeHolder: Display.PLACEHOLDERS) {
for (String[] placeHolder: PLACEHOLDERS) {
assertTrue(output.contains(placeHolder[1]), placeHolder[1] + " is not contained in output:\n" + output);
assertFalse(output.contains(placeHolder[0]), placeHolder[0] + " found in output:\n" + output);
}
}
finally {
System.setOut(originalOut);
System.setErr(originalErr);
}
}
@Test