1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package ca.uhn.hl7v2.parser;
25
26 import java.util.HashMap;
27 import java.util.Map;
28 import java.util.Map.Entry;
29 import java.util.concurrent.ConcurrentHashMap;
30 import java.util.concurrent.ConcurrentMap;
31
32 import ca.uhn.hl7v2.model.*;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 import ca.uhn.hl7v2.HL7Exception;
37 import ca.uhn.hl7v2.Version;
38 import ca.uhn.hl7v2.util.StringUtil;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public class CustomModelClassFactory extends AbstractModelClassFactory {
54
55 private static final long serialVersionUID = 1;
56 private static final Logger LOG = LoggerFactory.getLogger(CustomModelClassFactory.class);
57
58 private final ModelClassFactory delegate;
59 private Map<String, String[]> customModelClasses;
60
61
62 private final ConcurrentMap<String, Class> cache = new ConcurrentHashMap<>();
63
64
65
66
67 public CustomModelClassFactory() {
68 this((Map<String, String[]>)null);
69 }
70
71
72
73
74
75
76
77
78
79
80
81
82
83 public CustomModelClassFactory(String packageName) {
84 this(new HashMap<>());
85
86 if (!packageName.endsWith(".")) {
87 packageName += ".";
88 }
89 for (Version v : Version.values()) {
90 addModel(v.getVersion(), new String[] {packageName + v.getPackageVersion()});
91 }
92 }
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 public CustomModelClassFactory(Map<String, String[]> map) {
109 this(new DefaultModelClassFactory(), map);
110 }
111
112
113
114
115
116
117 public CustomModelClassFactory(ModelClassFactory defaultFactory, Map<String, String[]> map) {
118 this.delegate = defaultFactory;
119 customModelClasses = map;
120 }
121
122
123
124
125 public Class<? extends Message> getMessageClass(String name, String version, boolean isExplicit) throws HL7Exception {
126 if (!isExplicit) {
127 name = getMessageStructureForEvent(name, Version.versionOf(version));
128 }
129 String key = "message" + name + version;
130 Class<? extends Message> retVal = cache.get(key);
131 if (retVal != null) return retVal;
132
133 retVal = findClass("message", name, version);
134 if (retVal == null) {
135 retVal = delegate.getMessageClass(name, version, isExplicit);
136 }
137 if (retVal != null) cache.putIfAbsent(key, retVal);
138 return retVal;
139 }
140
141
142
143
144 public Class<? extends Group> getGroupClass(String name, String version) throws HL7Exception {
145 String key = "group" + name + version;
146 Class<? extends Group> retVal = cache.get(key);
147 if (retVal != null) return retVal;
148 retVal = findClass("group", name, version);
149 if (retVal == null) {
150 retVal = delegate.getGroupClass(name, version);
151 }
152 if (retVal != null) cache.putIfAbsent(key, retVal);
153 return retVal;
154 }
155
156
157
158
159 public Class<? extends Segment> getSegmentClass(String name, String version) throws HL7Exception {
160 String key = "segment" + name + version;
161 Class<? extends Segment> retVal = cache.get(key);
162 if (retVal != null) return retVal;
163 retVal = findClass("segment", name, version);
164 if (retVal == null) {
165 retVal = delegate.getSegmentClass(name, version);
166 }
167 if (retVal != null) cache.putIfAbsent(key, retVal);
168 return retVal;
169 }
170
171
172
173
174 public Class<? extends Type> getTypeClass(String name, String version) throws HL7Exception {
175 String key = "datatype" + name + version;
176 Class<? extends Type> retVal = cache.get(key);
177 if (retVal != null) return retVal;
178 retVal = findClass("datatype", name, version);
179 if (retVal == null) {
180 retVal = delegate.getTypeClass(name, version);
181 }
182 if (retVal != null) cache.putIfAbsent(key, retVal);
183 return retVal;
184 }
185
186
187
188
189 @SuppressWarnings("unchecked")
190 protected <T> Class<T> findClass(String subpackage, String name, String version) {
191 Class<T> classLoaded = null;
192 if (customModelClasses != null) {
193 if (customModelClasses.containsKey(version)) {
194 for (String next : customModelClasses.get(version)) {
195 if (!next.endsWith(".")) {
196 next += ".";
197 }
198 String fullyQualifiedName = next + subpackage + '.' + name;
199 try {
200 classLoaded = (Class<T>) Class.forName(fullyQualifiedName);
201 LOG.debug("Found " + fullyQualifiedName + " in custom HL7 model");
202 } catch (ClassNotFoundException e) {
203
204 }
205 }
206 }
207 }
208 return classLoaded;
209 }
210
211
212
213
214 public Class<? extends Message> getMessageClassInASpecificPackage(String theName, String theVersion, boolean theIsExplicit, String thePackageName) throws HL7Exception {
215 return delegate.getMessageClassInASpecificPackage(theName, theVersion, theIsExplicit, thePackageName);
216 }
217
218
219
220
221
222 public Map<String, String[]> getCustomModelClasses() {
223 return customModelClasses;
224 }
225
226
227
228
229
230
231 public void addModels(Map<String, String[]> addedModelClasses) {
232 if (customModelClasses == null) {
233 customModelClasses = new HashMap<>();
234 }
235 for (Entry<String, String[]> entry : addedModelClasses.entrySet()) {
236 addModel(entry.getKey(), entry.getValue());
237 }
238 }
239
240 private void addModel(String version, String[] newPackageNames) {
241 if (customModelClasses.containsKey(version)) {
242
243 String[] existingPackageNames = customModelClasses.get(version);
244 customModelClasses.put(version, StringUtil.concatenate(existingPackageNames, newPackageNames));
245 } else {
246 customModelClasses.put(version, newPackageNames);
247 }
248 }
249
250
251
252
253
254
255
256
257
258 @Override
259 public String getMessageStructureForEvent(String eventName, Version version) throws HL7Exception {
260 String structure = super.getMessageStructureForEvent(eventName, version);
261 if (structure != null) return structure;
262 structure = delegate.getMessageStructureForEvent(eventName, version);
263 return structure != null ? structure : eventName;
264 }
265
266 }