001package org.hl7.fhir.r5.terminologies.client;
002
003import java.net.URISyntaxException;
004import java.util.EnumSet;
005import java.util.Map;
006
007/*
008  Copyright (c) 2011+, HL7, Inc.
009  All rights reserved.
010  
011  Redistribution and use in source and binary forms, with or without modification, 
012  are permitted provided that the following conditions are met:
013    
014   * Redistributions of source code must retain the above copyright notice, this 
015     list of conditions and the following disclaimer.
016   * Redistributions in binary form must reproduce the above copyright notice, 
017     this list of conditions and the following disclaimer in the documentation 
018     and/or other materials provided with the distribution.
019   * Neither the name of HL7 nor the names of its contributors may be used to 
020     endorse or promote products derived from this software without specific 
021     prior written permission.
022  
023  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
024  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
025  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
026  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
027  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
028  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
029  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
030  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
031  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
032  POSSIBILITY OF SUCH DAMAGE.
033  
034 */
035
036
037import org.hl7.fhir.exceptions.FHIRException;
038import org.hl7.fhir.r5.model.Bundle;
039import org.hl7.fhir.r5.model.CanonicalResource;
040import org.hl7.fhir.r5.model.CapabilityStatement;
041import org.hl7.fhir.r5.model.CodeSystem;
042import org.hl7.fhir.r5.model.OperationOutcome;
043import org.hl7.fhir.r5.model.Parameters;
044import org.hl7.fhir.r5.model.Resource;
045import org.hl7.fhir.r5.model.TerminologyCapabilities;
046import org.hl7.fhir.r5.model.ValueSet;
047import org.hl7.fhir.r5.terminologies.client.TerminologyClientManager.ITerminologyClientFactory;
048import org.hl7.fhir.r5.utils.client.FHIRToolingClient;
049import org.hl7.fhir.r5.utils.client.network.ClientHeaders;
050import org.hl7.fhir.utilities.FhirPublication;
051import org.hl7.fhir.utilities.ToolingClientLogger;
052import org.hl7.fhir.utilities.Utilities;
053import org.hl7.fhir.utilities.http.HTTPHeader;
054
055public class TerminologyClientR5 implements ITerminologyClient {
056
057  public static class TerminologyClientR5Factory implements ITerminologyClientFactory {
058
059    @Override
060    public ITerminologyClient makeClient(String id, String url, String userAgent, ToolingClientLogger logger) throws URISyntaxException {
061      return new TerminologyClientR5(id, checkEndsWith("/r4", url), userAgent);
062    }
063
064    private String checkEndsWith(String term, String url) {
065      if (url.endsWith(term))
066        return url;
067      if (Utilities.isTxFhirOrgServer(url)) {
068        return Utilities.pathURL(url, term);
069      }
070      return url;
071    }
072
073    @Override
074    public String getVersion() {
075      return "5.0.0";
076    }
077  }
078
079  private final FHIRToolingClient client;
080  private ClientHeaders clientHeaders;
081  private String id;
082
083  public TerminologyClientR5(String id, String address, String userAgent) throws URISyntaxException {
084    this.client = new FHIRToolingClient(address, userAgent);
085    setClientHeaders(new ClientHeaders());
086    this.id = id;
087  }
088
089  @Override
090  public String getId() {
091    return id;
092  }
093
094  public TerminologyClientR5(String id, String address, String userAgent, ClientHeaders clientHeaders) throws URISyntaxException {
095    this.client = new FHIRToolingClient(address, userAgent);
096    setClientHeaders(clientHeaders);
097    this.id = id;
098  }
099
100  public EnumSet<FhirPublication> supportableVersions() {
101    // todo
102    return EnumSet.range(FhirPublication.STU3, FhirPublication.R5);
103  }
104  
105  public void setAllowedVersions(EnumSet<FhirPublication> versions) {
106    // todo
107  }
108  
109  public EnumSet<FhirPublication> getAllowedVersions() {
110    return null; // todo
111  }
112  
113  public FhirPublication getActualVersion() {
114    return FhirPublication.R5;
115  }
116  
117  
118  @Override
119  public TerminologyCapabilities getTerminologyCapabilities() {
120    return client.getTerminologyCapabilities();
121  }
122
123  @Override
124  public String getAddress() {
125    return client.getAddress();
126  }
127
128  @Override
129  public ValueSet expandValueset(ValueSet vs, Parameters p) {
130    return client.expandValueset(vs, p);
131  }
132
133  @Override
134  public Parameters validateCS(Parameters pin) {
135    return client.operateType(CodeSystem.class, "validate-code", pin);
136  }
137
138  @Override
139  public Parameters subsumes(Parameters pin) {
140    return client.operateType(CodeSystem.class, "subsumes", pin);
141  }
142
143  @Override
144  public Parameters validateVS(Parameters pin) {
145    return client.operateType(ValueSet.class, "validate-code", pin);
146  }
147
148  @Override
149  public ITerminologyClient setTimeoutFactor(int i) {
150    client.setTimeoutFactor(i);
151    return this;
152  }
153
154  @Override
155  public ToolingClientLogger getLogger() {
156    return client.getLogger();
157  }
158  
159  @Override
160  public ITerminologyClient setLogger(ToolingClientLogger txLog) {
161    client.setLogger(txLog);
162    return this;
163  }
164
165  @Override
166  public CapabilityStatement getCapabilitiesStatementQuick() {
167    return client.getCapabilitiesStatementQuick();
168  }
169
170  @Override
171  public CapabilityStatement getCapabilitiesStatement() {
172    return client.getCapabilitiesStatement();
173  }
174
175  @Override
176  public Parameters lookupCode(Map<String, String> params) {
177    return client.lookupCode(params);
178  }
179
180  @Override
181  public Parameters lookupCode(Parameters params) {
182    return client.lookupCode(params);
183  }
184
185  @Override
186  public ITerminologyClient setRetryCount(int retryCount) throws FHIRException {
187    client.setRetryCount(retryCount);
188    return this;
189  }
190
191  @Override
192  public int getRetryCount() throws FHIRException {
193    return client.getRetryCount();
194  }
195
196  @Override
197  public Bundle validateBatch(Bundle batch) {
198    return client.transaction(batch);
199  }
200
201  @Override
202  public CanonicalResource read(String type, String id) {
203    Class<Resource> t;
204    try {
205      t = (Class<Resource>) Class.forName("org.hl7.fhir.r5.model." + type);// todo: do we have to deal with any resource renaming? Use cases are limited...
206    } catch (ClassNotFoundException e) {
207      throw new FHIRException("Unable to fetch resources of type " + type + " in R5");
208    }
209    org.hl7.fhir.r5.model.Resource r5 = client.read(t, id);
210    if (r5 == null) {
211      throw new FHIRException("Unable to convert resource " + Utilities.pathURL(getAddress(), type, id) + " to R5 (internal representation)");
212    }
213    if (!(r5 instanceof CanonicalResource)) {
214      throw new FHIRException("Unable to convert resource " + Utilities.pathURL(getAddress(), type, id) + " to R5 canonical resource (internal representation)");
215    }
216    return (CanonicalResource) r5;
217  }
218
219  @Override
220  public Iterable<HTTPHeader> getClientHeaders() {
221    return clientHeaders.headers();
222  }
223
224  @Override
225  public ITerminologyClient setClientHeaders(ClientHeaders clientHeaders) {
226    this.clientHeaders = clientHeaders;
227    this.client.setClientHeaders(this.clientHeaders.headers());
228    this.client.setVersionInMimeTypes(true);
229    return this;
230  }
231
232  @Override
233  public ITerminologyClient setUserAgent(String userAgent) {
234    client.setUserAgent(userAgent);
235    return this;
236  }
237
238  @Override
239  public String getUserAgent() {
240    return client.getUserAgent();
241  }
242
243  @Override
244  public String getServerVersion() {
245    return client.getServerVersion();
246  }
247
248  @Override
249  public ITerminologyClient setAcceptLanguage(String lang) {
250    client.setAcceptLanguage(lang);
251    return this;
252  }
253  
254  @Override
255  public ITerminologyClient setContentLanguage(String lang) {
256    client.setContentLanguage(lang);
257    return this;
258  }
259  
260  @Override
261  public int getUseCount() {
262    return client.getUseCount();
263  }
264
265  public static ITerminologyClientFactory factory() {
266    return new TerminologyClientR5Factory();
267  }
268
269  @Override
270  public Bundle search(String type, String criteria) {
271    return client.search(type, criteria);
272  }
273
274  @Override
275  public Parameters translate(Parameters params) throws FHIRException {
276    return client.translate(params);
277  }
278
279  @Override
280  public void setConversionLogger(ITerminologyConversionLogger logger) {
281    // TODO Auto-generated method stub
282    
283  }
284
285  public OperationOutcome validateResource(Resource res) {
286    return client.validate(res, res.getId());
287  }
288}