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 2006/12/18 10:11:14 UTC

svn commit: r488163 [4/4] - in /incubator/qpid/branches/new_persistence/java: ./ broker/ broker/bin/ broker/etc/ broker/src/main/java/org/apache/qpid/server/ broker/src/main/java/org/apache/qpid/server/exchange/ broker/src/main/java/org/apache/qpid/ser...

Modified: incubator/qpid/branches/new_persistence/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/new_persistence/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java?view=diff&rev=488163&r1=488162&r2=488163
==============================================================================
--- incubator/qpid/branches/new_persistence/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java (original)
+++ incubator/qpid/branches/new_persistence/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java Mon Dec 18 01:10:59 2006
@@ -1,322 +1,96 @@
 /*
+ *  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
  *
- * 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.
+ *    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.framing;
 
-import org.apache.log4j.Logger;
 import org.apache.mina.common.ByteBuffer;
 
-import java.util.*;
+import java.util.Map;
+import java.util.Enumeration;
 
-/**
- * From the protocol document:
- * field-table      = short-integer *field-value-pair
- * field-value-pair = field-name field-value
- * field-name       = short-string
- * field-value      = 'S' long-string
- * / 'I' long-integer
- * / 'D' decimal-value
- * / 'T' long-integer
- * decimal-value    = decimals long-integer
- * decimals         = OCTET
- */
-public class FieldTable extends LinkedHashMap
+public interface FieldTable extends Map
 {
-    private static final Logger _logger = Logger.getLogger(FieldTable.class);
-    private long _encodedSize = 0;
+    void writeToBuffer(ByteBuffer buffer);
+
+    void setFromBuffer(ByteBuffer buffer, long length) throws AMQFrameDecodingException;    
+
+    byte[] getDataAsBytes();
+
+    public long getEncodedSize();
+
+    Object put(Object key, Object value);
+
+    Object remove(Object key);
+
+
+    public Enumeration getPropertyNames();
+
+    public boolean propertyExists(String propertyName);
+
+    //Getters
+
+    public Boolean getBoolean(String string);
+
+    public Byte getByte(String string);
+
+    public Short getShort(String string);
+
+    public Integer getInteger(String string);
+
+    public Long getLong(String string);
+
+    public Float getFloat(String string);
+
+    public Double getDouble(String string);
+
+    public String getString(String string);
+
+    public Character getCharacter(String string);
+
+    public byte[] getBytes(String string);
+
+    public Object getObject(String string);
+
+    // Setters
+    public Object setBoolean(String string, boolean b);
+
+    public Object setByte(String string, byte b);
+
+    public Object setShort(String string, short i);
+
+    public Object setInteger(String string, int i);
+
+    public Object setLong(String string, long l);
+
+    public Object setFloat(String string, float v);
+
+    public Object setDouble(String string, double v);
+
+    public Object setString(String string, String string1);
+
+    public Object setChar(String string, char c);
+
+    public Object setBytes(String string, byte[] bytes);
+
+    public Object setBytes(String string, byte[] bytes, int start, int length);
+
+    public Object setObject(String string, Object object);
 
-    public FieldTable()
-    {
-        super();
-    }
-
-    /**
-     * Construct a new field table.
-     *
-     * @param buffer the buffer from which to read data. The length byte must be read already
-     * @param length the length of the field table. Must be > 0.
-     * @throws AMQFrameDecodingException if there is an error decoding the table
-     */
-    public FieldTable(ByteBuffer buffer, long length) throws AMQFrameDecodingException
-    {
-        super();
-        final boolean debug = _logger.isDebugEnabled();
-        assert length > 0;
-        _encodedSize = length;
-        int sizeRead = 0;
-        while (sizeRead < _encodedSize)
-        {
-            int sizeRemaining = buffer.remaining();
-            final String key = EncodingUtils.readShortString(buffer);
-            // TODO: use proper charset decoder
-            byte iType = buffer.get();
-            final char type = (char) iType;
-            Object value;
-            switch (type)
-            {
-                case 'S':
-                    value = EncodingUtils.readLongString(buffer);
-                    break;
-                case 'I':
-                    value = new Long(buffer.getUnsignedInt());
-                    break;
-                default:
-                    String msg = "Field '" + key + "' - unsupported field table type: " + type;
-                    //some extra debug information...
-                    msg += " (" + iType + "), length=" + length + ", sizeRead=" + sizeRead + ", sizeRemaining=" + sizeRemaining;
-                    throw new AMQFrameDecodingException(msg);
-            }
-            sizeRead += (sizeRemaining - buffer.remaining());
-
-            if (debug)
-            {
-                _logger.debug("FieldTable::FieldTable(buffer," + length + "): Read type '" + type + "', key '" + key + "', value '" + value + "' (now read " + sizeRead + " of " + length + " encoded bytes)...");
-            }
-
-            // we deliberately want to call put in the parent class since we do
-            // not need to do the size calculations
-            super.put(key, value);
-        }
-
-        if (debug)
-        {
-            _logger.debug("FieldTable::FieldTable(buffer," + length + "): Done.");
-        }
-    }
-
-    public void writeToBuffer(ByteBuffer buffer)
-    {
-        final boolean debug = _logger.isDebugEnabled();
-
-        if (debug)
-        {
-            _logger.debug("FieldTable::writeToBuffer: Writing encoded size of " + _encodedSize + "...");
-        }
-
-        // write out the total length, which we have kept up to date as data is added
-        EncodingUtils.writeUnsignedInteger(buffer, _encodedSize);
-        final Iterator it = this.entrySet().iterator();
-        while (it.hasNext())
-        {
-            Map.Entry me = (Map.Entry) it.next();
-            String key = (String) me.getKey();
-
-            EncodingUtils.writeShortStringBytes(buffer, key);
-            Object value = me.getValue();
-
-            if (debug)
-            {
-                _logger.debug("FieldTable::writeToBuffer: Writing key '" + key + "' of type " + value.getClass() + ", value '" + value + "'...");
-            }
-
-            if (value instanceof byte[])
-            {
-                buffer.put((byte) 'S');
-                EncodingUtils.writeLongstr(buffer, (byte[]) value);
-            }
-            else if (value instanceof String)
-            {
-                // TODO: look at using proper charset encoder
-                buffer.put((byte) 'S');
-                EncodingUtils.writeLongStringBytes(buffer, (String) value);
-            }
-            else if (value instanceof Long)
-            {
-                // TODO: look at using proper charset encoder
-                buffer.put((byte) 'I');
-                EncodingUtils.writeUnsignedInteger(buffer, ((Long) value).longValue());
-            }
-            else
-            {
-                // Should never get here
-                throw new IllegalArgumentException("Key '" + key + "': Unsupported type in field table, type: " + ((value == null) ? "null-object" : value.getClass()));
-            }
-        }
-
-        if (debug)
-        {
-            _logger.debug("FieldTable::writeToBuffer: Done.");
-        }
-    }
-
-    public byte[] getDataAsBytes()
-    {
-        final ByteBuffer buffer = ByteBuffer.allocate((int) _encodedSize); // XXX: Is cast a problem?
-        final Iterator it = this.entrySet().iterator();
-        while (it.hasNext())
-        {
-            Map.Entry me = (Map.Entry) it.next();
-            String key = (String) me.getKey();
-            EncodingUtils.writeShortStringBytes(buffer, key);
-            Object value = me.getValue();
-            if (value instanceof byte[])
-            {
-                buffer.put((byte) 'S');
-                EncodingUtils.writeLongstr(buffer, (byte[]) value);
-            }
-            else if (value instanceof String)
-            {
-                // TODO: look at using proper charset encoder
-                buffer.put((byte) 'S');
-                EncodingUtils.writeLongStringBytes(buffer, (String) value);
-            }
-            else if (value instanceof char[])
-            {
-                // TODO: look at using proper charset encoder
-                buffer.put((byte) 'S');
-                EncodingUtils.writeLongStringBytes(buffer, (char[]) value);
-            }
-            else if (value instanceof Long || value instanceof Integer)
-            {
-                // TODO: look at using proper charset encoder
-                buffer.put((byte) 'I');
-                EncodingUtils.writeUnsignedInteger(buffer, ((Long) value).longValue());
-            }
-            else
-            {
-                // Should never get here
-                assert false;
-            }
-        }
-        final byte[] result = new byte[(int) _encodedSize];
-        buffer.flip();
-        buffer.get(result);
-        buffer.release();
-        return result;
-    }
-
-    public Object put(Object key, Object value)
-    {
-        final boolean debug = _logger.isDebugEnabled();
-
-        if (key == null)
-        {
-            throw new IllegalArgumentException("All keys must be Strings - was passed: null");
-        }
-        else if (!(key instanceof String))
-        {
-            throw new IllegalArgumentException("All keys must be Strings - was passed: " + key.getClass());
-        }
-
-        Object existing;
-
-        if ((existing = super.remove(key)) != null)
-        {
-            if (debug)
-            {
-                _logger.debug("Found duplicate of key '" + key + "', previous value '" + existing + "' (" + existing.getClass() + "), to be replaced by '" + value + "', (" + value.getClass() + ") - stack trace of source of duplicate follows...", new Throwable().fillInStackTrace());
-            }
-
-            // If we are in effect deleting the value (see comment on null values being deleted
-            // below) then we also need to remove the name from the encoding length.
-            if (value == null)
-            {
-                _encodedSize -= EncodingUtils.encodedShortStringLength((String) key);
-            }
-
-            // FIXME: Should be able to short-cut this process if the old and new values are
-            // the same object and/or type and size...
-            _encodedSize -= getEncodingSize(existing);
-        }
-        else
-        {
-            if (value != null)
-            {
-                _encodedSize += EncodingUtils.encodedShortStringLength((String) key);
-            }
-        }
-
-        // For now: Setting a null value is the equivalent of deleting it.
-        // This is ambiguous in the JMS spec and needs thrashing out and potentially
-        // testing against other implementations.
-        if (value != null)
-        {
-            _encodedSize += getEncodingSize(value);
-        }
-
-        return super.put(key, value);
-    }
-
-    public Object remove(Object key)
-    {
-        if (super.containsKey(key))
-        {
-            final Object value = super.remove(key);
-            _encodedSize -= EncodingUtils.encodedShortStringLength((String) key);
-
-            // This check is, for now, unnecessary (we don't store null values).
-            if (value != null)
-            {
-                _encodedSize -= getEncodingSize(value);
-            }
-
-            return value;
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-    /**
-     * @return unsigned integer
-     */
-    public long getEncodedSize()
-    {
-        return _encodedSize;
-    }
-
-    /**
-     * @return integer
-     */
-    private static int getEncodingSize(Object value)
-    {
-        int encodingSize;
-
-        // the extra byte if for the type indicator that is written out
-        if (value instanceof String)
-        {
-            encodingSize = 1 + EncodingUtils.encodedLongStringLength((String) value);
-        }
-        else if (value instanceof char[])
-        {
-            encodingSize = 1 + EncodingUtils.encodedLongStringLength((char[]) value);
-        }
-        else if (value instanceof Integer)
-        {
-            encodingSize = 1 + 4;
-        }
-        else if (value instanceof Long)
-        {
-            encodingSize = 1 + 4;
-        }
-        else
-        {
-            throw new IllegalArgumentException("Unsupported type in field table: " + value.getClass());
-        }
-
-        return encodingSize;
-    }   
-
-    public Enumeration keys()
-    {
-        return new FieldTableKeyEnumeration(this);
-    }
 }

Modified: incubator/qpid/branches/new_persistence/java/common/src/main/java/org/apache/qpid/framing/PropertyFieldTable.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/new_persistence/java/common/src/main/java/org/apache/qpid/framing/PropertyFieldTable.java?view=diff&rev=488163&r1=488162&r2=488163
==============================================================================
--- incubator/qpid/branches/new_persistence/java/common/src/main/java/org/apache/qpid/framing/PropertyFieldTable.java (original)
+++ incubator/qpid/branches/new_persistence/java/common/src/main/java/org/apache/qpid/framing/PropertyFieldTable.java Mon Dec 18 01:10:59 2006
@@ -21,31 +21,44 @@
 package org.apache.qpid.framing;
 
 import org.apache.log4j.Logger;
+import org.apache.mina.common.ByteBuffer;
 
+import java.util.Collection;
 import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
 //extends FieldTable
-public class PropertyFieldTable
+public class PropertyFieldTable implements FieldTable, Map
 {
-
     private static final Logger _logger = Logger.getLogger(PropertyFieldTable.class);
 
-    public static final char BOOLEAN_PROPERTY_PREFIX = 'B';
+    public static final char AMQP_DECIMAL_PROPERTY_PREFIX = 'D';
+    public static final char AMQP_UNSIGNEDINT_PROPERTY_PREFIX = 'I';
+    public static final char AMQP_TIMESTAMP_PROPERTY_PREFIX = 'T';
+    public static final char AMQP_STRING_PROPERTY_PREFIX = 'S';
+    public static final char AMQP_ASCII_STRING_PROPERTY_PREFIX = 'c';
+    public static final char AMQP_WIDE_STRING_PROPERTY_PREFIX = 'C';
+    public static final char AMQP_BINARY_PROPERTY_PREFIX = 'x';
+
+    public static final char BOOLEAN_PROPERTY_PREFIX = 't';
     public static final char BYTE_PROPERTY_PREFIX = 'b';
     public static final char SHORT_PROPERTY_PREFIX = 's';
     public static final char INT_PROPERTY_PREFIX = 'i';
     public static final char LONG_PROPERTY_PREFIX = 'l';
     public static final char FLOAT_PROPERTY_PREFIX = 'f';
     public static final char DOUBLE_PROPERTY_PREFIX = 'd';
-    public static final char STRING_PROPERTY_PREFIX = 'S';
-    public static final char CHAR_PROPERTY_PREFIX = 'c';
-    public static final char BYTES_PROPERTY_PREFIX = 'y';
 
+    public static final char STRING_PROPERTY_PREFIX = AMQP_STRING_PROPERTY_PREFIX;
+    public static final char CHAR_PROPERTY_PREFIX = AMQP_ASCII_STRING_PROPERTY_PREFIX;
+    public static final char BYTES_PROPERTY_PREFIX = AMQP_BINARY_PROPERTY_PREFIX;
+
+    //Our custom prefix for encoding across the wire
+    private static final char XML_PROPERTY_PREFIX = 'X';
 
     private static final String BOOLEAN = "boolean";
     private static final String BYTE = "byte";
@@ -66,7 +79,7 @@
 
     private LinkedHashMap<String, Object> _properties;
     private LinkedHashMap<String, String> _propertyNamesTypeMap;
-
+    private long _encodedSize = 0;
 
     public PropertyFieldTable()
     {
@@ -84,73 +97,167 @@
         }
         catch (Exception e)
         {
-            System.out.println(textFormat);
-            e.printStackTrace();
+            _logger.error("Unable to decode PropertyFieldTable format:" + textFormat, e);
         }
+    }
 
+    /**
+     * Construct a new field table.
+     *
+     * @param buffer the buffer from which to read data. The length byte must be read already
+     * @param length the length of the field table. Must be > 0.
+     * @throws AMQFrameDecodingException if there is an error decoding the table
+     */
+    public PropertyFieldTable(ByteBuffer buffer, long length) throws AMQFrameDecodingException
+    {
+        this();
+        setFromBuffer(buffer, length);
     }
 
     // ************  Getters
 
+    private Object get(String propertyName, char prefix)
+    {
+        String type = _propertyNamesTypeMap.get(propertyName);
+
+        if (type == null)
+        {
+            return null;
+        }
+
+        if (type.equals("" + prefix))
+        {
+            return _properties.get(propertyName);
+        }
+        else
+        {
+            return null;
+        }
+    }
+
     public Boolean getBoolean(String string)
     {
-        return (Boolean) _properties.get(BOOLEAN_PROPERTY_PREFIX + string);
+        Object o = get(string, BOOLEAN_PROPERTY_PREFIX);
+        if (o != null)
+        {
+            return (Boolean) o;
+        }
+        else
+        {
+            return null;
+        }
     }
 
     public Byte getByte(String string)
     {
-        return (Byte) _properties.get(BYTE_PROPERTY_PREFIX + string);
+        Object o = get(string, BYTE_PROPERTY_PREFIX);
+        if (o != null)
+        {
+            return (Byte) o;
+        }
+        else
+        {
+            return null;
+        }
     }
 
     public Short getShort(String string)
     {
-        return (Short) _properties.get(SHORT_PROPERTY_PREFIX + string);
+        Object o = get(string, SHORT_PROPERTY_PREFIX);
+        if (o != null)
+        {
+            return (Short) o;
+        }
+        else
+        {
+            return null;
+        }
     }
 
     public Integer getInteger(String string)
     {
-        return (Integer) _properties.get(INT_PROPERTY_PREFIX + string);
+        Object o = get(string, INT_PROPERTY_PREFIX);
+        if (o != null)
+        {
+            return (Integer) o;
+        }
+        else
+        {
+            return null;
+        }
     }
 
     public Long getLong(String string)
     {
-        return (Long) _properties.get(LONG_PROPERTY_PREFIX + string);
+        Object o = get(string, LONG_PROPERTY_PREFIX);
+        if (o != null)
+        {
+            return (Long) o;
+        }
+        else
+        {
+            return null;
+        }
     }
 
     public Float getFloat(String string)
     {
-        return (Float) _properties.get(FLOAT_PROPERTY_PREFIX + string);
+        Object o = get(string, FLOAT_PROPERTY_PREFIX);
+        if (o != null)
+        {
+            return (Float) o;
+        }
+        else
+        {
+            return null;
+        }
     }
 
     public Double getDouble(String string)
     {
-        return (Double) _properties.get(DOUBLE_PROPERTY_PREFIX + string);
+        Object o = get(string, DOUBLE_PROPERTY_PREFIX);
+        if (o != null)
+        {
+            return (Double) o;
+        }
+        else
+        {
+            return null;
+        }
     }
 
     public String getString(String string)
     {
-        return (String) _properties.get(STRING_PROPERTY_PREFIX + string);
+        Object o = get(string, STRING_PROPERTY_PREFIX);
+        if (o != null)
+        {
+            return (String) o;
+        }
+        else
+        {
+            return null;
+        }
     }
 
     public Character getCharacter(String string)
     {
-        return (Character) _properties.get(CHAR_PROPERTY_PREFIX + string);
+        Object o = get(string, CHAR_PROPERTY_PREFIX);
+        if (o != null)
+        {
+            return (Character) o;
+        }
+        else
+        {
+            return null;
+        }
     }
 
     public byte[] getBytes(String string)
     {
-        return (byte[]) _properties.get(BYTES_PROPERTY_PREFIX + string);
-    }
-
-    public Object getObject(String string)
-    {
-        String typestring = _propertyNamesTypeMap.get(string);
-
-        if (typestring != null && !typestring.equals(""))
+        Object o = get(string, BYTES_PROPERTY_PREFIX);
+        if (o != null)
         {
-            char type = typestring.charAt(0);
-
-            return _properties.get(type + string);
+            return (byte[]) o;
         }
         else
         {
@@ -158,91 +265,66 @@
         }
     }
 
-    // ************  Setters
-
-
-    public void setBoolean(String string, boolean b)
+    public Object getObject(String string)
     {
-        checkPropertyName(string, BOOLEAN_PROPERTY_PREFIX);
+        return _properties.get(string);
+    }
 
+    // ************  Setters
 
-        _propertyNamesTypeMap.put(string, "" + BOOLEAN_PROPERTY_PREFIX);
-        _properties.put(BOOLEAN_PROPERTY_PREFIX + string, b);// ? new Long(1) : new Long(0));
+    public Object setBoolean(String string, boolean b)
+    {
+        return put(BOOLEAN_PROPERTY_PREFIX + string, b);
     }
 
-    public void setByte(String string, byte b)
+    public Object setByte(String string, byte b)
     {
-        checkPropertyName(string, BYTE_PROPERTY_PREFIX);
-
-
-        _properties.put(BYTE_PROPERTY_PREFIX + string, b);
+        return put(BYTE_PROPERTY_PREFIX + string, b);
     }
 
-    public void setShort(String string, short i)
+    public Object setShort(String string, short i)
     {
-        checkPropertyName(string, SHORT_PROPERTY_PREFIX);
-
-
-        _properties.put(SHORT_PROPERTY_PREFIX + string, i);
+        return put(SHORT_PROPERTY_PREFIX + string, i);
     }
 
-    public void setInteger(String string, int i)
+    public Object setInteger(String string, int i)
     {
-        checkPropertyName(string, INT_PROPERTY_PREFIX);
-
-
-        _properties.put(INT_PROPERTY_PREFIX + string, i);
+        return put(INT_PROPERTY_PREFIX + string, i);
     }
 
-    public void setLong(String string, long l)
+    public Object setLong(String string, long l)
     {
-        checkPropertyName(string, LONG_PROPERTY_PREFIX);
-
-
-        _properties.put(LONG_PROPERTY_PREFIX + string, l);
+        return put(LONG_PROPERTY_PREFIX + string, l);
     }
 
-    public void setFloat(String string, float v)
+    public Object setFloat(String string, float v)
     {
-        checkPropertyName(string, FLOAT_PROPERTY_PREFIX);
-
-
-        _properties.put(FLOAT_PROPERTY_PREFIX + string, v);
+        return put(FLOAT_PROPERTY_PREFIX + string, v);
     }
 
-    public void setDouble(String string, double v)
+    public Object setDouble(String string, double v)
     {
-        checkPropertyName(string, DOUBLE_PROPERTY_PREFIX);
-
-
-        _properties.put(DOUBLE_PROPERTY_PREFIX + string, v);
+        return put(DOUBLE_PROPERTY_PREFIX + string, v);
     }
 
-    public void setString(String string, String string1)
+    public Object setString(String string, String string1)
     {
-        checkPropertyName(string, STRING_PROPERTY_PREFIX);
-
-
-        _properties.put(STRING_PROPERTY_PREFIX + string, string1);
+        return put(STRING_PROPERTY_PREFIX + string, string1);
     }
 
-    public void setChar(String string, char c)
+    public Object setChar(String string, char c)
     {
-        checkPropertyName(string, CHAR_PROPERTY_PREFIX);
-
-        _properties.put(CHAR_PROPERTY_PREFIX + string, c);
+        return put(CHAR_PROPERTY_PREFIX + string, c);
     }
 
-    public void setBytes(String string, byte[] bytes)
+    public Object setBytes(String string, byte[] bytes)
     {
-        setBytes(string, bytes, 0, bytes.length);
+        return setBytes(string, bytes, 0, bytes.length);
     }
 
-    public void setBytes(String string, byte[] bytes, int start, int length)
+    public Object setBytes(String string, byte[] bytes, int start, int length)
     {
-        checkPropertyName(string, BYTES_PROPERTY_PREFIX);
-
-        _properties.put(BYTES_PROPERTY_PREFIX + string, sizeByteArray(bytes, start, length));
+        return put(BYTES_PROPERTY_PREFIX + string, sizeByteArray(bytes, start, length));
     }
 
     private byte[] sizeByteArray(byte[] bytes, int start, int length)
@@ -259,65 +341,65 @@
     }
 
 
-    public void setObject(String string, Object object)
+    public Object setObject(String string, Object object)
     {
         if (object instanceof Boolean)
         {
-            setBoolean(string, (Boolean) object);
+            return setBoolean(string, (Boolean) object);
         }
         else
         {
             if (object instanceof Byte)
             {
-                setByte(string, (Byte) object);
+                return setByte(string, (Byte) object);
             }
             else
             {
                 if (object instanceof Short)
                 {
-                    setShort(string, (Short) object);
+                    return setShort(string, (Short) object);
                 }
                 else
                 {
                     if (object instanceof Integer)
                     {
-                        setInteger(string, (Integer) object);
+                        return setInteger(string, (Integer) object);
                     }
                     else
                     {
                         if (object instanceof Long)
                         {
-                            setLong(string, (Long) object);
+                            return setLong(string, (Long) object);
                         }
                         else
                         {
                             if (object instanceof Float)
                             {
-                                setFloat(string, (Float) object);
+                                return setFloat(string, (Float) object);
                             }
                             else
                             {
                                 if (object instanceof Double)
                                 {
-                                    setDouble(string, (Double) object);
+                                    return setDouble(string, (Double) object);
                                 }
                                 else
                                 {
                                     if (object instanceof String)
                                     {
-                                        setString(string, (String) object);
+                                        return setString(string, (String) object);
                                     }
                                     else
                                     {
                                         if (object instanceof Character)
                                         {
-                                            setChar(string, (Character) object);
+                                            return setChar(string, (Character) object);
                                         }
                                         else
                                         {
                                             if (object instanceof byte[])
                                             {
-                                                setBytes(string, (byte[]) object);
+                                                return setBytes(string, (byte[]) object);
                                             }
                                         }
                                     }
@@ -328,8 +410,7 @@
                 }
             }
         }
-
-
+        return null;
     }
 
     // ***** Methods
@@ -344,12 +425,16 @@
         {
             String key = (String) keys.next();
 
-            names.add(key.substring(1));
+            names.add(key);
         }
 
         return names.elements();
     }
 
+    public boolean propertyExists(String propertyName)
+    {
+        return _propertyNamesTypeMap.containsKey(propertyName);
+    }
 
     public boolean itemExists(String string)
     {
@@ -367,7 +452,6 @@
         return false;
     }
 
-
     public String toString()
     {
         return valueOf(this);
@@ -390,35 +474,55 @@
             else
             {
                 buf.append('\n');
-                buf.append(propertyXML(propertyName, true));
 
-                if (propertyName.charAt(0) == BYTES_PROPERTY_PREFIX)
-                {
-                    //remove '>'
-                    buf.deleteCharAt(buf.length() - 1);
+                buf.append(valueAsXML(table._propertyNamesTypeMap.get(propertyName) + propertyName, entry.getValue()));
+            }
+        }
+        buf.append("\n");
+        buf.append(PROPERTY_FIELD_TABLE_CLOSE_XML);
 
-                    byte[] bytes = (byte[]) entry.getValue();
-                    buf.append(" length='").append(bytes.length).append("'>");
+        return buf.toString();
+    }
 
-                    buf.append(byteArrayToXML(propertyName.substring(1), bytes));
-                }
-                else
-                {
+    private static String valueAsXML(String name, Object value)
+    {
+        char propertyPrefix = name.charAt(0);
+        String propertyName = name.substring(1);
 
-                    buf.append(String.valueOf(entry.getValue()));
-                }
-                buf.append(propertyXML(propertyName, false));
 
-            }
+        StringBuffer buf = new StringBuffer();
+        // Start Tag
+        buf.append(propertyXML(name, true));
+
+        // Value
+        if (propertyPrefix == BYTES_PROPERTY_PREFIX)
+        {
+            //remove '>'
+            buf.deleteCharAt(buf.length() - 1);
+
+            byte[] bytes = (byte[]) value;
+            buf.append(" length='").append(bytes.length).append("'>");
+
+            buf.append(byteArrayToXML(propertyName, bytes));
         }
-        buf.append("\n");
-        buf.append(PROPERTY_FIELD_TABLE_CLOSE_XML);
+        else
+        {
+            buf.append(String.valueOf(value));
+        }
+
+        //End Tag
+        buf.append(propertyXML(name, false));
 
         return buf.toString();
     }
 
-    private void checkPropertyName(String propertyName, char propertyPrefix)
+    private Object checkPropertyName(String name)
     {
+        String propertyName = name.substring(1);
+        char propertyPrefix = name.charAt(0);
+
+        Object previous = null;
+
         if (propertyName == null)
         {
             throw new IllegalArgumentException("Property name must not be null");
@@ -428,19 +532,134 @@
             throw new IllegalArgumentException("Property name must not be the empty string");
         }
 
+        checkIdentiferFormat(propertyName);
+
         String currentValue = _propertyNamesTypeMap.get(propertyName);
 
         if (currentValue != null)
         {
-            _properties.remove(currentValue + propertyName);
+            previous = _properties.remove(currentValue + propertyName);
+
+            // If we are in effect deleting the value (see comment on null values being deleted
+            // below) then we also need to remove the name from the encoding length.
+            if (previous == null)
+            {
+                _encodedSize -= EncodingUtils.encodedShortStringLength(propertyName);
+            }
+
+            // FIXME: Should be able to short-cut this process if the old and new values are
+            // the same object and/or type and size...
+            _encodedSize -= getEncodingSize(currentValue + propertyName, previous);
         }
 
         _propertyNamesTypeMap.put(propertyName, "" + propertyPrefix);
+
+        return previous;
     }
 
-    private static String propertyXML(String propertyName, boolean start)
+
+    protected static void checkIdentiferFormat(String propertyName)
     {
-        char typeIdentifier = propertyName.charAt(0);
+
+//        AMQP Spec: 4.2.5.5 Field Tables
+//        Guidelines for implementers:
+//           * Field names MUST start with a letter, '$' or '#' and may continue with
+//             letters, '$' or '#', digits, or underlines, to a maximum length of 128
+//             characters.
+//           * The server SHOULD validate field names and upon receiving an invalid
+//             field name, it SHOULD signal a connection exception with reply code
+//             503 (syntax error). Conformance test: amq_wlp_table_01.
+//           * A peer MUST handle duplicate fields by using only the first instance.
+
+//        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");
+            }
+
+        }
+        else
+        {
+            // AMQP length limit
+            if (propertyName.length() > 128)
+            {
+                throw new IllegalArgumentException("AMQP limits property names to 128 characters");
+            }
+
+            // AMQ start character
+            if (!(Character.isLetter(propertyName.charAt(0))
+                  || propertyName.charAt(0) == '$'
+                  || propertyName.charAt(0) == '#'))
+            {
+                throw new IllegalArgumentException("Identifier '" + propertyName + "' does not start with a valid AMQP start character");
+            }
+        }
+
+    }
+
+    private static String propertyXML(String name, boolean start)
+    {
+        char propertyPrefix = name.charAt(0);
+        String propertyName = name.substring(1);
 
         StringBuffer buf = new StringBuffer();
 
@@ -453,8 +672,7 @@
             buf.append("</");
         }
 
