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 package ca.uhn.hl7v2.testpanel.model.msg;
27
28 import java.beans.PropertyVetoException;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Collections;
32 import java.util.List;
33
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 import ca.uhn.hl7v2.HL7Exception;
38 import ca.uhn.hl7v2.model.Composite;
39 import ca.uhn.hl7v2.model.Group;
40 import ca.uhn.hl7v2.model.Message;
41 import ca.uhn.hl7v2.model.Primitive;
42 import ca.uhn.hl7v2.model.Segment;
43 import ca.uhn.hl7v2.model.Structure;
44 import ca.uhn.hl7v2.model.Type;
45 import ca.uhn.hl7v2.model.Varies;
46 import ca.uhn.hl7v2.parser.DefaultXMLParser;
47 import ca.uhn.hl7v2.parser.EncodingCharacters;
48 import ca.uhn.hl7v2.testpanel.util.CharCountingStringIteratorDecorator;
49 import ca.uhn.hl7v2.testpanel.util.Range;
50 import ca.uhn.hl7v2.testpanel.util.SegmentAndComponentPath;
51 import ca.uhn.hl7v2.testpanel.xsd.Hl7V2EncodingTypeEnum;
52
53 public class Hl7V2MessageEr7 extends Hl7V2MessageBase {
54 private static final Logger ourLog = LoggerFactory.getLogger(Hl7V2MessageEr7.class);
55 private String myHighlitedPath;
56 private Range myHighlitedRange;
57 private ArrayList<Segment> mySegmentIndexes = new ArrayList<Segment>();
58 private ArrayList<Range> mySegmentRanges = new ArrayList<Range>();
59 private ArrayList<String> mySegmentTerserPaths = new ArrayList<String>();
60
61 public Hl7V2MessageEr7() {
62 super();
63 }
64
65 public Hl7V2MessageEr7(int theIndexWithinCollection) throws PropertyVetoException {
66 this();
67
68 setIndexWithinCollection(theIndexWithinCollection);
69 }
70
71 @Override
72 public Hl7V2MessageBase asEncoding(Hl7V2EncodingTypeEnum theEncoding) {
73 switch (theEncoding) {
74 case ER_7:
75 return this;
76 case XML:
77 default:
78 Hl7V2MessageXml retVal = new Hl7V2MessageXml();
79 try {
80 retVal.setSourceMessage(new DefaultXMLParser().encode(getParsedMessage()));
81 } catch (PropertyVetoException e) {
82 ourLog.error("Failed to create XML message", e);
83 } catch (HL7Exception e) {
84 ourLog.error("Failed to create XML message", e);
85 }
86
87 return retVal;
88 }
89
90 }
91
92 public void clearHighlight() {
93 setHighlitedRangeBasedOnSegment((Segment[])null);
94 setHighlitedPathBasedOnRange(null);
95 }
96
97
98
99
100 public String getHighlitedPath() {
101 return myHighlitedPath;
102 }
103
104 public Range getHighlitedRange() {
105 return myHighlitedRange;
106 }
107
108 public int getLineIndex(Segment theSegment) {
109 int index = 0;
110 for (Segment next : mySegmentIndexes) {
111 if (next == theSegment) {
112 return index;
113 } else {
114 index++;
115 }
116 }
117
118 return -1;
119 }
120
121 List<Range> getSegmentRanges() {
122 return Collections.unmodifiableList(mySegmentRanges);
123 }
124
125 protected void recalculateIndexes() {
126 String[] lines = getSourceMessage().split("\\r");
127 CharCountingStringIteratorDecorator iter = new CharCountingStringIteratorDecorator(Arrays.asList(lines).iterator());
128 mySegmentIndexes.clear();
129 mySegmentRanges.clear();
130 mySegmentTerserPaths.clear();
131
132 try {
133
134 recalculateIndexes(iter, getParsedMessage(), null, "");
135 } catch (HL7Exception e) {
136 ourLog.error("Failed to calculate message segment indexes", e);
137 }
138 }
139
140 private String recalculateIndexes(CharCountingStringIteratorDecorator theIter, Group theGroup, String theNameToSearchFor, String thePath) throws HL7Exception {
141 for (String nextName : theGroup.getNames()) {
142
143 if (theNameToSearchFor == null && theIter.hasNext()) {
144 do {
145 theNameToSearchFor = theIter.next();
146
147
148 theIter.setNumCharsReturned(theIter.getNumCharsReturned() + 1);
149
150 if (theNameToSearchFor.length() < 3) {
151 mySegmentIndexes.add(null);
152 mySegmentRanges.add(null);
153 } else {
154 theNameToSearchFor = theNameToSearchFor.substring(0, 3);
155 }
156 } while (theNameToSearchFor == null);
157 }
158
159 if (theNameToSearchFor == null && theIter.hasNext() == false) {
160 return null;
161 }
162
163 Structure[] reps = theGroup.getAll(nextName);
164 if (theGroup.isGroup(nextName)) {
165 int repIndex = 1;
166 for (Structure structure : reps) {
167 String nextPath = thePath + "/" + nextName + (repIndex > 1 ? "(" + repIndex + ")" : "");
168 repIndex++;
169 theNameToSearchFor = recalculateIndexes(theIter, (Group) structure, theNameToSearchFor, nextPath);
170 }
171 continue;
172 }
173
174 if (!theNameToSearchFor.equals(nextName)) {
175 continue;
176 }
177
178 int repIndex = 1;
179 ER7_STRUCTURE_REPS: for (Structure structure : reps) {
180
181 String nextPath = thePath + "/" + nextName + (repIndex > 1 ? "(" + repIndex + ")" : "");
182 mySegmentTerserPaths.add(nextPath);
183 repIndex++;
184
185 mySegmentIndexes.add((Segment) structure);
186
187 int start = 0;
188 if (mySegmentRanges.size() > 0) {
189 start = mySegmentRanges.get(mySegmentRanges.size() - 1).getEnd() + 1;
190 }
191
192 int end = theIter.getNumCharsReturned();
193 mySegmentRanges.add(new Range(start, end - 1));
194
195 if (theIter.hasNext() == false) {
196 return null;
197 }
198
199 do {
200 theNameToSearchFor = theIter.next();
201
202
203 theIter.setNumCharsReturned(theIter.getNumCharsReturned() + 1);
204
205 if (theNameToSearchFor.length() < 3) {
206 mySegmentIndexes.add(null);
207 mySegmentRanges.add(null);
208 } else {
209 theNameToSearchFor = theNameToSearchFor.substring(0, 3);
210 }
211 } while (theNameToSearchFor == null);
212
213 if (!theNameToSearchFor.equals(nextName)) {
214 break ER7_STRUCTURE_REPS;
215 }
216
217 }
218
219 }
220
221 return theNameToSearchFor;
222
223 }
224
225 public void setHighlitedField(SegmentAndComponentPath theField) {
226
227 if (theField == null) {
228 setHighlitedPathBasedOnRange(null);
229 return;
230 }
231
232 int lineIndex = getLineIndex(theField.getSegment());
233 if (lineIndex == -1) {
234 setHighlitedPathBasedOnRange(null);
235 return;
236 }
237
238 Range segmentRange = mySegmentRanges.get(lineIndex);
239 String sourceMessage = getSourceMessage();
240 Message parsedMessage = getParsedMessage();
241
242 Range currentRange = findFieldRange(theField.getComponentPath(), theField.getRepNum(), segmentRange, sourceMessage, parsedMessage);
243 setHighlitedPathBasedOnRange(currentRange);
244 myHighlitedRange = currentRange;
245
246 }
247
248 public void setHighlitedPathBasedOnRange(Range theRange) {
249
250 if (theRange == null) {
251 myHighlitedPath = null;
252 return;
253 }
254
255 int dot = theRange.getStart();
256
257 int dotIndex = -1;
258 Range segmentRange = null;
259 for (int i = 0; i < mySegmentRanges.size(); i++) {
260 segmentRange = mySegmentRanges.get(i);
261 if (segmentRange != null && segmentRange.contains(dot)) {
262 dotIndex = i;
263 break;
264 }
265 }
266
267 if (dotIndex == -1) {
268 return;
269 }
270
271 EncodingCharacters enc;
272 try {
273 enc = EncodingCharacters.getInstance(getParsedMessage());
274 } catch (HL7Exception e) {
275 ourLog.error("Failed to find field", e);
276 return;
277 }
278
279 int fieldIndex = 0;
280 int cmpIndex = 0;
281 int subCmpIndex = 0;
282 int repIndex = 0;
283 for (int i = segmentRange.getStart() + 1; i <= segmentRange.getEnd() && i <= dot && i <= getSourceMessage().length(); i++) {
284 char nextChar = getSourceMessage().charAt(i - 1);
285 if (nextChar == enc.getRepetitionSeparator()) {
286 repIndex++;
287 cmpIndex = 1;
288 subCmpIndex = 1;
289 } else if (nextChar == enc.getFieldSeparator()) {
290 fieldIndex++;
291 repIndex = 0;
292 cmpIndex = 1;
293 subCmpIndex = 1;
294 } else if (nextChar == enc.getComponentSeparator()) {
295 cmpIndex++;
296 subCmpIndex = 1;
297 } else if (nextChar == enc.getSubcomponentSeparator()) {
298 subCmpIndex++;
299 }
300 }
301
302 Segment segment = mySegmentIndexes.get(dotIndex);
303 if (segment.getName().equals("MSH")) {
304 fieldIndex++;
305 if (fieldIndex == 2) {
306 cmpIndex = 1;
307 subCmpIndex = 1;
308 repIndex = 0;
309 }
310 }
311
312 try {
313 if (fieldIndex > 0) {
314 Type type = segment.getField(fieldIndex, 0);
315 if (type instanceof Varies) {
316 type = ((Varies) type).getData();
317 }
318 if (type instanceof Composite) {
319 Composite composite = (Composite) type;
320 if (subCmpIndex == 1) {
321 Type subComponent = composite.getComponent(1);
322 if (subComponent instanceof Varies) {
323 subComponent = ((Varies) subComponent).getData();
324 }
325 if (subComponent instanceof Primitive) {
326 subCmpIndex = 0;
327 }
328 }
329 } else if (cmpIndex == 1) {
330 cmpIndex = 0;
331 }
332 }
333
334 } catch (HL7Exception e) {
335 ourLog.error("Failed to retrieve field", e);
336 }
337
338 String basePath = mySegmentTerserPaths.get(dotIndex);
339 StringBuilder fullPathB = new StringBuilder(basePath);
340 if (fieldIndex >= 1) {
341 fullPathB.append('-').append(fieldIndex);
342 if (repIndex > 0) {
343 fullPathB.append('(');
344 fullPathB.append(repIndex + 1);
345 fullPathB.append(')');
346 }
347 if (cmpIndex >= 1) {
348 fullPathB.append('-').append(cmpIndex);
349 if (subCmpIndex >= 1) {
350 fullPathB.append('-').append(subCmpIndex);
351 }
352 }
353 }
354 String fullPath = fullPathB.toString();
355
356
357
358
359
360
361
362
363
364 ourLog.info("Highlited path is now: " + fullPath);
365
366 myHighlitedPath = fullPath;
367 }
368
369 public void setHighlitedRangeBasedOnSegment(Segment... theSegment) {
370 if (theSegment == null || theSegment.length == 0) {
371 myHighlitedRange = null;
372 } else {
373
374 myHighlitedRange = null;
375 for (Segment segment : theSegment) {
376 int newSelectedIndex = theSegment != null ? getLineIndex(segment) : -1;
377 if (newSelectedIndex != -1) {
378 Range nextRange = mySegmentRanges.get(newSelectedIndex);
379 if (nextRange == null) {
380
381 } else if (myHighlitedRange == null) {
382 myHighlitedRange = nextRange;
383 } else {
384 myHighlitedRange = myHighlitedRange.overlay(nextRange);
385 }
386 }
387 }
388
389 }
390
391 }
392
393 }