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