View Javadoc

1   package ca.uhn.hl7v2.conf.store;
2   
3   import java.io.IOException;
4   import java.net.URL;
5   import java.util.ArrayList;
6   import java.util.HashMap;
7   import java.util.List;
8   import java.util.Map;
9   
10  import org.xml.sax.Attributes;
11  import org.xml.sax.SAXException;
12  import org.xml.sax.XMLReader;
13  import org.xml.sax.helpers.DefaultHandler;
14  import org.xml.sax.helpers.XMLReaderFactory;
15  
16  import ca.uhn.hl7v2.conf.ProfileException;
17  
18  /**
19   * 
20   * This particular implementation of CodeStore retrieves valid codes and validates codeSystems using
21   * tables found in 'spec xml tables only' docs generated from the HL7 Messaging Workbench tool.
22   * 
23   * Note: The codeSystem parameter value used in the following methods must be a concatenation of a
24   * coding authority and coding table number that is 4 digits long.
25   * 
26   * Note: The current implementation only accepts a coding authority of HL7
27   * 
28   * @author Neal Acharya
29   * @author Christian Ohr
30   */
31  public class ProfileCodeStore extends AbstractCodeStore {
32  
33      private Map<String, List<String>> codes = new HashMap<String, List<String>>();
34  
35      /**
36       * Creates a ProfileCodeStore object that uses tables found in an 'spec xml tables only' xml doc
37       * specified by the input URI. The private field member tableDoc is created with content from
38       * the xml doc specified by the URI.
39       * 
40       * @param uri the location of the specification XML file
41       * 
42       * @throws ProfileException
43       * @throws IOException
44       * 
45       */
46      public ProfileCodeStore(String uri) throws ProfileException, IOException {
47          try {
48              if (uri == null) {
49                  throw new ProfileException("The input url parameter cannot be null");
50              }
51              XMLReader reader = XMLReaderFactory.createXMLReader();
52              reader.setContentHandler(new ProfileCodeStoreHandler());
53              reader.parse(uri);
54          } catch (IOException e) {
55              throw e;
56          } catch (Exception e) {
57              throw new ProfileException(e.toString(), e);
58          }
59      }
60  
61      /** As string constructor but accepts a URL object */
62      public ProfileCodeStore(URL url) throws ProfileException, IOException {
63          this(url.toExternalForm());
64      }
65  
66      /**
67       * Retrieves all codes for a given conformance profile and codeSystem. Note: The codeSystem
68       * parameter value must be a concatenation of a coding authority and coding table number that is
69       * 4 digits long.
70       * 
71       * Note: The current implementation only accepts a coding authority of HL7
72       * 
73       * @param codeSystem
74       * @return String[]
75       * @throws ProfileException
76       * @see ca.uhn.hl7v2.conf.store.CodeStore#getValidCodes(java.lang.String, java.lang.String)
77       * 
78       */
79      public String[] getValidCodes(String codeSystem) throws ProfileException {
80          List<String> result = getCodeTable(codeSystem);
81          if (result == null)
82              throw new ProfileException("Unknown code system: " + codeSystem);
83          return result.toArray(new String[result.size()]);
84      }
85  
86      /**
87       * Validates the codeSystem against the input conformance profile. If valid then output is
88       * 'true' else 'false'. Note: The codeSystem parameter value must be a concatenation of a coding
89       * authority and coding table number that is 4 digits long.
90       * 
91       * Note: The current implementation only accepts a coding authority of HL7
92       * 
93       * @param codeSystem
94       * 
95       * @return boolean
96       * @see ca.uhn.hl7v2.conf.store.CodeStore#knowsCodes(java.lang.String, java.lang.String)
97       * 
98       */
99      public boolean knowsCodes(String codeSystem) {
100         try {
101             return getCodeTable(codeSystem) != null;
102         } catch (ProfileException e) {
103             return false;
104         }
105     }
106 
107     /**
108      * Retrieves the hl7Table Element from the tableDoc object defined by the table number in the
109      * input codeSystem.
110      * 
111      * @param profileId
112      * 
113      * @param codeSystem
114      * @return Element
115      * @throws ProfileException Element
116      */
117     private List<String> getCodeTable(String codeSystem) throws ProfileException {
118         if (codeSystem == null) {
119             throw new ProfileException("The input codeSystem parameter cannot be null");
120         }
121         if (codeSystem.length() < 4) {
122             throw new ProfileException("The input codeSystem parameter cannot be less than 4 characters long");
123         }
124         // Extract the last 4 characters from the codeSystem param
125         String tableId = codeSystem.substring(codeSystem.length() - 4);
126         return codes.get(tableId);
127     }
128 
129     private class ProfileCodeStoreHandler extends DefaultHandler {
130 
131         private String currentTable;
132         private static final String HL7_TABLE_QNAME = "hl7table";
133         private static final String TABLE_ELEMENT_QNAME = "tableElement";
134 
135         @Override
136         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
137             if (HL7_TABLE_QNAME.equals(qName)) {
138                 currentTable = attributes.getValue("id");
139                 codes.put(currentTable, new ArrayList<String>());
140             } else if (TABLE_ELEMENT_QNAME.equals(qName)) {
141                 codes.get(currentTable).add(attributes.getValue("code"));
142             }
143         }
144 
145     }
146 }