You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ro...@apache.org on 2014/05/13 18:46:53 UTC

svn commit: r1594278 - in /qpid/jms/trunk/src: main/java/org/apache/qpid/jms/engine/ main/java/org/apache/qpid/jms/impl/ test/java/org/apache/qpid/jms/engine/ test/java/org/apache/qpid/jms/impl/

Author: robbie
Date: Tue May 13 16:46:53 2014
New Revision: 1594278

URL: http://svn.apache.org/r1594278
Log:
QPIDJMS-21: initial work on implementing the MapMessage interface

Added:
    qpid/jms/trunk/src/test/java/org/apache/qpid/jms/engine/AmqpMapMessageTest.java
    qpid/jms/trunk/src/test/java/org/apache/qpid/jms/impl/MapMessageImplTest.java
Modified:
    qpid/jms/trunk/src/main/java/org/apache/qpid/jms/engine/AmqpMapMessage.java
    qpid/jms/trunk/src/main/java/org/apache/qpid/jms/engine/AmqpMessage.java
    qpid/jms/trunk/src/main/java/org/apache/qpid/jms/impl/MapMessageImpl.java
    qpid/jms/trunk/src/test/java/org/apache/qpid/jms/impl/ObjectMessageImplTest.java

Modified: qpid/jms/trunk/src/main/java/org/apache/qpid/jms/engine/AmqpMapMessage.java
URL: http://svn.apache.org/viewvc/qpid/jms/trunk/src/main/java/org/apache/qpid/jms/engine/AmqpMapMessage.java?rev=1594278&r1=1594277&r2=1594278&view=diff
==============================================================================
--- qpid/jms/trunk/src/main/java/org/apache/qpid/jms/engine/AmqpMapMessage.java (original)
+++ qpid/jms/trunk/src/main/java/org/apache/qpid/jms/engine/AmqpMapMessage.java Tue May 13 16:46:53 2014
@@ -18,18 +18,109 @@
  */
 package org.apache.qpid.jms.engine;
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.qpid.proton.amqp.messaging.AmqpValue;
+import org.apache.qpid.proton.amqp.messaging.Section;
 import org.apache.qpid.proton.engine.Delivery;
 import org.apache.qpid.proton.message.Message;
 
 public class AmqpMapMessage extends AmqpMessage
 {
+    private volatile Map<String,Object> _messageBodyMap;
+
     public AmqpMapMessage()
     {
         super();
+        initialiseMessageBodyMap();
     }
 
+    @SuppressWarnings("unchecked")
     public AmqpMapMessage(Message message, Delivery delivery, AmqpConnection amqpConnection)
     {
         super(message, delivery, amqpConnection);
+
+        Section body = getMessage().getBody();
+        if(body == null)
+        {
+            initialiseMessageBodyMap();
+        }
+        else if(body instanceof AmqpValue)
+        {
+            Object o = ((AmqpValue) body).getValue();
+            if(o == null)
+            {
+                initialiseMessageBodyMap();
+            }
+            else
+            {
+                _messageBodyMap = (Map<String, Object>) o;
+            }
+        }
+        else
+        {
+            throw new IllegalStateException("Unexpected message body type: " + body.getClass().getSimpleName());
+        }
+    }
+
+    private void initialiseMessageBodyMap()
+    {
+        _messageBodyMap= new HashMap<String,Object>();
+        getMessage().setBody(new AmqpValue(_messageBodyMap));
+    }
+
+    /**
+     * Returns a Set view of the keys contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa.
+     *
+     * @return a set of the keys in the underlying map
+     */
+    public Set<String> getMapKeys()
+    {
+        return _messageBodyMap.keySet();
+    }
+
+    /**
+     * Associates the specified value with the specified key in this map message.
+     *
+     * If a previous mapping for the key exists, the old value is replaced by the specified value and the old value is returned.
+     * @param key the key for the mapping
+     * @param value the value for the mapping
+     * @return the old value if one exists for this key, or null if there was none.
+     */
+    public Object setMapEntry(String key, Object value)
+    {
+        return _messageBodyMap.put(key, value);
+    }
+
+    /**
+     * Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
+     *
+     * @param key the key for the mapping
+     * @return the value if one exists for this key, or null if there was none.
+     */
+    public Object getMapEntry(String key)
+    {
+        return _messageBodyMap.get(key);
+    }
+
+    /**
+     * Clears all existing map entries.
+     */
+    public void clearMapEntries()
+    {
+        _messageBodyMap.clear();
+    }
+
+    /**
+     * Check if a given key exists in the map.
+     *
+     * @param key the key to check
+     * @return
+     */
+    public boolean mapEntryExists(String key)
+    {
+        return _messageBodyMap.containsKey(key);
     }
 }

Modified: qpid/jms/trunk/src/main/java/org/apache/qpid/jms/engine/AmqpMessage.java
URL: http://svn.apache.org/viewvc/qpid/jms/trunk/src/main/java/org/apache/qpid/jms/engine/AmqpMessage.java?rev=1594278&r1=1594277&r2=1594278&view=diff
==============================================================================
--- qpid/jms/trunk/src/main/java/org/apache/qpid/jms/engine/AmqpMessage.java (original)
+++ qpid/jms/trunk/src/main/java/org/apache/qpid/jms/engine/AmqpMessage.java Tue May 13 16:46:53 2014
@@ -241,7 +241,7 @@ public abstract class AmqpMessage
             return false;
         }
 