-
-        switch (typeIdentifier)
+        switch (propertyPrefix)
         {
             case BOOLEAN_PROPERTY_PREFIX:
                 buf.append(BOOLEAN);
@@ -487,14 +705,13 @@
                 buf.append(CHAR);
                 break;
             default:
-                buf.append(UNKNOWN + " (identifier ").append(typeIdentifier).append(")");
+                buf.append(UNKNOWN + " (identifier ").append(propertyPrefix).append(")");
                 break;
         }
 
-
         if (start)
         {
-            buf.append(" name='").append(propertyName.substring(1)).append("'");
+            buf.append(" name='").append(propertyName).append("'");
         }
 
         buf.append(">");
@@ -519,8 +736,6 @@
 
     private void processBytesXMLLine(String xmlline)
     {
-        String type = xmlline.substring(1, xmlline.indexOf(" "));
-
         String propertyName = xmlline.substring(xmlline.indexOf('\'') + 1,
                                                 xmlline.indexOf('\'', xmlline.indexOf('\'') + 1));
         String value = xmlline.substring(xmlline.indexOf(">") + 1,
@@ -545,7 +760,6 @@
         {
             String token = tokenizer.nextToken();
 
-
             if (token.equals(PROPERTY_FIELD_TABLE_CLOSE_XML)
                 || token.equals(BYTES_CLOSE_XML))
             {
@@ -555,7 +769,6 @@
             if (token.equals(BYTES_CLOSE_XML))
             {
                 processing_bytes = false;
-
             }
 
             if (processing)
@@ -578,11 +791,9 @@
             {
                 processing = true;
             }
-
         }
     }
 
-
     private void processXMLLine(String xmlline)
     {
         // <<type> name='<property>'><value></<type>>
@@ -611,11 +822,39 @@
         }
         if (type.equals(BYTES))
         {
-            Integer length = Integer.parseInt(xmlline.substring(
-                    xmlline.lastIndexOf("=") + 2
-                    , xmlline.lastIndexOf("'")));
+            int headerEnd = xmlline.indexOf('>');
+            String bytesHeader = xmlline.substring(0, headerEnd);
+
+            //Extract length value
+            Integer length = Integer.parseInt(bytesHeader.substring(
+                    bytesHeader.lastIndexOf("=") + 2
+                    , bytesHeader.lastIndexOf("'")));
+
+
             byte[] bytes = new byte[length];
             setBytes(propertyName, bytes);
+
+            //Check if the line contains all the byte values
+            // This is needed as the XMLLine sent across the wire is the bytes value
+
+            int byteStart = xmlline.indexOf('<', headerEnd);
+
+            if (byteStart > 0)
+            {
+                while (!xmlline.startsWith(BYTES_CLOSE_XML, byteStart))
+                {
+                    //This should be the next byte line
+                    int bytePrefixEnd = xmlline.indexOf('>', byteStart) + 1;
+                    int byteEnd = xmlline.indexOf('>', bytePrefixEnd) + 1;
+
+                    String byteline = xmlline.substring(byteStart, byteEnd);
+
+                    processBytesXMLLine(byteline);
+
+                    byteStart = xmlline.indexOf('<', byteEnd);
+                }
+            }
+
         }
         if (type.equals(SHORT))
         {
@@ -651,6 +890,391 @@
         }
     }
 
+    // *************************  Byte Buffer Processing
 
-}
+    public void writeToBuffer(ByteBuffer buffer)
+    {
+        final boolean debug = _logger.isDebugEnabled();
+
+        if (debug)
+        {
+            _logger.debug("FieldTable::writeToBuffer: Writing encoded size of " + _encodedSize + "...");
+        }
+
+        EncodingUtils.writeUnsignedInteger(buffer, _encodedSize);
+
+        putDataInBuffer(buffer);
+    }
+
+    public byte[] getDataAsBytes()
+    {
+        final ByteBuffer buffer = ByteBuffer.allocate((int) _encodedSize); // FIXME XXX: Is cast a problem?
+
+        putDataInBuffer(buffer);
+
+        final byte[] result = new byte[(int) _encodedSize];
+        buffer.flip();
+        buffer.get(result);
+        buffer.release();
+        return result;
+    }
+
+
+    public int size()
+    {
+        return _properties.size();
+    }
+
+    public boolean isEmpty()
+    {
+        return _properties.isEmpty();
+    }
+
+    public boolean containsKey(Object key)
+    {
+        return _properties.containsKey(key);
+    }
+
+    public boolean containsValue(Object value)
+    {
+        return _properties.containsValue(value);
+    }
+
+    public Object get(Object key)
+    {
+        return _properties.get(key);
+    }
+
+
+    public Object put(Object key, Object value)
+    {
+        return setObject(key.toString(), value);
+    }
+
+    protected Object put(String key, Object value)
+    {
+        Object previous = checkPropertyName(key);
+
+
+        String propertyName = key.substring(1);
+        char propertyPrefix = _propertyNamesTypeMap.get(propertyName).charAt(0);
+
+        if (value != null)
+        {
+            //Add the size of the propertyName
+            _encodedSize += EncodingUtils.encodedShortStringLength(propertyName);
+
+            // For now: Setting a null value is the equivalent of deleting it.
+            // This is ambiguous in the JMS spec and needs thrashing out and potentially
+            // testing against other implementations.
+
+            //Add the size of the content
+            _encodedSize += getEncodingSize(key, value);
+        }
+
+        _properties.put((String) propertyName, value);
+
+        return previous;
+    }
+
+    public Object remove(Object key)
+    {
+        if (key instanceof String)
+        {
+            throw new IllegalArgumentException("Property key be a string");
+        }
+
+        char propertyPrefix = ((String) key).charAt(0);
+
+        if (_properties.containsKey(key))
+        {
+            final Object value = _properties.remove(key);
+            // plus one for the type
+            _encodedSize -= EncodingUtils.encodedShortStringLength(((String) key));
+
+            // This check is, for now, unnecessary (we don't store null values).
+            if (value != null)
+            {
+                _encodedSize -= getEncodingSize(propertyPrefix + (String) key, value);
+            }
+
+            return value;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    public void putAll(Map t)
+    {
+        Iterator it = t.keySet().iterator();
+
+        while (it.hasNext())
+        {
+            Object key = it.next();
+            put(key, t.get(key));
+        }
+    }
 
+    public void clear()
+    {
+        _properties.clear();
+        _propertyNamesTypeMap.clear();
+    }
+
+    public Set keySet()
+    {
+        return _properties.keySet();
+    }
+
+    public Collection values()
+    {
+        return _properties.values();
+    }
+
+    public Set entrySet()
+    {
+        return _properties.entrySet();
+    }
+
+    public long getEncodedSize()
+    {
+        return _encodedSize;
+    }
+
+
+    private void putDataInBuffer(ByteBuffer buffer)
+    {
+        final Iterator 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
+
+
+        while (it.hasNext())
+        {
+            Map.Entry me = (Map.Entry) it.next();
+            String propertyName = (String) me.getKey();
+
+            //The type value
+            char propertyPrefix = _propertyNamesTypeMap.get(propertyName).charAt(0);
+            //The actual param name skipping type
+
+            EncodingUtils.writeShortStringBytes(buffer, propertyName);
+            Object value = me.getValue();
+
+            switch (propertyPrefix)
+            {
+
+                case BOOLEAN_PROPERTY_PREFIX:
+                    buffer.put((byte) BOOLEAN_PROPERTY_PREFIX);
+                    EncodingUtils.writeBoolean(buffer, (Boolean) value);
+                    break;
+                case BYTE_PROPERTY_PREFIX:
+                    buffer.put((byte) BYTE_PROPERTY_PREFIX);
+                    EncodingUtils.writeByte(buffer, (Byte) value);
+                    break;
+                case SHORT_PROPERTY_PREFIX:
+                    buffer.put((byte) SHORT_PROPERTY_PREFIX);
+                    EncodingUtils.writeShort(buffer, (Short) value);
+                    break;
+                case INT_PROPERTY_PREFIX:
+                    buffer.put((byte) INT_PROPERTY_PREFIX);
+                    EncodingUtils.writeInteger(buffer, (Integer) value);
+                    break;
+                case AMQP_UNSIGNEDINT_PROPERTY_PREFIX: // Currently we don't create these
+                    buffer.put((byte) AMQP_UNSIGNEDINT_PROPERTY_PREFIX);
+                    EncodingUtils.writeUnsignedInteger(buffer, (Long) value);
+                    break;
+                case LONG_PROPERTY_PREFIX:
+                    buffer.put((byte) LONG_PROPERTY_PREFIX);
+                    EncodingUtils.writeLong(buffer, (Long) value);
+                    break;
+                case FLOAT_PROPERTY_PREFIX:
+                    buffer.put((byte) FLOAT_PROPERTY_PREFIX);
+                    EncodingUtils.writeFloat(buffer, (Float) value);
+                    break;
+                case DOUBLE_PROPERTY_PREFIX:
+                    buffer.put((byte) DOUBLE_PROPERTY_PREFIX);
+                    EncodingUtils.writeDouble(buffer, (Double) value);
+                    break;
+
+                case AMQP_WIDE_STRING_PROPERTY_PREFIX:
+                    //case AMQP_STRING_PROPERTY_PREFIX:
+                case STRING_PROPERTY_PREFIX:
+                    // TODO: look at using proper charset encoder
+                    buffer.put((byte) STRING_PROPERTY_PREFIX);
+                    EncodingUtils.writeLongStringBytes(buffer, (String) value);
+                    break;
+
+                    //case AMQP_ASCII_STRING_PROPERTY_PREFIX:
+                case CHAR_PROPERTY_PREFIX:
+                    // TODO: look at using proper charset encoder
+                    buffer.put((byte) CHAR_PROPERTY_PREFIX);
+                    EncodingUtils.writeShortStringBytes(buffer, "" + (Character) value);
+                    break;
+
+                case BYTES_PROPERTY_PREFIX:
+                    buffer.put((byte) BYTES_PROPERTY_PREFIX);
+                    EncodingUtils.writeBytes(buffer, (byte[]) value);
+                    break;
+
+                case XML_PROPERTY_PREFIX:
+                    // Encode as XML
+                    buffer.put((byte) XML_PROPERTY_PREFIX);
+                    EncodingUtils.writeLongStringBytes(buffer, valueAsXML(propertyPrefix + propertyName, value));
+                    break;
+                default:
+                {
+                    // Should never get here
+                    throw new IllegalArgumentException("Key '" + propertyName + "': Unsupported type in field table, type: " + ((value == null) ? "null-object" : value.getClass()));
+                }
+            }
+        }
+    }
+
+
+    public void setFromBuffer(ByteBuffer buffer, long length) throws AMQFrameDecodingException
+    {
+        final boolean debug = _logger.isDebugEnabled();
+
+        int sizeRead = 0;
+        while (sizeRead < length)
+        {
+            int sizeRemaining = buffer.remaining();
+            final String key = EncodingUtils.readShortString(buffer);
+            // TODO: use proper charset decoder
+            byte iType = buffer.get();
+            final char type = (char) iType;
+            Object value = null;
+
+            switch (type)
+            {
+                case BOOLEAN_PROPERTY_PREFIX:
+                    value = EncodingUtils.readBoolean(buffer);
+                    break;
+                case BYTE_PROPERTY_PREFIX:
+                    value = EncodingUtils.readByte(buffer);
+                    break;
+                case SHORT_PROPERTY_PREFIX:
+                    value = EncodingUtils.readShort(buffer);
+                    break;
+                case INT_PROPERTY_PREFIX:
+                    value = EncodingUtils.readInteger(buffer);
+                    break;
+                case AMQP_UNSIGNEDINT_PROPERTY_PREFIX:// This will only fit in a long
+                case LONG_PROPERTY_PREFIX:
+                    value = EncodingUtils.readLong(buffer);
+                    break;
+                case FLOAT_PROPERTY_PREFIX:
+                    value = EncodingUtils.readFloat(buffer);
+                    break;
+                case DOUBLE_PROPERTY_PREFIX:
+                    value = EncodingUtils.readDouble(buffer);
+                    break;
+
+                    // TODO: use proper charset decoder
+                case AMQP_WIDE_STRING_PROPERTY_PREFIX:
+                    //case AMQP_STRING_PROPERTY_PREFIX:
+                case STRING_PROPERTY_PREFIX:
+                    value = EncodingUtils.readLongString(buffer);
+                    break;
+                    //case AMQP_ASCII_STRING_PROPERTY_PREFIX:
+                case CHAR_PROPERTY_PREFIX:
+                    value = EncodingUtils.readShortString(buffer).charAt(0);
+                    break;
+                case BYTES_PROPERTY_PREFIX:
+                    value = EncodingUtils.readBytes(buffer);
+                    break;
+                case XML_PROPERTY_PREFIX:
+                    processXMLLine(EncodingUtils.readLongString(buffer));
+                    break;
+                default:
+                    String msg = "Field '" + key + "' - unsupported field table type: " + type + ".";
+                    //some extra debug information...
+                    msg += " (" + iType + "), length=" + length + ", sizeRead=" + sizeRead + ", sizeRemaining=" + sizeRemaining;
+                    throw new AMQFrameDecodingException(msg);
+            }
+
+            sizeRead += (sizeRemaining - buffer.remaining());
+
+            if (debug)
+            {
+                _logger.debug("FieldTable::PropFieldTable(buffer," + length + "): Read type '" + type + "', key '" + key + "', value '" + value + "' (now read " + sizeRead + " of " + length + " encoded bytes)...");
+            }
+
+            if (type != XML_PROPERTY_PREFIX)
+            {
+                setObject(key, value);
+            }
+        }
+
+        if (debug)
+        {
+            _logger.debug("FieldTable::FieldTable(buffer," + length + "): Done.");
+        }
+    }
+
+
+    /**
+     * @param name  the property name with type prefix
+     * @param value the property value
+     * @return integer
+     */
+    private static int getEncodingSize(String name, Object value)
+    {
+        int encodingSize;
+
+        char propertyPrefix = name.charAt(0);
+
+        switch (propertyPrefix)
+        {
+            case BOOLEAN_PROPERTY_PREFIX:
+                encodingSize = 1 + EncodingUtils.encodedBooleanLength();
+                break;
+            case BYTE_PROPERTY_PREFIX:
+                encodingSize = 1 + EncodingUtils.encodedByteLength();
+                break;
+            case SHORT_PROPERTY_PREFIX:
+                encodingSize = 1 + EncodingUtils.encodedShortLength();
+                break;
+            case INT_PROPERTY_PREFIX:
+                encodingSize = 1 + EncodingUtils.encodedIntegerLength();
+                break;
+            case LONG_PROPERTY_PREFIX:
+                encodingSize = 1 + EncodingUtils.encodedLongLength();
+                break;
+            case FLOAT_PROPERTY_PREFIX:
+                encodingSize = 1 + EncodingUtils.encodedFloatLength();
+                break;
+            case DOUBLE_PROPERTY_PREFIX:
+                encodingSize = 1 + EncodingUtils.encodedDoubleLength();
+                break;
+            case AMQP_WIDE_STRING_PROPERTY_PREFIX:
+                //case AMQP_STRING_PROPERTY_PREFIX:
+            case STRING_PROPERTY_PREFIX:
+                encodingSize = 1 + EncodingUtils.encodedLongStringLength((String) value);
+                break;
+                //case AMQP_ASCII_STRING_PROPERTY_PREFIX:
+            case CHAR_PROPERTY_PREFIX:
+                encodingSize = 1 + EncodingUtils.encodedShortStringLength("" + (Character) value);
+                break;
+            case BYTES_PROPERTY_PREFIX:
+                encodingSize = 1 + ((byte[]) value).length;
+                break;
+            case XML_PROPERTY_PREFIX:
+                encodingSize = 1 + EncodingUtils.encodedLongStringLength(valueAsXML(name, value));
+                break;
+            default:
+                //encodingSize = 1 + EncodingUtils.encodedLongStringLength(String.valueOf(value));
+                //  We are using XML String encoding
+                throw new IllegalArgumentException("Unsupported type in field table: " + value.getClass());
+        }
+
+// the extra byte for the type indicator is calculated in the name
+        return encodingSize;
+    }
+
+
+}

Modified: incubator/qpid/branches/new_persistence/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/new_persistence/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java?view=diff&rev=488163&r1=488162&r2=488163
==============================================================================
--- incubator/qpid/branches/new_persistence/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java (original)
+++ incubator/qpid/branches/new_persistence/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java Mon Dec 18 01:10:59 2006
@@ -25,6 +25,10 @@
 
 import java.util.Enumeration;
 
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.ByteBufferProxy;
+import org.apache.mina.common.support.BaseByteBuffer;
+
 public class PropertyFieldTableTest extends TestCase
 {
 
@@ -206,7 +210,7 @@
 
         PropertyFieldTable table2 = new PropertyFieldTable(table1XML);
 
-        Assert.assertEquals(table1XML, table2.toString());        
+        Assert.assertEquals(table1XML, table2.toString());
     }
 
     public void testKeyEnumeration()
@@ -271,6 +275,110 @@
         Assert.assertEquals(Integer.MAX_VALUE, table.getObject("object-int"));
         Assert.assertEquals(Long.MAX_VALUE, table.getObject("object-long"));
         Assert.assertEquals(Short.MAX_VALUE, table.getObject("object-short"));
+    }
+
+
+    public void testwriteBuffer()
+    {
+        byte[] bytes = {99, 98, 97, 96, 95};
+
+        PropertyFieldTable table = new PropertyFieldTable();
+        table.setBoolean("bool", true);
+        table.setByte("byte", Byte.MAX_VALUE);
+
+        table.setBytes("bytes", bytes);
+        table.setChar("char", 'c');
+        table.setDouble("double", Double.MAX_VALUE);
+        table.setFloat("float", Float.MAX_VALUE);
+        table.setInteger("int", Integer.MAX_VALUE);
+        table.setLong("long", Long.MAX_VALUE);
+        table.setShort("short", Short.MAX_VALUE);
+
+
+        final ByteBuffer buffer = ByteBuffer.allocate((int) table.getEncodedSize()); // FIXME XXX: Is cast a problem?
+
+        table.writeToBuffer(buffer);
+
+        buffer.flip();
+
+        long length = buffer.getUnsignedInt();
+
+        try
+        {
+            PropertyFieldTable table2 = new PropertyFieldTable(buffer, length);
+
+            Assert.assertEquals((Boolean) true, table2.getBoolean("bool"));
+            Assert.assertEquals((Byte) Byte.MAX_VALUE, table2.getByte("byte"));
+            assertBytesEqual(bytes, table2.getBytes("bytes"));
+            Assert.assertEquals((Character) 'c', table2.getCharacter("char"));
+            Assert.assertEquals(Double.MAX_VALUE, table2.getDouble("double"));
+            Assert.assertEquals(Float.MAX_VALUE, table2.getFloat("float"));
+            Assert.assertEquals((Integer) Integer.MAX_VALUE, table2.getInteger("int"));
+            Assert.assertEquals((Long) Long.MAX_VALUE, table2.getLong("long"));
+            Assert.assertEquals((Short) Short.MAX_VALUE, table2.getShort("short"));
+        }
+        catch (AMQFrameDecodingException e)
+        {
+            e.printStackTrace();
+            fail("PFT should be instantiated from bytes." + e.getCause());
+        }
+    }
+
+    public void testEncodingSize()
+    {
+        FieldTable result = FieldTableFactory.newFieldTable();
+        int size = 0;
+        result.put("one", 1L);
+        size = EncodingUtils.encodedShortStringLength("one");
+        size += 1 + EncodingUtils.encodedLongLength();
+        assertEquals(size, result.getEncodedSize());
+
+        result.put("two", 2L);
+        size += EncodingUtils.encodedShortStringLength("two");
+        size += 1 + EncodingUtils.encodedLongLength();
+        assertEquals(size, result.getEncodedSize());
+
+        result.put("three", 3L);
+        size += EncodingUtils.encodedShortStringLength("three");
+        size += 1 + EncodingUtils.encodedLongLength();
+        assertEquals(size, result.getEncodedSize());
+
+        result.put("four", 4L);
+        size += EncodingUtils.encodedShortStringLength("four");
+        size += 1 + EncodingUtils.encodedLongLength();
+        assertEquals(size, result.getEncodedSize());
+
+        result.put("five", 5L);
+        size += EncodingUtils.encodedShortStringLength("five");
+        size += 1 + EncodingUtils.encodedLongLength();
+        assertEquals(size, result.getEncodedSize());
+
+        //fixme should perhaps be expanded to incorporate all types.
+
+        final ByteBuffer buffer = ByteBuffer.allocate((int) result.getEncodedSize()); // FIXME XXX: Is cast a problem?
+
+        result.writeToBuffer(buffer);
+
+        buffer.flip();
+
+        long length = buffer.getUnsignedInt();
+
+        try
+        {
+            PropertyFieldTable table2 = new PropertyFieldTable(buffer, length);
+
+            Assert.assertEquals((Long) 1L, table2.getLong("one"));
+            Assert.assertEquals((Long) 2L, table2.getLong("two"));
+            Assert.assertEquals((Long) 3L, table2.getLong("three"));
+            Assert.assertEquals((Long) 4L, table2.getLong("four"));
+            Assert.assertEquals((Long) 5L, table2.getLong("five"));
+        }
+        catch (AMQFrameDecodingException e)
+        {
+            e.printStackTrace();
+            fail("PFT should be instantiated from bytes." + e.getCause());
+        }
+
     }
 
     private void assertBytesEqual(byte[] expected, byte[] actual)

