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