-        return _messageAnnotationsMap.containsKey(Symbol.valueOf(keyName));
+        return _messageAnnotationsMap.containsKey(getAnnotationMapKeySymbol(keyName));
     }
 
     /**
@@ -255,7 +255,7 @@ public abstract class AmqpMessage
             return null;
         }
 
-        return _messageAnnotationsMap.get(Symbol.valueOf(keyName));
+        return _messageAnnotationsMap.get(getAnnotationMapKeySymbol(keyName));
     }
 
     public void clearMessageAnnotation(String keyName)
@@ -265,7 +265,7 @@ public abstract class AmqpMessage
             return;
         }
 
-        _messageAnnotationsMap.remove(Symbol.valueOf(keyName));
+        _messageAnnotationsMap.remove(getAnnotationMapKeySymbol(keyName));
     }
 
     /**
@@ -279,7 +279,13 @@ public abstract class AmqpMessage
             initializeUnderlyingMessageAnnotations();
         }
 
-        _messageAnnotationsMap.put(Symbol.valueOf(keyName), value);
+        _messageAnnotationsMap.put(getAnnotationMapKeySymbol(keyName), value);
+    }
+
+    private Symbol getAnnotationMapKeySymbol(String keyName)
+    {
+        //Message Annotations maps must use Symbol or ulong keys, with the latter currently reserved.
+        return Symbol.valueOf(keyName);
     }
 
     /**

Modified: qpid/jms/trunk/src/main/java/org/apache/qpid/jms/impl/MapMessageImpl.java
URL: http://svn.apache.org/viewvc/qpid/jms/trunk/src/main/java/org/apache/qpid/jms/impl/MapMessageImpl.java?rev=1594278&r1=1594277&r2=1594278&view=diff
==============================================================================
--- qpid/jms/trunk/src/main/java/org/apache/qpid/jms/impl/MapMessageImpl.java (original)
+++ qpid/jms/trunk/src/main/java/org/apache/qpid/jms/impl/MapMessageImpl.java Tue May 13 16:46:53 2014
@@ -18,14 +18,25 @@
  */
 package org.apache.qpid.jms.impl;
 
+import java.util.Collections;
 import java.util.Enumeration;
+import java.util.Set;
 
 import javax.jms.Destination;
 import javax.jms.JMSException;
 import javax.jms.MapMessage;
+import javax.jms.MessageFormatException;
+import javax.jms.MessageNotWriteableException;
 
 import org.apache.qpid.jms.engine.AmqpMapMessage;
 
+/**
+ * TODO
+ *
+ * NOTES:
+ * Implement handling for byte[] in the map (e.g convert to/from Binary);
+ *
+ */
 public class MapMessageImpl extends MessageImpl<AmqpMapMessage> implements MapMessage
 {
     //message to be sent
@@ -47,154 +58,331 @@ public class MapMessageImpl extends Mess
         throw new UnsupportedOperationException("Not Implemented");
     }
 
+    private void setMapEntry(String name, Object value) throws IllegalArgumentException, MessageNotWriteableException
+    {
+        validateMapKeyName(name);
+        checkBodyWritable();
+
+        getUnderlyingAmqpMessage(false).setMapEntry(name, value);
+    }
+
+    private Object getMapEntry(String name) throws IllegalArgumentException
+    {
+        validateMapKeyName(name);
+
+        return getUnderlyingAmqpMessage(false).getMapEntry(name);
+    }
+
+    private void validateMapKeyName(String name) throws IllegalArgumentException
+    {
+        if (name == null)
+        {
+            throw new IllegalArgumentException("Map key name must not be null");
+        }
+        else if (name.length() == 0)
+        {
+            throw new IllegalArgumentException("Map key name must not be the empty string");
+        }
+    }
+
+    private boolean checkObjectMapValueIsValid(Object object) throws MessageFormatException
+    {
+        boolean valid = object instanceof Boolean || object instanceof Byte || object instanceof Short ||
+                        object instanceof Integer || object instanceof Long || object instanceof Float ||
+                        object instanceof Double || object instanceof String|| object instanceof Character ||
+                        object instanceof byte[] || object == null;
+        if(!valid)
+        {
+            throw new QpidJmsMessageFormatException("Invalid object value type: " + object.getClass());
+        }
+
+        return true;
+    }
+
      //======= JMS Methods =======
 
     @Override
     public boolean getBoolean(String name) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        Object value = getMapEntry(name);
+
+        if (value instanceof Boolean)
+        {
+            return ((Boolean) value).booleanValue();
+        }
+        else if ((value instanceof String) || (value == null))
+        {
+            return Boolean.valueOf((String) value);
+        }
+        else
+        {
+            throw new MessageFormatException("Map entry " + name + " of type " + value.getClass().getName() + " cannot be converted to boolean.");
+        }
     }
 
     @Override
     public byte getByte(String name) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        Object value = getMapEntry(name);
+
+        if (value instanceof Byte)
+        {
+            return ((Byte) value).byteValue();
+        }
+        else if ((value instanceof String) || (value == null))
+        {
+            return Byte.valueOf((String) value).byteValue();
+        }
+        else
+        {
+            throw new MessageFormatException("Map entry " + name + " of type " + value.getClass().getName() + " cannot be converted to byte.");
+        }
     }
 
     @Override
     public short getShort(String name) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        Object value = getMapEntry(name);
+
+        if (value instanceof Short)
+        {
+            return ((Short) value).shortValue();
+        }
+        else if (value instanceof Byte)
+        {
+            return ((Byte) value).shortValue();
+        }
+        else if ((value instanceof String) || (value == null))
+        {
+            return Short.valueOf((String) value).shortValue();
+        }
+        else
+        {
+            throw new MessageFormatException("Map entry " + name + " of type " + value.getClass().getName() + " cannot be converted to short.");
+        }
     }
 
     @Override
     public char getChar(String name) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        Object value = getMapEntry(name);
+
+        if ((value instanceof Character)) //TODO: verify we dont get a Binary, push down impl to ensure we dont
+        {
+            return (char) value;
+        }
+        else if(value == null)
+        {
+            throw new NullPointerException("Map entry " + name + " with null value cannot be converted to char.");
+        }
+        else
+        {
+            throw new MessageFormatException("Map entry " + name + " of type " + value.getClass().getName() + " cannot be converted to char.");
+        }
     }
 
     @Override
     public int getInt(String name) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        Object value = getMapEntry(name);
