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