Propchange: incubator/qpid/branches/new_persistence/java/management/eclipse-plugin/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon Dec 18 01:10:59 2006
@@ -0,0 +1 @@
+target

Modified: incubator/qpid/branches/new_persistence/java/pom.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/new_persistence/java/pom.xml?view=diff&rev=488163&r1=488162&r2=488163
==============================================================================
--- incubator/qpid/branches/new_persistence/java/pom.xml (original)
+++ incubator/qpid/branches/new_persistence/java/pom.xml Mon Dec 18 01:10:59 2006
@@ -105,6 +105,7 @@
         <module>client</module>
         <module>cluster</module>
         <module>systests</module>
+        <module>management/eclipse-plugin</module>
     </modules>
 
     <build>
@@ -226,13 +227,9 @@
                         <!--downloadSources>true</downloadSources-->
                         <buildcommands>
                             <java.lang.String>org.eclipse.jdt.core.javabuilder</java.lang.String>
-                            <java.lang.String>com.atlassw.tools.eclipse.checkstyle.CheckstyleBuilder</java.lang.String>
-                            <java.lang.String>net.sourceforge.pmd.runtime.pmdBuilder</java.lang.String>
                         </buildcommands>
                         <projectnatures>
                             <nature>org.eclipse.jdt.core.javanature</nature>
