View Javadoc

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          // prevent the message from being erased
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  }