001package org.hl7.fhir.r5.terminologies.client; 002 003import java.io.IOException; 004import java.util.HashMap; 005import java.util.HashSet; 006import java.util.Map; 007import java.util.Set; 008 009import org.hl7.fhir.r5.model.CanonicalResource; 010import org.hl7.fhir.r5.model.CapabilityStatement; 011import org.hl7.fhir.r5.model.TerminologyCapabilities; 012import org.hl7.fhir.r5.model.TerminologyCapabilities.TerminologyCapabilitiesCodeSystemComponent; 013import org.hl7.fhir.r5.model.TerminologyCapabilities.TerminologyCapabilitiesExpansionParameterComponent; 014import org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.TerminologyClientContextUseCount; 015import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache; 016 017public class TerminologyClientContext { 018 public enum TerminologyClientContextUseType { 019 expand, validate, readVS, readCS 020 } 021 public class TerminologyClientContextUseCount { 022 private int expands; 023 private int validates; 024 private int readVS; 025 private int readCS; 026 027 public int getReadVS() { 028 return readVS; 029 } 030 public void setReadVS(int readVS) { 031 this.readVS = readVS; 032 } 033 public int getReadCS() { 034 return readCS; 035 } 036 public void setReadCS(int readCS) { 037 this.readCS = readCS; 038 } 039 public int getExpands() { 040 return expands; 041 } 042 public void setExpands(int expands) { 043 this.expands = expands; 044 } 045 public int getValidates() { 046 return validates; 047 } 048 public void setValidates(int validates) { 049 this.validates = validates; 050 } 051 052 } 053 054 private ITerminologyClient client; 055 private boolean initialised = false; 056 private CapabilityStatement capabilitiesStatementQuick; 057 private TerminologyCapabilities txcaps; 058 private TerminologyCache txCache; 059 060 private Map<String, TerminologyClientContextUseCount> useCounts = new HashMap<>(); 061 private boolean isTxCaching; 062 private final Set<String> cached = new HashSet<>(); 063 private boolean master; 064 private String cacheId; 065 066 protected TerminologyClientContext(ITerminologyClient client, String cacheId, boolean master) { 067 super(); 068 this.client = client; 069 this.cacheId = cacheId; 070 this.master = master; 071 } 072 073 public Map<String, TerminologyClientContextUseCount> getUseCounts() { 074 return useCounts; 075 } 076 077 public boolean isMaster() { 078 return master; 079 } 080 081 public ITerminologyClient getClient() { 082 return client; 083 } 084 085 public void seeUse(Set<String> systems, TerminologyClientContextUseType useType) { 086 for (String s : systems) { 087 seeUse(s, useType); 088 } 089 } 090 091 public void seeUse(String s, TerminologyClientContextUseType useType) { 092 TerminologyClientContextUseCount uc = useCounts.get(s); 093 if (uc == null) { 094 uc = new TerminologyClientContextUseCount(); 095 useCounts.put(s,uc); 096 } 097 switch (useType) { 098 case expand: 099 uc.expands++; 100 break; 101 case readVS: 102 uc.readVS++; 103 break; 104 case readCS: 105 uc.readCS++; 106 break; 107 case validate: 108 uc.validates++; 109 break; 110 default: 111 break; 112 } 113 } 114 115 public TerminologyCapabilities getTxCapabilities() { 116 return txcaps; 117 } 118 119 public void setTxCapabilities(TerminologyCapabilities txcaps) { 120 this.txcaps = txcaps; 121 } 122 123 public Set<String> getCached() { 124 return cached; 125 } 126 127 public boolean alreadyCached(CanonicalResource cr) { 128 return cached.contains(cr.getVUrl()); 129 } 130 131 public void addToCache(CanonicalResource cr) { 132 cached.add(cr.getVUrl()); 133 } 134 135 public String getAddress() { 136 return client.getAddress(); 137 } 138 139 public int getUseCount() { 140 return getClient().getUseCount(); 141 } 142 143 public boolean isTxCaching() { 144 return isTxCaching; 145 } 146 147 public void setTxCaching(boolean isTxCaching) { 148 this.isTxCaching = isTxCaching; 149 } 150 151 public boolean usingCache() { 152 return isTxCaching && cacheId != null; 153 } 154 155 public String getCacheId() { 156 return cacheId; 157 } 158 159 public TerminologyCache getTxCache() { 160 return txCache; 161 } 162 163 public void setTxCache(TerminologyCache txCache) { 164 this.txCache = txCache; 165 } 166 167 public void initialize() throws IOException { 168 if (!initialised) { 169 // we don't cache the quick CS - we want to know that the server is with us. 170 capabilitiesStatementQuick = client.getCapabilitiesStatementQuick(); 171 if (txCache != null && txCache.hasTerminologyCapabilities(getAddress())) { 172 txcaps = txCache.getTerminologyCapabilities(getAddress()); 173 if (txcaps.getSoftware().hasVersion() && !txcaps.getSoftware().getVersion().equals(capabilitiesStatementQuick.getSoftware().getVersion())) { 174 txcaps = null; 175 } 176 } 177 if (txcaps == null) { 178 txcaps = client.getTerminologyCapabilities(); 179 if (txCache != null) { 180 txCache.cacheTerminologyCapabilities(getAddress(), txcaps); 181 } 182 } 183 if (txcaps != null) { 184 for (TerminologyCapabilitiesExpansionParameterComponent t : txcaps.getExpansion().getParameter()) { 185 if ("cache-id".equals(t.getName())) { 186 setTxCaching(true); 187 break; 188 } 189 } 190 } 191 initialised = true; 192 } 193 } 194 195 public boolean supportsSystem(String system) throws IOException { 196 initialize(); 197 for (TerminologyCapabilitiesCodeSystemComponent tccs : txcaps.getCodeSystem()) { 198 if (system.equals(tccs.getUri())) { 199 return true; 200 } 201 } 202 return false; 203 } 204 205 @Override 206 public String toString() { 207 return client.getAddress(); 208 } 209 210 211}