You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rg...@apache.org on 2007/01/08 18:02:37 UTC

svn commit: r494121 [4/5] - in /incubator/qpid/trunk/qpid: gentools/src/org/apache/qpid/gentools/ java/broker/src/main/java/org/apache/qpid/server/ java/broker/src/main/java/org/apache/qpid/server/ack/ java/broker/src/main/java/org/apache/qpid/server/c...

Modified: incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ReplayStore.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ReplayStore.java?view=diff&rev=494121&r1=494120&r2=494121
==============================================================================
--- incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ReplayStore.java (original)
+++ incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ReplayStore.java Mon Jan  8 09:02:26 2007
@@ -22,15 +22,7 @@
 
 import org.apache.log4j.Logger;
 import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQMethodBody;
-import org.apache.qpid.framing.ExchangeDeclareBody;
-import org.apache.qpid.framing.ExchangeDeleteBody;
-import org.apache.qpid.framing.QueueBindBody;
-import org.apache.qpid.framing.QueueDeclareBody;
-import org.apache.qpid.framing.QueueDeleteBody;
-import org.apache.qpid.framing.ClusterSynchBody;
-import org.apache.qpid.framing.BasicConsumeBody;
-import org.apache.qpid.framing.BasicCancelBody;
+import org.apache.qpid.framing.*;
 import org.apache.qpid.server.cluster.ClusteredProtocolSession;
 import org.apache.qpid.server.cluster.util.LogMessage;
 import org.apache.qpid.server.cluster.util.Bindings;
@@ -57,11 +49,11 @@
 
     private final Map<Class<? extends AMQMethodBody>, MethodRecorder> _globalRecorders = new HashMap<Class<? extends AMQMethodBody>, MethodRecorder>();
     private final Map<Class<? extends AMQMethodBody>, MethodRecorder> _localRecorders = new HashMap<Class<? extends AMQMethodBody>, MethodRecorder>();
-    private final Map<String, QueueDeclareBody> _sharedQueues = new ConcurrentHashMap<String, QueueDeclareBody>();
-    private final Map<String, QueueDeclareBody> _privateQueues = new ConcurrentHashMap<String, QueueDeclareBody>();
-    private final Bindings<String, String, QueueBindBody> _sharedBindings = new Bindings<String, String, QueueBindBody>();
-    private final Bindings<String, String, QueueBindBody> _privateBindings = new Bindings<String, String, QueueBindBody>();
-    private final Map<String, ExchangeDeclareBody> _exchanges = new ConcurrentHashMap<String, ExchangeDeclareBody>();
+    private final Map<AMQShortString, QueueDeclareBody> _sharedQueues = new ConcurrentHashMap<AMQShortString, QueueDeclareBody>();
+    private final Map<AMQShortString, QueueDeclareBody> _privateQueues = new ConcurrentHashMap<AMQShortString, QueueDeclareBody>();
+    private final Bindings<AMQShortString, AMQShortString, QueueBindBody> _sharedBindings = new Bindings<AMQShortString, AMQShortString, QueueBindBody>();
+    private final Bindings<AMQShortString, AMQShortString, QueueBindBody> _privateBindings = new Bindings<AMQShortString, AMQShortString, QueueBindBody>();
+    private final Map<AMQShortString, ExchangeDeclareBody> _exchanges = new ConcurrentHashMap<AMQShortString, ExchangeDeclareBody>();
     private final ConsumerCounts _consumers = new ConsumerCounts();
 
     public ReplayStore()