-                            <nature>com.atlassw.tools.eclipse.checkstyle.CheckstyleNature</nature>
-                            <nature>net.sourceforge.pmd.runtime.pmdNature</nature>
                         </projectnatures>
                     </configuration>
                 </plugin>
@@ -253,13 +250,11 @@
 
     <dependencyManagement>
         <dependencies>
-
             <dependency>
                 <groupId>commons-cli</groupId>
                 <artifactId>commons-cli</artifactId>
                 <version>1.0</version>
             </dependency>
-
             <dependency>
                 <groupId>commons-codec</groupId>
                 <artifactId>commons-codec</artifactId>
@@ -270,25 +265,28 @@
                 <artifactId>commons-collections</artifactId>
                 <version>3.1</version>
             </dependency>
-
             <dependency>
                 <groupId>commons-configuration</groupId>
                 <artifactId>commons-configuration</artifactId>
                 <version>1.2</version>
             </dependency>
-
             <dependency>
-
                 <groupId>commons-lang</groupId>
                 <artifactId>commons-lang</artifactId>
                 <version>2.1</version>
+                <exclusions>
+                    <!-- this seems to have a junit compile dependency -->
+                    <exclusion>
+                        <groupId>junit</groupId>
+                        <artifactId>junit</artifactId>
+                    </exclusion>
+                </exclusions>
             </dependency>
             <dependency>
                 <groupId>commons-logging</groupId>
                 <artifactId>commons-logging</artifactId>
                 <version>1.0.4</version>
             </dependency>
