You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ta...@apache.org on 2014/09/23 20:20:36 UTC

[12/27] Initial drop of donated AMQP Client Code.

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsBytesMessageTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsBytesMessageTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsBytesMessageTest.java
new file mode 100644
index 0000000..5f29da1
--- /dev/null
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsBytesMessageTest.java
@@ -0,0 +1,666 @@
+/**
+ * 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.message;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Arrays;
+
+import javax.jms.BytesMessage;
+import javax.jms.JMSException;
+import javax.jms.MessageFormatException;
+import javax.jms.MessageNotReadableException;
+import javax.jms.MessageNotWriteableException;
+
+import org.apache.qpid.jms.message.JmsBytesMessage;
+import org.apache.qpid.jms.message.JmsDefaultMessageFactory;
+import org.apache.qpid.jms.message.JmsMessageFactory;
+import org.apache.qpid.jms.message.facade.defaults.JmsDefaultBytesMessageFacade;
+import org.fusesource.hawtbuf.Buffer;
+import org.junit.Test;
+
+/**
+ * Test for JMS Spec compliance for the JmsBytesMessage class using the default message facade.
+ */
+public class JmsBytesMessageTest {
+
+    private static final int END_OF_STREAM = -1;
+
+    private final JmsMessageFactory factory = new JmsDefaultMessageFactory();
+
+    /**
+     * Test that calling {@link BytesMessage#getBodyLength()} on a new message which has been
+     * populated and {@link BytesMessage#reset()} causes the length to be reported correctly.
+     */
+    @Test
+    public void testResetOnNewlyPopulatedBytesMessageUpdatesBodyLength() throws Exception {
+        byte[] bytes = "newResetTestBytes".getBytes();
+        JmsBytesMessage bytesMessage = factory.createBytesMessage();
+        bytesMessage.writeBytes(bytes);
+        bytesMessage.reset();
+        assertEquals("Message reports unexpected length", bytes.length, bytesMessage.getBodyLength());
+    }
+
+    /**
+     * Test that attempting to call {@link BytesMessage#getBodyLength()} on a new message causes
+     * a {@link MessageNotReadableException} to be thrown due to being write-only.
+     */
+    @Test(expected = MessageNotReadableException.class)
+    public void testGetBodyLengthOnNewMessageThrowsMessageNotReadableException() throws Exception {
+        JmsBytesMessage bytesMessage = factory.createBytesMessage();
+        bytesMessage.getBodyLength();
+    }
+
+    @Test
+    public void testReadBytesUsingReceivedMessageWithNoBodyReturnsEOS() throws Exception {
+        JmsBytesMessage bytesMessage = factory.createBytesMessage();
+        bytesMessage.onSend();
+        //verify attempting to read bytes returns -1, i.e EOS
+        assertEquals("Expected input stream to be at end but data was returned", END_OF_STREAM, bytesMessage.readBytes(new byte[1]));
+    }
+
+    @Test
+    public void testReadBytesUsingReceivedMessageWithBodyReturnsBytes() throws Exception {
+        Buffer content = new Buffer("myBytesData".getBytes());
+        JmsDefaultBytesMessageFacade facade = new JmsDefaultBytesMessageFacade();
+        facade.setContent(content);
+
+        JmsBytesMessage bytesMessage = new JmsBytesMessage(facade);
+        bytesMessage.onSend();
+
+        // retrieve the expected bytes, check they match
+        byte[] receivedBytes = new byte[content.length];
+        bytesMessage.readBytes(receivedBytes);
+        assertTrue(Arrays.equals(content.data, receivedBytes));
+
+        // verify no more bytes remain, i.e EOS
+        assertEquals("Expected input stream to be at end but data was returned",
+                     END_OF_STREAM, bytesMessage.readBytes(new byte[1]));
+
+        assertEquals("Message reports unexpected length", content.length, bytesMessage.getBodyLength());
+    }
+
+    /**
+     * Test that attempting to write bytes to a received message (without calling {@link BytesMessage#clearBody()} first)
+     * causes a {@link MessageNotWriteableException} to be thrown due to being read-only.
+     */
+    @Test(expected = MessageNotWriteableException.class)
+    public void testReceivedBytesMessageThrowsMessageNotWriteableExceptionOnWriteBytes() throws Exception {
+        Buffer content = new Buffer("myBytesData".getBytes());
+        JmsDefaultBytesMessageFacade facade = new JmsDefaultBytesMessageFacade();
+        facade.setContent(content);
+
+        JmsBytesMessage bytesMessage = new JmsBytesMessage(facade);
+        bytesMessage.onSend();
+        bytesMessage.writeBytes(content.data);
+    }
+
+    /**
+     * Test that attempting to read bytes from a new message (without calling {@link BytesMessage#reset()} first) causes a
+     * {@link MessageNotReadableException} to be thrown due to being write-only.
+     */
+    @Test(expected = MessageNotReadableException.class)
+    public void testNewBytesMessageThrowsMessageNotReadableOnReadBytes() throws Exception {
+        JmsBytesMessage bytesMessage = factory.createBytesMessage();
+        byte[] receivedBytes = new byte[1];
+        bytesMessage.readBytes(receivedBytes);
+    }
+
+    /**
+     * Test that calling {@link BytesMessage#clearBody()} causes a received
+     * message to become writable
+     */
+    @Test
+    public void testClearBodyOnReceivedBytesMessageMakesMessageWritable() throws Exception {
+        Buffer content = new Buffer("myBytesData".getBytes());
+        JmsDefaultBytesMessageFacade facade = new JmsDefaultBytesMessageFacade();
+        facade.setContent(content);
+
+        JmsBytesMessage bytesMessage = new JmsBytesMessage(facade);
+        bytesMessage.onSend();
+        assertTrue("Message should not be writable", bytesMessage.isReadOnlyBody());
+        bytesMessage.clearBody();
+        assertFalse("Message should be writable", bytesMessage.isReadOnlyBody());
+    }
+
+    /**
+     * Test that calling {@link BytesMessage#clearBody()} of a received message
+     * causes the body of the underlying {@link AmqpBytesMessage} to be emptied.
+     */
+    @Test
+    public void testClearBodyOnReceivedBytesMessageClearsUnderlyingMessageBody() throws Exception {
+        Buffer content = new Buffer("myBytesData".getBytes());
+        JmsDefaultBytesMessageFacade facade = new JmsDefaultBytesMessageFacade();
+        facade.setContent(content);
+
+        JmsBytesMessage bytesMessage = new JmsBytesMessage(facade);
+        bytesMessage.onSend();
+
+        assertNotNull("Expected message content but none was present", facade.getContent());
+        bytesMessage.clearBody();
+        assertNull("Expected no message content but was present", facade.getContent());
+    }
+
+    /**
+     * Test that attempting to call {@link BytesMessage#getBodyLength()} on a received message after calling
+     * {@link BytesMessage#clearBody()} causes {@link MessageNotReadableException} to be thrown due to being write-only.
+     */
+    @Test
+    public void testGetBodyLengthOnClearedReceivedMessageThrowsMessageNotReadableException() throws Exception {
+        Buffer content = new Buffer("myBytesData".getBytes());
+        JmsDefaultBytesMessageFacade facade = new JmsDefaultBytesMessageFacade();
+        facade.setContent(content);
+
+        JmsBytesMessage bytesMessage = new JmsBytesMessage(facade);
+        bytesMessage.onSend();
+        assertEquals("Unexpected message length", content.length, bytesMessage.getBodyLength());
+        bytesMessage.clearBody();
+
+        try {
+            bytesMessage.getBodyLength();
+            fail("expected exception to be thrown");
+        } catch (MessageNotReadableException mnre) {
+            // expected
+        }
+    }
+
+    /**
+     * Test that calling {@link BytesMessage#reset()} causes a write-only
+     * message to become read-only
+     */
+    @Test
+    public void testResetOnReceivedBytesMessageResetsMarker() throws Exception {
+        Buffer content = new Buffer("resetTestBytes".getBytes());
+        JmsDefaultBytesMessageFacade facade = new JmsDefaultBytesMessageFacade();
+        facade.setContent(content);
+
+        JmsBytesMessage bytesMessage = new JmsBytesMessage(facade);
+        bytesMessage.onSend();
+
+        // retrieve a few bytes, check they match the first few expected bytes
+        byte[] partialBytes = new byte[3];
+        bytesMessage.readBytes(partialBytes);
+        byte[] partialOriginalBytes = Arrays.copyOf(content.data, 3);
+        assertTrue(Arrays.equals(partialOriginalBytes, partialBytes));
+
+        bytesMessage.reset();
+
+        // retrieve all the expected bytes, check they match
+        byte[] resetBytes = new byte[content.length];
+        bytesMessage.readBytes(resetBytes);
+        assertTrue(Arrays.equals(content.data, resetBytes));
+    }
+
+    /**
+     * Test that calling {@link BytesMessage#reset()} on a new message which has been populated
+     * causes the marker to be reset and makes the message read-only
+     */
+    @Test
+    public void testResetOnNewlyPopulatedBytesMessageResetsMarkerAndMakesReadable() throws Exception {
+        Buffer content = new Buffer("newResetTestBytes".getBytes());
+        JmsDefaultBytesMessageFacade facade = new JmsDefaultBytesMessageFacade();
+        facade.setContent(content);
+
+        JmsBytesMessage bytesMessage = new JmsBytesMessage(facade);
+
+        assertFalse("Message should be writable", bytesMessage.isReadOnlyBody());
+        bytesMessage.writeBytes(content.data);
+        bytesMessage.reset();
+        assertTrue("Message should not be writable", bytesMessage.isReadOnlyBody());
+
+        // retrieve the bytes, check they match
+        byte[] resetBytes = new byte[content.length];
+        bytesMessage.readBytes(resetBytes);
+        assertTrue(Arrays.equals(content.data, resetBytes));
+    }
+
+    /**
+     * Verify that nothing is read when {@link BytesMessage#readBytes(byte[])} is
+     * called with a zero length destination array.
+     */
+    @Test
+    public void testReadBytesWithZeroLengthDestination() throws Exception {
+        JmsBytesMessage bytesMessage = factory.createBytesMessage();
+        bytesMessage.reset();
+        assertEquals("Did not expect any bytes to be read", 0, bytesMessage.readBytes(new byte[0]));
+    }
+
+    /**
+     * Verify that when {@link BytesMessage#readBytes(byte[], int))} is called
+     * with a negative length that an {@link IndexOutOfBoundsException} is thrown.
+     */
+    @Test(expected=IndexOutOfBoundsException.class)
+    public void testReadBytesWithNegativeLengthThrowsIOOBE() throws Exception
+    {
+        JmsBytesMessage bytesMessage = factory.createBytesMessage();
+        bytesMessage.reset();
+        bytesMessage.readBytes(new byte[0], -1);
+    }
+
+    /**
+     * Verify that when {@link BytesMessage#readBytes(byte[], int))} is called
+     * with a length that is greater than the size of the provided array,
+     * an {@link IndexOutOfBoundsException} is thrown.
+     */
+    @Test(expected=IndexOutOfBoundsException.class)
+    public void testReadBytesWithLengthGreatThanArraySizeThrowsIOOBE() throws Exception {
+        JmsBytesMessage bytesMessage = factory.createBytesMessage();
+        bytesMessage.reset();
+        bytesMessage.readBytes(new byte[1], 2);
+    }
+
+    /**
+     * Test that writing a null using {@link BytesMessage#writeObject(Object)}
+     * results in a NPE being thrown.
+     */
+    @Test(expected=NullPointerException.class)
+    public void testWriteObjectWithNullThrowsNPE() throws Exception {
+        JmsBytesMessage bytesMessage = factory.createBytesMessage();
+        bytesMessage.writeObject(null);
+    }
+
+    /**
+     * Test that writing a null using {@link BytesMessage#writeObject(Object)}
+     * results in an {@link MessageFormatException} being thrown.
+     */
+    @Test(expected=MessageFormatException.class)
+    public void testWriteObjectWithIllegalTypeThrowsMFE() throws Exception {
+        JmsBytesMessage bytesMessage = factory.createBytesMessage();
+        bytesMessage.writeObject(new Object());
+    }
+
+    @Test
+    public void testGetBodyLength() throws JMSException {
+        JmsBytesMessage msg = factory.createBytesMessage();
+        int len = 10;
+        for (int i = 0; i < len; i++) {
+            msg.writeLong(5L);
+        }
+
+        msg.reset();
+        assertTrue(msg.getBodyLength() == (len * 8));
+    }
+
+    @Test
+    public void testReadBoolean() throws JMSException {
+        JmsBytesMessage msg = factory.createBytesMessage();
+        msg.writeBoolean(true);
+        msg.reset();
+        assertTrue(msg.readBoolean());
+    }
+
+    @Test
+    public void testReadByte() throws JMSException {
+        JmsBytesMessage msg = factory.createBytesMessage();
+        msg.writeByte((byte) 2);
+        msg.reset();
+        assertTrue(msg.readByte() == 2);
+    }
+
+    @Test
+    public void testReadUnsignedByte() throws JMSException {
+        JmsBytesMessage msg = factory.createBytesMessage();
+        msg.writeByte((byte) 2);
+        msg.reset();
+        assertTrue(msg.readUnsignedByte() == 2);
+    }
+
+    @Test
+    public void testReadShort() throws JMSException {
+        JmsBytesMessage msg = factory.createBytesMessage();
+        msg.writeShort((short) 3000);
+        msg.reset();
+        assertTrue(msg.readShort() == 3000);
+    }
+
+    @Test
+    public void testReadUnsignedShort() throws JMSException {
+        JmsBytesMessage msg = factory.createBytesMessage();
+        msg.writeShort((short) 3000);
+        msg.reset();
+        assertTrue(msg.readUnsignedShort() == 3000);
+    }
+
+    @Test
+    public void testReadChar() throws JMSException {
+        JmsBytesMessage msg = factory.createBytesMessage();
+        msg.writeChar('a');
+        msg.reset();
+        assertTrue(msg.readChar() == 'a');
+    }
+
+    @Test
+    public void testReadInt() throws JMSException {
+        JmsBytesMessage msg = factory.createBytesMessage();
+        msg.writeInt(3000);
+        msg.reset();
+        assertTrue(msg.readInt() == 3000);
+    }
+
+    @Test
+    public void testReadLong() throws JMSException {
+        JmsBytesMessage msg = factory.createBytesMessage();
+        msg.writeLong(3000);
+        msg.reset();
+        assertTrue(msg.readLong() == 3000);
+    }
+
+    @Test
+    public void testReadFloat() throws JMSException {
+        JmsBytesMessage msg = factory.createBytesMessage();
+        msg.writeFloat(3.3f);
+        msg.reset();
+        assertTrue(msg.readFloat() == 3.3f);
+    }
+
+    @Test
+    public void testReadDouble() throws JMSException {
+        JmsBytesMessage msg = factory.createBytesMessage();
+        msg.writeDouble(3.3d);
+        msg.reset();
+        assertTrue(msg.readDouble() == 3.3d);
+    }
+
+    @Test
+    public void testReadUTF() throws JMSException {
+        JmsBytesMessage msg = factory.createBytesMessage();
+        String str = "this is a test";
+        msg.writeUTF(str);
+        msg.reset();
+        assertTrue(msg.readUTF().equals(str));
+    }
+
+    @Test
+    public void testReadBytesbyteArray() throws JMSException {
+        JmsBytesMessage msg = factory.createBytesMessage();
+        byte[] data = new byte[50];
+        for (int i = 0; i < data.length; i++) {
+            data[i] = (byte) i;
+        }
+        msg.writeBytes(data);
+        msg.reset();
+        byte[] test = new byte[data.length];
+        msg.readBytes(test);
+        for (int i = 0; i < test.length; i++) {
+            assertTrue(test[i] == i);
+        }
+    }
+
+    @Test
+    public void testWriteObject() throws JMSException {
+        JmsBytesMessage msg = factory.createBytesMessage();
+        try {
+            msg.writeObject("fred");
+            msg.writeObject(Boolean.TRUE);
+            msg.writeObject(Character.valueOf('q'));
+            msg.writeObject(Byte.valueOf((byte) 1));
+            msg.writeObject(Short.valueOf((short) 3));
+            msg.writeObject(Integer.valueOf(3));
+            msg.writeObject(Long.valueOf(300L));
+            msg.writeObject(new Float(3.3f));
+            msg.writeObject(new Double(3.3));
+            msg.writeObject(new byte[3]);
+        } catch (MessageFormatException mfe) {
+            fail("objectified primitives should be allowed");
+        }
+        try {
+            msg.writeObject(new Object());
+            fail("only objectified primitives are allowed");
+        } catch (MessageFormatException mfe) {
+        }
+    }
+
+    @Test
+    public void testClearBody() throws JMSException {
+        JmsBytesMessage bytesMessage = factory.createBytesMessage();
+        try {
+            bytesMessage.writeInt(1);
+            bytesMessage.clearBody();
+            assertFalse(bytesMessage.isReadOnlyBody());
+            bytesMessage.writeInt(1);
+            bytesMessage.readInt();
+        } catch (MessageNotReadableException mnwe) {
+        } catch (MessageNotWriteableException mnwe) {
+            assertTrue(false);
+        }
+    }
+
+    @Test
+    public void testReset() throws JMSException {
+        JmsBytesMessage message = factory.createBytesMessage();
+        try {
+            message.writeDouble(24.5);
+            message.writeLong(311);
+        } catch (MessageNotWriteableException mnwe) {
+            fail("should be writeable");
+        }
+        message.reset();
+        try {
+            assertTrue(message.isReadOnlyBody());
+            assertEquals(message.readDouble(), 24.5, 0);
+            assertEquals(message.readLong(), 311);
+        } catch (MessageNotReadableException mnre) {
+            fail("should be readable");
+        }
+        try {
+            message.writeInt(33);
+            fail("should throw exception");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+    }
+
+    @Test
+    public void testReadOnlyBody() throws JMSException {
+        JmsBytesMessage message = factory.createBytesMessage();
+        try {
+            message.writeBoolean(true);
+            message.writeByte((byte) 1);
+            message.writeByte((byte) 1);
+            message.writeBytes(new byte[1]);
+            message.writeBytes(new byte[3], 0, 2);
+            message.writeChar('a');
+            message.writeDouble(1.5);
+            message.writeFloat((float) 1.5);
+            message.writeInt(1);
+            message.writeLong(1);
+            message.writeObject("stringobj");
+            message.writeShort((short) 1);
+            message.writeShort((short) 1);
+            message.writeUTF("utfstring");
+        } catch (MessageNotWriteableException mnwe) {
+            fail("Should be writeable");
+        }
+        message.reset();
+        try {
+            message.readBoolean();
+            message.readByte();
+            message.readUnsignedByte();
+            message.readBytes(new byte[1]);
+            message.readBytes(new byte[2], 2);
+            message.readChar();
+            message.readDouble();
+            message.readFloat();
+            message.readInt();
+            message.readLong();
+            message.readUTF();
+            message.readShort();
+            message.readUnsignedShort();
+            message.readUTF();
+        } catch (MessageNotReadableException mnwe) {
+            fail("Should be readable");
+        }
+        try {
+            message.writeBoolean(true);
+            fail("Should have thrown exception");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+        try {
+            message.writeByte((byte) 1);
+            fail("Should have thrown exception");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+        try {
+            message.writeBytes(new byte[1]);
+            fail("Should have thrown exception");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+        try {
+            message.writeBytes(new byte[3], 0, 2);
+            fail("Should have thrown exception");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+        try {
+            message.writeChar('a');
+            fail("Should have thrown exception");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+        try {
+            message.writeDouble(1.5);
+            fail("Should have thrown exception");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+        try {
+            message.writeFloat((float) 1.5);
+            fail("Should have thrown exception");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+        try {
+            message.writeInt(1);
+            fail("Should have thrown exception");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+        try {
+            message.writeLong(1);
+            fail("Should have thrown exception");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+        try {
+            message.writeObject("stringobj");
+            fail("Should have thrown exception");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+        try {
+            message.writeShort((short) 1);
+            fail("Should have thrown exception");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+        try {
+            message.writeUTF("utfstring");
+            fail("Should have thrown exception");
+        } catch (MessageNotWriteableException mnwe) {
+        }
+    }
+
+    @Test
+    public void testWriteOnlyBody() throws JMSException {
+        JmsBytesMessage message = factory.createBytesMessage();
+        message.clearBody();
+        try {
+            message.writeBoolean(true);
+            message.writeByte((byte) 1);
+            message.writeByte((byte) 1);
+            message.writeBytes(new byte[1]);
+            message.writeBytes(new byte[3], 0, 2);
+            message.writeChar('a');
+            message.writeDouble(1.5);
+            message.writeFloat((float) 1.5);
+            message.writeInt(1);
+            message.writeLong(1);
+            message.writeObject("stringobj");
+            message.writeShort((short) 1);
+            message.writeShort((short) 1);
+            message.writeUTF("utfstring");
+        } catch (MessageNotWriteableException mnwe) {
+            fail("Should be writeable");
+        }
+        try {
+            message.readBoolean();
+            fail("Should have thrown exception");
+        } catch (MessageNotReadableException mnwe) {
+        }
+        try {
+            message.readByte();
+            fail("Should have thrown exception");
+        } catch (MessageNotReadableException e) {
+        }
+        try {
+            message.readUnsignedByte();
+            fail("Should have thrown exception");
+        } catch (MessageNotReadableException e) {
+        }
+        try {
+            message.readBytes(new byte[1]);
+            fail("Should have thrown exception");
+        } catch (MessageNotReadableException e) {
+        }
+        try {
+            message.readBytes(new byte[2], 2);
+            fail("Should have thrown exception");
+        } catch (MessageNotReadableException e) {
+        }
+        try {
+            message.readChar();
+            fail("Should have thrown exception");
+        } catch (MessageNotReadableException e) {
+        }
+        try {
+            message.readDouble();
+            fail("Should have thrown exception");
+        } catch (MessageNotReadableException e) {
+        }
+        try {
+            message.readFloat();
+            fail("Should have thrown exception");
+        } catch (MessageNotReadableException e) {
+        }
+        try {
+            message.readInt();
+            fail("Should have thrown exception");
+        } catch (MessageNotReadableException e) {
+        }
+        try {
+            message.readLong();
+            fail("Should have thrown exception");
+        } catch (MessageNotReadableException e) {
+        }
+        try {
+            message.readUTF();
+            fail("Should have thrown exception");
+        } catch (MessageNotReadableException e) {
+        }
+        try {
+            message.readShort();
+            fail("Should have thrown exception");
+        } catch (MessageNotReadableException e) {
+        }
+        try {
+            message.readUnsignedShort();
+            fail("Should have thrown exception");
+        } catch (MessageNotReadableException e) {
+        }
+        try {
+            message.readUTF();
+            fail("Should have thrown exception");
+        } catch (MessageNotReadableException e) {
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/e4decdc1/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsMapMessageTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsMapMessageTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsMapMessageTest.java
new file mode 100644
index 0000000..9b335af
--- /dev/null
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/message/JmsMapMessageTest.java
@@ -0,0 +1,911 @@
+/**
+ * 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.message;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.jms.JMSException;
+import javax.jms.MessageFormatException;
+import javax.jms.MessageNotWriteableException;
+
+import org.apache.qpid.jms.message.JmsDefaultMessageFactory;
+import org.apache.qpid.jms.message.JmsMapMessage;
+import org.apache.qpid.jms.message.JmsMessageFactory;
+import org.apache.qpid.jms.message.facade.JmsMapMessageFacade;
+import org.apache.qpid.jms.message.facade.defaults.JmsDefaultMapMessageFacade;
+import org.junit.Test;
+
+/**
+ * Test that the JMS level JmsMapMessage using a simple default message facade follows
+ * the JMS spec.
+ */
+public class JmsMapMessageTest {
+
+    private final JmsMessageFactory factory = new JmsDefaultMessageFactory();
+
+    // ======= general =========
+
+    @Test
+    public void testGetMapNamesWithNewMessageToSendReturnsEmptyEnumeration() throws Exception {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+        Enumeration<?> names = mapMessage.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 {
+        JmsMapMessageFacade facade = new JmsDefaultMapMessageFacade();
+        String myKey1 = "key1";
+        String myKey2 = "key2";
+        facade.put(myKey1, "value1");
+        facade.put(myKey2, "value2");
+
+        JmsMapMessage mapMessage = new JmsMapMessage(facade);
+        Enumeration<?> names = mapMessage.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 {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+        try {
+            mapMessage.setObject(null, "value");
+            fail("Expected exception not thrown");
+        } catch (IllegalArgumentException iae) {
+            // expected
+        }
+
+        try {
+            mapMessage.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 JmsMapMessage#clearBody()}
+     */
+    @Test
+    public void testReceivedMessageIsReadOnlyAndThrowsMNWE() throws Exception {
+        JmsMapMessageFacade facade = new JmsDefaultMapMessageFacade();
+        String myKey1 = "key1";
+        facade.put(myKey1, "value1");
+        JmsMapMessage mapMessage = new JmsMapMessage(facade);
+        mapMessage.onSend();
+
+        try {
+            mapMessage.setObject("name", "value");
+            fail("expected exception to be thrown");
+        } catch (MessageNotWriteableException mnwe) {
+            // expected
+        }
+    }
+
+    /**
+     * Test that calling {@link JmsMapMessage#clearBody()} makes a received message writable
+     */
+    @Test
+    public void testClearBodyMakesReceivedMessageWritable() throws Exception {
+        JmsMapMessageFacade facade = new JmsDefaultMapMessageFacade();
+        String myKey1 = "key1";
+        facade.put(myKey1, "value1");
+
+        JmsMapMessage mapMessage = new JmsMapMessage(facade);
+        mapMessage.onSend();
+
+        assertTrue("expected message to be read-only", mapMessage.isReadOnlyBody());
+        mapMessage.clearBody();
+        assertFalse("expected message to be writable", mapMessage.isReadOnlyBody());
+        mapMessage.setObject("name", "value");
+    }
+
+    /**
+     * Test that calling {@link JmsMapMessage#clearBody()} clears the underlying message body
+     * map.
+     */
+    @Test
+    public void testClearBodyClearsUnderlyingMessageMap() throws Exception {
+        JmsMapMessageFacade facade = new JmsDefaultMapMessageFacade();
+        String myKey1 = "key1";
+        facade.put(myKey1, "value1");
+
+        JmsMapMessage mapMessage = new JmsMapMessage(facade);
+
+        assertTrue("key should exist: " + myKey1, mapMessage.itemExists(myKey1));
+        mapMessage.clearBody();
+        assertTrue("expected map to be emptied", facade.isEmpty());
+        assertFalse("key should not exist", mapMessage.itemExists(myKey1));
+    }
+
+    /**
+     * When a map entry is not set, the behaviour of JMS specifies that it is equivalent to a
+     * null value, and the accessors should either return null, throw NPE, or behave in the same
+     * fashion as <primitive>.valueOf(String).
+     *
+     * Test that this is the case.
+     */
+    @Test
+    public void testGetMissingMapEntryResultsInExpectedBehaviour() throws Exception {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "does_not_exist";
+
+        // expect null
+        assertNull(mapMessage.getBytes(name));
+        assertNull(mapMessage.getString(name));
+
+        // expect false from Boolean.valueOf(null).
+        assertFalse(mapMessage.getBoolean(name));
+
+        // expect an NFE from the primitive integral <type>.valueOf(null) conversions
+        assertGetMapEntryThrowsNumberFormatException(mapMessage, name, Byte.class);
+        assertGetMapEntryThrowsNumberFormatException(mapMessage, name, Short.class);
+        assertGetMapEntryThrowsNumberFormatException(mapMessage, name, Integer.class);
+        assertGetMapEntryThrowsNumberFormatException(mapMessage, name, Long.class);
+
+        // expect an NPE from the primitive float, double, and char <type>.valuleOf(null)
+        // conversions
+        assertGetMapEntryThrowsNullPointerException(mapMessage, name, Float.class);
+        assertGetMapEntryThrowsNullPointerException(mapMessage, name, Double.class);
+        assertGetMapEntryThrowsNullPointerException(mapMessage, name, Character.class);
+    }
+
+    // ======= object =========
+
+    /**
+     * Test that the {@link JmsMapMessage#setObject(String, Object)} method rejects Objects of
+     * unexpected types
+     */
+    @Test(expected=MessageFormatException.class)
+    public void testSetObjectWithIllegalTypeThrowsMFE() throws Exception {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+        mapMessage.setObject("myPKey", new Exception());
+    }
+
+    @Test
+    public void testSetGetObject() throws Exception {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+        String keyName = "myProperty";
+
+        Object entryValue = null;
+        mapMessage.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessage.getObject(keyName));
+
+        entryValue = Boolean.valueOf(false);
+        mapMessage.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessage.getObject(keyName));
+
+        entryValue = Byte.valueOf((byte) 1);
+        mapMessage.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessage.getObject(keyName));
+
+        entryValue = Short.valueOf((short) 2);
+        mapMessage.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessage.getObject(keyName));
+
+        entryValue = Integer.valueOf(3);
+        mapMessage.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessage.getObject(keyName));
+
+        entryValue = Long.valueOf(4);
+        mapMessage.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessage.getObject(keyName));
+
+        entryValue = Float.valueOf(5.01F);
+        mapMessage.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessage.getObject(keyName));
+
+        entryValue = Double.valueOf(6.01);
+        mapMessage.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessage.getObject(keyName));
+
+        entryValue = "string";
+        mapMessage.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessage.getObject(keyName));
+
+        entryValue = Character.valueOf('c');
+        mapMessage.setObject(keyName, entryValue);
+        assertEquals(entryValue, mapMessage.getObject(keyName));
+
+        byte[] bytes = new byte[] { (byte) 1, (byte) 0, (byte) 1 };
+        mapMessage.setObject(keyName, bytes);
+        Object retrieved = mapMessage.getObject(keyName);
+        assertTrue(retrieved instanceof byte[]);
+        assertTrue(Arrays.equals(bytes, (byte[]) retrieved));
+    }
+
+    // ======= Strings =========
+
+    @Test
+    public void testSetGetString() throws Exception {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        // null value
+        String name = "myNullString";
+        String value = null;
+
+        assertFalse(mapMessage.itemExists(name));
+        mapMessage.setString(name, value);
+        assertTrue(mapMessage.itemExists(name));
+        assertEquals(value, mapMessage.getString(name));
+
+        // non-null value
+        name = "myName";
+        value = "myValue";
+
+        assertFalse(mapMessage.itemExists(name));
+        mapMessage.setString(name, value);
+        assertTrue(mapMessage.itemExists(name));
+        assertEquals(value, mapMessage.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 {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myStringName";
+        String value;
+
+        // boolean
+        value = "true";
+        mapMessage.setString(name, value);
+        assertGetMapEntryEquals(mapMessage, name, Boolean.valueOf(value), Boolean.class);
+
+        // byte
+        value = String.valueOf(Byte.MAX_VALUE);
+        mapMessage.setString(name, value);
+        assertGetMapEntryEquals(mapMessage, name, Byte.valueOf(value), Byte.class);
+
+        // short
+        value = String.valueOf(Short.MAX_VALUE);
+        mapMessage.setString(name, value);
+        assertGetMapEntryEquals(mapMessage, name, Short.valueOf(value), Short.class);
+
+        // int
+        value = String.valueOf(Integer.MAX_VALUE);
+        mapMessage.setString(name, value);
+        assertGetMapEntryEquals(mapMessage, name, Integer.valueOf(value), Integer.class);
+
+        // long
+        value = String.valueOf(Long.MAX_VALUE);
+        mapMessage.setString(name, value);
+        assertGetMapEntryEquals(mapMessage, name, Long.valueOf(value), Long.class);
+
+        // float
+        value = String.valueOf(Float.MAX_VALUE);
+        mapMessage.setString(name, value);
+        assertGetMapEntryEquals(mapMessage, name, Float.valueOf(value), Float.class);
+
+        // double
+        value = String.valueOf(Double.MAX_VALUE);
+        mapMessage.setString(name, value);
+        assertGetMapEntryEquals(mapMessage, 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 {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        String value = "myStringValue";
+
+        mapMessage.setString(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, 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 {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        boolean value = true;
+
+        mapMessage.setBoolean(name, value);
+        assertEquals("value not as expected", value, mapMessage.getBoolean(name));
+
+        assertGetMapEntryEquals(mapMessage, 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 {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        boolean value = true;
+
+        mapMessage.setBoolean(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Character.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Byte.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Short.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Integer.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Long.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Float.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, 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 {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        byte value = (byte) 1;
+
+        mapMessage.setByte(name, value);
+        assertEquals(value, mapMessage.getByte(name));
+
+        assertGetMapEntryEquals(mapMessage, name, String.valueOf(value), String.class);
+        assertGetMapEntryEquals(mapMessage, name, Short.valueOf(value), Short.class);
+        assertGetMapEntryEquals(mapMessage, name, Integer.valueOf(value), Integer.class);
+        assertGetMapEntryEquals(mapMessage, 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 {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        byte value = (byte) 1;
+
+        mapMessage.setByte(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Character.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Boolean.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Float.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, 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 {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        short value = (short) 1;
+
+        mapMessage.setShort(name, value);
+        assertEquals(value, mapMessage.getShort(name));
+
+        assertGetMapEntryEquals(mapMessage, name, String.valueOf(value), String.class);
+        assertGetMapEntryEquals(mapMessage, name, Integer.valueOf(value), Integer.class);
+        assertGetMapEntryEquals(mapMessage, 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 {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        short value = (short) 1;
+
+        mapMessage.setShort(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Character.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Boolean.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Byte.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Float.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, 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 {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        int value = 1;
+
+        mapMessage.setInt(name, value);
+        assertEquals(value, mapMessage.getInt(name));
+
+        assertGetMapEntryEquals(mapMessage, name, String.valueOf(value), String.class);
+        assertGetMapEntryEquals(mapMessage, 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 {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        int value = 1;
+
+        mapMessage.setInt(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Character.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Boolean.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Byte.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Short.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Float.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, 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 {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        long value = Long.MAX_VALUE;
+
+        mapMessage.setLong(name, value);
+        assertEquals(value, mapMessage.getLong(name));
+
+        assertGetMapEntryEquals(mapMessage, 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 {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        long value = Long.MAX_VALUE;
+
+        mapMessage.setLong(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Character.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Boolean.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Byte.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Short.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Integer.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Float.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, 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 {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        float value = Float.MAX_VALUE;
+
+        mapMessage.setFloat(name, value);
+        assertEquals(value, mapMessage.getFloat(name), 0.0);
+
+        assertGetMapEntryEquals(mapMessage, name, String.valueOf(value), String.class);
+        assertGetMapEntryEquals(mapMessage, 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 {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        float value = Float.MAX_VALUE;
+
+        mapMessage.setFloat(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Character.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Boolean.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Byte.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Short.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Integer.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Long.class);
+    }
+
+    // ======= double =========
+
+    /**
+     * Set a double, then retrieve it as all of the legal type combinations to verify it is
+     * parsed correctly
+     */
+    @Test
+    public void testSetDoubleGetLegal() throws Exception {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        double value = Double.MAX_VALUE;
+
+        mapMessage.setDouble(name, value);
+        assertEquals(value, mapMessage.getDouble(name), 0.0);
+
+        assertGetMapEntryEquals(mapMessage, name, String.valueOf(value), String.class);
+    }
+
+    /**
+     * Set a double, then retrieve it as all of the illegal type combinations to verify it fails
+     * as expected
+     */
+    @Test
+    public void testSetDoubleGetIllegal() throws Exception {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        double value = Double.MAX_VALUE;
+
+        mapMessage.setDouble(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Character.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Boolean.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Byte.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Short.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Integer.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Long.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Float.class);
+    }
+
+    // ======= character =========
+
+    /**
+     * Set a char, then retrieve it as all of the legal type combinations to verify it is parsed
+     * correctly
+     */
+    @Test
+    public void testSetCharGetLegal() throws Exception {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        char value = 'c';
+
+        mapMessage.setChar(name, value);
+        assertEquals(value, mapMessage.getChar(name));
+
+        assertGetMapEntryEquals(mapMessage, name, String.valueOf(value), String.class);
+    }
+
+    /**
+     * Set a char, then retrieve it as all of the illegal type combinations to verify it fails
+     * as expected
+     */
+    @Test
+    public void testSetCharGetIllegal() throws Exception {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        char value = 'c';
+
+        mapMessage.setChar(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, byte[].class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Boolean.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Byte.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Short.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Integer.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Long.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Float.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Double.class);
+    }
+
+    // ========= bytes ========
+
+    /**
+     * Set bytes, then retrieve it as all of the legal type combinations to verify it is parsed
+     * correctly
+     */
+    @Test
+    public void testSetBytesGetLegal() throws Exception {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        byte[] value = "myBytes".getBytes();
+
+        mapMessage.setBytes(name, value);
+        assertTrue(Arrays.equals(value, mapMessage.getBytes(name)));
+    }
+
+    /**
+     * Set bytes, then retrieve it as all of the illegal type combinations to verify it fails as
+     * expected
+     */
+    @Test
+    public void testSetBytesGetIllegal() throws Exception {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        byte[] value = "myBytes".getBytes();
+
+        mapMessage.setBytes(name, value);
+
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Character.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, String.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Boolean.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Byte.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Short.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Integer.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Long.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Float.class);
+        assertGetMapEntryThrowsMessageFormatException(mapMessage, name, Double.class);
+    }
+
+//  TODO - This is a test that should be moved to the Facade test for the AMQP message facades.
+//
+//    /**
+//     * Verify that for a message received with an AmqpValue containing a Map with a Binary entry
+//     * value, we are able to read it back as a byte[].
+//     */
+//    @Test
+//    public void testReceivedMapWithBinaryEntryReturnsByteArray() throws Exception {
+//        String myKey1 = "key1";
+//        String bytesSource = "myBytesAmqpValue";
+//
+//        Map<String, Object> origMap = new HashMap<String, Object>();
+//        byte[] bytes = bytesSource.getBytes();
+//        origMap.put(myKey1, new Binary(bytes));
+//
+//        org.apache.qpid.proton.codec.Data payloadData = new DataImpl();
+//        payloadData.putDescribedType(new AmqpValueDescribedType(origMap));
+//        Binary b = payloadData.encode();
+//
+//        System.out.println("Using encoded AMQP message payload: " + b);
+//
+//        Message message = Proton.message();
+//        int decoded = message.decode(b.getArray(), b.getArrayOffset(), b.getLength());
+//        assertEquals(decoded, b.getLength());
+//
+//        AmqpMapMessage amqpMapMessage = new AmqpMapMessage(message, _mockDelivery, _mockAmqpConnection);
+//
+//        JmsMapMessage mapMessage = new JmsMapMessage(amqpMapMessage, _mockSessionImpl, _mockConnectionImpl, null);
+//
+//        // retrieve the bytes using getBytes, check they match expectation
+//        byte[] receivedBytes = mapMessage.getBytes(myKey1);
+//        assertTrue(Arrays.equals(bytes, receivedBytes));
+//
+//        // retrieve the bytes using getObject, check they match expectation
+//        Object o = mapMessage.getObject(myKey1);
+//        assertTrue(o instanceof byte[]);
+//        assertTrue(Arrays.equals(bytes, (byte[]) o));
+//    }
+
+    /**
+     * Verify that setting bytes takes a copy of the array. Set bytes, then modify them, then
+     * retrieve the map entry and verify the two differ.
+     */
+    @Test
+    public void testSetBytesTakesSnapshot() throws Exception {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        byte[] orig = "myBytes".getBytes();
+        byte[] copy = Arrays.copyOf(orig, orig.length);
+
+        // set the original bytes
+        mapMessage.setBytes(name, orig);
+
+        // corrupt the original bytes
+        orig[0] = (byte) 0;
+
+        // verify retrieving the bytes still matches the copy but not the original array
+        byte[] retrieved = mapMessage.getBytes(name);
+        assertFalse(Arrays.equals(orig, retrieved));
+        assertTrue(Arrays.equals(copy, retrieved));
+    }
+
+    /**
+     * Verify that getting bytes returns a copy of the array. Set bytes, then get them, modify
+     * the retrieved value, then get them again and verify the two differ.
+     */
+    @Test
+    public void testGetBytesReturnsSnapshot() throws Exception {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        byte[] orig = "myBytes".getBytes();
+
+        // set the original bytes
+        mapMessage.setBytes(name, orig);
+
+        // retrieve them
+        byte[] retrieved1 = mapMessage.getBytes(name);
+        ;
+
+        // corrupt the retrieved bytes
+        retrieved1[0] = (byte) 0;
+
+        // verify retrieving the bytes again still matches the original array, but not the
+        // previously retrieved (and now corrupted) bytes.
+        byte[] retrieved2 = mapMessage.getBytes(name);
+        assertTrue(Arrays.equals(orig, retrieved2));
+        assertFalse(Arrays.equals(retrieved1, retrieved2));
+    }
+
+    /**
+     * Verify that setting bytes takes a copy of the array. Set bytes, then modify them, then
+     * retrieve the map entry and verify the two differ.
+     */
+    @Test
+    public void testSetBytesWithOffsetAndLength() throws Exception {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        byte[] orig = "myBytesAll".getBytes();
+
+        // extract the segment containing 'Bytes'
+        int offset = 2;
+        int length = 5;
+        byte[] segment = Arrays.copyOfRange(orig, offset, offset + length);
+
+        // set the same section from the original bytes
+        mapMessage.setBytes(name, orig, offset, length);
+
+        // verify the retrieved bytes from the map match the segment but not the full original
+        // array
+        byte[] retrieved = mapMessage.getBytes(name);
+        assertFalse(Arrays.equals(orig, retrieved));
+        assertTrue(Arrays.equals(segment, retrieved));
+    }
+
+    @Test
+    public void testSetBytesWithNull() throws Exception {
+        JmsMapMessage mapMessage = factory.createMapMessage();
+
+        String name = "myName";
+        mapMessage.setBytes(name, null);
+        assertNull(mapMessage.getBytes(name));
+    }
+
+    // ========= utility methods ========
+
+    private void assertGetMapEntryEquals(JmsMapMessage testMessage, String name, Object expectedValue, Class<?> clazz) throws JMSException {
+        Object actualValue = getMapEntryUsingTypeMethod(testMessage, name, clazz);
+        assertEquals(expectedValue, actualValue);
+    }
+
+    private void assertGetMapEntryThrowsMessageFormatException(JmsMapMessage testMessage, String name, Class<?> clazz) throws JMSException {
+        try {
+            getMapEntryUsingTypeMethod(testMessage, name, clazz);
+            fail("expected exception to be thrown");
+        } catch (MessageFormatException jmsMFE) {
+            // expected
+        }
+    }
+
+    private void assertGetMapEntryThrowsNumberFormatException(JmsMapMessage testMessage, String name, Class<?> clazz) throws JMSException {
+        try {
+            getMapEntryUsingTypeMethod(testMessage, name, clazz);
+            fail("expected exception to be thrown");
+        } catch (NumberFormatException nfe) {
+            // expected
+        }
+    }
+
+    private void assertGetMapEntryThrowsNullPointerException(JmsMapMessage testMessage, String name, Class<?> clazz) throws JMSException {
+        try {
+            getMapEntryUsingTypeMethod(testMessage, name, clazz);
+            fail("expected exception to be thrown");
+        } catch (NullPointerException npe) {
+            // expected
+        }
+    }
+
+    private Object getMapEntryUsingTypeMethod(JmsMapMessage 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");
+        }
+    }
+}


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