From 8c3e03399e6d525bface8f8170f0312bbeea0e7f Mon Sep 17 00:00:00 2001 From: markiantorno Date: Thu, 16 Apr 2020 10:17:33 -0400 Subject: [PATCH 1/8] wip --- .../org/hl7/fhir/r5/elementmodel/Manager.java | 40 +++-- .../validation/ValidationMessage.java | 1 + org.hl7.fhir.validation/pom.xml | 28 ++- .../hl7/fhir/validation/ValidationEngine.java | 7 + .../org/hl7/fhir/validation/Validator.java | 67 ++++++-- .../fhir/validation/cli/RestEndpoints.java | 30 ++++ .../hl7/fhir/validation/cli/ValidatorGui.java | 37 ++++ .../cli/controller/CliContextController.java | 27 +++ .../cli/controller/UIController.java | 13 ++ .../cli/controller/ValidationController.java | 31 ++++ .../fhir/validation/cli/controller/test.json | 29 ++++ .../cli/{ => model}/CliContext.java | 161 +++++++++++++++--- .../validation/cli/model/CliContextTest.java | 80 +++++++++ .../fhir/validation/cli/model/FileInfo.java | 49 ++++++ .../validation/cli/model/ValidationIssue.java | 32 ++++ .../cli/model/ValidationOutcome.java | 47 +++++ .../cli/model/ValidationRequest.java | 45 +++++ .../cli/model/ValidationResponse.java | 33 ++++ .../ComparisonService.java} | 11 +- .../ValidationService.java} | 33 +++- .../validation/cli/{ => utils}/Common.java | 10 +- .../validation/cli/{ => utils}/Display.java | 2 +- .../validation/cli/{ => utils}/Params.java | 4 +- .../cli/{ => utils}/SnomedVersion.java | 2 +- .../public/assets/bootstrap-outline.svg | 5 + .../resources/public/assets/fhir-logo-www.png | Bin 0 -> 13319 bytes .../public/assets/json-svgrepo-com.svg | 72 ++++++++ .../public/assets/xml-svgrepo-com.svg | 51 ++++++ .../src/main/resources/public/cliwindow.html | 56 ++++++ .../main/resources/public/enums/EngineMode.js | 10 ++ .../main/resources/public/enums/FhirFormat.js | 17 ++ .../src/main/resources/public/enums/Locale.js | 30 ++++ .../resources/public/enums/SnomedVersion.js | 38 +++++ .../src/main/resources/public/index.html | 66 +++++++ .../src/main/resources/public/main.js | 133 +++++++++++++++ .../main/resources/public/model/CliContext.js | 34 ++++ .../main/resources/public/model/FileInfo.js | 13 ++ .../resources/public/model/ValidationIssue.js | 6 + .../public/model/ValidationOutcome.js | 8 + .../public/model/ValidationRequest.js | 8 + .../public/model/ValidationResponse.js | 7 + .../src/main/resources/public/style.css | 94 ++++++++++ .../src/main/resources/public/test.html | 154 +++++++++++++++++ 43 files changed, 1549 insertions(+), 72 deletions(-) create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/CliContextController.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/UIController.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/test.json rename org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/{ => model}/CliContext.java (63%) create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContextTest.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/FileInfo.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationIssue.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationOutcome.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationRequest.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationResponse.java rename org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/{Comparison.java => services/ComparisonService.java} (91%) rename org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/{ValidationUtils.java => services/ValidationService.java} (88%) rename org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/{ => utils}/Common.java (88%) rename org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/{ => utils}/Display.java (99%) rename org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/{ => utils}/Params.java (98%) rename org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/{ => utils}/SnomedVersion.java (95%) create mode 100644 org.hl7.fhir.validation/src/main/resources/public/assets/bootstrap-outline.svg create mode 100644 org.hl7.fhir.validation/src/main/resources/public/assets/fhir-logo-www.png create mode 100644 org.hl7.fhir.validation/src/main/resources/public/assets/json-svgrepo-com.svg create mode 100644 org.hl7.fhir.validation/src/main/resources/public/assets/xml-svgrepo-com.svg create mode 100644 org.hl7.fhir.validation/src/main/resources/public/cliwindow.html create mode 100644 org.hl7.fhir.validation/src/main/resources/public/enums/EngineMode.js create mode 100644 org.hl7.fhir.validation/src/main/resources/public/enums/FhirFormat.js create mode 100644 org.hl7.fhir.validation/src/main/resources/public/enums/Locale.js create mode 100644 org.hl7.fhir.validation/src/main/resources/public/enums/SnomedVersion.js create mode 100644 org.hl7.fhir.validation/src/main/resources/public/index.html create mode 100644 org.hl7.fhir.validation/src/main/resources/public/main.js create mode 100644 org.hl7.fhir.validation/src/main/resources/public/model/CliContext.js create mode 100644 org.hl7.fhir.validation/src/main/resources/public/model/FileInfo.js create mode 100644 org.hl7.fhir.validation/src/main/resources/public/model/ValidationIssue.js create mode 100644 org.hl7.fhir.validation/src/main/resources/public/model/ValidationOutcome.js create mode 100644 org.hl7.fhir.validation/src/main/resources/public/model/ValidationRequest.js create mode 100644 org.hl7.fhir.validation/src/main/resources/public/model/ValidationResponse.js create mode 100644 org.hl7.fhir.validation/src/main/resources/public/style.css create mode 100644 org.hl7.fhir.validation/src/main/resources/public/test.html diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Manager.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Manager.java index 7ec051cbc..a69ea4c5e 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Manager.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Manager.java @@ -24,6 +24,8 @@ package org.hl7.fhir.r5.elementmodel; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; import org.hl7.fhir.exceptions.DefinitionException; import org.hl7.fhir.exceptions.FHIRException; @@ -34,22 +36,34 @@ import org.hl7.fhir.r5.model.StructureDefinition; public class Manager { - public enum FhirFormat { XML, JSON, TURTLE, TEXT, VBAR; + //TODO use EnumMap + public enum FhirFormat { + XML("xml"), + JSON("json"), + TURTLE("ttl"), + TEXT("txt"), + VBAR("hl7"); + + final String extension; + + FhirFormat(String extension) { + this.extension = extension; + } public String getExtension() { - switch (this) { - case JSON: - return "json"; - case TURTLE: - return "ttl"; - case XML: - return "xml"; - case TEXT: - return "txt"; - case VBAR: - return "hl7"; + return this.extension; + } + + private static final Map lookup = new HashMap<>(); + + static { + for(FhirFormat ff : FhirFormat.values()) { + lookup.put(ff.getExtension(), ff); } - return null; + } + + public static FhirFormat get(String extension) { + return lookup.get(extension); } } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/ValidationMessage.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/ValidationMessage.java index fe28e6cb4..c52257716 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/ValidationMessage.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/ValidationMessage.java @@ -51,6 +51,7 @@ package org.hl7.fhir.utilities.validation; */ import java.util.Comparator; +import java.util.EnumMap; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml index 3d933bbbf..12db7dce5 100644 --- a/org.hl7.fhir.validation/pom.xml +++ b/org.hl7.fhir.validation/pom.xml @@ -12,6 +12,10 @@ org.hl7.fhir.validation bundle + + 1.3.4 + + @@ -99,12 +103,26 @@ 1.0.2 - - org.hl7.fhir.testcases - fhir-test-cases - ${validator_test_case_version} - test + io.javalin + javalin + 3.8.0 + + + org.slf4j + slf4j-simple + 1.7.28 + + + + com.fasterxml.jackson.core + jackson-databind + 2.10.3 + + + org.thymeleaf + thymeleaf + 3.0.9.RELEASE diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java index 77bef9dfd..1b765f440 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java @@ -1070,6 +1070,13 @@ public class ValidationEngine implements IValidatorResourceFetcher { return isBundle; } + public OperationOutcome validate(byte[] source, FhirFormat cntType, List profiles) throws Exception { + List messages = new ArrayList(); + InstanceValidator validator = getValidator(); + validator.validate(null, messages, new ByteArrayInputStream(source), cntType, asSdList(profiles)); + return messagesToOutcome(messages); + } + public OperationOutcome validate(String location, byte[] source, FhirFormat cntType, List profiles) throws Exception { List messages = new ArrayList(); if (doNative) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java index c98dbfdde..713271985 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java @@ -49,12 +49,17 @@ POSSIBILITY OF SUCH DAMAGE. */ import java.io.File; +import java.net.URI; import org.hl7.fhir.r5.model.ImplementationGuide; import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; -import org.hl7.fhir.validation.cli.*; +import org.hl7.fhir.validation.cli.ValidatorGui; +import org.hl7.fhir.validation.cli.services.ComparisonService; +import org.hl7.fhir.validation.cli.services.ValidationService; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.utils.*; /** * A executable class that will validate one or more FHIR resources against @@ -75,6 +80,8 @@ public class Validator { VALIDATION, TRANSFORM, NARRATIVE, SNAPSHOT, SCAN, CONVERT, FHIRPATH, VERSION } + private static CliContext cliContext; + private static String getNamedParam(String[] args, String param) { boolean found = false; for (String a : args) { @@ -91,7 +98,29 @@ public class Validator { return Long.toString(maxMemory / (1024 * 1024)); } + private static CliContext getCliContext() { + if (cliContext == null) { + cliContext = new CliContext(); + } + return cliContext; + } + + private static void goToWebPage(String url) { + try { + + URI uri= new URI(url); + + java.awt.Desktop.getDesktop().browse(uri); + System.out.println("Web page opened in browser"); + + } catch (Exception e) { + + e.printStackTrace(); + } + } + public static void main(String[] args) throws Exception { + System.out.println("FHIR Validation tool " + VersionUtil.getVersionString()); System.out.println("Detected Java version: " + System.getProperty("java.version") + " from " + System.getProperty("java.home") + " on " + System.getProperty("os.arch") + " (" + System.getProperty("sun.arch.data.model") + "bit). " + toMB(Runtime.getRuntime().maxMemory()) + "MB available"); String proxy = getNamedParam(args, Params.PROXY); @@ -101,7 +130,13 @@ public class Validator { System.setProperty("http.proxyPort", p[1]); } - if (Params.hasParam(args, Params.TEST)) { + if (Params.hasParam(args, Params.GUI)) { + cliContext = Params.loadCliContext(args); + String v = Common.getVersion(args); + String definitions = VersionUtilities.packageForVersion(v) + "#" + v; + ValidationEngine validationEngine = Common.getValidationEngine(v, definitions, cliContext.getTxLog()); + ValidatorGui.start(cliContext, validationEngine); + }else if (Params.hasParam(args, Params.TEST)) { Common.runValidationEngineTests(); } else if (args.length == 0 || Params.hasParam(args, Params.HELP) || Params.hasParam(args, "?") || Params.hasParam(args, "-?") || Params.hasParam(args, "/?")) { Display.displayHelpDetails(); @@ -115,30 +150,32 @@ public class Validator { else { // first, prepare the context String txLog = Params.getTerminologyServerLog(args); - ValidationEngine validator = Common.getValidationEngine(args, txLog); + String v = Common.getVersion(args); + String definitions = VersionUtilities.packageForVersion(v) + "#" + v; + ValidationEngine validator = Common.getValidationEngine(v, definitions, txLog); Params.checkIGFileReferences(args); - Comparison.doLeftRightComparison(args, dest, validator); + ComparisonService.doLeftRightComparison(args, dest, validator); } } else { Display.printCliArgumentsAndInfo(args); - CliContext cliContext = Params.loadCliContext(args); + cliContext = Params.loadCliContext(args); // Comment this out because definitions filename doesn't necessarily contain version (and many not even be 14 characters long). Version gets spit out a couple of lines later after we've loaded the context String definitions = VersionUtilities.packageForVersion(cliContext.getSv()) + "#" + VersionUtilities.getCurrentVersion(cliContext.getSv()); - ValidationEngine validator = ValidationUtils.getValidator(cliContext, definitions); - + ValidationEngine validator = ValidationService.getValidator(cliContext, definitions); if (cliContext.getMode() == EngineMode.VERSION) { - ValidationUtils.transformVersion(cliContext, validator); + + ValidationService.transformVersion(cliContext, validator); } else if (cliContext.getMode() == EngineMode.TRANSFORM) { - ValidationUtils.transform(cliContext, validator); + ValidationService.transform(cliContext, validator); } else if (cliContext.getMode() == EngineMode.NARRATIVE) { - ValidationUtils.generateNarrative(cliContext, validator); + ValidationService.generateNarrative(cliContext, validator); } else if (cliContext.getMode() == EngineMode.SNAPSHOT) { - ValidationUtils.generateSnapshot(cliContext, validator); + ValidationService.generateSnapshot(cliContext, validator); } else if (cliContext.getMode() == EngineMode.CONVERT) { - ValidationUtils.convertSources(cliContext, validator); + ValidationService.convertSources(cliContext, validator); } else if (cliContext.getMode() == EngineMode.FHIRPATH) { - ValidationUtils.evaluateFhirpath(cliContext, validator); + ValidationService.evaluateFhirpath(cliContext, validator); } else { if (definitions == null) { throw new Exception("Must provide a defn when doing validation"); @@ -150,9 +187,9 @@ public class Validator { } } if (cliContext.getMode() == EngineMode.SCAN) { - ValidationUtils.validateScan(cliContext, validator); + ValidationService.validateScan(cliContext, validator); } else { - ValidationUtils.validateSources(cliContext, validator); + ValidationService.validateSources(cliContext, validator); } } } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java new file mode 100644 index 000000000..b3999fc0a --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java @@ -0,0 +1,30 @@ +package org.hl7.fhir.validation.cli; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.javalin.Javalin; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.controller.CliContextController; +import org.hl7.fhir.validation.cli.controller.ValidationController; +import org.hl7.fhir.validation.cli.controller.UIController; +import org.hl7.fhir.validation.cli.model.CliContext; + +public class RestEndpoints { + + public UIController myUIController; + public CliContextController myCliContextController; + public ValidationController myValidationController; + + public void initRestEndpoints(Javalin app, CliContext cliContext, ValidationEngine validationEngine) { + + myUIController = new UIController(); + myCliContextController = new CliContextController(cliContext); + myValidationController = new ValidationController(validationEngine); + + app.get("/home", myUIController.renderLandingPage); + + app.get("/context", myCliContextController.getCurrentCliContext); + app.post("/context", myCliContextController.setCurrentCliContext); + + app.post("/validate", myValidationController.handleValidationRequest); + } +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java new file mode 100644 index 000000000..bc287cad1 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java @@ -0,0 +1,37 @@ +package org.hl7.fhir.validation.cli; + +import io.javalin.Javalin; +import org.hl7.fhir.utilities.VersionUtilities; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.utils.Common; + +public class ValidatorGui { + + private static final String WEB_APP_FILE_LOCATION = "/public"; + private static Javalin app; + + /** + * N.B. this entry point, is only for testing. Please start from command line using the argument {@code -gui} for + * actual use. + */ + public static void main(String[] args) throws Exception { + CliContext cliContext = new CliContext(); + String v = Common.getVersion(args); + String definitions = VersionUtilities.packageForVersion(v) + "#" + v; + ValidationEngine validationEngine = Common.getValidationEngine(v, definitions, cliContext.getTxLog()); + start(new CliContext(), validationEngine); + } + + public static void start(CliContext currentContext, ValidationEngine validationEngine) { + app = Javalin.create(); + new RestEndpoints().initRestEndpoints(app, new CliContext(), validationEngine); + app.config.addStaticFiles(WEB_APP_FILE_LOCATION); + app.start(8080); + } + + public static void stop() { + app.stop(); + } + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/CliContextController.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/CliContextController.java new file mode 100644 index 000000000..1835a9f6b --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/CliContextController.java @@ -0,0 +1,27 @@ +package org.hl7.fhir.validation.cli.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.javalin.http.Handler; +import org.apache.http.HttpStatus; +import org.hl7.fhir.validation.cli.model.CliContext; + +public class CliContextController { + + private CliContext myCliContext; + + public CliContextController(CliContext cliContext) { + this.myCliContext = cliContext; + } + + public Handler getCurrentCliContext = ctx -> { + ObjectMapper Obj = new ObjectMapper(); + String jsonStr = Obj.writeValueAsString(myCliContext); + ctx.result(jsonStr); + }; + + public Handler setCurrentCliContext = ctx -> { + myCliContext = ctx.bodyAsClass(CliContext.class); + ctx.status(HttpStatus.SC_CREATED); + }; + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/UIController.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/UIController.java new file mode 100644 index 000000000..2c583a030 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/UIController.java @@ -0,0 +1,13 @@ +package org.hl7.fhir.validation.cli.controller; + +import io.javalin.http.Handler; + +public class UIController { + + public UIController() {} + + public Handler renderLandingPage = ctx -> { + ctx.render("/public/test.html"); + }; + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java new file mode 100644 index 000000000..c290415a2 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java @@ -0,0 +1,31 @@ +package org.hl7.fhir.validation.cli.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.javalin.http.Handler; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.ValidationRequest; +import org.hl7.fhir.validation.cli.model.ValidationResponse; +import org.hl7.fhir.validation.cli.services.ValidationService; + +public class ValidationController { + + private ValidationEngine myValidationEngine; + + public ValidationController(ValidationEngine validationEngine) { + this.myValidationEngine = validationEngine; + } + + public Handler handleValidationRequest = ctx -> { + ValidationRequest request = ctx.bodyAsClass(ValidationRequest.class); + ValidationResponse response = ValidationService.validateSources(request, myValidationEngine); + +// File new temp file +// DeleteOnShutdown + + ObjectMapper Obj = new ObjectMapper(); + String jsonStr = Obj.writeValueAsString(response); + + ctx.status(200).json(jsonStr); + }; + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/test.json b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/test.json new file mode 100644 index 000000000..56d816c22 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/test.json @@ -0,0 +1,29 @@ +{ + "outcomes": [ + { + "fileInfo": { + "fileName": "account-example.canonical.json", + "fileContent": "{\"id\":\"example\",\"resourceType\":\"Account\",\"text\":{\"div\":\"
[Put rendering here]
\",\"status\":\"generated\"}}", + "fileType": "JSON" + }, + "issues": [ + { + "severity": "Error", + "details": "Wrong namespace on the XHTML (\"null\", should be \"http://www.w3.org/1999/xhtml\")" + }, + { + "severity": "Error", + "details": "Profile http://hl7.org/fhir/StructureDefinition/Account, Element 'Account.status': minimum required = 1, but only found 0" + } + ] + }, + { + "fileInfo": { + "fileName": "account-example(example).xml", + "fileContent": "\n\t\n\t\n \n \n \n \n \n \n \n\t\t\n\t\t
HACC Funded Billing for Peter James Chalmers
\n\t
\n\t\n\t\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\n\t\n
", + "fileType": "XML" + }, + "issues": [] + } + ] +} \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/CliContext.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java similarity index 63% rename from org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/CliContext.java rename to org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java index 3df25408a..81335261c 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/CliContext.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java @@ -1,6 +1,8 @@ -package org.hl7.fhir.validation.cli; +package org.hl7.fhir.validation.cli.model; +import com.fasterxml.jackson.annotation.JsonProperty; import org.hl7.fhir.validation.Validator; +import org.hl7.fhir.validation.cli.utils.SnomedVersion; import java.util.*; @@ -9,44 +11,78 @@ import java.util.*; */ public class CliContext { - private String map = null; - private List igs = new ArrayList(); - private List questionnaires = new ArrayList(); - private String txServer = "http://tx.fhir.org"; + @JsonProperty("doNative") private boolean doNative = false; + @JsonProperty("anyExtensionsAllowed") private boolean anyExtensionsAllowed = true; + @JsonProperty("hintAboutNonMustSupport") private boolean hintAboutNonMustSupport = false; + @JsonProperty("recursive") private boolean recursive = false; - private Locale locale = null; - private List profiles = new ArrayList(); - private Validator.EngineMode mode = Validator.EngineMode.VALIDATION; - private String output = null; - private Boolean canDoNative = null; - private List sources = new ArrayList(); - private Map locations = new HashMap(); - private String sv = "current"; - private String txLog = null; - private String mapLog = null; - private String lang = null; - private String fhirpath = null; - private String snomedCT = SnomedVersion.INTL.getCode(); - private String targetVer = null; + @JsonProperty("doDebug") private boolean doDebug = false; + @JsonProperty("assumeValidRestReferences") private boolean assumeValidRestReferences = false; + @JsonProperty("canDoNative") + private boolean canDoNative = false; + @JsonProperty("map") + private String map = null; + @JsonProperty("output") + private String output = null; + @JsonProperty("txServer") + private String txServer = "http://tx.fhir.org"; + @JsonProperty("sv") + private String sv = "current"; + @JsonProperty("txLog") + private String txLog = null; + @JsonProperty("mapLog") + private String mapLog = null; + @JsonProperty("lang") + private String lang = null; + @JsonProperty("fhirpath") + private String fhirpath = null; + @JsonProperty("snomedCT") + private String snomedCT = SnomedVersion.INTL.getCode(); + @JsonProperty("targetVer") + private String targetVer = null; + + @JsonProperty("igs") + private List igs = new ArrayList(); + @JsonProperty("questionnaires") + private List questionnaires = new ArrayList(); + @JsonProperty("profiles") + private List profiles = new ArrayList(); + @JsonProperty("sources") + private List sources = new ArrayList(); + + @JsonProperty("mode") + private Validator.EngineMode mode = Validator.EngineMode.VALIDATION; + + @JsonProperty("locale") + private Locale locale = null; + + @JsonProperty("locations") + private Map locations = new HashMap(); + + + @JsonProperty("map") public String getMap() { return map; } + @JsonProperty("map") public CliContext setMap(String map) { this.map = map; return this; } + @JsonProperty("igs") public List getIgs() { return igs; } + @JsonProperty("igs") public CliContext setIgs(List igs) { this.igs = igs; return this; @@ -60,10 +96,12 @@ public class CliContext { return this; } + @JsonProperty("questionnaires") public List getQuestionnaires() { return questionnaires; } + @JsonProperty("questionnaires") public CliContext setQuestionnaires(List questionnaires) { this.questionnaires = questionnaires; return this; @@ -77,64 +115,87 @@ public class CliContext { return this; } + @JsonProperty("txServer") public String getTxServer() { return txServer; } + @JsonProperty("txServer") public CliContext setTxServer(String txServer) { this.txServer = txServer; return this; } + @JsonProperty("doNative") public boolean isDoNative() { return doNative; } + @JsonProperty("doNative") public CliContext setDoNative(boolean doNative) { this.doNative = doNative; return this; } + @JsonProperty("anyExtensionsAllowed") public boolean isAnyExtensionsAllowed() { return anyExtensionsAllowed; } + @JsonProperty("anyExtensionsAllowed") public CliContext setAnyExtensionsAllowed(boolean anyExtensionsAllowed) { this.anyExtensionsAllowed = anyExtensionsAllowed; return this; } + @JsonProperty("hintAboutNonMustSupport") public boolean isHintAboutNonMustSupport() { return hintAboutNonMustSupport; } + @JsonProperty("hintAboutNonMustSupport") public CliContext setHintAboutNonMustSupport(boolean hintAboutNonMustSupport) { this.hintAboutNonMustSupport = hintAboutNonMustSupport; return this; } + @JsonProperty("recursive") public boolean isRecursive() { return recursive; } + @JsonProperty("recursive") public CliContext setRecursive(boolean recursive) { this.recursive = recursive; return this; } + @JsonProperty("locale") + public String getLanguageCode() { + return this.locale.getDisplayLanguage(); + } + public Locale getLocale() { return locale; } + @JsonProperty("locale") + public CliContext setLocale(String languageString) { + this.locale = new Locale(languageString); + return this; + } + public CliContext setLocale(Locale locale) { this.locale = locale; return this; } + @JsonProperty("profiles") public List getProfiles() { return profiles; } + @JsonProperty("profiles") public CliContext setProfiles(List profiles) { this.profiles = profiles; return this; @@ -148,37 +209,45 @@ public class CliContext { return this; } + @JsonProperty("mode") public Validator.EngineMode getMode() { return mode; } + @JsonProperty("mode") public CliContext setMode(Validator.EngineMode mode) { this.mode = mode; return this; } + @JsonProperty("output") public String getOutput() { return output; } + @JsonProperty("output") public CliContext setOutput(String output) { this.output = output; return this; } - public Boolean getCanDoNative() { + @JsonProperty("canDoNative") + public boolean getCanDoNative() { return canDoNative; } - public CliContext setCanDoNative(Boolean canDoNative) { + @JsonProperty("canDoNative") + public CliContext setCanDoNative(boolean canDoNative) { this.canDoNative = canDoNative; return this; } + @JsonProperty("sources") public List getSources() { return sources; } + @JsonProperty("sources") public CliContext setSources(List sources) { this.sources = sources; return this; @@ -192,10 +261,12 @@ public class CliContext { return this; } + @JsonProperty("locations") public Map getLocations() { return locations; } + @JsonProperty("locations") public CliContext setLocations(Map locations) { this.locations = locations; return this; @@ -206,84 +277,132 @@ public class CliContext { return this; } + @JsonProperty("sv") public String getSv() { return sv; } + @JsonProperty("sv") public CliContext setSv(String sv) { this.sv = sv; return this; } + @JsonProperty("txLog") public String getTxLog() { return txLog; } + @JsonProperty("txLog") public CliContext setTxLog(String txLog) { this.txLog = txLog; return this; } + @JsonProperty("mapLog") public String getMapLog() { return mapLog; } + @JsonProperty("mapLog") public CliContext setMapLog(String mapLog) { this.mapLog = mapLog; return this; } + @JsonProperty("lang") public String getLang() { return lang; } + @JsonProperty("lang") public CliContext setLang(String lang) { this.lang = lang; return this; } + @JsonProperty("fhirpath") public String getFhirpath() { return fhirpath; } + @JsonProperty("fhirpath") public CliContext setFhirpath(String fhirpath) { this.fhirpath = fhirpath; return this; } + @JsonProperty("snomedCT") public String getSnomedCT() { return snomedCT; } + @JsonProperty("snomedCT") public CliContext setSnomedCT(String snomedCT) { this.snomedCT = SnomedVersion.resolveSnomedCTCode(snomedCT); return this; } + @JsonProperty("targetVer") public String getTargetVer() { return targetVer; } + @JsonProperty("targetVer") public CliContext setTargetVer(String targetVer) { this.targetVer = targetVer; return this; } + @JsonProperty("doDebug") public boolean isDoDebug() { return doDebug; } + @JsonProperty("doDebug") public CliContext setDoDebug(boolean doDebug) { this.doDebug = doDebug; return this; } + @JsonProperty("assumeValidRestReferences") public boolean isAssumeValidRestReferences() { return assumeValidRestReferences; } + @JsonProperty("assumeValidRestReferences") public CliContext setAssumeValidRestReferences(boolean assumeValidRestReferences) { this.assumeValidRestReferences = assumeValidRestReferences; return this; } + + @Override + public String toString() { + return "CliContext{" + + "map='" + map + '\'' + + ", igs=" + igs + + ", questionnaires=" + questionnaires + + ", txServer='" + txServer + '\'' + + ", doNative=" + doNative + + ", anyExtensionsAllowed=" + anyExtensionsAllowed + + ", hintAboutNonMustSupport=" + hintAboutNonMustSupport + + ", recursive=" + recursive + + ", locale=" + locale + + ", profiles=" + profiles + + ", mode=" + mode + + ", output='" + output + '\'' + + ", canDoNative=" + canDoNative + + ", sources=" + sources + + ", locations=" + locations + + ", sv='" + sv + '\'' + + ", txLog='" + txLog + '\'' + + ", mapLog='" + mapLog + '\'' + + ", lang='" + lang + '\'' + + ", fhirpath='" + fhirpath + '\'' + + ", snomedCT='" + snomedCT + '\'' + + ", targetVer='" + targetVer + '\'' + + ", doDebug=" + doDebug + + ", assumeValidRestReferences=" + assumeValidRestReferences + + '}'; + } } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContextTest.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContextTest.java new file mode 100644 index 000000000..82466642c --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContextTest.java @@ -0,0 +1,80 @@ +package org.hl7.fhir.validation.cli.model; + +/** + * A POJO for storing the flags/values for the CLI validator. + */ +public class CliContextTest { + + private boolean doNative = false; + private boolean anyExtensionsAllowed = true; + private boolean hintAboutNonMustSupport = false; + private boolean recursive = false; + private boolean doDebug = false; + private boolean assumeValidRestReferences = false; + + public boolean isDoNative() { + return doNative; + } + + public CliContextTest setDoNative(boolean doNative) { + this.doNative = doNative; + return this; + } + + public boolean isAnyExtensionsAllowed() { + return anyExtensionsAllowed; + } + + public CliContextTest setAnyExtensionsAllowed(boolean anyExtensionsAllowed) { + this.anyExtensionsAllowed = anyExtensionsAllowed; + return this; + } + + public boolean isHintAboutNonMustSupport() { + return hintAboutNonMustSupport; + } + + public CliContextTest setHintAboutNonMustSupport(boolean hintAboutNonMustSupport) { + this.hintAboutNonMustSupport = hintAboutNonMustSupport; + return this; + } + + public boolean isRecursive() { + return recursive; + } + + public CliContextTest setRecursive(boolean recursive) { + this.recursive = recursive; + return this; + } + + public boolean isDoDebug() { + return doDebug; + } + + public CliContextTest setDoDebug(boolean doDebug) { + this.doDebug = doDebug; + return this; + } + + public boolean isAssumeValidRestReferences() { + return assumeValidRestReferences; + } + + public CliContextTest setAssumeValidRestReferences(boolean assumeValidRestReferences) { + this.assumeValidRestReferences = assumeValidRestReferences; + return this; + } + + @Override + public String toString() { + return "CliContext{" + + ", doNative=" + doNative + + ", anyExtensionsAllowed=" + anyExtensionsAllowed + + ", hintAboutNonMustSupport=" + hintAboutNonMustSupport + + ", recursive=" + recursive + + ", doDebug=" + doDebug + + ", assumeValidRestReferences=" + assumeValidRestReferences + + '}'; + } +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/FileInfo.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/FileInfo.java new file mode 100644 index 000000000..4d655972a --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/FileInfo.java @@ -0,0 +1,49 @@ +package org.hl7.fhir.validation.cli.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.hl7.fhir.r5.elementmodel.Manager; + +public class FileInfo { + + @JsonProperty("fileName") + private String fileName; + + @JsonProperty("fileContent") + private String fileContent; + + @JsonProperty("fileType") + private String fileType; + + @JsonProperty("fileName") + public String getFileName() { + return fileName; + } + + @JsonProperty("fileName") + public FileInfo setFileName(String fileName) { + this.fileName = fileName; + return this; + } + + @JsonProperty("fileContent") + public String getFileContent() { + return fileContent; + } + + @JsonProperty("fileContent") + public FileInfo setFileContent(String fileContent) { + this.fileContent = fileContent; + return this; + } + + @JsonProperty("fileType") + public Manager.FhirFormat getFileType() { + return Manager.FhirFormat.get(fileType); + } + + @JsonProperty("fileType") + public FileInfo setFileType(String fileType) { + this.fileType = fileType; + return this; + } +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationIssue.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationIssue.java new file mode 100644 index 000000000..a18f1a33e --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationIssue.java @@ -0,0 +1,32 @@ +package org.hl7.fhir.validation.cli.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ValidationIssue { + @JsonProperty("severity") + private String severity; + @JsonProperty("details") + private String details; + + @JsonProperty("severity") + public String getSeverity() { + return severity; + } + + @JsonProperty("severity") + public ValidationIssue setSeverity(String severity) { + this.severity = severity; + return this; + } + + @JsonProperty("details") + public String getDetails() { + return details; + } + + @JsonProperty("details") + public ValidationIssue setDetails(String details) { + this.details = details; + return this; + } +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationOutcome.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationOutcome.java new file mode 100644 index 000000000..1510c806b --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationOutcome.java @@ -0,0 +1,47 @@ +package org.hl7.fhir.validation.cli.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.hl7.fhir.r5.model.OperationOutcome; + +import java.util.ArrayList; +import java.util.List; + +public class ValidationOutcome { + + @JsonProperty("fileInfo") + private FileInfo fileInfo; + @JsonProperty("issues") + private List issues = new ArrayList<>(); + + @JsonProperty("fileInfo") + public FileInfo getFileInfo() { + return fileInfo; + } + + @JsonProperty("fileInfo") + public ValidationOutcome setFileInfo(FileInfo fileInfo) { + this.fileInfo = fileInfo; + return this; + } + + @JsonProperty("issues") + public List getIssues() { + return issues; + } + + @JsonProperty("issues") + public ValidationOutcome setIssues(List issues) { + this.issues = issues; + return this; + } + + public ValidationOutcome addIssue(OperationOutcome.OperationOutcomeIssueComponent outcome) { + String text = outcome.getDetails().getText(); + text.replace("\'", "\""); + issues.add(new ValidationIssue() + .setSeverity(outcome.getSeverity().getDisplay()) + .setDetails(outcome.getDetails().getText())); + return this; + } + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationRequest.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationRequest.java new file mode 100644 index 000000000..a515c5afa --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationRequest.java @@ -0,0 +1,45 @@ +package org.hl7.fhir.validation.cli.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.ArrayList; +import java.util.List; + +public class ValidationRequest { + + @JsonProperty("cliContext") + private CliContext cliContext; + + @JsonProperty("filesToValidate") + private List filesToValidate = new ArrayList<>(); + + @JsonProperty("cliContext") + public CliContext getCliContext() { + return cliContext; + } + + @JsonProperty("cliContext") + public ValidationRequest setCliContext(CliContext cliContext) { + this.cliContext = cliContext; + return this; + } + + @JsonProperty("filesToValidate") + public List getFilesToValidate() { + return filesToValidate; + } + + @JsonProperty("filesToValidate") + public ValidationRequest setFilesToValidate(List filesToValidate) { + this.filesToValidate = filesToValidate; + return this; + } + + public String listSourceFiles() { + List fileNames = new ArrayList<>(); + for (FileInfo fp : filesToValidate) { + fileNames.add(fp.getFileName()); + } + return String.join(", ", fileNames); + } +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationResponse.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationResponse.java new file mode 100644 index 000000000..7c010916d --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/ValidationResponse.java @@ -0,0 +1,33 @@ +package org.hl7.fhir.validation.cli.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.ArrayList; +import java.util.List; + +public class ValidationResponse { + + @JsonProperty("outcomes") + public List outcomes = new ArrayList<>(); + + @JsonProperty("outcomes") + public List getOutcomes() { + return outcomes; + } + + @JsonProperty("outcomes") + public ValidationResponse setOutcomes(List outcomes) { + this.outcomes = outcomes; + return this; + } + + public ValidationResponse addOutcome(ValidationOutcome outcome) { + if (outcomes == null) { + outcomes = new ArrayList<>(); + } + outcomes.add(outcome); + return this; + } + +} + diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/Comparison.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ComparisonService.java similarity index 91% rename from org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/Comparison.java rename to org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ComparisonService.java index 2ae398529..5e584d339 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/Comparison.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ComparisonService.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.validation.cli; +package org.hl7.fhir.validation.cli.services; import org.hl7.fhir.r5.conformance.CapabilityStatementUtilities; import org.hl7.fhir.r5.conformance.ProfileComparer; @@ -14,6 +14,7 @@ import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.utils.Params; import java.awt.*; import java.io.File; @@ -21,7 +22,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.UUID; -public class Comparison { +public class ComparisonService { public static void doLeftRightComparison(String[] args, String dest, ValidationEngine validator) throws IOException { // ok now set up the comparison @@ -39,9 +40,9 @@ public class Comparison { if (resLeft != null && resRight != null) { if (resLeft instanceof StructureDefinition && resRight instanceof StructureDefinition) { - Comparison.compareStructureDefinitions(dest, validator, left, right, (StructureDefinition) resLeft, (StructureDefinition) resRight); + ComparisonService.compareStructureDefinitions(dest, validator, left, right, (StructureDefinition) resLeft, (StructureDefinition) resRight); } else if (resLeft instanceof CapabilityStatement && resRight instanceof CapabilityStatement) { - Comparison.compareCapabilityStatements(args, dest, validator, left, right, (CanonicalResource) resLeft, (CanonicalResource) resRight); + ComparisonService.compareCapabilityStatements(args, dest, validator, left, right, (CanonicalResource) resLeft, (CanonicalResource) resRight); } else System.out.println("Unable to compare left resource " + left + " (" + resLeft.fhirType() + ") with right resource " + right + " (" + resRight.fhirType() + ")"); } @@ -71,7 +72,7 @@ public class Comparison { new JsonParser().setOutputStyle(IParser.OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path(dest, "CapabilityStatement-intersection.json")), output.getSubset()); new JsonParser().setOutputStyle(IParser.OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path(dest, "OperationOutcome-issues.json")), output.getOutcome()); - String destHtml = Utilities.path(dest, "index.html"); + String destHtml = Utilities.path(dest, "public/index.html"); File htmlFile = new File(destHtml); Desktop.getDesktop().browse(htmlFile.toURI()); System.out.println("Done"); diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidationUtils.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java similarity index 88% rename from org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidationUtils.java rename to org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java index 7d0fc466f..67ab7dbf0 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidationUtils.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.validation.cli; +package org.hl7.fhir.validation.cli.services; import org.hl7.fhir.r5.elementmodel.Manager; import org.hl7.fhir.r5.formats.IParser; @@ -9,6 +9,7 @@ import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.*; import java.io.File; import java.io.FileOutputStream; @@ -16,13 +17,37 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -public class ValidationUtils { +public class ValidationService { + + public static ValidationResponse validateSources(ValidationRequest request, ValidationEngine validator) throws Exception { + if (request.getCliContext().getProfiles().size() > 0) { + System.out.println(" .. validate " + request.listSourceFiles() + " against " + request.getCliContext().getProfiles().toString()); + } else { + System.out.println(" .. validate " + request.listSourceFiles()); + } + validator.prepare(); // generate any missing snapshots + + ValidationResponse response = new ValidationResponse(); + for (FileInfo fp : request.getFilesToValidate()) { + OperationOutcome operationOutcome = validator.validate(fp.getFileContent().getBytes(), fp.getFileType(), + request.getCliContext().getProfiles()); + ValidationOutcome outcome = new ValidationOutcome(); + + // Need to set file content to null as server can't handle json in json + fp.setFileContent(null); + outcome.setFileInfo(fp); + operationOutcome.getIssue().forEach(outcome::addIssue); + response.addOutcome(outcome); + } + return response; + } public static void validateSources(CliContext cliContext, ValidationEngine validator) throws Exception { - if (cliContext.getProfiles().size() > 0) + if (cliContext.getProfiles().size() > 0) { System.out.println(" .. validate " + cliContext.getSources() + " against " + cliContext.getProfiles().toString()); - else + } else { System.out.println(" .. validate " + cliContext.getSources()); + } validator.prepare(); // generate any missing snapshots Resource r = validator.validate(cliContext.getSources(), cliContext.getProfiles()); int ec = 0; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/Common.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Common.java similarity index 88% rename from org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/Common.java rename to org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Common.java index 66e617399..f13de0b4e 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/Common.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Common.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.validation.cli; +package org.hl7.fhir.validation.cli.utils; import org.hl7.fhir.r5.model.Constants; import org.hl7.fhir.r5.model.FhirPublication; @@ -75,11 +75,9 @@ public class Common { } } - public static ValidationEngine getValidationEngine(String[] args, String txLog) throws Exception { - String v = Common.getVersion(args); - String definitions = VersionUtilities.packageForVersion(v) + "#" + v; - System.out.println("Loading (v = " + v + ", tx server http://tx.fhir.org)"); - return new ValidationEngine(definitions, "http://tx.fhir.org", txLog, FhirPublication.fromCode(v), v); + public static ValidationEngine getValidationEngine(String version, String definitions, String txLog) throws Exception { + System.out.println("Loading (v = " + version + ", tx server http://tx.fhir.org)"); + return new ValidationEngine(definitions, "http://tx.fhir.org", txLog, FhirPublication.fromCode(version), version); } } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/Display.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Display.java similarity index 99% rename from org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/Display.java rename to org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Display.java index 4bfda8ecc..f06fe27cf 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/Display.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Display.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.validation.cli; +package org.hl7.fhir.validation.cli.utils; import org.hl7.fhir.r5.model.Constants; import org.hl7.fhir.utilities.VersionUtilities; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/Params.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java similarity index 98% rename from org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/Params.java rename to org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java index 59f57212e..d5c001427 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/Params.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java @@ -1,7 +1,8 @@ -package org.hl7.fhir.validation.cli; +package org.hl7.fhir.validation.cli.utils; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.validation.Validator; +import org.hl7.fhir.validation.cli.model.CliContext; import java.io.File; import java.util.Arrays; @@ -9,6 +10,7 @@ import java.util.Locale; public class Params { + public static final String GUI = "-gui"; public static final String VERSION = "-version"; public static final String OUTPUT = "-output"; public static final String PROXY = "-proxy"; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/SnomedVersion.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/SnomedVersion.java similarity index 95% rename from org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/SnomedVersion.java rename to org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/SnomedVersion.java index 84a33a65e..11cae4b20 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/SnomedVersion.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/SnomedVersion.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.validation.cli; +package org.hl7.fhir.validation.cli.utils; import java.util.Arrays; import java.util.Optional; diff --git a/org.hl7.fhir.validation/src/main/resources/public/assets/bootstrap-outline.svg b/org.hl7.fhir.validation/src/main/resources/public/assets/bootstrap-outline.svg new file mode 100644 index 000000000..ed1825e3e --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/assets/bootstrap-outline.svg @@ -0,0 +1,5 @@ + + Bootstrap + + + diff --git a/org.hl7.fhir.validation/src/main/resources/public/assets/fhir-logo-www.png b/org.hl7.fhir.validation/src/main/resources/public/assets/fhir-logo-www.png new file mode 100644 index 0000000000000000000000000000000000000000..90cb7dc8197a2e72709b34224367060eb9e7fdd2 GIT binary patch literal 13319 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 HHsSvdCq0js literal 0 HcmV?d00001 diff --git a/org.hl7.fhir.validation/src/main/resources/public/assets/json-svgrepo-com.svg b/org.hl7.fhir.validation/src/main/resources/public/assets/json-svgrepo-com.svg new file mode 100644 index 000000000..5643327d1 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/assets/json-svgrepo-com.svg @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.hl7.fhir.validation/src/main/resources/public/assets/xml-svgrepo-com.svg b/org.hl7.fhir.validation/src/main/resources/public/assets/xml-svgrepo-com.svg new file mode 100644 index 000000000..d0b7a4375 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/assets/xml-svgrepo-com.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.hl7.fhir.validation/src/main/resources/public/cliwindow.html b/org.hl7.fhir.validation/src/main/resources/public/cliwindow.html new file mode 100644 index 000000000..607f775e6 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/cliwindow.html @@ -0,0 +1,56 @@ + diff --git a/org.hl7.fhir.validation/src/main/resources/public/enums/EngineMode.js b/org.hl7.fhir.validation/src/main/resources/public/enums/EngineMode.js new file mode 100644 index 000000000..63b88cdec --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/enums/EngineMode.js @@ -0,0 +1,10 @@ +export const EngineMode { + VALIDATION, + TRANSFORM, + NARRATIVE, + SNAPSHOT, + SCAN, + CONVERT, + FHIRPATH, + VERSION +} diff --git a/org.hl7.fhir.validation/src/main/resources/public/enums/FhirFormat.js b/org.hl7.fhir.validation/src/main/resources/public/enums/FhirFormat.js new file mode 100644 index 000000000..c7df35004 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/enums/FhirFormat.js @@ -0,0 +1,17 @@ +export const FhirFormat = { + XML: { + extension:'xml' + }, + JSON: { + extension:'json' + }, + TURTLE: { + extension:'ttl' + }, + TEXT: { + extension:'txt' + }, + VBAR: { + extension:'hl7' + }, +} diff --git a/org.hl7.fhir.validation/src/main/resources/public/enums/Locale.js b/org.hl7.fhir.validation/src/main/resources/public/enums/Locale.js new file mode 100644 index 000000000..e3195a1d8 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/enums/Locale.js @@ -0,0 +1,30 @@ +export const Locale = { + ENGLISH: { + code: 'en', + value: 'English' + }, + FRENCH: { + code: 'fr', + value: 'French' + }, + GERMAN: { + code: 'de', + value: 'German' + }, + ITALIAN: { + code: 'it', + value: 'Italian' + }, + JAPANESE: { + code: 'ja', + value: 'Japanese' + }, + KOREAN: { + code: 'ko', + value: 'Korean' + }, + CHINESE: { + code: 'zh', + value: 'Chinese' + } +} diff --git a/org.hl7.fhir.validation/src/main/resources/public/enums/SnomedVersion.js b/org.hl7.fhir.validation/src/main/resources/public/enums/SnomedVersion.js new file mode 100644 index 000000000..3f82d797f --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/enums/SnomedVersion.js @@ -0,0 +1,38 @@ +export const SnomedVersion = { + INTL: { + value: "intl", + code: "900000000000207008" + }, + US: { + value: "us", + code: "731000124108" + }, + UK: { + value: "uk", + code: "999000041000000102" + }, + AU: { + value: "au", + code: "32506021000036107" + }, + CA: { + value: "ca", + code: "20611000087101" + }, + NL: { + value: "nl", + code: "11000146104" + }, + SE: { + value: "se", + code: "45991000052106" + }, + ES: { + value: "es", + code: "449081005" + }, + DK: { + value: "dk", + code: "554471000005108" + } +} diff --git a/org.hl7.fhir.validation/src/main/resources/public/index.html b/org.hl7.fhir.validation/src/main/resources/public/index.html new file mode 100644 index 000000000..94a6e5220 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/index.html @@ -0,0 +1,66 @@ + + + + + + + JS For Beginners + + + + + + + +
+

Validator 2.0

+
+
+
+
+
    +
  • + + +
  • +
  • + Filename Here + + + +
  • +
+ +
+ +
+ + +
    +
    + + + +
    + +
    +
    +

    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    +
    + + + diff --git a/org.hl7.fhir.validation/src/main/resources/public/main.js b/org.hl7.fhir.validation/src/main/resources/public/main.js new file mode 100644 index 000000000..b12fdcd70 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/main.js @@ -0,0 +1,133 @@ +import {CliContext} from './model/CliContext.js'; +import {ValidationRequest} from './model/ValidationRequest.js'; +import {FileInfo} from './model/FileInfo.js'; + +// Constants +const jsonIcon = './assets/json-svgrepo-com.svg'; +const xmlIcon = './assets/xml-svgrepo-com.svg'; + +// Data Fields +const cli = new CliContext(); +const filesToValidate = []; + +document.getElementById('validate_button').addEventListener("click", validateCurrentFiles); +document.getElementById('files').addEventListener('change', handleFileSelect, false); + +// File reading +function handleFileSelect(evt) { + var files = evt.target.files; + var output = []; + for (var i = 0, f; f = files[i]; i++) { + generateFileEntry(f); + // Check for proper file type here + console.log(f.type); + } +} + +function generateFileEntry(file) { + var fr = new FileReader(); + fr.onload = function(e) { + // TODO there may be timing issues here + filesToValidate.push(new FileInfo(file.name, e.target.result, file.type)); + document.getElementById('loaded_file_list').appendChild(generateNewFileListItemFromTemplate(file)); + }; + fr.readAsText(file); +} + +// File List Template Generation + +function generateNewFileListItemFromTemplate(file) { + var template = document.querySelector('#loaded_file_entry'); + var clone = template.content.cloneNode(true); + + // Add file name + clone.getElementById('file_name_field').textContent = file.name; + + // Add appropriate icon for filetype + if (file.type.includes("json")) { + clone.getElementById('file_type_icon').src = jsonIcon; + } else if (file.type.includes("xml")) { + clone.getElementById('file_type_icon').src = xmlIcon; + } + + // Add delete listener + clone.getElementById("delete_button").addEventListener("click", handleDeleteOnFileList); + + return clone; +} + +function handleDeleteOnFileList(e) { + var li = e.target.closest('li'); + var nodes = Array.from( li.closest('ul').children ); + var index = nodes.indexOf( li ); + nodes[index].remove(); + filesToValidate.splice((index - 1), 1); + console.log('Index -> ' + index); + console.log(filesToValidate); +} + +// Validation +function validateCurrentFiles() { + sendFilesToValidate(filesToValidate); +} + +function sendFilesToValidate(arrayOfFileInfo) { + var req = new ValidationRequest(); + req.filesToValidate = arrayOfFileInfo; + + var xhr = new XMLHttpRequest(); + xhr.open("POST", 'http://localhost:8080/' + 'validate', true); + xhr.setRequestHeader('Content-Type', 'application/json'); + xhr.send(JSON.stringify(req)); + + xhr.onload = function () { + const response = '{"outcomes": [{"fileInfo": {"fileName": "account-example.canonical.json", "fileType": "JSON"}, "issues": [{"severity": "Error", "details": "\"null\""}, {"severity": "Error", "details": "Profile http://hl7.org/fhir/StructureDefinition/Account, Element: minimum required = 1, but only found 0"}]}, {"fileInfo": {"fileName": "account-example(example).xml", "fileType": "XML"}, "issues": []}]}'; + var test = xhr.responseText; + processValidationResponse(JSON.parse(JSON.parse(xhr.responseText))); + }; +} + +function processValidationResponse(validationResponse) { + console.log(validationResponse.outcomes[0]); + console.log(validationResponse.outcomes[1]); + //console.log(validationResponse); + //Do something +} + + + + +// window.onload = function loadCliContext() { +// var xhr = new XMLHttpRequest(); +// xhr.open("GET", 'http://localhost:8080/currentContext'); +// xhr.send(); +// xhr.onreadystatechange = function() { +// if (this.readyState == 4 && this.status == 200) { +// console.log(xhr.responseText); +// } +// } +// } + +// /* +// Escape JSON +// */ +// var escapeJSON = exports.escapeJSON = function(json) { +// var escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; +// var meta = { // table of character substitutions +// '\b': '\\b', +// '\t': '\\t', +// '\n': '\\n', +// '\f': '\\f', +// '\r': '\\r', +// '"' : '\\"', +// '\\': '\\\\' +// }; +// +// escapable.lastIndex = 0; +// return escapable.test(json) ? '"' + json.replace(escapable, function (a) { +// var c = meta[a]; +// return (typeof c === 'string') ? c +// : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); +// }) + '"' : '"' + json + '"'; +// +// }; diff --git a/org.hl7.fhir.validation/src/main/resources/public/model/CliContext.js b/org.hl7.fhir.validation/src/main/resources/public/model/CliContext.js new file mode 100644 index 000000000..673637cd9 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/model/CliContext.js @@ -0,0 +1,34 @@ +import {SnomedVersion} from '../enums/SnomedVersion.js'; +import {Locale} from '../enums/Locale.js'; + +export class CliContext { + constructor(){ + this.doNative = false; + this.anyExtensionsAllowed = true; + this.hintAboutNonMustSupport = false; + this.recursive = false; + this.doDebug = false; + this.assumeValidRestReferences = false; + this.canDoNative = false; + + this.map = null; + this.output = null; + this.txServer = "http://tx.fhir.org"; + this.sv = "current"; + this.txLog = null; + this.mapLog = null; + this.lang = null; + this.fhirpath = null; + this.snomedCT = SnomedVersion.ES.value; + this.targetVer = null; + + this.igs = []; + this.questionnaires = []; + this.profiles = []; + this.sources = []; + + this.locale = Locale.ENGLISH.value; + + this.locations = new Map(); + } +} diff --git a/org.hl7.fhir.validation/src/main/resources/public/model/FileInfo.js b/org.hl7.fhir.validation/src/main/resources/public/model/FileInfo.js new file mode 100644 index 000000000..d853c1e44 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/model/FileInfo.js @@ -0,0 +1,13 @@ +import {FhirFormat} from '../enums/FhirFormat.js'; + +export class FileInfo { + constructor(fileName, fileContent, type){ + this.fileName = fileName; + this.fileContent = fileContent; + if (type.includes('json')) { + this.fileType = FhirFormat.JSON.extension; + } else if (type.includes('xml')) { + this.fileType = FhirFormat.XML.extension; + } + } +} diff --git a/org.hl7.fhir.validation/src/main/resources/public/model/ValidationIssue.js b/org.hl7.fhir.validation/src/main/resources/public/model/ValidationIssue.js new file mode 100644 index 000000000..0ce182359 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/model/ValidationIssue.js @@ -0,0 +1,6 @@ +export class ValidationIssue { + constructor(){ + this.severity = ""; + this.details = ""; + } +} diff --git a/org.hl7.fhir.validation/src/main/resources/public/model/ValidationOutcome.js b/org.hl7.fhir.validation/src/main/resources/public/model/ValidationOutcome.js new file mode 100644 index 000000000..77f5e41d0 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/model/ValidationOutcome.js @@ -0,0 +1,8 @@ +import {FileInfo} from './FileInfo.js'; + +export class ValidationOutcome { + constructor(){ + this.fileInfo = null; + this.issues = []; + } +} diff --git a/org.hl7.fhir.validation/src/main/resources/public/model/ValidationRequest.js b/org.hl7.fhir.validation/src/main/resources/public/model/ValidationRequest.js new file mode 100644 index 000000000..85b7559bb --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/model/ValidationRequest.js @@ -0,0 +1,8 @@ +import {CliContext} from './CliContext.js'; + +export class ValidationRequest { + constructor(){ + this.cliContext = new CliContext(); + this.filesToValidate = []; + } +} diff --git a/org.hl7.fhir.validation/src/main/resources/public/model/ValidationResponse.js b/org.hl7.fhir.validation/src/main/resources/public/model/ValidationResponse.js new file mode 100644 index 000000000..d128d3e30 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/model/ValidationResponse.js @@ -0,0 +1,7 @@ +import {ValidationOutcome} from './ValidationOutcome.js'; + +export class ValidationResponse { + constructor() { + this.outcomes = []; + } +} diff --git a/org.hl7.fhir.validation/src/main/resources/public/style.css b/org.hl7.fhir.validation/src/main/resources/public/style.css new file mode 100644 index 000000000..1cba70413 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/style.css @@ -0,0 +1,94 @@ +/* */ +.container{ + width:80%; + margin:auto; + overflow: hidden; +} + +#main{ + float: left; + width: 70%; +} + +#sidebar{ + float: right; + width: 30%; +} + + +html, +body { + overflow-x: hidden; /* Prevent scroll on narrow devices */ +} + +body { + padding-top: 56px; +} + +@media (max-width: 991.98px) { + .offcanvas-collapse { + position: fixed; + top: 56px; /* Height of navbar */ + bottom: 0; + left: 100%; + width: 100%; + padding-right: 1rem; + padding-left: 1rem; + overflow-y: auto; + visibility: hidden; + background-color: #343a40; + transition: visibility .3s ease-in-out, -webkit-transform .3s ease-in-out; + transition: transform .3s ease-in-out, visibility .3s ease-in-out; + transition: transform .3s ease-in-out, visibility .3s ease-in-out, -webkit-transform .3s ease-in-out; + } + .offcanvas-collapse.open { + visibility: visible; + -webkit-transform: translateX(-100%); + transform: translateX(-100%); + } +} + +.nav-scroller { + position: relative; + z-index: 2; + height: 2.75rem; + overflow-y: hidden; +} + +.nav-scroller .nav { + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + padding-bottom: 1rem; + margin-top: -1px; + overflow-x: auto; + color: rgba(255, 255, 255, .75); + text-align: center; + white-space: nowrap; + -webkit-overflow-scrolling: touch; +} + +.nav-underline .nav-link { + padding-top: .75rem; + padding-bottom: .75rem; + font-size: .875rem; + color: #6c757d; +} + +.nav-underline .nav-link:hover { + color: #007bff; +} + +.nav-underline .active { + font-weight: 500; + color: #343a40; +} + +.text-white-50 { color: rgba(255, 255, 255, .5); } + +.bg-purple { background-color: #6f42c1; } + +.lh-100 { line-height: 1; } +.lh-125 { line-height: 1.25; } +.lh-150 { line-height: 1.5; } diff --git a/org.hl7.fhir.validation/src/main/resources/public/test.html b/org.hl7.fhir.validation/src/main/resources/public/test.html new file mode 100644 index 000000000..3a993e4fb --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/test.html @@ -0,0 +1,154 @@ + + + + + + + + + FHIR HL7 Resrouce Validator GUI + + + + + + + + + + + + + +
    +
    + +
    +
    FHIR Core Validator
    + Experimental +
    +
    + +
    +
    +
    Files to Validate
    + +
    + +
      + +
    + +
    + + + + +
    + + +
    +
    +
    +
    + +
    +
    +
    +
    + Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 + wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum + eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla + assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred + nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer + farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus + labore sustainable. +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 + wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum + eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla + assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred + nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer + farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus + labore sustainable. +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 + wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum + eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla + assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred + nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer + farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus + labore sustainable. +
    +
    +
    +
    + + +
    + + + + + + + + From 65b10fe9948144d190083b44061f3d81cde3fde6 Mon Sep 17 00:00:00 2001 From: markiantorno Date: Thu, 16 Apr 2020 17:06:19 -0400 Subject: [PATCH 2/8] Base functionality working --- .../resources/public/enums/IssueSeverity.js | 14 +++ .../src/main/resources/public/main.js | 101 +++++++++++++--- .../src/main/resources/public/test.html | 110 +++++------------- 3 files changed, 130 insertions(+), 95 deletions(-) create mode 100644 org.hl7.fhir.validation/src/main/resources/public/enums/IssueSeverity.js diff --git a/org.hl7.fhir.validation/src/main/resources/public/enums/IssueSeverity.js b/org.hl7.fhir.validation/src/main/resources/public/enums/IssueSeverity.js new file mode 100644 index 000000000..89665077f --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/public/enums/IssueSeverity.js @@ -0,0 +1,14 @@ +export const IssueSeverity = { + FATAL: { + code: 'Fatal' + }, + ERROR: { + code: 'Error' + }, + WARNING: { + code: 'Warning' + }, + INFORMATION: { + code: 'Information' + } +} diff --git a/org.hl7.fhir.validation/src/main/resources/public/main.js b/org.hl7.fhir.validation/src/main/resources/public/main.js index b12fdcd70..76ddbc1d1 100644 --- a/org.hl7.fhir.validation/src/main/resources/public/main.js +++ b/org.hl7.fhir.validation/src/main/resources/public/main.js @@ -1,11 +1,37 @@ import {CliContext} from './model/CliContext.js'; import {ValidationRequest} from './model/ValidationRequest.js'; import {FileInfo} from './model/FileInfo.js'; +import {FhirFormat} from './enums/FhirFormat.js'; +import {IssueSeverity} from './enums/IssueSeverity.js'; -// Constants +/* + +*/ + +// Icon Constants const jsonIcon = './assets/json-svgrepo-com.svg'; const xmlIcon = './assets/xml-svgrepo-com.svg'; +// HTML classes +const CLASS_LIST_ITEM_PLAIN = "list-group-item"; +const CLASS_LIST_ITEM_FATAL = "list-group-item list-group-item-dark"; +const CLASS_LIST_ITEM_ERROR = "list-group-item list-group-item-danger"; +const CLASS_LIST_ITEM_WARNING = "list-group-item list-group-item-warning"; +const CLASS_LIST_ITEM_INFORMATION = "list-group-item list-group-item-info"; + +// HTML IDs +const ID_FILE_ENTRY_TEMPLATE = '#file_entry_template'; +const ID_FILE_ENTRY_NAME = 'file_entry_name_field'; +const ID_FILE_ENTRY_ICON = 'file_entry_type_icon'; +const ID_FILE_ENTRY_DELETE_BUTTON = 'file_entry_delete_button'; +const ID_FILE_ENTRY_FILE_LIST = 'file_entry_file_list'; +const ID_FILE_ENTRY_OUTCOME_LIST = 'file_entry_outcome_list'; +const ID_FILE_ENTRY_COLLAPSE_SECTION = 'file_entry_collapse_section'; + +/* + +*/ + // Data Fields const cli = new CliContext(); const filesToValidate = []; @@ -29,33 +55,69 @@ function generateFileEntry(file) { fr.onload = function(e) { // TODO there may be timing issues here filesToValidate.push(new FileInfo(file.name, e.target.result, file.type)); - document.getElementById('loaded_file_list').appendChild(generateNewFileListItemFromTemplate(file)); + document.getElementById(ID_FILE_ENTRY_FILE_LIST).appendChild(generateNewFileListItemFromTemplate(file, filesToValidate.length - 1)); }; fr.readAsText(file); } // File List Template Generation -function generateNewFileListItemFromTemplate(file) { - var template = document.querySelector('#loaded_file_entry'); +function generateNewFileListItemFromTemplate(file, index) { + var template = document.querySelector(ID_FILE_ENTRY_TEMPLATE); var clone = template.content.cloneNode(true); // Add file name - clone.getElementById('file_name_field').textContent = file.name; + clone.getElementById(ID_FILE_ENTRY_NAME).textContent = file.name; // Add appropriate icon for filetype - if (file.type.includes("json")) { - clone.getElementById('file_type_icon').src = jsonIcon; - } else if (file.type.includes("xml")) { - clone.getElementById('file_type_icon').src = xmlIcon; + if (file.type.includes(FhirFormat.JSON.extension)) { + clone.getElementById(ID_FILE_ENTRY_ICON).src = jsonIcon; + } else if (file.type.includes(FhirFormat.XML.extension)) { + clone.getElementById(ID_FILE_ENTRY_ICON).src = xmlIcon; } + clone.getElementById(ID_FILE_ENTRY_COLLAPSE_SECTION).setAttribute("id", (ID_FILE_ENTRY_COLLAPSE_SECTION + index)); + clone.getElementById(ID_FILE_ENTRY_NAME).setAttribute("aria-controls", (ID_FILE_ENTRY_COLLAPSE_SECTION + index)); + clone.getElementById(ID_FILE_ENTRY_NAME).setAttribute("data-target", ('#' + ID_FILE_ENTRY_COLLAPSE_SECTION + index)); + // Add delete listener - clone.getElementById("delete_button").addEventListener("click", handleDeleteOnFileList); + clone.getElementById(ID_FILE_ENTRY_DELETE_BUTTON).addEventListener("click", handleDeleteOnFileList); return clone; } +function addIssueToFileEntryList(index, severity, details) { + var ul = document.getElementById(ID_FILE_ENTRY_FILE_LIST); + var listItems = ul.children; + var fileEntry = listItems[index]; + console.log(fileEntry); + var listOfIssues = fileEntry.querySelector('#' + ID_FILE_ENTRY_OUTCOME_LIST); + var issueItem = createIssueListItem(severity, details); + listOfIssues.appendChild(issueItem); +} + +function createIssueListItem(severity, details) { + var newIssue = document.createElement('li'); + switch(severity) { + case IssueSeverity.FATAL.code: + newIssue.setAttribute("class", CLASS_LIST_ITEM_FATAL); + break; + case IssueSeverity.ERROR.code: + newIssue.setAttribute("class", CLASS_LIST_ITEM_ERROR); + break; + case IssueSeverity.WARNING.code: + newIssue.setAttribute("class", CLASS_LIST_ITEM_WARNING); + break; + case IssueSeverity.INFORMATION.code: + newIssue.setAttribute("class", CLASS_LIST_ITEM_INFORMATION); + break; + default: + console.error('Passed in bad severity: ' + severity); + } + newIssue.innerHTML = details; + return newIssue; +} + function handleDeleteOnFileList(e) { var li = e.target.closest('li'); var nodes = Array.from( li.closest('ul').children ); @@ -88,10 +150,21 @@ function sendFilesToValidate(arrayOfFileInfo) { } function processValidationResponse(validationResponse) { - console.log(validationResponse.outcomes[0]); - console.log(validationResponse.outcomes[1]); - //console.log(validationResponse); - //Do something + console.log(validationResponse); + console.log(validationResponse.length); + console.log(validationResponse.outcomes); + console.log(validationResponse.outcomes.length); + + for (var i = 0; i < validationResponse.outcomes.length; i++) { + console.log(validationResponse.outcomes[i]); + var fileInfo = validationResponse.outcomes[i].fileInfo; + var issues = validationResponse.outcomes[i].issues; + issues.forEach(issue => { + console.log(issue); + addIssueToFileEntryList(i, issue.severity, issue.details); + }); + } + } diff --git a/org.hl7.fhir.validation/src/main/resources/public/test.html b/org.hl7.fhir.validation/src/main/resources/public/test.html index 3a993e4fb..7e4193ffd 100644 --- a/org.hl7.fhir.validation/src/main/resources/public/test.html +++ b/org.hl7.fhir.validation/src/main/resources/public/test.html @@ -50,22 +50,10 @@ -
      - -
    +
    +
      +
    +
    @@ -74,74 +62,34 @@
    + From 0b92c7efe545d9c07b55edd369394077240a4388 Mon Sep 17 00:00:00 2001 From: markiantorno Date: Fri, 17 Apr 2020 14:16:54 -0400 Subject: [PATCH 3/8] removed hardcoded path --- .../main/java/org/hl7/fhir/r4/test/utils/TestingUtilities.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/test/utils/TestingUtilities.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/test/utils/TestingUtilities.java index 62999b83d..30daa6ca6 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/test/utils/TestingUtilities.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/test/utils/TestingUtilities.java @@ -88,8 +88,6 @@ public class TestingUtilities { if (!Utilities.noString(s)) return s; s = "C:\\work\\org.hl7.fhir\\build"; - // FIXME: change this back - s = "/Users/jamesagnew/git/fhir"; if (new File(s).exists()) return s; throw new Error("FHIR Home directory not configured"); From 5c06cfcfb809ed5a2df2bcb3fbeae9663a9f3394 Mon Sep 17 00:00:00 2001 From: markiantorno Date: Fri, 17 Apr 2020 14:34:52 -0400 Subject: [PATCH 4/8] removed hardcoded path --- .../main/java/org/hl7/fhir/r4/test/utils/TestingUtilities.java | 1 - 1 file changed, 1 deletion(-) diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/test/utils/TestingUtilities.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/test/utils/TestingUtilities.java index 30daa6ca6..00bc0fb47 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/test/utils/TestingUtilities.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/test/utils/TestingUtilities.java @@ -92,7 +92,6 @@ public class TestingUtilities { return s; throw new Error("FHIR Home directory not configured"); } - public static String content() throws IOException { if (contentpath != null) From 9a9de764b4fdd8f3f641a78656cafb8b32351ef1 Mon Sep 17 00:00:00 2001 From: markiantorno Date: Fri, 17 Apr 2020 16:02:58 -0400 Subject: [PATCH 5/8] Boots on cli command now. --- org.hl7.fhir.validation/pom.xml | 19 +++ .../org/hl7/fhir/validation/Validator.java | 2 +- .../hl7/fhir/validation/cli/ValidatorGui.java | 23 ++- .../cli/controller/UIController.java | 2 +- .../fhir/validation/cli/controller/test.json | 29 ---- .../src/main/resources/public/index.html | 147 +++++++++++------- .../src/main/resources/public/test.html | 102 ------------ .../fhir/validation/cli/ValidatorGuiTest.java | 31 ++++ 8 files changed, 163 insertions(+), 192 deletions(-) delete mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/test.json delete mode 100644 org.hl7.fhir.validation/src/main/resources/public/test.html create mode 100644 org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/ValidatorGuiTest.java diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml index d7a2f88e3..98728ef76 100644 --- a/org.hl7.fhir.validation/pom.xml +++ b/org.hl7.fhir.validation/pom.xml @@ -164,7 +164,26 @@ thymeleaf 3.0.9.RELEASE + + org.junit.jupiter + junit-jupiter + RELEASE + test + + + + org.seleniumhq.selenium + selenium-chrome-driver + 3.141.59 + test + + + io.github.bonigarcia + webdrivermanager + 3.6.2 + test + diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java index 713271985..ba3b97b3d 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java @@ -136,7 +136,7 @@ public class Validator { String definitions = VersionUtilities.packageForVersion(v) + "#" + v; ValidationEngine validationEngine = Common.getValidationEngine(v, definitions, cliContext.getTxLog()); ValidatorGui.start(cliContext, validationEngine); - }else if (Params.hasParam(args, Params.TEST)) { + } else if (Params.hasParam(args, Params.TEST)) { Common.runValidationEngineTests(); } else if (args.length == 0 || Params.hasParam(args, Params.HELP) || Params.hasParam(args, "?") || Params.hasParam(args, "-?") || Params.hasParam(args, "/?")) { Display.displayHelpDetails(); diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java index bc287cad1..93a5f09e8 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java @@ -6,8 +6,15 @@ import org.hl7.fhir.validation.ValidationEngine; import org.hl7.fhir.validation.cli.model.CliContext; import org.hl7.fhir.validation.cli.utils.Common; +import java.awt.*; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + public class ValidatorGui { + private static final int GUI_FRONTEND_PORT = 8080; + private static final String PAGE_ADDRESS = "http://localhost:" + GUI_FRONTEND_PORT + "/home"; private static final String WEB_APP_FILE_LOCATION = "/public"; private static Javalin app; @@ -25,9 +32,21 @@ public class ValidatorGui { public static void start(CliContext currentContext, ValidationEngine validationEngine) { app = Javalin.create(); - new RestEndpoints().initRestEndpoints(app, new CliContext(), validationEngine); + new RestEndpoints().initRestEndpoints(app, currentContext, validationEngine); app.config.addStaticFiles(WEB_APP_FILE_LOCATION); - app.start(8080); + app.start(GUI_FRONTEND_PORT); + openBrowser(); + } + + public static void openBrowser() { + if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) { + try { + Desktop.getDesktop().browse(new URI(PAGE_ADDRESS)); + } catch (Exception e) { + System.out.println("Error opening web browser to validator GUI.\nYou can try to open the page manually at:: " + + PAGE_ADDRESS + "\nError:: " + e.getMessage()); + } + } } public static void stop() { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/UIController.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/UIController.java index 2c583a030..fcb978335 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/UIController.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/UIController.java @@ -7,7 +7,7 @@ public class UIController { public UIController() {} public Handler renderLandingPage = ctx -> { - ctx.render("/public/test.html"); + ctx.render("/public/index.html"); }; } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/test.json b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/test.json deleted file mode 100644 index 56d816c22..000000000 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/test.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "outcomes": [ - { - "fileInfo": { - "fileName": "account-example.canonical.json", - "fileContent": "{\"id\":\"example\",\"resourceType\":\"Account\",\"text\":{\"div\":\"
    [Put rendering here]
    \",\"status\":\"generated\"}}", - "fileType": "JSON" - }, - "issues": [ - { - "severity": "Error", - "details": "Wrong namespace on the XHTML (\"null\", should be \"http://www.w3.org/1999/xhtml\")" - }, - { - "severity": "Error", - "details": "Profile http://hl7.org/fhir/StructureDefinition/Account, Element 'Account.status': minimum required = 1, but only found 0" - } - ] - }, - { - "fileInfo": { - "fileName": "account-example(example).xml", - "fileContent": "\n\t\n\t\n \n \n \n \n \n \n \n\t\t\n\t\t
    HACC Funded Billing for Peter James Chalmers
    \n\t
    \n\t\n\t\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\t\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\n\t\n
    ", - "fileType": "XML" - }, - "issues": [] - } - ] -} \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/main/resources/public/index.html b/org.hl7.fhir.validation/src/main/resources/public/index.html index 94a6e5220..e698edd74 100644 --- a/org.hl7.fhir.validation/src/main/resources/public/index.html +++ b/org.hl7.fhir.validation/src/main/resources/public/index.html @@ -1,66 +1,99 @@ - - - - - - - JS For Beginners - + + + + + + + FHIR HL7 Resrouce Validator GUI - - - + + + + + + + + + + - -
    -

    Validator 2.0

    -
    -
    -
    -
    -
      -
    • - - -
    • -
    • - Filename Here - - - -
    • + +
      +
      + +
      +
      FHIR Core Validator
      + Experimental +
      +
      + +
      +
      +
      Files to Validate
      + +
      + +
      +
      -
      -
      - - -
        +
        + + + +
        - + +
        +
        - - + + + + + + diff --git a/org.hl7.fhir.validation/src/main/resources/public/test.html b/org.hl7.fhir.validation/src/main/resources/public/test.html deleted file mode 100644 index 7e4193ffd..000000000 --- a/org.hl7.fhir.validation/src/main/resources/public/test.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - FHIR HL7 Resrouce Validator GUI - - - - - - - - - - - - - -
        -
        - -
        -
        FHIR Core Validator
        - Experimental -
        -
        - -
        -
        -
        Files to Validate
        - -
        - -
        -
          -
        -
        - -
        - - - - -
        - - - -
        - - - - - - - - diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/ValidatorGuiTest.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/ValidatorGuiTest.java new file mode 100644 index 000000000..b9b5e3f4d --- /dev/null +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/ValidatorGuiTest.java @@ -0,0 +1,31 @@ +package org.hl7.fhir.validation.cli; + +import io.github.bonigarcia.wdm.WebDriverManager; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; + +import java.io.IOException; + +class ValidatorGuiTest { + + private final String HTML_TITLE_TAG = "FHIR HL7 Resrouce Validator GUI"; + + @Test + public void UI_contains_correct_heading() throws IOException { + ValidatorGui.start(new CliContext(), null); + WebDriverManager.chromedriver().setup(); + ChromeOptions options = new ChromeOptions(); + options.addArguments("--headless"); + options.addArguments("--disable-gpu"); + WebDriver driver = new ChromeDriver(options); + driver.get("http://localhost:8080/home"); + + Assertions.assertTrue(driver.getPageSource().contains(HTML_TITLE_TAG)); + driver.quit(); + ValidatorGui.stop(); + } +} \ No newline at end of file From 89250de244695c5d4b13c9c88659e718cf32775e Mon Sep 17 00:00:00 2001 From: markiantorno Date: Fri, 17 Apr 2020 20:17:12 -0400 Subject: [PATCH 6/8] Some cleanup and tests before first commit. --- org.hl7.fhir.validation/pom.xml | 1 - .../org/hl7/fhir/validation/Validator.java | 2 +- .../fhir/validation/cli/RestEndpoints.java | 5 +- .../hl7/fhir/validation/cli/ValidatorGui.java | 10 ++-- .../cli/controller/CliContextController.java | 19 ++++--- .../cli/controller/ValidationController.java | 21 ++++++++ .../fhir/validation/cli/model/CliContext.java | 54 ++++++++++++++++--- .../cli/services/ValidationService.java | 2 +- .../validation/cli/utils/SnomedVersion.java | 20 +++---- .../hl7/fhir/validation/cli/BaseRestTest.java | 36 +++++++++++++ .../fhir/validation/cli/ValidatorGuiTest.java | 4 +- .../cli/controller/HttpGetContextTest.java | 47 ++++++++++++++++ .../cli/controller/HttpPutContextTest.java | 24 +++++++++ .../org.mockito.plugins.MockMaker | 1 + 14 files changed, 212 insertions(+), 34 deletions(-) create mode 100644 org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/BaseRestTest.java create mode 100644 org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpGetContextTest.java create mode 100644 org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpPutContextTest.java create mode 100644 org.hl7.fhir.validation/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml index 98728ef76..ea27cfbdd 100644 --- a/org.hl7.fhir.validation/pom.xml +++ b/org.hl7.fhir.validation/pom.xml @@ -197,5 +197,4 @@ - diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java index ba3b97b3d..8abac8da5 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/Validator.java @@ -135,7 +135,7 @@ public class Validator { String v = Common.getVersion(args); String definitions = VersionUtilities.packageForVersion(v) + "#" + v; ValidationEngine validationEngine = Common.getValidationEngine(v, definitions, cliContext.getTxLog()); - ValidatorGui.start(cliContext, validationEngine); + ValidatorGui.start(cliContext, validationEngine, true); } else if (Params.hasParam(args, Params.TEST)) { Common.runValidationEngineTests(); } else if (args.length == 0 || Params.hasParam(args, Params.HELP) || Params.hasParam(args, "?") || Params.hasParam(args, "-?") || Params.hasParam(args, "/?")) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java index b3999fc0a..8b71d7c81 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java @@ -1,6 +1,5 @@ package org.hl7.fhir.validation.cli; -import com.fasterxml.jackson.databind.ObjectMapper; import io.javalin.Javalin; import org.hl7.fhir.validation.ValidationEngine; import org.hl7.fhir.validation.cli.controller.CliContextController; @@ -22,8 +21,8 @@ public class RestEndpoints { app.get("/home", myUIController.renderLandingPage); - app.get("/context", myCliContextController.getCurrentCliContext); - app.post("/context", myCliContextController.setCurrentCliContext); + app.get("/context", myCliContextController::handleGetCurrentCliContext); + app.post("/context", myCliContextController::handleSetCurrentCliContext); app.post("/validate", myValidationController.handleValidationRequest); } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java index 93a5f09e8..3030d0e2e 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/ValidatorGui.java @@ -18,6 +18,8 @@ public class ValidatorGui { private static final String WEB_APP_FILE_LOCATION = "/public"; private static Javalin app; + private ValidatorGui(){} + /** * N.B. this entry point, is only for testing. Please start from command line using the argument {@code -gui} for * actual use. @@ -27,15 +29,17 @@ public class ValidatorGui { String v = Common.getVersion(args); String definitions = VersionUtilities.packageForVersion(v) + "#" + v; ValidationEngine validationEngine = Common.getValidationEngine(v, definitions, cliContext.getTxLog()); - start(new CliContext(), validationEngine); + start(new CliContext(), validationEngine, false); } - public static void start(CliContext currentContext, ValidationEngine validationEngine) { + public static void start(CliContext currentContext, ValidationEngine validationEngine, boolean bootBrowser) { app = Javalin.create(); new RestEndpoints().initRestEndpoints(app, currentContext, validationEngine); app.config.addStaticFiles(WEB_APP_FILE_LOCATION); app.start(GUI_FRONTEND_PORT); - openBrowser(); + if (bootBrowser) { + openBrowser(); + } } public static void openBrowser() { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/CliContextController.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/CliContextController.java index 1835a9f6b..afd3e4478 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/CliContextController.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/CliContextController.java @@ -1,27 +1,30 @@ package org.hl7.fhir.validation.cli.controller; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import io.javalin.http.Handler; +import io.javalin.http.Context; import org.apache.http.HttpStatus; import org.hl7.fhir.validation.cli.model.CliContext; +import org.jetbrains.annotations.NotNull; public class CliContextController { + private final String JSON_MIME_TYPE = "application/json"; + private CliContext myCliContext; public CliContextController(CliContext cliContext) { this.myCliContext = cliContext; } - public Handler getCurrentCliContext = ctx -> { + public void handleGetCurrentCliContext(@NotNull Context ctx) throws JsonProcessingException { ObjectMapper Obj = new ObjectMapper(); String jsonStr = Obj.writeValueAsString(myCliContext); - ctx.result(jsonStr); - }; + ctx.result(jsonStr).contentType(JSON_MIME_TYPE).status(HttpStatus.SC_OK); + } - public Handler setCurrentCliContext = ctx -> { + public void handleSetCurrentCliContext(@NotNull Context ctx) { myCliContext = ctx.bodyAsClass(CliContext.class); - ctx.status(HttpStatus.SC_CREATED); - }; - + ctx.status(HttpStatus.SC_OK); + } } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java index c290415a2..12cb2d4e1 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java @@ -1,7 +1,9 @@ package org.hl7.fhir.validation.cli.controller; import com.fasterxml.jackson.databind.ObjectMapper; +import io.javalin.http.Context; import io.javalin.http.Handler; +import org.apache.http.HttpStatus; import org.hl7.fhir.validation.ValidationEngine; import org.hl7.fhir.validation.cli.model.ValidationRequest; import org.hl7.fhir.validation.cli.model.ValidationResponse; @@ -15,6 +17,25 @@ public class ValidationController { this.myValidationEngine = validationEngine; } + public void handleValidationRequest(Context ctx) { + ValidationRequest request = ctx.bodyAsClass(ValidationRequest.class); + ValidationResponse response = null; + try { + response = ValidationService.validateSources(request, myValidationEngine); + ObjectMapper Obj = new ObjectMapper(); + /* + * TODO + * Write file contents to temp files to pass to validator instead of creating our own endpoint. + * Create File => new temp file + * Use Option => DeleteOnShutdown + */ + String jsonStr = Obj.writeValueAsString(response); + ctx.status(200).json(jsonStr); + } catch (Exception e) { + ctx.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).result(e.getLocalizedMessage()); + } + } + public Handler handleValidationRequest = ctx -> { ValidationRequest request = ctx.bodyAsClass(ValidationRequest.class); ValidationResponse response = ValidationService.validateSources(request, myValidationEngine); diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java index 81335261c..1e910eae7 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java @@ -60,7 +60,7 @@ public class CliContext { private Validator.EngineMode mode = Validator.EngineMode.VALIDATION; @JsonProperty("locale") - private Locale locale = null; + private String locale = Locale.ENGLISH.getDisplayLanguage(); @JsonProperty("locations") private Map locations = new HashMap(); @@ -172,21 +172,21 @@ public class CliContext { @JsonProperty("locale") public String getLanguageCode() { - return this.locale.getDisplayLanguage(); + return locale; } public Locale getLocale() { - return locale; + return Locale.forLanguageTag(this.locale); } @JsonProperty("locale") public CliContext setLocale(String languageString) { - this.locale = new Locale(languageString); + this.locale = languageString; return this; } public CliContext setLocale(Locale locale) { - this.locale = locale; + this.locale = locale.getDisplayLanguage(); return this; } @@ -332,14 +332,18 @@ public class CliContext { return this; } + public SnomedVersion getSnomedCT() { + return SnomedVersion.getFromCode(snomedCT); + } + @JsonProperty("snomedCT") - public String getSnomedCT() { + public String getSnomedCTCode() { return snomedCT; } @JsonProperty("snomedCT") public CliContext setSnomedCT(String snomedCT) { - this.snomedCT = SnomedVersion.resolveSnomedCTCode(snomedCT); + this.snomedCT = snomedCT; return this; } @@ -405,4 +409,40 @@ public class CliContext { ", assumeValidRestReferences=" + assumeValidRestReferences + '}'; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CliContext that = (CliContext) o; + return doNative == that.doNative && + anyExtensionsAllowed == that.anyExtensionsAllowed && + hintAboutNonMustSupport == that.hintAboutNonMustSupport && + recursive == that.recursive && + doDebug == that.doDebug && + assumeValidRestReferences == that.assumeValidRestReferences && + canDoNative == that.canDoNative && + Objects.equals(map, that.map) && + Objects.equals(output, that.output) && + Objects.equals(txServer, that.txServer) && + Objects.equals(sv, that.sv) && + Objects.equals(txLog, that.txLog) && + Objects.equals(mapLog, that.mapLog) && + Objects.equals(lang, that.lang) && + Objects.equals(fhirpath, that.fhirpath) && + Objects.equals(snomedCT, that.snomedCT) && + Objects.equals(targetVer, that.targetVer) && + Objects.equals(igs, that.igs) && + Objects.equals(questionnaires, that.questionnaires) && + Objects.equals(profiles, that.profiles) && + Objects.equals(sources, that.sources) && + mode == that.mode && + Objects.equals(locale, that.locale) && + Objects.equals(locations, that.locations); + } + + @Override + public int hashCode() { + return Objects.hash(doNative, anyExtensionsAllowed, hintAboutNonMustSupport, recursive, doDebug, assumeValidRestReferences, canDoNative, map, output, txServer, sv, txLog, mapLog, lang, fhirpath, snomedCT, targetVer, igs, questionnaires, profiles, sources, mode, locale, locations); + } } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java index 67ab7dbf0..953a524be 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java @@ -178,7 +178,7 @@ public class ValidationService { validator.setAnyExtensionsAllowed(cliContext.isAnyExtensionsAllowed()); validator.setLanguage(cliContext.getLang()); validator.setLocale(cliContext.getLocale()); - validator.setSnomedExtension(cliContext.getSnomedCT()); + validator.setSnomedExtension(cliContext.getSnomedCTCode()); validator.setAssumeValidRestReferences(cliContext.isAssumeValidRestReferences()); return validator; } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/SnomedVersion.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/SnomedVersion.java index 11cae4b20..3be055e5f 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/SnomedVersion.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/SnomedVersion.java @@ -1,6 +1,8 @@ package org.hl7.fhir.validation.cli.utils; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; public enum SnomedVersion { @@ -32,15 +34,15 @@ public enum SnomedVersion { return code; } - public static String resolveSnomedCTCode(String s) { - String foundCode; - Optional opt = Arrays.stream(values()) - .filter(v -> v.lang.equals(s)) - .findFirst(); - if (opt.isPresent()) { - return opt.get().code; - } else { - throw new Error("Snomed edition '" + s + "' not known"); + public static SnomedVersion getFromCode(String code) { + return lookup.get(code); + } + + private static final Map lookup = new HashMap<>(); + + static { + for (SnomedVersion s : SnomedVersion.values()) { + lookup.put(s.getCode(), s); } } } diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/BaseRestTest.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/BaseRestTest.java new file mode 100644 index 000000000..cd3a88874 --- /dev/null +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/BaseRestTest.java @@ -0,0 +1,36 @@ +package org.hl7.fhir.validation.cli; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.http.HttpResponse; +import org.apache.http.util.EntityUtils; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; + +import java.io.IOException; + +public abstract class BaseRestTest { + + protected final String JSON_MIME_TYPE = "application/json"; + + @BeforeAll + public static void startServer() { + ValidatorGui.start(new CliContext(), null, false); + } + + @AfterAll + public static void stopServer() { + ValidatorGui.stop(); + } + + public static T retrieveResourceFromResponse(HttpResponse response, Class clazz) + throws IOException { + + String jsonFromResponse = EntityUtils.toString(response.getEntity()); + ObjectMapper mapper = new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + return mapper.readValue(jsonFromResponse, clazz); + } + +} diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/ValidatorGuiTest.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/ValidatorGuiTest.java index b9b5e3f4d..b8e88e779 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/ValidatorGuiTest.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/ValidatorGuiTest.java @@ -3,6 +3,7 @@ package org.hl7.fhir.validation.cli; import io.github.bonigarcia.wdm.WebDriverManager; import org.hl7.fhir.validation.cli.model.CliContext; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; @@ -15,8 +16,9 @@ class ValidatorGuiTest { private final String HTML_TITLE_TAG = "FHIR HL7 Resrouce Validator GUI"; @Test + @DisplayName("Page boots correctly, and displays index.html") public void UI_contains_correct_heading() throws IOException { - ValidatorGui.start(new CliContext(), null); + ValidatorGui.start(new CliContext(), null, false); WebDriverManager.chromedriver().setup(); ChromeOptions options = new ChromeOptions(); options.addArguments("--headless"); diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpGetContextTest.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpGetContextTest.java new file mode 100644 index 000000000..ac10cd47a --- /dev/null +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpGetContextTest.java @@ -0,0 +1,47 @@ +package org.hl7.fhir.validation.cli.controller; + +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.entity.ContentType; +import org.apache.http.impl.client.HttpClientBuilder; +import org.hl7.fhir.validation.cli.BaseRestTest; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +class HttpGetContextTest extends BaseRestTest { + + private final String GET_CONTEXT_URL = "http://localhost:8080/context"; + + @Test + @DisplayName("Testing status code on get context endpoint.") + public void testStatus() throws IOException { + HttpUriRequest request = new HttpGet(GET_CONTEXT_URL); + HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request); + Assertions.assertEquals(httpResponse.getStatusLine().getStatusCode(), HttpStatus.SC_OK); + } + + @Test + @DisplayName("Testing media type on get context endpoint.") + public void testMediaType() throws IOException { + HttpUriRequest request = new HttpGet(GET_CONTEXT_URL); + HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request); + String mimeType = ContentType.getOrDefault(httpResponse.getEntity()).getMimeType(); + Assertions.assertEquals(JSON_MIME_TYPE, mimeType ); + } + + @Test + @DisplayName("Testing status code on get context endpoint.") + public void testJSONPayload() throws IOException { + HttpUriRequest request = new HttpGet(GET_CONTEXT_URL); + HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request); + CliContext resource = retrieveResourceFromResponse(httpResponse, CliContext.class); + Assertions.assertEquals(new CliContext(), resource); + } + +} \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpPutContextTest.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpPutContextTest.java new file mode 100644 index 000000000..5c967191e --- /dev/null +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/controller/HttpPutContextTest.java @@ -0,0 +1,24 @@ +package org.hl7.fhir.validation.cli.controller; + +import io.javalin.http.Context; + +import org.junit.jupiter.api.Test; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +class HttpPutContextTest { + + public CliContextController myCliContextController; + + public HttpPutContextTest() { + this.myCliContextController = new CliContextController(null); + } + + @Test + void handleSetCurrentCliContext() { + Context context = mock(Context.class); + this.myCliContextController.handleSetCurrentCliContext(context); + verify(context).status(200); + } +} \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/org.hl7.fhir.validation/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 000000000..ca6ee9cea --- /dev/null +++ b/org.hl7.fhir.validation/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file From 0db6635a753a05263c8002443f8d8a83b46952a9 Mon Sep 17 00:00:00 2001 From: markiantorno Date: Fri, 17 Apr 2020 20:18:42 -0400 Subject: [PATCH 7/8] deleting unused file --- .../src/main/resources/public/assets/bootstrap-outline.svg | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 org.hl7.fhir.validation/src/main/resources/public/assets/bootstrap-outline.svg diff --git a/org.hl7.fhir.validation/src/main/resources/public/assets/bootstrap-outline.svg b/org.hl7.fhir.validation/src/main/resources/public/assets/bootstrap-outline.svg deleted file mode 100644 index ed1825e3e..000000000 --- a/org.hl7.fhir.validation/src/main/resources/public/assets/bootstrap-outline.svg +++ /dev/null @@ -1,5 +0,0 @@ - - Bootstrap - - - From 46922bac09cc279e99c3a6d0a731f3214a1fdd02 Mon Sep 17 00:00:00 2001 From: markiantorno Date: Fri, 17 Apr 2020 20:49:27 -0400 Subject: [PATCH 8/8] forgot to remove the method --- .../org/hl7/fhir/validation/cli/RestEndpoints.java | 2 +- .../cli/controller/ValidationController.java | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java index 8b71d7c81..055515301 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/RestEndpoints.java @@ -24,6 +24,6 @@ public class RestEndpoints { app.get("/context", myCliContextController::handleGetCurrentCliContext); app.post("/context", myCliContextController::handleSetCurrentCliContext); - app.post("/validate", myValidationController.handleValidationRequest); + app.post("/validate", myValidationController::handleValidationRequest); } } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java index 12cb2d4e1..48af31ccd 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/controller/ValidationController.java @@ -35,18 +35,4 @@ public class ValidationController { ctx.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).result(e.getLocalizedMessage()); } } - - public Handler handleValidationRequest = ctx -> { - ValidationRequest request = ctx.bodyAsClass(ValidationRequest.class); - ValidationResponse response = ValidationService.validateSources(request, myValidationEngine); - -// File new temp file -// DeleteOnShutdown - - ObjectMapper Obj = new ObjectMapper(); - String jsonStr = Obj.writeValueAsString(response); - - ctx.status(200).json(jsonStr); - }; - }