-
             <dependency>
                 <groupId>org.apache.geronimo.specs</groupId>
                 <artifactId>geronimo-jms_1.1_spec</artifactId>
@@ -304,12 +302,6 @@
                 <artifactId>saxon</artifactId>
                 <version>8.7</version>
             </dependency>
-
-            <dependency>
-                <groupId>jython</groupId>
-                <artifactId>jython</artifactId>
-                <version>2.1</version>
-            </dependency>
             <dependency>
                 <groupId>log4j</groupId>
                 <artifactId>log4j</artifactId>
@@ -343,15 +335,10 @@
             <dependency>
                 <groupId>junit</groupId>
                 <artifactId>junit</artifactId>
-                <version>3.8.2</version>
+                <version>3.8.1</version>
+                <scope>test</scope>
             </dependency>
             <dependency>
-                <groupId>ant</groupId>
-                <artifactId>ant-junit</artifactId>
-                <version>1.6.5</version>
-            </dependency>
-
-            <dependency>
                 <groupId>org.easymock</groupId>
                 <artifactId>easymockclassextension</artifactId>
                 <version>2.2</version>
@@ -412,23 +399,6 @@
                 <artifactId>maven-javadoc-plugin</artifactId>
                 <version>${javadoc.version}</version>
             </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-checkstyle-plugin</artifactId>
