From f6e7905f59a9f47d6e0f1be24a6df83db379ee34 Mon Sep 17 00:00:00 2001 From: jamesagnew Date: Thu, 17 Sep 2015 08:40:28 -0400 Subject: [PATCH] CLI commits --- .../uhn/fhir/cli/CommandFailureException.java | 2 +- .../fhir/cli/LoadingValidationSupport.java | 58 +++++++++++++++++++ .../java/ca/uhn/fhir/cli/ValidateCommand.java | 40 ++++++++++--- 3 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/LoadingValidationSupport.java diff --git a/hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/CommandFailureException.java b/hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/CommandFailureException.java index 93f77bc0ea1c..cc33e3e925e1 100644 --- a/hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/CommandFailureException.java +++ b/hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/CommandFailureException.java @@ -1,6 +1,6 @@ package ca.uhn.fhir.cli; -public class CommandFailureException extends Exception { +public class CommandFailureException extends Error { public CommandFailureException(String theMessage) { super(theMessage); diff --git a/hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/LoadingValidationSupport.java b/hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/LoadingValidationSupport.java new file mode 100644 index 000000000000..85d92f1addd2 --- /dev/null +++ b/hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/LoadingValidationSupport.java @@ -0,0 +1,58 @@ +package ca.uhn.fhir.cli; + +import org.hl7.fhir.instance.model.ValueSet; +import org.hl7.fhir.instance.model.ValueSet.ConceptSetComponent; +import org.hl7.fhir.instance.model.ValueSet.ValueSetExpansionComponent; +import org.hl7.fhir.instance.model.api.IBaseResource; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.client.IGenericClient; +import ca.uhn.fhir.rest.client.ServerValidationModeEnum; +import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; +import ca.uhn.fhir.validation.IValidationSupport; + +public class LoadingValidationSupport implements IValidationSupport { + + private static FhirContext myCtx = FhirContext.forDstu2Hl7Org(); + + @Override + public ValueSetExpansionComponent expandValueSet(ConceptSetComponent theInclude) { + return null; + } + + @Override + public ValueSet fetchCodeSystem(String theSystem) { + return null; + } + + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(LoadingValidationSupport.class); + + @Override + public T fetchResource(FhirContext theContext, Class theClass, String theUri) { + String resName = myCtx.getResourceDefinition(theClass).getName(); + ourLog.info("Attempting to fetch {} at URL: {}", resName, theUri); + + myCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); + IGenericClient client = myCtx.newRestfulGenericClient("http://example.com"); + + T result; + try { + result = client.read(theClass, theUri); + } catch (BaseServerResponseException e) { + throw new CommandFailureException("FAILURE: Received HTTP " + e.getStatusCode() + ": " + e.getMessage()); + } + ourLog.info("Successfully loaded resource"); + return result; + } + + @Override + public boolean isCodeSystemSupported(String theSystem) { + return false; + } + + @Override + public CodeValidationResult validateCode(String theCodeSystem, String theCode, String theDisplay) { + return null; + } + +} diff --git a/hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/ValidateCommand.java b/hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/ValidateCommand.java index 7bc49ca11d4b..680417450aac 100644 --- a/hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/ValidateCommand.java +++ b/hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/ValidateCommand.java @@ -3,7 +3,7 @@ import static org.apache.commons.lang3.StringUtils.defaultString; import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank; - +import static org.apache.commons.lang3.StringUtils.leftPad; import static org.fusesource.jansi.Ansi.*; import java.io.FileInputStream; @@ -15,16 +15,20 @@ import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.text.WordUtils; import org.fusesource.jansi.Ansi; import com.phloc.commons.io.file.FileUtils; import ca.uhn.fhir.rest.method.MethodUtil; import ca.uhn.fhir.rest.server.EncodingEnum; +import ca.uhn.fhir.validation.DefaultProfileValidationSupport; import ca.uhn.fhir.validation.FhirInstanceValidator; import ca.uhn.fhir.validation.FhirValidator; import ca.uhn.fhir.validation.SingleValidationMessage; import ca.uhn.fhir.validation.ValidationResult; +import ca.uhn.fhir.validation.ValidationSupportChain; +import net.sf.saxon.om.Chain; public class ValidateCommand extends BaseCommand { @@ -52,6 +56,7 @@ public Options getOptions() { retVal.addOption("x", "xsd", false, "Validate using Schemas"); retVal.addOption("s", "sch", false, "Validate using Schematrons"); retVal.addOption("p", "profile", false, "Validate using Profiles (StructureDefinition / ValueSet)"); + retVal.addOption("r", "fetch-remote", false, "Allow fetching remote resources (in other words, if a resource being validated refers to an external StructureDefinition, Questionnaire, etc. this flag allows the validator to access the internet to try and fetch this resource)"); retVal.addOption("e", "encoding", false, "File encoding (default is UTF-8)"); @@ -84,29 +89,46 @@ public void run(CommandLine theCommandLine) throws ParseException, Exception { FhirValidator val = getFhirCtx().newValidator(); if (theCommandLine.hasOption("p")) { - val.registerValidatorModule(new FhirInstanceValidator()); + FhirInstanceValidator instanceValidator = new FhirInstanceValidator(); + val.registerValidatorModule(instanceValidator); + if (theCommandLine.hasOption("r")) { + instanceValidator.setValidationSupport(new ValidationSupportChain(new DefaultProfileValidationSupport(), new LoadingValidationSupport())); + } } val.setValidateAgainstStandardSchema(theCommandLine.hasOption("x")); val.setValidateAgainstStandardSchematron(theCommandLine.hasOption("s")); ValidationResult results = val.validateWithResult(contents); - + StringBuilder b = new StringBuilder("Validation results:" + ansi().boldOff()); int count = 0; for (SingleValidationMessage next : results.getMessages()) { count++; b.append(App.LINESEP); - b.append("Issue ").append(count).append(": "); - b.append(next.getSeverity()).append(" - ").append(next.getLocationString()); - b.append(App.LINESEP); - b.append(" ").append(next.getMessage()); + String leftString = "Issue "+count+": "; + int leftWidth = leftString.length(); + b.append(ansi().fg(Color.GREEN)).append(leftString); + if (next.getSeverity() != null) { + b.append(next.getSeverity()).append(ansi().fg(Color.WHITE)).append(" - "); + } + if (isNotBlank(next.getLocationString())) { + b.append(ansi().fg(Color.WHITE)).append(next.getLocationString()); + } + String[] message = WordUtils.wrap(next.getMessage(), 80 - leftWidth, "\n", true).split("\\n"); + for (String line : message) { + b.append(App.LINESEP); + b.append(ansi().fg(Color.WHITE)); + b.append(leftPad("", leftWidth)).append(line); + } + } - + b.append(App.LINESEP); + if (count > 0) { ourLog.info(b.toString()); } - + if (results.isSuccessful()) { ourLog.info("Validation successful!"); } else {