View Javadoc
1   /*
2    * Created on 28-Apr-2004
3    */
4   package ca.uhn.hl7v2.preparser;
5   
6   import java.util.Arrays;
7   import java.util.List;
8   import java.util.Properties;
9   import java.util.StringTokenizer;
10  
11  import ca.uhn.hl7v2.HL7Exception;
12  import ca.uhn.hl7v2.parser.EncodingDetector;
13  import ca.uhn.hl7v2.util.Terser;
14  
15  /**
16   * <p>Extracts specified fields from unparsed messages.  This class is a 
17   * facade for the ER7 and XML classes.  Use it like this: </p>
18   * 
19   * <code>
20   * String message = null; //... your ER7 or XML message string goes here
21   * String[] fieldSpecs = {"MSH-9-1", "MSH-9-2", "MSH-12"};
22   * String[] fields = PreParser.getFields(message, fieldSpecs);
23   * </code>
24   * 
25   * @author <a href="mailto:bryan.tripp@uhn.on.ca">Bryan Tripp</a>
26   * @version $Revision: 1.1 $ updated on $Date: 2007-02-19 02:24:37 $ by $Author: jamesagnew $
27   */
28  public class PreParser {
29  
30      /**
31       * Extracts selected fields from a message.  
32       *   
33       * @param theMessageText an unparsed message from which to get fields 
34       * @param thePathSpecs Terser-like paths to fields in the message.  See documentation
35       *      for Terser.  These paths are identical except that they start with the segment
36       *      name (search flags and group names are to be omitted as they are not relevant 
37       *      with unparsed ER7 messages).  
38       * @return field values corresponding to the given paths
39       * @throws HL7Exception
40       */
41      public static String[] getFields(String theMessageText, String... thePathSpecs) throws HL7Exception {
42          DatumPath.html#DatumPath">DatumPath[] paths = new DatumPath[thePathSpecs.length];
43          for (int i = 0; i < thePathSpecs.length; i++) {
44              StringTokenizer tok = new StringTokenizer(thePathSpecs[i], "-", false);
45              String segSpec = tok.nextToken();
46              tok = new StringTokenizer(segSpec, "()", false);
47              String segName = tok.nextToken();
48              if (segName.length() != 3) {
49                  throw new HL7Exception("In field path, " + segName + " is not a valid segment name");
50              }
51              int segRep = 0;
52              if (tok.hasMoreTokens()) {
53                  String rep = tok.nextToken();
54                  try {
55                      segRep = Integer.parseInt(rep);
56                  } catch (NumberFormatException e) {
57                      throw new HL7Exception("In field path, segment rep" + rep + " is not valid", e);
58                  }
59              }
60              
61              int[] indices = Terser.getIndices(thePathSpecs[i]);
62              paths[i] = new DatumPath();
63              paths[i].add(segName).add(segRep);
64              paths[i].add(indices[0]).add(indices[1]).add(indices[2]).add(indices[3]);
65              
66          }
67          return getFields(theMessageText, paths);
68      }
69      
70      /** 
71       * Gets selected fields from a message, as with String[] arg version but 
72       * using DatumPaths. 
73       */     
74      private static String[] getFields(String theMessageText, DatumPath[] thePaths) throws HL7Exception {
75          String[] fields = new String[thePaths.length];
76          Properties props = new Properties();
77          
78          List<DatumPath> mask = Arrays.asList(thePaths);
79  
80          boolean OK;
81          if (EncodingDetector.isEr7Encoded(theMessageText)) {
82              OK = ER7.parseMessage(props, mask, theMessageText);
83          } else if (EncodingDetector.isXmlEncoded(theMessageText)) {
84              OK = XML.parseMessage(props, theMessageText, null);
85          } else {
86              throw new HL7Exception("Message encoding is not recognized"); 
87          }
88          
89          if (!OK) {
90              throw new HL7Exception("Parse failed");
91          }
92          
93          for (int i = 0; i < fields.length; i++) {
94              fields[i] = props.getProperty(thePaths[i].toString());
95          }
96          return fields;
97      }    
98  
99  }