Validator 2 (#366)

* changes to accomodate front end gui for validator wrapper

* removing debug code
This commit is contained in:
Mark Iantorno 2020-10-19 16:39:22 -04:00 committed by GitHub
parent eb1c67c1cb
commit e1ecd06282
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 202 additions and 1131 deletions

View File

@ -1,33 +1,33 @@
package org.hl7.fhir.utilities.validation;
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
@ -581,20 +581,6 @@ public class ValidationMessage implements Comparator<ValidationMessage>, Compara
throw new Error("A type must be provided");
}
// public ValidationMessage(Source source, IssueType type, String message, IssueSeverity level) {
// super();
// this.line = -1;
// this.col = -1;
// if (message == null)
// throw new Error("message is null");
// this.message = message;
// this.level = level;
// this.source = source;
// this.type = type;
// if (type == null)
// throw new Error("A type must be provided");
// }
private IssueSeverity determineLevel(String path) {
if (isGrandfathered(path))
return IssueSeverity.WARNING;

View File

@ -88,7 +88,7 @@
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>org.hl7.fhir.validation.Validator</mainClass>
<mainClass>org.hl7.fhir.validation.ValidatorCli</mainClass>
</manifest>
</archive>
</configuration>

View File

@ -109,10 +109,7 @@ import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
import org.hl7.fhir.validation.BaseValidator.ValidationControl;
import org.hl7.fhir.validation.cli.model.ScanOutputItem;
import org.hl7.fhir.validation.cli.services.StandAloneValidatorFetcher.IPackageInstaller;
import org.hl7.fhir.validation.cli.utils.AsteriskFilter;
import org.hl7.fhir.validation.cli.utils.Common;
import org.hl7.fhir.validation.cli.utils.QuestionnaireMode;
import org.hl7.fhir.validation.cli.utils.VersionSourceInformation;
import org.hl7.fhir.validation.cli.utils.*;
import org.hl7.fhir.validation.instance.InstanceValidator;
import org.xml.sax.SAXException;
@ -402,35 +399,6 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
return ep;
}
private byte[] loadProfileSource(String src) throws FHIRException, FileNotFoundException, IOException {
if (Utilities.noString(src)) {
throw new FHIRException("Profile Source '" + src + "' could not be processed");
} else if (Common.isNetworkPath(src)) {
return loadProfileFromUrl(src);
} else if (new File(src).exists()) {
return loadProfileFromFile(src);
} else {
throw new FHIRException("Definitions Source '"+src+"' could not be processed");
}
}
private byte[] loadProfileFromUrl(String src) throws FHIRException {
try {
URL url = new URL(src+"?nocache=" + System.currentTimeMillis());
URLConnection c = url.openConnection();
return IOUtils.toByteArray(c.getInputStream());
} catch (Exception e) {
throw new FHIRException("Unable to find definitions at URL '"+src+"': "+e.getMessage(), e);
}
}
private byte[] loadProfileFromFile(String src) throws FileNotFoundException, IOException {
File f = new File(src);
if (f.isDirectory())
throw new IOException("You must provide a file name, not a directory name");
return TextFile.fileToBytes(src);
}
/** explore should be true if we're trying to load an -ig parameter, and false if we're loading source
* @throws IOException **/
@ -907,7 +875,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
if (context.hasResource(ImplementationGuide.class, src))
return;
byte[] source = loadProfileSource(src);
byte[] source = ProfileLoader.loadProfileSource(src);
FhirFormat fmt = FormatUtilities.determineFormat(source);
Resource r = FormatUtilities.makeParser(fmt).parse(source);
context.cacheResource(r);
@ -1196,10 +1164,6 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
return res;
}
private Resource resolve(Reference reference) {
return null;
}
private String getGlobal(ImplementationGuide ig, String rt) {
for (ImplementationGuideGlobalComponent igg : ig.getGlobal()) {
if (rt.equals(igg.getType()))
@ -1316,15 +1280,11 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
return messagesToOutcome(messages);
}
public OperationOutcome validate(String location, byte[] source, FhirFormat cntType, List<String> profiles) throws FHIRException, IOException, EOperationOutcome, SAXException {
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
if (doNative) {
if (cntType == FhirFormat.JSON)
validateJsonSchema(location, messages);
if (cntType == FhirFormat.XML)
validateXmlSchema(location, messages);
if (cntType == FhirFormat.TURTLE)
validateSHEX(location, messages);
SchemaValidator.validateSchema(location, cntType, messages);
}
InstanceValidator validator = getValidator();
validator.validate(null, messages, new ByteArrayInputStream(source), cntType, asSdList(profiles));
@ -1337,12 +1297,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
public OperationOutcome validate(String location, byte[] source, FhirFormat cntType, List<String> profiles, IdStatus resourceIdRule, boolean anyExtensionsAllowed, BestPracticeWarningLevel bpWarnings, CheckDisplayOption displayOption) throws FHIRException, IOException, EOperationOutcome, SAXException {
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
if (doNative) {
if (cntType == FhirFormat.JSON)
validateJsonSchema(location, messages);
if (cntType == FhirFormat.XML)
validateXmlSchema(location, messages);
if (cntType == FhirFormat.TURTLE)
validateSHEX(location, messages);
SchemaValidator.validateSchema(location, cntType, messages);
}
InstanceValidator validator = getValidator();
validator.setResourceIdRule(resourceIdRule);
@ -1352,19 +1307,6 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
return messagesToOutcome(messages);
}
private void validateSHEX(String location, List<ValidationMessage> messages) {
messages.add(new ValidationMessage(Source.InstanceValidator, IssueType.INFORMATIONAL, location, "SHEX Validation is not done yet", IssueSeverity.INFORMATION));
}
private void validateXmlSchema(String location, List<ValidationMessage> messages) throws FileNotFoundException, IOException, SAXException {
messages.add(new ValidationMessage(Source.InstanceValidator, IssueType.INFORMATIONAL, location, "XML Schema Validation is not done yet", IssueSeverity.INFORMATION));
}
private void validateJsonSchema(String location, List<ValidationMessage> messages) {
messages.add(new ValidationMessage(Source.InstanceValidator, IssueType.INFORMATIONAL, location, "JSON Schema Validation is not done yet", IssueSeverity.INFORMATION));
}
private List<ValidationMessage> filterMessages(List<ValidationMessage> messages) {
List<ValidationMessage> filteredValidation = new ArrayList<ValidationMessage>();
for (ValidationMessage e : messages) {

View File

@ -82,7 +82,7 @@ import java.io.File;
*
* @author Grahame
*/
public class Validator {
public class ValidatorCli {
public static final String HTTP_PROXY_HOST = "http.proxyHost";
public static final String HTTP_PROXY_PORT = "http.proxyPort";
@ -140,7 +140,7 @@ public class Validator {
private static void doLeftRightComparison(String[] args, CliContext cliContext, TimeTracker tt) throws Exception {
Display.printCliArgumentsAndInfo(args);
if (cliContext.getSv() == null) {
cliContext.setSv(determineVersion(cliContext));
cliContext.setSv(ValidationService.determineVersion(cliContext));
}
String v = VersionUtilities.getCurrentVersion(cliContext.getSv());
String definitions = VersionUtilities.packageForVersion(v) + "#" + v;
@ -150,7 +150,7 @@ public class Validator {
private static void doValidation(TimeTracker tt, TimeTracker.Session tts, CliContext cliContext) throws Exception {
if (cliContext.getSv() == null) {
cliContext.setSv(determineVersion(cliContext));
cliContext.setSv(ValidationService.determineVersion(cliContext));
}
System.out.println("Loading");
// Comment this out because definitions filename doesn't necessarily contain version (and many not even be 14 characters long).
@ -196,25 +196,4 @@ public class Validator {
}
System.out.println("Done. " + tt.report());
}
public static String determineVersion(CliContext cliContext) throws Exception {
if (cliContext.getMode() != EngineMode.VALIDATION) {
return "current";
}
System.out.println("Scanning for versions (no -version parameter):");
VersionSourceInformation versions = ValidationService.scanForVersions(cliContext);
for (String s : versions.getReport()) {
System.out.println(" " + s);
}
if (versions.isEmpty()) {
System.out.println("-> Using Default version '" + VersionUtilities.CURRENT_VERSION + "'");
return "current";
}
if (versions.size() == 1) {
System.out.println("-> use version " + versions.version());
return versions.version();
}
throw new Exception("-> Multiple versions found. Specify a particular version using the -version parameter");
}
}

View File

@ -1,30 +0,0 @@
package org.hl7.fhir.validation.cli;
import org.hl7.fhir.validation.ValidationEngine;
import org.hl7.fhir.validation.cli.controller.CliContextController;
import org.hl7.fhir.validation.cli.controller.UIController;
import org.hl7.fhir.validation.cli.controller.ValidationController;
import org.hl7.fhir.validation.cli.model.CliContext;
import io.javalin.Javalin;
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::handleGetCurrentCliContext);
app.post("/context", myCliContextController::handleSetCurrentCliContext);
app.post("/validate", myValidationController::handleValidationRequest);
}
}

View File

@ -1,63 +0,0 @@
package org.hl7.fhir.validation.cli;
import java.awt.Desktop;
import java.net.URI;
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;
import io.javalin.Javalin;
public class ValidatorGui {
private static final int GUI_FRONTEND_PORT = 8081;
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;
private ValidatorGui(){}
/**
* 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(), null);
start(new CliContext(), validationEngine, false);
}
public static int getPort() {
return GUI_FRONTEND_PORT;
}
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);
if (bootBrowser) {
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() {
app.stop();
}
}

View File

@ -1,32 +0,0 @@
package org.hl7.fhir.validation.cli.controller;
import org.apache.http.HttpStatus;
import org.hl7.fhir.validation.cli.model.CliContext;
import org.jetbrains.annotations.NotNull;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.javalin.http.Context;
public class CliContextController {
private final String JSON_MIME_TYPE = "application/json";
private CliContext myCliContext;
public CliContextController(CliContext cliContext) {
this.myCliContext = cliContext;
}
public void handleGetCurrentCliContext(@NotNull Context ctx) throws JsonProcessingException {
ObjectMapper Obj = new ObjectMapper();
String jsonStr = Obj.writeValueAsString(myCliContext);
ctx.result(jsonStr).contentType(JSON_MIME_TYPE).status(HttpStatus.SC_OK);
}
public void handleSetCurrentCliContext(@NotNull Context ctx) {
myCliContext = ctx.bodyAsClass(CliContext.class);
ctx.status(HttpStatus.SC_OK);
}
}

View File

@ -1,13 +0,0 @@
package org.hl7.fhir.validation.cli.controller;
import io.javalin.http.Handler;
public class UIController {
public UIController() {}
public Handler renderLandingPage = ctx -> {
ctx.render("/public/index.html");
};
}

View File

@ -1,39 +0,0 @@
package org.hl7.fhir.validation.cli.controller;
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;
import org.hl7.fhir.validation.cli.services.ValidationService;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.javalin.http.Context;
public class ValidationController {
private ValidationEngine myValidationEngine;
public ValidationController(ValidationEngine validationEngine) {
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());
}
}
}

View File

@ -21,8 +21,8 @@ import org.hl7.fhir.utilities.npm.NpmPackage;
public class StandAloneValidatorFetcher implements IValidatorResourceFetcher {
public interface IPackageInstaller {
public boolean packageExists(String id, String ver) throws IOException, FHIRException;
public void loadPackage(String id, String ver) throws IOException, FHIRException;
boolean packageExists(String id, String ver) throws IOException, FHIRException;
void loadPackage(String id, String ver) throws IOException, FHIRException;
}
private BasePackageCacheManager pcm;

View File

@ -24,22 +24,22 @@ import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.TimeTracker;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.validation.ValidationEngine;
import org.hl7.fhir.validation.cli.model.*;
import org.hl7.fhir.validation.cli.utils.EngineMode;
import org.hl7.fhir.validation.cli.utils.VersionSourceInformation;
public class ValidationService {
/*
* TEMPORARY METHOD
*/
public static void validateFileInfo(FileInfo f) {
System.out.println("success");
}
public static ValidationResponse validateSources(ValidationRequest request) throws Exception {
if (request.getCliContext().getSv() == null) {
request.getCliContext().setSv(ValidationService.determineVersion(request.getCliContext()));
}
String definitions = VersionUtilities.packageForVersion(request.getCliContext().getSv()) + "#" + VersionUtilities.getCurrentVersion(request.getCliContext().getSv());
ValidationEngine validator = ValidationService.getValidator(request.getCliContext(), definitions, new TimeTracker());
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 {
@ -280,4 +280,24 @@ public class ValidationService {
}
return " " + issue.getSeverity().getDisplay() + " @ " + loc + " : " + issue.getDetails().getText();
}
public static String determineVersion(CliContext cliContext) throws Exception {
if (cliContext.getMode() != EngineMode.VALIDATION) {
return "current";
}
System.out.println("Scanning for versions (no -version parameter):");
VersionSourceInformation versions = ValidationService.scanForVersions(cliContext);
for (String s : versions.getReport()) {
System.out.println(" " + s);
}
if (versions.isEmpty()) {
System.out.println("-> Using Default version '" + VersionUtilities.CURRENT_VERSION + "'");
return "current";
}
if (versions.size() == 1) {
System.out.println("-> use version " + versions.version());
return versions.version();
}
throw new Exception("-> Multiple versions found. Specify a particular version using the -version parameter");
}
}

View File

@ -17,7 +17,7 @@ public class AsteriskFilter implements FilenameFilter {
for (int i = 0; i < expression.length(); i++) {
if (Character.isAlphabetic(expression.codePointAt(i)) || Character.isDigit(expression.codePointAt(i)))
regex = regex + expression.charAt(i);
else if (expression.charAt(i)=='*')
else if (expression.charAt(i) == '*')
regex = regex + ".*";
else
regex = regex + "\\" + expression.charAt(i);

View File

@ -89,7 +89,7 @@ public class Common {
System.out.println("Loading (v = " + version + ", tx server -> " + txServer + ")");
ValidationEngine ve = new ValidationEngine(definitions, FhirPublication.fromCode(version), version, tt);
ve.connectToTSServer(txServer, txLog, FhirPublication.fromCode(version));
return ve;
return ve;
}
public static boolean isNetworkPath(String path) {

View File

@ -1,19 +1,15 @@
package org.hl7.fhir.validation.cli.utils;
import org.apache.commons.io.FileUtils;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.npm.ToolsVersion;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.r5.model.Constants;
import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.npm.ToolsVersion;
import org.hl7.fhir.validation.VersionUtil;
/**
* Class for displaying output to the cli user.
*
* <p>
* TODO - Clean this up for localization
*/
public class Display {

View File

@ -1,4 +1,12 @@
package org.hl7.fhir.validation.cli.utils;
public enum EngineMode {
VALIDATION, TRANSFORM, NARRATIVE, SNAPSHOT, SCAN, CONVERT, FHIRPATH, VERSION
VALIDATION,
TRANSFORM,
NARRATIVE,
SNAPSHOT,
SCAN,
CONVERT,
FHIRPATH,
VERSION
}

View File

@ -1,13 +1,13 @@
package org.hl7.fhir.validation.cli.utils;
import java.io.File;
import java.util.Arrays;
import java.util.Locale;
import org.hl7.fhir.r5.utils.IResourceValidator.BundleValidationRule;
import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.validation.cli.model.CliContext;
import java.io.File;
import java.util.Arrays;
import java.util.Locale;
public class Params {
public static final String VERSION = "-version";

View File

@ -0,0 +1,43 @@
package org.hl7.fhir.validation.cli.utils;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
public class ProfileLoader {
public static byte[] loadProfileSource(String src) throws FHIRException, IOException {
if (Utilities.noString(src)) {
throw new FHIRException("Profile Source '" + src + "' could not be processed");
} else if (Common.isNetworkPath(src)) {
return loadProfileFromUrl(src);
} else if (new File(src).exists()) {
return loadProfileFromFile(src);
} else {
throw new FHIRException("Definitions Source '" + src + "' could not be processed");
}
}
private static byte[] loadProfileFromUrl(String src) throws FHIRException {
try {
URL url = new URL(src + "?nocache=" + System.currentTimeMillis());
URLConnection c = url.openConnection();
return IOUtils.toByteArray(c.getInputStream());
} catch (Exception e) {
throw new FHIRException("Unable to find definitions at URL '" + src + "': " + e.getMessage(), e);
}
}
private static byte[] loadProfileFromFile(String src) throws IOException {
File f = new File(src);
if (f.isDirectory())
throw new IOException("You must provide a file name, not a directory name");
return TextFile.fileToBytes(src);
}
}

View File

@ -1,3 +1,7 @@
package org.hl7.fhir.validation.cli.utils;
public enum QuestionnaireMode { NONE, CHECK, REQUIRED }
public enum QuestionnaireMode {
NONE,
CHECK,
REQUIRED
}

View File

@ -0,0 +1,33 @@
package org.hl7.fhir.validation.cli.utils;
import org.hl7.fhir.r5.elementmodel.Manager;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.xml.sax.SAXException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
public class SchemaValidator {
public static void validateSchema(String location, Manager.FhirFormat cntType, List<ValidationMessage> messages) throws IOException, SAXException {
if (cntType == Manager.FhirFormat.JSON)
validateJsonSchema(location, messages);
if (cntType == Manager.FhirFormat.XML)
validateXmlSchema(location, messages);
if (cntType == Manager.FhirFormat.TURTLE)
validateSHEX(location, messages);
}
private static void validateSHEX(String location, List<ValidationMessage> messages) {
messages.add(new ValidationMessage(ValidationMessage.Source.InstanceValidator, ValidationMessage.IssueType.INFORMATIONAL, location, "SHEX Validation is not done yet", ValidationMessage.IssueSeverity.INFORMATION));
}
private static void validateXmlSchema(String location, List<ValidationMessage> messages) throws FileNotFoundException, IOException, SAXException {
messages.add(new ValidationMessage(ValidationMessage.Source.InstanceValidator, ValidationMessage.IssueType.INFORMATIONAL, location, "XML Schema Validation is not done yet", ValidationMessage.IssueSeverity.INFORMATION));
}
private static void validateJsonSchema(String location, List<ValidationMessage> messages) {
messages.add(new ValidationMessage(ValidationMessage.Source.InstanceValidator, ValidationMessage.IssueType.INFORMATIONAL, location, "JSON Schema Validation is not done yet", ValidationMessage.IssueSeverity.INFORMATION));
}
}

View File

@ -13,7 +13,7 @@ public class VersionSourceInformation {
public void see(String version, String src) {
version = VersionUtilities.getMajMin(version);
report.add(src+": "+version);
report.add(src + ": " + version);
if (!versions.contains(version)) {
versions.add(version);
Collections.sort(versions);

View File

@ -1,36 +1,36 @@
package org.hl7.fhir.validation;
package org.hl7.fhir.validation.cli.utils;
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
import static org.apache.commons.lang3.StringUtils.left;
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.InputStream;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,72 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 58 58" style="enable-background:new 0 0 58 58;" xml:space="preserve">
<g>
<path d="M33.655,45.988c-0.232-0.31-0.497-0.533-0.793-0.67s-0.608-0.205-0.937-0.205c-0.337,0-0.658,0.063-0.964,0.191
s-0.579,0.344-0.82,0.649s-0.431,0.699-0.567,1.183c-0.137,0.483-0.21,1.075-0.219,1.777c0.009,0.684,0.08,1.267,0.212,1.75
s0.314,0.877,0.547,1.183s0.497,0.528,0.793,0.67s0.608,0.212,0.937,0.212c0.337,0,0.658-0.066,0.964-0.198s0.579-0.349,0.82-0.649
s0.431-0.695,0.567-1.183s0.21-1.082,0.219-1.784c-0.009-0.684-0.08-1.265-0.212-1.743S33.888,46.298,33.655,45.988z"/>
<path d="M51.5,39V13.978c0-0.766-0.092-1.333-0.55-1.792L39.313,0.55C38.964,0.201,38.48,0,37.985,0H8.963
C7.777,0,6.5,0.916,6.5,2.926V39H51.5z M29.5,33c0,0.552-0.447,1-1,1s-1-0.448-1-1v-3c0-0.552,0.447-1,1-1s1,0.448,1,1V33z
M37.5,3.391c0-0.458,0.553-0.687,0.877-0.363l10.095,10.095C48.796,13.447,48.567,14,48.109,14H37.5V3.391z M36.5,24v-4
c0-0.551-0.448-1-1-1c-0.553,0-1-0.448-1-1s0.447-1,1-1c1.654,0,3,1.346,3,3v4c0,1.103,0.897,2,2,2c0.553,0,1,0.448,1,1
s-0.447,1-1,1c-1.103,0-2,0.897-2,2v4c0,1.654-1.346,3-3,3c-0.553,0-1-0.448-1-1s0.447-1,1-1c0.552,0,1-0.449,1-1v-4
c0-1.2,0.542-2.266,1.382-3C37.042,26.266,36.5,25.2,36.5,24z M28.5,22c0.828,0,1.5,0.672,1.5,1.5S29.328,25,28.5,25
c-0.828,0-1.5-0.672-1.5-1.5S27.672,22,28.5,22z M16.5,26c1.103,0,2-0.897,2-2v-4c0-1.654,1.346-3,3-3c0.553,0,1,0.448,1,1
s-0.447,1-1,1c-0.552,0-1,0.449-1,1v4c0,1.2-0.542,2.266-1.382,3c0.84,0.734,1.382,1.8,1.382,3v4c0,0.551,0.448,1,1,1
c0.553,0,1,0.448,1,1s-0.447,1-1,1c-1.654,0-3-1.346-3-3v-4c0-1.103-0.897-2-2-2c-0.553,0-1-0.448-1-1S15.947,26,16.5,26z"/>
<path d="M6.5,41v15c0,1.009,1.22,2,2.463,2h40.074c1.243,0,2.463-0.991,2.463-2V41H6.5z M18.021,51.566
c0,0.474-0.087,0.873-0.26,1.196s-0.405,0.583-0.697,0.779s-0.627,0.333-1.005,0.41c-0.378,0.077-0.768,0.116-1.169,0.116
c-0.2,0-0.436-0.021-0.704-0.062s-0.547-0.104-0.834-0.191s-0.563-0.185-0.827-0.294s-0.487-0.232-0.67-0.369l0.697-1.107
c0.091,0.063,0.221,0.13,0.39,0.198s0.354,0.132,0.554,0.191s0.41,0.111,0.629,0.157s0.424,0.068,0.615,0.068
c0.483,0,0.868-0.094,1.155-0.28s0.439-0.504,0.458-0.95v-7.711h1.668V51.566z M25.958,52.298c-0.15,0.342-0.362,0.643-0.636,0.902
s-0.61,0.467-1.012,0.622s-0.856,0.232-1.367,0.232c-0.219,0-0.444-0.012-0.677-0.034s-0.467-0.062-0.704-0.116
c-0.237-0.055-0.463-0.13-0.677-0.226s-0.398-0.212-0.554-0.349l0.287-1.176c0.128,0.073,0.289,0.144,0.485,0.212
s0.398,0.132,0.608,0.191s0.419,0.107,0.629,0.144s0.405,0.055,0.588,0.055c0.556,0,0.982-0.13,1.278-0.39s0.444-0.645,0.444-1.155
c0-0.31-0.104-0.574-0.314-0.793s-0.472-0.417-0.786-0.595s-0.654-0.355-1.019-0.533s-0.706-0.388-1.025-0.629
s-0.583-0.526-0.793-0.854s-0.314-0.738-0.314-1.23c0-0.446,0.082-0.843,0.246-1.189s0.385-0.641,0.663-0.882
s0.602-0.426,0.971-0.554s0.759-0.191,1.169-0.191c0.419,0,0.843,0.039,1.271,0.116s0.774,0.203,1.039,0.376
c-0.055,0.118-0.118,0.248-0.191,0.39s-0.142,0.273-0.205,0.396s-0.118,0.226-0.164,0.308s-0.073,0.128-0.082,0.137
c-0.055-0.027-0.116-0.063-0.185-0.109s-0.166-0.091-0.294-0.137s-0.296-0.077-0.506-0.096s-0.479-0.014-0.807,0.014
c-0.183,0.019-0.355,0.07-0.52,0.157s-0.31,0.193-0.438,0.321s-0.228,0.271-0.301,0.431s-0.109,0.313-0.109,0.458
c0,0.364,0.104,0.658,0.314,0.882s0.47,0.419,0.779,0.588s0.647,0.333,1.012,0.492s0.704,0.354,1.019,0.581
s0.576,0.513,0.786,0.854s0.314,0.781,0.314,1.319C26.184,51.603,26.108,51.956,25.958,52.298z M35.761,51.156
c-0.214,0.647-0.511,1.185-0.889,1.613s-0.82,0.752-1.326,0.971s-1.06,0.328-1.661,0.328s-1.155-0.109-1.661-0.328
s-0.948-0.542-1.326-0.971s-0.675-0.966-0.889-1.613s-0.321-1.395-0.321-2.242s0.107-1.593,0.321-2.235s0.511-1.178,0.889-1.606
s0.82-0.754,1.326-0.978s1.06-0.335,1.661-0.335s1.155,0.111,1.661,0.335s0.948,0.549,1.326,0.978s0.675,0.964,0.889,1.606
s0.321,1.388,0.321,2.235S35.975,50.509,35.761,51.156z M45.68,54h-1.668l-3.951-6.945V54h-1.668V43.924h1.668l3.951,6.945v-6.945
h1.668V54z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -1,51 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 58 58" style="enable-background:new 0 0 58 58;" xml:space="preserve">
<g>
<path d="M51.5,39V13.978c0-0.766-0.092-1.333-0.55-1.792L39.313,0.55C38.964,0.201,38.48,0,37.985,0H8.963
C7.777,0,6.5,0.916,6.5,2.926V39H51.5z M37.5,3.391c0-0.458,0.553-0.687,0.877-0.363l10.095,10.095
C48.796,13.447,48.567,14,48.109,14H37.5V3.391z M33.793,18.707c-0.391-0.391-0.391-1.023,0-1.414s1.023-0.391,1.414,0l6,6
c0.391,0.391,0.391,1.023,0,1.414l-6,6C35.012,30.902,34.756,31,34.5,31s-0.512-0.098-0.707-0.293
c-0.391-0.391-0.391-1.023,0-1.414L39.086,24L33.793,18.707z M24.557,31.667l6-17c0.185-0.521,0.753-0.795,1.276-0.61
c0.521,0.184,0.794,0.755,0.61,1.276l-6,17C26.298,32.744,25.912,33,25.5,33c-0.11,0-0.223-0.019-0.333-0.058
C24.646,32.759,24.373,32.188,24.557,31.667z M15.793,23.293l6-6c0.391-0.391,1.023-0.391,1.414,0s0.391,1.023,0,1.414L17.914,24
l5.293,5.293c0.391,0.391,0.391,1.023,0,1.414C23.012,30.902,22.756,31,22.5,31s-0.512-0.098-0.707-0.293l-6-6
C15.402,24.316,15.402,23.684,15.793,23.293z"/>
<path d="M6.5,41v15c0,1.009,1.22,2,2.463,2h40.074c1.243,0,2.463-0.991,2.463-2V41H6.5z M22.936,54h-1.9l-1.6-3.801h-0.137
L17.576,54h-1.9l2.557-4.895l-2.721-5.182h1.873l1.777,4.102h0.137l1.928-4.102H23.1l-2.721,5.182L22.936,54z M34.666,54h-1.668
v-6.932l-2.256,5.605h-1.449l-2.27-5.605V54h-1.668V43.924h1.668l2.994,6.891l2.98-6.891h1.668V54z M43.498,54h-6.303V43.924h1.668
v8.832h4.635V54z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,56 +0,0 @@
<!--aside id="sidebar">
<div class="">
<label>Validation Options</label>
<ul>
<li><input type="checkbox" id="doNative">doNative</li>
<li><input type="checkbox" id="anyExtensionAllowed">anyExtensionAllowed</li>
<li><input type="checkbox" id="hintAboutNonMustSupport">hintAboutNonMustSupport</li>
<li><input type="checkbox" id="recursive">recursive</li>
<li><input type="checkbox" id="doDebug">doDebug</li>
<li><input type="checkbox" id="assumeValidRestReferences">assumeValidRestReferences</li>
<li><input type="checkbox" name="canDoNative" id="canDoNative">canDoNative</li>
<li>
<label>Map</label>
<input type="text" name="map" placeholder="enter map">
</li>
<li>
<label>Output</label>
<input type="text" name="output" placeholder="enter output">
</li>
<li>
<label>txServer</label>
<input type="text" name="txServer" placeholder="enter txServer">
</li>
<li>
<label>sv</label>
<input type="text" name="sv" placeholder="enter sv">
</li>
<li>
<label>txLog</label>
<input type="text" name="txLog" placeholder="enter txLog">
</li>
<li>
<label>mapLog</label>
<input type="text" name="mapLog" placeholder="enter mapLog">
</li>
<li>
<label>lang</label>
<input type="text" name="lang" placeholder="enter lang">
</li>
<li>
<label>fhirpath</label>
<input type="text" name="fhirpath" placeholder="enter fhirpath">
</li>
<li>
<label>snomedCT</label>
<input type="text" name="snomedCT" placeholder="enter snomedCT">
</li>
<li>
<label>targetVer</label>
<input type="text" name="targetVer" placeholder="enter targetVer">
</li>
</ul>
<input id='test_button' class="btn" type="submit" value="Submit">
</div>
</aside-->

View File

@ -1,10 +0,0 @@
export const EngineMode {
VALIDATION,
TRANSFORM,
NARRATIVE,
SNAPSHOT,
SCAN,
CONVERT,
FHIRPATH,
VERSION
}

View File

@ -1,17 +0,0 @@
export const FhirFormat = {
XML: {
extension:'xml'
},
JSON: {
extension:'json'
},
TURTLE: {
extension:'ttl'
},
TEXT: {
extension:'txt'
},
VBAR: {
extension:'hl7'
},
}

View File

@ -1,14 +0,0 @@
export const IssueSeverity = {
FATAL: {
code: 'Fatal'
},
ERROR: {
code: 'Error'
},
WARNING: {
code: 'Warning'
},
INFORMATION: {
code: 'Information'
}
}

View File

@ -1,30 +0,0 @@
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'
}
}

View File

@ -1,38 +0,0 @@
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"
}
}

View File

@ -1,99 +0,0 @@
<html lang="en"><head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="Mark Iantorno">
<meta name="generator" content="Jekyll v3.8.6">
<title>FHIR HL7 Resrouce Validator GUI</title>
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link rel="canonical" href="https://getbootstrap.com/docs/4.4/examples/offcanvas/">
<!-- Favicons -->
<meta name="theme-color" content="#563d7c">
<style>
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}
</style>
<!-- Custom styles for this template -->
<link href="style.css" rel="stylesheet">
</head>
<body class="bg-light">
<main role="main" class="container">
<div class="d-flex align-items-center p-3 my-3 text-white-50 bg-secondary rounded shadow-sm">
<img class="mr-3" src="./assets/fhir-logo-www.png" alt="" height="48">
<div class="lh-100">
<h6 class="mb-0 text-white lh-100">FHIR Core Validator</h6>
<small class="text-white">Experimental</small>
</div>
</div>
<div class="my-3 p-3 bg-white rounded shadow-sm">
<div class="d-flex border-bottom border-gray justify-content-between align-items-center w-100">
<h6 class="pb-2 mb-0">Files to Validate</h6>
<button id="validate_button" class="btn btn-secondary mb-1">Validate</button>
</div>
<div class="accordion" id="accordionExample">
<ul id="file_entry_file_list" class="list-group border">
</ul>
</div>
<div class="bd-callout bd-callout-info">
<small class="d-block text-right mt-3">
<input type="file" style="display:none;" id="files" name="files[]" multiple="" >
<button type="button" class="btn btn-secondary" onclick="document.getElementById('files').click()">Add Files</button>
</small>
</div>
<template id="file_entry_template">
<li class="list-unstyled">
<div class="card">
<div class="card-header" id="headingOne">
<div class="d-flex">
<div class="d-flex align-items-center">
<img id="file_entry_type_icon" class="bd-placeholder-img mr-2 rounded" src="./assets/json-svgrepo-com.svg" width="32" height="32" preserveaspectratio="xMidYMid slice">
<button id="file_entry_name_field" class="btn btn-link" type="button" data-toggle="collapse" data-target="#file_entry_collapse_section" aria-expanded="true" aria-controls="file_entry_collapse_section">
Collapsible Group Item #1
</button>
</div>
<div class="ml-auto d-flex">
<svg id="file_entry_delete_button" class="delete_button align-self-center" height="24" viewBox="0 0 24 24" width="24">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zm2.46-7.12l1.41-1.41L12 12.59l2.12-2.12 1.41 1.41L13.41 14l2.12 2.12-1.41 1.41L12 15.41l-2.12 2.12-1.41-1.41L10.59 14l-2.13-2.12zM15.5 4l-1-1h-5l-1 1H5v2h14V4z"></path>
</svg>
</div>
</div>
</div>
<div id="file_entry_collapse_section" class="collapse" aria-labelledby="headingOne" data-parent="#accordionExample">
<div class="card-body">
<ul id="file_entry_outcome_list" class="list-group">
</ul>
</div>
</div>
</div>
</li>
</template>
</div>
</main>
<script type="module" src="./main.js"></script>
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
</body></html>

View File

@ -1,206 +0,0 @@
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';
/*
</Constants>
*/
// 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(ID_FILE_ENTRY_FILE_LIST).appendChild(generateNewFileListItemFromTemplate(file, filesToValidate.length - 1));
};
fr.readAsText(file);
}
// File List Template Generation
function generateNewFileListItemFromTemplate(file, index) {
var template = document.querySelector(ID_FILE_ENTRY_TEMPLATE);
var clone = template.content.cloneNode(true);
// Add file name
clone.getElementById(ID_FILE_ENTRY_NAME).textContent = file.name;
// Add appropriate icon for filetype
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(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 );
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);
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);
});
}
}
// 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 + '"';
//
// };

View File

@ -1,34 +0,0 @@
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();
}
}