@@ -204,15 +196,15 @@
     private static class QueueDeclareRecorder extends ChainedMethodRecorder<QueueDeclareBody>
     {
         private final boolean _exclusive;
-        private final Map<String, QueueDeclareBody> _queues;
+        private final Map<AMQShortString, QueueDeclareBody> _queues;
 
-        QueueDeclareRecorder(boolean exclusive, Map<String, QueueDeclareBody> queues)
+        QueueDeclareRecorder(boolean exclusive, Map<AMQShortString, QueueDeclareBody> queues)
         {
             _queues = queues;
             _exclusive = exclusive;
         }
 
-        QueueDeclareRecorder(boolean exclusive, Map<String, QueueDeclareBody> queues, QueueDeclareRecorder recorder)
+        QueueDeclareRecorder(boolean exclusive, Map<AMQShortString, QueueDeclareBody> queues, QueueDeclareRecorder recorder)
         {
             super(recorder);
             _queues = queues;
@@ -236,15 +228,15 @@
 
     private class QueueDeleteRecorder extends ChainedMethodRecorder<QueueDeleteBody>
     {
-        private final Map<String, QueueDeclareBody> _queues;
-        private final Bindings<String, String, QueueBindBody> _bindings;
+        private final Map<AMQShortString, QueueDeclareBody> _queues;
+        private final Bindings<AMQShortString, AMQShortString, QueueBindBody> _bindings;
 
-        QueueDeleteRecorder(Map<String, QueueDeclareBody> queues, Bindings<String, String, QueueBindBody> bindings)
+        QueueDeleteRecorder(Map<AMQShortString, QueueDeclareBody> queues, Bindings<AMQShortString, AMQShortString, QueueBindBody> bindings)
         {
             this(queues, bindings, null);
         }
 
-        QueueDeleteRecorder(Map<String, QueueDeclareBody> queues, Bindings<String, String, QueueBindBody> bindings, QueueDeleteRecorder recorder)
+        QueueDeleteRecorder(Map<AMQShortString, QueueDeclareBody> queues, Bindings<AMQShortString, AMQShortString, QueueBindBody> bindings, QueueDeleteRecorder recorder)
         {
             super(recorder);
             _queues = queues;
@@ -267,16 +259,16 @@
 
     private class QueueBindRecorder extends ChainedMethodRecorder<QueueBindBody>
     {
-        private final Map<String, QueueDeclareBody> _queues;
-        private final Bindings<String, String, QueueBindBody> _bindings;
+        private final Map<AMQShortString, QueueDeclareBody> _queues;
+        private final Bindings<AMQShortString, AMQShortString, QueueBindBody> _bindings;
 
-        QueueBindRecorder(Map<String, QueueDeclareBody> queues, Bindings<String, String, QueueBindBody> bindings)
+        QueueBindRecorder(Map<AMQShortString, QueueDeclareBody> queues, Bindings<AMQShortString, AMQShortString, QueueBindBody> bindings)
         {
             _queues = queues;
             _bindings = bindings;
         }
 
-        QueueBindRecorder(Map<String, QueueDeclareBody> queues, Bindings<String, String, QueueBindBody> bindings, QueueBindRecorder recorder)
+        QueueBindRecorder(Map<AMQShortString, QueueDeclareBody> queues, Bindings<AMQShortString, AMQShortString, QueueBindBody> bindings, QueueBindRecorder recorder)
         {
             super(recorder);
             _queues = queues;

Modified: incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/queue/ClusteredQueue.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/queue/ClusteredQueue.java?view=diff&rev=494121&r1=494120&r2=494121
==============================================================================
--- incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/queue/ClusteredQueue.java (original)
+++ incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/queue/ClusteredQueue.java Mon Jan  8 09:02:26 2007
@@ -24,6 +24,7 @@
 import org.apache.qpid.AMQException;
 import org.apache.qpid.framing.BasicCancelBody;
 import org.apache.qpid.framing.QueueDeleteBody;
+import org.apache.qpid.framing.AMQShortString;
 import org.apache.qpid.server.cluster.*;
 import org.apache.qpid.server.cluster.util.LogMessage;
 import org.apache.qpid.server.protocol.AMQProtocolSession;
@@ -45,7 +46,7 @@
     private final GroupManager _groupMgr;
     private final NestedSubscriptionManager _subscriptions;
 
-    public ClusteredQueue(GroupManager groupMgr, String name, boolean durable, String owner, boolean autoDelete, QueueRegistry queueRegistry)
+    public ClusteredQueue(GroupManager groupMgr, AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete, QueueRegistry queueRegistry)
             throws AMQException
     {
         super(name, durable, owner, autoDelete, queueRegistry, new ClusteredSubscriptionManager());
@@ -53,7 +54,7 @@
         _subscriptions = ((ClusteredSubscriptionManager) getSubscribers()).getAllSubscribers();
     }
 
-    public ClusteredQueue(GroupManager groupMgr, String name, boolean durable, String owner, boolean autoDelete, QueueRegistry queueRegistry, Executor asyncDelivery)
+    public ClusteredQueue(GroupManager groupMgr, AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete, QueueRegistry queueRegistry, Executor asyncDelivery)
             throws AMQException
     {
         super(name, durable, owner, autoDelete, queueRegistry, asyncDelivery, new ClusteredSubscriptionManager(),
@@ -84,7 +85,7 @@
         }
     }
 
-    public void unregisterProtocolSession(AMQProtocolSession ps, int channel, String consumerTag) throws AMQException
+    public void unregisterProtocolSession(AMQProtocolSession ps, int channel, AMQShortString consumerTag) throws AMQException
     {
         //handle locally:
         super.unregisterProtocolSession(ps, channel, consumerTag);

Modified: incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/queue/PrivateQueue.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/queue/PrivateQueue.java?view=diff&rev=494121&r1=494120&r2=494121
==============================================================================
--- incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/queue/PrivateQueue.java (original)
+++ incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/queue/PrivateQueue.java Mon Jan  8 09:02:26 2007
@@ -25,6 +25,7 @@
 import org.apache.qpid.server.cluster.GroupManager;
 import org.apache.qpid.server.cluster.SimpleBodySendable;
 import org.apache.qpid.framing.QueueDeleteBody;
+import org.apache.qpid.framing.AMQShortString;
 
 import java.util.concurrent.Executor;
 
@@ -36,7 +37,7 @@
 {
     private final GroupManager _groupMgr;
 
-    public PrivateQueue(GroupManager groupMgr, String name, boolean durable, String owner, boolean autoDelete, QueueRegistry queueRegistry)
+    public PrivateQueue(GroupManager groupMgr, AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete, QueueRegistry queueRegistry)
             throws AMQException
     {
         super(name, durable, owner, autoDelete, queueRegistry);
@@ -44,7 +45,7 @@
 
     }
 
-    public PrivateQueue(GroupManager groupMgr, String name, boolean durable, String owner, boolean autoDelete, QueueRegistry queueRegistry, Executor asyncDelivery)
+    public PrivateQueue(GroupManager groupMgr, AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete, QueueRegistry queueRegistry, Executor asyncDelivery)
             throws AMQException
     {
         super(name, durable, owner, autoDelete, queueRegistry, asyncDelivery);

Modified: incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/queue/RemoteQueueProxy.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/queue/RemoteQueueProxy.java?view=diff&rev=494121&r1=494120&r2=494121
==============================================================================
--- incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/queue/RemoteQueueProxy.java (original)
+++ incubator/qpid/trunk/qpid/java/cluster/src/main/java/org/apache/qpid/server/queue/RemoteQueueProxy.java Mon Jan  8 09:02:26 2007
@@ -23,6 +23,7 @@
 import org.apache.log4j.Logger;
 import org.apache.qpid.AMQException;
 import org.apache.qpid.framing.BasicPublishBody;
+import org.apache.qpid.framing.AMQShortString;
 import org.apache.qpid.server.cluster.ClusteredProtocolSession;
 import org.apache.qpid.server.cluster.GroupManager;
 import org.apache.qpid.server.cluster.MemberHandle;
@@ -42,7 +43,7 @@
     private final MemberHandle _target;
     private final GroupManager _groupMgr;
 
-    public RemoteQueueProxy(MemberHandle target, GroupManager groupMgr, String name, boolean durable, String owner, boolean autoDelete, QueueRegistry queueRegistry)
+    public RemoteQueueProxy(MemberHandle target, GroupManager groupMgr, AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete, QueueRegistry queueRegistry)
             throws AMQException
     {
         super(name, durable, owner, autoDelete, queueRegistry);
@@ -51,7 +52,7 @@
         _groupMgr.addMemberhipChangeListener(new ProxiedQueueCleanup(target, this));
     }
 
-    public RemoteQueueProxy(MemberHandle target, GroupManager groupMgr, String name, boolean durable, String owner, boolean autoDelete, QueueRegistry queueRegistry, Executor asyncDelivery)
+    public RemoteQueueProxy(MemberHandle target, GroupManager groupMgr, AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete, QueueRegistry queueRegistry, Executor asyncDelivery)
             throws AMQException
     {
         super(name, durable, owner, autoDelete, queueRegistry, asyncDelivery);

Modified: incubator/qpid/trunk/qpid/java/cluster/src/test/java/org/apache/qpid/server/cluster/ClusterCapabilityTest.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/cluster/src/test/java/org/apache/qpid/server/cluster/ClusterCapabilityTest.java?view=diff&rev=494121&r1=494120&r2=494121
==============================================================================
--- incubator/qpid/trunk/qpid/java/cluster/src/test/java/org/apache/qpid/server/cluster/ClusterCapabilityTest.java (original)
+++ incubator/qpid/trunk/qpid/java/cluster/src/test/java/org/apache/qpid/server/cluster/ClusterCapabilityTest.java Mon Jan  8 09:02:26 2007
@@ -21,13 +21,14 @@
 package org.apache.qpid.server.cluster;
 
 import junit.framework.TestCase;
+import org.apache.qpid.framing.AMQShortString;
 
 public class ClusterCapabilityTest extends TestCase
 {
     public void testStartWithNull()
     {
         MemberHandle peer = new SimpleMemberHandle("myhost:9999");
-        String c = ClusterCapability.add(null, peer);
+        AMQShortString c = ClusterCapability.add(null, peer);
         assertTrue(ClusterCapability.contains(c));
         assertTrue(peer.matches(ClusterCapability.getPeer(c)));
     }
@@ -35,7 +36,7 @@
     public void testStartWithText()
     {
         MemberHandle peer = new SimpleMemberHandle("myhost:9999");
-        String c = ClusterCapability.add("existing text", peer);
+        AMQShortString c = ClusterCapability.add(new AMQShortString("existing text"), peer);
         assertTrue(ClusterCapability.contains(c));
         assertTrue(peer.matches(ClusterCapability.getPeer(c)));
     }

Modified: incubator/qpid/trunk/qpid/java/cluster/src/test/java/org/apache/qpid/server/cluster/SimpleClusterTest.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/cluster/src/test/java/org/apache/qpid/server/cluster/SimpleClusterTest.java?view=diff&rev=494121&r1=494120&r2=494121
==============================================================================
--- incubator/qpid/trunk/qpid/java/cluster/src/test/java/org/apache/qpid/server/cluster/SimpleClusterTest.java (original)
+++ incubator/qpid/trunk/qpid/java/cluster/src/test/java/org/apache/qpid/server/cluster/SimpleClusterTest.java Mon Jan  8 09:02:26 2007
@@ -21,6 +21,7 @@
 package org.apache.qpid.server.cluster;
 
 import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
 import org.apache.qpid.url.URLSyntaxException;
 import org.apache.qpid.client.AMQConnection;
 import org.apache.qpid.client.AMQSession;
@@ -36,7 +37,7 @@
         AMQConnection con = new AMQConnection("localhost:9000", "guest", "guest", "test", "/test");
         AMQSession session = (AMQSession) con.createSession(false, AMQSession.NO_ACKNOWLEDGE);
         System.out.println("Session created");
-        session.declareExchange("my_exchange", "direct");
+        session.declareExchange(new AMQShortString("my_exchange"), new AMQShortString("direct"));
         System.out.println("Exchange declared");
         con.close();
         System.out.println("Connection closed");

Modified: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java?view=diff&rev=494121&r1=494120&r2=494121
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java Mon Jan  8 09:02:26 2007
@@ -22,6 +22,7 @@
 
 import org.apache.qpid.framing.ChannelCloseBody;
 import org.apache.qpid.framing.AMQFrame;
+import org.apache.qpid.framing.AMQShortString;
 
 public class AMQChannelException extends AMQException
 {
@@ -51,6 +52,6 @@
 
     public AMQFrame getCloseFrame(int channel)
     {
-        return ChannelCloseBody.createAMQFrame(channel, major, minor, _classId, _methodId, getErrorCode(), getMessage());
+        return ChannelCloseBody.createAMQFrame(channel, major, minor, _classId, _methodId, getErrorCode(), new AMQShortString(getMessage()));
     }
 }

Modified: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/common/AMQPFilterTypes.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/common/AMQPFilterTypes.java?view=diff&rev=494121&r1=494120&r2=494121
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/common/AMQPFilterTypes.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/common/AMQPFilterTypes.java Mon Jan  8 09:02:26 2007
@@ -20,20 +20,22 @@
  */
 package org.apache.qpid.common;
 
+import org.apache.qpid.framing.AMQShortString;
+
 public enum AMQPFilterTypes
 {
     JMS_SELECTOR("x-filter-jms-selector"),
     NO_CONSUME("x-filter-no-consume"),
     AUTO_CLOSE("x-filter-auto-close");
 
-    private final String _value;
+    private final AMQShortString _value;
 
     AMQPFilterTypes(String value)
     {
-        _value = value;
+        _value = new AMQShortString(value);
     }
 
-    public String getValue()
+    public AMQShortString getValue()
     {
         return _value;
     }

Modified: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/exchange/ExchangeDefaults.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/exchange/ExchangeDefaults.java?view=diff&rev=494121&r1=494120&r2=494121
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/exchange/ExchangeDefaults.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/exchange/ExchangeDefaults.java Mon Jan  8 09:02:26 2007
@@ -20,17 +20,19 @@
  */
 package org.apache.qpid.exchange;
 
+import org.apache.qpid.framing.AMQShortString;
+
 public class ExchangeDefaults
 {
-    public final static String TOPIC_EXCHANGE_NAME = "amq.topic";
+    public final static AMQShortString TOPIC_EXCHANGE_NAME = new AMQShortString("amq.topic");
 
-    public final static String TOPIC_EXCHANGE_CLASS = "topic";
+    public final static AMQShortString TOPIC_EXCHANGE_CLASS = new AMQShortString("topic");
 
-    public final static String DIRECT_EXCHANGE_NAME = "amq.direct";
+    public final static AMQShortString DIRECT_EXCHANGE_NAME = new AMQShortString("amq.direct");
 
-    public final static String DIRECT_EXCHANGE_CLASS = "direct";
+    public final static AMQShortString DIRECT_EXCHANGE_CLASS = new AMQShortString("direct");
 
-    public final static String HEADERS_EXCHANGE_NAME = "amq.match";
+    public final static AMQShortString HEADERS_EXCHANGE_NAME = new AMQShortString("amq.match");
 
-    public final static String HEADERS_EXCHANGE_CLASS = "headers";
+    public final static AMQShortString HEADERS_EXCHANGE_CLASS = new AMQShortString("headers");
 }

Added: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java?view=auto&rev=494121
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java (added)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java Mon Jan  8 09:02:26 2007
@@ -0,0 +1,334 @@
+package org.apache.qpid.framing;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.log4j.Logger;
+
+import java.util.Arrays;
+
+/**
+ * A short string is a representation of an AMQ Short String
+ * Short strings differ from the Java String class by being limited to on ASCII characters (0-127)
+ * and thus can be held more effectively in a byte buffer.
+ *
+ */
+public final class AMQShortString implements CharSequence
+{
+    private static final Logger _logger = Logger.getLogger(AMQShortString.class);
+
+    private final ByteBuffer _data;
+    private int _hashCode;
+    private static final char[] EMPTY_CHAR_ARRAY = new char[0];
+
+    public AMQShortString(String data)
+    {
+        this(data == null ? EMPTY_CHAR_ARRAY : data.toCharArray());
+        if(data != null) _hashCode = data.hashCode();
+    }
+
+    public AMQShortString(char[] data)
+    {
+        if(data == null)
+        {
+            throw new NullPointerException("Cannot create AMQShortString with null char[]");
+        }
+        final int length = data.length;
+        final byte[] stringBytes = new byte[length];
+        for(int i = 0; i < length; i++)
+        {
+            stringBytes[i] = (byte) (0xFF & data[i]);
+        }
+
+        _data = ByteBuffer.wrap(stringBytes);
+        _data.rewind();
+
+    }
+
+    public AMQShortString(CharSequence charSequence)
+    {
+        final int length = charSequence.length();
+        final byte[] stringBytes = new byte[length];
+        int hash = 0;
+        for(int i = 0 ; i < length; i++)
+        {
+            stringBytes[i] = ((byte) (0xFF & charSequence.charAt(i)));
+            hash = (31 * hash) + stringBytes[i];
+
+        }
+        _data = ByteBuffer.wrap(stringBytes);
+        _data.rewind();
+        _hashCode = hash;
+
+    }
+
+    private AMQShortString(ByteBuffer data)
+    {
+        _data = data;
+        
+    }
+
+
+    /**
+     * Get the length of the short string
+     * @return length of the underlying byte array
+     */
+    public int length()
+    {
+        return _data.limit();
+    }
+
+    public char charAt(int index)
+    {
+
+        return (char) _data.get(index);
+
+    }
+
+    public CharSequence subSequence(int start, int end)
+    {
+        return new CharSubSequence(start,end);
+    }
+
+    public int writeToByteArray(byte[] encoding, int pos)
+    {
+        final int size = length();
+        encoding[pos++] = (byte) length();
+        for(int i = 0; i < size; i++)
+        {
+            encoding[pos++] = _data.get(i);
+        }
+        return pos;
+    }
+
+    public static AMQShortString readFromByteArray(byte[] byteEncodedDestination, int pos)
+    {
+
+        final byte len = byteEncodedDestination[pos];
+        if(len == 0)
+        {
+            return null;
+        }
+        ByteBuffer data = ByteBuffer.wrap(byteEncodedDestination,pos+1,len).slice();
+        
+
+        return new AMQShortString(data);
+    }
+
+    public static AMQShortString readFromBuffer(ByteBuffer buffer)
+    {
+        final short length = buffer.getUnsigned();
+        if (length == 0)
+        {
+            return null;
+        }
+        else
+        {
+            ByteBuffer data = buffer.slice();
+            data.limit(length);
+            data.rewind();
+            buffer.skip(length);
+
+            return new AMQShortString(data);
+        }
+    }
+
+    public void writeToBuffer(ByteBuffer buffer)
+    {
+
+
+        final int size = length();
+        if (size != 0)
+        {
+
+            buffer.put((byte)size);
+            if(_data.buf().hasArray())
+            {
+                buffer.put(_data.array(),_data.arrayOffset(),length());
+            }
+            else
+            {
+
+                for(int i = 0; i < size; i++)
+                {
+
+                    buffer.put(_data.get(i));
+                }
+            }
+        }
+        else
+        {
+            // really writing out unsigned byte
+            buffer.put((byte) 0);
+        }
+
+    }
+
+    private final class CharSubSequence implements CharSequence
+    {
+        private final int _offset;
+        private final int _end;
+
+
+        public CharSubSequence(final int offset, final int end)
+        {
+            _offset = offset;
+            _end = end;
+        }
+
+
+        public int length()
+        {
+            return _end - _offset;
+        }
+
+        public char charAt(int index)
+        {
+            return AMQShortString.this.charAt(index + _offset);
+        }
+
+        public CharSequence subSequence(int start, int end)
+        {
+            return new CharSubSequence(start+_offset,end+_offset);
+        }
+    }
+
+
+
+    public char[] asChars()
+    {
+        final int size = length();
+        final char[] chars = new char[size];
+
+
+
+
+        for(int i = 0 ; i < size; i++)
+        {
+            chars[i] = (char) _data.get(i);
+        }
+        return chars;
+    }
+
+
+
+    public String asString()
+    {
+        return new String(asChars());
+    }
+
+    public boolean equals(Object o)
+    {
+        if(o == null)
+        {
+            return false;
+        }
+        if(o == this)
+        {
+            return true;
+        }
+        if(o instanceof AMQShortString)
+        {
+
+            final AMQShortString otherString = (AMQShortString) o;
+
+            if(otherString.length() != length())
+            {
+                return false;
+            }
+            if((_hashCode != 0) && (otherString._hashCode != 0) && (_hashCode != otherString._hashCode))
+            {
+                return false;
+            }
+            final int size = length();
+            for(int i = 0; i < size; i++)
+            {
+                if(_data.get(i) != otherString._data.get(i))
+                {
+                    return false;
+                }
+            }
+
+            return true;
+
+
+        }
+        return (o instanceof CharSequence) && equals((CharSequence)o);
+
+    }
+
+    public boolean equals(CharSequence s)
+    {
+        if(s == null)
+        {
+            return false;
+        }
+        if(s.length() != length())
+        {
+            return false;
+        }
+        for(int i = 0; i < length(); i++)
+        {
+            if(charAt(i)!= s.charAt(i))
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public int hashCode()
+    {
+        int hash = _hashCode;
+        if(hash == 0)
+        {
+            final int size = length();
+
+
+            for(int i = 0; i < size; i++)
+            {
+                hash = (31 * hash) + _data.get(i);
+            }
+            _hashCode = hash;
+        }
+
+        return hash;
+    }
+
+    public void setDirty()
+    {
+        _hashCode = 0;
+    }
+    
+    public String toString()
+    {
+        return asString();
+    }
+
+
+    public int compareTo(AMQShortString name)
+    {
+        if(name == null)
+        {
+            return 1;
+        }
+        else
+        {
+
+            if(name.length() < length())
+            {
+                return - name.compareTo(this);
+            }
+
+
+
+            for(int i = 0; i < length() ; i++)
+            {
+                final byte d = _data.get(i);
+                final byte n = name._data.get(i);
+                if(d < n) return -1;
+                if(d > n) return 1;
+            }
+
+            return length() == name.length() ? 0 : -1;
+        }
+    }
+}

Modified: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java?view=diff&rev=494121&r1=494120&r2=494121
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java Mon Jan  8 09:02:26 2007
@@ -22,11 +22,18 @@
 
 import org.apache.log4j.Logger;
 import org.apache.mina.common.ByteBuffer;
+import org.apache.qpid.AMQPInvalidClassException;
+
+import javax.jms.JMSException;
+import javax.jms.MessageFormatException;
+import java.util.Enumeration;
 
 public class BasicContentHeaderProperties implements ContentHeaderProperties
 {
     private static final Logger _logger = Logger.getLogger(BasicContentHeaderProperties.class);
 
+    private static final AMQShortString ZERO_STRING = null;
+
     /**
      * We store the encoded form when we decode the content header so that if we need to
      * write it out without modifying it we can do so without incurring the expense of
@@ -51,35 +58,33 @@
      */
     private boolean _decodedContentType = true;
 
-    private String _contentType;
+    private AMQShortString _contentType;
 
-    private String _encoding;
+    private AMQShortString _encoding;
 
     private FieldTable _headers;
 
-    private JMSPropertyFieldTable _jmsHeaders;
-
     private byte _deliveryMode;
 
     private byte _priority;
 
-    private String _correlationId;
+    private AMQShortString _correlationId;
 
-    private String _replyTo;
+    private AMQShortString _replyTo;
 
     private long _expiration;
 
-    private String _messageId;
+    private AMQShortString _messageId;
 
     private long _timestamp;
 
-    private String _type;
+    private AMQShortString _type;
 
-    private String _userId;
+    private AMQShortString _userId;
 
-    private String _appId;
+    private AMQShortString _appId;
 
-    private String _clusterId;
+    private AMQShortString _clusterId;
 
     private int _propertyFlags = 0;
 
@@ -127,7 +132,14 @@
             }
             if ((_propertyFlags & (1 << 8)) > 0)
             {
-                size += EncodingUtils.encodedShortStringLength(String.valueOf(_expiration));
+                if(_expiration == 0L)
+                {
+                    size+=EncodingUtils.encodedShortStringLength(ZERO_STRING);
+                }
+                else
+                {
+                    size += EncodingUtils.encodedShortStringLength(_expiration);
+                }
             }
             if ((_propertyFlags & (1 << 7)) > 0)
             {
@@ -215,7 +227,14 @@
             }
             if ((_propertyFlags & (1 << 8)) > 0)
             {
-                EncodingUtils.writeShortStringBytes(buffer, String.valueOf(_expiration));
+                if(_expiration == 0L)
+                {
+                    EncodingUtils.writeShortStringBytes(buffer, ZERO_STRING);                    
+                }
+                else
+                {
+                    EncodingUtils.writeShortStringBytes(buffer, String.valueOf(_expiration));
+                }
             }
             if ((_propertyFlags & (1 << 7)) > 0)
             {
@@ -269,16 +288,15 @@
         {
             if ((_propertyFlags & (1 << 15)) > 0)
             {
-                _contentType = EncodingUtils.readShortString(buffer);
+                _contentType = EncodingUtils.readAMQShortString(buffer);
             }
             if ((_propertyFlags & (1 << 14)) > 0)
             {
-                _encoding = EncodingUtils.readShortString(buffer);
+                _encoding = EncodingUtils.readAMQShortString(buffer);
             }
             if ((_propertyFlags & (1 << 13)) > 0)
             {
                 _headers = EncodingUtils.readFieldTable(buffer);
-                setJMSHeaders();
             }
             if ((_propertyFlags & (1 << 12)) > 0)
             {
@@ -290,19 +308,19 @@
             }
             if ((_propertyFlags & (1 << 10)) > 0)
             {
-                _correlationId = EncodingUtils.readShortString(buffer);
+                _correlationId = EncodingUtils.readAMQShortString(buffer);
             }
             if ((_propertyFlags & (1 << 9)) > 0)
             {
-                _replyTo = EncodingUtils.readShortString(buffer);
+                _replyTo = EncodingUtils.readAMQShortString(buffer);
             }
             if ((_propertyFlags & (1 << 8)) > 0)
             {
-                _expiration = Long.parseLong(EncodingUtils.readShortString(buffer));
+                _expiration = EncodingUtils.readLongAsShortString(buffer);
             }
             if ((_propertyFlags & (1 << 7)) > 0)
             {
-                _messageId = EncodingUtils.readShortString(buffer);
+                _messageId = EncodingUtils.readAMQShortString(buffer);
             }
             if ((_propertyFlags & (1 << 6)) > 0)
             {
@@ -310,19 +328,19 @@
             }
             if ((_propertyFlags & (1 << 5)) > 0)
             {
-                _type = EncodingUtils.readShortString(buffer);
+                _type = EncodingUtils.readAMQShortString(buffer);
             }
             if ((_propertyFlags & (1 << 4)) > 0)
             {
-                _userId = EncodingUtils.readShortString(buffer);
+                _userId = EncodingUtils.readAMQShortString(buffer);
             }
             if ((_propertyFlags & (1 << 3)) > 0)
             {
-                _appId = EncodingUtils.readShortString(buffer);
+                _appId = EncodingUtils.readAMQShortString(buffer);
             }
             if ((_propertyFlags & (1 << 2)) > 0)
             {
-                _clusterId = EncodingUtils.readShortString(buffer);
+                _clusterId = EncodingUtils.readAMQShortString(buffer);
             }
         }
         catch (AMQFrameDecodingException e)
@@ -361,7 +379,6 @@
             if ((_propertyFlags & (1 << 13)) > 0)
             {
                 _headers = EncodingUtils.readFieldTable(buffer);
-                setJMSHeaders();
 
             }
             _decodedHeaders = true;
@@ -378,7 +395,7 @@
 
         if ((_propertyFlags & (1 << 15)) > 0)
         {
-            _contentType = EncodingUtils.readShortString(buffer);
+            _contentType = EncodingUtils.readAMQShortString(buffer);
         }
 
         _decodedContentType = true;
@@ -408,30 +425,45 @@
         }
     }
 
-    public String getContentType()
+    public AMQShortString getContentTypeShortString()
     {
         decodeContentTypeIfNecessary();
         return _contentType;
     }
 
-    public void setContentType(String contentType)
+
+    public String getContentType()
+    {
+        decodeContentTypeIfNecessary();
+        return _contentType == null ? null : _contentType.toString();
+    }
+
+    public void setContentType(AMQShortString contentType)
     {
         clearEncodedForm();
         _propertyFlags |= (1 << 15);
         _contentType = contentType;
     }
 
+
+    public void setContentType(String contentType)
+    {
+        clearEncodedForm();
+        _propertyFlags |= (1 << 15);
+        _contentType = contentType == null ? null : new AMQShortString(contentType);
+    }
+
     public String getEncoding()
     {
         decodeIfNecessary();
-        return _encoding;
+        return _encoding == null ? null : _encoding.toString();
     }
 
     public void setEncoding(String encoding)
     {
         clearEncodedForm();
         _propertyFlags |= (1 << 14);
-        _encoding = encoding;
+        _encoding = encoding == null ? null : new AMQShortString(encoding);
     }
 
     public FieldTable getHeaders()
@@ -451,27 +483,8 @@
         clearEncodedForm();
         _propertyFlags |= (1 << 13);
         _headers = headers;
-        setJMSHeaders();
     }
 
-    private void setJMSHeaders()
-    {
-        if (_jmsHeaders == null)
-        {
-            _jmsHeaders = new JMSPropertyFieldTable(_headers);
-        }
-        else
-        {
-            _jmsHeaders.setFieldTable(_headers);
-        }
-    }
-
-    public JMSPropertyFieldTable getJMSHeaders()
-    {
-        //This will ensure we have a blank header
-        getHeaders();
-        return _jmsHeaders;
-    }
 
     public byte getDeliveryMode()
     {
@@ -502,24 +515,30 @@
     public String getCorrelationId()
     {
         decodeIfNecessary();
-        return _correlationId;
+        return _correlationId == null ? null : _correlationId.toString();
     }
 
     public void setCorrelationId(String correlationId)
     {
         clearEncodedForm();
         _propertyFlags |= (1 << 10);
-        _correlationId = correlationId;
+        _correlationId = correlationId == null ? null : new AMQShortString(correlationId);
     }
 
     public String getReplyTo()
     {
         decodeIfNecessary();
-        return _replyTo;
+        return _replyTo == null ? null : _replyTo.toString();
     }
 
     public void setReplyTo(String replyTo)
     {
+        setReplyTo(replyTo == null ? null : new AMQShortString(replyTo));
+    }
+    
+    public void setReplyTo(AMQShortString replyTo)
+    {
+
         clearEncodedForm();
         _propertyFlags |= (1 << 9);
         _replyTo = replyTo;
@@ -542,14 +561,14 @@
     public String getMessageId()
     {
         decodeIfNecessary();
-        return _messageId;
+        return _messageId == null ? null : _messageId.toString();
     }
 
     public void setMessageId(String messageId)
     {
         clearEncodedForm();
         _propertyFlags |= (1 << 7);
-        _messageId = messageId;
+        _messageId = messageId == null ? null : new AMQShortString(messageId);
     }
 
     public long getTimestamp()
@@ -568,57 +587,528 @@
     public String getType()
     {
         decodeIfNecessary();
-        return _type;
+        return _type == null ? null : _type.toString();
     }
 
     public void setType(String type)
     {
         clearEncodedForm();
         _propertyFlags |= (1 << 5);
-        _type = type;
+        _type = type == null ? null : new AMQShortString(type);
     }
 
     public String getUserId()
     {
         decodeIfNecessary();
-        return _userId;
+        return _userId == null ? null : _userId.toString();
     }
 
     public void setUserId(String userId)
     {
         clearEncodedForm();
         _propertyFlags |= (1 << 4);
-        _userId = userId;
+        _userId = userId == null ? null : new AMQShortString(userId);
     }
 
     public String getAppId()
     {
         decodeIfNecessary();
-        return _appId;
+        return _appId == null ? null : _appId.toString();
     }
 
     public void setAppId(String appId)
     {
         clearEncodedForm();
         _propertyFlags |= (1 << 3);
-        _appId = appId;
+        _appId = appId == null ? null : new AMQShortString(appId);
     }
 
     public String getClusterId()
     {
         decodeIfNecessary();
-        return _clusterId;
+        return _clusterId == null ? null : _clusterId.toString();
     }
 
     public void setClusterId(String clusterId)
     {
         clearEncodedForm();
         _propertyFlags |= (1 << 2);
-        _clusterId = clusterId;
+        _clusterId = clusterId == null ? null : new AMQShortString(clusterId);
     }
 
     public String toString()
     {
         return "reply-to = " + _replyTo + " propertyFlags = " + _propertyFlags;
+    }
+
+    // MapMessage  Interface
+    public boolean getBoolean(String string) throws JMSException
+    {
+        Boolean b = getHeaders().getBoolean(string);
+
+        if (b == null)
+        {
+            if (getHeaders().containsKey(string))
+            {
+                Object str = getHeaders().getObject(string);
+
+                if (str == null || !(str instanceof String))
+                {
+                    throw new MessageFormatException("getBoolean can't use " + string + " item.");
+                }
+                else
+                {
+                    return Boolean.valueOf((String) str);
+                }
+            }
+            else
+            {
+                b = Boolean.valueOf(null);
+            }
+        }
+
+        return b;
+    }
+
+    public boolean getBoolean(AMQShortString string) throws JMSException
+    {
+        Boolean b = getHeaders().getBoolean(string);
+
+        if (b == null)
+        {
+            if (getHeaders().containsKey(string))
+            {
+                Object str = getHeaders().getObject(string);
+
+                if (str == null || !(str instanceof String))
+                {
+                    throw new MessageFormatException("getBoolean can't use " + string + " item.");
+                }
+                else
+                {
+                    return Boolean.valueOf((String) str);
+                }
+            }
+            else
+            {
+                b = Boolean.valueOf(null);
+            }
+        }
+
+        return b;
+    }
+
+    public char getCharacter(String string) throws JMSException
+    {
+        Character c = getHeaders().getCharacter(string);
+
+        if (c == null)
+        {
+            if (getHeaders().isNullStringValue(string))
+            {
+                throw new NullPointerException("Cannot convert null char");
+            }
+            else
+            {
+                throw new MessageFormatException("getChar can't use " + string + " item.");
+            }
+        }
+        else
+        {
+            return (char) c;
+        }
+    }
+
+    public byte[] getBytes(String string) throws JMSException
+    {
+        return getBytes(new AMQShortString(string));
+    }
+
+    public byte[] getBytes(AMQShortString string) throws JMSException
+    {
+        byte[] bs = getHeaders().getBytes(string);
+
+        if (bs == null)
+        {
+            throw new MessageFormatException("getBytes can't use " + string + " item.");
+        }
+        else
+        {
+            return bs;
+        }
+    }
+
+    public byte getByte(String string) throws JMSException
+    {
+            Byte b = getHeaders().getByte(string);
+            if (b == null)
+            {
+                if (getHeaders().containsKey(string))
+                {
+                    Object str = getHeaders().getObject(string);
+
+                    if (str == null || !(str instanceof String))
+                    {
+                        throw new MessageFormatException("getByte can't use " + string + " item.");
+                    }
+                    else
+                    {
+                        return Byte.valueOf((String) str);
+                    }
+                }
+                else
+                {
+                    b = Byte.valueOf(null);
+                }
+            }
+
+            return b;
+    }
+
+    public short getShort(String string) throws JMSException
+    {
+            Short s = getHeaders().getShort(string);
+
+            if (s == null)
+            {
+                s = Short.valueOf(getByte(string));
+            }
+
+            return s;
+    }
+
+    public int getInteger(String string) throws JMSException
+    {
+            Integer i = getHeaders().getInteger(string);
+
+            if (i == null)
+            {
+                i = Integer.valueOf(getShort(string));
+            }
+
+            return i;
+    }
+
+    public long getLong(String string) throws JMSException
+    {
+            Long l = getHeaders().getLong(string);
+
+            if (l == null)
+            {
+                l = Long.valueOf(getInteger(string));
+            }
+
+            return l;
+    }
+
+    public float getFloat(String string) throws JMSException
+    {
+            Float f = getHeaders().getFloat(string);
+
+            if (f == null)
+            {
+                if (getHeaders().containsKey(string))
+                {
+                    Object str = getHeaders().getObject(string);
+
+                    if (str == null || !(str instanceof String))
+                    {
+                        throw new MessageFormatException("getFloat can't use " + string + " item.");
+                    }
+                    else
+                    {
+                        return Float.valueOf((String) str);
+                    }
+                }
+                else
+                {
+                    f = Float.valueOf(null);
+                }
+
+            }
+
+            return f;
+    }
+
+    public double getDouble(String string) throws JMSException
+    {
+            Double d = getHeaders().getDouble(string);
+
+            if (d == null)
+            {
+                d = Double.valueOf(getFloat(string));
+            }
+
+            return d;
+    }
+
+    public String getString(String string) throws JMSException
+    {
+        String s = getHeaders().getString(string);
+
+        if (s == null)
+        {
+            if (getHeaders().containsKey(string))
+            {
+                Object o = getHeaders().getObject(string);
+                if (o instanceof byte[])
+                {
+                    throw new MessageFormatException("getObject couldn't find " + string + " item.");
+                }
+                else
+                {
+                    if (o == null)
+                    {
+                        return null;
+                    }
+                    else
+                    {
+                        s = String.valueOf(o);
+                    }
+                }
+            }
+        }
+
+        return s;
+    }
+
+    public Object getObject(String string) throws JMSException
+    {
+        return getHeaders().getObject(string);
+    }
+
+    public void setBoolean(AMQShortString string, boolean b) throws JMSException
+    {
+        checkPropertyName(string);
+        getHeaders().setBoolean(string, b);
+    }
+
+    public void setBoolean(String string, boolean b) throws JMSException
+    {
+        checkPropertyName(string);
+        getHeaders().setBoolean(string, b);
+    }
+
+    public void setChar(String string, char c) throws JMSException
+    {
+        checkPropertyName(string);
+        getHeaders().setChar(string, c);
+    }
+
+    public Object setBytes(AMQShortString string, byte[] bytes)
+    {
+        return getHeaders().setBytes(string, bytes);
+    }
+
+    public Object setBytes(String string, byte[] bytes)
+    {
+        return getHeaders().setBytes(string, bytes);
+    }
+
+    public Object setBytes(String string, byte[] bytes, int start, int length)
+    {
+        return getHeaders().setBytes(string, bytes, start, length);
+    }
+
+    public void setByte(String string, byte b) throws JMSException
+    {
+        checkPropertyName(string);
+        getHeaders().setByte(string, b);
+    }
+
+    public void setShort(String string, short i) throws JMSException
+    {
+        checkPropertyName(string);
+        getHeaders().setShort(string, i);
+    }
+
+    public void setInteger(String string, int i) throws JMSException
+    {
+        checkPropertyName(string);
+        getHeaders().setInteger(string, i);
+    }
+
+    public void setLong(String string, long l) throws JMSException
+    {
+        checkPropertyName(string);
+        getHeaders().setLong(string, l);
+    }
+
+    public void setFloat(String string, float v) throws JMSException
+    {
+        checkPropertyName(string);
+        getHeaders().setFloat(string, v);
+    }
+
+    public void setDouble(String string, double v) throws JMSException
+    {
+        checkPropertyName(string);
+        getHeaders().setDouble(string, v);
+    }
+
+    public void setString(String string, String string1) throws JMSException
+    {
+        checkPropertyName(string);
+        getHeaders().setString(string, string1);
+    }
+
+    public void setString(AMQShortString string, String string1) throws JMSException
+    {
+        checkPropertyName(string);
+        getHeaders().setString(string, string1);
+    }
+
+    public void setObject(String string, Object object) throws JMSException
+    {
+        checkPropertyName(string);
+        try
+        {
+            getHeaders().setObject(string, object);
+        }
+        catch (AMQPInvalidClassException aice)
+        {
+            throw new MessageFormatException("Only primatives are allowed object is:" + object.getClass());
+        }
+    }
+
+    public boolean itemExists(String string) throws JMSException
+    {
+        return getHeaders().containsKey(string);
+    }
+
+    public Enumeration getPropertyNames()
+    {
+        return getHeaders().getPropertyNames();
+    }
+
+    public void clear()
+    {
+        getHeaders().clear();
+    }
+
+    public boolean propertyExists(AMQShortString propertyName)
+    {
+        return getHeaders().propertyExists(propertyName);
+    }
+
+    public boolean propertyExists(String propertyName)
+    {
+        return getHeaders().propertyExists(propertyName);
+    }
+
+    public Object put(Object key, Object value)
+    {
+        return getHeaders().setObject(key.toString(), value);
+    }
+
+    public Object remove(AMQShortString propertyName)
+    {
+        return getHeaders().remove(propertyName);
+    }
+
+    public Object remove(String propertyName)
+    {
+        return getHeaders().remove(propertyName);
+    }
+
+    public boolean isEmpty()
+    {
+        return getHeaders().isEmpty();
+    }
+
+    public void writeToBuffer(ByteBuffer data)
+    {
+        getHeaders().writeToBuffer(data);
+    }
+
+    public Enumeration getMapNames()
+    {
+        return getPropertyNames();
+    }
+
+    protected static void checkPropertyName(CharSequence propertyName)
+    {
+        if (propertyName == null)
+        {
+            throw new IllegalArgumentException("Property name must not be null");
+        }
+        else if (propertyName.length() == 0)
+        {
+            throw new IllegalArgumentException("Property name must not be the empty string");
+        }
+
+        checkIdentiferFormat(propertyName);
+    }
+
+    protected static void checkIdentiferFormat(CharSequence propertyName)
+    {
+//        JMS requirements 3.5.1 Property Names
+//        Identifiers:
+//        - An identifier is an unlimited-length character sequence that must begin
+//          with a Java identifier start character; all following characters must be Java
+//          identifier part characters. An identifier start character is any character for
+//          which the method Character.isJavaIdentifierStart returns true. This includes
+//          '_' and '$'. An identifier part character is any character for which the
+//          method Character.isJavaIdentifierPart returns true.
+//        - Identifiers cannot be the names NULL, TRUE, or FALSE.
+//        – Identifiers cannot be NOT, AND, OR, BETWEEN, LIKE, IN, IS, or
+//          ESCAPE.
+//        – Identifiers are either header field references or property references. The
+//          type of a property value in a message selector corresponds to the type
+//          used to set the property. If a property that does not exist in a message is
+//          referenced, its value is NULL. The semantics of evaluating NULL values
+//          in a selector are described in Section 3.8.1.2, “Null Values.”
+//        – The conversions that apply to the get methods for properties do not
+//          apply when a property is used in a message selector expression. For
+//          example, suppose you set a property as a string value, as in the
+//          following:
+//              myMessage.setStringProperty("NumberOfOrders", "2");
+//          The following expression in a message selector would evaluate to false,
+//          because a string cannot be used in an arithmetic expression:
+//          "NumberOfOrders > 1"
+//        – Identifiers are case sensitive.
+//        – Message header field references are restricted to JMSDeliveryMode,
+//          JMSPriority, JMSMessageID, JMSTimestamp, JMSCorrelationID, and
+//          JMSType. JMSMessageID, JMSCorrelationID, and JMSType values may be
+//          null and if so are treated as a NULL value.
+
+        if (Boolean.getBoolean("strict-jms"))
+        {
+            // JMS start character
+            if (!(Character.isJavaIdentifierStart(propertyName.charAt(0))))
+            {
+                throw new IllegalArgumentException("Identifier '" + propertyName + "' does not start with a valid JMS identifier start character");
+            }
+
+            // JMS part character
+            int length = propertyName.length();
+            for (int c = 1; c < length; c++)
+            {
+                if (!(Character.isJavaIdentifierPart(propertyName.charAt(c))))
+                {
+                    throw new IllegalArgumentException("Identifier '" + propertyName + "' contains an invalid JMS identifier character");
+                }
+            }
+
+
+
+
+            // JMS invalid names
+            if ((propertyName.equals("NULL")
+                 || propertyName.equals("TRUE")
+                 || propertyName.equals("FALSE")
+                 || propertyName.equals("NOT")
+                 || propertyName.equals("AND")
+                 || propertyName.equals("OR")
+                 || propertyName.equals("BETWEEN")
+                 || propertyName.equals("LIKE")
+                 || propertyName.equals("IN")
+                 || propertyName.equals("IS")
+                 || propertyName.equals("ESCAPE")))
+            {
+                throw new IllegalArgumentException("Identifier '" + propertyName + "' is not allowed in JMS");
+            }
+        }
+
     }
 }

Modified: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java?view=diff&rev=494121&r1=494120&r2=494121
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java Mon Jan  8 09:02:26 2007
@@ -28,6 +28,15 @@
 
     public ByteBuffer payload;
 
+    public ContentBody()
+    {
+    }
+
+    public ContentBody(ByteBuffer payload)
+    {
+        this.payload = payload;
+    }
+
     protected byte getFrameType()
     {
         return TYPE;

Modified: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java?view=diff&rev=494121&r1=494120&r2=494121
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java Mon Jan  8 09:02:26 2007
@@ -35,6 +35,7 @@
 
     public static final int SIZEOF_UNSIGNED_SHORT = 2;
     public static final int SIZEOF_UNSIGNED_INT = 4;
+    private static final boolean[] ALL_FALSE_ARRAY = new boolean[8];
 
     public static int encodedShortStringLength(String s)
     {
@@ -48,6 +49,120 @@
         }
     }
 
+
+    public static int encodedShortStringLength(short s)
+    {
+        if( s == 0 )
+        {
+            return 1 + 1;
+        }
+
+        int len = 0;
+        if(s < 0)
+        {
+            len=1;
+            // sloppy - doesn't work of Integer.MIN_VALUE
+            s=(short)-s;
+        }
+
+        if(s>9999)
+        {
+            return 1+5;
+        }
+        else if(s>999)
+        {
+            return 1+4;
+        }
+        else if(s>99)
+        {
+            return 1+3;
+        }
+        else if(s>9)
+        {
+            return 1+2;
+        }
+        else
+        {
+            return 1+1;
+        }
+
+    }
+
+
+    public static int encodedShortStringLength(int i)
+    {
+        if( i == 0 )
+        {
+            return 1 + 1;
+        }
+
+        int len = 0;
+        if(i < 0)
+        {
+            len=1;
+            // sloppy - doesn't work of Integer.MIN_VALUE
+            i=-i;
+        }
+
+        // range is now 1 - 2147483647
+        if(i < Short.MAX_VALUE)
+        {
+            return len + encodedShortStringLength((short)i);
+        }
+        else if (i > 999999)
+        {
+            return len + 6 + encodedShortStringLength((short)(i/1000000));
+        }
+        else // if (i > 99999)
+        {
+            return len + 5 + encodedShortStringLength((short)(i/100000));
+        }
+
+    }
+
+    public static int encodedShortStringLength(long l)
+    {
+        if(l == 0)
+        {
+            return 1 + 1;
+        }
+
+        int len = 0;
+        if(l < 0)
+        {
+            len=1;
+            // sloppy - doesn't work of Long.MIN_VALUE
+            l=-l;
+        }
+        if(l < Integer.MAX_VALUE)
+        {
+            return len + encodedShortStringLength((int) l);
+        }
+        else if(l > 9999999999L)
+        {
+            return len + 10 + encodedShortStringLength((int) (l / 10000000000L));
+        }
+        else
+        {
+            return len + 1 + encodedShortStringLength((int) (l / 10L));
+        }
+
+    }
+
+
+    public static int encodedShortStringLength(AMQShortString s)
+    {
+        if (s == null)
+        {
+            return 1;
+        }
+        else
+        {
+            return (short) (1 + s.length());
+        }
+    }
+
+
     public static int encodedLongStringLength(String s)
     {
         if (s == null)
@@ -124,6 +239,21 @@
         }
     }
 
+
+    public static void writeShortStringBytes(ByteBuffer buffer, AMQShortString s)
+    {
+        if (s != null)
+        {
+
+            s.writeToBuffer(buffer);
+        }
+        else
+        {
+            // really writing out unsigned byte
+            buffer.put((byte) 0);
+        }
+    }
+
     public static void writeLongStringBytes(ByteBuffer buffer, String s)
     {
         assert s == null || s.length() <= 0xFFFE;
@@ -284,13 +414,27 @@
 
     public static boolean[] readBooleans(ByteBuffer buffer)
     {
-        byte packedValue = buffer.get();
-        boolean[] result = new boolean[8];
+        final byte packedValue = buffer.get();
+        if(packedValue == 0)
+        {
+            return ALL_FALSE_ARRAY;
+        }
+        final boolean[] result = new boolean[8];
 
-        for (int i = 0; i < 8; i++)
+        result[0] = ((packedValue & 1) != 0);
+        result[1] = ((packedValue & (1 << 1)) != 0);
+        result[2] = ((packedValue & (1 << 2)) != 0);
+        result[3] = ((packedValue & (1 << 3)) != 0);
+        if((packedValue & 0xF0) == 0)
         {
-            result[i] = ((packedValue & (1 << i)) != 0);
+            result[0] = ((packedValue & 1) != 0);
         }
+        result[4] = ((packedValue & (1 << 4)) != 0);
+        result[5] = ((packedValue & (1 << 5)) != 0);
+        result[6] = ((packedValue & (1 << 6)) != 0);
+        result[7] = ((packedValue & (1 << 7)) != 0);
+
+
         return result;
     }
 
@@ -313,6 +457,12 @@
         return null;
     }
 
+    public static AMQShortString readAMQShortString(ByteBuffer buffer)
+    {
+        return AMQShortString.readFromBuffer(buffer);
+
+    }
+
     public static String readShortString(ByteBuffer buffer)
     {
         short length = buffer.getUnsigned();
@@ -628,4 +778,83 @@
         writeByte(buffer, (byte) character);
     }
 
+
+
+    public static void main(String[] args)
+    {
+        long[] nums = { 1000000000000000000L,
+                        100000000000000000L,
+                        10000000000000000L,
+                        1000000000000000L,
+                        100000000000000L,
+                        10000000000000L,
+                        1000000000000L,
+                        100000000000L,
+                        10000000000L,
+                        1000000000L,
+                        100000000L,
+                        10000000L,
+                        1000000L,
+                        100000L,
+                        10000L,
+                        1000L,
+                        100L,
+                        10L,
+                        1L,
+                        0L,
+                        787987932453564535L,
+                        543289830889480230L,
+                        3748104703875785L,
+                        463402485702857L,
+                        87402780489392L,
+                        1190489015032L,
+                        134303883744L
+                };
+
+
+
+
+        for(int i = 0; i < nums.length; i++)
+        {
+            ByteBuffer buffer = ByteBuffer.allocate(25);
+            writeShortStringBytes(buffer, String.valueOf(nums[i]));
+            buffer.flip();
+            System.out.println(nums[i] + " : " + readLongAsShortString(buffer));
+        }
+    }
+
+    public static long readLongAsShortString(ByteBuffer buffer)
+    {
+        short length = buffer.getUnsigned();
+        short pos = 0;
+        if(length == 0)
+        {
+            return 0L;
+        }
+        byte digit = buffer.get();
+        boolean isNegative;
+        long result = 0;
+        if(digit == (byte)'-')
+        {
+            isNegative = true;
+            pos++;
+            digit = buffer.get();
+        }
+        else
+        {
+            isNegative = false;
+        }
+        result = digit - (byte)'0';
+        pos++;
+
+        while(pos < length)
+        {
+            pos++;
+            digit = buffer.get();
+            result = (result << 3) + (result << 1);
+            result += digit - (byte)'0';
+        }
+
+        return result;
+    }
 }

Modified: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java?view=diff&rev=494121&r1=494120&r2=494121
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java Mon Jan  8 09:02:26 2007
@@ -31,17 +31,16 @@
 {
     private static final Logger _logger = Logger.getLogger(FieldTable.class);
 
-    private LinkedHashMap<String, AMQTypedValue> _properties;
+    private ByteBuffer _encodedForm;
+    private LinkedHashMap<AMQShortString, AMQTypedValue> _properties;
+    private long _encodedSize;
+    private static final int INITIAL_HASHMAP_CAPACITY = 16;
 
     public FieldTable()
     {
         super();
-        _properties = new LinkedHashMap<String, AMQTypedValue>();
-
     }
 
-
-
     /**
      * Construct a new field table.
      *
@@ -52,14 +51,105 @@
     public FieldTable(ByteBuffer buffer, long length) throws AMQFrameDecodingException
     {
         this();
-        setFromBuffer(buffer, length);
+        _encodedForm = buffer.slice();
+        _encodedForm.limit((int)length);
+        _encodedSize = length;
+        buffer.skip((int)length);
     }
 
 
 
+    private AMQTypedValue getProperty(AMQShortString string)
+    {
+        synchronized(this)
+        {
+            if(_properties == null)
+            {
+                if(_encodedForm == null)
+                {
+                    return null;
+                }
+                else
+                {
+                    populateFromBuffer();
+                }
+            }
+        }
+
+        if(_properties == null)
+        {
+            return null;
+        }
+        else
+        {
+            return _properties.get(string);
+        }
+    }
+
+    private void populateFromBuffer()
+    {
+        try
+        {
+            setFromBuffer(_encodedForm, _encodedSize);
+        }
+        catch (AMQFrameDecodingException e)
+        {
+            _logger.error("Error decoding FieldTable in deferred decoding mode ", e);
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+
+    private AMQTypedValue setProperty(AMQShortString key, AMQTypedValue val)
+    {
+        initMapIfNecessary();
+        _encodedForm = null;
+        if(val == null)
+        {
+            return removeKey(key);
+        }
+        AMQTypedValue oldVal = _properties.put(key,val);
+        if(oldVal != null)
+        {
+            _encodedSize -= oldVal.getEncodingSize();
+        }
+        else
+        {
+            _encodedSize += EncodingUtils.encodedShortStringLength(key) + 1;
+        }
+        _encodedSize += val.getEncodingSize();
+
+        return oldVal;
+    }
+
+    private void initMapIfNecessary()
+    {
+        synchronized(this)
+        {
+            if(_properties == null)
+            {
+                if(_encodedForm == null)
+                {
+                    _properties = new LinkedHashMap<AMQShortString,AMQTypedValue>();
+                }
+                else
+                {
+                    populateFromBuffer();
+                }
+            }
+
+        }
+    }
+
+
     public Boolean getBoolean(String string)
     {
-        AMQTypedValue value = _properties.get(string);
+        return getBoolean(new AMQShortString(string));
+    }
+
+    public Boolean getBoolean(AMQShortString string)
+    {
+        AMQTypedValue value = getProperty(string);
         if (value != null && (value.getType() == AMQType.BOOLEAN))
         {
             return (Boolean) value.getValue();
@@ -70,9 +160,15 @@
         }
     }
 
+
     public Byte getByte(String string)
     {
-        AMQTypedValue value = _properties.get(string);
+        return getByte(new AMQShortString(string));
+    }
+
+    public Byte getByte(AMQShortString string)
+    {
+        AMQTypedValue value = getProperty(string);
         if (value != null && (value.getType() == AMQType.BYTE))
         {
             return (Byte) value.getValue();
@@ -85,7 +181,12 @@
 
     public Short getShort(String string)
     {
-        AMQTypedValue value = _properties.get(string);
+        return getShort(new AMQShortString(string));
+    }
+
+    public Short getShort(AMQShortString string)
+    {
+        AMQTypedValue value = getProperty(string);
         if (value != null && (value.getType() == AMQType.SHORT))
         {
             return (Short) value.getValue();
@@ -98,7 +199,12 @@
 
     public Integer getInteger(String string)
     {
-        AMQTypedValue value = _properties.get(string);
+        return getInteger(new AMQShortString(string));
+    }
+
+    public Integer getInteger(AMQShortString string)
+    {
+        AMQTypedValue value = getProperty(string);
         if (value != null && (value.getType() == AMQType.INT))
         {
             return (Integer) value.getValue();
@@ -111,7 +217,12 @@
 
     public Long getLong(String string)
     {
-        AMQTypedValue value = _properties.get(string);
+        return getLong(new AMQShortString(string));
+    }
+
+    public Long getLong(AMQShortString string)
+    {
+        AMQTypedValue value = getProperty(string);
         if (value != null && (value.getType() == AMQType.LONG))
         {
             return (Long) value.getValue();
@@ -124,7 +235,12 @@
 
     public Float getFloat(String string)
     {
-        AMQTypedValue value = _properties.get(string);
+        return getFloat(new AMQShortString(string));
+    }
+
+    public Float getFloat(AMQShortString string)
+    {
+        AMQTypedValue value = getProperty(string);
         if (value != null && (value.getType() == AMQType.FLOAT))
         {
             return (Float) value.getValue();
@@ -137,7 +253,12 @@
 
     public Double getDouble(String string)
     {
-        AMQTypedValue value = _properties.get(string);
+        return getDouble(new AMQShortString(string));
+    }
+
+    public Double getDouble(AMQShortString string)
+    {
+        AMQTypedValue value = getProperty(string);
         if (value != null && (value.getType() == AMQType.DOUBLE))
         {
             return (Double) value.getValue();
@@ -150,7 +271,12 @@
 
     public String getString(String string)
     {
-        AMQTypedValue value = _properties.get(string);
+        return getString(new AMQShortString(string));
+    }
+
+    public String getString(AMQShortString string)
+    {
+        AMQTypedValue value = getProperty(string);
         if ((value != null) && ((value.getType() == AMQType.WIDE_STRING) ||
                                 (value.getType() == AMQType.ASCII_STRING)))
         {
@@ -170,7 +296,12 @@
 
     public Character getCharacter(String string)
     {
-        AMQTypedValue value = _properties.get(string);
+        return getCharacter(new AMQShortString(string));
+    }
+
+    public Character getCharacter(AMQShortString string)
+    {
+        AMQTypedValue value = getProperty(string);
         if (value != null && (value.getType() == AMQType.ASCII_CHARACTER))
         {
             return (Character) value.getValue();
@@ -183,7 +314,12 @@
 
     public byte[] getBytes(String string)
     {
-        AMQTypedValue value = _properties.get(string);
+        return getBytes(new AMQShortString(string));
+    }
+
+    public byte[] getBytes(AMQShortString string)
+    {
+        AMQTypedValue value = getProperty(string);
         if (value != null && (value.getType() == AMQType.BINARY))
         {
             return (byte[]) value.getValue();
@@ -196,7 +332,12 @@
 
     public Object getObject(String string)
     {
-        AMQTypedValue value = _properties.get(string);
+        return getObject(new AMQShortString(string));
+    }
+
+    public Object getObject(AMQShortString string)
+    {
+        AMQTypedValue value = getProperty(string);
         if(value != null)
         {
             return value.getValue();
@@ -209,92 +350,172 @@
     }
 
     // ************  Setters
-
     public Object setBoolean(String string, boolean b)
     {
+        return setBoolean(new AMQShortString(string), b);
+    }
+
+    public Object setBoolean(AMQShortString string, boolean b)
+    {
         checkPropertyName(string);
-        return _properties.put(string, AMQType.BOOLEAN.asTypedValue(b));
+        return setProperty(string, AMQType.BOOLEAN.asTypedValue(b));
     }
 
     public Object setByte(String string, byte b)
     {
+        return setByte(new AMQShortString(string), b);
+    }    
+
+    public Object setByte(AMQShortString string, byte b)
+    {
         checkPropertyName(string);
-        return _properties.put(string, AMQType.BYTE.asTypedValue(b));
+        return setProperty(string, AMQType.BYTE.asTypedValue(b));
     }
 
     public Object setShort(String string, short i)
     {
+        return setShort(new AMQShortString(string), i);
+    }
+
+    public Object setShort(AMQShortString string, short i)
+    {
         checkPropertyName(string);
-        return _properties.put(string, AMQType.SHORT.asTypedValue(i));
+        return setProperty(string, AMQType.SHORT.asTypedValue(i));
     }
 
+
     public Object setInteger(String string, int i)
     {
+        return setInteger(new AMQShortString(string), i);
+    }
+
+    public Object setInteger(AMQShortString string, int i)
+    {
         checkPropertyName(string);
-        return _properties.put(string, AMQType.INT.asTypedValue(i));
+        return setProperty(string, AMQType.INT.asTypedValue(i));
     }
 
+
     public Object setLong(String string, long l)
     {
+        return setLong(new AMQShortString(string), l);
+    }
+
+    public Object setLong(AMQShortString string, long l)
+    {
+        checkPropertyName(string);
+        return setProperty(string, AMQType.LONG.asTypedValue(l));
+    }
+
+
+    public Object setFloat(String string, float f)
+    {
+        return setFloat(new AMQShortString(string), f);
+    }
+
+    public Object setFloat(AMQShortString string, float v)
+    {
         checkPropertyName(string);
-        return _properties.put(string, AMQType.LONG.asTypedValue(l));
+        return setProperty(string, AMQType.FLOAT.asTypedValue(v));
     }
 
-    public Object setFloat(String string, float v)
+    public Object setDouble(String string, double d)
+    {
+        return setDouble(new AMQShortString(string), d);
+    }
+
+
+    public Object setDouble(AMQShortString string, double v)
     {
         checkPropertyName(string);
-        return _properties.put(string, AMQType.FLOAT.asTypedValue(v));
+        return setProperty(string, AMQType.DOUBLE.asTypedValue(v));
     }
 
-    public Object setDouble(String string, double v)
+
+    public Object setString(String string, String s)
+    {
+        return setString(new AMQShortString(string), s);
+    }
+
+    public Object setAsciiString(AMQShortString string, String value)
     {
         checkPropertyName(string);
-        return _properties.put(string, AMQType.DOUBLE.asTypedValue(v));
+        if (value == null)
+        {
+            return setProperty(string, AMQType.VOID.asTypedValue(null));
+        }
+        else
+        {
+            return setProperty(string, AMQType.ASCII_STRING.asTypedValue(value));
+        }
+
     }
 
-    public Object setString(String string, String value)
+    public Object setString(AMQShortString string, String value)
     {
         checkPropertyName(string);
         if (value == null)
         {
-            return _properties.put(string, AMQType.VOID.asTypedValue(null));
+            return setProperty(string, AMQType.VOID.asTypedValue(null));
         }
         else
         {
             //FIXME: determine string encoding and set either WIDE or ASCII string
 //            if ()
             {
-                return _properties.put(string, AMQType.WIDE_STRING.asTypedValue(value));
+                return setProperty(string, AMQType.WIDE_STRING.asTypedValue(value));
             }
 //            else
 //            {
-//                return _properties.put(string, AMQType.ASCII_STRING.asTypedValue(value));
+//                return setProperty(string, AMQType.ASCII_STRING.asTypedValue(value));
 //            }
         }
     }
 
+
     public Object setChar(String string, char c)
     {
+        return setChar(new AMQShortString(string), c);
+    }
+
+
+    public Object setChar(AMQShortString string, char c)
+    {
         checkPropertyName(string);
-        return _properties.put(string, AMQType.ASCII_CHARACTER.asTypedValue(c));
+        return setProperty(string, AMQType.ASCII_CHARACTER.asTypedValue(c));
     }
 
-    public Object setBytes(String string, byte[] bytes)
+
+    public Object setBytes(String string, byte[] b)
+    {
+        return setBytes(new AMQShortString(string), b);
+    }
+
+    public Object setBytes(AMQShortString string, byte[] bytes)
     {
         checkPropertyName(string);
-        return _properties.put(string, AMQType.BINARY.asTypedValue(bytes));
+        return setProperty(string, AMQType.BINARY.asTypedValue(bytes));
     }
 
     public Object setBytes(String string, byte[] bytes, int start, int length)
     {
+        return setBytes(new AMQShortString(string), bytes,start,length);
+    }
+
+    public Object setBytes(AMQShortString string, byte[] bytes, int start, int length)
+    {
         checkPropertyName(string);
         byte[] newBytes = new byte[length];
         System.arraycopy(bytes,start,newBytes,0,length);
         return setBytes(string, bytes);
     }
 
+    public Object setObject(String string, Object o)
+    {
+        return setObject(new AMQShortString(string), o);
+    }
 
-    public Object setObject(String string, Object object)
+    public Object setObject(AMQShortString string, Object object)
     {
         if (object instanceof Boolean)
         {
@@ -343,7 +564,7 @@
 
     public boolean isNullStringValue(String name)
     {
-        AMQTypedValue value = _properties.get(name);
+        AMQTypedValue value = getProperty(new AMQShortString(name));
         return (value != null) && (value.getType() == AMQType.VOID);
     }
 
@@ -351,7 +572,12 @@
 
     public Enumeration getPropertyNames()
     {
-        return Collections.enumeration(_properties.keySet());
+        return Collections.enumeration(keys());
+    }
+
+    public boolean propertyExists(AMQShortString propertyName)
+    {
+        return itemExists(propertyName);
     }
 
     public boolean propertyExists(String propertyName)
@@ -359,25 +585,32 @@
         return itemExists(propertyName);
     }
 
-    public boolean itemExists(String string)
+    public boolean itemExists(AMQShortString string)
     {
+        initMapIfNecessary();
         return _properties.containsKey(string);
     }
 
+    public boolean itemExists(String string)
+    {
+        return itemExists(new AMQShortString(string));
+    }
+
     public String toString()
     {
+        initMapIfNecessary();
         return _properties.toString();
     }
 
 
 
-    private void checkPropertyName(String propertyName)
+    private void checkPropertyName(AMQShortString propertyName)
     {
         if (propertyName == null)
         {
             throw new IllegalArgumentException("Property name must not be null");
         }
-        else if ("".equals(propertyName))
+        else if (propertyName.length()==0)
         {
             throw new IllegalArgumentException("Property name must not be the empty string");
         }
@@ -386,7 +619,7 @@
     }
 
 
-    protected static void checkIdentiferFormat(String propertyName)
+    protected static void checkIdentiferFormat(AMQShortString propertyName)
     {
 //        AMQP Spec: 4.2.5.5 Field Tables
 //        Guidelines for implementers:
@@ -448,20 +681,31 @@
 
     public long getEncodedSize()
     {
+        return _encodedSize;
+    }
+
+    private void recalculateEncodedSize()
+    {
+
         int encodedSize = 0;
-        for(Map.Entry<String,AMQTypedValue> e : _properties.entrySet())
+        if(_properties != null)
         {
-            encodedSize += EncodingUtils.encodedShortStringLength(e.getKey());
-            encodedSize++; // the byte for the encoding Type
-            encodedSize += e.getValue().getEncodingSize();
+            for(Map.Entry<AMQShortString,AMQTypedValue> e : _properties.entrySet())
+            {
+                encodedSize += EncodingUtils.encodedShortStringLength(e.getKey());
+                encodedSize++; // the byte for the encoding Type
+                encodedSize += e.getValue().getEncodingSize();
 
+            }
         }
-        return encodedSize;
+        _encodedSize = encodedSize;
     }
 
     public void addAll(FieldTable fieldTable)
     {
+        initMapIfNecessary();
         _properties.putAll(fieldTable._properties);
+        recalculateEncodedSize();
     }
 
 
@@ -473,135 +717,209 @@
 
     public Object processOverElements(FieldTableElementProcessor processor)
     {
-        for(Map.Entry<String,AMQTypedValue> e : _properties.entrySet())
+        initMapIfNecessary();
+        if(_properties != null)
         {
-            boolean result = processor.processElement(e.getKey(), e.getValue());
-            if(!result)
+            for(Map.Entry<AMQShortString,AMQTypedValue> e : _properties.entrySet())
             {
-                break;
+                boolean result = processor.processElement(e.getKey().toString(), e.getValue());
+                if(!result)
+                {
+                    break;
+                }
             }
         }
         return processor.getResult();
+
+
     }
 
 
     public int size()
     {
+        initMapIfNecessary();
         return _properties.size();
+
     }
 
     public boolean isEmpty()
     {
-        return _properties.isEmpty();
+        return size() ==0;
     }
 
-    public boolean containsKey(String key)
+    public boolean containsKey(AMQShortString key)
     {
+        initMapIfNecessary();
         return _properties.containsKey(key);
     }
 
+    public boolean containsKey(String key)
+    {
+        return containsKey(new AMQShortString(key));
+    }
+
     public Set<String> keys()
     {
-        return _properties.keySet();
+        initMapIfNecessary();
+        Set<String> keys = new LinkedHashSet<String>();
+        for(AMQShortString key : _properties.keySet())
+        {
+            keys.add(key.toString());
+        }
+        return keys;
     }
 
 
-    public Object get(Object key)
+    public Object get(AMQShortString key)
     {
 
-        return getObject((String)key);
+        return getObject(key);
     }
 
 
-    public Object put(Object key, Object value)
+
+    public Object put(AMQShortString key, Object value)
     {
-        return setObject(key.toString(), value);
+        return setObject(key, value);
     }
 
-    
+
     public Object remove(String key)
     {
+
+        return remove(new AMQShortString(key));
+
+    }
+
+    public Object remove(AMQShortString key)
+    {
+        AMQTypedValue val = removeKey(key);
+        return val == null ? null : val.getValue();
+
+    }
+
+
+    public AMQTypedValue removeKey(AMQShortString key)
+    {
+        initMapIfNecessary();
+        _encodedForm = null;
         AMQTypedValue value = _properties.remove(key);
-        return value == null ? null : value.getValue();
+        if(value == null)
+        {
+            return null;
+        }
+        else
+        {
+            _encodedSize -= EncodingUtils.encodedShortStringLength(key);
+            _encodedSize--;
+            _encodedSize -= value.getEncodingSize();
+            return value;
+        }
+
     }
 
 
 
     public void clear()
     {
+        initMapIfNecessary();
+        _encodedForm = null;        
         _properties.clear();
+        _encodedSize = 0;
     }
 
-    public Set keySet()
+    public Set<AMQShortString> keySet()
     {
+        initMapIfNecessary();
         return _properties.keySet();
     }
 
     private void putDataInBuffer(ByteBuffer buffer)
     {
 
-        final Iterator<Map.Entry<String,AMQTypedValue>> it = _properties.entrySet().iterator();
+        if(_encodedForm != null)
+        {
+             buffer.put(_encodedForm);
+        }
+        else if(_properties != null)
+        {
+            final Iterator<Map.Entry<AMQShortString,AMQTypedValue>> it = _properties.entrySet().iterator();
 
-        //If there are values then write out the encoded Size... could check _encodedSize != 0
-        // write out the total length, which we have kept up to date as data is added
+            //If there are values then write out the encoded Size... could check _encodedSize != 0
+            // write out the total length, which we have kept up to date as data is added
 
 
-        while (it.hasNext())
-        {
-            final Map.Entry<String,AMQTypedValue> me = it.next();
-            try
+            while (it.hasNext())
             {
-                if (_logger.isTraceEnabled())
+                final Map.Entry<AMQShortString,AMQTypedValue> me = it.next();
+                try
                 {
-                    _logger.trace("Writing Property:" + me.getKey() +
-                                  " Type:" + me.getValue().getType() +
-                                  " Value:" + me.getValue().getValue());
-                    _logger.trace("Buffer Position:" + buffer.position() +
-                                  " Remaining:" + buffer.remaining());
-                }
+                    if (_logger.isTraceEnabled())
+                    {
+                        _logger.trace("Writing Property:" + me.getKey() +
+                                      " Type:" + me.getValue().getType() +
+                                      " Value:" + me.getValue().getValue());
+                        _logger.trace("Buffer Position:" + buffer.position() +
+                                      " Remaining:" + buffer.remaining());
+                    }
 
 
 
-                //Write the actual parameter name
-                EncodingUtils.writeShortStringBytes(buffer, me.getKey());
-                me.getValue().writeToBuffer(buffer);
-            }
-            catch (Exception e)
-            {
-                if (_logger.isTraceEnabled())
+                    //Write the actual parameter name
+                    EncodingUtils.writeShortStringBytes(buffer, me.getKey());
+                    me.getValue().writeToBuffer(buffer);
+                }
+                catch (Exception e)
                 {
-                    _logger.trace("Exception thrown:" + e);
-                    _logger.trace("Writing Property:" + me.getKey() +
-                                  " Type:" + me.getValue().getType() +
-                                  " Value:" + me.getValue().getValue());
-                    _logger.trace("Buffer Position:" + buffer.position() +
-                                  " Remaining:" + buffer.remaining());
+                    if (_logger.isTraceEnabled())
+                    {
+                        _logger.trace("Exception thrown:" + e);
+                        _logger.trace("Writing Property:" + me.getKey() +
+                                      " Type:" + me.getValue().getType() +
+                                      " Value:" + me.getValue().getValue());
+                        _logger.trace("Buffer Position:" + buffer.position() +
+                                      " Remaining:" + buffer.remaining());
+                    }
+                    throw new RuntimeException(e);
                 }
-                throw new RuntimeException(e);
             }
         }
     }
 
 
-    public void setFromBuffer(ByteBuffer buffer, long length) throws AMQFrameDecodingException
+    private void setFromBuffer(ByteBuffer buffer, long length) throws AMQFrameDecodingException
     {
-        final boolean trace = _logger.isTraceEnabled();
 
-        int sizeRead = 0;
-        while (sizeRead < length)
+        final boolean trace = _logger.isTraceEnabled();
+        if(length > 0)
         {
-            int sizeRemaining = buffer.remaining();
-            final String key = EncodingUtils.readShortString(buffer);
-            AMQTypedValue value = AMQTypedValue.readFromBuffer(buffer);
-            sizeRead += (sizeRemaining - buffer.remaining());
 
-            if (trace)
+            final int expectedRemaining = buffer.remaining()-(int)length;
+
+            _properties = new LinkedHashMap<AMQShortString,AMQTypedValue>(INITIAL_HASHMAP_CAPACITY);
+
+            do
             {
-                _logger.trace("FieldTable::PropFieldTable(buffer," + length + "): Read type '" + value.getType() + "', key '" + key + "', value '" + value.getValue() + "' (now read " + sizeRead + " of " + length + " encoded bytes)...");
+
+                final AMQShortString key = EncodingUtils.readAMQShortString(buffer);
+                AMQTypedValue value = AMQTypedValue.readFromBuffer(buffer);
+
+                if (trace)
+                {
+                    _logger.trace("FieldTable::PropFieldTable(buffer," + length + "): Read type '" + value.getType() + "', key '" + key + "', value '" + value.getValue() + "'");
+                }
+
+
+
+                _properties.put(key,value);
+
+
+            
             }
+            while (buffer.remaining() > expectedRemaining);
 
-            _properties.put(key,value);
         }
+        _encodedSize = length;
 
         if (trace)
         {

Modified: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/protocol/AMQConstant.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/protocol/AMQConstant.java?view=diff&rev=494121&r1=494120&r2=494121
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/protocol/AMQConstant.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/protocol/AMQConstant.java Mon Jan  8 09:02:26 2007
@@ -20,6 +20,8 @@
  */
 package org.apache.qpid.protocol;
 
+import org.apache.qpid.framing.AMQShortString;
+
 import java.util.Map;
 import java.util.HashMap;
 
@@ -27,14 +29,14 @@
 {
     private int _code;
 
-    private String _name;
+    private AMQShortString _name;
 
     private static Map _codeMap = new HashMap();
 
     private AMQConstant(int code, String name, boolean map)
     {
         _code = code;
-        _name = name;
+        _name = new AMQShortString(name);
         if (map)
         {
             _codeMap.put(new Integer(code), this);
@@ -51,7 +53,7 @@
         return _code;
     }
 
-    public String getName()
+    public AMQShortString getName()
     {
         return _name;
     }