JMSMapMessage.java
001 /*
002  *  Licensed to the Apache Software Foundation (ASF) under one
003  *  or more contributor license agreements.  See the NOTICE file
004  *  distributed with this work for additional information
005  *  regarding copyright ownership.  The ASF licenses this file
006  *  to you under the Apache License, Version 2.0 (the
007  *  "License"); you may not use this file except in compliance
008  *  with the License.  You may obtain a copy of the License at
009  *
010  *    http://www.apache.org/licenses/LICENSE-2.0
011  *
012  *  Unless required by applicable law or agreed to in writing,
013  *  software distributed under the License is distributed on an
014  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015  *  KIND, either express or implied.  See the License for the
016  *  specific language governing permissions and limitations
017  *  under the License.
018  *
019  *
020  */
021 package org.apache.qpid.client.message;
022 
023 import org.apache.mina.common.ByteBuffer;
024 
025 import org.apache.qpid.AMQException;
026 import org.apache.qpid.framing.AMQShortString;
027 import org.apache.qpid.framing.BasicContentHeaderProperties;
028 
029 import org.slf4j.Logger;
030 import org.slf4j.LoggerFactory;
031 
032 import javax.jms.JMSException;
033 import javax.jms.MessageFormatException;
034 
035 import java.nio.charset.CharacterCodingException;
036 import java.util.Collections;
037 import java.util.Enumeration;
038 import java.util.HashMap;
039 import java.util.Map;
040 
041 public class JMSMapMessage extends AbstractBytesTypedMessage implements javax.jms.MapMessage
042 {
043     private static final Logger _logger = LoggerFactory.getLogger(JMSMapMessage.class);
044 
045     public static final String MIME_TYPE = "jms/map-message";
046 
047 
048     private Map<String, Object> _map = new HashMap<String, Object>();
049 
050     public JMSMapMessage(AMQMessageDelegateFactory delegateFactorythrows JMSException
051     {
052         this(delegateFactory, null);
053     }
054 
055     JMSMapMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer datathrows JMSException
056     {
057 
058         super(delegateFactory, data)// this instantiates a content header
059         if(data != null)
060         {
061             populateMapFromData();
062         }
063 
064     }
065 
066     JMSMapMessage(AMQMessageDelegate delegate, ByteBuffer datathrows AMQException
067     {
068 
069         super(delegate, data);
070         try
071         {
072             populateMapFromData();
073         }
074         catch (JMSException je)
075         {
076             throw new AMQException(null, "Error populating MapMessage from ByteBuffer", je);
077 
078         }
079 
080     }
081 
082 
083     public String toBodyString() throws JMSException
084     {
085         return _map == null "" : _map.toString();
086     }
087 
088     protected String getMimeType()
089     {
090         return MIME_TYPE;
091     }
092 
093     public ByteBuffer getData()
094     {
095         // What if _data is null?
096         writeMapToData();
097 
098         return super.getData();
099     }
100 
101     @Override
102     public void clearBodyImpl() throws JMSException
103     {
104         super.clearBodyImpl();
105         _map.clear();
106     }
107 
108     public boolean getBoolean(String propNamethrows JMSException
109     {
110         Object value = _map.get(propName);
111 
112         if (value instanceof Boolean)
113         {
114             return ((Booleanvalue).booleanValue();
115         }
116         else if ((value instanceof String|| (value == null))
117         {
118             return Boolean.valueOf((Stringvalue);
119         }
120         else
121         {
122             throw new MessageFormatException("Property " + propName + " of type " + value.getClass().getName()
123                 " cannot be converted to boolean.");
124         }
125 
126     }
127 
128     public byte getByte(String propNamethrows JMSException
129     {
130         Object value = _map.get(propName);
131 
132         if (value instanceof Byte)
133         {
134             return ((Bytevalue).byteValue();
135         }
136         else if ((value instanceof String|| (value == null))
137         {
138             return Byte.valueOf((Stringvalue).byteValue();
139         }
140         else
141         {
142             throw new MessageFormatException("Property " + propName + " of type " + value.getClass().getName()
143                 " cannot be converted to byte.");
144         }
145     }
146 
147     public short getShort(String propNamethrows JMSException
148     {
149         Object value = _map.get(propName);
150 
151         if (value instanceof Short)
152         {
153             return ((Shortvalue).shortValue();
154         }
155         else if (value instanceof Byte)
156         {
157             return ((Bytevalue).shortValue();
158         }
159         else if ((value instanceof String|| (value == null))
160         {
161             return Short.valueOf((Stringvalue).shortValue();
162         }
163         else
164         {
165             throw new MessageFormatException("Property " + propName + " of type " + value.getClass().getName()
166                 " cannot be converted to short.");
167         }
168 
169     }
170 
171     public int getInt(String propNamethrows JMSException
172     {
173         Object value = _map.get(propName);
174 
175         if (value instanceof Integer)
176         {
177             return ((Integervalue).intValue();
178         }
179         else if (value instanceof Short)
180         {
181             return ((Shortvalue).intValue();
182         }
183         else if (value instanceof Byte)
184         {
185             return ((Bytevalue).intValue();
186         }
187         else if ((value instanceof String|| (value == null))
188         {
189             return Integer.valueOf((Stringvalue).intValue();
190         }
191         else
192         {
193             throw new MessageFormatException("Property " + propName + " of type " + value.getClass().getName()
194                 " cannot be converted to int.");
195         }
196 
197     }
198 
199     public long getLong(String propNamethrows JMSException
200     {
201         Object value = _map.get(propName);
202 
203         if (value instanceof Long)
204         {
205             return ((Longvalue).longValue();
206         }
207         else if (value instanceof Integer)
208         {
209             return ((Integervalue).longValue();
210         }
211 
212         if (value instanceof Short)
213         {
214             return ((Shortvalue).longValue();
215         }
216 
217         if (value instanceof Byte)
218         {
219             return ((Bytevalue).longValue();
220         }
221         else if ((value instanceof String|| (value == null))
222         {
223             return Long.valueOf((Stringvalue).longValue();
224         }
225         else
226         {
227             throw new MessageFormatException("Property " + propName + " of type " + value.getClass().getName()
228                 " cannot be converted to long.");
229         }
230 
231     }
232 
233     public char getChar(String propNamethrows JMSException
234     {
235         Object value = _map.get(propName);
236 
237         if (!_map.containsKey(propName))
238         {
239             throw new MessageFormatException("Property " + propName + " not present");
240         }
241         else if (value instanceof Character)
242         {
243             return ((Charactervalue).charValue();
244         }
245         else if (value == null)
246         {
247             throw new NullPointerException("Property " + propName + " has null value and therefore cannot "
248                 "be converted to char.");
249         }
250         else
251         {
252             throw new MessageFormatException("Property " + propName + " of type " + value.getClass().getName()
253                 " cannot be converted to boolan.");
254         }
255 
256     }
257 
258     public float getFloat(String propNamethrows JMSException
259     {
260         Object value = _map.get(propName);
261 
262         if (value instanceof Float)
263         {
264             return ((Floatvalue).floatValue();
265         }
266         else if ((value instanceof String|| (value == null))
267         {
268             return Float.valueOf((Stringvalue).floatValue();
269         }
270         else
271         {
272             throw new MessageFormatException("Property " + propName + " of type " + value.getClass().getName()
273                 " cannot be converted to float.");
274         }
275     }
276 
277     public double getDouble(String propNamethrows JMSException
278     {
279         Object value = _map.get(propName);
280 
281         if (value instanceof Double)
282         {
283             return ((Doublevalue).doubleValue();
284         }
285         else if (value instanceof Float)
286         {
287             return ((Floatvalue).doubleValue();
288         }
289         else if ((value instanceof String|| (value == null))
290         {
291             return Double.valueOf((Stringvalue).doubleValue();
292         }
293         else
294         {
295             throw new MessageFormatException("Property " + propName + " of type " + value.getClass().getName()
296                 " cannot be converted to double.");
297         }
298     }
299 
300     public String getString(String propNamethrows JMSException
301     {
302         Object value = _map.get(propName);
303 
304         if ((value instanceof String|| (value == null))
305         {
306             return (Stringvalue;
307         }
308         else if (value instanceof byte[])
309         {
310             throw new MessageFormatException("Property " + propName + " of type byte[] " "cannot be converted to String.");
311         }
312         else
313         {
314             return value.toString();
315         }
316 
317     }
318 
319     public byte[] getBytes(String propNamethrows JMSException
320     {
321         Object value = _map.get(propName);
322 
323         if (!_map.containsKey(propName))
324         {
325             throw new MessageFormatException("Property " + propName + " not present");
326         }
327         else if ((value instanceof byte[]) || (value == null))
328         {
329             return (byte[]) value;
330         }
331         else
332         {
333             throw new MessageFormatException("Property " + propName + " of type " + value.getClass().getName()
334                 " cannot be converted to byte[].");
335         }
336     }
337 
338     public Object getObject(String propNamethrows JMSException
339     {
340         return _map.get(propName);
341     }
342 
343     public Enumeration getMapNames() throws JMSException
344     {
345         return Collections.enumeration(_map.keySet());
346     }
347 
348     public void setBoolean(String propName, boolean bthrows JMSException
349     {
350         checkWritable();
351         checkPropertyName(propName);
352         _map.put(propName, b);
353     }
354 
355     public void setByte(String propName, byte bthrows JMSException
356     {
357         checkWritable();
358         checkPropertyName(propName);
359         _map.put(propName, b);
360     }
361 
362     public void setShort(String propName, short ithrows JMSException
363     {
364         checkWritable();
365         checkPropertyName(propName);
366         _map.put(propName, i);
367     }
368 
369     public void setChar(String propName, char cthrows JMSException
370     {
371         checkWritable();
372         checkPropertyName(propName);
373         _map.put(propName, c);
374     }
375 
376     public void setInt(String propName, int ithrows JMSException
377     {
378         checkWritable();
379         checkPropertyName(propName);
380         _map.put(propName, i);
381     }
382 
383     public void setLong(String propName, long lthrows JMSException
384     {
385         checkWritable();
386         checkPropertyName(propName);
387         _map.put(propName, l);
388     }
389 
390     public void setFloat(String propName, float vthrows JMSException
391     {
392         checkWritable();
393         checkPropertyName(propName);
394         _map.put(propName, v);
395     }
396 
397     public void setDouble(String propName, double vthrows JMSException
398     {
399         checkWritable();
400         checkPropertyName(propName);
401         _map.put(propName, v);
402     }
403 
404     public void setString(String propName, String string1throws JMSException
405     {
406         checkWritable();
407         checkPropertyName(propName);
408         _map.put(propName, string1);
409     }
410 
411     public void setBytes(String propName, byte[] bytesthrows JMSException
412     {
413         checkWritable();
414         checkPropertyName(propName);
415         _map.put(propName, bytes);
416     }
417 
418     public void setBytes(String propName, byte[] bytes, int offset, int lengththrows JMSException
419     {
420         if ((offset == 0&& (length == bytes.length))
421         {
422             setBytes(propName, bytes);
423         }
424         else
425         {
426             byte[] newBytes = new byte[length];
427             System.arraycopy(bytes, offset, newBytes, 0, length);
428             setBytes(propName, newBytes);
429         }
430     }
431 
432     public void setObject(String propName, Object valuethrows JMSException
433     {
434         checkWritable();
435         checkPropertyName(propName);
436         if ((value instanceof Boolean|| (value instanceof Byte|| (value instanceof Short|| (value instanceof Integer)
437                 || (value instanceof Long|| (value instanceof Character|| (value instanceof Float)
438                 || (value instanceof Double|| (value instanceof String|| (value instanceof byte[]) || (value == null))
439         {
440             _map.put(propName, value);
441         }
442         else
443         {
444             throw new MessageFormatException("Cannot set property " + propName + " to value " + value + "of type "
445                 + value.getClass().getName() ".");
446         }
447     }
448 
449     private void checkPropertyName(String propName)
450     {
451         if ((propName == null|| propName.equals(""))
452         {
453             throw new IllegalArgumentException("Property name cannot be null, or the empty String.");
454         }
455     }
456 
457     public boolean itemExists(String propNamethrows JMSException
458     {
459         return _map.containsKey(propName);
460     }
461 
462     private void populateMapFromData() throws JMSException
463     {
464         if (_data != null)
465         {
466             _data.rewind();
467 
468             final int entries = readIntImpl();
469             for (int i = 0; i < entries; i++)
470             {
471                 String propName = readStringImpl();
472                 Object value = readObject();
473                 _map.put(propName, value);
474             }
475         }
476         else
477         {
478             _map.clear();
479         }
480     }
481 
482     private void writeMapToData()
483     {
484         allocateInitialBuffer();
485         final int size = _map.size();
486         writeIntImpl(size);
487         for (Map.Entry<String, Object> entry : _map.entrySet())
488         {
489             try
490             {
491                 writeStringImpl(entry.getKey());
492             }
493             catch (CharacterCodingException e)
494             {
495                 throw new IllegalArgumentException("Cannot encode property key name " + entry.getKey(), e);
496 
497             }
498 
499             try
500             {
501                 writeObject(entry.getValue());
502             }
503             catch (JMSException e)
504             {
505                 Object value = entry.getValue();
506                 throw new IllegalArgumentException("Cannot encode property key name " + entry.getKey() " value : " + value
507                     " (type: " + value.getClass().getName() ").", e);
508             }
509         }
510 
511     }
512 
513 }