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.io.File;
27 import java.io.FileReader;
28 import java.util.ArrayList;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Set;
32
33 import ca.uhn.hl7v2.DefaultHapiContext;
34 import ca.uhn.hl7v2.model.GenericMessage;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37 import org.w3c.dom.DOMException;
38 import org.w3c.dom.Document;
39 import org.w3c.dom.Element;
40 import org.w3c.dom.Node;
41 import org.w3c.dom.NodeList;
42
43 import ca.uhn.hl7v2.HL7Exception;
44 import ca.uhn.hl7v2.HapiContext;
45 import ca.uhn.hl7v2.model.Group;
46 import ca.uhn.hl7v2.model.Message;
47 import ca.uhn.hl7v2.model.Segment;
48 import ca.uhn.hl7v2.model.Structure;
49 import ca.uhn.hl7v2.util.XMLUtils;
50 import ca.uhn.hl7v2.validation.impl.NoValidation;
51 import ca.uhn.hl7v2.validation.impl.ValidationContextFactory;
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public class DefaultXMLParser extends XMLParser {
72
73 private static final Logger log = LoggerFactory.getLogger(DefaultXMLParser.class);
74
75 private static final Set<String> ourForceGroupNames;
76
77 static {
78 ourForceGroupNames = new HashSet<>();
79 ourForceGroupNames.add("DIET");
80 }
81
82 public DefaultXMLParser() {
83 super();
84 }
85
86 public DefaultXMLParser(HapiContext context) {
87 super(context);
88 }
89
90
91
92
93
94
95 public DefaultXMLParser(ModelClassFactory theFactory) {
96 super(theFactory);
97 }
98
99
100
101
102
103
104
105
106
107 public Document encodeDocument(Message source) throws HL7Exception {
108 String messageClassName = source.getClass().getName();
109 String messageName = messageClassName.substring(messageClassName.lastIndexOf('.') + 1);
110
111
112 if (source instanceof GenericMessage) {
113 messageName = messageName.replaceAll("\\$", "");
114 }
115
116 try {
117 Document doc = XMLUtils.emptyDocument(messageName);
118 encode(source, doc.getDocumentElement());
119 return doc;
120 } catch (Exception e) {
121 throw new HL7Exception(
122 "Can't create XML document - " + e.getClass().getName(), e);
123 }
124 }
125
126
127
128
129
130 private void encode(Group groupObject, Element groupElement) throws HL7Exception {
131 String[] childNames = groupObject.getNames();
132 String messageName = groupObject.getMessage().getName();
133
134 try {
135 for (String name : childNames) {
136 Structure[] reps = groupObject.getAll(name);
137 for (Structure rep : reps) {
138 String elementName = makeGroupElementName(messageName, name);
139 Element childElement;
140 try {
141 childElement = groupElement.getOwnerDocument().createElementNS(NS, elementName);
142 } catch (DOMException e) {
143 throw new HL7Exception(
144 "Can't encode element " + elementName + " in group " + groupObject.getClass().getName(), e);
145 }
146 groupElement.appendChild(childElement);
147 if (rep instanceof Group) {
148 encode((Group) rep, childElement);
149 }
150 else if (rep instanceof Segment) {
151 encode((Segment) rep, childElement);
152 }
153 }
154 }
155 } catch (DOMException e) {
156 throw new HL7Exception(
157 "Can't encode group " + groupObject.getClass().getName(), e);
158 }
159 }
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177 public Message parseDocument(Document xmlMessage, String version) throws HL7Exception {
178
179 assertNamespaceURI(xmlMessage.getDocumentElement().getNamespaceURI());
180
181 Message message = instantiateMessage(xmlMessage.getDocumentElement().getLocalName(), version, true);
182
183
184 message.setParser(this);
185 parse(message, xmlMessage.getDocumentElement());
186 return message;
187 }
188
189
190
191
192
193 private void parse(Group groupObject, Element groupElement) throws HL7Exception {
194 String[] childNames = groupObject.getNames();
195 String messageName = groupObject.getMessage().getName();
196
197 NodeList allChildNodes = groupElement.getChildNodes();
198 List<String> unparsedElementList = new ArrayList<>();
199 for (int i = 0; i < allChildNodes.getLength(); i++) {
200 Node node = allChildNodes.item(i);
201 String name = node.getLocalName();
202 if (node.getNodeType() == Node.ELEMENT_NODE && !unparsedElementList.contains(name)) {
203 assertNamespaceURI(node.getNamespaceURI());
204 unparsedElementList.add(name);
205 }
206 }
207
208
209 for (String nextChildName : childNames) {
210 String childName = nextChildName;
211 if(groupObject.isGroup(nextChildName)) {
212 childName = makeGroupElementName(groupObject.getMessage().getName(), nextChildName);
213 }
214 unparsedElementList.remove(childName);
215
216
217
218
219 if (nextChildName.length() == 4 && Character.isDigit(nextChildName.charAt(3))) {
220 log.trace("Skipping rep segment: {}", nextChildName);
221 } else {
222 parseReps(groupElement, groupObject, messageName, nextChildName, nextChildName);
223 }
224 }
225
226 for (String segName : unparsedElementList) {
227 String segIndexName = groupObject.addNonstandardSegment(segName);
228 parseReps(groupElement, groupObject, messageName, segName, segIndexName);
229 }
230 }
231
232
233 private void parseReps(Element groupElement, Group groupObject,
234 String messageName, String childName, String childIndexName) throws HL7Exception {
235
236 String groupName = makeGroupElementName(messageName, childName);
237 List<Element> reps = getChildElementsByTagName(groupElement, groupName);
238 log.trace("# of elements matching {}: {}", groupName, reps.size());
239
240 if (groupObject.isRepeating(childIndexName)) {
241 for (int i = 0; i < reps.size(); i++) {
242 parseRep(reps.get(i), groupObject.get(childIndexName, i));
243 }
244 } else {
245 if (reps.size() > 0) {
246 parseRep(reps.get(0), groupObject.get(childIndexName, 0));
247 }
248
249
250
251
252
253
254
255 if (reps.size() > 1) {
256 String newIndexName;
257 int i=1;
258 try {
259 for (i = 1; i < reps.size(); i++) {
260 newIndexName = childName+(i+1);
261 Structure st = groupObject.get(newIndexName);
262 parseRep(reps.get(i), st);
263 }
264 } catch(Throwable t) {
265 log.info("Issue Parsing: " + t);
266 newIndexName = groupObject.addNonstandardSegment(childName);
267 for (int j = i; j < reps.size(); j++) {
268 parseRep(reps.get(j), groupObject.get(newIndexName, j-i));
269 }
270 }
271 }
272
273 }
274 }
275
276 private void parseRep(Element theElem, Structure theObj) throws HL7Exception {
277 if (theObj instanceof Group) {
278 parse((Group) theObj, theElem);
279 }
280 else if (theObj instanceof Segment) {
281 parse((Segment) theObj, theElem);
282 }
283 log.trace("Parsed element: {}", theElem.getNodeName());
284 }
285
286
287 private List<Element> getChildElementsByTagName(Element theElement, String theName) throws HL7Exception {
288 List<Element> result = new ArrayList<>(10);
289 NodeList children = theElement.getChildNodes();
290
291 for (int i = 0; i < children.getLength(); i++) {
292 Node child = children.item(i);
293 if (child.getNodeType() == Node.ELEMENT_NODE && child.getLocalName().equals(theName)) {
294 assertNamespaceURI(child.getNamespaceURI());
295 result.add((Element)child);
296 }
297 }
298
299 return result;
300 }
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320 protected static String makeGroupElementName(String messageName, String className) {
321 String ret;
322
323 if (className.length() > 4 || ourForceGroupNames.contains(className)) {
324 ret = messageName +
325 '.' +
326 className;
327 } else if (className.length() == 4) {
328
329
330
331 ret = className.substring(0,3);
332 } else {
333 ret = className;
334 }
335
336 return ret;
337 }
338
339
340 public static void main(String[] args) {
341 if (args.length != 1) {
342 System.out.println("Usage: DefaultXMLParser pipe_encoded_file");
343 System.exit(1);
344 }
345
346
347 try {
348 File messageFile = new File(args[0]);
349 long fileLength = messageFile.length();
350 FileReader r = new FileReader(messageFile);
351 char[] cbuf = new char[(int) fileLength];
352 System.out.println("Reading message file ... " + r.read(cbuf) + " of " + fileLength + " chars");
353 r.close();
354 String messString = String.valueOf(cbuf);
355
356 Parser inParser = null;
357 Parser outParser = null;
358 PipeParserer.html#PipeParser">PipeParser pp = new PipeParser();
359 ca.uhn.hl7v2.parser.XMLParser xp = new DefaultXMLParser();
360 System.out.println("Encoding: " + pp.getEncoding(messString));
361 if (pp.getEncoding(messString) != null) {
362 inParser = pp;
363 outParser = xp;
364 }
365 else if (xp.getEncoding(messString) != null) {
366 inParser = xp;
367 outParser = pp;
368 }
369
370 Message mess = inParser.parse(messString);
371 System.out.println("Got message of type " + mess.getClass().getName());
372
373 String otherEncoding = outParser.encode(mess);
374 System.out.println(otherEncoding);
375 }
376 catch (Exception e) {
377 e.printStackTrace();
378 }
379 }
380
381
382
383
384 @Override
385 public void parse(Message theMessage, String theString) throws HL7Exception {
386 theMessage.setParser(this);
387 Document doc = parseStringIntoDocument(theString);
388 parse(theMessage, doc.getDocumentElement());
389
390 applySuperStructureName(theMessage);
391 }
392
393
394
395
396
397 public static XMLParser getInstanceWithNoValidation() {
398 HapiContext context = new DefaultHapiContext(ValidationContextFactory.noValidation());
399 return context.getXMLParser();
400 }
401
402
403 }