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 "Receiver.java".  Description:
10   * "Listens for incoming messages on a certain input stream, and
11   * sends them to the appropriate location."
12   *
13   * The Initial Developer of the Original Code is University Health Network. Copyright (C)
14   * 2002.  All Rights Reserved.
15   *
16   * Contributor(s): _____________.
17   *
18   * Alternatively, the contents of this file may be used under the terms of the
19   * GNU General Public License (the  �GPL�), in which case the provisions of the GPL are
20   * applicable instead of those above.  If you wish to allow use of your version of this
21   * file only under the terms of the GPL and not to allow others to use your version
22   * of this file under the MPL, indicate your decision by deleting  the provisions above
23   * and replace  them with the notice and other provisions required by the GPL License.
24   * If you do not delete the provisions above, a recipient may use your version of
25   * this file under either the MPL or the GPL.
26   */
27  package ca.uhn.hl7v2.app;
28  
29  import java.util.HashMap;
30  import java.util.Map;
31  
32  import org.slf4j.Logger;
33  import org.slf4j.LoggerFactory;
34  
35  import ca.uhn.hl7v2.HL7Exception;
36  import ca.uhn.hl7v2.model.Message;
37  import ca.uhn.hl7v2.protocol.ApplicationRouter;
38  import ca.uhn.hl7v2.util.Terser;
39  
40  /**
41   * Routes messages to various Applications based on message type and trigger
42   * event. The router is told which Application to which to route various
43   * messages by calling the method <code>registerApplication(...)</code>.
44   * 
45   * @author Bryan Tripp
46   * @deprecated Replaced with {@link ApplicationRouter}
47   */
48  public class MessageTypeRouter implements Application,
49  		ApplicationExceptionHandler {
50  
51  	private static final Logger log = LoggerFactory
52  			.getLogger(MessageTypeRouter.class);
53  	private Map<String, Application> apps;
54  
55  	/** Creates a new instance of MessageTypeRouter */
56  	public MessageTypeRouter() {
57  		apps = new HashMap<String, Application>(20);
58  	}
59  
60  	/**
61  	 * Returns true if at least one application has been registered to accept
62  	 * this type of message. Applications are registered using
63  	 * <code>registerApplication(...)</code>.
64  	 */
65  	public boolean canProcess(Message in) {
66  		try {
67  			Application match = getMatchingApplication(in);
68  			return match != null && match.canProcess(in);
69  		} catch (Exception e) {
70  			return false;
71  		}
72  	}
73  
74  	/**
75  	 * Forwards the given message to any Applications that have been registered
76  	 * to accept messages of that type and trigger event.
77  	 * 
78  	 * @throws ApplicationException
79  	 *             if no such Applications are registered, or if the underlying
80  	 *             Application throws this exception during processing.
81  	 */
82  	public Message processMessage(Message in) throws ApplicationException {
83  		try {
84  			Application matchingApp = this.getMatchingApplication(in);
85  			return matchingApp.processMessage(in);
86  		} catch (HL7Exception e) {
87  			throw new ApplicationException("Error internally routing message: "
88  					+ e.toString(), e);
89  		}
90  	}
91  
92  	/**
93  	 * Forwards the given exception to all Applications.
94       * TODO this may call itself leading to infinite loops
95  	 */
96  	public String processException(String incomingMessage,
97  			String outgoingMessage, Exception e) throws HL7Exception {
98  		String outgoingMessageResult = outgoingMessage;
99  		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 }