View Javadoc

1   /*
2    * $Id: AjaxMessageDispatcher.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.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  package org.mule.transport.ajax;
11  
12  import org.mule.api.MuleEvent;
13  import org.mule.api.MuleMessage;
14  import org.mule.api.endpoint.OutboundEndpoint;
15  import org.mule.api.lifecycle.CreateException;
16  import org.mule.api.lifecycle.InitialisationException;
17  import org.mule.transport.AbstractMessageDispatcher;
18  import org.mule.transport.NullPayload;
19  import org.mule.transport.ajax.i18n.AjaxMessages;
20  import org.mule.util.MapUtils;
21  import org.mule.util.StringUtils;
22  
23  import org.apache.commons.collections.Buffer;
24  import org.apache.commons.collections.buffer.BoundedFifoBuffer;
25  import org.cometd.Channel;
26  import org.cometd.Client;
27  import org.mortbay.cometd.AbstractBayeux;
28  
29  /**
30   * Will dispatch Mule events to ajax clients available in Bayeux that are listening to this endpoint.
31   */
32  public class AjaxMessageDispatcher extends AbstractMessageDispatcher implements BayeuxAware
33  {
34      protected AbstractBayeux bayeux;
35  
36      protected boolean cacheMessages = false;
37  
38      protected int messageCacheSize = 500;
39  
40      protected Buffer messageCache;
41  
42      protected String channel;
43  
44      protected Client client;
45  
46      public AjaxMessageDispatcher(OutboundEndpoint endpoint) throws CreateException
47      {
48          super(endpoint);
49          cacheMessages = MapUtils.getBoolean(endpoint.getProperties(), "cacheMessages", false);
50          messageCacheSize = MapUtils.getInteger(endpoint.getProperties(), "messageCacheSize", 500);
51          channel = endpoint.getEndpointURI().getPath();
52          if(StringUtils.isEmpty(channel) || channel.equals("/"))
53          {
54              //TODO i18n
55              throw new CreateException(AjaxMessages.createStaticMessage("The subscription path cannot be empty or equal '/'"), this);
56          }
57      }
58  
59      public AbstractBayeux getBayeux()
60      {
61          return bayeux;
62      }
63  
64      public void setBayeux(AbstractBayeux bayeux)
65      {
66          this.bayeux = bayeux;
67      }
68  
69      @Override
70      protected void doInitialise() throws InitialisationException
71      {
72          if (cacheMessages)
73          {
74              messageCache = new BoundedFifoBuffer(messageCacheSize);
75          }
76      }
77  
78      protected Client getClient()
79      {
80          if(client == null)
81          {
82              client = bayeux.newClient(channel);
83          }
84          return client;
85      }
86  
87      protected void doDispatch(MuleEvent event) throws Exception
88      {
89          //We have no need for Null messages to be sent to the browser
90          if(NullPayload.getInstance().equals(event.getMessage().getPayload()))
91          {
92              return;
93          }
94          if (!connector.isStarted())
95          {
96              //TODO MULE-4320
97              logger.warn("Servlet container has not yet initialised, ignoring event: " + event.getMessage().getPayload());
98              return;
99          }
100 
101         Channel chan = bayeux.getChannel(channel);
102         if(chan!=null)
103         {
104             if (chan.getSubscribers().size() > 0 && cacheMessages && !messageCache.isEmpty())
105             {
106                 while (!messageCache.isEmpty())
107                 {
108                     for (Client client : chan.getSubscribers())
109                     {
110                         deliver(client, channel, messageCache.remove());
111                     }
112                     //deliver(getClient(), channel, messageCache.remove());
113                 }
114             }
115 
116             Object data = event.getMessage().getPayload();
117             //deliver(getClient(), channel, data);
118             for (Client client : chan.getSubscribers())
119             {
120                 deliver(client, channel, data);
121             }
122         }
123         else if (cacheMessages)
124         {
125             Object data = event.getMessage().getPayload();
126             if (logger.isTraceEnabled())
127             {
128                 logger.trace("There are no clients waiting, adding message to cache: " + data);
129             }
130             messageCache.add(data);
131         }
132     }
133 
134     protected void deliver(Client client, String channel, Object data)
135     {
136         if (logger.isTraceEnabled())
137         {
138             logger.trace("Delivering to client id: " + client.getId() + " channel:" + channel);
139         }
140         client.deliver(client, channel, data, null);
141     }
142 
143     protected MuleMessage doSend(MuleEvent event) throws Exception
144     {
145         doDispatch(event);
146         return null;
147     }
148 
149     @Override
150     protected void doDispose()
151     {
152         if (messageCache != null)
153         {
154             messageCache.clear();
155             messageCache = null;
156         }
157     }
158 }