001/**
002The contents of this file are subject to the Mozilla Public License Version 1.1 
003(the "License"); you may not use this file except in compliance with the License. 
004You may obtain a copy of the License at http://www.mozilla.org/MPL/ 
005Software distributed under the License is distributed on an "AS IS" basis, 
006WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 
007specific language governing rights and limitations under the License. 
008
009The Original Code is "HapiContext.java".  Description: 
010"HAPI configuration and factory" 
011
012The Initial Developer of the Original Code is University Health Network. Copyright (C) 
0132001.  All Rights Reserved. 
014
015Contributor(s): ______________________________________. 
016
017Alternatively, the contents of this file may be used under the terms of the 
018GNU General Public License (the  "GPL"), in which case the provisions of the GPL are 
019applicable instead of those above.  If you wish to allow use of your version of this 
020file only under the terms of the GPL and not to allow others to use your version 
021of this file under the MPL, indicate your decision by deleting  the provisions above 
022and replace  them with the notice and other provisions required by the GPL License.  
023If you do not delete the provisions above, a recipient may use your version of 
024this file under either the MPL or the GPL. 
025 */
026package ca.uhn.hl7v2;
027
028import java.io.Closeable;
029import java.util.concurrent.ExecutorService;
030
031import ca.uhn.hl7v2.app.Connection;
032import ca.uhn.hl7v2.app.ConnectionHub;
033import ca.uhn.hl7v2.app.HL7Service;
034import ca.uhn.hl7v2.app.ServerConfiguration;
035import ca.uhn.hl7v2.conf.store.CodeStoreRegistry;
036import ca.uhn.hl7v2.conf.store.ProfileStore;
037import ca.uhn.hl7v2.llp.LowerLayerProtocol;
038import ca.uhn.hl7v2.parser.GenericParser;
039import ca.uhn.hl7v2.parser.ModelClassFactory;
040import ca.uhn.hl7v2.parser.ParserConfiguration;
041import ca.uhn.hl7v2.parser.PipeParser;
042import ca.uhn.hl7v2.parser.XMLParser;
043import ca.uhn.hl7v2.util.SocketFactory;
044import ca.uhn.hl7v2.validation.ValidationContext;
045import ca.uhn.hl7v2.validation.ValidationExceptionHandlerFactory;
046import ca.uhn.hl7v2.validation.Validator;
047import ca.uhn.hl7v2.validation.builder.ValidationRuleBuilder;
048
049/**
050 * Interface that provides a starting point for
051 * <ul>
052 * <li>Configuring HAPI core services (e.g. parsing)
053 * <li>Obtaining correspondingly configured instances of HAPI core services
054 * </ul>
055 * 
056 * HapiContext instances are not supposed to be singletons, i.e. if necessary, it is possible to
057 * have several HapiContexts within one application.
058 * <p>
059 * HapiContext objects maintains the following configuration information
060 * <ul>
061 * <li>{@link ExecutorService}: thread executors used for the HAPI networking features in
062 * ca.uhn.hl7v2.app
063 * <li>{@link LowerLayerProtocol}: MLLP protocol used for the HAPI networking features in
064 * ca.uhn.hl7v2.app
065 * <li>{@link SocketFactory}: Socket factory used for the HAPI networking features in
066 * ca.uhn.hl7v2.app
067 * <li>{@link ParserConfiguration}: detail configuration for all HL7 parsers
068 * <li>{@link ModelClassFactory}: lookup for message model classes during parsing or message
069 * creation
070 * <li>{@link ValidationContext}: validation rules used during parsing or during a dedcated
071 * validation step
072 * <li>{@link ValidationRuleBuilder}: alternative way of providing a ValidationContext
073 * <li>{@link ValidationExceptionHandlerFactory}: factory for exception handler used during message validation
074 * </ul>
075 * <p>
076 * HapiContext serves as factory for HAPI objects that refer to this configuration. Changing the
077 * configuration automatically influence all HAPI objects that were created and will be created
078 * using the given factory instance:
079 * <ul>
080 * <li>{@link PipeParser}
081 * <li>{@link XMLParser}
082 * <li>{@link GenericParser}
083 * <li>{@link Validator}
084 * <li>{@link ConnectionHub}
085 * <li>{@link ca.uhn.hl7v2.app.SimpleServer}
086 * <li>{@link ca.uhn.hl7v2.app.TwoPortService}
087 * </ul>
088 * 
089 */
090public interface HapiContext extends Closeable {
091
092        /**
093         * @return the {@link ExecutorService} to be used by all services that spawn threads
094         */
095        ExecutorService getExecutorService();
096
097        /**
098         * @param executorService the {@link ExecutorService} to be used by all services that spawn
099         *            threads
100         */
101        void setExecutorService(ExecutorService executorService);
102
103        /**
104         * @return a new ConnectionHub instance
105     * @deprecated use {@link #newClient(String, int, boolean)}
106         */
107        ConnectionHub getConnectionHub();
108
109        /**
110         * @return the {@link ParserConfiguration} to be used by all parsers obtained from this class.
111         */
112        ParserConfiguration getParserConfiguration();
113
114        /**
115         * @return the {@link ServerConfiguration} to be used by all HL7 servers obtained from this class.
116         * @see #newServer(int, boolean)
117         * @see #newServer(int, int, boolean)
118         */
119        ServerConfiguration getServerConfiguration();
120
121        /**
122         * Sets the {@link ServerConfiguration} to be used by all HL7 servers obtained from this class.
123         * 
124         * @see #newServer(int, boolean)
125         * @see #newServer(int, int, boolean)
126         */
127        void setServerConfiguration(ServerConfiguration theServerConfiguration);
128        
129        /**
130         * @param configuration {@link ParserConfiguration} to be used by all parsers obtained from this
131         *            class.
132         */
133        void setParserConfiguration(ParserConfiguration configuration);
134
135        /**
136         * @return the {@link ValidationContext} to be used by all parsers obtained from this class.
137         */
138        ValidationContext getValidationContext();
139
140        /**
141         * @param context {@link ValidationContext} to be used by all parsers obtained from this class.
142         */
143        void setValidationContext(ValidationContext context);
144
145        /**
146         * Sets a default {@link ValidationContext}. Note that a default {@link ValidationRuleBuilder}
147         * has precedence of this ValidationContext.
148         * 
149         * @param contextClassName class name of the {@link ValidationContext} to be used by all parsers
150         *            obtained from this class.
151         */
152        void setValidationContext(String contextClassName);
153
154        /**
155         * @return the {@link ValidationRuleBuilder} to be used by all parsers obtained from this class.
156         */
157        ValidationRuleBuilder getValidationRuleBuilder();
158
159        /**
160         * Sets a default {@link ValidationRuleBuilder}. Note that this {@link ValidationRuleBuilder}
161         * has precedence over a default {@link ValidationContext} set with
162         * {@link #setValidationContext(ValidationContext)} or {@link #setValidationContext(String)}
163         * 
164         * @param ruleBuilder {@link ValidationRuleBuilder} to be used by all parsers obtained from this
165         *            class.
166         */
167        void setValidationRuleBuilder(ValidationRuleBuilder ruleBuilder);
168
169        /**
170         * Sets a new instance of {@link ValidationRuleBuilder} as default. Note that this
171         * {@link ValidationRuleBuilder} has precedence over a default {@link ValidationContext} set
172         * with {@link #setValidationContext(ValidationContext)} or
173         * {@link #setValidationContext(String)}
174         * 
175         * @param builderClassName class name of the {@link ValidationRuleBuilder} to be used by all
176         *            parsers obtained from this class.
177         */
178        void setValidationRuleBuilder(String builderClassName);
179
180        /**
181         * @return the {@link ModelClassFactory} to be used by all parsers obtained from this class.
182         */
183        ModelClassFactory getModelClassFactory();
184
185        /**
186         * @param modelClassFactory the {@link ModelClassFactory} to be used by all parsers obtained
187         *            from this class.
188         */
189        void setModelClassFactory(ModelClassFactory modelClassFactory);
190        
191        /**
192         * @return the {@link ProfileStore} to be used for loading conformance profile files
193         */
194        ProfileStore getProfileStore();
195        
196        /**
197         * @param store the {@link ProfileStore} to be used for loading conformance profile files
198         */
199        void setProfileStore(ProfileStore store);
200        
201    /**
202     * @return the {@link CodeStoreRegistry} to be used for serving codes for conformance profiles
203     */
204        CodeStoreRegistry getCodeStoreRegistry();
205    
206    /**
207     * @param store the {@link CodeStoreRegistry} to be used for serving codes for conformance profiles
208     */
209    void setCodeStoreRegistry(CodeStoreRegistry store); 
210
211        // Default instances of business objects
212
213        /**
214         * @return a new PipeParser instance initialized as set with
215         *         {@link #setModelClassFactory(ModelClassFactory)},
216         *         {@link #setValidationContext(String)} and
217         *         {@link #setParserConfiguration(ParserConfiguration)}.
218         */
219        PipeParser getPipeParser();
220
221        /**
222         * @return a new XMLParser instance initialized as set with
223         *         {@link #setModelClassFactory(ModelClassFactory)},
224         *         {@link #setValidationContext(String)} and
225         *         {@link #setParserConfiguration(ParserConfiguration)}.
226         */
227        XMLParser getXMLParser();
228
229        /**
230         * @return a new GenericParser instance initialized as set with
231         *         {@link #setModelClassFactory(ModelClassFactory)},
232         *         {@link #setValidationContext(String)} and
233         *         {@link #setParserConfiguration(ParserConfiguration)}.
234         */
235        GenericParser getGenericParser();
236
237    /**
238     * Returns a ca.uhn.hl7v2.conf.check.Validator instance. It is recommended to
239     * use {@link #getMessageValidator()} and configure a Validation rule that checks
240     * a message against a conformance profile
241     * 
242     * @return a ca.uhn.hl7v2.conf.check.Validator instance initialized as set with
243     * {@link #setCodeStoreRegistry(CodeStoreRegistry)}
244     */
245    ca.uhn.hl7v2.conf.check.Validator getConformanceValidator();
246    
247        /**
248         * @return a MessageValidator instance initialized with the {@link ValidationContext} as set
249         *         using {@link #setValidationContext(ValidationContext)}. For each validation it will
250         *         use a new instance of {@link ca.uhn.hl7v2.validation.ValidationExceptionHandler ValidationExceptionHandler} as obtained by
251         *         {@link #getValidationExceptionHandlerFactory()}.
252         */
253        <R> Validator<R> getMessageValidator();
254        
255        <R> ValidationExceptionHandlerFactory<R> getValidationExceptionHandlerFactory();
256
257        /**
258         * @param factory a {@link ValidationExceptionHandlerFactory} that is used to create
259         * a {@link ca.uhn.hl7v2.validation.ValidationExceptionHandler ValidationExceptionHandler} during message validation.
260         */
261        <R> void setValidationExceptionHandlerFactory(ValidationExceptionHandlerFactory<R> factory);
262
263        /**
264         * @return the {@link LowerLayerProtocol} instance used by all HL7 MLLP operations
265         */
266        LowerLayerProtocol getLowerLayerProtocol();
267
268        /**
269         * @param llp the {@link LowerLayerProtocol} instance used by all HL7 MLLP operations
270         */
271        void setLowerLayerProtocol(LowerLayerProtocol llp);
272
273        /**
274         * @return the {@link SocketFactory} instance used by HL7 networking operations
275         */
276        SocketFactory getSocketFactory();
277
278        /**
279         * @param socketFactory the {@link SocketFactory} instance used by HL7 networking operations
280         */
281        void setSocketFactory(SocketFactory socketFactory);
282
283        /**
284         * Construct a new HL7 Server which will listen for incoming connections
285         * 
286         * @param port The port on which to listen for new connections
287         * @param tls Whether or not to use SSL/TLS
288         * @return HL7 service running on the configured port using the default parser and executor
289         *         service instances provided by this interface. Note that the returned service <b>will not
290         *         be started</b>, and must manually be started using {@link HL7Service#start()} or
291         *         {@link HL7Service#startAndWait()}
292         * @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
293         * @see #setSocketFactory(SocketFactory)
294         */
295        HL7Service newServer(int port, boolean tls);
296
297        /**
298         * Construct a new HL7 Server which will listen for a pair of connections (one for
299         * incoming messages, one for outgoing)
300         * 
301         * @param inboundPort The port on which to listen for connections for inbound messages
302         * @param outboundPort The port on which to listen for connections for outgoing messages
303         * @param tls Whether or not to use SSL/TLS
304         * @return HL7 service running on the configured ports using the default parser and executor
305         *         service instances provided by this interface. Note that the returned service <b>will not
306         *         be started</b>, and must manually be started using {@link HL7Service#start()} or
307         *         {@link HL7Service#startAndWait()}
308         * @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
309         * @see #setSocketFactory(SocketFactory)
310         */
311        HL7Service newServer(int inboundPort, int outboundPort, boolean tls);
312        
313        /**
314         * Construct a new HL7 Client which will connect to an external TCP server for
315         * the purpose of sending messages (and receiving responses). Unless otherwise
316         * stated, the connection is established by the time this method
317         * returns, or an exception should be thrown if the connection can not be
318         * established. If a connection to this server already exists, it is reused.
319         * <p>
320         * Note that connections are pooled by the HapiContext by default. If multiple
321         * concurrent connections to the same server are required, the easiest way
322         * to accomplish this is currently to create multiple HapiContext instances.
323         * </p>
324         * 
325         * @param host The host IP/hostname to connect to
326         * @param port The port to connect to
327         * @param tls Whether or not to use SSL/TLS
328         * @return Returns a connection which can be used to transmit messages. Note that this method
329         *         will attempt to connect to the specified address, and will throw an exception
330         *         if it fails to connect.
331         * @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
332         * @throws HL7Exception If the connection can not be initialized for any reason 
333         */
334        Connection newClient(String host, int port, boolean tls) throws HL7Exception;
335
336    /**
337     * Construct a new HL7 Client which will connect to an external TCP server for
338     * the purpose of sending messages (and receiving responses). The connection
339     * should be established by the time the first message is sent.
340         * <p>
341         * Note that connections are pooled by the HapiContext by default. If multiple
342         * concurrent connections to the same server are required, the easiest way
343         * to accomplish this is currently to create multiple HapiContext instances.
344         * </p>
345     *
346     * @param host The host IP/hostname to connect to
347     * @param port The port to connect to
348     * @param tls Whether or not to use SSL/TLS
349     * @return Returns a connection which can be used to transmit messages.
350     * @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
351     * @throws HL7Exception If the connection can not be initialized for any reason
352     */
353    Connection newLazyClient(String host, int port, boolean tls) throws HL7Exception;
354
355    /**
356     * Construct a new HL7 two-port client which will connect to an external TCP server for
357     * the purpose of sending messages (and receiving responses). Unless otherwise
358     * stated, the connection is established by the time this method
359     * returns, or an exception should be thrown if the connection can not be
360     * established. If a connection to this server already exists, it is reused.
361         * <p>
362         * Note that connections are pooled by the HapiContext by default. If multiple
363         * concurrent connections to the same server are required, the easiest way
364         * to accomplish this is currently to create multiple HapiContext instances.
365         * </p>
366     *
367     * @param host The host IP/hostname to connect to
368     * @param outboundPort The port to connect to for outgoing messages
369     * @param inboundPort The port to connect to for inbound (response) messages
370     * @param tls Whether or not to use SSL/TLS
371     * @return Returns a connection which can be used to transmit messages. Note that this method
372     *         will attempt to connect to the specified address, and will throw an exception
373     *         if it fails to connect.
374     * @throws HL7Exception If the connection can not be initialized for any reason
375     */
376    Connection newClient(String host, int outboundPort, int inboundPort, boolean tls) throws HL7Exception;
377
378    /**
379     * Construct a new HL7 two-port client which will connect to an external TCP server for
380     * the purpose of sending messages (and receiving responses). The connection
381     * should be established by the time the first message is sent.
382         * <p>
383         * Note that connections are pooled by the HapiContext by default. If multiple
384         * concurrent connections to the same server are required, the easiest way
385         * to accomplish this is currently to create multiple HapiContext instances.
386         * </p>
387     *
388     * @param host The host IP/hostname to connect to
389     * @param outboundPort The port to connect to for outgoing messages
390     * @param inboundPort The port to connect to for inbound (response) messages
391     * @param tls Whether or not to use SSL/TLS
392     * @return Returns a connection which can be used to transmit messages.
393     * @throws HL7Exception If the connection can not be initialized for any reason
394     */
395    Connection newLazyClient(String host, int outboundPort, int inboundPort, boolean tls) throws HL7Exception;
396
397}