1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package ca.uhn.hl7v2.util;
29
30 import ca.uhn.hl7v2.Location;
31 import ca.uhn.hl7v2.model.*;
32 import ca.uhn.hl7v2.HL7Exception;
33 import java.util.StringTokenizer;
34
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 public class Terser {
114
115 private final SegmentFinder finder;
116 private static final Logger log = LoggerFactory.getLogger(Terser.class);
117
118
119
120
121
122 public Terser(Message message) {
123 if (message == null) {
124 throw new NullPointerException("Message may not be null");
125 }
126 finder = new SegmentFinder(message);
127 }
128
129
130
131
132
133
134
135
136
137
138
139
140 public static String get(Segment segment, int field, int rep, int component, int subcomponent) throws HL7Exception {
141 if (segment == null) {
142 throw new NullPointerException("segment may not be null");
143 }
144 if (rep < 0) {
145 throw new IllegalArgumentException("rep must not be negative");
146 }
147 if (component < 1) {
148 throw new IllegalArgumentException(
149 "component must not be 1 or more (note that this parameter is 1-indexed, not 0-indexed)");
150 }
151 if (subcomponent < 1) {
152 throw new IllegalArgumentException(
153 "subcomponent must not be 1 or more (note that this parameter is 1-indexed, not 0-indexed)");
154 }
155
156 Primitive prim = getPrimitive(segment, field, rep, component, subcomponent);
157 return prim.getValue();
158 }
159
160
161
162
163
164
165
166
167
168
169
170
171 public static void set(Segment segment, int field, int rep, int component, int subcomponent, String value)
172 throws HL7Exception {
173 if (segment == null) {
174 throw new NullPointerException("segment may not be null");
175 }
176 if (rep < 0) {
177 throw new IllegalArgumentException("rep must not be negative");
178 }
179 if (component < 1) {
180 throw new IllegalArgumentException(
181 "component must be 1 or more (note that this parameter is 1-indexed, not 0-indexed)");
182 }
183 if (subcomponent < 1) {
184 throw new IllegalArgumentException(
185 "subcomponent must be 1 or more (note that this parameter is 1-indexed, not 0-indexed)");
186 }
187
188 Primitive prim = getPrimitive(segment, field, rep, component, subcomponent);
189 prim.setValue(value);
190 }
191
192 public static void set(Segment segment, Location location, String value) throws HL7Exception {
193 set(segment,
194 location.getField(),
195 location.getFieldRepetition(),
196 location.getComponent(),
197 location.getSubcomponent(),
198 value);
199 }
200
201
202
203
204 private static Primitive getPrimitive(Segment segment, int field, int rep, int component, int subcomponent)
205 throws HL7Exception {
206 Type type = segment.getField(field, rep);
207 return getPrimitive(type, component, subcomponent);
208 }
209
210
211
212
213
214
215
216
217
218
219
220
221 public static Primitive getPrimitive(final Type type, final int component, final int subcomponent) {
222 if (type == null) {
223 throw new NullPointerException("type may not be null");
224 }
225 if (component < 1) {
226 throw new IllegalArgumentException(
227 "component must not be 1 or more (note that this parameter is 1-indexed, not 0-indexed)");
228 }
229 if (subcomponent < 1) {
230 throw new IllegalArgumentException(
231 "subcomponent must not be 1 or more (note that this parameter is 1-indexed, not 0-indexed)");
232 }
233
234 Type comp = getComponent(type, component);
235 if (type instanceof Varies && comp instanceof GenericPrimitive && subcomponent > 1) {
236 try {
237 final Varies../../../../ca/uhn/hl7v2/model/Varies.html#Varies">Varies varies = (Varies) type;
238 final GenericCompositetml#GenericComposite">GenericComposite comp2 = new GenericComposite(type.getMessage());
239 varies.setData(comp2);
240 comp = getComponent(type, component);
241 } catch (final DataTypeException de) {
242 final String message = "Unexpected exception copying data to generic composite. This is probably a bug within HAPI. "
243 + de.getMessage();
244 log.error(message, de);
245 throw new Error(message);
246 }
247 }
248 final Type sub = getComponent(comp, subcomponent);
249 return getPrimitive(sub);
250 }
251
252
253
254
255
256 private static Primitive getPrimitive(Type type) {
257 if (type instanceof Primitive) {
258 return (Primitive) type;
259 }
260 if (type instanceof Composite) {
261 try {
262 return getPrimitive(((Composite) type).getComponent(0));
263 } catch (HL7Exception e) {
264 throw new RuntimeException("Internal error: HL7Exception thrown on Composite.getComponent(0).");
265 }
266 }
267 return getPrimitive(((Varies) type).getData());
268 }
269
270
271
272
273
274
275
276 private static Type./../../../ca/uhn/hl7v2/model/Type.html#Type">Type getComponent(Type type, int comp) {
277
278 if (type instanceof Primitive && comp == 1) {
279 return type;
280 }
281 if (type instanceof Composite) {
282 if (comp <= numStandardComponents(type) || type instanceof GenericComposite) {
283 try {
284 return ((Composite) type).getComponent(comp - 1);
285 } catch (DataTypeException e) {
286 throw new RuntimeException(
287 "Internal error: HL7Exception thrown on getComponent(x) where x < # standard components.",
288 e);
289 }
290 }
291 }
292 if (Varies.class.isAssignableFrom(type.getClass())) {
293 Variesref="../../../../ca/uhn/hl7v2/model/Varies.html#Varies">Varies v = (Varies) type;
294 try {
295 if (comp > 1 && GenericPrimitive.class.isAssignableFrom(v.getData().getClass()))
296 v.setData(new GenericComposite(v.getMessage()));
297 } catch (DataTypeException e) {
298 throw new RuntimeException("Unexpected exception copying data to generic composite: " + e.getMessage(),
299 e);
300 }
301
302 return getComponent(v.getData(), comp);
303 }
304
305 return type.getExtraComponents().getComponent(comp - numStandardComponents(type) - 1);
306 }
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322 public String get(String spec) throws HL7Exception {
323 StringTokenizer tok = new StringTokenizer(spec, "-", false);
324 Segment segment = getSegment(tok.nextToken());
325
326 int[] ind = getIndices(spec);
327 return get(segment, ind[0], ind[1], ind[2], ind[3]);
328 }
329
330
331
332
333
334
335
336
337 public Segment getSegment(String segSpec) throws HL7Exception {
338 Segment seg = null;
339
340 if (segSpec.startsWith("/")) {
341 getFinder().reset();
342 }
343
344 StringTokenizer tok = new StringTokenizer(segSpec, "/", false);
345 SegmentFinder finder = getFinder();
346 while (tok.hasMoreTokens()) {
347 String pathSpec = tok.nextToken();
348 Terser.PathSpec ps = parsePathSpec(pathSpec);
349 ps.isGroup = tok.hasMoreTokens();
350 if (ps.isGroup) {
351 Group g = ps.find ?
352 finder.findGroup(ps.pattern, ps.rep) :
353 finder.getGroup(ps.pattern, ps.rep);
354 finder = new SegmentFinder(g);
355 } else {
356 seg = ps.find ?
357 finder.findSegment(ps.pattern, ps.rep) :
358 finder.getSegment(ps.pattern, ps.rep);
359 }
360 }
361
362 return seg;
363 }
364
365
366 private PathSpec parsePathSpec(String spec) throws HL7Exception {
367 PathSpec ps = new PathSpec();
368
369 if (spec.startsWith(".")) {
370 ps.find = true;
371 spec = spec.substring(1);
372 } else {
373 ps.find = false;
374 }
375
376 if (spec.length() == 0) {
377 throw new HL7Exception("Invalid path (some path element is either empty or contains only a dot)");
378 }
379 StringTokenizer tok = new StringTokenizer(spec, "()", false);
380 ps.pattern = tok.nextToken();
381 if (tok.hasMoreTokens()) {
382 String repString = tok.nextToken();
383 try {
384 ps.rep = Integer.parseInt(repString);
385 } catch (NumberFormatException e) {
386 throw new HL7Exception(repString + " is not a valid rep #");
387 }
388 } else {
389 ps.rep = 0;
390 }
391 return ps;
392 }
393
394
395
396
397
398
399
400
401
402 public static int[] getIndices(String spec) throws HL7Exception {
403 StringTokenizer tok = new StringTokenizer(spec, "-", false);
404 tok.nextToken();
405 if (!tok.hasMoreTokens())
406 throw new HL7Exception("Must specify field in spec " + spec);
407 try {
408 StringTokenizer fieldSpec = new StringTokenizer(tok.nextToken(), "()", false);
409 int fieldNum = Integer.parseInt(fieldSpec.nextToken());
410 int fieldRep = fieldSpec.hasMoreTokens() ?
411 Integer.parseInt(fieldSpec.nextToken()) : 0;
412 int component = tok.hasMoreTokens() ?
413 Integer.parseInt(tok.nextToken()) : 1;
414 int subcomponent = tok.hasMoreTokens() ?
415 Integer.parseInt(tok.nextToken()) : 1;
416 return new int[] { fieldNum, fieldRep, component, subcomponent };
417 } catch (NumberFormatException e) {
418 throw new HL7Exception("Invalid integer in spec " + spec);
419 }
420 }
421
422
423
424
425
426
427
428
429
430 public void set(String spec, String value) throws HL7Exception {
431 StringTokenizer tok = new StringTokenizer(spec, "-", false);
432 Segment segment = getSegment(tok.nextToken());
433
434 int[] ind = getIndices(spec);
435 log.trace("Setting {} seg: {} ind: {} {} {} {}", spec, segment.getName(), ind[0], ind[1],
436 ind[2], ind[3]);
437 set(segment, ind[0], ind[1], ind[2], ind[3], value);
438 }
439
440
441
442
443
444
445
446
447
448
449 public static int numSubComponents(Type type, int component) {
450 if (component == 1 && Primitive.class.isAssignableFrom(type.getClass())) {
451
452
453
454 return 1;
455 }
456 Type comp = getComponent(type, component);
457 return numComponents(comp);
458 }
459
460
461
462
463
464
465
466
467 public static int numComponents(Type t) {
468 if (!(t instanceof Varies)) {
469 return numStandardComponents(t) + t.getExtraComponents().numComponents();
470 }
471 return numComponents(((Varies) t).getData());
472 }
473
474 private static int numStandardComponents(Type t) {
475 if (t instanceof Composite) {
476 return ((Composite) t).getComponents().length;
477 }
478 if (t instanceof Varies) {
479 return numStandardComponents(((Varies) t).getData());
480 }
481 return 1;
482 }
483
484
485
486
487
488
489
490
491 public SegmentFinder getFinder() {
492 return finder;
493 }
494
495
496 private static class PathSpec {
497 public String pattern;
498 public boolean isGroup;
499 public boolean find;
500 public int rep;
501 }
502 }