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 "JMSTransport.java".  Description: 
10  "A TransportLayer that exchanges messages through JMS destinations." 
11  
12  The Initial Developer of the Original Code is University Health Network. Copyright (C) 
13  2004.  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  */
27  package ca.uhn.hl7v2.protocol.impl;
28  
29  import java.util.HashMap;
30  import java.util.Map;
31  
32  import javax.jms.JMSException;
33  import javax.jms.Message;
34  import javax.jms.TextMessage;
35  
36  import org.slf4j.Logger;
37  import org.slf4j.LoggerFactory;
38  
39  import ca.uhn.hl7v2.protocol.JMSDestination;
40  import ca.uhn.hl7v2.protocol.TransportException;
41  import ca.uhn.hl7v2.protocol.TransportLayer;
42  import ca.uhn.hl7v2.protocol.Transportable;
43  
44  /**
45   * A <code>TransportLayer</code> that exchanges messages through JMS destinations.   
46   * 
47   * @author <a href="mailto:bryan.tripp@uhn.on.ca">Bryan Tripp</a>
48   * @version $Revision: 1.1 $ updated on $Date: 2007-02-19 02:24:26 $ by $Author: jamesagnew $
49   */
50  public class JMSTransport extends AbstractTransport implements TransportLayer {
51  
52      private static final Logger log = LoggerFactory.getLogger(URLTransport.class);    
53  
54      public static final String INBOUND_DESTINATION_NAME_KEY = "INBOUND_DESTINATION_NAME";
55      public static final String INBOUND_CLIENT_ID_KEY = "INBOUND_CLIENT_ID";
56      public static final String INBOUND_CONNECTION_METADATA_KEY = "INBOUND_CONNECTION_METADATA";
57      public static final String OUTBOUND_DESTINATION_NAME_KEY = "OUTBOUND_DESTINATION_NAME";
58      public static final String OUTBOUND_CLIENT_ID_KEY = "OUTBOUND_CLIENT_ID";
59      public static final String OUTBOUND_CONNECTION_METADATA_KEY = "OUTBOUND_CONNECTION_METADATA";
60       
61      private JMSDestination myInbound;
62      private JMSDestination myOutbound;
63      private Map<String, Object> myMetadata;
64      
65      /**
66       * @param theInboundDestination wrapper around the Queue or Topic to which outgoing messages 
67       *      are to be sent
68       * @param theOutboundDestination wrapper around the Queue or Topic from which incoming messages
69       *      are to be retrieved
70       */
71      public JMSTransport(JMSDestination/hl7v2/protocol/JMSDestination.html#JMSDestination">JMSDestination theInboundDestination, JMSDestination theOutboundDestination) {
72          myInbound = theInboundDestination;
73          myOutbound = theOutboundDestination;
74      }
75      
76  
77      public JMSTransport() {
78          myMetadata = makeMetadata();
79      }
80      
81      /** 
82       * Sets common metadata on the basis of connection and destination.  
83       */ 
84      private Map<String, Object> makeMetadata() {
85          Map<String, Object> md = new HashMap<>();
86          try {
87              md.put(INBOUND_CLIENT_ID_KEY, myInbound.getConnection().getClientID());
88              md.put(INBOUND_CONNECTION_METADATA_KEY, myInbound.getConnection().getMetaData());
89              md.put(INBOUND_DESTINATION_NAME_KEY, myInbound.getName());
90              md.put(OUTBOUND_CLIENT_ID_KEY, myOutbound.getConnection().getClientID());
91              md.put(OUTBOUND_CONNECTION_METADATA_KEY, myOutbound.getConnection().getMetaData());
92              md.put(OUTBOUND_DESTINATION_NAME_KEY, myOutbound.getName());
93          } catch (JMSException e) {
94              log.error("Error setting JMSTransport metadata", e);
95          }
96          return md;
97      }
98      
99  //    /**
100 //     * @param theDestination a Queue or Topic 
101 //     * @return either getQueueName() or getTopicName() 
102 //     */
103 //    private static String getName(Destination theDestination) throws JMSException {
104 //        String name = null;
105 //        
106 //        if (theDestination instanceof Queue) {
107 //            name = ((Queue) theDestination).getQueueName();
108 //        } else if (theDestination instanceof Topic) {
109 //            name = ((Topic) theDestination).getTopicName();
110 //        } else {
111 //            throw new IllegalArgumentException("We don't support Destinations of type " 
112 //                + theDestination.getClass().getName());
113 //        }
114 //        return name;
115 //    }
116 
117     /** 
118      * @see AbstractTransport#doSend(ca.uhn.hl7v2.protocol.Transportable)
119      */
120     public void doSend(Transportable theMessage) throws TransportException {
121         try {            
122             Message message = toMessage(theMessage);
123             myOutbound.send(message);
124         } catch (JMSException e) {
125             throw new TransportException(e);
126         }
127     } 
128     
129     /**
130      * Fills a JMS message object with text and metadata from the given 
131      * <code>Transportable</code>.  The default implementation obtains a 
132      * the Message from getMessage(), and expects this to be a TextMessage.   
133      * Override this method if you want to use a different message type.  
134      * 
135      * @param theSource a Transportable from which to obtain data for filling the 
136      *      given Message
137      * @return a Message containing data from the given Transportable
138      */
139     protected Message toMessage(Transportable theSource) throws TransportException {
140         TextMessage message;
141         try {
142             message = myOutbound.createMessage();
143          
144             if (message == null) {
145                 throw new TransportException("This implementation expects getMessage() to return "
146                     + " a TextMessage.  Override this method if another message type is to be used");
147             }
148 
149             message.setText(theSource.getMessage());
150 
151             for (Object key : theSource.getMetadata().keySet()) {
152                 Object val = theSource.getMetadata().get(key);
153                 message.setObjectProperty(key.toString(), val);
154             }
155         } catch (JMSException e) {
156             throw new TransportException(e);
157         }       
158         
159         return message;
160     }
161     
162     /**
163      * Copies data from the given Message into a Transportable.  The default 
164      * implementation expects a TextMessage, but this can be overridden.  
165      * 
166      * @param theMessage a JMS Message from which to obtain data  
167      * @return a Transportable containing data from the given Message
168      */
169     protected Transportable toTransportable(Message theMessage) throws TransportException {
170         if ( !(theMessage instanceof TextMessage)) {
171             throw new TransportException("This implementation expects getMessage() to return "
172                 + " a TextMessage.  Override this method if another message type is to be used");
173         }
174         
175         Transportable result;
176         try {
177             String text = ((TextMessage) theMessage).getText();
178             result = new TransportableImpl(text);
179             result.getMetadata().putAll(getCommonMetadata());
180         } catch (JMSException e) {
181             throw new TransportException(e);
182         }
183 
184         return result;
185     }
186     
187     /** 
188      * @see AbstractTransport#doReceive()
189      */
190     public Transportable doReceive() throws TransportException {
191         Transportable result;
192         try {
193             Message message = myInbound.receive();
194             result = toTransportable(message);
195         } catch (JMSException e) {
196             throw new TransportException(e);            
197         }
198         return result;
199     }
200 
201     /** 
202      * Returns metadata under the static keys defined by this class.  
203      *  
204      * @see ca.uhn.hl7v2.protocol.TransportLayer#getCommonMetadata()
205      */
206     public Map<String, Object> getCommonMetadata() {
207         return myMetadata;
208     }
209 
210     /** 
211      * @see ca.uhn.hl7v2.protocol.impl.AbstractTransport#doConnect()
212      */
213     public void doConnect() throws TransportException {
214         try {
215             myInbound.connect();
216             if (myInbound != myOutbound) {
217                 myOutbound.connect();
218             }
219         } catch (JMSException e) {
220             throw new TransportException(e);
221         }
222     }
223 
224     /** 
225      * @see ca.uhn.hl7v2.protocol.impl.AbstractTransport#doDisconnect()
226      */
227     public void doDisconnect() throws TransportException {
228         try {
229             myInbound.disconnect();
230             if (myInbound != myOutbound) {
231                 myOutbound.disconnect();
232             }
233         } catch (JMSException e) {
234             throw new TransportException(e);
235         }
236     }
237     
238 }