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 }