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