View Javadoc
1   /**
2    The contents of this file are subject to the Mozilla Public License Version 1.1
3    (the "License"); you may not use this file except in compliance with the License.
4    You may obtain a copy of the License at http://www.mozilla.org/MPL/
5    Software distributed under the License is distributed on an "AS IS" basis,
6    WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
7    specific language governing rights and limitations under the License.
8   
9    The Original Code is "HapiContext.java".  Description:
10   "HAPI configuration and factory"
11  
12   The Initial Developer of the Original Code is University Health Network. Copyright (C)
13   2001.  All Rights Reserved.
14  
15   Contributor(s): ______________________________________.
16  
17   Alternatively, the contents of this file may be used under the terms of the
18   GNU General Public License (the  "GPL"), in which case the provisions of the GPL are
19   applicable instead of those above.  If you wish to allow use of your version of this
20   file only under the terms of the GPL and not to allow others to use your version
21   of this file under the MPL, indicate your decision by deleting  the provisions above
22   and replace  them with the notice and other provisions required by the GPL License.
23   If you do not delete the provisions above, a recipient may use your version of
24   this file under either the MPL or the GPL.
25   */
26  package ca.uhn.hl7v2;
27  
28  import java.io.Closeable;
29  import java.util.concurrent.ExecutorService;
30  
31  import ca.uhn.hl7v2.app.Connection;
32  import ca.uhn.hl7v2.app.ConnectionHub;
33  import ca.uhn.hl7v2.app.HL7Service;
34  import ca.uhn.hl7v2.app.ServerConfiguration;
35  import ca.uhn.hl7v2.conf.store.CodeStoreRegistry;
36  import ca.uhn.hl7v2.conf.store.ProfileStore;
37  import ca.uhn.hl7v2.llp.LowerLayerProtocol;
38  import ca.uhn.hl7v2.model.Message;
39  import ca.uhn.hl7v2.parser.*;
40  import ca.uhn.hl7v2.util.SocketFactory;
41  import ca.uhn.hl7v2.validation.ValidationContext;
42  import ca.uhn.hl7v2.validation.ValidationExceptionHandlerFactory;
43  import ca.uhn.hl7v2.validation.Validator;
44  import ca.uhn.hl7v2.validation.builder.ValidationRuleBuilder;
45  
46  /**
47   * Interface that provides a starting point for
48   * <ul>
49   * <li>Configuring HAPI core services (e.g. parsing)
50   * <li>Obtaining correspondingly configured instances of HAPI core services
51   * </ul>
52   * <p/>
53   * HapiContext instances are not supposed to be singletons, i.e. if necessary, it is possible to
54   * have several HapiContexts within one application.
55   * <p/>
56   * HapiContext objects maintains the following configuration information
57   * <ul>
58   * <li>{@link ExecutorService}: thread executors used for the HAPI networking features in
59   * ca.uhn.hl7v2.app
60   * <li>{@link LowerLayerProtocol}: MLLP protocol used for the HAPI networking features in
61   * ca.uhn.hl7v2.app
62   * <li>{@link SocketFactory}: Socket factory used for the HAPI networking features in
63   * ca.uhn.hl7v2.app
64   * <li>{@link ParserConfiguration}: detail configuration for all HL7 parsers
65   * <li>{@link ModelClassFactory}: lookup for message model classes during parsing or message
66   * creation
67   * <li>{@link ValidationContext}: validation rules used during parsing or during a dedcated
68   * validation step
69   * <li>{@link ValidationRuleBuilder}: alternative way of providing a ValidationContext
70   * <li>{@link ValidationExceptionHandlerFactory}: factory for exception handler used during message validation
71   * </ul>
72   * <p/>
73   * HapiContext serves as factory for HAPI objects that refer to this configuration. Changing the
74   * configuration automatically influence all HAPI objects that were created and will be created
75   * using the given factory instance:
76   * <ul>
77   * <li>{@link PipeParser}
78   * <li>{@link XMLParser}
79   * <li>{@link GenericParser}
80   * <li>{@link Validator}
81   * <li>{@link ConnectionHub}
82   * <li>{@link ca.uhn.hl7v2.app.SimpleServer}
83   * <li>{@link ca.uhn.hl7v2.app.TwoPortService}
84   * </ul>
85   */
86  public interface HapiContext extends Closeable {
87  
88      /**
89       * @return the {@link ExecutorService} to be used by all services that spawn threads
90       */
91      ExecutorService getExecutorService();
92  
93      /**
94       * @param executorService the {@link ExecutorService} to be used by all services that spawn
95       *                        threads
96       */
97      void setExecutorService(ExecutorService executorService);
98  
99      /**
100      * @return a new ConnectionHub instance
101      * @deprecated use {@link #newClient(String, int, boolean)}
102      */
103     ConnectionHub getConnectionHub();
104 
105     /**
106      * @return the {@link ParserConfiguration} to be used by all parsers obtained from this class.
107      */
108     ParserConfiguration getParserConfiguration();
109 
110     /**
111      * @return the {@link ServerConfiguration} to be used by all HL7 servers obtained from this class.
112      * @see #newServer(int, boolean)
113      * @see #newServer(int, int, boolean)
114      */
115     ServerConfiguration getServerConfiguration();
116 
117     /**
118      * Sets the {@link ServerConfiguration} to be used by all HL7 servers obtained from this class.
119      *
120      * @see #newServer(int, boolean)
121      * @see #newServer(int, int, boolean)
122      */
123     void setServerConfiguration(ServerConfiguration theServerConfiguration);
124 
125     /**
126      * @param configuration {@link ParserConfiguration} to be used by all parsers obtained from this
127      *                      class.
128      */
129     void setParserConfiguration(ParserConfiguration configuration);
130 
131     /**
132      * @return the {@link ValidationContext} to be used by all parsers obtained from this class.
133      */
134     ValidationContext getValidationContext();
135 
136     /**
137      * @param context {@link ValidationContext} to be used by all parsers obtained from this class.
138      */
139     void setValidationContext(ValidationContext context);
140 
141     /**
142      * Sets a default {@link ValidationContext}. Note that a default {@link ValidationRuleBuilder}
143      * has precedence of this ValidationContext.
144      *
145      * @param contextClassName class name of the {@link ValidationContext} to be used by all parsers
146      *                         obtained from this class.
147      */
148     void setValidationContext(String contextClassName);
149 
150     /**
151      * @return the {@link ValidationRuleBuilder} to be used by all parsers obtained from this class.
152      */
153     ValidationRuleBuilder getValidationRuleBuilder();
154 
155     /**
156      * Sets a default {@link ValidationRuleBuilder}. Note that this {@link ValidationRuleBuilder}
157      * has precedence over a default {@link ValidationContext} set with
158      * {@link #setValidationContext(ValidationContext)} or {@link #setValidationContext(String)}
159      *
160      * @param ruleBuilder {@link ValidationRuleBuilder} to be used by all parsers obtained from this
161      *                    class.
162      */
163     void setValidationRuleBuilder(ValidationRuleBuilder ruleBuilder);
164 
165     /**
166      * Sets a new instance of {@link ValidationRuleBuilder} as default. Note that this
167      * {@link ValidationRuleBuilder} has precedence over a default {@link ValidationContext} set
168      * with {@link #setValidationContext(ValidationContext)} or
169      * {@link #setValidationContext(String)}
170      *
171      * @param builderClassName class name of the {@link ValidationRuleBuilder} to be used by all
172      *                         parsers obtained from this class.
173      */
174     void setValidationRuleBuilder(String builderClassName);
175 
176     /**
177      * @return the {@link ModelClassFactory} to be used by all parsers obtained from this class.
178      */
179     ModelClassFactory getModelClassFactory();
180 
181     /**
182      * @param modelClassFactory the {@link ModelClassFactory} to be used by all parsers obtained
183      *                          from this class.
184      */
185     void setModelClassFactory(ModelClassFactory modelClassFactory);
186 
187     /**
188      * @return the {@link ProfileStore} to be used for loading conformance profile files
189      */
190     ProfileStore getProfileStore();
191 
192     /**
193      * @param store the {@link ProfileStore} to be used for loading conformance profile files
194      */
195     void setProfileStore(ProfileStore store);
196 
197     /**
198      * @return the {@link CodeStoreRegistry} to be used for serving codes for conformance profiles
199      */
200     CodeStoreRegistry getCodeStoreRegistry();
201 
202     /**
203      * @param store the {@link CodeStoreRegistry} to be used for serving codes for conformance profiles
204      */
205     void setCodeStoreRegistry(CodeStoreRegistry store);
206 
207     // Default instances of business objects
208 
209     /**
210      * @return a new PipeParser instance initialized as set with
211      * {@link #setModelClassFactory(ModelClassFactory)},
212      * {@link #setValidationContext(String)} and
213      * {@link #setParserConfiguration(ParserConfiguration)}.
214      */
215     PipeParser getPipeParser();
216 
217     /**
218      * @return a new XMLParser instance initialized as set with
219      * {@link #setModelClassFactory(ModelClassFactory)},
220      * {@link #setValidationContext(String)} and
221      * {@link #setParserConfiguration(ParserConfiguration)}.
222      */
223     XMLParser getXMLParser();
224 
225     /**
226      * @return a new GenericParser instance initialized as set with
227      * {@link #setModelClassFactory(ModelClassFactory)},
228      * {@link #setValidationContext(String)} and
229      * {@link #setParserConfiguration(ParserConfiguration)}.
230      */
231     GenericParser getGenericParser();
232 
233     /**
234      * Returns a ca.uhn.hl7v2.conf.check.Validator instance. It is recommended to
235      * use {@link #getMessageValidator()} and configure a Validation rule that checks
236      * a message against a conformance profile
237      *
238      * @return a ca.uhn.hl7v2.conf.check.Validator instance initialized as set with
239      * {@link #setCodeStoreRegistry(CodeStoreRegistry)}
240      */
241     ca.uhn.hl7v2.conf.check.Validator getConformanceValidator();
242 
243     /**
244      * @return a MessageValidator instance initialized with the {@link ValidationContext} as set
245      * using {@link #setValidationContext(ValidationContext)}. For each validation it will
246      * use a new instance of {@link ca.uhn.hl7v2.validation.ValidationExceptionHandler ValidationExceptionHandler} as obtained by
247      * {@link #getValidationExceptionHandlerFactory()}.
248      */
249     <R> Validator<R> getMessageValidator();
250 
251     <R> ValidationExceptionHandlerFactory<R> getValidationExceptionHandlerFactory();
252 
253     /**
254      * @param factory a {@link ValidationExceptionHandlerFactory} that is used to create
255      *                a {@link ca.uhn.hl7v2.validation.ValidationExceptionHandler ValidationExceptionHandler} during message validation.
256      */
257     <R> void setValidationExceptionHandlerFactory(ValidationExceptionHandlerFactory<R> factory);
258 
259     /**
260      * @return the {@link LowerLayerProtocol} instance used by all HL7 MLLP operations
261      */
262     LowerLayerProtocol getLowerLayerProtocol();
263 
264     /**
265      * @param llp the {@link LowerLayerProtocol} instance used by all HL7 MLLP operations
266      */
267     void setLowerLayerProtocol(LowerLayerProtocol llp);
268 
269     /**
270      * @return the {@link SocketFactory} instance used by HL7 networking operations
271      */
272     SocketFactory getSocketFactory();
273 
274     /**
275      * @param socketFactory the {@link SocketFactory} instance used by HL7 networking operations
276      */
277     void setSocketFactory(SocketFactory socketFactory);
278 
279     /**
280      * Construct a new HL7 Server which will listen for incoming connections
281      *
282      * @param port The port on which to listen for new connections
283      * @param tls  Whether or not to use SSL/TLS
284      * @return HL7 service running on the configured port using the default parser and executor
285      * service instances provided by this interface. Note that the returned service <b>will not
286      * be started</b>, and must manually be started using {@link HL7Service#start()} or
287      * {@link HL7Service#startAndWait()}
288      * @see <a href="http://hl7api.sourceforge.net/xref/ca/uhn/hl7v2/examples/SendAndReceiveAMessage.html">here</a> for an example of how to use this method
289      * @see #setSocketFactory(SocketFactory)
290      */
291     HL7Service newServer(int port, boolean tls);
292 
293     /**
294     * Construct a new HL7 Server which will listen for incoming connections
295     * and will pass all messages to the responders, even if the message control id is not 
296     * known to the server
297     *
298     * @param port The port on which to listen for new connections
299     * @param tls  Whether or not to use SSL/TLS
300     * @param acceptAll  Whether or not to accept all messages
301     * @return HL7 service running on the configured port using the default parser and executor
302     * service instances provided by this interface. Note that the returned service <b>will not
303     * be started</b>, and must manually be started using {@link HL7Service#start()} or
304     * {@link HL7Service#startAndWait()}
305     * @see <a href="http://hl7api.sourceforge.net/xref/ca/uhn/hl7v2/examples/SendAndReceiveAMessage.html">here<> for an example of how to use this method
306     * @see #setSocketFactory(SocketFactory)
307     */
308     HL7Service newServer(int port, boolean tls, boolean acceptAll);
309 
310     /**
311      * Construct a new HL7 Server which will listen for a pair of connections (one for
312      * incoming messages, one for outgoing)
313      *
314      * @param inboundPort  The port on which to listen for connections for inbound messages
315      * @param outboundPort The port on which to listen for connections for outgoing messages
316      * @param tls          Whether or not to use SSL/TLS
317      * @return HL7 service running on the configured ports using the default parser and executor
318      * service instances provided by this interface. Note that the returned service <b>will not
319      * be started</b>, and must manually be started using {@link HL7Service#start()} or
320      * {@link HL7Service#startAndWait()}
321      * @see <a href="http://hl7api.sourceforge.net/xref/ca/uhn/hl7v2/examples/SendAndReceiveAMessage.html">here</a> for an example of how to use this method
322      * @see #setSocketFactory(SocketFactory)
323      */
324     HL7Service newServer(int inboundPort, int outboundPort, boolean tls);
325 
326     /**
327      * Construct a new HL7 Client which will connect to an external TCP server for
328      * the purpose of sending messages (and receiving responses). Unless otherwise
329      * stated, the connection is established by the time this method
330      * returns, or an exception should be thrown if the connection can not be
331      * established. If a connection to this server already exists, it is reused.
332      * <p>
333      * Note that connections are pooled by the HapiContext by default. If multiple
334      * concurrent connections to the same server are required, the easiest way
335      * to accomplish this is currently to create multiple HapiContext instances.
336      * </p>
337      *
338      * @param host The host IP/hostname to connect to
339      * @param port The port to connect to
340      * @param tls  Whether or not to use SSL/TLS
341      * @return Returns a connection which can be used to transmit messages. Note that this method
342      * will attempt to connect to the specified address, and will throw an exception
343      * if it fails to connect.
344      * @throws HL7Exception If the connection can not be initialized for any reason
345      * @see <a href="http://hl7api.sourceforge.net/xref/ca/uhn/hl7v2/examples/SendAndReceiveAMessage.html">here</a> for an example of how to use this method
346      */
347     Connection newClient(String host, int port, boolean tls) throws HL7Exception;
348 
349     /**
350      * Construct a new HL7 Client which will connect to an external TCP server for
351      * the purpose of sending messages (and receiving responses). The connection
352      * should be established by the time the first message is sent.
353      * <p>
354      * Note that connections are pooled by the HapiContext by default. If multiple
355      * concurrent connections to the same server are required, the easiest way
356      * to accomplish this is currently to create multiple HapiContext instances.
357      * </p>
358      *
359      * @param host The host IP/hostname to connect to
360      * @param port The port to connect to
361      * @param tls  Whether or not to use SSL/TLS
362      * @return Returns a connection which can be used to transmit messages.
363      * @throws HL7Exception If the connection can not be initialized for any reason
364      * @see <a href="http://hl7api.sourceforge.net/xref/ca/uhn/hl7v2/examples/SendAndReceiveAMessage.html">here</a> for an example of how to use this method
365      */
366     Connection newLazyClient(String host, int port, boolean tls) throws HL7Exception;
367 
368     /**
369      * Construct a new HL7 two-port client which will connect to an external TCP server for
370      * the purpose of sending messages (and receiving responses). Unless otherwise
371      * stated, the connection is established by the time this method
372      * returns, or an exception should be thrown if the connection can not be
373      * established. If a connection to this server already exists, it is reused.
374      * <p>
375      * Note that connections are pooled by the HapiContext by default. If multiple
376      * concurrent connections to the same server are required, the easiest way
377      * to accomplish this is currently to create multiple HapiContext instances.
378      * </p>
379      *
380      * @param host         The host IP/hostname to connect to
381      * @param outboundPort The port to connect to for outgoing messages
382      * @param inboundPort  The port to connect to for inbound (response) messages
383      * @param tls          Whether or not to use SSL/TLS
384      * @return Returns a connection which can be used to transmit messages. Note that this method
385      * will attempt to connect to the specified address, and will throw an exception
386      * if it fails to connect.
387      * @throws HL7Exception If the connection can not be initialized for any reason
388      */
389     Connection newClient(String host, int outboundPort, int inboundPort, boolean tls) throws HL7Exception;
390 
391     /**
392      * Construct a new HL7 two-port client which will connect to an external TCP server for
393      * the purpose of sending messages (and receiving responses). The connection
394      * should be established by the time the first message is sent.
395      * <p>
396      * Note that connections are pooled by the HapiContext by default. If multiple
397      * concurrent connections to the same server are required, the easiest way
398      * to accomplish this is currently to create multiple HapiContext instances.
399      * </p>
400      *
401      * @param host         The host IP/hostname to connect to
402      * @param outboundPort The port to connect to for outgoing messages
403      * @param inboundPort  The port to connect to for inbound (response) messages
404      * @param tls          Whether or not to use SSL/TLS
405      * @return Returns a connection which can be used to transmit messages.
406      * @throws HL7Exception If the connection can not be initialized for any reason
407      */
408     Connection newLazyClient(String host, int outboundPort, int inboundPort, boolean tls) throws HL7Exception;
409 
410     /**
411      * Creates a new message of the given event type, trigger and version, and initializes the message header
412      *
413      * @param eventType    event type, e.g. ADT
414      * @param triggerEvent trigger event, e.g. A01
415      * @param version      HL7v2 version
416      * @return Message object of the type determined by the underlying model class factory
417      * @throws HL7Exception if no message object could be created
418      */
419     Message newMessage(String eventType, String triggerEvent, Version version) throws HL7Exception;
420 
421     /**
422      * Creates a new message of the provided message structure class, without further initializing the message
423      *
424      * @param clazz message structure class
425      * @param <T>   message structure class type
426      * @return the created message instance
427      * @throws HL7Exception
428      */
429     <T extends Message> T newMessage(Class<T> clazz) throws HL7Exception;
430 }