View Javadoc

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