+
+        if (value instanceof Integer)
+        {
+            return ((Integer) value).intValue();
+        }
+        else if (value instanceof Short)
+        {
+            return ((Short) value).intValue();
+        }
+        else if (value instanceof Byte)
+        {
+            return ((Byte) value).intValue();
+        }
+        else if ((value instanceof String) || (value == null))
+        {
+            return Integer.valueOf((String) value).intValue();
+        }
+        else
+        {
+            throw new MessageFormatException("Map entry " + name + " of type " + value.getClass().getName() + " cannot be converted to int.");
+        }
     }
 
     @Override
     public long getLong(String name) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        Object value = getMapEntry(name);
+
+        if (value instanceof Long)
+        {
+            return ((Long) value).longValue();
+        }
+        else if (value instanceof Integer)
+        {
+            return ((Integer) value).longValue();
+        }
+        else if (value instanceof Short)
+        {
+            return ((Short) value).longValue();
+        }
+        else if (value instanceof Byte)
+        {
+            return ((Byte) value).longValue();
+        }
+        else if ((value instanceof String) || (value == null))
+        {
+            return Long.valueOf((String) value).longValue();
+        }
+        else
+        {
+            throw new MessageFormatException("Map entry " + name + " of type " + value.getClass().getName() + " cannot be converted to long.");
+        }
     }
 
     @Override
     public float getFloat(String name) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        Object value = getMapEntry(name);
+
+        if (value instanceof Float)
+        {
+            return ((Float) value).floatValue();
+        }
+        else if ((value instanceof String) || (value == null))
+        {
+            return Float.valueOf((String) value).floatValue();
+        }
+        else
+        {
+            throw new MessageFormatException("Map entry " + name + " of type " + value.getClass().getName() + " cannot be converted to float.");
+        }
     }
 
     @Override
     public double getDouble(String name) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        Object value = getMapEntry(name);
+
+        if (value instanceof Double)
+        {
+            return ((Double) value).doubleValue();
+        }
+        else if (value instanceof Float)
+        {
+            return ((Float) value).doubleValue();
+        }
+        else if ((value instanceof String) || (value == null))
+        {
+            return Double.valueOf((String) value).doubleValue();
+        }
+        else
+        {
+            throw new MessageFormatException("Map entry  " + name + " of type " + value.getClass().getName() + " cannot be converted to double.");
+        }
     }
 
     @Override
     public String getString(String name) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        Object value = getMapEntry(name);
+
+        if ((value instanceof String) || (value == null))
+        {
+            return (String) value;
+        }
+        else if (value instanceof byte[])//TODO: verify we dont get a Binary, push down impl to ensure we dont
+        {
+            throw new MessageFormatException("Map entry " + name + " of type byte[] " + "cannot be converted to String.");
+        }
+        else
+        {
+            return value.toString();
+        }
     }
 
     @Override
     public byte[] getBytes(String name) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        Object value = getMapEntry(name);
+
+        if ((value instanceof byte[]) || (value == null)) //TODO: verify we dont get a Binary, push down impl to ensure we dont
+        {
+            return (byte[]) value;
+        }
+        else
+        {
+            throw new MessageFormatException("Map entry " + name + " of type " + value.getClass().getName() + " cannot be converted to byte[].");
+        }
     }
 
     @Override
     public Object getObject(String name) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        //TODO: verify what happens with byte[] for received messages
+        //(i.e does it return a Binary? if so, push impl down to ensure we get a byte[] instead)
+        return getMapEntry(name);
     }
 
-    @SuppressWarnings("rawtypes")
     @Override
-    public Enumeration getMapNames() throws JMSException
+    public Enumeration<?> getMapNames() throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        Set<String> names = getUnderlyingAmqpMessage(false).getMapKeys();
+
+        return Collections.enumeration(names);
     }
 
     @Override
     public void setBoolean(String name, boolean value) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        setMapEntry(name, value);
     }
 
     @Override
     public void setByte(String name, byte value) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        setMapEntry(name, value);
     }
 
     @Override
     public void setShort(String name, short value) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        setMapEntry(name, value);
     }
 
     @Override
     public void setChar(String name, char value) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        setMapEntry(name, value);
     }
 
     @Override
     public void setInt(String name, int value) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        setMapEntry(name, value);
     }
 
     @Override
     public void setLong(String name, long value) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        setMapEntry(name, value);
     }
 
     @Override
     public void setFloat(String name, float value) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        setMapEntry(name, value);
     }
 
     @Override
     public void setDouble(String name, double value) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        setMapEntry(name, value);
     }
 
     @Override
     public void setString(String name, String value) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        setMapEntry(name, value);
     }
 
     @Override
@@ -215,21 +403,20 @@ public class MapMessageImpl extends Mess
     @Override
     public void setObject(String name, Object value) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        checkObjectMapValueIsValid(value);
+        setMapEntry(name, value);
     }
 
     @Override
     public boolean itemExists(String name) throws JMSException
     {
-        //TODO
-        throw new UnsupportedOperationException("Not Implemented");
+        return getUnderlyingAmqpMessage(false).mapEntryExists(name);
     }
 
     @Override
     public void clearBody() throws JMSException
     {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Not Implemented");
+        getUnderlyingAmqpMessage(false).clearMapEntries();
+        setBodyWritable(true);
     }
 }

