Use R4 validator for DSTU3 validation
This commit is contained in:
parent
e52f582769
commit
8d468de551
|
@ -18,7 +18,7 @@ import ca.uhn.fhir.jpa.validation.JpaValidationSupportChainDstu3;
|
||||||
import ca.uhn.fhir.validation.IValidatorModule;
|
import ca.uhn.fhir.validation.IValidatorModule;
|
||||||
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
|
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
|
||||||
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
|
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
|
||||||
import org.hl7.fhir.dstu3.utils.IResourceValidator.BestPracticeWarningLevel;
|
import org.hl7.fhir.r4.utils.IResourceValidator;
|
||||||
import org.springframework.beans.factory.annotation.Autowire;
|
import org.springframework.beans.factory.annotation.Autowire;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
@ -66,7 +66,7 @@ public class BaseDstu3Config extends BaseConfig {
|
||||||
@Lazy
|
@Lazy
|
||||||
public IValidatorModule instanceValidatorDstu3() {
|
public IValidatorModule instanceValidatorDstu3() {
|
||||||
FhirInstanceValidator val = new FhirInstanceValidator();
|
FhirInstanceValidator val = new FhirInstanceValidator();
|
||||||
val.setBestPracticeWarningLevel(BestPracticeWarningLevel.Warning);
|
val.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Warning);
|
||||||
val.setValidationSupport(validationSupportChainDstu3());
|
val.setValidationSupport(validationSupportChainDstu3());
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,354 +1,335 @@
|
||||||
package org.hl7.fhir.dstu3.context;
|
package org.hl7.fhir.dstu3.context;
|
||||||
|
|
||||||
import java.util.List;
|
import org.hl7.fhir.dstu3.formats.IParser;
|
||||||
import java.util.Set;
|
import org.hl7.fhir.dstu3.formats.ParserType;
|
||||||
|
import org.hl7.fhir.dstu3.model.*;
|
||||||
import org.hl7.fhir.dstu3.formats.IParser;
|
import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;
|
||||||
import org.hl7.fhir.dstu3.formats.ParserType;
|
import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
|
||||||
import org.hl7.fhir.dstu3.model.CodeSystem;
|
import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent;
|
||||||
import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;
|
import org.hl7.fhir.dstu3.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
|
||||||
import org.hl7.fhir.dstu3.model.CodeableConcept;
|
import org.hl7.fhir.dstu3.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||||
import org.hl7.fhir.dstu3.model.Coding;
|
import org.hl7.fhir.dstu3.utils.INarrativeGenerator;
|
||||||
import org.hl7.fhir.dstu3.model.ConceptMap;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.dstu3.model.ExpansionProfile;
|
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
||||||
import org.hl7.fhir.dstu3.model.MetadataResource;
|
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||||
import org.hl7.fhir.dstu3.model.Resource;
|
|
||||||
import org.hl7.fhir.dstu3.model.StructureDefinition;
|
import java.util.List;
|
||||||
import org.hl7.fhir.dstu3.model.ValueSet;
|
import java.util.Set;
|
||||||
import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
|
|
||||||
import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent;
|
|
||||||
import org.hl7.fhir.dstu3.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
|
/**
|
||||||
import org.hl7.fhir.dstu3.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
* This is the standard interface used for access to underlying FHIR
|
||||||
import org.hl7.fhir.dstu3.utils.INarrativeGenerator;
|
* services through the tools and utilities provided by the reference
|
||||||
import org.hl7.fhir.dstu3.utils.IResourceValidator;
|
* implementation.
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
*
|
||||||
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
* The functionality it provides is
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
* - get access to parsers, validators, narrative builders etc
|
||||||
|
* (you can't create these directly because they need access
|
||||||
|
* to the right context for their information)
|
||||||
/**
|
*
|
||||||
* This is the standard interface used for access to underlying FHIR
|
* - find resources that the tools need to carry out their tasks
|
||||||
* services through the tools and utilities provided by the reference
|
*
|
||||||
* implementation.
|
* - provide access to terminology services they need.
|
||||||
*
|
* (typically, these terminology service requests are just
|
||||||
* The functionality it provides is
|
* passed through to the local implementation's terminology
|
||||||
* - get access to parsers, validators, narrative builders etc
|
* service)
|
||||||
* (you can't create these directly because they need access
|
*
|
||||||
* to the right context for their information)
|
* @author Grahame
|
||||||
*
|
*/
|
||||||
* - find resources that the tools need to carry out their tasks
|
public interface IWorkerContext {
|
||||||
*
|
|
||||||
* - provide access to terminology services they need.
|
/**
|
||||||
* (typically, these terminology service requests are just
|
* Get the versions of the definitions loaded in context
|
||||||
* passed through to the local implementation's terminology
|
* @return
|
||||||
* service)
|
*/
|
||||||
*
|
public String getVersion();
|
||||||
* @author Grahame
|
|
||||||
*/
|
// -- Parsers (read and write instances) ----------------------------------------
|
||||||
public interface IWorkerContext {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the versions of the definitions loaded in context
|
* Get a parser to read/write instances. Use the defined type (will be extended
|
||||||
* @return
|
* as further types are added, though the only currently anticipate type is RDF)
|
||||||
*/
|
*
|
||||||
public String getVersion();
|
* XML/JSON - the standard renderers
|
||||||
|
* XHTML - render the narrative only (generate it if necessary)
|
||||||
// -- Parsers (read and write instances) ----------------------------------------
|
*
|
||||||
|
* @param type
|
||||||
|
* @return
|
||||||
/**
|
*/
|
||||||
* Get a parser to read/write instances. Use the defined type (will be extended
|
public IParser getParser(ParserType type);
|
||||||
* as further types are added, though the only currently anticipate type is RDF)
|
|
||||||
*
|
/**
|
||||||
* XML/JSON - the standard renderers
|
* Get a parser to read/write instances. Determine the type
|
||||||
* XHTML - render the narrative only (generate it if necessary)
|
* from the stated type. Supported value for type:
|
||||||
*
|
* - the recommended MIME types
|
||||||
* @param type
|
* - variants of application/xml and application/json
|
||||||
* @return
|
* - _format values xml, json
|
||||||
*/
|
*
|
||||||
public IParser getParser(ParserType type);
|
* @param type
|
||||||
|
* @return
|
||||||
/**
|
*/
|
||||||
* Get a parser to read/write instances. Determine the type
|
public IParser getParser(String type);
|
||||||
* from the stated type. Supported value for type:
|
|
||||||
* - the recommended MIME types
|
/**
|
||||||
* - variants of application/xml and application/json
|
* Get a JSON parser
|
||||||
* - _format values xml, json
|
*
|
||||||
*
|
* @return
|
||||||
* @param type
|
*/
|
||||||
* @return
|
public IParser newJsonParser();
|
||||||
*/
|
|
||||||
public IParser getParser(String type);
|
/**
|
||||||
|
* Get an XML parser
|
||||||
/**
|
*
|
||||||
* Get a JSON parser
|
* @return
|
||||||
*
|
*/
|
||||||
* @return
|
public IParser newXmlParser();
|
||||||
*/
|
|
||||||
public IParser newJsonParser();
|
/**
|
||||||
|
* Get a generator that can generate narrative for the instance
|
||||||
/**
|
*
|
||||||
* Get an XML parser
|
* @return a prepared generator
|
||||||
*
|
*/
|
||||||
* @return
|
public INarrativeGenerator getNarrativeGenerator(String prefix, String basePath);
|
||||||
*/
|
|
||||||
public IParser newXmlParser();
|
|
||||||
|
// -- resource fetchers ---------------------------------------------------
|
||||||
/**
|
|
||||||
* Get a generator that can generate narrative for the instance
|
/**
|
||||||
*
|
* Find an identified resource. The most common use of this is to access the the
|
||||||
* @return a prepared generator
|
* standard conformance resources that are part of the standard - structure
|
||||||
*/
|
* definitions, value sets, concept maps, etc.
|
||||||
public INarrativeGenerator getNarrativeGenerator(String prefix, String basePath);
|
*
|
||||||
|
* Also, the narrative generator uses this, and may access any kind of resource
|
||||||
/**
|
*
|
||||||
* Get a validator that can check whether a resource is valid
|
* The URI is called speculatively for things that might exist, so not finding
|
||||||
*
|
* a matching resouce, return null, not an error
|
||||||
* @return a prepared generator
|
*
|
||||||
* @throws FHIRException
|
* The URI can have one of 3 formats:
|
||||||
* @
|
* - a full URL e.g. http://acme.org/fhir/ValueSet/[id]
|
||||||
*/
|
* - a relative URL e.g. ValueSet/[id]
|
||||||
public IResourceValidator newValidator() throws FHIRException;
|
* - a logical id e.g. [id]
|
||||||
|
*
|
||||||
// -- resource fetchers ---------------------------------------------------
|
* It's an error if the second form doesn't agree with class_. It's an
|
||||||
|
* error if class_ is null for the last form
|
||||||
/**
|
*
|
||||||
* Find an identified resource. The most common use of this is to access the the
|
* @return
|
||||||
* standard conformance resources that are part of the standard - structure
|
* @throws FHIRException
|
||||||
* definitions, value sets, concept maps, etc.
|
* @throws Exception
|
||||||
*
|
*/
|
||||||
* Also, the narrative generator uses this, and may access any kind of resource
|
public <T extends Resource> T fetchResource(Class<T> class_, String uri);
|
||||||
*
|
public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri) throws FHIRException;
|
||||||
* The URI is called speculatively for things that might exist, so not finding
|
|
||||||
* a matching resouce, return null, not an error
|
/**
|
||||||
*
|
* find whether a resource is available.
|
||||||
* The URI can have one of 3 formats:
|
*
|
||||||
* - a full URL e.g. http://acme.org/fhir/ValueSet/[id]
|
* Implementations of the interface can assume that if hasResource ruturns
|
||||||
* - a relative URL e.g. ValueSet/[id]
|
* true, the resource will usually be fetched subsequently
|
||||||
* - a logical id e.g. [id]
|
*
|
||||||
*
|
* @param class_
|
||||||
* It's an error if the second form doesn't agree with class_. It's an
|
* @param uri
|
||||||
* error if class_ is null for the last form
|
* @return
|
||||||
*
|
*/
|
||||||
* @param resource
|
public <T extends Resource> boolean hasResource(Class<T> class_, String uri);
|
||||||
* @param Reference
|
|
||||||
* @return
|
// -- profile services ---------------------------------------------------------
|
||||||
* @throws FHIRException
|
|
||||||
* @throws Exception
|
public List<String> getResourceNames();
|
||||||
*/
|
public List<String> getTypeNames();
|
||||||
public <T extends Resource> T fetchResource(Class<T> class_, String uri);
|
public List<StructureDefinition> allStructures();
|
||||||
public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri) throws FHIRException;
|
public List<MetadataResource> allConformanceResources();
|
||||||
|
|
||||||
/**
|
// -- Terminology services ------------------------------------------------------
|
||||||
* find whether a resource is available.
|
|
||||||
*
|
public ExpansionProfile getExpansionProfile();
|
||||||
* Implementations of the interface can assume that if hasResource ruturns
|
public void setExpansionProfile(ExpansionProfile expProfile);
|
||||||
* true, the resource will usually be fetched subsequently
|
|
||||||
*
|
// these are the terminology services used internally by the tools
|
||||||
* @param class_
|
/**
|
||||||
* @param uri
|
* Find the code system definition for the nominated system uri.
|
||||||
* @return
|
* return null if there isn't one (then the tool might try
|
||||||
*/
|
* supportsSystem)
|
||||||
public <T extends Resource> boolean hasResource(Class<T> class_, String uri);
|
*
|
||||||
|
* @param system
|
||||||
// -- profile services ---------------------------------------------------------
|
* @return
|
||||||
|
*/
|
||||||
public List<String> getResourceNames();
|
public CodeSystem fetchCodeSystem(String system);
|
||||||
public List<String> getTypeNames();
|
|
||||||
public List<StructureDefinition> allStructures();
|
/**
|
||||||
public List<MetadataResource> allConformanceResources();
|
* True if the underlying terminology service provider will do
|
||||||
|
* expansion and code validation for the terminology. Corresponds
|
||||||
// -- Terminology services ------------------------------------------------------
|
* to the extension
|
||||||
|
*
|
||||||
public ExpansionProfile getExpansionProfile();
|
* http://hl7.org/fhir/StructureDefinition/capabilitystatement-supported-system
|
||||||
public void setExpansionProfile(ExpansionProfile expProfile);
|
*
|
||||||
|
* in the Conformance resource
|
||||||
// these are the terminology services used internally by the tools
|
*
|
||||||
/**
|
* @param system
|
||||||
* Find the code system definition for the nominated system uri.
|
* @return
|
||||||
* return null if there isn't one (then the tool might try
|
* @throws Exception
|
||||||
* supportsSystem)
|
*/
|
||||||
*
|
public boolean supportsSystem(String system) throws TerminologyServiceException;
|
||||||
* @param system
|
|
||||||
* @return
|
/**
|
||||||
*/
|
* find concept maps for a source
|
||||||
public CodeSystem fetchCodeSystem(String system);
|
* @param url
|
||||||
|
* @return
|
||||||
/**
|
*/
|
||||||
* True if the underlying terminology service provider will do
|
public List<ConceptMap> findMapsForSource(String url);
|
||||||
* expansion and code validation for the terminology. Corresponds
|
|
||||||
* to the extension
|
/**
|
||||||
*
|
* ValueSet Expansion - see $expand
|
||||||
* http://hl7.org/fhir/StructureDefinition/capabilitystatement-supported-system
|
*
|
||||||
*
|
* @param source
|
||||||
* in the Conformance resource
|
* @return
|
||||||
*
|
*/
|
||||||
* @param system
|
public ValueSetExpansionOutcome expandVS(ValueSet source, boolean cacheOk, boolean heiarchical);
|
||||||
* @return
|
|
||||||
* @throws Exception
|
/**
|
||||||
*/
|
* Value set expanion inside the internal expansion engine - used
|
||||||
public boolean supportsSystem(String system) throws TerminologyServiceException;
|
* for references to supported system (see "supportsSystem") for
|
||||||
|
* which there is no value set.
|
||||||
/**
|
*
|
||||||
* find concept maps for a source
|
* @param inc
|
||||||
* @param url
|
* @return
|
||||||
* @return
|
* @throws FHIRException
|
||||||
*/
|
*/
|
||||||
public List<ConceptMap> findMapsForSource(String url);
|
public ValueSetExpansionComponent expandVS(ConceptSetComponent inc, boolean heiarchical) throws TerminologyServiceException;
|
||||||
|
|
||||||
/**
|
public class ValidationResult {
|
||||||
* ValueSet Expansion - see $expand
|
private ConceptDefinitionComponent definition;
|
||||||
*
|
private IssueSeverity severity;
|
||||||
* @param source
|
private String message;
|
||||||
* @return
|
private TerminologyServiceErrorClass errorClass;
|
||||||
*/
|
|
||||||
public ValueSetExpansionOutcome expandVS(ValueSet source, boolean cacheOk, boolean heiarchical);
|
public ValidationResult(IssueSeverity severity, String message) {
|
||||||
|
this.severity = severity;
|
||||||
/**
|
this.message = message;
|
||||||
* Value set expanion inside the internal expansion engine - used
|
}
|
||||||
* for references to supported system (see "supportsSystem") for
|
|
||||||
* which there is no value set.
|
public ValidationResult(ConceptDefinitionComponent definition) {
|
||||||
*
|
this.definition = definition;
|
||||||
* @param inc
|
}
|
||||||
* @return
|
|
||||||
* @throws FHIRException
|
public ValidationResult(IssueSeverity severity, String message, ConceptDefinitionComponent definition) {
|
||||||
*/
|
this.severity = severity;
|
||||||
public ValueSetExpansionComponent expandVS(ConceptSetComponent inc, boolean heiarchical) throws TerminologyServiceException;
|
this.message = message;
|
||||||
|
this.definition = definition;
|
||||||
public class ValidationResult {
|
}
|
||||||
private ConceptDefinitionComponent definition;
|
|
||||||
private IssueSeverity severity;
|
public ValidationResult(IssueSeverity severity, String message, TerminologyServiceErrorClass errorClass) {
|
||||||
private String message;
|
this.severity = severity;
|
||||||
private TerminologyServiceErrorClass errorClass;
|
this.message = message;
|
||||||
|
this.errorClass = errorClass;
|
||||||
public ValidationResult(IssueSeverity severity, String message) {
|
}
|
||||||
this.severity = severity;
|
|
||||||
this.message = message;
|
public boolean isOk() {
|
||||||
}
|
return definition != null;
|
||||||
|
}
|
||||||
public ValidationResult(ConceptDefinitionComponent definition) {
|
|
||||||
this.definition = definition;
|
public String getDisplay() {
|
||||||
}
|
// We don't want to return question-marks because that prevents something more useful from being displayed (e.g. the code) if there's no display value
|
||||||
|
// return definition == null ? "??" : definition.getDisplay();
|
||||||
public ValidationResult(IssueSeverity severity, String message, ConceptDefinitionComponent definition) {
|
return definition == null ? null : definition.getDisplay();
|
||||||
this.severity = severity;
|
}
|
||||||
this.message = message;
|
|
||||||
this.definition = definition;
|
public ConceptDefinitionComponent asConceptDefinition() {
|
||||||
}
|
return definition;
|
||||||
|
}
|
||||||
public ValidationResult(IssueSeverity severity, String message, TerminologyServiceErrorClass errorClass) {
|
|
||||||
this.severity = severity;
|
public IssueSeverity getSeverity() {
|
||||||
this.message = message;
|
return severity;
|
||||||
this.errorClass = errorClass;
|
}
|
||||||
}
|
|
||||||
|
public String getMessage() {
|
||||||
public boolean isOk() {
|
return message;
|
||||||
return definition != null;
|
}
|
||||||
}
|
|
||||||
|
public boolean IsNoService() {
|
||||||
public String getDisplay() {
|
return errorClass == TerminologyServiceErrorClass.NOSERVICE;
|
||||||
// We don't want to return question-marks because that prevents something more useful from being displayed (e.g. the code) if there's no display value
|
}
|
||||||
// return definition == null ? "??" : definition.getDisplay();
|
|
||||||
return definition == null ? null : definition.getDisplay();
|
public TerminologyServiceErrorClass getErrorClass() {
|
||||||
}
|
return errorClass;
|
||||||
|
}
|
||||||
public ConceptDefinitionComponent asConceptDefinition() {
|
|
||||||
return definition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IssueSeverity getSeverity() {
|
/**
|
||||||
return severity;
|
* Validation of a code - consult the terminology service
|
||||||
}
|
* to see whether it is known. If known, return a description of it
|
||||||
|
*
|
||||||
public String getMessage() {
|
* note: always return a result, with either an error or a code description
|
||||||
return message;
|
*
|
||||||
}
|
* corresponds to 2 terminology service calls: $validate-code and $lookup
|
||||||
|
*
|
||||||
public boolean IsNoService() {
|
* @param system
|
||||||
return errorClass == TerminologyServiceErrorClass.NOSERVICE;
|
* @param code
|
||||||
}
|
* @param display
|
||||||
|
* @return
|
||||||
public TerminologyServiceErrorClass getErrorClass() {
|
*/
|
||||||
return errorClass;
|
public ValidationResult validateCode(String system, String code, String display);
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Validation of a code - consult the terminology service
|
||||||
}
|
* to see whether it is known. If known, return a description of it
|
||||||
|
* Also, check whether it's in the provided value set
|
||||||
/**
|
*
|
||||||
* Validation of a code - consult the terminology service
|
* note: always return a result, with either an error or a code description, or both (e.g. known code, but not in the value set)
|
||||||
* to see whether it is known. If known, return a description of it
|
*
|
||||||
*
|
* corresponds to 2 terminology service calls: $validate-code and $lookup
|
||||||
* note: always return a result, with either an error or a code description
|
*
|
||||||
*
|
* @param system
|
||||||
* corresponds to 2 terminology service calls: $validate-code and $lookup
|
* @param code
|
||||||
*
|
* @param display
|
||||||
* @param system
|
* @return
|
||||||
* @param code
|
*/
|
||||||
* @param display
|
public ValidationResult validateCode(String system, String code, String display, ValueSet vs);
|
||||||
* @return
|
public ValidationResult validateCode(Coding code, ValueSet vs);
|
||||||
*/
|
public ValidationResult validateCode(CodeableConcept code, ValueSet vs);
|
||||||
public ValidationResult validateCode(String system, String code, String display);
|
|
||||||
|
/**
|
||||||
/**
|
* Validation of a code - consult the terminology service
|
||||||
* Validation of a code - consult the terminology service
|
* to see whether it is known. If known, return a description of it
|
||||||
* to see whether it is known. If known, return a description of it
|
* Also, check whether it's in the provided value set fragment (for supported systems with no value set definition)
|
||||||
* Also, check whether it's in the provided value set
|
*
|
||||||
*
|
* note: always return a result, with either an error or a code description, or both (e.g. known code, but not in the value set)
|
||||||
* note: always return a result, with either an error or a code description, or both (e.g. known code, but not in the value set)
|
*
|
||||||
*
|
* corresponds to 2 terminology service calls: $validate-code and $lookup
|
||||||
* corresponds to 2 terminology service calls: $validate-code and $lookup
|
*
|
||||||
*
|
* @param system
|
||||||
* @param system
|
* @param code
|
||||||
* @param code
|
* @param display
|
||||||
* @param display
|
* @return
|
||||||
* @return
|
*/
|
||||||
*/
|
public ValidationResult validateCode(String system, String code, String display, ConceptSetComponent vsi);
|
||||||
public ValidationResult validateCode(String system, String code, String display, ValueSet vs);
|
|
||||||
public ValidationResult validateCode(Coding code, ValueSet vs);
|
/**
|
||||||
public ValidationResult validateCode(CodeableConcept code, ValueSet vs);
|
* returns the recommended tla for the type
|
||||||
|
*
|
||||||
/**
|
* @param name
|
||||||
* Validation of a code - consult the terminology service
|
* @return
|
||||||
* to see whether it is known. If known, return a description of it
|
*/
|
||||||
* Also, check whether it's in the provided value set fragment (for supported systems with no value set definition)
|
public String getAbbreviation(String name);
|
||||||
*
|
|
||||||
* note: always return a result, with either an error or a code description, or both (e.g. known code, but not in the value set)
|
// return a set of types that have tails
|
||||||
*
|
public Set<String> typeTails();
|
||||||
* corresponds to 2 terminology service calls: $validate-code and $lookup
|
|
||||||
*
|
public String oid2Uri(String code);
|
||||||
* @param system
|
|
||||||
* @param code
|
public boolean hasCache();
|
||||||
* @param display
|
|
||||||
* @return
|
public interface ILoggingService {
|
||||||
*/
|
public enum LogCategory {
|
||||||
public ValidationResult validateCode(String system, String code, String display, ConceptSetComponent vsi);
|
PROGRESS, TX, INIT, CONTEXT, HTML
|
||||||
|
}
|
||||||
/**
|
public void logMessage(String message); // status messages, always display
|
||||||
* returns the recommended tla for the type
|
public void logDebugMessage(LogCategory category, String message); // verbose; only when debugging
|
||||||
*
|
}
|
||||||
* @param name
|
|
||||||
* @return
|
public void setLogger(ILoggingService logger);
|
||||||
*/
|
|
||||||
public String getAbbreviation(String name);
|
public boolean isNoTerminologyServer();
|
||||||
|
|
||||||
// return a set of types that have tails
|
}
|
||||||
public Set<String> typeTails();
|
|
||||||
|
|
||||||
public String oid2Uri(String code);
|
|
||||||
|
|
||||||
public boolean hasCache();
|
|
||||||
|
|
||||||
public interface ILoggingService {
|
|
||||||
public enum LogCategory {
|
|
||||||
PROGRESS, TX, INIT, CONTEXT, HTML
|
|
||||||
}
|
|
||||||
public void logMessage(String message); // status messages, always display
|
|
||||||
public void logDebugMessage(LogCategory category, String message); // verbose; only when debugging
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLogger(ILoggingService logger);
|
|
||||||
|
|
||||||
public boolean isNoTerminologyServer();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ import org.hl7.fhir.dstu3.terminologies.ValueSetExpander;
|
||||||
import org.hl7.fhir.dstu3.terminologies.ValueSetExpanderFactory;
|
import org.hl7.fhir.dstu3.terminologies.ValueSetExpanderFactory;
|
||||||
import org.hl7.fhir.dstu3.terminologies.ValueSetExpanderSimple;
|
import org.hl7.fhir.dstu3.terminologies.ValueSetExpanderSimple;
|
||||||
import org.hl7.fhir.dstu3.utils.INarrativeGenerator;
|
import org.hl7.fhir.dstu3.utils.INarrativeGenerator;
|
||||||
import org.hl7.fhir.dstu3.utils.IResourceValidator;
|
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||||
|
@ -124,10 +123,6 @@ public final class HapiWorkerContext implements IWorkerContext, ValueSetExpander
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IResourceValidator newValidator() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IParser newXmlParser() {
|
public IParser newXmlParser() {
|
||||||
|
@ -204,8 +199,8 @@ public final class HapiWorkerContext implements IWorkerContext, ValueSetExpander
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
boolean caseSensitive = true;
|
boolean caseSensitive = true;
|
||||||
if (isNotBlank(theSystem)) {
|
if (isNotBlank(theSystem)) {
|
||||||
CodeSystem system = fetchCodeSystem(theSystem);
|
CodeSystem system = fetchCodeSystem(theSystem);
|
||||||
|
|
|
@ -1,174 +0,0 @@
|
||||||
package org.hl7.fhir.dstu3.utils;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.hl7.fhir.dstu3.elementmodel.Element;
|
|
||||||
import org.hl7.fhir.dstu3.elementmodel.Manager.FhirFormat;
|
|
||||||
import org.hl7.fhir.dstu3.model.StructureDefinition;
|
|
||||||
import org.hl7.fhir.dstu3.utils.IResourceValidator.ReferenceValidationPolicy;
|
|
||||||
import org.hl7.fhir.exceptions.DefinitionException;
|
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface to the instance validator. This takes a resource, in one of many forms, and
|
|
||||||
* checks whether it is valid
|
|
||||||
*
|
|
||||||
* @author Grahame Grieve
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface IResourceValidator {
|
|
||||||
|
|
||||||
public enum ReferenceValidationPolicy {
|
|
||||||
IGNORE, CHECK_TYPE_IF_EXISTS, CHECK_EXISTS, CHECK_EXISTS_AND_TYPE, CHECK_VALID;
|
|
||||||
|
|
||||||
public boolean checkExists() {
|
|
||||||
return this == CHECK_EXISTS_AND_TYPE || this == CHECK_EXISTS || this == CHECK_VALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean checkType() {
|
|
||||||
return this == CHECK_TYPE_IF_EXISTS || this == CHECK_EXISTS_AND_TYPE || this == CHECK_VALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean checkValid() {
|
|
||||||
return this == CHECK_VALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IValidatorResourceFetcher {
|
|
||||||
Element fetch(Object appContext, String url) throws FHIRFormatError, DefinitionException, IOException, FHIRException;
|
|
||||||
ReferenceValidationPolicy validationPolicy(Object appContext, String path, String url);
|
|
||||||
boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum BestPracticeWarningLevel {
|
|
||||||
Ignore,
|
|
||||||
Hint,
|
|
||||||
Warning,
|
|
||||||
Error
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum CheckDisplayOption {
|
|
||||||
Ignore,
|
|
||||||
Check,
|
|
||||||
CheckCaseAndSpace,
|
|
||||||
CheckCase,
|
|
||||||
CheckSpace
|
|
||||||
}
|
|
||||||
|
|
||||||
enum IdStatus {
|
|
||||||
OPTIONAL, REQUIRED, PROHIBITED
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* how much to check displays for coded elements
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
CheckDisplayOption getCheckDisplay();
|
|
||||||
void setCheckDisplay(CheckDisplayOption checkDisplay);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* whether the resource must have an id or not (depends on context)
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
|
|
||||||
IdStatus getResourceIdRule();
|
|
||||||
void setResourceIdRule(IdStatus resourceIdRule);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* whether the validator should enforce best practice guidelines
|
|
||||||
* as defined by various HL7 committees
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
BestPracticeWarningLevel getBasePracticeWarningLevel();
|
|
||||||
IResourceValidator setBestPracticeWarningLevel(BestPracticeWarningLevel value);
|
|
||||||
|
|
||||||
IValidatorResourceFetcher getFetcher();
|
|
||||||
IResourceValidator setFetcher(IValidatorResourceFetcher value);
|
|
||||||
|
|
||||||
boolean isNoBindingMsgSuppressed();
|
|
||||||
IResourceValidator setNoBindingMsgSuppressed(boolean noBindingMsgSuppressed);
|
|
||||||
|
|
||||||
public boolean isNoInvariantChecks();
|
|
||||||
public IResourceValidator setNoInvariantChecks(boolean value) ;
|
|
||||||
|
|
||||||
public boolean isNoTerminologyChecks();
|
|
||||||
public IResourceValidator setNoTerminologyChecks(boolean noTerminologyChecks);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether being unable to resolve a profile in found in Resource.meta.profile or ElementDefinition.type.profile or targetProfile is an error or just a warning
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public boolean isErrorForUnknownProfiles();
|
|
||||||
public void setErrorForUnknownProfiles(boolean errorForUnknownProfiles);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate suite
|
|
||||||
*
|
|
||||||
* you can validate one of the following representations of resources:
|
|
||||||
*
|
|
||||||
* stream - provide a format - this is the preferred choice
|
|
||||||
*
|
|
||||||
* Use one of these two if the content is known to be valid XML/JSON, and already parsed
|
|
||||||
* - a DOM element or Document
|
|
||||||
* - a Json Object
|
|
||||||
*
|
|
||||||
* In order to use these, the content must already be parsed - e.g. it must syntactically valid
|
|
||||||
* - a native resource
|
|
||||||
* - a elementmodel resource
|
|
||||||
*
|
|
||||||
* in addition, you can pass one or more profiles ti validate beyond the base standard - as structure definitions or canonical URLs
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
void validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.dstu3.elementmodel.Element element) throws FHIRException, IOException;
|
|
||||||
void validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.dstu3.elementmodel.Element element, ValidationProfileSet profiles) throws FHIRException, IOException;
|
|
||||||
@Deprecated
|
|
||||||
void validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.dstu3.elementmodel.Element element, String profile) throws FHIRException, IOException;
|
|
||||||
@Deprecated
|
|
||||||
void validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.dstu3.elementmodel.Element element, StructureDefinition profile) throws FHIRException, IOException;
|
|
||||||
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, InputStream stream, FhirFormat format) throws FHIRException, IOException;
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, InputStream stream, FhirFormat format, ValidationProfileSet profiles) throws FHIRException, IOException;
|
|
||||||
@Deprecated
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, InputStream stream, FhirFormat format, String profile) throws FHIRException, IOException;
|
|
||||||
@Deprecated
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, InputStream stream, FhirFormat format, StructureDefinition profile) throws FHIRException, IOException;
|
|
||||||
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.dstu3.model.Resource resource) throws FHIRException, IOException;
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.dstu3.model.Resource resource, ValidationProfileSet profiles) throws FHIRException, IOException;
|
|
||||||
@Deprecated
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.dstu3.model.Resource resource, String profile) throws FHIRException, IOException;
|
|
||||||
@Deprecated
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.hl7.fhir.dstu3.model.Resource resource, StructureDefinition profile) throws FHIRException, IOException;
|
|
||||||
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Element element) throws FHIRException, IOException;
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Element element, ValidationProfileSet profiles) throws FHIRException, IOException;
|
|
||||||
@Deprecated
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Element element, String profile) throws FHIRException, IOException;
|
|
||||||
@Deprecated
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Element element, StructureDefinition profile) throws FHIRException, IOException;
|
|
||||||
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Document document) throws FHIRException, IOException;
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Document document, ValidationProfileSet profiles) throws FHIRException, IOException;
|
|
||||||
@Deprecated
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Document document, String profile) throws FHIRException, IOException;
|
|
||||||
@Deprecated
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, org.w3c.dom.Document document, StructureDefinition profile) throws FHIRException, IOException;
|
|
||||||
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, JsonObject object) throws FHIRException, IOException;
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, JsonObject object, ValidationProfileSet profiles) throws FHIRException, IOException;
|
|
||||||
@Deprecated
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, JsonObject object, String profile) throws FHIRException, IOException;
|
|
||||||
@Deprecated
|
|
||||||
org.hl7.fhir.dstu3.elementmodel.Element validate(Object Context, List<ValidationMessage> errors, JsonObject object, StructureDefinition profile) throws FHIRException, IOException;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -25,6 +25,11 @@
|
||||||
<artifactId>hapi-fhir-utilities</artifactId>
|
<artifactId>hapi-fhir-utilities</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
|
<artifactId>hapi-fhir-converter</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Optional dependencies from RI codebase
|
Optional dependencies from RI codebase
|
||||||
|
@ -105,12 +110,6 @@
|
||||||
<artifactId>woodstox-core-asl</artifactId>
|
<artifactId>woodstox-core-asl</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
|
||||||
<artifactId>hapi-fhir-converter</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-server</artifactId>
|
<artifactId>hapi-fhir-server</artifactId>
|
||||||
|
|
|
@ -1,284 +1,609 @@
|
||||||
package org.hl7.fhir.dstu3.hapi.validation;
|
package org.hl7.fhir.dstu3.hapi.validation;
|
||||||
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.Validate;
|
|
||||||
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
|
|
||||||
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
|
|
||||||
import org.hl7.fhir.dstu3.model.*;
|
|
||||||
import org.hl7.fhir.dstu3.utils.FHIRPathEngine.IEvaluationContext;
|
|
||||||
import org.hl7.fhir.dstu3.utils.IResourceValidator.BestPracticeWarningLevel;
|
|
||||||
import org.hl7.fhir.dstu3.utils.IResourceValidator.IdStatus;
|
|
||||||
import org.hl7.fhir.dstu3.validation.InstanceValidator;
|
|
||||||
import org.hl7.fhir.exceptions.PathEngineException;
|
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.w3c.dom.Element;
|
|
||||||
import org.w3c.dom.NodeList;
|
|
||||||
import org.xml.sax.InputSource;
|
|
||||||
|
|
||||||
import com.google.gson.*;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import ca.uhn.fhir.validation.IValidationContext;
|
import ca.uhn.fhir.validation.IValidationContext;
|
||||||
import ca.uhn.fhir.validation.IValidatorModule;
|
import ca.uhn.fhir.validation.IValidatorModule;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
|
import org.hl7.fhir.convertors.VersionConvertor_30_40;
|
||||||
|
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
|
||||||
|
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
|
||||||
|
import org.hl7.fhir.dstu3.model.*;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
||||||
|
import org.hl7.fhir.r4.context.IWorkerContext;
|
||||||
|
import org.hl7.fhir.r4.formats.IParser;
|
||||||
|
import org.hl7.fhir.r4.formats.ParserType;
|
||||||
|
import org.hl7.fhir.r4.terminologies.ValueSetExpander;
|
||||||
|
import org.hl7.fhir.r4.utils.FHIRPathEngine;
|
||||||
|
import org.hl7.fhir.r4.utils.INarrativeGenerator;
|
||||||
|
import org.hl7.fhir.r4.utils.IResourceValidator;
|
||||||
|
import org.hl7.fhir.r4.utils.IResourceValidator.BestPracticeWarningLevel;
|
||||||
|
import org.hl7.fhir.r4.utils.IResourceValidator.IdStatus;
|
||||||
|
import org.hl7.fhir.r4.validation.InstanceValidator;
|
||||||
|
import org.hl7.fhir.utilities.TranslationServices;
|
||||||
|
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||||
|
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
public class FhirInstanceValidator extends BaseValidatorBridge implements IValidatorModule {
|
public class FhirInstanceValidator extends BaseValidatorBridge implements IValidatorModule {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirInstanceValidator.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirInstanceValidator.class);
|
||||||
|
|
||||||
private boolean myAnyExtensionsAllowed = true;
|
private boolean myAnyExtensionsAllowed = true;
|
||||||
private BestPracticeWarningLevel myBestPracticeWarningLevel;
|
private BestPracticeWarningLevel myBestPracticeWarningLevel;
|
||||||
private DocumentBuilderFactory myDocBuilderFactory;
|
private DocumentBuilderFactory myDocBuilderFactory;
|
||||||
private StructureDefinition myStructureDefintion;
|
private StructureDefinition myStructureDefintion;
|
||||||
private IValidationSupport myValidationSupport;
|
private IValidationSupport myValidationSupport;
|
||||||
private boolean noTerminologyChecks = false;
|
private boolean noTerminologyChecks = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
* <p>
|
||||||
* Uses {@link DefaultProfileValidationSupport} for {@link IValidationSupport validation support}
|
* Uses {@link DefaultProfileValidationSupport} for {@link IValidationSupport validation support}
|
||||||
*/
|
*/
|
||||||
public FhirInstanceValidator() {
|
public FhirInstanceValidator() {
|
||||||
this(new DefaultProfileValidationSupport());
|
this(new DefaultProfileValidationSupport());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor which uses the given validation support
|
* Constructor which uses the given validation support
|
||||||
*
|
*
|
||||||
* @param theValidationSupport
|
* @param theValidationSupport The validation support
|
||||||
* The validation support
|
*/
|
||||||
*/
|
public FhirInstanceValidator(IValidationSupport theValidationSupport) {
|
||||||
public FhirInstanceValidator(IValidationSupport theValidationSupport) {
|
myDocBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||||
myDocBuilderFactory = DocumentBuilderFactory.newInstance();
|
myDocBuilderFactory.setNamespaceAware(true);
|
||||||
myDocBuilderFactory.setNamespaceAware(true);
|
myValidationSupport = theValidationSupport;
|
||||||
myValidationSupport = theValidationSupport;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private String determineResourceName(Document theDocument) {
|
private String determineResourceName(Document theDocument) {
|
||||||
Element root = null;
|
Element root = null;
|
||||||
|
|
||||||
NodeList list = theDocument.getChildNodes();
|
NodeList list = theDocument.getChildNodes();
|
||||||
for (int i = 0; i < list.getLength(); i++) {
|
for (int i = 0; i < list.getLength(); i++) {
|
||||||
if (list.item(i) instanceof Element) {
|
if (list.item(i) instanceof Element) {
|
||||||
root = (Element) list.item(i);
|
root = (Element) list.item(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
root = theDocument.getDocumentElement();
|
root = theDocument.getDocumentElement();
|
||||||
return root.getLocalName();
|
return root.getLocalName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private StructureDefinition findStructureDefinitionForResourceName(final FhirContext theCtx, String resourceName) {
|
private StructureDefinition findStructureDefinitionForResourceName(final FhirContext theCtx, String resourceName) {
|
||||||
String sdName = "http://hl7.org/fhir/StructureDefinition/" + resourceName;
|
String sdName = "http://hl7.org/fhir/StructureDefinition/" + resourceName;
|
||||||
StructureDefinition profile = myStructureDefintion != null ? myStructureDefintion : myValidationSupport.fetchStructureDefinition(theCtx, sdName);
|
StructureDefinition profile = myStructureDefintion != null ? myStructureDefintion : myValidationSupport.fetchStructureDefinition(theCtx, sdName);
|
||||||
return profile;
|
return profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the "best practice" warning level (default is {@link BestPracticeWarningLevel#Hint}).
|
* Returns the "best practice" warning level (default is {@link BestPracticeWarningLevel#Hint}).
|
||||||
* <p>
|
* <p>
|
||||||
* The FHIR Instance Validator has a number of checks for best practices in terms of FHIR usage. If this setting is
|
* The FHIR Instance Validator has a number of checks for best practices in terms of FHIR usage. If this setting is
|
||||||
* set to {@link BestPracticeWarningLevel#Error}, any resource data which does not meet these best practices will be
|
* set to {@link BestPracticeWarningLevel#Error}, any resource data which does not meet these best practices will be
|
||||||
* reported at the ERROR level. If this setting is set to {@link BestPracticeWarningLevel#Ignore}, best practice
|
* reported at the ERROR level. If this setting is set to {@link BestPracticeWarningLevel#Ignore}, best practice
|
||||||
* guielines will be ignored.
|
* guielines will be ignored.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @see {@link #setBestPracticeWarningLevel(BestPracticeWarningLevel)}
|
* @see {@link #setBestPracticeWarningLevel(BestPracticeWarningLevel)}
|
||||||
*/
|
*/
|
||||||
public BestPracticeWarningLevel getBestPracticeWarningLevel() {
|
public BestPracticeWarningLevel getBestPracticeWarningLevel() {
|
||||||
return myBestPracticeWarningLevel;
|
return myBestPracticeWarningLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link IValidationSupport validation support} in use by this validator. Default is an instance of
|
* Sets the "best practice warning level". When validating, any deviations from best practices will be reported at
|
||||||
* {@link DefaultProfileValidationSupport} if the no-arguments constructor for this object was used.
|
* this level.
|
||||||
*/
|
* <p>
|
||||||
public IValidationSupport getValidationSupport() {
|
* The FHIR Instance Validator has a number of checks for best practices in terms of FHIR usage. If this setting is
|
||||||
return myValidationSupport;
|
* set to {@link BestPracticeWarningLevel#Error}, any resource data which does not meet these best practices will be
|
||||||
}
|
* reported at the ERROR level. If this setting is set to {@link BestPracticeWarningLevel#Ignore}, best practice
|
||||||
|
* guielines will be ignored.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param theBestPracticeWarningLevel The level, must not be <code>null</code>
|
||||||
|
*/
|
||||||
|
public void setBestPracticeWarningLevel(BestPracticeWarningLevel theBestPracticeWarningLevel) {
|
||||||
|
Validate.notNull(theBestPracticeWarningLevel);
|
||||||
|
myBestPracticeWarningLevel = theBestPracticeWarningLevel;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to {@literal true} (default is true) extensions which are not known to the
|
* Returns the {@link IValidationSupport validation support} in use by this validator. Default is an instance of
|
||||||
* validator (e.g. because they have not been explicitly declared in a profile) will
|
* {@link DefaultProfileValidationSupport} if the no-arguments constructor for this object was used.
|
||||||
* be validated but will not cause an error.
|
*/
|
||||||
*/
|
public IValidationSupport getValidationSupport() {
|
||||||
public boolean isAnyExtensionsAllowed() {
|
return myValidationSupport;
|
||||||
return myAnyExtensionsAllowed;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to {@literal true} (default is true) extensions which are not known to the
|
* Sets the {@link IValidationSupport validation support} in use by this validator. Default is an instance of
|
||||||
* validator (e.g. because they have not been explicitly declared in a profile) will
|
* {@link DefaultProfileValidationSupport} if the no-arguments constructor for this object was used.
|
||||||
* be validated but will not cause an error.
|
*/
|
||||||
*/
|
public void setValidationSupport(IValidationSupport theValidationSupport) {
|
||||||
public void setAnyExtensionsAllowed(boolean theAnyExtensionsAllowed) {
|
myValidationSupport = theValidationSupport;
|
||||||
myAnyExtensionsAllowed = theAnyExtensionsAllowed;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to {@literal true} (default is false) the valueSet will not be validate
|
* If set to {@literal true} (default is true) extensions which are not known to the
|
||||||
*/
|
* validator (e.g. because they have not been explicitly declared in a profile) will
|
||||||
public boolean isNoTerminologyChecks() {
|
* be validated but will not cause an error.
|
||||||
return noTerminologyChecks;
|
*/
|
||||||
}
|
public boolean isAnyExtensionsAllowed() {
|
||||||
|
return myAnyExtensionsAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to {@literal true} (default is false) the valueSet will not be validate
|
* If set to {@literal true} (default is true) extensions which are not known to the
|
||||||
*/
|
* validator (e.g. because they have not been explicitly declared in a profile) will
|
||||||
public void setNoTerminologyChecks(final boolean theNoTerminologyChecks) {
|
* be validated but will not cause an error.
|
||||||
noTerminologyChecks = theNoTerminologyChecks;
|
*/
|
||||||
}
|
public void setAnyExtensionsAllowed(boolean theAnyExtensionsAllowed) {
|
||||||
|
myAnyExtensionsAllowed = theAnyExtensionsAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the "best practice warning level". When validating, any deviations from best practices will be reported at
|
* If set to {@literal true} (default is false) the valueSet will not be validate
|
||||||
* this level.
|
*/
|
||||||
* <p>
|
public boolean isNoTerminologyChecks() {
|
||||||
* The FHIR Instance Validator has a number of checks for best practices in terms of FHIR usage. If this setting is
|
return noTerminologyChecks;
|
||||||
* set to {@link BestPracticeWarningLevel#Error}, any resource data which does not meet these best practices will be
|
}
|
||||||
* reported at the ERROR level. If this setting is set to {@link BestPracticeWarningLevel#Ignore}, best practice
|
|
||||||
* guielines will be ignored.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param theBestPracticeWarningLevel
|
|
||||||
* The level, must not be <code>null</code>
|
|
||||||
*/
|
|
||||||
public void setBestPracticeWarningLevel(BestPracticeWarningLevel theBestPracticeWarningLevel) {
|
|
||||||
Validate.notNull(theBestPracticeWarningLevel);
|
|
||||||
myBestPracticeWarningLevel = theBestPracticeWarningLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStructureDefintion(StructureDefinition theStructureDefintion) {
|
/**
|
||||||
myStructureDefintion = theStructureDefintion;
|
* If set to {@literal true} (default is false) the valueSet will not be validate
|
||||||
}
|
*/
|
||||||
|
public void setNoTerminologyChecks(final boolean theNoTerminologyChecks) {
|
||||||
|
noTerminologyChecks = theNoTerminologyChecks;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
public void setStructureDefintion(StructureDefinition theStructureDefintion) {
|
||||||
* Sets the {@link IValidationSupport validation support} in use by this validator. Default is an instance of
|
myStructureDefintion = theStructureDefintion;
|
||||||
* {@link DefaultProfileValidationSupport} if the no-arguments constructor for this object was used.
|
}
|
||||||
*/
|
|
||||||
public void setValidationSupport(IValidationSupport theValidationSupport) {
|
|
||||||
myValidationSupport = theValidationSupport;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected List<ValidationMessage> validate(final FhirContext theCtx, String theInput, EncodingEnum theEncoding) {
|
protected List<ValidationMessage> validate(final FhirContext theCtx, String theInput, EncodingEnum theEncoding) {
|
||||||
HapiWorkerContext workerContext = new HapiWorkerContext(theCtx, myValidationSupport);
|
HapiWorkerContext workerContext = new HapiWorkerContext(theCtx, myValidationSupport);
|
||||||
|
WorkerContextWrapper wrappedWorkerContext = new WorkerContextWrapper(workerContext);
|
||||||
|
|
||||||
InstanceValidator v;
|
InstanceValidator v;
|
||||||
IEvaluationContext evaluationCtx = new NullEvaluationContext();
|
FHIRPathEngine.IEvaluationContext evaluationCtx = new org.hl7.fhir.r4.hapi.validation.FhirInstanceValidator.NullEvaluationContext();
|
||||||
try {
|
try {
|
||||||
v = new InstanceValidator(workerContext, evaluationCtx);
|
v = new InstanceValidator(wrappedWorkerContext, evaluationCtx);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ConfigurationException(e);
|
throw new ConfigurationException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
v.setBestPracticeWarningLevel(getBestPracticeWarningLevel());
|
v.setBestPracticeWarningLevel(getBestPracticeWarningLevel());
|
||||||
v.setAnyExtensionsAllowed(isAnyExtensionsAllowed());
|
v.setAnyExtensionsAllowed(isAnyExtensionsAllowed());
|
||||||
v.setResourceIdRule(IdStatus.OPTIONAL);
|
v.setResourceIdRule(IdStatus.OPTIONAL);
|
||||||
v.setNoTerminologyChecks(isNoTerminologyChecks());
|
v.setNoTerminologyChecks(isNoTerminologyChecks());
|
||||||
|
|
||||||
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
|
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
|
||||||
|
|
||||||
if (theEncoding == EncodingEnum.XML) {
|
if (theEncoding == EncodingEnum.XML) {
|
||||||
Document document;
|
Document document;
|
||||||
try {
|
try {
|
||||||
DocumentBuilder builder = myDocBuilderFactory.newDocumentBuilder();
|
DocumentBuilder builder = myDocBuilderFactory.newDocumentBuilder();
|
||||||
InputSource src = new InputSource(new StringReader(theInput));
|
InputSource src = new InputSource(new StringReader(theInput));
|
||||||
document = builder.parse(src);
|
document = builder.parse(src);
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
ourLog.error("Failure to parse XML input", e2);
|
ourLog.error("Failure to parse XML input", e2);
|
||||||
ValidationMessage m = new ValidationMessage();
|
ValidationMessage m = new ValidationMessage();
|
||||||
m.setLevel(IssueSeverity.FATAL);
|
m.setLevel(IssueSeverity.FATAL);
|
||||||
m.setMessage("Failed to parse input, it does not appear to be valid XML:" + e2.getMessage());
|
m.setMessage("Failed to parse input, it does not appear to be valid XML:" + e2.getMessage());
|
||||||
return Collections.singletonList(m);
|
return Collections.singletonList(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
String resourceName = determineResourceName(document);
|
String resourceName = determineResourceName(document);
|
||||||
StructureDefinition profile = findStructureDefinitionForResourceName(theCtx, resourceName);
|
StructureDefinition profile = findStructureDefinitionForResourceName(theCtx, resourceName);
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
try {
|
try {
|
||||||
v.validate(null, messages, document, profile);
|
v.validate(null, messages, document, profile.getUrl());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new InternalErrorException("Unexpected failure while validating resource", e);
|
throw new InternalErrorException("Unexpected failure while validating resource", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (theEncoding == EncodingEnum.JSON) {
|
} else if (theEncoding == EncodingEnum.JSON) {
|
||||||
Gson gson = new GsonBuilder().create();
|
Gson gson = new GsonBuilder().create();
|
||||||
JsonObject json = gson.fromJson(theInput, JsonObject.class);
|
JsonObject json = gson.fromJson(theInput, JsonObject.class);
|
||||||
|
|
||||||
String resourceName = json.get("resourceType").getAsString();
|
String resourceName = json.get("resourceType").getAsString();
|
||||||
StructureDefinition profile = findStructureDefinitionForResourceName(theCtx, resourceName);
|
StructureDefinition profile = findStructureDefinitionForResourceName(theCtx, resourceName);
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
try {
|
try {
|
||||||
v.validate(null, messages, json, profile);
|
v.validate(null, messages, json, profile.getUrl());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new InternalErrorException("Unexpected failure while validating resource", e);
|
throw new InternalErrorException("Unexpected failure while validating resource", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unknown encoding: " + theEncoding);
|
throw new IllegalArgumentException("Unknown encoding: " + theEncoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < messages.size(); i++) {
|
for (int i = 0; i < messages.size(); i++) {
|
||||||
ValidationMessage next = messages.get(i);
|
ValidationMessage next = messages.get(i);
|
||||||
if ("Binding has no source, so can't be checked".equals(next.getMessage())) {
|
if ("Binding has no source, so can't be checked".equals(next.getMessage())) {
|
||||||
messages.remove(i);
|
messages.remove(i);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<ValidationMessage> validate(IValidationContext<?> theCtx) {
|
protected List<ValidationMessage> validate(IValidationContext<?> theCtx) {
|
||||||
return validate(theCtx.getFhirContext(), theCtx.getResourceAsString(), theCtx.getResourceAsStringEncoding());
|
return validate(theCtx.getFhirContext(), theCtx.getResourceAsString(), theCtx.getResourceAsStringEncoding());
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NullEvaluationContext implements IEvaluationContext {
|
|
||||||
|
|
||||||
@Override
|
private class WorkerContextWrapper implements IWorkerContext {
|
||||||
public TypeDetails checkFunction(Object theAppContext, String theFunctionName, List<TypeDetails> theParameters) throws PathEngineException {
|
private final HapiWorkerContext myWrap;
|
||||||
return null;
|
private final VersionConvertor_30_40 myConverter;
|
||||||
}
|
private volatile List<org.hl7.fhir.r4.model.StructureDefinition> myAllStructures;
|
||||||
|
|
||||||
@Override
|
public WorkerContextWrapper(HapiWorkerContext theWorkerContext) {
|
||||||
public List<Base> executeFunction(Object theAppContext, String theFunctionName, List<List<Base>> theParameters) {
|
myWrap = theWorkerContext;
|
||||||
return null;
|
myConverter = new VersionConvertor_30_40();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean log(String theArgument, List<Base> theFocus) {
|
public List<org.hl7.fhir.r4.model.MetadataResource> allConformanceResources() {
|
||||||
return false;
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Base resolveConstant(Object theAppContext, String theName) throws PathEngineException {
|
public List<org.hl7.fhir.r4.model.StructureDefinition> allStructures() {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
List<org.hl7.fhir.r4.model.StructureDefinition> retVal = myAllStructures;
|
||||||
public TypeDetails resolveConstantType(Object theAppContext, String theName) throws PathEngineException {
|
if (retVal == null) {
|
||||||
return null;
|
retVal = new ArrayList<>();
|
||||||
}
|
for (StructureDefinition next : myWrap.allStructures()) {
|
||||||
|
try {
|
||||||
|
retVal.add(VersionConvertor_30_40.convertStructureDefinition(next));
|
||||||
|
} catch (FHIRException e) {
|
||||||
|
throw new InternalErrorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myAllStructures = retVal;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
return retVal;
|
||||||
public FunctionDetails resolveFunction(String theFunctionName) {
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Base resolveReference(Object theAppContext, String theUrl) {
|
public void cacheResource(org.hl7.fhir.r4.model.Resource res) throws FHIRException {
|
||||||
return null;
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
private ValidationResult convertValidationResult(org.hl7.fhir.dstu3.context.IWorkerContext.ValidationResult theResult) {
|
||||||
|
IssueSeverity issueSeverity = theResult.getSeverity();
|
||||||
|
String message = theResult.getMessage();
|
||||||
|
org.hl7.fhir.r4.model.CodeSystem.ConceptDefinitionComponent conceptDefinition = null;
|
||||||
|
if (theResult.asConceptDefinition() != null) {
|
||||||
|
try {
|
||||||
|
conceptDefinition = VersionConvertor_30_40.convertConceptDefinitionComponent(theResult.asConceptDefinition());
|
||||||
|
} catch (FHIRException e) {
|
||||||
|
throw new InternalErrorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ValidationResult retVal = new ValidationResult(issueSeverity, message, conceptDefinition);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValueSetExpander.ValueSetExpansionOutcome expandVS(org.hl7.fhir.r4.model.ValueSet source, boolean cacheOk, boolean heiarchical) {
|
||||||
|
ValueSet convertedSource = null;
|
||||||
|
try {
|
||||||
|
convertedSource = VersionConvertor_30_40.convertValueSet(source);
|
||||||
|
} catch (FHIRException e) {
|
||||||
|
throw new InternalErrorException(e);
|
||||||
|
}
|
||||||
|
org.hl7.fhir.dstu3.terminologies.ValueSetExpander.ValueSetExpansionOutcome expanded = myWrap.expandVS(convertedSource, cacheOk, heiarchical);
|
||||||
|
|
||||||
|
org.hl7.fhir.r4.model.ValueSet convertedResult = null;
|
||||||
|
if (expanded.getValueset() != null) {
|
||||||
|
try {
|
||||||
|
convertedResult = VersionConvertor_30_40.convertValueSet(expanded.getValueset());
|
||||||
|
} catch (FHIRException e) {
|
||||||
|
throw new InternalErrorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String error = expanded.getError();
|
||||||
|
ValueSetExpander.TerminologyServiceErrorClass result = null;
|
||||||
|
|
||||||
|
return new ValueSetExpander.ValueSetExpansionOutcome(convertedResult, error, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValueSetExpander.ValueSetExpansionOutcome expandVS(org.hl7.fhir.r4.model.ElementDefinition.ElementDefinitionBindingComponent binding, boolean cacheOk, boolean heiarchical) throws FHIRException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.hl7.fhir.r4.model.ValueSet.ValueSetExpansionComponent expandVS(org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent inc, boolean heirarchical) throws TerminologyServiceException {
|
||||||
|
ValueSet.ConceptSetComponent convertedInc = null;
|
||||||
|
if (inc != null) {
|
||||||
|
try {
|
||||||
|
convertedInc = VersionConvertor_30_40.convertConceptSetComponent(inc);
|
||||||
|
} catch (FHIRException e) {
|
||||||
|
throw new InternalErrorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueSet.ValueSetExpansionComponent expansion = myWrap.expandVS(convertedInc, heirarchical);
|
||||||
|
org.hl7.fhir.r4.model.ValueSet.ValueSetExpansionComponent retVal = null;
|
||||||
|
if (expansion != null) {
|
||||||
|
try {
|
||||||
|
retVal = VersionConvertor_30_40.convertValueSetExpansionComponent(expansion);
|
||||||
|
} catch (FHIRException e) {
|
||||||
|
throw new InternalErrorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.hl7.fhir.r4.model.CodeSystem fetchCodeSystem(String system) {
|
||||||
|
CodeSystem fetched = myWrap.fetchCodeSystem(system);
|
||||||
|
if (fetched == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return VersionConvertor_30_40.convertCodeSystem(fetched);
|
||||||
|
} catch (FHIRException e) {
|
||||||
|
throw new InternalErrorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends org.hl7.fhir.r4.model.Resource> T fetchResource(Class<T> class_, String uri) {
|
||||||
|
org.hl7.fhir.dstu3.model.Resource fetched;
|
||||||
|
switch (class_.getSimpleName()) {
|
||||||
|
case "StructureDefinition":
|
||||||
|
fetched = myWrap.fetchResource(StructureDefinition.class, uri);
|
||||||
|
break;
|
||||||
|
case "ValueSet":
|
||||||
|
fetched = myWrap.fetchResource(ValueSet.class, uri);
|
||||||
|
break;
|
||||||
|
case "CodeSystem":
|
||||||
|
fetched = myWrap.fetchResource(CodeSystem.class, uri);
|
||||||
|
break;
|
||||||
|
case "Questionnaire":
|
||||||
|
fetched = myWrap.fetchResource(Questionnaire.class, uri);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Don't know how to fetch " + class_.getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fetched == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return (T) VersionConvertor_30_40.convertResource(fetched);
|
||||||
|
} catch (FHIRException e) {
|
||||||
|
throw new InternalErrorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.hl7.fhir.r4.model.Resource fetchResourceById(String type, String uri) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends org.hl7.fhir.r4.model.Resource> T fetchResourceWithException(Class<T> class_, String uri) throws FHIRException {
|
||||||
|
T retVal = fetchResource(class_, uri);
|
||||||
|
if (retVal == null) {
|
||||||
|
throw new FHIRException("Can not find resource of type " + class_.getSimpleName() + " with uri " + uri);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<org.hl7.fhir.r4.model.ConceptMap> findMapsForSource(String url) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAbbreviation(String name) {
|
||||||
|
return myWrap.getAbbreviation(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VersionConvertor_30_40 getConverter() {
|
||||||
|
return myConverter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.hl7.fhir.r4.model.ExpansionProfile getExpansionProfile() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setExpansionProfile(org.hl7.fhir.r4.model.ExpansionProfile expProfile) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public INarrativeGenerator getNarrativeGenerator(String prefix, String basePath) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IParser getParser(ParserType type) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IParser getParser(String type) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getResourceNames() {
|
||||||
|
return myWrap.getResourceNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getResourceNamesAsSet() {
|
||||||
|
return new HashSet<>(myWrap.getResourceNames());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getTypeNames() {
|
||||||
|
return myWrap.getTypeNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVersion() {
|
||||||
|
return myWrap.getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasCache() {
|
||||||
|
return myWrap.hasCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends org.hl7.fhir.r4.model.Resource> boolean hasResource(Class<T> class_, String uri) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNoTerminologyServer() {
|
||||||
|
return myWrap.isNoTerminologyServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IParser newJsonParser() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IResourceValidator newValidator() throws FHIRException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IParser newXmlParser() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String oid2Uri(String code) {
|
||||||
|
return myWrap.oid2Uri(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLogger(ILoggingService logger) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsSystem(String system) throws TerminologyServiceException {
|
||||||
|
return myWrap.supportsSystem(system);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TranslationServices translator() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> typeTails() {
|
||||||
|
return myWrap.typeTails();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValidationResult validateCode(String system, String code, String display) {
|
||||||
|
org.hl7.fhir.dstu3.context.IWorkerContext.ValidationResult result = myWrap.validateCode(system, code, display);
|
||||||
|
return convertValidationResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValidationResult validateCode(String system, String code, String display, org.hl7.fhir.r4.model.ValueSet vs) {
|
||||||
|
ValueSet convertedVs = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (vs != null) {
|
||||||
|
convertedVs = VersionConvertor_30_40.convertValueSet(vs);
|
||||||
|
}
|
||||||
|
} catch (FHIRException e) {
|
||||||
|
throw new InternalErrorException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
org.hl7.fhir.dstu3.context.IWorkerContext.ValidationResult result = myWrap.validateCode(system, code, display, convertedVs);
|
||||||
|
return convertValidationResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValidationResult validateCode(org.hl7.fhir.r4.model.Coding code, org.hl7.fhir.r4.model.ValueSet vs) {
|
||||||
|
Coding convertedCode = null;
|
||||||
|
ValueSet convertedVs = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (code != null) {
|
||||||
|
convertedCode = VersionConvertor_30_40.convertCoding(code);
|
||||||
|
}
|
||||||
|
if (vs != null) {
|
||||||
|
convertedVs = VersionConvertor_30_40.convertValueSet(vs);
|
||||||
|
}
|
||||||
|
} catch (FHIRException e) {
|
||||||
|
throw new InternalErrorException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
org.hl7.fhir.dstu3.context.IWorkerContext.ValidationResult result = myWrap.validateCode(convertedCode, convertedVs);
|
||||||
|
return convertValidationResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValidationResult validateCode(org.hl7.fhir.r4.model.CodeableConcept code, org.hl7.fhir.r4.model.ValueSet vs) {
|
||||||
|
CodeableConcept convertedCode = null;
|
||||||
|
ValueSet convertedVs = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (code != null) {
|
||||||
|
convertedCode = VersionConvertor_30_40.convertCodeableConcept(code);
|
||||||
|
}
|
||||||
|
if (vs != null) {
|
||||||
|
convertedVs = VersionConvertor_30_40.convertValueSet(vs);
|
||||||
|
}
|
||||||
|
} catch (FHIRException e) {
|
||||||
|
throw new InternalErrorException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
org.hl7.fhir.dstu3.context.IWorkerContext.ValidationResult result = myWrap.validateCode(convertedCode, convertedVs);
|
||||||
|
return convertValidationResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValidationResult validateCode(String system, String code, String display, org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent vsi) {
|
||||||
|
ValueSet.ConceptSetComponent conceptSetComponent = null;
|
||||||
|
if (vsi != null) {
|
||||||
|
try {
|
||||||
|
conceptSetComponent = VersionConvertor_30_40.convertConceptSetComponent(vsi);
|
||||||
|
} catch (FHIRException e) {
|
||||||
|
throw new InternalErrorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
org.hl7.fhir.dstu3.context.IWorkerContext.ValidationResult result = myWrap.validateCode(system, code, display, conceptSetComponent);
|
||||||
|
return convertValidationResult(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -241,7 +241,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
|
||||||
return validate(theCtx.getFhirContext(), theCtx.getResourceAsString(), theCtx.getResourceAsStringEncoding());
|
return validate(theCtx.getFhirContext(), theCtx.getResourceAsString(), theCtx.getResourceAsStringEncoding());
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NullEvaluationContext implements IEvaluationContext {
|
public static class NullEvaluationContext implements IEvaluationContext {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeDetails checkFunction(Object theAppContext, String theFunctionName, List<TypeDetails> theParameters) throws PathEngineException {
|
public TypeDetails checkFunction(Object theAppContext, String theFunctionName, List<TypeDetails> theParameters) throws PathEngineException {
|
||||||
|
|
|
@ -286,7 +286,6 @@ public class ResponseValidatingInterceptorDstu3Test {
|
||||||
* Ignored until #264 is fixed
|
* Ignored until #264 is fixed
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testSearchJsonInvalidNoValidatorsSpecified() throws Exception {
|
public void testSearchJsonInvalidNoValidatorsSpecified() throws Exception {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setValue("002");
|
patient.addIdentifier().setValue("002");
|
||||||
|
@ -305,7 +304,6 @@ public class ResponseValidatingInterceptorDstu3Test {
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
Assert.assertEquals(422, status.getStatusLine().getStatusCode());
|
Assert.assertEquals(422, status.getStatusLine().getStatusCode());
|
||||||
Assert.assertThat(status.toString(), Matchers.containsString("X-FHIR-Response-Validation"));
|
|
||||||
Assert.assertThat(responseContent, Matchers.containsString("<severity value=\"error\"/>"));
|
Assert.assertThat(responseContent, Matchers.containsString("<severity value=\"error\"/>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,7 +382,6 @@ public class ResponseValidatingInterceptorDstu3Test {
|
||||||
* Ignored until #264 is fixed
|
* Ignored until #264 is fixed
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testSearchXmlInvalidNoValidatorsSpecified() throws Exception {
|
public void testSearchXmlInvalidNoValidatorsSpecified() throws Exception {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setValue("002");
|
patient.addIdentifier().setValue("002");
|
||||||
|
@ -403,7 +400,7 @@ public class ResponseValidatingInterceptorDstu3Test {
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
Assert.assertEquals(422, status.getStatusLine().getStatusCode());
|
Assert.assertEquals(422, status.getStatusLine().getStatusCode());
|
||||||
Assert.assertThat(status.toString(), Matchers.containsString("X-FHIR-Response-Validation"));
|
Assert.assertThat(responseContent, Matchers.containsString("<severity value=\"error\"/>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.servlet.ServletHandler;
|
import org.eclipse.jetty.servlet.ServletHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.r4.hapi.validation.FhirInstanceValidator;
|
import org.hl7.fhir.r4.hapi.validation.FhirInstanceValidator;
|
||||||
import org.hl7.fhir.r4.model.Enumerations.AdministrativeGender;
|
import org.hl7.fhir.r4.model.Enumerations.AdministrativeGender;
|
||||||
|
@ -283,7 +284,6 @@ public class ResponseValidatingInterceptorR4Test {
|
||||||
* Ignored until #264 is fixed
|
* Ignored until #264 is fixed
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testSearchJsonInvalidNoValidatorsSpecified() throws Exception {
|
public void testSearchJsonInvalidNoValidatorsSpecified() throws Exception {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setValue("002");
|
patient.addIdentifier().setValue("002");
|
||||||
|
@ -302,7 +302,6 @@ public class ResponseValidatingInterceptorR4Test {
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
assertEquals(422, status.getStatusLine().getStatusCode());
|
assertEquals(422, status.getStatusLine().getStatusCode());
|
||||||
assertThat(status.toString(), containsString("X-FHIR-Response-Validation"));
|
|
||||||
assertThat(responseContent, containsString("<severity value=\"error\"/>"));
|
assertThat(responseContent, containsString("<severity value=\"error\"/>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,7 +380,6 @@ public class ResponseValidatingInterceptorR4Test {
|
||||||
* Ignored until #264 is fixed
|
* Ignored until #264 is fixed
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testSearchXmlInvalidNoValidatorsSpecified() throws Exception {
|
public void testSearchXmlInvalidNoValidatorsSpecified() throws Exception {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setValue("002");
|
patient.addIdentifier().setValue("002");
|
||||||
|
@ -400,7 +398,7 @@ public class ResponseValidatingInterceptorR4Test {
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
assertEquals(422, status.getStatusLine().getStatusCode());
|
assertEquals(422, status.getStatusLine().getStatusCode());
|
||||||
assertThat(status.toString(), containsString("X-FHIR-Response-Validation"));
|
Assert.assertThat(responseContent, Matchers.containsString("<severity value=\"error\"/>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -506,12 +506,11 @@ public class FhirInstanceValidatorDstu3Test {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidateRawXmlResourceWithEmptyPrimitive() {
|
public void testValidateRawXmlResourceWithEmptyPrimitive() {
|
||||||
// @formatter:off
|
|
||||||
String input = "<Patient xmlns=\"http://hl7.org/fhir\"><name><given/></name></Patient>";
|
String input = "<Patient xmlns=\"http://hl7.org/fhir\"><name><given/></name></Patient>";
|
||||||
// @formatter:on
|
|
||||||
|
|
||||||
ValidationResult output = myVal.validateWithResult(input);
|
ValidationResult output = myVal.validateWithResult(input);
|
||||||
assertEquals(output.toString(), 2, output.getMessages().size());
|
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(output.toOperationOutcome()));
|
||||||
|
assertEquals(output.toString(), 3, output.getMessages().size());
|
||||||
assertThat(output.getMessages().get(0).getMessage(), containsString("Element must have some content"));
|
assertThat(output.getMessages().get(0).getMessage(), containsString("Element must have some content"));
|
||||||
assertThat(output.getMessages().get(1).getMessage(), containsString("primitive types must have a value or must have child extensions"));
|
assertThat(output.getMessages().get(1).getMessage(), containsString("primitive types must have a value or must have child extensions"));
|
||||||
}
|
}
|
||||||
|
@ -677,7 +676,7 @@ public class FhirInstanceValidatorDstu3Test {
|
||||||
List<SingleValidationMessage> errors = logResultsAndReturnNonInformationalOnes(output);
|
List<SingleValidationMessage> errors = logResultsAndReturnNonInformationalOnes(output);
|
||||||
|
|
||||||
assertThat(errors.toString(), containsString("Element 'Observation.subject': minimum required = 1, but only found 0"));
|
assertThat(errors.toString(), containsString("Element 'Observation.subject': minimum required = 1, but only found 0"));
|
||||||
assertThat(errors.toString(), containsString("Element 'Observation.context: max allowed = 0, but found 1"));
|
assertThat(errors.toString(), containsString("Element 'Observation.context': max allowed = 0, but found 1"));
|
||||||
assertThat(errors.toString(), containsString("Element 'Observation.device': minimum required = 1, but only found 0"));
|
assertThat(errors.toString(), containsString("Element 'Observation.device': minimum required = 1, but only found 0"));
|
||||||
assertThat(errors.toString(), containsString(""));
|
assertThat(errors.toString(), containsString(""));
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,7 @@ public class QuestionnaireResponseValidatorDstu3Test {
|
||||||
ValidationResult errors = myVal.validateWithResult(qa);
|
ValidationResult errors = myVal.validateWithResult(qa);
|
||||||
|
|
||||||
ourLog.info(errors.toString());
|
ourLog.info(errors.toString());
|
||||||
assertThat(errors.toString(), containsString("minimum required = 1, but only found 0 - QuestionnaireResponse.item"));
|
assertThat(errors.toString(), containsString("No LinkId, so can't be validated"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -287,7 +287,6 @@ public class ResourceValidatorDstu3Test {
|
||||||
* TODO: re-enable this
|
* TODO: re-enable this
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testValidateQuestionnaireWithCanonicalUrl() {
|
public void testValidateQuestionnaireWithCanonicalUrl() {
|
||||||
String input = "{\n" +
|
String input = "{\n" +
|
||||||
" \"resourceType\": \"Questionnaire\",\n" +
|
" \"resourceType\": \"Questionnaire\",\n" +
|
||||||
|
@ -377,16 +376,15 @@ public class ResourceValidatorDstu3Test {
|
||||||
PatientProfileDstu3 myPatient = new PatientProfileDstu3();
|
PatientProfileDstu3 myPatient = new PatientProfileDstu3();
|
||||||
myPatient.setId("1");
|
myPatient.setId("1");
|
||||||
myPatient.setColorPrimary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setCode("furry-grey")));
|
myPatient.setColorPrimary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setCode("furry-grey")));
|
||||||
myPatient.setColorSecondary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setSystem("furry-white")));
|
myPatient.setColorSecondary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setCode("furry-white")));
|
||||||
myPatient.setOwningOrganization(new Reference("Organization/2.25.79433498044103547197447759549862032393"));
|
myPatient.setOwningOrganization(new Reference("Organization/2.25.79433498044103547197447759549862032393"));
|
||||||
myPatient.addName().setFamily("FamilyName");
|
myPatient.addName().setFamily("FamilyName");
|
||||||
myPatient.addExtension().setUrl("http://foo.com/example").setValue(new StringType("String Extension"));
|
myPatient.addExtension().setUrl("http://foo.com/example").setValue(new StringType("String Extension"));
|
||||||
|
|
||||||
IParser p = ourCtx.newJsonParser().setPrettyPrint(true);
|
IParser p = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||||
String messageString = p.encodeResourceToString(myPatient);
|
String messageString = p.encodeResourceToString(myPatient);
|
||||||
ourLog.info(messageString);
|
// ourLog.info(messageString);
|
||||||
|
|
||||||
//@formatter:off
|
|
||||||
assertThat(messageString, stringContainsInOrder(
|
assertThat(messageString, stringContainsInOrder(
|
||||||
"meta",
|
"meta",
|
||||||
"String Extension",
|
"String Extension",
|
||||||
|
@ -399,7 +397,6 @@ public class ResourceValidatorDstu3Test {
|
||||||
"extension",
|
"extension",
|
||||||
"meta"
|
"meta"
|
||||||
)));
|
)));
|
||||||
//@formatter:on
|
|
||||||
|
|
||||||
FhirValidator val = ourCtx.newValidator();
|
FhirValidator val = ourCtx.newValidator();
|
||||||
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
|
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
|
||||||
|
@ -426,7 +423,7 @@ public class ResourceValidatorDstu3Test {
|
||||||
PatientProfileDstu3 myPatient = new PatientProfileDstu3();
|
PatientProfileDstu3 myPatient = new PatientProfileDstu3();
|
||||||
myPatient.setId("1");
|
myPatient.setId("1");
|
||||||
myPatient.setColorPrimary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setCode("furry-grey")));
|
myPatient.setColorPrimary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setCode("furry-grey")));
|
||||||
myPatient.setColorSecondary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setSystem("furry-white")));
|
myPatient.setColorSecondary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setCode("furry-white")));
|
||||||
myPatient.setOwningOrganization(new Reference("Organization/2.25.79433498044103547197447759549862032393"));
|
myPatient.setOwningOrganization(new Reference("Organization/2.25.79433498044103547197447759549862032393"));
|
||||||
myPatient.addName().setFamily("FamilyName");
|
myPatient.addName().setFamily("FamilyName");
|
||||||
myPatient.addExtension().setUrl("http://foo.com/example").setValue(new StringType("String Extension"));
|
myPatient.addExtension().setUrl("http://foo.com/example").setValue(new StringType("String Extension"));
|
||||||
|
|
|
@ -8,20 +8,9 @@
|
||||||
<body>
|
<body>
|
||||||
<release version="3.3.0" date="TBD">
|
<release version="3.3.0" date="TBD">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
The version of a few dependencies have been bumped to the
|
|
||||||
latest versions (dependent HAPI modules listed in brackets):
|
|
||||||
<![CDATA[
|
|
||||||
<ul>
|
|
||||||
<li>Hibernate (JPA): 5.2.10.Final -> 5.2.12.Final</li>
|
|
||||||
<li>Spring (JPA): 5.0.0 -> 5.0.3</li>
|
|
||||||
<li>Thymeleaf (Web Tespage Overlay): 3.0.7.RELEASE -> 3.0.9.RELEASE</li>
|
|
||||||
</ul>
|
|
||||||
]]>
|
|
||||||
</action>
|
|
||||||
<action type="add">
|
|
||||||
This release corrects an inefficiency in the JPA Server, but requires a schema
|
This release corrects an inefficiency in the JPA Server, but requires a schema
|
||||||
change in order to update. Prior to this version of HAPI FHIR, a CLOB column
|
change in order to update. Prior to this version of HAPI FHIR, a CLOB column
|
||||||
containing the complete resource body was stored in two
|
containing the complete resource body was stored in two
|
||||||
tables: HFJ_RESOURCE and HFJ_RES_VER. Because the same content was stored in two
|
tables: HFJ_RESOURCE and HFJ_RES_VER. Because the same content was stored in two
|
||||||
places, the database consumed more space than is needed to.
|
places, the database consumed more space than is needed to.
|
||||||
<![CDATA[<br/><br/>]]>
|
<![CDATA[<br/><br/>]]>
|
||||||
|
@ -32,6 +21,26 @@
|
||||||
set them to nullable if you want an easy means of rolling back). Naturally
|
set them to nullable if you want an easy means of rolling back). Naturally
|
||||||
you should back your database up prior to making this change.
|
you should back your database up prior to making this change.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix">
|
||||||
|
The validation module has been refactored to use the R4 (currently maintained)
|
||||||
|
validator even for DSTU3 validation. This is done by using an automatic
|
||||||
|
converter which converts StructureDefinition/ValueSet/CodeSystem resources
|
||||||
|
which are used as inputs to the validator. This change should fix a number
|
||||||
|
of known issues with the validator, as they have been fixed in R4 but
|
||||||
|
not in DSTU3. This also makes our validator much more maintainable
|
||||||
|
since it is now one codebase.
|
||||||
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
The version of a few dependencies have been bumped to the
|
||||||
|
latest versions (dependent HAPI modules listed in brackets):
|
||||||
|
<![CDATA[
|
||||||
|
<ul>
|
||||||
|
<li>Hibernate (JPA): 5.2.10.Final -> 5.2.12.Final</li>
|
||||||
|
<li>Spring (JPA): 5.0.0 -> 5.0.3</li>
|
||||||
|
<li>Thymeleaf (Web Tespage Overlay): 3.0.7.RELEASE -> 3.0.9.RELEASE</li>
|
||||||
|
</ul>
|
||||||
|
]]>
|
||||||
|
</action>
|
||||||
<action type="fix">
|
<action type="fix">
|
||||||
Fix a crash in the JSON parser when parsing extensions on repeatable
|
Fix a crash in the JSON parser when parsing extensions on repeatable
|
||||||
elements (e.g. Patient.address.line) where there is an extension on the
|
elements (e.g. Patient.address.line) where there is an extension on the
|
||||||
|
|
Loading…
Reference in New Issue