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 "DefaultHapiContext.java". Description: 010"Default implementation of 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 ca.uhn.hl7v2.app.*; 029import ca.uhn.hl7v2.concurrent.DefaultExecutorService; 030import ca.uhn.hl7v2.conf.store.CodeStoreRegistry; 031import ca.uhn.hl7v2.conf.store.DefaultCodeStoreRegistry; 032import ca.uhn.hl7v2.conf.store.ProfileStore; 033import ca.uhn.hl7v2.conf.store.ProfileStoreFactory; 034import ca.uhn.hl7v2.llp.LowerLayerProtocol; 035import ca.uhn.hl7v2.llp.MinLowerLayerProtocol; 036import ca.uhn.hl7v2.model.AbstractMessage; 037import ca.uhn.hl7v2.model.Message; 038import ca.uhn.hl7v2.parser.*; 039import ca.uhn.hl7v2.util.ReflectionUtil; 040import ca.uhn.hl7v2.util.SocketFactory; 041import ca.uhn.hl7v2.util.StandardSocketFactory; 042import ca.uhn.hl7v2.validation.*; 043import ca.uhn.hl7v2.validation.builder.ValidationRuleBuilder; 044import ca.uhn.hl7v2.validation.impl.ValidationContextFactory; 045 046import java.io.IOException; 047import java.util.concurrent.ExecutorService; 048 049/** 050 * Default implementation for {@link HapiContext}. 051 * 052 * With this class you can configure HAPI and obtain all major HAPI business 053 * objects that are initialized accordingly. All configuration objects already 054 * have reasonable defaults. 055 * <p> 056 * When using Spring Framework for initializing objects, you can use the factory 057 * methods like this: 058 * 059 * <pre> 060 * <!-- Define the context --> 061 * <bean id="hapiContext" class="ca.uhn.hl7v2.DefaultHapiContext"> 062 * ... 063 * </bean> 064 * 065 * <!-- Obtain the default PipeParser instance --> 066 * <bean id="pipeParser" factory-bean="hapiContext" factory-method="getPipeParser"/> 067 * ... 068 * </pre> 069 * 070 */ 071public class DefaultHapiContext implements HapiContext { 072 073 private ExecutorService executorService; 074 private ParserConfiguration parserConfiguration; 075 private ValidationContext validationContext; 076 private ValidationRuleBuilder validationRuleBuilder; 077 private ModelClassFactory modelClassFactory; 078 private ConnectionHub connectionHub; 079 private LowerLayerProtocol llp; 080 private SocketFactory socketFactory; 081 private ProfileStore profileStore; 082 private CodeStoreRegistry codeStoreRegistry; 083 private PipeParser pipeParser; 084 private XMLParser xmlParser; 085 private GenericParser genericParser; 086 private Validator<?> validator; 087 private ValidationExceptionHandlerFactory<?> validationExceptionHandlerFactory; 088 private ServerConfiguration serverConfiguration; 089 090 public DefaultHapiContext() { 091 this(new DefaultModelClassFactory()); 092 } 093 094 public DefaultHapiContext(ExecutorService executorService) { 095 this(); 096 setExecutorService(executorService); 097 } 098 099 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}