Added: qpid/jms/trunk/src/test/java/org/apache/qpid/jms/engine/AmqpMapMessageTest.java
URL: http://svn.apache.org/viewvc/qpid/jms/trunk/src/test/java/org/apache/qpid/jms/engine/AmqpMapMessageTest.java?rev=1594278&view=auto
==============================================================================
--- qpid/jms/trunk/src/test/java/org/apache/qpid/jms/engine/AmqpMapMessageTest.java (added)
+++ qpid/jms/trunk/src/test/java/org/apache/qpid/jms/engine/AmqpMapMessageTest.java Tue May 13 16:46:53 2014
@@ -0,0 +1,197 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.jms.engine;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.qpid.jms.QpidJmsTestCase;
+import org.apache.qpid.proton.Proton;
+import org.apache.qpid.proton.amqp.messaging.AmqpSequence;
+import org.apache.qpid.proton.amqp.messaging.AmqpValue;
+import org.apache.qpid.proton.engine.Delivery;
+import org.apache.qpid.proton.message.Message;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class AmqpMapMessageTest extends QpidJmsTestCase
+{
+    private AmqpConnection _mockAmqpConnection;
+    private Delivery _mockDelivery;
+
+    @Before
+    @Override
+    public void setUp() throws Exception
+    {
+        super.setUp();
+        _mockAmqpConnection = Mockito.mock(AmqpConnection.class);
+        _mockDelivery = Mockito.mock(Delivery.class);
+    }
+
+    @Test
+    public void testNewMessageToSendContainsAmqpValueBodyWithMap() throws Exception
+    {
+        AmqpMapMessage amqpMapMessage = new AmqpMapMessage();
+        assertTrue(amqpMapMessage.getMessage().getBody() instanceof AmqpValue);
+        assertTrue(((AmqpValue)amqpMapMessage.getMessage().getBody()).getValue() instanceof Map<?,?>);
+    }
+
+    @Test
+    public void testGetMapNamesWithNewMessageToSendReturnsEmptySet() throws Exception
+    {
+        AmqpMapMessage amqpMapMessage = new AmqpMapMessage();
+
+        assertEquals("expected empty set", 0, amqpMapMessage.getMapKeys().size());
+    }
+
+    @Test
+    public void testGetMapNamesUsingReceivedMessageWithNoBodySectionReturnsEmptySet() throws Exception
+    {
+        Message message = Proton.message();
+        AmqpMapMessage amqpMapMessage = new AmqpMapMessage(message, _mockDelivery, _mockAmqpConnection);
+
+        assertEquals("expected empty set", 0, amqpMapMessage.getMapKeys().size());
+    }
+
+    @Test
+    public void testGetMapNamesUsingReceivedMessageWithEmptyAmqpValueBodyReturnsExpectedSet() throws Exception
+    {
+        Message message = Proton.message();
+        message.setBody(new AmqpValue(null));
+        AmqpMapMessage amqpMapMessage = new AmqpMapMessage(message, _mockDelivery, _mockAmqpConnection);
+
+        assertEquals("expected empty set", 0, amqpMapMessage.getMapKeys().size());
+    }
+
+    @Test
+    public void testGetMapNamesUsingReceivedMessageWithAmqpValueMapBodyReturnsExpectedSet() throws Exception
+    {
+        Map<String,String> origMap = new HashMap<String,String>();
+        String myKey1 = "key1";
+        String myKey2 = "key2";
+        origMap.put(myKey1, "value1");
+        origMap.put(myKey2, "value2");
+
+        Message message = Proton.message();
+        message.setBody(new AmqpValue(origMap));
+        AmqpMapMessage amqpMapMessage = new AmqpMapMessage(message, _mockDelivery, _mockAmqpConnection);
+
+        assertEquals("expected 2 map keys in set", 2, amqpMapMessage.getMapKeys().size());
+        assertTrue("expected key was not found: " + myKey1, amqpMapMessage.getMapKeys().contains(myKey1));
+        assertTrue("expected key was not found: " + myKey2, amqpMapMessage.getMapKeys().contains(myKey2));
+    }
+
+    @Test
+    public void testClearMapEntriesUsingReceivedMessageWithAmqpValueMapBody() throws Exception
+    {
+        Map<String,String> origMap = new HashMap<String,String>();
+        String myKey1 = "key1";
+        String myKey2 = "key2";
+        origMap.put(myKey1, "value1");
+        origMap.put(myKey2, "value2");
+
+        Message message = Proton.message();
+        message.setBody(new AmqpValue(origMap));
+        AmqpMapMessage amqpMapMessage = new AmqpMapMessage(message, _mockDelivery, _mockAmqpConnection);
+
+        assertEquals("expected 2 map keys in set", 2, amqpMapMessage.getMapKeys().size());
+        amqpMapMessage.clearMapEntries();
+        assertEquals("expected empty set", 0, amqpMapMessage.getMapKeys().size());
+    }
+
+    @Test
+    public void testGetMapEntryUsingReceivedMessageWithAmqpValueMapBody() throws Exception
+    {
+        Map<String,String> origMap = new HashMap<String,String>();
+        String myKey1 = "key1";
+        String myKey2 = "key2";
+        String myValue1 = "value1";
+        String myValue2 = "value2";
+        origMap.put(myKey1, myValue1);
+        origMap.put(myKey2, myValue2);
+
+        Message message = Proton.message();
+        message.setBody(new AmqpValue(origMap));
+        AmqpMapMessage amqpMapMessage = new AmqpMapMessage(message, _mockDelivery, _mockAmqpConnection);
+
+        Object val1 = amqpMapMessage.getMapEntry(myKey1);
+        assertEquals("expected value was not found for key" + myKey1 + ": " + myKey1, myValue1, val1);
+        Object val2 = amqpMapMessage.getMapEntry(myKey2);
+        assertEquals("expected value was not found for key" + myKey2 + ": " + myKey2, myValue2, val2);
+    }
+
+    @Test
+    public void testSetEntryOnNewMessageUpdatesUnderlyingMessageBody() throws Exception
+    {
+        AmqpMapMessage amqpMapMessage = new AmqpMapMessage();
+        String myKey1 = "key1";
+        String myValue1 = "value1";
+
+        Map<?,?> bodyMap = (Map<?,?>) ((AmqpValue)amqpMapMessage.getMessage().getBody()).getValue();
+        assertTrue("expected empty map", bodyMap.isEmpty());
+
+        amqpMapMessage.setMapEntry(myKey1, myValue1);
+
+        assertEquals("expected map to be updated", 1, amqpMapMessage.getMapKeys().size());
+        assertTrue("expected key was not found: " + myKey1, bodyMap.containsKey(myKey1));
+        assertEquals("expected value was not found: " + myValue1, myValue1, bodyMap.get(myKey1));
+    }
+
+    @Test
+    public void testCreateAmqpMapMessageWithUnexpectedBodySectionTypeThrowsISE() throws Exception
+    {
+        Message message = Proton.message();
+        message.setBody(new AmqpSequence(new ArrayList<Object>()));
+
+        try
+        {
+            new AmqpMapMessage(message, _mockDelivery, _mockAmqpConnection);
+            fail("expected exception not thrown");
+        }
+        catch(IllegalStateException ise)
+        {
+            //expected
+        }
+    }
+
+    @Test
+    public void testMapEntryExistsUsingReceivedMessage() throws Exception
+    {
+        Map<String,String> origMap = new HashMap<String,String>();
+        String myKey1 = "key1";
+        String myKey2 = "key2";
+        origMap.put(myKey1, "value1");
+
+        Message message = Proton.message();
+        message.setBody(new AmqpValue(origMap));
+        AmqpMapMessage amqpMapMessage = new AmqpMapMessage(message, _mockDelivery, _mockAmqpConnection);
+
+        assertTrue("expected key was not found: " + myKey1, amqpMapMessage.mapEntryExists(myKey1));
+        assertFalse("key should not have been found: " + myKey2, amqpMapMessage.mapEntryExists(myKey2));
+    }
+}

