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() throws IOException { 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() { 155 156 @Override 157 public void run() { 158 executorService.shutdownNow(); 159 } 160 161 }); 162 } 163 return executorService; 164 } 165 166 public synchronized void setExecutorService(ExecutorService executorService) { 167 this.executorService = executorService; 168 } 169 170 public ConnectionHub getConnectionHub() { 171 if (this.connectionHub == null) { 172 this.connectionHub = ConnectionHub.getNewInstance(this); 173 } 174 return this.connectionHub; 175 } 176 177 public ParserConfiguration getParserConfiguration() { 178 return parserConfiguration; 179 } 180 181 public void setParserConfiguration(ParserConfiguration configuration) { 182 if (configuration == null) 183 throw new IllegalArgumentException("ParserConfiguration must not be null"); 184 this.parserConfiguration = configuration; 185 } 186 187 /** 188 * Returns the ValidationContext. If none has been explicitly set, 189 * {@link #getValidationRuleBuilder()} is called in order to to contruct a 190 * context. If this is also null, the ca.uhn.hl7v2.validation.context_class 191 * system property is evaluated, otherwise it returns the DefaultValidation 192 * context. 193 */ 194 public ValidationContext getValidationContext() { 195 if (validationContext == null) { 196 197 if (getValidationRuleBuilder() != null) { 198 setValidationContext(ValidationContextFactory 199 .fromBuilder(getValidationRuleBuilder())); 200 } else { 201 try { 202 setValidationContext(ValidationContextFactory.getContext()); 203 } catch (HL7Exception e) { 204 setValidationContext(ValidationContextFactory.defaultValidation()); 205 } 206 } 207 } 208 return validationContext; 209 } 210 211 public void setValidationContext(ValidationContext context) { 212 this.validationContext = context; 213 } 214 215 public void setValidationContext(String contextClassName) { 216 try { 217 this.validationContext = ValidationContextFactory.customValidation(contextClassName); 218 } catch (HL7Exception e) { 219 throw new IllegalArgumentException(e); 220 } 221 } 222 223 public ValidationRuleBuilder getValidationRuleBuilder() { 224 return validationRuleBuilder; 225 } 226 227 public void setValidationRuleBuilder(ValidationRuleBuilder validationRuleBuilder) { 228 this.validationRuleBuilder = validationRuleBuilder; 229 setValidationContext(ValidationContextFactory.fromBuilder(validationRuleBuilder)); 230 } 231 232 public void setValidationRuleBuilder(String builderClassName) { 233 try { 234 setValidationRuleBuilder(ValidationContextFactory.customBuilder(builderClassName)); 235 } catch (HL7Exception e) { 236 throw new IllegalArgumentException(e); 237 } 238 } 239 240 public ModelClassFactory getModelClassFactory() { 241 return modelClassFactory == null ? new DefaultModelClassFactory() : modelClassFactory; 242 } 243 244 public void setModelClassFactory(ModelClassFactory modelClassFactory) { 245 this.modelClassFactory = modelClassFactory; 246 } 247 248 public ProfileStore getProfileStore() { 249 return profileStore; 250 } 251 252 public void setProfileStore(ProfileStore profileStore) { 253 this.profileStore = profileStore; 254 } 255 256 public CodeStoreRegistry getCodeStoreRegistry() { 257 return codeStoreRegistry; 258 } 259 260 public void setCodeStoreRegistry(CodeStoreRegistry codeStoreRegistry) { 261 this.codeStoreRegistry = codeStoreRegistry; 262 } 263 264 public ca.uhn.hl7v2.conf.check.Validator getConformanceValidator() { 265 return new ca.uhn.hl7v2.conf.check.DefaultValidator(this); 266 } 267 268 public synchronized PipeParser getPipeParser() { 269 if (pipeParser == null) { 270 pipeParser = new PipeParser(this); 271 } 272 return pipeParser; 273 } 274 275 public synchronized XMLParser getXMLParser() { 276 if (xmlParser == null) { 277 xmlParser = new DefaultXMLParser(this); 278 } 279 return xmlParser; 280 } 281 282 public synchronized GenericParser getGenericParser() { 283 if (genericParser == null) { 284 genericParser = new GenericParser(this); 285 } 286 return genericParser; 287 } 288 289 @SuppressWarnings("unchecked") 290 public synchronized <R> Validator<R> getMessageValidator() { 291 if (validator == null) { 292 validator = new DefaultValidator<R>(this); 293 } 294 return (Validator<R>) validator; 295 } 296 297 @SuppressWarnings("unchecked") 298 public <R> ValidationExceptionHandlerFactory<R> getValidationExceptionHandlerFactory() { 299 if (validationExceptionHandlerFactory == null) { 300 validationExceptionHandlerFactory = new DefaultValidationExceptionHandler(this); 301 } 302 return (ValidationExceptionHandlerFactory<R>) validationExceptionHandlerFactory; 303 } 304 305 public <R> void setValidationExceptionHandlerFactory( 306 ValidationExceptionHandlerFactory<R> factory) { 307 if (factory == null) { 308 throw new NullPointerException("ValidationExceptionHandlerFactory can not be null"); 309 } 310 this.validationExceptionHandlerFactory = factory; 311 } 312 313 public LowerLayerProtocol getLowerLayerProtocol() { 314 return llp; 315 } 316 317 public void setLowerLayerProtocol(LowerLayerProtocol llp) { 318 this.llp = llp; 319 } 320 321 public SocketFactory getSocketFactory() { 322 return socketFactory; 323 } 324 325 public void setSocketFactory(SocketFactory socketFactory) { 326 this.socketFactory = socketFactory; 327 } 328 329 public SimpleServer newServer(int port, boolean tls) { 330 return new SimpleServer(this, port, tls); 331 } 332 333 public TwoPortService newServer(int port1, int port2, boolean tls) { 334 return new TwoPortService(this, port1, port2, tls); 335 } 336 337 public Connection newClient(String host, int port, boolean tls) throws HL7Exception { 338 return getConnectionHub().attach(this, host, port, tls); 339 } 340 341 public Connection newClient(String host, int outboundPort, int inboundPort, boolean tls) throws HL7Exception { 342 return getConnectionHub().attach(this, host, outboundPort, inboundPort, tls); 343 } 344 345 public Connection newLazyClient(String host, int port, boolean tls) throws HL7Exception { 346 return getConnectionHub().attachLazily(this, host, port, tls); 347 } 348 349 public Connection newLazyClient(String host, int outboundPort, int inboundPort, boolean tls) throws HL7Exception { 350 return getConnectionHub().attachLazily(this, host, outboundPort, inboundPort, tls); 351 } 352 353 public ServerConfiguration getServerConfiguration() { 354 if (this.serverConfiguration == null) { 355 serverConfiguration = new ServerConfiguration(); 356 } 357 return this.serverConfiguration; 358 } 359 360 public void setServerConfiguration(ServerConfiguration theServerConfiguration) { 361 if (theServerConfiguration==null) { 362 throw new NullPointerException("Server configuration can not be null"); 363 } 364 serverConfiguration = theServerConfiguration; 365 } 366 367 public Message newMessage(String eventType, String triggerEvent, Version version) throws HL7Exception { 368 try { 369 String structure = getModelClassFactory().getMessageStructureForEvent(eventType + "_" + triggerEvent, version); 370 Class<? extends Message> messageClass = getModelClassFactory().getMessageClass(structure, version.getVersion(), false); 371 Message msg = newMessage(messageClass); 372 ((AbstractMessage) msg).initQuickstart(eventType, triggerEvent, "P"); 373 return msg; 374 } catch (IOException e) { 375 throw new HL7Exception(e); 376 } 377 } 378 379 public <T extends Message> T newMessage(Class<T> clazz) throws HL7Exception { 380 T msg = ReflectionUtil.instantiateMessage(clazz, getModelClassFactory()); 381 msg.setParser(getGenericParser()); 382 return msg; 383 } 384 385}