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 "DefaultHapiContext.java".  Description: 
10  "Default implementation of 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 ca.uhn.hl7v2.app.*;
29  import ca.uhn.hl7v2.concurrent.DefaultExecutorService;
30  import ca.uhn.hl7v2.conf.store.CodeStoreRegistry;
31  import ca.uhn.hl7v2.conf.store.DefaultCodeStoreRegistry;
32  import ca.uhn.hl7v2.conf.store.ProfileStore;
33  import ca.uhn.hl7v2.conf.store.ProfileStoreFactory;
34  import ca.uhn.hl7v2.llp.LowerLayerProtocol;
35  import ca.uhn.hl7v2.llp.MinLowerLayerProtocol;
36  import ca.uhn.hl7v2.model.AbstractMessage;
37  import ca.uhn.hl7v2.model.Message;
38  import ca.uhn.hl7v2.parser.*;
39  import ca.uhn.hl7v2.util.ReflectionUtil;
40  import ca.uhn.hl7v2.util.SocketFactory;
41  import ca.uhn.hl7v2.util.StandardSocketFactory;
42  import ca.uhn.hl7v2.validation.*;
43  import ca.uhn.hl7v2.validation.builder.ValidationRuleBuilder;
44  import ca.uhn.hl7v2.validation.impl.ValidationContextFactory;
45  
46  import java.io.IOException;
47  import java.util.concurrent.ExecutorService;
48  
49  /**
50   * Default implementation for {@link HapiContext}.
51   * 
52   * With this class you can configure HAPI and obtain all major HAPI business
53   * objects that are initialized accordingly. All configuration objects already
54   * have reasonable defaults.
55   * <p>
56   * When using Spring Framework for initializing objects, you can use the factory
57   * methods like this:
58   * 
59   * <pre>
60   * &lt;!-- Define the context --&gt;
61   * &lt;bean id="hapiContext" class="ca.uhn.hl7v2.DefaultHapiContext"&gt;
62   *    ...
63   * &lt;/bean&gt;
64   * 
65   * &lt;!-- Obtain the default PipeParser instance --&gt;
66   * &lt;bean id="pipeParser" factory-bean="hapiContext" factory-method="getPipeParser"/&gt;
67   * ...
68   * </pre>
69   * 
70   */
71  public class DefaultHapiContext implements HapiContext {
72  
73      private ExecutorService executorService;
74      private ParserConfiguration parserConfiguration;
75      private ValidationContext validationContext;
76      private ValidationRuleBuilder validationRuleBuilder;
77      private ModelClassFactory modelClassFactory;
78      private ConnectionHub connectionHub;
79      private LowerLayerProtocol llp;
80      private SocketFactory socketFactory;
81      private ProfileStore profileStore;
82      private CodeStoreRegistry codeStoreRegistry;
83      private PipeParser pipeParser;
84      private XMLParser xmlParser;
85      private GenericParser genericParser;
86      private Validator<?> validator;
87      private ValidationExceptionHandlerFactory<?> validationExceptionHandlerFactory;
88  	private ServerConfiguration serverConfiguration;
89  
90      public DefaultHapiContext() {
91          this(new DefaultModelClassFactory());
92      }
93  
94      public DefaultHapiContext(ExecutorService executorService) {
95          this();
96          setExecutorService(executorService);
97      }
98  
99      public DefaultHapiContext(ModelClassFactory modelClassFactory) {
100         this(new ParserConfiguration(), ValidationContextFactory.defaultValidation(),
101                 modelClassFactory);
102     }
103 
104     public DefaultHapiContext(ValidationContext validationContext) {
105         this(new ParserConfiguration(), validationContext, new DefaultModelClassFactory());
106     }
107 
108     public DefaultHapiContext(ValidationRuleBuilder builder) {
109         this(new ParserConfiguration(), builder, new DefaultModelClassFactory());
110     }
111 
112     public DefaultHapiContext(ParserConfiguration parserConfiguration,
113             ValidationContext validationContext, ModelClassFactory modelClassFactory) {
114         VersionLogger.init();
115         setParserConfiguration(parserConfiguration);
116         setValidationContext(validationContext);
117         setModelClassFactory(modelClassFactory);
118         setLowerLayerProtocol(new MinLowerLayerProtocol(false));
119         setSocketFactory(new StandardSocketFactory());
120         setValidationExceptionHandlerFactory(new ReportingValidationExceptionHandler(true));
121         setProfileStore(ProfileStoreFactory.getProfileStore());
122         setCodeStoreRegistry(new DefaultCodeStoreRegistry());
123         setServerConfiguration(new ServerConfiguration());
124     }
125 
126     public DefaultHapiContext(ParserConfiguration parserConfiguration,
127             ValidationRuleBuilder builder, ModelClassFactory modelClassFactory) {
128         VersionLogger.init();
129         setParserConfiguration(parserConfiguration);
130         setValidationRuleBuilder(builder);
131         setModelClassFactory(modelClassFactory);
132         setLowerLayerProtocol(new MinLowerLayerProtocol(false));
133         setSocketFactory(new StandardSocketFactory());
134         setProfileStore(ProfileStoreFactory.getProfileStore());
135         setCodeStoreRegistry(new DefaultCodeStoreRegistry());
136         setServerConfiguration(new ServerConfiguration());
137     }
138 
139     public DefaultHapiContext(HapiContext context) {
140         this(context.getParserConfiguration(), context.getValidationContext(), context
141                 .getModelClassFactory());
142     }
143 
144     public void close() {
145         getConnectionHub().discardAll();
146         if (DefaultExecutorService.isDefaultService(executorService)) {
147             executorService.shutdownNow();
148         }
149     }
150 
151     public synchronized ExecutorService getExecutorService() {
152         if (executorService == null) {
153             executorService = DefaultExecutorService.getDefaultService();
154             Runtime.getRuntime().addShutdownHook(new Thread(() -> executorService.shutdownNow()));
155         }
156         return executorService;
157     }
158 
159     public synchronized void setExecutorService(ExecutorService executorService) {
160         this.executorService = executorService;
161     }
162 
163     public ConnectionHub getConnectionHub() {
164         if (this.connectionHub == null) {
165             this.connectionHub = ConnectionHub.getNewInstance(this);
166         }
167         return this.connectionHub;
168     }
169 
170     public ParserConfiguration getParserConfiguration() {
171         return parserConfiguration;
172     }
173 
174     public void setParserConfiguration(ParserConfiguration configuration) {
175         if (configuration == null)
176             throw new IllegalArgumentException("ParserConfiguration must not be null");
177         this.parserConfiguration = configuration;
178     }
179 
180     /**
181      * Returns the ValidationContext. If none has been explicitly set,
182      * {@link #getValidationRuleBuilder()} is called in order to to contruct a
183      * context. If this is also null, the ca.uhn.hl7v2.validation.context_class
184      * system property is evaluated, otherwise it returns the DefaultValidation
185      * context.
186      */
187     public ValidationContext getValidationContext() {
188         if (validationContext == null) {
189 
190             if (getValidationRuleBuilder() != null) {
191                 setValidationContext(ValidationContextFactory
192                         .fromBuilder(getValidationRuleBuilder()));
193             } else {
194                 try {
195                     setValidationContext(ValidationContextFactory.getContext());
196                 } catch (HL7Exception e) {
197                     setValidationContext(ValidationContextFactory.defaultValidation());
198                 }
199             }
200         }
201         return validationContext;
202     }
203 
204     public void setValidationContext(ValidationContext context) {
205         this.validationContext = context;
206     }
207 
208     public void setValidationContext(String contextClassName) {
209         try {
210             this.validationContext = ValidationContextFactory.customValidation(contextClassName);
211         } catch (HL7Exception e) {
212             throw new IllegalArgumentException(e);
213         }
214     }
215 
216     public ValidationRuleBuilder getValidationRuleBuilder() {
217         return validationRuleBuilder;
218     }
219 
220     public void setValidationRuleBuilder(ValidationRuleBuilder validationRuleBuilder) {
221         this.validationRuleBuilder = validationRuleBuilder;
222         setValidationContext(ValidationContextFactory.fromBuilder(validationRuleBuilder));
223     }
224 
225     public void setValidationRuleBuilder(String builderClassName) {
226         try {
227             setValidationRuleBuilder(ValidationContextFactory.customBuilder(builderClassName));
228         } catch (HL7Exception e) {
229             throw new IllegalArgumentException(e);
230         }
231     }
232 
233     public ModelClassFactory getModelClassFactory() {
234         return modelClassFactory == null ? new DefaultModelClassFactory() : modelClassFactory;
235     }
236 
237     public void setModelClassFactory(ModelClassFactory modelClassFactory) {
238         this.modelClassFactory = modelClassFactory;
239     }
240     
241     public ProfileStore getProfileStore() {
242         return profileStore;
243     }
244 
245     public void setProfileStore(ProfileStore profileStore) {
246         this.profileStore = profileStore;
247     }
248 
249     public CodeStoreRegistry getCodeStoreRegistry() {
250         return codeStoreRegistry;
251     }
252 
253     public void setCodeStoreRegistry(CodeStoreRegistry codeStoreRegistry) {
254         this.codeStoreRegistry = codeStoreRegistry;
255     }
256     
257     public ca.uhn.hl7v2.conf.check.Validator getConformanceValidator() {
258         return new ca.uhn.hl7v2.conf.check.DefaultValidator(this);
259     }
260 
261     public synchronized PipeParser getPipeParser() {
262         if (pipeParser == null) {
263             pipeParser = new PipeParser(this);
264         }
265         return pipeParser;
266     }
267 
268     public synchronized XMLParser getXMLParser() {
269         if (xmlParser == null) {
270             xmlParser = new DefaultXMLParser(this);
271         }
272         return xmlParser;
273     }
274 
275     public synchronized GenericParser getGenericParser() {
276         if (genericParser == null) {
277             genericParser = new GenericParser(this);
278         }
279         return genericParser;
280     }
281 
282     @SuppressWarnings("unchecked")
283     public synchronized <R> Validator<R> getMessageValidator() {
284         if (validator == null) {
285             validator = new DefaultValidator<R>(this);
286         }
287         return (Validator<R>) validator;
288     }
289 
290     @SuppressWarnings("unchecked")
291     public <R> ValidationExceptionHandlerFactory<R> getValidationExceptionHandlerFactory() {
292     	if (validationExceptionHandlerFactory == null) {
293     		validationExceptionHandlerFactory = new DefaultValidationExceptionHandler(this);
294     	}
295         return (ValidationExceptionHandlerFactory<R>) validationExceptionHandlerFactory;
296     }
297 
298     public <R> void setValidationExceptionHandlerFactory(
299             ValidationExceptionHandlerFactory<R> factory) {
300     	if (factory == null) {
301     		throw new NullPointerException("ValidationExceptionHandlerFactory can not be null");
302     	}
303         this.validationExceptionHandlerFactory = factory;
304     }
305 
306     public LowerLayerProtocol getLowerLayerProtocol() {
307         return llp;
308     }
309 
310     public void setLowerLayerProtocol(LowerLayerProtocol llp) {
311         this.llp = llp;
312     }
313 
314     public SocketFactory getSocketFactory() {
315         return socketFactory;
316     }
317 
318     public void setSocketFactory(SocketFactory socketFactory) {
319         this.socketFactory = socketFactory;
320     }
321 
322     public SimpleServer newServer(int port, boolean tls) {
323         return new SimpleServer(this, port, tls);
324     }
325     
326     public SimpleServer newServer(int port, boolean tls, boolean acceptAll) {
327         return new SimpleServer(this, port, tls, acceptAll);
328     }
329 
330     public TwoPortService newServer(int port1, int port2, boolean tls) {
331         return new TwoPortService(this, port1, port2, tls);
332     }
333 
334 	public Connection newClient(String host, int port, boolean tls) throws HL7Exception {
335 		return getConnectionHub().attach(this, host, port, tls);
336 	}
337 
338 	public Connection newClient(String host, int outboundPort, int inboundPort, boolean tls) throws HL7Exception {
339 		return getConnectionHub().attach(this, host, outboundPort, inboundPort, tls);
340 	}
341 
342     public Connection newLazyClient(String host, int port, boolean tls) throws HL7Exception {
343         return getConnectionHub().attachLazily(this, host, port, tls);
344     }
345 
346     public Connection newLazyClient(String host, int outboundPort, int inboundPort, boolean tls) throws HL7Exception {
347         return getConnectionHub().attachLazily(this, host, outboundPort, inboundPort, tls);
348     }
349 
350 	public ServerConfiguration getServerConfiguration() {
351 		if (this.serverConfiguration == null) {
352 			serverConfiguration = new ServerConfiguration();
353 		}
354 		return this.serverConfiguration;
355 	}
356 
357 	public void setServerConfiguration(ServerConfiguration theServerConfiguration) {
358 		if (theServerConfiguration==null) {
359 			throw new NullPointerException("Server configuration can not be null");
360 		}
361 		serverConfiguration = theServerConfiguration;
362 	}
363 
364     public Message newMessage(String eventType, String triggerEvent, Version version) throws HL7Exception {
365         try {
366             String structure = getModelClassFactory().getMessageStructureForEvent(eventType + "_" + triggerEvent, version);
367             Class<? extends Message> messageClass = getModelClassFactory().getMessageClass(structure, version.getVersion(), false);
368             Message msg = newMessage(messageClass);
369             ((AbstractMessage) msg).initQuickstart(eventType, triggerEvent, "P");
370             return msg;
371         } catch (IOException e) {
372             throw new HL7Exception(e);
373         }
374     }
375 
376     public <T extends Message> T newMessage(Class<T> clazz) throws HL7Exception {
377         T msg = ReflectionUtil.instantiateMessage(clazz, getModelClassFactory());
378         msg.setParser(getGenericParser());
379         return msg;
380     }
381 
382 }