1 package org.mortbay.cometd;
2
3 import java.nio.ByteBuffer;
4 import java.util.Collections;
5 import java.util.HashMap;
6 import java.util.Iterator;
7 import java.util.Map;
8 import java.util.Set;
9 import java.util.concurrent.atomic.AtomicInteger;
10
11 import org.cometd.Bayeux;
12 import org.cometd.Message;
13 import org.mortbay.util.ajax.JSON;
14
15
16 public class MessageImpl extends HashMap<String, Object> implements Message, org.mortbay.util.ajax.JSON.Generator
17 {
18 MessagePool _pool;
19 String _clientId;
20 String _json;
21 String _channel;
22 String _id;
23 Object _data;
24 Message _associated;
25 AtomicInteger _refs=new AtomicInteger();
26
27 private ByteBuffer _buffer;
28
29
30 public MessageImpl()
31 {
32 super(8);
33 }
34
35
36 public MessageImpl(MessagePool bayeux)
37 {
38 super(8);
39 _pool=bayeux;
40 }
41
42
43 public int getRefs()
44 {
45 return _refs.get();
46 }
47
48
49 public void incRef()
50 {
51 _refs.getAndIncrement();
52 }
53
54
55 public void decRef()
56 {
57 int r= _refs.decrementAndGet();
58 if (r==0 && _pool!=null)
59 _pool.recycleMessage(this);
60 else if (r<0)
61 throw new IllegalStateException();
62 }
63
64
65 public String getChannel()
66 {
67 return _channel;
68 }
69
70
71 public String getClientId()
72 {
73 if (_clientId==null)
74 _clientId=(String)get(Bayeux.CLIENT_FIELD);
75 return _clientId;
76 }
77
78
79 public String getId()
80 {
81 return _id;
82 }
83
84
85 public Object getData()
86 {
87 return _data;
88 }
89
90
91 public void addJSON(StringBuffer buffer)
92 {
93 buffer.append(getJSON());
94 }
95
96
97 public String getJSON()
98 {
99 if (_json==null)
100 {
101 JSON json=_pool==null?JSON.getDefault():_pool.getMsgJSON();
102 StringBuffer buf = new StringBuffer(json.getStringBufferSize());
103 synchronized(buf)
104 {
105 json.appendMap(buf,this);
106 _json=buf.toString();
107 }
108 }
109 return _json;
110 }
111
112
113
114
115
116 @Override
117 public void clear()
118 {
119 _json=null;
120 _buffer=null;
121 _id=null;
122 _channel=null;
123 _clientId=null;
124 setAssociated(null);
125 _refs.set(0);
126 Iterator<Map.Entry<String,Object>> iterator=super.entrySet().iterator();
127 while(iterator.hasNext())
128 {
129 Map.Entry<String, Object> entry=iterator.next();
130 String key=entry.getKey();
131 if (Bayeux.CHANNEL_FIELD.equals(key))
132 entry.setValue(null);
133 else if (Bayeux.ID_FIELD.equals(key))
134 entry.setValue(null);
135 else if (Bayeux.TIMESTAMP_FIELD.equals(key))
136 entry.setValue(null);
137 else if (Bayeux.DATA_FIELD.equals(key))
138 entry.setValue(null);
139 else
140 iterator.remove();
141 }
142 super.clear();
143 }
144
145
146
147
148
149 @Override
150 public Object put(String key, Object value)
151 {
152 _json=null;
153 _buffer=null;
154 if (Bayeux.CHANNEL_FIELD.equals(key))
155 _channel=(String)value;
156 else if (Bayeux.ID_FIELD.equals(key))
157 _id=value.toString();
158 else if (Bayeux.CLIENT_FIELD.equals(key))
159 _clientId=(String)value;
160 else if (Bayeux.DATA_FIELD.equals(key))
161 _data=value;
162 return super.put(key,value);
163 }
164
165
166
167
168
169 @Override
170 public void putAll(Map<? extends String, ? extends Object> m)
171 {
172 _json=null;
173 _buffer=null;
174 super.putAll(m);
175 _channel=(String)get(Bayeux.CHANNEL_FIELD);
176 Object id=get(Bayeux.ID_FIELD);
177 _id=id==null?null:id.toString();
178 _data=get(Bayeux.DATA_FIELD);
179 }
180
181
182
183
184
185 @Override
186 public Object remove(Object key)
187 {
188 _json=null;
189 _buffer=null;
190 if (Bayeux.CHANNEL_FIELD.equals(key))
191 _channel=null;
192 else if (Bayeux.ID_FIELD.equals(key))
193 _id=null;
194 else if (Bayeux.DATA_FIELD.equals(key))
195 _data=null;
196 return super.remove(key);
197 }
198
199
200
201
202
203 @Override
204 public Set<java.util.Map.Entry<String, Object>> entrySet()
205 {
206 return Collections.unmodifiableSet(super.entrySet());
207 }
208
209
210
211
212
213 @Override
214 public Set<String> keySet()
215 {
216 return Collections.unmodifiableSet(super.keySet());
217 }
218
219
220 public Message getAssociated()
221 {
222 return _associated;
223 }
224
225
226 public void setAssociated(Message associated)
227 {
228 if (_associated!=associated)
229 {
230 if (_associated!=null)
231 ((MessageImpl)_associated).decRef();
232 _associated=associated;
233 if (_associated!=null)
234 ((MessageImpl)_associated).incRef();
235 }
236 }
237
238
239
240
241
242
243
244 public void setBuffer(ByteBuffer buffer)
245 {
246 _buffer = buffer;
247 }
248
249
250 public ByteBuffer getBuffer()
251 {
252 return _buffer;
253 }
254 }