-                <configuration>
-                    <configLocation>${basedir}/${topDirectoryLocation}/checkstyle.xml</configLocation>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-pmd-plugin</artifactId>
-                <configuration>
-                    <targetJdk>${java.source.version}</targetJdk>
-                    <rulesets>
-                        <ruleset>${basedir}/.ruleset</ruleset>
-                    </rulesets>
-                </configuration>
-            </plugin>
         </plugins>
     </reporting>
 
@@ -468,36 +438,6 @@
         </profile>
 
         <profile>
-            <!-- default profile enables checkstyle and Xlint stuff -->
-            <id>sourcecheck</id>
-            <activation>
-                <activeByDefault>true</activeByDefault>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-checkstyle-plugin</artifactId>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-compiler-plugin</artifactId>
-                        <configuration>
-                            <source>1.5</source>
-                            <target>1.5</target>
-                            <showDeprecation>false</showDeprecation>
-                            <compilerArgument>${compile.flags}</compilerArgument>
-                        </configuration>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-pmd-plugin</artifactId>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-
-        <profile>
             <id>setup.eclipse</id>
             <build>
                 <defaultGoal>process-test-sources</defaultGoal>
@@ -522,109 +462,6 @@
                                 <configuration>
                                     <workspace>${eclipse.workspace.dir}</workspace>
                                 </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-antrun-plugin</artifactId>
