1 package ca.uhn.hl7v2.util;
2
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.FileFilter;
6 import java.io.FileReader;
7 import java.io.FilenameFilter;
8 import java.io.IOException;
9 import java.util.HashMap;
10 import java.util.Map;
11 import java.util.StringTokenizer;
12
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
15
16 import ca.uhn.hl7v2.ErrorCode;
17 import ca.uhn.hl7v2.HL7Exception;
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 public class FileCodeMapper extends CodeMapper {
42
43 private static final Logger log = LoggerFactory.getLogger(FileCodeMapper.class);
44
45 private boolean throwIfNoMatch = false;
46 final File baseDir;
47 private Map<String, Map<String, Map<String, String>>> interfaceToLocal;
48 private Map<String, Map<String, Map<String, String>>> localToInterface;
49
50
51
52
53
54
55
56
57 public FileCodeMapper() throws HL7Exception {
58 baseDir = new File(Home.getHomeDirectory().getAbsolutePath() + "/codemap");
59 refreshCache();
60 }
61
62
63
64
65
66 public void refreshCache() throws HL7Exception {
67 localToInterface = new HashMap<>(10);
68 interfaceToLocal = new HashMap<>(10);
69
70 log.info("Refreshing cache");
71
72 try {
73
74 File[] interfaceDirs = this.baseDir.listFiles(pathname -> {
75 boolean acc = false;
76 if (pathname.isDirectory())
77 acc = true;
78 return acc;
79 });
80
81
82 for (File interfaceDir : interfaceDirs) {
83
84 log.info(
85 "Checking directory {} for interface code maps.", interfaceDir.getName());
86
87
88 File[] mapFiles = interfaceDir.listFiles((dir, name) -> {
89 boolean acc = false;
90 if (name.toUpperCase().startsWith("HL7")) {
91 if (name.substring(name.lastIndexOf('.')).equals(".li")
92 || name.substring(name.lastIndexOf('.')).equals(".il"))
93 acc = true;
94 }
95 return acc;
96 });
97
98
99 HashMap<String, Map<String, String>> li = new HashMap<>(50);
100 HashMap<String, Map<String, String>> il = new HashMap<>(50);
101 for (File mapFile : mapFiles) {
102 log.info("Reading map entries from file {}", mapFile);
103
104 String fName = mapFile.getName();
105 String tableName = fName.substring(0, fName.lastIndexOf('.'));
106 String mapDirection = fName.substring(fName.lastIndexOf('.') + 1);
107
108
109 Map<String, String> codeMap = new HashMap<>(25);
110 try (BufferedReader in = new BufferedReader(new FileReader(mapFile))) {
111 while (in.ready()) {
112 String line = in.readLine();
113 if (!line.startsWith("//")) {
114 StringTokenizer tok = new StringTokenizer(line, "\t", false);
115 String from = null;
116 String to = null;
117 if (tok.hasMoreTokens())
118 from = tok.nextToken();
119 if (tok.hasMoreTokens())
120 to = tok.nextToken();
121 if (from != null && to != null)
122 codeMap.put(from, to);
123 }
124 }
125 }
126
127
128 if (mapDirection.equals("il")) {
129 il.put(tableName.toUpperCase(), codeMap);
130 log.debug("Adding {} codes to interface -> local map for {} in {} interface",
131 codeMap.size(), tableName, interfaceDir.getName());
132 } else {
133 li.put(tableName.toUpperCase(), codeMap);
134 log.debug("Adding {} codes to local -> interface map for {} in {} interface",
135 codeMap.size(), tableName, interfaceDir.getName());
136 }
137 }
138
139
140 interfaceToLocal.put(interfaceDir.getName(), il);
141 localToInterface.put(interfaceDir.getName(), li);
142 }
143
144 }
145 catch (IOException e) {
146 throw new HL7Exception(
147 "Can't read interface code maps from disk", e);
148 }
149 }
150
151
152
153
154
155 public String getLocalCode(String interfaceName, int hl7Table, String interfaceCode) throws HL7Exception {
156 String localCode = null;
157 try {
158 Map<String, Map<String, String>> interfaceMap = interfaceToLocal.get(interfaceName);
159 localCode = getCode(interfaceMap, hl7Table, interfaceCode);
160 }
161 catch (NullPointerException npe) {
162 if (this.throwIfNoMatch)
163 throw new HL7Exception(
164 "No local mapping for the interface code "
165 + interfaceCode
166 + " for HL7 table "
167 + hl7Table
168 + " for the interface '"
169 + interfaceName
170 + "'",
171 ErrorCode.TABLE_VALUE_NOT_FOUND);
172 }
173 return localCode;
174 }
175
176
177
178
179 private String getCode(Map<String, Map<String, String>> interfaceMap, int hl7Table, String code) {
180 String ret;
181
182
183 StringBuilder tableName = new StringBuilder();
184 tableName.append("HL7");
185 if (hl7Table < 1000)
186 tableName.append("0");
187 if (hl7Table < 100)
188 tableName.append("0");
189 if (hl7Table < 10)
190 tableName.append("0");
191 tableName.append(hl7Table);
192 Map<String, String> tableMap = interfaceMap.get(tableName.toString());
193
194
195 ret = tableMap.get(code);
196 return ret;
197 }
198
199
200
201
202
203 public String getInterfaceCode(String interfaceName, int hl7Table, String localCode) throws HL7Exception {
204 String interfaceCode = null;
205 try {
206 Map<String, Map<String, String>> interfaceMap = localToInterface.get(interfaceName);
207 interfaceCode = getCode(interfaceMap, hl7Table, localCode);
208 }
209 catch (NullPointerException npe) {
210 if (this.throwIfNoMatch)
211 throw new HL7Exception(
212 "No interface mapping for the local code "
213 + localCode
214 + " for HL7 table "
215 + hl7Table
216 + " for the interface '"
217 + interfaceName
218 + "'",
219 ErrorCode.TABLE_VALUE_NOT_FOUND);
220 }
221 return interfaceCode;
222 }
223
224
225
226
227
228
229 public void throwExceptionIfNoMatch(boolean throwException) {
230 this.throwIfNoMatch = throwException;
231 }
232
233
234
235
236 public static void main(String[] args) {
237 try {
238
239 CodeMapper.getInstance().throwExceptionIfNoMatch(true);
240 System.out.println("Local code for M is " + CodeMapper.getLocal("test", 1, "M"));
241 System.out.println("Interface code for female is " + CodeMapper.getInt("test", 1, "female"));
242
243 }
244 catch (HL7Exception e) {
245 e.printStackTrace();
246 }
247 }
248
249 }