View File

@ -1,13 +0,0 @@
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;
}
}
}

View File

@ -1,6 +0,0 @@
export class ValidationIssue {
constructor(){
this.severity = "";
this.details = "";
}
}

View File

@ -1,8 +0,0 @@
import {FileInfo} from './FileInfo.js';
export class ValidationOutcome {
constructor(){
this.fileInfo = null;
this.issues = [];
}
}

View File

@ -1,8 +0,0 @@
import {CliContext} from './CliContext.js';
export class ValidationRequest {
constructor(){
this.cliContext = new CliContext();
this.filesToValidate = [];
}
}

View File

@ -1,7 +0,0 @@
import {ValidationOutcome} from './ValidationOutcome.js';
export class ValidationResponse {
constructor() {
this.outcomes = [];
}
}

View File

@ -1,94 +0,0 @@
/* */
.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; }

View File

@ -2,7 +2,7 @@ package org.hl7.fhir.validation.tests;
import org.hl7.fhir.r4.context.SimpleWorkerContext;
import org.hl7.fhir.r5.test.utils.TestingUtilities;
import org.hl7.fhir.validation.Validator;
import org.hl7.fhir.validation.ValidatorCli;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@ -13,7 +13,7 @@ public class CDAValidationTest {
@Test
public void test() throws Exception {
Validator.main(new String[] {TestingUtilities.loadTestResource("ccda.xml"), "-ig", "hl7.fhir.cda"});
ValidatorCli.main(new String[] {TestingUtilities.loadTestResource("ccda.xml"), "-ig", "hl7.fhir.cda"});
}
}

View File

@ -4,7 +4,7 @@ import java.io.File;
import org.hl7.fhir.r4.test.utils.TestingUtilities;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.validation.Validator;
import org.hl7.fhir.validation.ValidatorCli;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@ -18,7 +18,7 @@ public class TransformationTests {
String output = Utilities.path("[tmp]", "cda-bundle.txt");
String log = Utilities.path("[tmp]", "transform-log.txt");
Validator.main(new String[] {input, "-transform", "http://hl7.org/fhir/cda/mapping/ccdaDocumentToFhir", "-ig", "hl7.fhir.cda", "-ig", mappings, "-output", output, "-log", log});
ValidatorCli.main(new String[] {input, "-transform", "http://hl7.org/fhir/cda/mapping/ccdaDocumentToFhir", "-ig", "hl7.fhir.cda", "-ig", mappings, "-output", output, "-log", log});
checkFile(output);
checkFile(log);
}