001/** 002 * The 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. 004 * You may obtain a copy of the License at http://www.mozilla.org/MPL/ 005 * Software distributed under the License is distributed on an "AS IS" basis, 006 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 007 * specific language governing rights and limitations under the License. 008 * 009 * The Original Code is "Receiver.java". Description: 010 * "Listens for incoming messages on a certain input stream, and 011 * sends them to the appropriate location." 012 * 013 * The Initial Developer of the Original Code is University Health Network. Copyright (C) 014 * 2002. All Rights Reserved. 015 * 016 * Contributor(s): _____________. 017 * 018 * Alternatively, the contents of this file may be used under the terms of the 019 * GNU General Public License (the ?GPL?), in which case the provisions of the GPL are 020 * applicable instead of those above. If you wish to allow use of your version of this 021 * file only under the terms of the GPL and not to allow others to use your version 022 * of this file under the MPL, indicate your decision by deleting the provisions above 023 * and replace them with the notice and other provisions required by the GPL License. 024 * If you do not delete the provisions above, a recipient may use your version of 025 * this file under either the MPL or the GPL. 026 */ 027package ca.uhn.hl7v2.app; 028 029import java.util.HashMap; 030import java.util.Map; 031 032import org.slf4j.Logger; 033import org.slf4j.LoggerFactory; 034 035import ca.uhn.hl7v2.HL7Exception; 036import ca.uhn.hl7v2.model.Message; 037import ca.uhn.hl7v2.protocol.ApplicationRouter; 038import ca.uhn.hl7v2.util.Terser; 039 040/** 041 * Routes messages to various Applications based on message type and trigger 042 * event. The router is told which Application to which to route various 043 * messages by calling the method <code>registerApplication(...)</code>. 044 * 045 * @author Bryan Tripp 046 * @deprecated Replaced with {@link ApplicationRouter} 047 */ 048public class MessageTypeRouter implements Application, 049 ApplicationExceptionHandler { 050 051 private static final Logger log = LoggerFactory 052 .getLogger(MessageTypeRouter.class); 053 private Map<String, Application> apps; 054 055 /** Creates a new instance of MessageTypeRouter */ 056 public MessageTypeRouter() { 057 apps = new HashMap<String, Application>(20); 058 } 059 060 /** 061 * Returns true if at least one application has been registered to accept 062 * this type of message. Applications are registered using 063 * <code>registerApplication(...)</code>. 064 */ 065 public boolean canProcess(Message in) { 066 try { 067 Application match = getMatchingApplication(in); 068 return match != null && match.canProcess(in); 069 } catch (Exception e) { 070 return false; 071 } 072 } 073 074 /** 075 * Forwards the given message to any Applications that have been registered 076 * to accept messages of that type and trigger event. 077 * 078 * @throws ApplicationException 079 * if no such Applications are registered, or if the underlying 080 * Application throws this exception during processing. 081 */ 082 public Message processMessage(Message in) throws ApplicationException { 083 try { 084 Application matchingApp = this.getMatchingApplication(in); 085 return matchingApp.processMessage(in); 086 } catch (HL7Exception e) { 087 throw new ApplicationException("Error internally routing message: " 088 + e.toString(), e); 089 } 090 } 091 092 /** 093 * Forwards the given exception to all Applications. 094 * TODO this may call itself leading to infinite loops 095 */ 096 public String processException(String incomingMessage, 097 String outgoingMessage, Exception e) throws HL7Exception { 098 String outgoingMessageResult = outgoingMessage; 099 for (Application app : apps.values()) { 100 if (app instanceof ApplicationExceptionHandler) { 101 ApplicationExceptionHandler aeh = (ApplicationExceptionHandler) app; 102 outgoingMessageResult = aeh.processException(incomingMessage, 103 outgoingMessageResult, e); 104 } 105 } 106 return outgoingMessageResult; 107 } 108 109 /** 110 * Registers the given application to handle messages corresponding to the 111 * given type and trigger event. Only one application can be registered for 112 * a given message type and trigger event combination. A repeated 113 * registration for a particular combination of type and trigger event 114 * over-writes the previous one. Use "*" as a wildcard (e.g. 115 * registerApplication("ADT", "*", myApp) would register your app for all 116 * ADT messages). 117 */ 118 public synchronized void registerApplication(String messageType, 119 String triggerEvent, Application handler) { 120 this.apps.put(getKey(messageType, triggerEvent), handler); 121 log.info("{} registered to handle {}^{} messages", new Object[] { 122 handler.getClass().getName(), messageType, triggerEvent }); 123 } 124 125 /** 126 * Returns the Applications that has been registered to handle messages of 127 * the type and trigger event of the given message, or null if there are 128 * none. 129 */ 130 private Application getMatchingApplication(Message message) 131 throws HL7Exception { 132 Terser t = new Terser(message); 133 String messageType = t.get("/MSH-9-1"); 134 String triggerEvent = t.get("/MSH-9-2"); 135 return this.getMatchingApplication(messageType, triggerEvent); 136 } 137 138 /** 139 * Returns the Applications that has been registered to handle messages of 140 * the given type and trigger event, or null if there are none. If there is 141 * not an exact match, wildcards ("*") are tried as well. 142 */ 143 private synchronized Application getMatchingApplication(String messageType, 144 String triggerEvent) { 145 Application matchingApp = null; 146 Application o = this.apps.get(getKey(messageType, triggerEvent)); 147 if (o == null) 148 o = this.apps.get(getKey(messageType, "*")); 149 if (o == null) 150 o = this.apps.get(getKey("*", triggerEvent)); 151 if (o == null) 152 o = this.apps.get(getKey("*", "*")); 153 if (o != null) 154 matchingApp = o; 155 return matchingApp; 156 } 157 158 /** 159 * Creates reproducible hash key. 160 */ 161 private String getKey(String messageType, String triggerEvent) { 162 // create hash key string by concatenating type and trigger event 163 return messageType + "|" + triggerEvent; 164 } 165 166}