Added: qpid/jms/trunk/src/test/java/org/apache/qpid/jms/impl/MapMessageImplTest.java
URL: http://svn.apache.org/viewvc/qpid/jms/trunk/src/test/java/org/apache/qpid/jms/impl/MapMessageImplTest.java?rev=1594278&view=auto
==============================================================================
--- qpid/jms/trunk/src/test/java/org/apache/qpid/jms/impl/MapMessageImplTest.java (added)
+++ qpid/jms/trunk/src/test/java/org/apache/qpid/jms/impl/MapMessageImplTest.java Tue May 13 16:46:53 2014
@@ -0,0 +1,783 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.jms.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jms.JMSException;
+import javax.jms.MessageFormatException;
+import javax.jms.MessageNotWriteableException;
+
+import org.apache.qpid.jms.QpidJmsTestCase;
+import org.apache.qpid.jms.engine.AmqpConnection;
+import org.apache.qpid.jms.engine.AmqpMapMessage;
+import org.apache.qpid.proton.Proton;
+import org.apache.qpid.proton.amqp.messaging.AmqpValue;
+import org.apache.qpid.proton.engine.Delivery;
+import org.apache.qpid.proton.message.Message;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class MapMessageImplTest extends QpidJmsTestCase
+{
+    private Delivery _mockDelivery;
+    private ConnectionImpl _mockConnectionImpl;
+    private SessionImpl _mockSessionImpl;
+    private AmqpConnection _mockAmqpConnection;
+
+    @Before
+    @Override
+    public void setUp() throws Exception
+    {
+        super.setUp();
+        _mockAmqpConnection = Mockito.mock(AmqpConnection.class);
+        _mockConnectionImpl = Mockito.mock(ConnectionImpl.class);
+        _mockSessionImpl = Mockito.mock(SessionImpl.class);
+        Mockito.when(_mockSessionImpl.getDestinationHelper()).thenReturn(new DestinationHelper());
+    }
+
+    @Test
+    public void testGetMapNamesWithNewMessageToSendReturnsEmptyEnumeration() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+        Enumeration<?> names = mapMessageImpl.getMapNames();
+
+        assertFalse("Expected new message to have no map names", names.hasMoreElements());
+    }
+
+    /**
+     * Test that we are able to retrieve the names and values of map entries on a received message
+     */
+    @Test
+    public void testGetMapNamesUsingReceivedMessageReturnsExpectedEnumeration() throws Exception
+    {
+        Map<String,String> origMap = new HashMap<String,String>();
+        String myKey1 = "key1";
+        String myKey2 = "key2";
+        origMap.put(myKey1, "value1");
+        origMap.put(myKey2, "value2");
+
+        Message message = Proton.message();
+        message.setBody(new AmqpValue(origMap));
+        AmqpMapMessage amqpMapMessage = new AmqpMapMessage(message, _mockDelivery, _mockAmqpConnection);
+
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(amqpMapMessage, _mockSessionImpl,_mockConnectionImpl, null);
+        Enumeration<?> names = mapMessageImpl.getMapNames();
+
+        int count = 0;
+        List<Object> elements = new ArrayList<Object>();
+        while(names.hasMoreElements())
+        {
+            count++;
+            elements.add(names.nextElement());
+        }
+        assertEquals("expected 2 map keys in enumeration", 2,count);
+        assertTrue("expected key was not found: " + myKey1, elements.contains(myKey1));
+        assertTrue("expected key was not found: " + myKey2, elements.contains(myKey2));
+    }
+
+    /**
+     * Test that we enforce the requirement that map message key names not be null or the empty string.
+     */
+    @Test
+    public void testSetObjectWithNullOrEmptyKeyNameThrowsIAE() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+        try
+        {
+            mapMessageImpl.setObject(null, "value");
+            fail("Expected exception not thrown");
+        }
+        catch(IllegalArgumentException iae)
+        {
+            //expected
+        }
+
+        try
+        {
+            mapMessageImpl.setObject("", "value");
+            fail("Expected exception not thrown");
+        }
+        catch(IllegalArgumentException iae)
+        {
+            //expected
+        }
+    }
+
+    /**
+     * Test that we are not able to write to a received message without calling {@link MapMessageImpl#clearBody()}
+     */
+    @Test
+    public void testReceivedMessageIsReadOnlyAndThrowsMNWE() throws Exception
+    {
+        Map<String,String> origMap = new HashMap<String,String>();
+        String myKey1 = "key1";
+        origMap.put(myKey1, "value1");
+
+        Message message = Proton.message();
+        message.setBody(new AmqpValue(origMap));
+        AmqpMapMessage amqpMapMessage = new AmqpMapMessage(message, _mockDelivery, _mockAmqpConnection);
+
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(amqpMapMessage, _mockSessionImpl,_mockConnectionImpl, null);
+
+        try
+        {
+            mapMessageImpl.setObject("name", "value");
+            fail("expected exception to be thrown");
+        }
+        catch(MessageNotWriteableException mnwe)
+        {
+            //expected
+        }
+    }
+
+    /**
+     * Test that calling {@link MapMessageImpl#clearBody()} makes a received message writable
+     */
+    @Test
+    public void testClearBodyMakesReceivedMessageWritable() throws Exception
+    {
+        Map<String,String> origMap = new HashMap<String,String>();
+        String myKey1 = "key1";
+        origMap.put(myKey1, "value1");
+
+        Message message = Proton.message();
+        message.setBody(new AmqpValue(origMap));
+        AmqpMapMessage amqpMapMessage = new AmqpMapMessage(message, _mockDelivery, _mockAmqpConnection);
+
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(amqpMapMessage, _mockSessionImpl,_mockConnectionImpl, null);
+
+        assertFalse("expected message to be read-only", mapMessageImpl.isBodyWritable());
+        mapMessageImpl.clearBody();
+        assertTrue("expected message to be writable", mapMessageImpl.isBodyWritable());
+        mapMessageImpl.setObject("name", "value");
+    }
+
+    /**
+     * Test that calling {@link MapMessageImpl#clearBody()} clears the underlying message body map.
+     */
+    @Test
+    public void testClearBodyClearsUnderlyingMessageMap() throws Exception
+    {
+        Map<String,String> origMap = new HashMap<String,String>();
+        String myKey1 = "key1";
+        origMap.put(myKey1, "value1");
+
+        Message message = Proton.message();
+        message.setBody(new AmqpValue(origMap));
+        AmqpMapMessage amqpMapMessage = new AmqpMapMessage(message, _mockDelivery, _mockAmqpConnection);
+
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(amqpMapMessage, _mockSessionImpl,_mockConnectionImpl, null);
+
+        assertTrue("key should exist: " + myKey1, mapMessageImpl.itemExists(myKey1));
+        mapMessageImpl.clearBody();
+        assertTrue("expected map to be emptied", origMap.isEmpty());
+        assertFalse("key should not exist", mapMessageImpl.itemExists(myKey1));
+    }
+
+    /**
+     * Test that the {@link MapMessageImpl#setObject(String, Object)} method rejects Objects of unexpected types
+     */
+    @Test
+    public void testSetObjectWithIllegalTypeThrowsMFE() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+        try
+        {
+            mapMessageImpl.setObject("myPKey", new Exception());
+            fail("Expected exception not thrown");
+        }
+        catch(MessageFormatException mfe)
+        {
+            //expected
+        }
+    }
+
+    @Test
+    public void testSetGetObject() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+        String keyName = "myProperty";
+
+        Object entryValue = null;
+        mapMessageImpl.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessageImpl.getObject(keyName));
+
+        entryValue = Boolean.valueOf(false);
+        mapMessageImpl.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessageImpl.getObject(keyName));
+
+        entryValue = Byte.valueOf((byte)1);
+        mapMessageImpl.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessageImpl.getObject(keyName));
+
+        entryValue = Short.valueOf((short)2);
+        mapMessageImpl.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessageImpl.getObject(keyName));
+
+        entryValue = Integer.valueOf(3);
+        mapMessageImpl.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessageImpl.getObject(keyName));
+
+        entryValue = Long.valueOf(4);
+        mapMessageImpl.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessageImpl.getObject(keyName));
+
+        entryValue = Float.valueOf(5.01F);
+        mapMessageImpl.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessageImpl.getObject(keyName));
+
+        entryValue = Double.valueOf(6.01);
+        mapMessageImpl.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessageImpl.getObject(keyName));
+
+        entryValue = "string";
+        mapMessageImpl.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessageImpl.getObject(keyName));
+
+        entryValue = Character.valueOf('c');
+        mapMessageImpl.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessageImpl.getObject(keyName));
+
+        entryValue = new byte[] { (byte)1, (byte) 0, (byte)1};
+        mapMessageImpl.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessageImpl.getObject(keyName));
+    }
+
+    // ======= Strings =========
+
+    @Test
+    public void testSetGetString() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        //null value
+        String name = "myNullString";
+        String value = null;
+
+        assertFalse(mapMessageImpl.itemExists(name));
+        mapMessageImpl.setString(name, value);
+        assertTrue(mapMessageImpl.itemExists(name));
+        assertEquals(value, mapMessageImpl.getString(name));
+
+        //non-null value
+        name = "myName";
+        value = "myValue";
+
+        assertFalse(mapMessageImpl.itemExists(name));
+        mapMessageImpl.setString(name, value);
+        assertTrue(mapMessageImpl.itemExists(name));
+        assertEquals(value, mapMessageImpl.getString(name));
+    }
+
+    /**
+     * Set a String, then retrieve it as all of the legal type combinations to verify it is parsed correctly
+     */
+    @Test
+    public void testSetStringGetLegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myStringName";
+        String value;
+
+        //boolean
+        value =  "true";
+        mapMessageImpl.setString(name, value);
+        assertGetMapEntryEquals(mapMessageImpl, name, Boolean.valueOf(value), Boolean.class);
+
+        //byte
+        value =  String.valueOf(Byte.MAX_VALUE);
+        mapMessageImpl.setString(name, value);
+        assertGetMapEntryEquals(mapMessageImpl, name, Byte.valueOf(value), Byte.class);
+
+        //short
+        value =  String.valueOf(Short.MAX_VALUE);
+        mapMessageImpl.setString(name, value);
+        assertGetMapEntryEquals(mapMessageImpl, name, Short.valueOf(value), Short.class);
+
+        //int
+        value =  String.valueOf(Integer.MAX_VALUE);
+        mapMessageImpl.setString(name, value);
+        assertGetMapEntryEquals(mapMessageImpl, name, Integer.valueOf(value), Integer.class);
+
+        //long
+        value =  String.valueOf(Long.MAX_VALUE);
+        mapMessageImpl.setString(name, value);
+        assertGetMapEntryEquals(mapMessageImpl, name, Long.valueOf(value), Long.class);
+
+        //float
+        value =  String.valueOf(Float.MAX_VALUE);
+        mapMessageImpl.setString(name, value);
+        assertGetMapEntryEquals(mapMessageImpl, name, Float.valueOf(value), Float.class);
+
+        //double
+        value =  String.valueOf(Double.MAX_VALUE);
+        mapMessageImpl.setString(name, value);
+        assertGetMapEntryEquals(mapMessageImpl, name, Double.valueOf(value), Double.class);
+    }
+
+    /**
+     * Set a String, then retrieve it as all of the illegal type combinations to verify it fails as expected
+     */
+    @Test
+    public void testSetStringGetIllegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        String value = "myStringValue";
+
+        mapMessageImpl.setString(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Character.class);
+    }
+
+    // ======= boolean =========
+
+    /**
+     * Set a boolean, then retrieve it as all of the legal type combinations to verify it is parsed correctly
+     */
+    @Test
+    public void testSetBooleanGetLegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        boolean value = true;
+
+        mapMessageImpl.setBoolean(name, value);
+        assertEquals("value not as expected", value, mapMessageImpl.getBoolean(name));
+
+        assertGetMapEntryEquals(mapMessageImpl, name, String.valueOf(value), String.class);
+    }
+
+    /**
+     * Set a boolean, then retrieve it as all of the illegal type combinations to verify it fails as expected
+     */
+    @Test
+    public void testSetBooleanGetIllegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        boolean value = true;
+
+        mapMessageImpl.setBoolean(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Character.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Byte.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Short.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Integer.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Long.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Float.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Double.class);
+    }
+
+    // ======= byte =========
+
+    /**
+     * Set a byte, then retrieve it as all of the legal type combinations to verify it is parsed correctly
+     */
+    @Test
+    public void testSetByteGetLegalProperty() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        byte value = (byte)1;
+
+        mapMessageImpl.setByte(name, value);
+        assertEquals(value, mapMessageImpl.getByte(name));
+
+        assertGetMapEntryEquals(mapMessageImpl, name, String.valueOf(value), String.class);
+        assertGetMapEntryEquals(mapMessageImpl, name, Short.valueOf(value), Short.class);
+        assertGetMapEntryEquals(mapMessageImpl, name, Integer.valueOf(value), Integer.class);
+        assertGetMapEntryEquals(mapMessageImpl, name, Long.valueOf(value), Long.class);
+    }
+
+    /**
+     * Set a byte, then retrieve it as all of the illegal type combinations to verify it is fails as expected
+     */
+    @Test
+    public void testSetByteGetIllegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        byte value = (byte)1;
+
+        mapMessageImpl.setByte(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Character.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Boolean.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Float.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Double.class);
+    }
+
+
+    // ======= short =========
+
+    /**
+     * Set a short, then retrieve it as all of the legal type combinations to verify it is parsed correctly
+     */
+    @Test
+    public void testSetShortGetLegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        short value = (short)1;
+
+        mapMessageImpl.setShort(name, value);
+        assertEquals(value, mapMessageImpl.getShort(name));
+
+        assertGetMapEntryEquals(mapMessageImpl, name, String.valueOf(value), String.class);
+        assertGetMapEntryEquals(mapMessageImpl, name, Integer.valueOf(value), Integer.class);
+        assertGetMapEntryEquals(mapMessageImpl, name, Long.valueOf(value), Long.class);
+    }
+
+    /**
+     * Set a short, then retrieve it as all of the illegal type combinations to verify it fails as expected
+     */
+    @Test
+    public void testSetShortGetIllegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        short value = (short)1;
+
+        mapMessageImpl.setShort(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Character.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Boolean.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Byte.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Float.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Double.class);
+    }
+
+
+    // ======= int =========
+
+    /**
+     * Set an int, then retrieve it as all of the legal type combinations to verify it is parsed correctly
+     */
+    @Test
+    public void testSetIntGetLegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        int value = (int)1;
+
+        mapMessageImpl.setInt(name, value);
+        assertEquals(value, mapMessageImpl.getInt(name));
+
+        assertGetMapEntryEquals(mapMessageImpl, name, String.valueOf(value), String.class);
+        assertGetMapEntryEquals(mapMessageImpl, name, Long.valueOf(value), Long.class);
+    }
+
+    /**
+     * Set an int, then retrieve it as all of the illegal type combinations to verify it fails as expected
+     */
+    @Test
+    public void testSetIntGetIllegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        int value = (int)1;
+
+        mapMessageImpl.setInt(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Character.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Boolean.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Byte.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Short.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Float.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Double.class);
+    }
+
+    // ======= long =========
+
+    /**
+     * Set a long, then retrieve it as all of the legal type combinations to verify it is parsed correctly
+     */
+    @Test
+    public void testSetLongGetLegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        long value = Long.MAX_VALUE;
+
+        mapMessageImpl.setLong(name, value);
+        assertEquals(value, mapMessageImpl.getLong(name));
+
+        assertGetMapEntryEquals(mapMessageImpl, name, String.valueOf(value), String.class);
+    }
+
+    /**
+     * Set an long, then retrieve it as all of the illegal type combinations to verify it fails as expected
+     */
+    @Test
+    public void testSetLongGetIllegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        long value = Long.MAX_VALUE;
+
+        mapMessageImpl.setLong(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Character.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Boolean.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Byte.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Short.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Integer.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Float.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Double.class);
+    }
+
+    // ======= float =========
+
+    /**
+     * Set a float, then retrieve it as all of the legal type combinations to verify it is parsed correctly
+     */
+    @Test
+    public void testSetFloatGetLegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        float value = Float.MAX_VALUE;
+
+        mapMessageImpl.setFloat(name, value);
+        assertEquals(value, mapMessageImpl.getFloat(name), 0.0);
+
+        assertGetMapEntryEquals(mapMessageImpl, name, String.valueOf(value), String.class);
+        assertGetMapEntryEquals(mapMessageImpl, name, Double.valueOf(value), Double.class);
+    }
+
+    /**
+     * Set a float, then retrieve it as all of the illegal type combinations to verify it fails as expected
+     */
+    @Test
+    public void testSetFloatGetIllegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        float value = Float.MAX_VALUE;
+
+        mapMessageImpl.setFloat(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Character.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Boolean.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Byte.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Short.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Integer.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Long.class);
+    }
+
+    // ======= double  =========
+
+    @Test
+    public void testSetDoubleGetLegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        double value = Double.MAX_VALUE;
+
+        mapMessageImpl.setDouble(name, value);
+        assertEquals(value, mapMessageImpl.getDouble(name), 0.0);
+
+        assertGetMapEntryEquals(mapMessageImpl, name, String.valueOf(value), String.class);
+    }
+
+    @Test
+    public void testSetDoubleGetIllegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        double value = Double.MAX_VALUE;
+
+        mapMessageImpl.setDouble(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Character.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Boolean.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Byte.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Short.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Integer.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Long.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Float.class);
+    }
+
+    // ======= character =========
+
+    @Test
+    public void testSetCharGetLegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        char value = 'c';
+
+        mapMessageImpl.setChar(name, value);
+        assertEquals(value, mapMessageImpl.getChar(name));
+
+        assertGetMapEntryEquals(mapMessageImpl, name, String.valueOf(value), String.class);
+    }
+
+    @Test
+    public void testSetCharGetIllegal() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        String name = "myName";
+        char value = 'c';
+
+        mapMessageImpl.setChar(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Boolean.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Byte.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Short.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Integer.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Long.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessageImpl, name, Float.class);
+    }
+
+    /**
+     * Verify behaviour when retrieving a character with null value (i.e missing).
+     * Unlike all the other types, this should throw an explicit NPE.
+     */
+    @Test
+    public void testGetCharWithMissingValueThrowsNPE() throws Exception
+    {
+        MapMessageImpl mapMessageImpl = new MapMessageImpl(_mockSessionImpl,_mockConnectionImpl);
+
+        try
+        {
+            mapMessageImpl.getChar("does.not.exist");
+            fail("expected exception to be thrown");
+        }
+        catch(NullPointerException npe)
+        {
+            //expected
+        }
+    }
+
+    //========= utility methods ========
+
+    private void assertGetMapEntryEquals(MapMessageImpl testMessage, String name,
+                                         Object expectedValue,
+                                         Class<?> clazz) throws JMSException
+    {
+        Object actualValue = getMapEntryUsingTypeMethod(testMessage, name, clazz);
+        assertEquals(expectedValue, actualValue);
+    }
+
+    private void assertGetMapEntryThrowsMessageFormatException(MapMessageImpl testMessage,
+                                                               String name,
+                                                               Class<?> clazz) throws JMSException
+    {
+        try
+        {
+            getMapEntryUsingTypeMethod(testMessage, name, clazz);
+
+            fail("expected exception to be thrown");
+        }
+        catch(MessageFormatException jmsMFE)
+        {
+            //expected
+        }
+    }
+
+    private Object getMapEntryUsingTypeMethod(MapMessageImpl testMessage, String name, Class<?> clazz) throws JMSException
+    {
+        if(clazz == Boolean.class)
+        {
+            return testMessage.getBoolean(name);
+        }
+        else if(clazz == Byte.class)
+        {
+            return testMessage.getByte(name);
+        }
+        else if(clazz == Character.class)
+        {
+            return testMessage.getChar(name);
+        }
+        else if(clazz == Short.class)
+        {
+            return testMessage.getShort(name);
+        }
+        else if(clazz == Integer.class)
+        {
+            return testMessage.getInt(name);
+        }
+        else if(clazz == Long.class)
+        {
+            return testMessage.getLong(name);
+        }
+        else if(clazz == Float.class)
+        {
+            return testMessage.getFloat(name);
+        }
+        else if(clazz == Double.class)
+        {
+            return testMessage.getDouble(name);
+        }
+        else if(clazz == String.class)
+        {
+            return testMessage.getString(name);
+        }
+        else if(clazz == byte[].class)
+        {
+            return testMessage.getBytes(name);
+        }
+        else
+        {
+            throw new RuntimeException("Unexpected entry type class");
+        }
+    }
+}

Modified: qpid/jms/trunk/src/test/java/org/apache/qpid/jms/impl/ObjectMessageImplTest.java
URL: http://svn.apache.org/viewvc/qpid/jms/trunk/src/test/java/org/apache/qpid/jms/impl/ObjectMessageImplTest.java?rev=1594278&r1=1594277&r2=1594278&view=diff
==============================================================================
--- qpid/jms/trunk/src/test/java/org/apache/qpid/jms/impl/ObjectMessageImplTest.java (original)
+++ qpid/jms/trunk/src/test/java/org/apache/qpid/jms/impl/ObjectMessageImplTest.java Tue May 13 16:46:53 2014
@@ -42,7 +42,6 @@ import javax.jms.ObjectMessage;
 import org.apache.qpid.jms.QpidJmsTestCase;
 import org.apache.qpid.jms.engine.AmqpConnection;
 import org.apache.qpid.jms.engine.AmqpObjectMessage;
-import org.apache.qpid.jms.engine.AmqpObjectMessage;
 import org.apache.qpid.proton.Proton;
 import org.apache.qpid.proton.amqp.Binary;
 import org.apache.qpid.proton.amqp.messaging.Data;



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org