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     /* (non-Javadoc)
105      * @see java.util.HashMap#clear()
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     /* (non-Javadoc)
136      * @see java.util.HashMap#put(java.lang.Object, java.lang.Object)
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     /* (non-Javadoc)
154      * @see java.util.HashMap#putAll(java.util.Map)
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     /* (non-Javadoc)
168      * @see java.util.HashMap#remove(java.lang.Object)
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     /* (non-Javadoc)
184      * @see java.util.HashMap#entrySet()
185      */
186     public Set<java.util.Map.Entry<String, Object>> entrySet()
187     {
188         return Collections.unmodifiableSet(super.entrySet());
189     }
190 
191     /* ------------------------------------------------------------ */
192     /* (non-Javadoc)
193      * @see java.util.HashMap#keySet()
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 }