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
38
39 public JSON getJSON()
40 {
41 return _json;
42 }
43
44
45
46
47
48 public void setJSON(JSON json)
49 {
50 _json=json;
51 }
52
53
54
55
56
57 public JSON getMsgJSON()
58 {
59 return _msgJSON;
60 }
61
62
63
64
65
66 public void setMsgJSON(JSON msgJSON)
67 {
68 _msgJSON=msgJSON;
69 }
70
71
72
73
74
75 public JSON getBatchJSON()
76 {
77 return _batchJSON;
78 }
79
80
81
82
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];
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 }