Merge pull request #34 from jjathman/remove-validation-exception
Fixes #32 - removes new validation API that doesn't use exceptions
This commit is contained in:
commit
d140e0b829
|
@ -20,18 +20,15 @@ package ca.uhn.fhir.validation;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import com.phloc.schematron.ISchematronResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Resource validator, which checks resources for compliance against various validation schemes (schemas, schematrons, etc.)
|
||||
|
@ -133,25 +130,18 @@ public class FhirValidator {
|
|||
/**
|
||||
* Validates a bundle instance, throwing a {@link ValidationFailureException} if the validation fails. This validation includes validation of all resources in the bundle.
|
||||
*
|
||||
* @param theResource
|
||||
* @param theBundle
|
||||
* The resource to validate
|
||||
* @throws ValidationFailureException
|
||||
* If the validation fails
|
||||
* @deprecated use {@link #validateWithResult(ca.uhn.fhir.model.api.Bundle)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void validate(Bundle theBundle) {
|
||||
Validate.notNull(theBundle, "theBundle must not be null");
|
||||
|
||||
ValidationContext<Bundle> ctx = ValidationContext.forBundle(myContext, theBundle);
|
||||
|
||||
for (IValidator next : myValidators) {
|
||||
next.validateBundle(ctx);
|
||||
ValidationResult validationResult = validateWithResult(theBundle);
|
||||
if (!validationResult.isSuccessful()) {
|
||||
throw new ValidationFailureException(validationResult.getOperationOutcome());
|
||||
}
|
||||
|
||||
OperationOutcome oo = ctx.getOperationOutcome();
|
||||
if (oo != null && oo.getIssue().size() > 0) {
|
||||
throw new ValidationFailureException(oo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -161,8 +151,45 @@ public class FhirValidator {
|
|||
* The resource to validate
|
||||
* @throws ValidationFailureException
|
||||
* If the validation fails
|
||||
* @deprecated use {@link #validateWithResult(ca.uhn.fhir.model.api.IResource)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void validate(IResource theResource) throws ValidationFailureException {
|
||||
ValidationResult validationResult = validateWithResult(theResource);
|
||||
if (!validationResult.isSuccessful()) {
|
||||
throw new ValidationFailureException(validationResult.getOperationOutcome());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a bundle instance returning a {@link ca.uhn.fhir.validation.ValidationResult} which contains the results.
|
||||
* This validation includes validation of all resources in the bundle.
|
||||
*
|
||||
* @param theBundle the bundle to validate
|
||||
* @return the results of validation
|
||||
* @since 0.7
|
||||
*/
|
||||
public ValidationResult validateWithResult(Bundle theBundle) {
|
||||
Validate.notNull(theBundle, "theBundle must not be null");
|
||||
|
||||
ValidationContext<Bundle> ctx = ValidationContext.forBundle(myContext, theBundle);
|
||||
|
||||
for (IValidator next : myValidators) {
|
||||
next.validateBundle(ctx);
|
||||
}
|
||||
|
||||
OperationOutcome oo = ctx.getOperationOutcome();
|
||||
return ValidationResult.valueOf(oo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a resource instance returning a {@link ca.uhn.fhir.validation.ValidationResult} which contains the results.
|
||||
*
|
||||
* @param theResource the resource to validate
|
||||
* @return the results of validation
|
||||
* @since 0.7
|
||||
*/
|
||||
public ValidationResult validateWithResult(IResource theResource) {
|
||||
Validate.notNull(theResource, "theResource must not be null");
|
||||
|
||||
ValidationContext<IResource> ctx = ValidationContext.forResource(myContext, theResource);
|
||||
|
@ -172,10 +199,6 @@ public class FhirValidator {
|
|||
}
|
||||
|
||||
OperationOutcome oo = ctx.getOperationOutcome();
|
||||
if (oo != null && oo.getIssue().size() > 0) {
|
||||
throw new ValidationFailureException(oo);
|
||||
return ValidationResult.valueOf(oo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||
|
||||
/**
|
||||
* Encapsulates the results of validation
|
||||
*
|
||||
* @see ca.uhn.fhir.validation.FhirValidator
|
||||
* @since 0.7
|
||||
*/
|
||||
public class ValidationResult {
|
||||
private OperationOutcome myOperationOutcome;
|
||||
|
||||
private ValidationResult(OperationOutcome myOperationOutcome) {
|
||||
this.myOperationOutcome = myOperationOutcome;
|
||||
}
|
||||
|
||||
public static ValidationResult valueOf(OperationOutcome myOperationOutcome) {
|
||||
return new ValidationResult(myOperationOutcome);
|
||||
}
|
||||
|
||||
public OperationOutcome getOperationOutcome() {
|
||||
return myOperationOutcome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ValidationResult{" +
|
||||
"myOperationOutcome=" + myOperationOutcome +
|
||||
", description='" + toDescription() + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
private String toDescription() {
|
||||
StringBuilder b = new StringBuilder(100);
|
||||
if (myOperationOutcome != null) {
|
||||
OperationOutcome.Issue issueFirstRep = myOperationOutcome.getIssueFirstRep();
|
||||
b.append(issueFirstRep.getDetails().getValue());
|
||||
b.append(" - ");
|
||||
b.append(issueFirstRep.getLocationFirstRep().getValue());
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Was the validation successful
|
||||
* @return true if the validation was successful
|
||||
*/
|
||||
public boolean isSuccessful() {
|
||||
return myOperationOutcome == null || myOperationOutcome.getIssue().isEmpty();
|
||||
}
|
||||
}
|
|
@ -1,17 +1,22 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu.valueset.ContactSystemEnum;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class ResourceValidatorTest {
|
||||
|
||||
|
@ -45,9 +50,7 @@ public class ResourceValidatorTest {
|
|||
String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("atom-document-large.xml"));
|
||||
Bundle b = ourCtx.newXmlParser().parseBundle(res);
|
||||
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.setValidateAgainstStandardSchema(true);
|
||||
val.setValidateAgainstStandardSchematron(true);
|
||||
FhirValidator val = createFhirValidator();
|
||||
|
||||
val.validate(b);
|
||||
|
||||
|
@ -64,7 +67,6 @@ public class ResourceValidatorTest {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSchematronResourceValidator() throws IOException {
|
||||
String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("patient-example-dicom.xml"));
|
||||
|
@ -74,20 +76,60 @@ public class ResourceValidatorTest {
|
|||
val.setValidateAgainstStandardSchema(false);
|
||||
val.setValidateAgainstStandardSchematron(true);
|
||||
|
||||
val.validate(p);
|
||||
ValidationResult validationResult = val.validateWithResult(p);
|
||||
assertTrue(validationResult.isSuccessful());
|
||||
|
||||
p.getTelecomFirstRep().setValue("123-4567");
|
||||
try {
|
||||
val.validate(p);
|
||||
fail();
|
||||
} catch (ValidationFailureException e) {
|
||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
|
||||
assertEquals(1, e.getOperationOutcome().getIssue().size());
|
||||
assertThat(e.getOperationOutcome().getIssueFirstRep().getDetails().getValue(), containsString("Inv-2: A system is required if a value is provided."));
|
||||
}
|
||||
validationResult = val.validateWithResult(p);
|
||||
assertFalse(validationResult.isSuccessful());
|
||||
OperationOutcome operationOutcome = validationResult.getOperationOutcome();
|
||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome));
|
||||
assertEquals(1, operationOutcome.getIssue().size());
|
||||
assertThat(operationOutcome.getIssueFirstRep().getDetails().getValue(), containsString("Inv-2: A system is required if a value is provided."));
|
||||
|
||||
p.getTelecomFirstRep().setSystem(ContactSystemEnum.EMAIL);
|
||||
val.validate(p);
|
||||
validationResult = val.validateWithResult(p);
|
||||
assertTrue(validationResult.isSuccessful());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSchemaBundleValidatorIsSuccessful() throws IOException {
|
||||
String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("atom-document-large.xml"));
|
||||
Bundle b = ourCtx.newXmlParser().parseBundle(res);
|
||||
|
||||
FhirValidator val = createFhirValidator();
|
||||
|
||||
ValidationResult result = val.validateWithResult(b);
|
||||
assertTrue(result.isSuccessful());
|
||||
OperationOutcome operationOutcome = result.getOperationOutcome();
|
||||
assertNotNull(operationOutcome);
|
||||
assertEquals(0, operationOutcome.getIssue().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSchemaBundleValidatorFails() throws IOException {
|
||||
String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("atom-document-large.xml"));
|
||||
Bundle b = ourCtx.newXmlParser().parseBundle(res);
|
||||
|
||||
FhirValidator val = createFhirValidator();
|
||||
|
||||
ValidationResult validationResult = val.validateWithResult(b);
|
||||
assertTrue(validationResult.isSuccessful());
|
||||
|
||||
Patient p = (Patient) b.getEntries().get(0).getResource();
|
||||
p.getTelecomFirstRep().setValue("123-4567");
|
||||
validationResult = val.validateWithResult(b);
|
||||
assertFalse(validationResult.isSuccessful());
|
||||
OperationOutcome operationOutcome = validationResult.getOperationOutcome();
|
||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome));
|
||||
assertEquals(1, operationOutcome.getIssue().size());
|
||||
assertThat(operationOutcome.getIssueFirstRep().getDetails().getValue(), containsString("Inv-2: A system is required if a value is provided."));
|
||||
}
|
||||
|
||||
private FhirValidator createFhirValidator() {
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.setValidateAgainstStandardSchema(true);
|
||||
val.setValidateAgainstStandardSchematron(true);
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class ValidationResultTest {
|
||||
|
||||
@Test
|
||||
public void isSuccessful_IsTrueForNullOperationOutcome() {
|
||||
ValidationResult result = ValidationResult.valueOf(null);
|
||||
assertTrue(result.isSuccessful());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSuccessful_IsTrueForNoIssues() {
|
||||
OperationOutcome operationOutcome = new OperationOutcome();
|
||||
// make sure a non-null ID doesn't cause the validation result to be a fail
|
||||
operationOutcome.setId(UUID.randomUUID().toString());
|
||||
ValidationResult result = ValidationResult.valueOf(operationOutcome);
|
||||
assertTrue(result.isSuccessful());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSuccessful_FalseForIssues() {
|
||||
OperationOutcome operationOutcome = new OperationOutcome();
|
||||
OperationOutcome.Issue issue = operationOutcome.addIssue();
|
||||
String errorMessage = "There was a validation problem";
|
||||
issue.setDetails(errorMessage);
|
||||
ValidationResult result = ValidationResult.valueOf(operationOutcome);
|
||||
assertFalse(result.isSuccessful());
|
||||
List<OperationOutcome.Issue> issues = result.getOperationOutcome().getIssue();
|
||||
assertEquals(1, issues.size());
|
||||
assertEquals(errorMessage, issues.get(0).getDetails().getValue());
|
||||
|
||||
assertThat("ValidationResult#toString should contain the issue description", result.toString(), containsString(errorMessage));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue