View Javadoc

1   /*
2    * $Id: XmppMessageReceiver.java 7976 2007-08-21 14:26:13Z 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.config.i18n.CoreMessages;
14  import org.mule.impl.MuleMessage;
15  import org.mule.impl.RequestContext;
16  import org.mule.providers.AbstractConnector;
17  import org.mule.providers.AbstractMessageReceiver;
18  import org.mule.providers.ConnectException;
19  import org.mule.umo.UMOComponent;
20  import org.mule.umo.UMOException;
21  import org.mule.umo.UMOMessage;
22  import org.mule.umo.endpoint.UMOEndpoint;
23  import org.mule.umo.lifecycle.InitialisationException;
24  import org.mule.umo.provider.UMOMessageAdapter;
25  
26  import javax.resource.spi.work.Work;
27  import javax.resource.spi.work.WorkException;
28  import javax.resource.spi.work.WorkManager;
29  
30  import org.jivesoftware.smack.PacketListener;
31  import org.jivesoftware.smack.XMPPConnection;
32  import org.jivesoftware.smack.XMPPException;
33  import org.jivesoftware.smack.filter.PacketFilter;
34  import org.jivesoftware.smack.filter.PacketTypeFilter;
35  import org.jivesoftware.smack.packet.Message;
36  import org.jivesoftware.smack.packet.Packet;
37  
38  /**
39   * <code>XmppMessageReceiver</code> is responsible for receiving Mule events over XMPP.
40   */
41  public class XmppMessageReceiver extends AbstractMessageReceiver implements PacketListener
42  {
43      private XMPPConnection xmppConnection = null;
44  
45      public XmppMessageReceiver(AbstractConnector connector, UMOComponent component, UMOEndpoint endpoint)
46          throws InitialisationException
47      {
48          super(connector, component, endpoint);
49      }
50  
51      protected void doConnect() throws Exception
52      {
53          try
54          {
55              XmppConnector cnn = (XmppConnector)connector;
56              xmppConnection = cnn.createXmppConnection(endpoint.getEndpointURI());
57              if (endpoint.getFilter() instanceof PacketFilter)
58              {
59                  xmppConnection.addPacketListener(this, (PacketFilter)endpoint.getFilter());
60              }
61              else
62              {
63                  PacketFilter filter = new PacketTypeFilter(Message.class);
64                  xmppConnection.addPacketListener(this, filter);
65              }
66          }
67          catch (XMPPException e)
68          {
69              throw new ConnectException(CoreMessages.failedToCreate("XMPP Connection"), e, this);
70          }
71      }
72  
73      protected void doDisconnect() throws Exception
74      {
75          if (xmppConnection != null)
76          {
77              xmppConnection.removePacketListener(this);
78              xmppConnection.close();
79          }
80      }
81  
82      protected void doStart() throws UMOException
83      {
84          // nothing to do
85      }
86  
87      protected void doStop() throws UMOException
88      {
89          // nothing to do
90      }
91  
92      protected void doDispose()
93      {
94          // nothing to do
95      }
96  
97      protected Work createWork(Packet message)
98      {
99          return new XMPPWorker(message);
100     }
101 
102     /**
103      * @see org.jivesoftware.smack.PacketListener#processPacket(org.jivesoftware.smack.packet.Packet)
104      */
105     public void processPacket(Packet packet)
106     {
107         if (logger.isDebugEnabled())
108         {
109             logger.debug("processing packet: " + packet.toXML());
110         }
111 
112         Work work = createWork(packet);
113         try
114         {
115             getWorkManager().scheduleWork(work, WorkManager.INDEFINITE, null, connector);
116         }
117         catch (WorkException e)
118         {
119             logger.error("Xmpp Server receiver work failed: " + e.getMessage(), e);
120         }
121     }
122 
123     private class XMPPWorker implements Work
124     {
125         Packet packet = null;
126 
127         public XMPPWorker(Packet message)
128         {
129             this.packet = message;
130         }
131 
132         /**
133          * Accept requests from a given TCP port
134          */
135         public void run()
136         {
137             try
138             {
139                 UMOMessageAdapter adapter = connector.getMessageAdapter(packet);
140 
141                 if (logger.isDebugEnabled())
142                 {
143                     logger.debug("Processing XMPP packet from: " + packet.getFrom());
144                     logger.debug("UMOMessageAdapter is a: " + adapter.getClass().getName());
145                 }
146 
147                 UMOMessage returnMessage = routeMessage(new MuleMessage(adapter), endpoint.isSynchronous());
148 
149                 if (returnMessage != null && packet instanceof Message)
150                 {
151                     RequestContext.rewriteEvent(returnMessage);
152                     Packet result = (Packet)connector.getDefaultResponseTransformer().transform(
153                         returnMessage.getPayload());
154                     xmppConnection.sendPacket(result);
155                 }
156             }
157             catch (Exception e)
158             {
159                 handleException(e);
160             }
161         }
162 
163         public void release()
164         {
165             // template method
166         }
167     }
168 }