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