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