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.Parameters;
043import org.hl7.fhir.r5.model.Resource;
044import org.hl7.fhir.r5.model.TerminologyCapabilities;
045import org.hl7.fhir.r5.model.ValueSet;
046import org.hl7.fhir.r5.terminologies.client.TerminologyClientManager.ITerminologyClientFactory;
047import org.hl7.fhir.r5.utils.client.FHIRToolingClient;
048import org.hl7.fhir.r5.utils.client.network.ClientHeaders;
049import org.hl7.fhir.utilities.FhirPublication;
050import org.hl7.fhir.utilities.ToolingClientLogger;
051import org.hl7.fhir.utilities.Utilities;
052import org.hl7.fhir.utilities.http.HTTPHeader;
053
054public class TerminologyClientR5 implements ITerminologyClient {
055
056  public static class TerminologyClientR5Factory implements ITerminologyClientFactory {
057
058    @Override
059    public ITerminologyClient makeClient(String id, String url, String userAgent, ToolingClientLogger logger) throws URISyntaxException {
060      return new TerminologyClientR5(id, checkEndsWith("/r4", url), userAgent);
061    }
062
063    private String checkEndsWith(String term, String url) {
064      if (url.endsWith(term))
065        return url;
066      if (Utilities.isTxFhirOrgServer(url)) {
067        return Utilities.pathURL(url, term);
068      }
069      return url;
070    }
071
072    @Override
073    public String getVersion() {
074      return "5.0.0";
075    }
076  }
077
078  private final FHIRToolingClient client;
079  private ClientHeaders clientHeaders;
080  private String id;
081
082  public TerminologyClientR5(String id, String address, String userAgent) throws URISyntaxException {
083    this.client = new FHIRToolingClient(address, userAgent);
084    setClientHeaders(new ClientHeaders());
085    this.id = id;
086  }
087
088  @Override
089  public String getId() {
090    return id;
091  }
092
093  public TerminologyClientR5(String id, String address, String userAgent, ClientHeaders clientHeaders) throws URISyntaxException {
094    this.client = new FHIRToolingClient(address, userAgent);
095    setClientHeaders(clientHeaders);
096    this.id = id;
097  }
098
099  public EnumSet<FhirPublication> supportableVersions() {
100    // todo
101    return EnumSet.range(FhirPublication.STU3, FhirPublication.R5);
102  }
103  
104  public void setAllowedVersions(EnumSet<FhirPublication> versions) {
105    // todo
106  }
107  
108  public EnumSet<FhirPublication> getAllowedVersions() {
109    return null; // todo
110  }
111  
112  public FhirPublication getActualVersion() {
113    return FhirPublication.STU3;
114  }
115  
116  
117  @Override
118  public TerminologyCapabilities getTerminologyCapabilities() {
119    return client.getTerminologyCapabilities();
120  }
121
122  @Override
123  public String getAddress() {
124    return client.getAddress();
125  }
126
127  @Override
128  public ValueSet expandValueset(ValueSet vs, Parameters p) {
129    return client.expandValueset(vs, p);
130  }
131
132  @Override
133  public Parameters validateCS(Parameters pin) {
134    return client.operateType(CodeSystem.class, "validate-code", pin);
135  }
136
137  @Override
138  public Parameters subsumes(Parameters pin) {
139    return client.operateType(CodeSystem.class, "subsumes", pin);
140  }
141
142  @Override
143  public Parameters validateVS(Parameters pin) {
144    return client.operateType(ValueSet.class, "validate-code", pin);
145  }
146
147  @Override
148  public ITerminologyClient setTimeoutFactor(int i) {
149    client.setTimeoutFactor(i);
150    return this;
151  }
152
153  @Override
154  public ToolingClientLogger getLogger() {
155    return client.getLogger();
156  }
157  
158  @Override
159  public ITerminologyClient setLogger(ToolingClientLogger txLog) {
160    client.setLogger(txLog);
161    return this;
162  }
163
164  @Override
165  public CapabilityStatement getCapabilitiesStatementQuick() {
166    return client.getCapabilitiesStatementQuick();
167  }
168
169  @Override
170  public CapabilityStatement getCapabilitiesStatement() {
171    return client.getCapabilitiesStatement();
172  }
173
174  @Override
175  public Parameters lookupCode(Map<String, String> params) {
176    return client.lookupCode(params);
177  }
178
179  @Override
180  public Parameters lookupCode(Parameters params) {
181    return client.lookupCode(params);
182  }
183
184  @Override
185  public ITerminologyClient setRetryCount(int retryCount) throws FHIRException {
186    client.setRetryCount(retryCount);
187    return this;
188  }
189
190  @Override
191  public int getRetryCount() throws FHIRException {
192    return client.getRetryCount();
193  }
194
195  @Override
196  public Bundle validateBatch(Bundle batch) {
197    return client.transaction(batch);
198  }
199
200  @Override
201  public CanonicalResource read(String type, String id) {
202    Class<Resource> t;
203    try {
204      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...
205    } catch (ClassNotFoundException e) {
206      throw new FHIRException("Unable to fetch resources of type " + type + " in R5");
207    }
208    org.hl7.fhir.r5.model.Resource r5 = client.read(t, id);
209    if (r5 == null) {
210      throw new FHIRException("Unable to convert resource " + Utilities.pathURL(getAddress(), type, id) + " to R5 (internal representation)");
211    }
212    if (!(r5 instanceof CanonicalResource)) {
213      throw new FHIRException("Unable to convert resource " + Utilities.pathURL(getAddress(), type, id) + " to R5 canonical resource (internal representation)");
214    }
215    return (CanonicalResource) r5;
216  }
217
218  @Override
219  public Iterable<HTTPHeader> getClientHeaders() {
220    return clientHeaders.headers();
221  }
222
223  @Override
224  public ITerminologyClient setClientHeaders(ClientHeaders clientHeaders) {
225    this.clientHeaders = clientHeaders;
226    this.client.setClientHeaders(this.clientHeaders.headers());
227    this.client.setVersionInMimeTypes(true);
228    return this;
229  }
230
231  @Override
232  public ITerminologyClient setUserAgent(String userAgent) {
233    client.setUserAgent(userAgent);
234    return this;
235  }
236
237  @Override
238  public String getUserAgent() {
239    return client.getUserAgent();
240  }
241
242  @Override
243  public String getServerVersion() {
244    return client.getServerVersion();
245  }
246
247  @Override
248  public ITerminologyClient setAcceptLanguage(String lang) {
249    client.setAcceptLanguage(lang);
250    return this;
251  }
252  
253  @Override
254  public ITerminologyClient setContentLanguage(String lang) {
255    client.setContentLanguage(lang);
256    return this;
257  }
258  
259  @Override
260  public int getUseCount() {
261    return client.getUseCount();
262  }
263
264  public static ITerminologyClientFactory factory() {
265    return new TerminologyClientR5Factory();
266  }
267
268  @Override
269  public Bundle search(String type, String criteria) {
270    return client.search(type, criteria);
271  }
272
273  @Override
274  public Parameters translate(Parameters params) throws FHIRException {
275    return client.translate(params);
276  }
277
278  @Override
279  public void setConversionLogger(ITerminologyConversionLogger logger) {
280    // TODO Auto-generated method stub
281    
282  }
283
284
285}