-                        <version>${antrun.version}</version>
-                        <dependencies>
-                            <dependency>
-                                <groupId>ant</groupId>
-                                <artifactId>ant-nodeps</artifactId>
-                                <version>1.6.5</version>
-                            </dependency>
-                            <dependency>
-                                <groupId>ant</groupId>
-                                <artifactId>ant-trax</artifactId>
-                                <version>1.6.5</version>
-                            </dependency>
-                        </dependencies>
-                        <executions>
-                            <execution>
-                                <id>setup.workspace</id>
-                                <phase>validate</phase>
-                                <configuration>
-                                    <tasks>
-                                        <path id="ecp.ws.path" location="${eclipse.workspace.dir}"/>
-                                        <property name="full.eclipse.workspace" refid="ecp.ws.path"/>
-
-                                        <mkdir dir="${full.eclipse.workspace}/.metadata/.plugins/org.eclipse.core.runtime/.settings"/>
-                                        <mkdir dir="${full.eclipse.workspace}/.metadata/.plugins/com.atlassw.tools.eclipse.checkstyle"/>
-                                        <mkdir dir="${full.eclipse.workspace}/.metadata/.plugins/net.sourceforge.pmd.eclipse"/>
-                                        <copy file="${basedir}/${topDirectoryLocation}/checkstyle.xml"
-                                              tofile="${full.eclipse.workspace}/qpid-checkstyle.xml"/>
-                                        <copy file="${basedir}/${topDirectoryLocation}/etc/apache-header.txt"
-                                              tofile="${full.eclipse.workspace}/apache-header.txt"/>
-
-                                        <!-- Add checkstyle config -->
-                                        <copy file="${basedir}/${topDirectoryLocation}/etc/eclipse/template.checkstyle-config.xml"
-                                              tofile="${full.eclipse.workspace}/.metadata/.plugins/com.atlassw.tools.eclipse.checkstyle/checkstyle-config.xml"
-                                              overwrite="no">
-                                            <filterset>
-                                                <filter token="CHECKSTYLE_CONFIG_FILE"
-                                                        value="${full.eclipse.workspace}/qpid-checkstyle.xml"/>
-                                                <filter token="APACHE_HEADER_FILE"
-                                                        value="${full.eclipse.workspace}/apache-header.txt"/>
-                                            </filterset>
-                                        </copy>
-
-                                        <xslt style="${basedir}/${topDirectoryLocation}/etc/eclipse/addcheckstyle.xsl"
-                                              in="${full.eclipse.workspace}/.metadata/.plugins/com.atlassw.tools.eclipse.checkstyle/checkstyle-config.xml"
-                                              out="${full.eclipse.workspace}/.metadata/.plugins/com.atlassw.tools.eclipse.checkstyle/checkstyle-config.xml.new">
-                                            <param name="checkstyleconfig"
-                                                   expression="${full.eclipse.workspace}/qpid-checkstyle.xml"/>
-                                        </xslt>
-                                        <copy
-                                                file="${full.eclipse.workspace}/.metadata/.plugins/com.atlassw.tools.eclipse.checkstyle/checkstyle-config.xml.new"
-                                                tofile="${full.eclipse.workspace}/.metadata/.plugins/com.atlassw.tools.eclipse.checkstyle/checkstyle-config.xml"
-                                                overwrite="yes"/>
-
-
-                                        <!-- Add warning flags that we want -->
-                                        <propertyfile
-                                                file="${full.eclipse.workspace}/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.core.prefs">
-                                            <entry key="org.eclipse.jdt.core.compiler.problem.missingSerialVersion"
-                                                   value="ignore"/>
-                                            <entry key="org.eclipse.jdt.core.compiler.problem.unusedImport"
-                                                   value="ignore"/>
-                                            <entry key="org.eclipse.jdt.core.compiler.problem.annotationSuperInterface"
-                                                   value="ignore"/>
-                                        </propertyfile>
-
-
-                                        <!-- Add code format rules -->
-                                        <concat destfile="${full.eclipse.workspace}/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.core.prefs"
-                                                append="true" fixlastline="true">
-                                            <filelist dir="${basedir}/${topDirectoryLocation}/etc/eclipse"
-                                                      files="org.eclipse.jdt.core.prefs"/>
-                                        </concat>
-                                        <loadfile property="eclipse.code.format"
-                                                  srcFile="${basedir}/${topDirectoryLocation}/etc/eclipse/QpidCodeFormatter.xml"/>
-                                        <loadfile property="eclipse.code.templates"
-                                                  srcFile="${basedir}/${topDirectoryLocation}/etc/eclipse/codetemplates.xml"/>
-                                        <propertyfile
-                                                file="${full.eclipse.workspace}/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs">
-                                            <entry key="formatter_profile" value="_Qpid Java Conventions"/>
-                                            <entry key="org.eclipse.jdt.ui.formatterprofiles"
-                                                   value="${eclipse.code.format}"/>
-                                            <entry key="org.eclipse.jdt.ui.text.custom_code_templates"
-                                                   value="${eclipse.code.templates}"/>
-
-                                            <!-- Add import order -->
-                                            <entry key="org.eclipse.jdt.ui.importorder"
-                                                   value="java;javax;org.w3c;org.xml;junit;com;org;"/>
-                                            <!-- Sort order -->
-                                            <entry key="org.eclipse.jdt.ui.visibility.order" value="B,R,D,V,"/>
-                                            <entry key="outlinesortoption" value="T,SF,F,SI,I,C,SM,M,"/>
-                                            <entry key="org.eclipse.jdt.ui.enable.visibility.order" value="true"/>
-                                        </propertyfile>
-                                    </tasks>
-                                </configuration>
-                                <goals>
-                                    <goal>run</goal>
-                                </goals>
                             </execution>
                         </executions>
                     </plugin>

