001package org.hl7.fhir.dstu3.hapi.validation; 002 003import static org.apache.commons.lang3.StringUtils.isBlank; 004 005import java.util.ArrayList; 006import java.util.HashSet; 007import java.util.List; 008import java.util.Set; 009 010import org.hl7.fhir.dstu3.model.CodeSystem; 011import org.hl7.fhir.dstu3.model.StructureDefinition; 012import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent; 013import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent; 014import org.hl7.fhir.instance.model.api.IBaseResource; 015 016import ca.uhn.fhir.context.FhirContext; 017 018public class ValidationSupportChain implements IValidationSupport { 019 020 private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidationSupportChain.class); 021 022 private List<IValidationSupport> myChain; 023 024 /** 025 * Constructor 026 */ 027 public ValidationSupportChain() { 028 myChain = new ArrayList<IValidationSupport>(); 029 } 030 031 /** 032 * Constructor 033 */ 034 public ValidationSupportChain(IValidationSupport... theValidationSupportModules) { 035 this(); 036 for (IValidationSupport next : theValidationSupportModules) { 037 if (next != null) { 038 myChain.add(next); 039 } 040 } 041 } 042 043 public void addValidationSupport(IValidationSupport theValidationSupport) { 044 myChain.add(theValidationSupport); 045 } 046 047 @Override 048 public ValueSetExpansionComponent expandValueSet(FhirContext theCtx, ConceptSetComponent theInclude) { 049 for (IValidationSupport next : myChain) { 050 if (next.isCodeSystemSupported(theCtx, theInclude.getSystem())) { 051 return next.expandValueSet(theCtx, theInclude); 052 } 053 } 054 return myChain.get(0).expandValueSet(theCtx, theInclude); 055 } 056 057 @Override 058 public CodeSystem fetchCodeSystem(FhirContext theCtx, String theSystem) { 059 for (IValidationSupport next : myChain) { 060 CodeSystem retVal = next.fetchCodeSystem(theCtx, theSystem); 061 if (retVal != null) { 062 return retVal; 063 } 064 } 065 return null; 066 } 067 068 @Override 069 public <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri) { 070 for (IValidationSupport next : myChain) { 071 T retVal = next.fetchResource(theContext, theClass, theUri); 072 if (retVal != null) { 073 return retVal; 074 } 075 } 076 return null; 077 } 078 079 @Override 080 public StructureDefinition fetchStructureDefinition(FhirContext theCtx, String theUrl) { 081 for (IValidationSupport next : myChain) { 082 StructureDefinition retVal = next.fetchStructureDefinition(theCtx, theUrl); 083 if (retVal != null) { 084 return retVal; 085 } 086 } 087 return null; 088 } 089 090 @Override 091 public boolean isCodeSystemSupported(FhirContext theCtx, String theSystem) { 092 for (IValidationSupport next : myChain) { 093 if (next.isCodeSystemSupported(theCtx, theSystem)) { 094 return true; 095 } 096 } 097 return false; 098 } 099 100 @Override 101 public CodeValidationResult validateCode(FhirContext theCtx, String theCodeSystem, String theCode, String theDisplay) { 102 103 ourLog.info("Validating code {} in chain with {} items", theCode, myChain.size()); 104 105 for (IValidationSupport next : myChain) { 106 if (next.isCodeSystemSupported(theCtx, theCodeSystem)) { 107 CodeValidationResult result = next.validateCode(theCtx, theCodeSystem, theCode, theDisplay); 108 ourLog.info("Chain item {} returned outcome {}", next, result.isOk()); 109 return result; 110 } else { 111 ourLog.info("Chain item {} does not support code system {}", next, theCodeSystem); 112 } 113 } 114 return myChain.get(0).validateCode(theCtx, theCodeSystem, theCode, theDisplay); 115 } 116 117 @Override 118 public List<StructureDefinition> fetchAllStructureDefinitions(FhirContext theContext) { 119 ArrayList<StructureDefinition> retVal = new ArrayList<StructureDefinition>(); 120 Set<String> urls= new HashSet<String>(); 121 for (IValidationSupport nextSupport : myChain) { 122 for (StructureDefinition next : nextSupport.fetchAllStructureDefinitions(theContext)) { 123 if (isBlank(next.getUrl()) || urls.add(next.getUrl())) { 124 retVal.add(next); 125 } 126 } 127 } 128 return retVal; 129 } 130 131}