View Javadoc

1   package org.mortbay.cometd;
2   
3   import java.io.IOException;
4   import java.io.Reader;
5   import java.util.HashMap;
6   import java.util.List;
7   import java.util.Map;
8   
9   import org.cometd.Bayeux;
10  import org.cometd.Message;
11  import org.mortbay.util.ArrayQueue;
12  import org.mortbay.util.StringMap;
13  import org.mortbay.util.ajax.JSON;
14  import org.omg.CORBA._PolicyStub;
15  
16  
17  public class MessagePool 
18  {
19      final private ArrayQueue<MessageImpl> _messagePool;
20      final private ArrayQueue<JSON.ReaderSource> _readerPool;
21  
22      /* ------------------------------------------------------------ */
23      public MessagePool()
24      {
25          this(50);
26      }
27  
28      /* ------------------------------------------------------------ */
29      public MessagePool(int capacity)
30      {
31          _messagePool=new ArrayQueue<MessageImpl>(capacity,capacity);
32          _readerPool=new ArrayQueue<JSON.ReaderSource>(capacity,capacity);
33      }
34      
35      /* ------------------------------------------------------------ */
36      /**
37       * @return the {@link JSON} instance used to convert data and ext fields
38       */
39      public JSON getJSON()
40      {
41          return _json;
42      }
43  
44      /* ------------------------------------------------------------ */
45      /**
46       * @param json the {@link JSON} instance used to convert data and ext fields
47       */
48      public void setJSON(JSON json)
49      {
50          _json=json;
51      }
52  
53      /* ------------------------------------------------------------ */
54      /**
55       * @return the {@link JSON} instance used to serialize and deserialize bayeux bayeux messages
56       */
57      public JSON getMsgJSON()
58      {
59          return _msgJSON;
60      }
61  
62      /* ------------------------------------------------------------ */
63      /**
64       * @param msgJSON the {@link JSON} instance used to serialize and deserialize bayeux messages
65       */
66      public void setMsgJSON(JSON msgJSON)
67      {
68          _msgJSON=msgJSON;
69      }
70  
71      /* ------------------------------------------------------------ */
72      /**
73       * @return the {@link JSON} instance used to deserialize batches of bayeux messages
74       */
75      public JSON getBatchJSON()
76      {
77          return _batchJSON;
78      }
79  
80      /* ------------------------------------------------------------ */
81      /**
82       * @param batchJSON the {@link JSON} instance used to convert batches of bayeux messages
83       */
84      public void setBatchJSON(JSON batchJSON)
85      {
86          _batchJSON=batchJSON;
87      }
88  
89  
90      /* ------------------------------------------------------------ */
91      public MessageImpl newMessage()
92      {
93          MessageImpl message=_messagePool.poll();
94          if (message==null)
95          {
96              message=new MessageImpl(this);
97          }
98          message.incRef();
99          return message;
100     }
101 
102     /* ------------------------------------------------------------ */
103     public MessageImpl newMessage(Message associated)
104     {
105         MessageImpl message=_messagePool.poll();
106         if (message==null)
107         {
108             message=new MessageImpl(this);
109         }
110         message.incRef();
111         if (associated!=null)
112             message.setAssociated(associated);
113         return message;
114     }
115 
116     /* ------------------------------------------------------------ */
117     void recycleMessage(MessageImpl message)
118     {
119         message.clear();
120         _messagePool.offer(message);
121     }
122 
123     /* ------------------------------------------------------------ */
124     public Message[] parse(Reader reader) throws IOException
125     {
126         JSON.ReaderSource source =_readerPool.poll();
127         if (source==null)
128             source=new JSON.ReaderSource(reader);
129         else
130             source.setReader(reader);
131         
132         Object batch=_batchJSON.parse(source);
133         _readerPool.offer(source);
134 
135         if (batch==null)
136             return new Message[0]; 
137         if (batch.getClass().isArray())
138             return (Message[])batch;
139         return new Message[]{(Message)batch};
140     }
141 
142     /* ------------------------------------------------------------ */
143     public Message[] parse(String s) throws IOException
144     {
145         Object batch=_batchJSON.parse(new JSON.StringSource(s));
146         if (batch==null)
147             return new Message[0]; 
148         if (batch.getClass().isArray())
149             return (Message[])batch;
150         return new Message[]{(Message)batch};
151     }
152 
153     /* ------------------------------------------------------------ */
154     public void parseTo(String fodder, List<Message> messages)
155     {
156         Object batch=_batchJSON.parse(new JSON.StringSource(fodder));
157         if (batch==null)
158             return;
159         if (batch.getClass().isArray())
160         {
161             Message[] msgs=(Message[])batch;
162             for (int m=0;m<msgs.length;m++)
163                 messages.add(msgs[m]);
164         }
165         else
166             messages.add((Message)batch);
167     }
168 
169     /* ------------------------------------------------------------ */
170     public String toString()
171     {
172         return "MessagePool:"+_messagePool.size()+"/"+_messagePool.getCapacity();
173         
174     }
175     
176     /* ------------------------------------------------------------ */
177     /* ------------------------------------------------------------ */
178     private StringMap _fieldStrings = new StringMap();
179     private StringMap _valueStrings = new StringMap();
180     {
181         _fieldStrings.put(Bayeux.ADVICE_FIELD,Bayeux.ADVICE_FIELD);
182         _fieldStrings.put(Bayeux.CHANNEL_FIELD,Bayeux.CHANNEL_FIELD);
183         _fieldStrings.put(Bayeux.CLIENT_FIELD,Bayeux.CLIENT_FIELD);
184         _fieldStrings.put(Bayeux.DATA_FIELD,Bayeux.DATA_FIELD);
185         _fieldStrings.put(Bayeux.ERROR_FIELD,Bayeux.ERROR_FIELD);
186         _fieldStrings.put(Bayeux.EXT_FIELD,Bayeux.EXT_FIELD);
187         _fieldStrings.put(Bayeux.ID_FIELD,Bayeux.ID_FIELD);
188         _fieldStrings.put(Bayeux.SUBSCRIPTION_FIELD,Bayeux.SUBSCRIPTION_FIELD);
189         _fieldStrings.put(Bayeux.SUCCESSFUL_FIELD,Bayeux.SUCCESSFUL_FIELD);
190         _fieldStrings.put(Bayeux.TIMESTAMP_FIELD,Bayeux.TIMESTAMP_FIELD);
191         _fieldStrings.put(Bayeux.TRANSPORT_FIELD,Bayeux.TRANSPORT_FIELD);
192         _fieldStrings.put("connectionType","connectionType");
193         
194         _valueStrings.put(Bayeux.META_CLIENT,Bayeux.META_CLIENT);
195         _valueStrings.put(Bayeux.META_CONNECT,Bayeux.META_CONNECT);
196         _valueStrings.put(Bayeux.META_DISCONNECT,Bayeux.META_DISCONNECT);
197         _valueStrings.put(Bayeux.META_HANDSHAKE,Bayeux.META_HANDSHAKE);
198         _valueStrings.put(Bayeux.META_SUBSCRIBE,Bayeux.META_SUBSCRIBE);
199         _valueStrings.put(Bayeux.META_UNSUBSCRIBE,Bayeux.META_UNSUBSCRIBE);
200         _valueStrings.put("long-polling","long-polling");
201     }
202     
203 
204     /* ------------------------------------------------------------ */
205     /* ------------------------------------------------------------ */
206     private JSON _json = new JSON()
207     {
208         @Override
209         protected Map newMap()
210         {
211             return new HashMap(8);
212         }
213         
214         @Override
215         protected String toString(char[] buffer, int offset, int length)
216         {
217             Map.Entry entry = _valueStrings.getEntry(buffer,offset,length);
218             if (entry!=null)
219                 return (String)entry.getValue();
220             String s= new String(buffer,offset,length);
221             return s;
222         }
223     };
224 
225     /* ------------------------------------------------------------ */
226     /* ------------------------------------------------------------ */
227     private JSON _msgJSON = new JSON()
228     {
229         @Override
230         protected Map newMap()
231         {
232             return newMessage();
233         }
234 
235         @Override
236         protected String toString(char[] buffer, int offset, int length)
237         {
238             Map.Entry entry = _fieldStrings.getEntry(buffer,offset,length);
239             if (entry!=null)
240                 return (String)entry.getValue();
241             
242             String s= new String(buffer,offset,length);
243             return s;
244         }
245 
246         @Override
247         protected JSON contextFor(String field)
248         {
249             return _json;
250         }
251     };
252 
253     /* ------------------------------------------------------------ */
254     /* ------------------------------------------------------------ */
255     private JSON _batchJSON = new JSON()
256     {
257         @Override
258         protected Map newMap()
259         {
260             return newMessage();
261         }
262 
263         @Override
264         protected Object[] newArray(int size)
265         {
266             return new Message[size]; // todo recycle
267         }
268 
269         @Override
270         protected JSON contextFor(String field)
271         {
272             return _json;
273         }
274 
275         @Override
276         protected JSON contextForArray()
277         {
278             return _msgJSON;
279         }
280     };
281 
282 }