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 }