View Javadoc

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