View Javadoc

1   /*
2    * $Id: XmppMessageDispatcher.java 10114 2007-12-19 11:29:22Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.providers.xmpp;
12  
13  import org.mule.impl.MuleMessage;
14  import org.mule.providers.AbstractMessageDispatcher;
15  import org.mule.umo.UMOEvent;
16  import org.mule.umo.UMOMessage;
17  import org.mule.umo.endpoint.MalformedEndpointException;
18  import org.mule.umo.endpoint.UMOEndpointURI;
19  import org.mule.umo.endpoint.UMOImmutableEndpoint;
20  
21  import org.jivesoftware.smack.Chat;
22  import org.jivesoftware.smack.GroupChat;
23  import org.jivesoftware.smack.XMPPConnection;
24  import org.jivesoftware.smack.packet.Message;
25  
26  /**
27   * <code>XmppMessageDispatcher</code> allows Mule events to be sent and received
28   * over Xmpp
29   */
30  
31  public class XmppMessageDispatcher extends AbstractMessageDispatcher
32  {
33      private final XmppConnector connector;
34      private volatile XMPPConnection xmppConnection = null;
35      private volatile Chat chat;
36      private volatile GroupChat groupChat;
37  
38      public XmppMessageDispatcher(UMOImmutableEndpoint endpoint)
39      {
40          super(endpoint);
41          this.connector = (XmppConnector)endpoint.getConnector();
42      }
43  
44      protected void doConnect() throws Exception
45      {
46          if (xmppConnection == null)
47          {
48              UMOEndpointURI uri = endpoint.getEndpointURI();
49              xmppConnection = connector.createXmppConnection(uri);
50          }
51      }
52  
53      protected void doDisconnect() throws Exception
54      {
55          try
56          {
57              if (groupChat != null)
58              {
59                  groupChat.leave();
60              }
61              if (xmppConnection != null)
62              {
63                  xmppConnection.close();
64              }
65          }
66          finally
67          {
68              xmppConnection = null;
69          }
70      }
71  
72      protected void doDispose()
73      {
74          // template method
75      }
76  
77      protected void doDispatch(UMOEvent event) throws Exception
78      {
79          sendMessage(event);
80      }
81  
82      protected UMOMessage doSend(UMOEvent event) throws Exception
83      {
84          sendMessage(event);
85  
86          if (useRemoteSync(event))
87          {
88              Message response;
89  
90              if (groupChat != null)
91              {
92                  response = groupChat.nextMessage(event.getTimeout());
93              }
94              else
95              {
96                  response = chat.nextMessage(event.getTimeout());
97              }
98  
99              if (response != null)
100             {
101                 if (logger.isDebugEnabled())
102                 {
103                     logger.debug("Got a response from chat: " + chat);
104                 }
105                 return new MuleMessage(connector.getMessageAdapter(response));
106             }
107         }
108         return null;
109     }
110 
111     protected void sendMessage(UMOEvent event) throws Exception
112     {
113         if (chat == null && groupChat == null)
114         {
115             UMOMessage msg = event.getMessage();
116             boolean group = msg.getBooleanProperty(XmppConnector.XMPP_GROUP_CHAT, false);
117             String nickname = msg.getStringProperty(XmppConnector.XMPP_NICKNAME, "mule");
118             String recipient = event.getEndpoint().getEndpointURI().getPath().substring(1);
119 
120             if (group)
121             {
122                 groupChat = new GroupChat(xmppConnection, recipient);
123                 if (!groupChat.isJoined())
124                 {
125                     groupChat.join(nickname);
126                 }
127             }
128             else
129             {
130                 chat = new Chat(xmppConnection, recipient);
131             }
132         }
133 
134         Object msgObj = event.getMessage().getPayload();
135         Message message;
136         // avoid duplicate transformation
137         if (!(msgObj instanceof Message))
138         {
139             message = (Message)event.getTransformedMessage();
140         }
141         else
142         {
143             message = (Message)msgObj;
144         }
145 
146         if (logger.isTraceEnabled())
147         {
148             logger.trace("Transformed packet: " + message.toXML());
149         }
150 
151         // if the endpoint specified a designated recipient, use that
152         if (message.getTo() != null)
153         {
154             xmppConnection.sendPacket(message);
155         }
156         else if (chat != null)
157         {
158             chat.sendMessage(message);
159         }
160         else
161         {
162             groupChat.sendMessage(message);
163         }
164 
165         if (logger.isDebugEnabled())
166         {
167             logger.debug("Packet successfully sent");
168         }
169     }
170 
171     /**
172      * Make a specific request to the underlying transport
173      * 
174      * @param endpoint the endpoint to use when connecting to the resource
175      * @param timeout the maximum time the operation should block before returning.
176      *            The call should return immediately if there is data available. If
177      *            no data becomes available before the timeout elapses, null will be
178      *            returned
179      * @return the result of the request wrapped in a UMOMessage object. Null will be
180      *         returned if no data was avaialable
181      * @throws Exception if the call to the underlying protocal cuases an exception
182      */
183     protected UMOMessage doReceive(long timeout) throws Exception
184     {
185         // Should be in the form of xmpp://user:pass@host:[port]/folder
186         String to = (String)endpoint.getProperty("folder");
187         if (to == null)
188         {
189             throw new MalformedEndpointException(endpoint.getEndpointURI().toString());
190         }
191         Chat chat = xmppConnection.createChat(to);
192         Message message = null;
193         if (timeout == UMOEvent.TIMEOUT_WAIT_FOREVER)
194         {
195             message = chat.nextMessage();
196         }
197         else if (timeout == UMOEvent.TIMEOUT_DO_NOT_WAIT)
198         {
199             message = chat.nextMessage(1);
200         }
201         else
202         {
203             message = chat.nextMessage(timeout);
204         }
205         if (message != null)
206         {
207             return new MuleMessage(connector.getMessageAdapter(message));
208         }
209         else
210         {
211             return null;
212         }
213     }
214 
215 }