Modified: incubator/qpid/branches/new_persistence/java/systests/pom.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/new_persistence/java/systests/pom.xml?view=diff&rev=488163&r1=488162&r2=488163
==============================================================================
--- incubator/qpid/branches/new_persistence/java/systests/pom.xml (original)
+++ incubator/qpid/branches/new_persistence/java/systests/pom.xml Mon Dec 18 01:10:59 2006
@@ -58,11 +58,6 @@
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
         </dependency>
-        <dependency>
-            <groupId>ant</groupId>
-            <artifactId>ant-junit</artifactId>
-            <scope>test</scope>
-        </dependency>
     </dependencies>
 
     <build>

Modified: incubator/qpid/branches/new_persistence/java/systests/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTest.java
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/new_persistence/java/systests/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTest.java?view=diff&rev=488163&r1=488162&r2=488163
==============================================================================
--- incubator/qpid/branches/new_persistence/java/systests/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTest.java (original)
+++ incubator/qpid/branches/new_persistence/java/systests/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTest.java Mon Dec 18 01:10:59 2006
@@ -21,10 +21,13 @@
 package org.apache.qpid.server.exchange;
 
 import junit.framework.TestCase;
-import org.apache.log4j.Logger;
 import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.*;
-import org.apache.qpid.server.RequiredDeliveryException;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
+import org.apache.qpid.framing.BasicPublishBody;
+import org.apache.qpid.framing.ContentBody;
+import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.FieldTableFactory;
 import org.apache.qpid.server.queue.AMQMessage;
 import org.apache.qpid.server.queue.AMQQueue;
 import org.apache.qpid.server.queue.MessageHandleFactory;
@@ -34,6 +37,8 @@
 import org.apache.qpid.server.store.MemoryMessageStore;
 import org.apache.qpid.server.txn.NonTransactionalContext;
 import org.apache.qpid.server.txn.TransactionalContext;
+import org.apache.qpid.server.RequiredDeliveryException;
+import org.apache.log4j.Logger;
 
 import java.util.*;
 
@@ -112,7 +117,7 @@
 
     static FieldTable getHeaders(String... entries)
     {
-        FieldTable headers = new FieldTable();
+        FieldTable headers = FieldTableFactory.newFieldTable();
         for (String s : entries)
         {
             String[] parts = s.split("=", 2);