1 package org.mortbay.cometd.ext;
2
3 import java.util.Map;
4 import java.util.Queue;
5
6 import org.cometd.Bayeux;
7 import org.cometd.Client;
8 import org.cometd.Extension;
9 import org.cometd.Message;
10 import org.mortbay.cometd.MessageImpl;
11 import org.mortbay.util.ArrayIdQueue;
12 import org.mortbay.util.ArrayIdQueue.ArrayIdIterator;
13
14 public class AcknowledgedMessagesClientExtension implements Extension
15 {
16 private final ArrayIdQueue<Message> _unackedQueue=new ArrayIdQueue<Message>(8,16,this);
17 public Message rcv(Client from, Message message)
18 {
19 return message;
20 }
21
22 public Message rcvMeta(Client from, Message message)
23 {
24 if (message.getChannel().equals(Bayeux.META_CONNECT))
25 {
26 Map<String, Object> ext=(Map<String, Object>) message.get(Bayeux.EXT_FIELD);
27 if (ext != null)
28 {
29 Long acked=(Long) ext.get("ack");
30 if (acked != null)
31 {
32 ArrayIdIterator it=_unackedQueue.idIterator();
33 MessageImpl queuedMessage=null;
34 while (it.hasNext())
35 {
36 queuedMessage=(MessageImpl)it.next();
37 long messageBatchId=it.associatedId();
38 if (acked >= messageBatchId)
39 {
40 queuedMessage.decRef();
41 it.remove();
42 }
43 }
44 }
45 }
46
47
48 Queue<Message> messages=from.getQueue();
49
50 messages.addAll(_unackedQueue);
51 _unackedQueue.clear();
52 }
53
54 return message;
55 }
56
57 public Message send(Client from, Message message)
58 {
59 _unackedQueue.add(message);
60
61 ((MessageImpl) message).incRef();
62
63 return message;
64 }
65
66 public Message sendMeta(Client from, Message message)
67 {
68 if ( (message.getChannel().equals(Bayeux.META_CONNECT) && from.getQueue().size()>0 )
69 || message.getChannel().equals(Bayeux.META_SUBSCRIBE))
70 {
71 _unackedQueue.incrementCurrentId();
72
73 Map<String, Object> ext= message.getExt(true);
74 ext.put("ack",_unackedQueue.getCurrentId());
75 message.put(Bayeux.EXT_FIELD,ext);
76 }
77 return message;
78 }
79 }