001package org.hl7.fhir.convertors.txClient;
002
003import java.io.IOException;
004import java.net.URISyntaxException;
005import java.util.EnumSet;
006import java.util.HashMap;
007import java.util.Map;
008
009import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
010import org.hl7.fhir.exceptions.FHIRException;
011import org.hl7.fhir.r4.model.Resource;
012import org.hl7.fhir.r4.utils.client.EFhirClientException;
013import org.hl7.fhir.r4.utils.client.FHIRToolingClient;
014import org.hl7.fhir.r5.model.Bundle;
015import org.hl7.fhir.r5.model.CanonicalResource;
016import org.hl7.fhir.r5.model.CapabilityStatement;
017import org.hl7.fhir.r5.model.OperationOutcome;
018import org.hl7.fhir.r5.model.Parameters;
019import org.hl7.fhir.r5.model.TerminologyCapabilities;
020import org.hl7.fhir.r5.model.ValueSet;
021import org.hl7.fhir.r5.terminologies.client.ITerminologyClient;
022import org.hl7.fhir.r5.utils.client.network.ClientHeaders;
023import org.hl7.fhir.utilities.FhirPublication;
024import org.hl7.fhir.utilities.ToolingClientLogger;
025import org.hl7.fhir.utilities.Utilities;
026
027public class TerminologyClientR4 implements ITerminologyClient {
028
029  private final FHIRToolingClient client; // todo: use the R2 client
030  private ClientHeaders clientHeaders;
031  private String id;
032
033  public TerminologyClientR4(String id, String address, String userAgent) throws URISyntaxException {
034    this.client = new FHIRToolingClient(address, userAgent);
035    setClientHeaders(new ClientHeaders());
036    this.id = id;
037  }
038
039  public TerminologyClientR4(String id, String address, String userAgent, ClientHeaders clientHeaders) throws URISyntaxException {
040    this.client = new FHIRToolingClient(address, userAgent);
041    setClientHeaders(clientHeaders);
042    this.id = id;
043  }
044
045  @Override
046  public String getId() {
047    return id;
048  }
049
050
051
052  public EnumSet<FhirPublication> supportableVersions() {
053    // todo
054    return EnumSet.range(FhirPublication.STU3, FhirPublication.R5);
055  }
056  
057  public void setAllowedVersions(EnumSet<FhirPublication> versions) {
058    // todo
059  }
060  
061  public EnumSet<FhirPublication> getAllowedVersions() {
062    return null; // todo
063  }
064  
065  public FhirPublication getActualVersion() {
066    return FhirPublication.STU3;
067  }
068  
069  
070  @Override
071  public TerminologyCapabilities getTerminologyCapabilities() throws FHIRException {
072    return (TerminologyCapabilities) VersionConvertorFactory_40_50.convertResource(client.getTerminologyCapabilities());
073  }
074
075  @Override
076  public String getAddress() {
077    return client.getAddress();
078  }
079
080  @Override
081  public ValueSet expandValueset(ValueSet vs, Parameters p, Map<String, String> params) throws FHIRException {
082    org.hl7.fhir.r4.model.ValueSet vs2 = vs == null ? null : (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_40_50.convertResource(vs);
083    org.hl7.fhir.r4.model.Parameters p2 = p == null ? null :  (org.hl7.fhir.r4.model.Parameters) VersionConvertorFactory_40_50.convertResource(p);
084    if (params == null) {
085      params = new HashMap<>();
086    }
087    try {
088      vs2 = client.expandValueset(vs2, p2, params); // todo: second parameter
089      return (ValueSet) VersionConvertorFactory_40_50.convertResource(vs2);
090    } catch (org.hl7.fhir.r4.utils.client.EFhirClientException e) {
091      throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getMessage(), 
092          (org.hl7.fhir.r5.model.OperationOutcome) VersionConvertorFactory_40_50.convertResource(e.getServerErrors().get(0)));
093
094    }
095  }
096
097  @Override
098  public Parameters validateCS(Parameters pin) throws FHIRException {
099    try {
100      org.hl7.fhir.r4.model.Parameters p2 = (org.hl7.fhir.r4.model.Parameters) VersionConvertorFactory_40_50.convertResource(pin);
101      p2 = client.operateType(org.hl7.fhir.r4.model.CodeSystem.class, "validate-code", p2);
102      return (Parameters) VersionConvertorFactory_40_50.convertResource(p2);
103    } catch (EFhirClientException e) {
104      if (e.getServerErrors().size() == 1) {
105        OperationOutcome op =  (OperationOutcome) VersionConvertorFactory_40_50.convertResource(e.getServerErrors().get(0));
106        throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getMessage(), op, e);
107      } else {
108        throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getMessage(), e);        
109      }
110    } catch (IOException e) {
111      throw new FHIRException(e);
112    }
113  }
114
115  @Override
116  public Parameters validateVS(Parameters pin) throws FHIRException {
117    try {
118      org.hl7.fhir.r4.model.Parameters p2 = (org.hl7.fhir.r4.model.Parameters) VersionConvertorFactory_40_50.convertResource(pin);
119      p2 = client.operateType(org.hl7.fhir.r4.model.ValueSet.class, "validate-code", p2);
120      return (Parameters) VersionConvertorFactory_40_50.convertResource(p2);
121    } catch (EFhirClientException e) {
122      if (e.getServerErrors().size() == 1) {
123        OperationOutcome op =  (OperationOutcome) VersionConvertorFactory_40_50.convertResource(e.getServerErrors().get(0));
124        throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getMessage(), op, e);
125      } else {
126        throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getMessage(), e);        
127      }
128    } catch (IOException e) {
129      throw new FHIRException(e);
130    }
131  }
132
133  @Override
134  public ITerminologyClient setTimeout(int i) {
135    client.setTimeout(i);
136    return this;
137  }
138
139  @Override
140  public ITerminologyClient setLogger(ToolingClientLogger txLog) {
141    client.setLogger(txLog);
142    return this;
143  }
144
145  @Override
146  public ITerminologyClient setRetryCount(int retryCount) throws FHIRException {
147    client.setRetryCount(retryCount);
148    return this;
149  }
150
151  @Override
152  public CapabilityStatement getCapabilitiesStatementQuick() throws FHIRException {
153    return (CapabilityStatement) VersionConvertorFactory_40_50.convertResource(client.getCapabilitiesStatementQuick());
154  }
155
156  @Override
157  public Parameters lookupCode(Map<String, String> params) throws FHIRException {
158    return (Parameters) VersionConvertorFactory_40_50.convertResource(client.lookupCode(params));
159  }
160
161  @Override
162  public int getRetryCount() throws FHIRException {
163    return client.getRetryCount();
164  }
165
166  @Override
167  public Bundle validateBatch(Bundle batch) {
168    return (Bundle) VersionConvertorFactory_40_50.convertResource(client.transaction((org.hl7.fhir.r4.model.Bundle) VersionConvertorFactory_40_50.convertResource(batch)));
169  }
170
171  @Override
172  public CanonicalResource read(String type, String id) {
173    Class<Resource> t;
174    try {
175      t = (Class<Resource>) Class.forName("org.hl7.fhir.r4.model." + type);// todo: do we have to deal with any resource renaming? Use cases are limited...
176    } catch (ClassNotFoundException e) {
177      throw new FHIRException("Unable to fetch resources of type " + type + " in R2");
178    }
179    org.hl7.fhir.r4.model.Resource r4 = client.read(t, id);
180    if (r4 == null) {
181      throw new FHIRException("Unable to fetch resource " + Utilities.pathURL(getAddress(), type, id));
182    }
183    org.hl7.fhir.r5.model.Resource r5 = VersionConvertorFactory_40_50.convertResource(r4);
184    if (r5 == null) {
185      throw new FHIRException("Unable to convert resource " + Utilities.pathURL(getAddress(), type, id) + " to R5 (internal representation)");
186    }
187    if (!(r5 instanceof CanonicalResource)) {
188      throw new FHIRException("Unable to convert resource " + Utilities.pathURL(getAddress(), type, id) + " to R5 canonical resource (internal representation)");
189    }
190    return (CanonicalResource) r5;
191  }
192
193  @Override
194  public ClientHeaders getClientHeaders() {
195    return clientHeaders;
196  }
197
198  @Override
199  public ITerminologyClient setClientHeaders(ClientHeaders clientHeaders) {
200    this.clientHeaders = clientHeaders;
201    if (this.clientHeaders != null) {
202      this.client.setClientHeaders(this.clientHeaders.headers());
203    }
204    return this;
205  }
206
207  @Override
208  public ITerminologyClient setUserAgent(String userAgent) {
209    client.setUserAgent(userAgent);
210    return this;
211  }
212
213  @Override
214  public String getUserAgent() {
215    return client.getUserAgent();
216  }
217
218  @Override
219  public String getServerVersion() {
220    return client.getServerVersion();
221  }
222
223  @Override
224  public ITerminologyClient setLanguage(String lang) {
225    client.setLanguage(lang);
226    return this;
227  }
228}