View Javadoc

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     /* (non-Javadoc)
114      * @see java.util.HashMap#clear()
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     /* (non-Javadoc)
147      * @see java.util.HashMap#put(java.lang.Object, java.lang.Object)
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     /* (non-Javadoc)
167      * @see java.util.HashMap#putAll(java.util.Map)
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     /* (non-Javadoc)
183      * @see java.util.HashMap#remove(java.lang.Object)
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     /* (non-Javadoc)
201      * @see java.util.HashMap#entrySet()
202      */
203     @Override
204     public Set<java.util.Map.Entry<String, Object>> entrySet()
205     {
206         return Collections.unmodifiableSet(super.entrySet());
207     }
208 
209     /* ------------------------------------------------------------ */
210     /* (non-Javadoc)
211      * @see java.util.HashMap#keySet()
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      * @param buffer A cached buffer containing HTTP response headers 
241      * and message content, to be reused when sending one message
242      * to multiple clients 
243      */
244     public void setBuffer(ByteBuffer buffer)
245     {
246         _buffer = buffer;
247     }
248     
249     /* ------------------------------------------------------------ */
250     public ByteBuffer getBuffer()
251     {
252         return _buffer;
253     }
254 }