001package ca.uhn.fhir.context.support;
002
003/*
004 * #%L
005 * HAPI FHIR - Core Library
006 * %%
007 * Copyright (C) 2014 - 2018 University Health Network
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 * 
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import ca.uhn.fhir.context.FhirContext;
024import org.hl7.fhir.instance.model.api.IBaseResource;
025
026import java.util.List;
027
028/**
029 * This interface is a version-independent representation of the
030 * various functions that can be provided by validation and terminology
031 * services.
032 * <p>
033 * Implementations are not required to implement all of the functions
034 * in this interface; in fact it is expected that most won't. Any
035 * methods which are not implemented may simply return <code>null</code>
036 * and calling code is expected to be able to handle this.
037 * </p>
038 */
039public interface IContextValidationSupport<EVS_IN, EVS_OUT, SDT, CST, CDCT, IST> {
040
041        /**
042         * Expands the given portion of a ValueSet
043         *
044         * @param theInclude The portion to include
045         * @return The expansion
046         */
047        EVS_OUT expandValueSet(FhirContext theContext, EVS_IN theInclude);
048
049        /**
050         * Load and return all conformance resources associated with this
051         * validation support module. This method may return null if it doesn't
052         * make sense for a given module.
053         */
054        List<IBaseResource> fetchAllConformanceResources(FhirContext theContext);
055
056        /**
057         * Load and return all possible structure definitions
058         */
059        List<SDT> fetchAllStructureDefinitions(FhirContext theContext);
060
061        /**
062         * Fetch a code system by ID
063         *
064         * @param theSystem The code system
065         * @return The valueset (must not be null, but can be an empty ValueSet)
066         */
067        CST fetchCodeSystem(FhirContext theContext, String theSystem);
068
069        /**
070         * Loads a resource needed by the validation (a StructureDefinition, or a
071         * ValueSet)
072         *
073         * @param theContext The HAPI FHIR Context object current in use by the validator
074         * @param theClass   The type of the resource to load
075         * @param theUri     The resource URI
076         * @return Returns the resource, or <code>null</code> if no resource with the
077         * given URI can be found
078         */
079        <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri);
080
081        SDT fetchStructureDefinition(FhirContext theCtx, String theUrl);
082
083        /**
084         * Returns <code>true</code> if codes in the given code system can be expanded
085         * or validated
086         *
087         * @param theSystem The URI for the code system, e.g. <code>"http://loinc.org"</code>
088         * @return Returns <code>true</code> if codes in the given code system can be
089         * validated
090         */
091        boolean isCodeSystemSupported(FhirContext theContext, String theSystem);
092
093        /**
094         * Validates that the given code exists and if possible returns a display
095         * name. This method is called to check codes which are found in "example"
096         * binding fields (e.g. <code>Observation.code</code> in the default profile.
097         *
098         * @param theCodeSystem The code system, e.g. "<code>http://loinc.org</code>"
099         * @param theCode       The code, e.g. "<code>1234-5</code>"
100         * @param theDisplay    The display name, if it should also be validated
101         * @return Returns a validation result object
102         */
103        CodeValidationResult<CDCT, IST> validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay);
104
105        abstract class BaseConceptProperty {
106                private final String myPropertyName;
107
108                /**
109                 * Constructor
110                 */
111                protected BaseConceptProperty(String thePropertyName) {
112                        myPropertyName = thePropertyName;
113                }
114
115                public String getPropertyName() {
116                        return myPropertyName;
117                }
118        }
119
120        class StringConceptProperty extends BaseConceptProperty {
121                private final String myValue;
122
123                /**
124                 * Constructor
125                 *
126                 * @param theName The name
127                 */
128                public StringConceptProperty(String theName, String theValue) {
129                        super(theName);
130                        myValue = theValue;
131                }
132
133                public String getValue() {
134                        return myValue;
135                }
136        }
137
138        class CodingConceptProperty extends BaseConceptProperty {
139                private final String myCode;
140                private final String myCodeSystem;
141                private final String myDisplay;
142
143                /**
144                 * Constructor
145                 *
146                 * @param theName The name
147                 */
148                public CodingConceptProperty(String theName, String theCodeSystem, String theCode, String theDisplay) {
149                        super(theName);
150                        myCodeSystem = theCodeSystem;
151                        myCode = theCode;
152                        myDisplay = theDisplay;
153                }
154
155                public String getCode() {
156                        return myCode;
157                }
158
159                public String getCodeSystem() {
160                        return myCodeSystem;
161                }
162
163                public String getDisplay() {
164                        return myDisplay;
165                }
166        }
167
168        class CodeValidationResult<CDCT, IST> {
169                private CDCT myDefinition;
170                private String myMessage;
171                private IST mySeverity;
172                private String myCodeSystemName;
173                private String myCodeSystemVersion;
174                private List<BaseConceptProperty> myProperties;
175
176                public CodeValidationResult(CDCT theNext) {
177                        this.myDefinition = theNext;
178                }
179
180                public CodeValidationResult(IST severity, String message) {
181                        this.mySeverity = severity;
182                        this.myMessage = message;
183                }
184
185                public CodeValidationResult(IST severity, String message, CDCT definition) {
186                        this.mySeverity = severity;
187                        this.myMessage = message;
188                        this.myDefinition = definition;
189                }
190
191                public CDCT asConceptDefinition() {
192                        return myDefinition;
193                }
194
195                public String getCodeSystemName() {
196                        return myCodeSystemName;
197                }
198
199                public void setCodeSystemName(String theCodeSystemName) {
200                        myCodeSystemName = theCodeSystemName;
201                }
202
203                public String getCodeSystemVersion() {
204                        return myCodeSystemVersion;
205                }
206
207                public void setCodeSystemVersion(String theCodeSystemVersion) {
208                        myCodeSystemVersion = theCodeSystemVersion;
209                }
210
211                public String getMessage() {
212                        return myMessage;
213                }
214
215                public List<BaseConceptProperty> getProperties() {
216                        return myProperties;
217                }
218
219                public void setProperties(List<BaseConceptProperty> theProperties) {
220                        myProperties = theProperties;
221                }
222
223                public IST getSeverity() {
224                        return mySeverity;
225                }
226
227                public boolean isOk() {
228                        return myDefinition != null;
229                }
230
231        }
232
233}