package org.hl7.fhir.instance.hapi.validation; import java.util.List; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.instance.formats.IParser; import org.hl7.fhir.instance.formats.ParserType; import org.hl7.fhir.instance.hapi.validation.IValidationSupport.CodeValidationResult; import org.hl7.fhir.instance.model.CodeableConcept; import org.hl7.fhir.instance.model.Coding; import org.hl7.fhir.instance.model.ConceptMap; import org.hl7.fhir.instance.model.OperationOutcome.IssueSeverity; import org.hl7.fhir.instance.model.Resource; import org.hl7.fhir.instance.model.ValueSet; import org.hl7.fhir.instance.model.ValueSet.ConceptDefinitionComponent; import org.hl7.fhir.instance.model.ValueSet.ConceptReferenceComponent; import org.hl7.fhir.instance.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.instance.model.ValueSet.ValueSetExpansionComponent; import org.hl7.fhir.instance.terminologies.ValueSetExpander; import org.hl7.fhir.instance.terminologies.ValueSetExpanderFactory; import org.hl7.fhir.instance.terminologies.ValueSetExpanderSimple; import org.hl7.fhir.instance.utils.EOperationOutcome; import org.hl7.fhir.instance.utils.INarrativeGenerator; import org.hl7.fhir.instance.utils.IWorkerContext; import org.hl7.fhir.instance.validation.IResourceValidator; import ca.uhn.fhir.context.FhirContext; public final class HapiWorkerContext implements IWorkerContext, ValueSetExpanderFactory, ValueSetExpander { private final FhirContext myCtx; private IValidationSupport myValidationSupport; public HapiWorkerContext(FhirContext theCtx, IValidationSupport theValidationSupport) { myCtx = theCtx; myValidationSupport = theValidationSupport; } @Override public ValueSetExpansionComponent expandVS(ConceptSetComponent theInc) { return myValidationSupport.expandValueSet(myCtx, theInc); } @Override public ValueSet fetchCodeSystem(String theSystem) { if (myValidationSupport == null) { return null; } else { return myValidationSupport.fetchCodeSystem(myCtx, theSystem); } } @Override public <T extends Resource> T fetchResource(Class<T> theClass, String theUri) throws EOperationOutcome, Exception { if (myValidationSupport == null) { return null; } else { return myValidationSupport.fetchResource(myCtx, theClass, theUri); } } @Override public INarrativeGenerator getNarrativeGenerator(String thePrefix, String theBasePath) { throw new UnsupportedOperationException(); } @Override public IParser getParser(ParserType theType) { throw new UnsupportedOperationException(); } @Override public IParser getParser(String theType) { throw new UnsupportedOperationException(); } @Override public <T extends Resource> boolean hasResource(Class<T> theClass_, String theUri) { throw new UnsupportedOperationException(); } @Override public IParser newJsonParser() { throw new UnsupportedOperationException(); } @Override public IResourceValidator newValidator() throws Exception { throw new UnsupportedOperationException(); } @Override public IParser newXmlParser() { throw new UnsupportedOperationException(); } @Override public boolean supportsSystem(String theSystem) { if (myValidationSupport == null) { return false; } else { return myValidationSupport.isCodeSystemSupported(myCtx, theSystem); } } @Override public ValidationResult validateCode(String theSystem, String theCode, String theDisplay) { CodeValidationResult result = myValidationSupport.validateCode(myCtx, theSystem, theCode, theDisplay); if (result == null) { return null; } return new ValidationResult(result.getSeverity(), result.getMessage(), result.asConceptDefinition()); } @Override public ValidationResult validateCode(String theSystem, String theCode, String theDisplay, ConceptSetComponent theVsi) { throw new UnsupportedOperationException(); } @Override public ValidationResult validateCode(String theSystem, String theCode, String theDisplay, ValueSet theVs) { if (theSystem == null || StringUtils.equals(theSystem, theVs.getCodeSystem().getSystem())) { for (ConceptDefinitionComponent next : theVs.getCodeSystem().getConcept()) { ValidationResult retVal = validateCodeSystem(theCode, next); if (retVal != null && retVal.isOk()) { return retVal; } } } for (ConceptSetComponent nextComposeConceptSet : theVs.getCompose().getInclude()) { if (StringUtils.equals(theSystem, nextComposeConceptSet.getSystem())) { for (ConceptReferenceComponent nextComposeCode : nextComposeConceptSet.getConcept()) { ConceptDefinitionComponent conceptDef = new ConceptDefinitionComponent(); conceptDef.setCode(nextComposeCode.getCode()); conceptDef.setDisplay(nextComposeCode.getDisplay()); ValidationResult retVal = validateCodeSystem(theCode, conceptDef); if (retVal != null && retVal.isOk()) { return retVal; } } } } return new ValidationResult(IssueSeverity.ERROR, "Unknown code[" + theCode + "] in system[" + theSystem + "]"); } private ValidationResult validateCodeSystem(String theCode, ConceptDefinitionComponent theConcept) { if (StringUtils.equals(theCode, theConcept.getCode())) { return new ValidationResult(theConcept); } else { for (ConceptDefinitionComponent next : theConcept.getConcept()) { ValidationResult retVal = validateCodeSystem(theCode, next); if (retVal != null && retVal.isOk()) { return retVal; } } return null; } } @Override public ValueSetExpander getExpander() { return this; } @Override public ValueSetExpansionOutcome expand(ValueSet theSource) throws ETooCostly, Exception { ValueSetExpander vse = new ValueSetExpanderSimple(this, this); ValueSetExpansionOutcome vso = vse.expand(theSource); if (vso.getError() != null) { return null; } else { return vso; } } @Override public List<ConceptMap> findMapsForSource(String theUrl) { throw new UnsupportedOperationException(); } @Override public ValueSetExpansionOutcome expandVS(ValueSet theSource, boolean theCacheOk) { throw new UnsupportedOperationException(); } @Override public ValidationResult validateCode(Coding theCode, ValueSet theVs) { String system = theCode.getSystem(); String code = theCode.getCode(); String display = theCode.getDisplay(); return validateCode(system, code, display, theVs); } @Override public ValidationResult validateCode(CodeableConcept theCode, ValueSet theVs) { for (Coding next : theCode.getCoding()) { ValidationResult retVal = validateCode(next, theVs); if (retVal != null && retVal.isOk()) { return retVal; } } return new ValidationResult(null, null); } }