You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by or...@apache.org on 2018/10/04 13:04:10 UTC
[2/2] qpid-broker-j git commit: QPID-8245: [Broker-J][AMQP 0-8..0-91]
Make FieldTable properties immutable and decode them on demand
QPID-8245: [Broker-J][AMQP 0-8..0-91] Make FieldTable properties immutable and decode them on demand
Project: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/commit/ae14be5d
Tree: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/tree/ae14be5d
Diff: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/diff/ae14be5d
Branch: refs/heads/master
Commit: ae14be5dffcf89b84c7d3eef5346d3b3d3ca75fc
Parents: bab681e
Author: Alex Rudyy <or...@apache.org>
Authored: Thu Oct 4 12:32:00 2018 +0100
Committer: Alex Rudyy <or...@apache.org>
Committed: Thu Oct 4 14:03:37 2018 +0100
----------------------------------------------------------------------
.../store/berkeleydb/FieldTableEncoding.java | 3 +-
.../berkeleydb/upgrade/UpgradeFrom4To5.java | 16 +-
.../berkeleydb/upgrade/UpgradeFrom5To6.java | 9 +-
.../store/berkeleydb/BDBMessageStoreTest.java | 4 +-
.../server/protocol/v0_8/AMQShortString.java | 2 +-
.../qpid/server/protocol/v0_8/AMQType.java | 129 +-
.../server/protocol/v0_8/AMQTypedValue.java | 6 +-
.../server/protocol/v0_8/EncodingUtils.java | 21 +-
.../qpid/server/protocol/v0_8/FieldArray.java | 10 +
.../qpid/server/protocol/v0_8/FieldTable.java | 1190 +++---------------
.../server/protocol/v0_8/FieldTableFactory.java | 16 +-
.../server/protocol/v0_8/FieldTableTest.java | 847 +++----------
.../protocol/v0_8/AMQPConnection_0_8Impl.java | 17 +-
.../server/protocol/v0_8/MessageMetaData.java | 4 +-
.../transport/BasicContentHeaderProperties.java | 36 +-
.../server/protocol/v0_8/AMQDecoderTest.java | 11 +-
.../protocol/v0_8/AMQPConnection_0_8Test.java | 2 +-
.../BasicContentHeaderPropertiesTest.java | 10 +-
.../MessageConverter_0_10_to_0_8.java | 22 +-
.../v0_8_v1_0/MessageConverter_1_0_to_v0_8.java | 3 +-
20 files changed, 641 insertions(+), 1717 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/ae14be5d/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/FieldTableEncoding.java
----------------------------------------------------------------------
diff --git a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/FieldTableEncoding.java b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/FieldTableEncoding.java
index a084e93..8dddbe8 100644
--- a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/FieldTableEncoding.java
+++ b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/FieldTableEncoding.java
@@ -26,6 +26,7 @@ import com.sleepycat.je.DatabaseException;
import org.apache.qpid.server.bytebuffer.QpidByteBuffer;
import org.apache.qpid.server.protocol.v0_8.FieldTable;
+import org.apache.qpid.server.protocol.v0_8.FieldTableFactory;
import org.apache.qpid.server.store.berkeleydb.tuple.ByteBufferBinding;
import java.nio.ByteBuffer;
@@ -49,7 +50,7 @@ public class FieldTableEncoding
ByteBuffer buf = ByteBufferBinding.getInstance().readByteBuffer(tupleInput, (int) length);
- return new FieldTable(QpidByteBuffer.wrap(buf));
+ return FieldTableFactory.createFieldTable(QpidByteBuffer.wrap(buf));
}
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/ae14be5d/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom4To5.java
----------------------------------------------------------------------
diff --git a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom4To5.java b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom4To5.java
index 8935d37..f7c9b87 100644
--- a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom4To5.java
+++ b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom4To5.java
@@ -23,8 +23,11 @@ package org.apache.qpid.server.store.berkeleydb.upgrade;
import java.nio.ByteBuffer;
import java.text.MessageFormat;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import com.sleepycat.bind.tuple.ByteBinding;
@@ -44,6 +47,7 @@ import org.apache.qpid.server.bytebuffer.QpidByteBuffer;
import org.apache.qpid.server.filter.AMQPFilterTypes;
import org.apache.qpid.server.exchange.ExchangeDefaults;
import org.apache.qpid.server.protocol.v0_8.AMQFrameDecodingException;
+import org.apache.qpid.server.protocol.v0_8.FieldTableFactory;
import org.apache.qpid.server.protocol.v0_8.transport.AMQProtocolVersionException;
import org.apache.qpid.server.protocol.v0_8.AMQShortString;
import org.apache.qpid.server.protocol.v0_8.transport.ContentHeaderBody;
@@ -130,21 +134,23 @@ public class UpgradeFrom4To5 extends AbstractStoreUpgrade
if (potentialDurableSubs.contains(queueName)
&& exchangeName.equals(AMQShortString.valueOf(ExchangeDefaults.TOPIC_EXCHANGE_NAME)))
{
- if (arguments == null)
+ Map<String, Object> argumentsMap = new HashMap<>();
+ if (arguments != null)
{
- arguments = new FieldTable();
+ argumentsMap.putAll(FieldTable.convertToMap(arguments));
}
String selectorFilterKey = AMQPFilterTypes.JMS_SELECTOR.getValue();
- if (!arguments.containsKey(selectorFilterKey))
+ if (!argumentsMap.containsKey(selectorFilterKey))
{
if (LOGGER.isDebugEnabled())
{
LOGGER.info("adding the empty string (i.e. 'no selector') value for " + queueName
+ " and exchange " + exchangeName);
}
- arguments.setObject(selectorFilterKey, "");
+ argumentsMap.put(selectorFilterKey, "");
}
+ arguments = FieldTable.convertToFieldTable(argumentsMap);
}
addBindingToDatabase(bindingTuple, targetDatabase, transaction, queueName, exchangeName, routingKey,
arguments);
@@ -320,7 +326,7 @@ public class UpgradeFrom4To5 extends AbstractStoreUpgrade
binding.objectToEntry(record, newValue);
newQueueDatabase.put(transaction, key, newValue);
- FieldTable emptyArguments = new FieldTable();
+ FieldTable emptyArguments = FieldTableFactory.createFieldTable(Collections.emptyMap());
addBindingToDatabase(bindingTuple, newBindingsDatabase, transaction, queueNameAMQ,
AMQShortString.valueOf(ExchangeDefaults.DIRECT_EXCHANGE_NAME), queueNameAMQ, emptyArguments);
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/ae14be5d/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom5To6.java
----------------------------------------------------------------------
diff --git a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom5To6.java b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom5To6.java
index cde1bec..1d3a77c 100644
--- a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom5To6.java
+++ b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom5To6.java
@@ -60,6 +60,7 @@ import org.apache.qpid.server.model.Exchange;
import org.apache.qpid.server.model.LifetimePolicy;
import org.apache.qpid.server.model.Queue;
import org.apache.qpid.server.model.UUIDGenerator;
+import org.apache.qpid.server.protocol.v0_8.FieldTableFactory;
import org.apache.qpid.server.queue.QueueArgumentsConverter;
import org.apache.qpid.server.store.StoreException;
import org.apache.qpid.server.store.berkeleydb.AMQShortStringEncoding;
@@ -536,10 +537,10 @@ public class UpgradeFrom5To6 extends AbstractStoreUpgrade
attributesMap.put(Queue.NAME, queueName);
attributesMap.put(Queue.EXCLUSIVE, exclusive);
- FieldTable argumentsCopy = new FieldTable();
+ HashMap<String, Object> argumentsCopy = new HashMap<>();
if (arguments != null)
{
- argumentsCopy.addAll(arguments);
+ argumentsCopy.putAll(FieldTable.convertToMap(arguments));
}
if (moveNonExclusiveOwnerToDescription(owner, exclusive))
@@ -547,7 +548,7 @@ public class UpgradeFrom5To6 extends AbstractStoreUpgrade
LOGGER.info("Non-exclusive owner " + owner + " for queue " + queueName + " moved to " + QueueArgumentsConverter.X_QPID_DESCRIPTION);
attributesMap.put(Queue.OWNER, null);
- argumentsCopy.setObject(QueueArgumentsConverter.X_QPID_DESCRIPTION, owner);
+ argumentsCopy.put(QueueArgumentsConverter.X_QPID_DESCRIPTION, owner);
}
else
{
@@ -555,7 +556,7 @@ public class UpgradeFrom5To6 extends AbstractStoreUpgrade
}
if (!argumentsCopy.isEmpty())
{
- attributesMap.put(ARGUMENTS, FieldTable.convertToMap(argumentsCopy));
+ attributesMap.put(ARGUMENTS, argumentsCopy);
}
return attributesMap;
}
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/ae14be5d/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreTest.java
----------------------------------------------------------------------
diff --git a/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreTest.java b/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreTest.java
index 2226600..b45f6c2 100644
--- a/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreTest.java
+++ b/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreTest.java
@@ -30,12 +30,14 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.File;
+import java.util.Collections;
import org.junit.Test;
import org.apache.qpid.server.bytebuffer.QpidByteBuffer;
import org.apache.qpid.server.model.VirtualHost;
import org.apache.qpid.server.protocol.v0_8.AMQShortString;
+import org.apache.qpid.server.protocol.v0_8.FieldTableFactory;
import org.apache.qpid.server.protocol.v0_8.MessageMetaData;
import org.apache.qpid.server.protocol.v0_8.transport.BasicContentHeaderProperties;
import org.apache.qpid.server.protocol.v0_8.transport.ContentHeaderBody;
@@ -96,7 +98,7 @@ public class BDBMessageStoreTest extends MessageStoreTestCase
BasicContentHeaderProperties props = new BasicContentHeaderProperties();
props.setDeliveryMode(Integer.valueOf(BasicContentHeaderProperties.PERSISTENT).byteValue());
props.setContentType("text/html");
- props.getHeaders().setString("Test", "MST");
+ props.setHeaders(FieldTableFactory.createFieldTable(Collections.singletonMap("Test", "MST")));
return props;
}
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/ae14be5d/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQShortString.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQShortString.java b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQShortString.java
index 13af160..0f9db43 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQShortString.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQShortString.java
@@ -74,7 +74,7 @@ public final class AMQShortString implements Comparable<AMQShortString>
_data = data;
}
- private static byte[] readAMQShortStringAsBytes(QpidByteBuffer buffer)
+ static byte[] readAMQShortStringAsBytes(QpidByteBuffer buffer)
{
int length = buffer.getUnsignedByte();
if(length == 0)
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/ae14be5d/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQType.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQType.java b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQType.java
index 29543b5..171f4d8 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQType.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQType.java
@@ -22,6 +22,7 @@ package org.apache.qpid.server.protocol.v0_8;
import java.math.BigDecimal;
import java.util.Collection;
+import java.util.Date;
import org.apache.qpid.server.bytebuffer.QpidByteBuffer;
@@ -64,6 +65,12 @@ public enum AMQType
{
return EncodingUtils.readLongString(buffer);
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ EncodingUtils.skipLongString(buffer);
+ }
},
INTEGER('i')
@@ -115,6 +122,12 @@ public enum AMQType
{
return buffer.getUnsignedInt();
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ buffer.position(buffer.position() + Integer.BYTES);
+ }
},
DECIMAL('D')
@@ -165,6 +178,12 @@ public enum AMQType
return bd.setScale(places);
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ buffer.position(buffer.position() + Integer.BYTES + Byte.BYTES);
+ }
},
TIMESTAMP('T')
@@ -180,7 +199,11 @@ public enum AMQType
{
if (value instanceof Long)
{
- return (Long) value;
+ return value;
+ }
+ else if (value instanceof Date)
+ {
+ return ((Date) value).getTime();
}
else
{
@@ -200,6 +223,12 @@ public enum AMQType
{
return buffer.getLong();
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ buffer.position(buffer.position() + Long.BYTES);
+ }
},
/**
@@ -285,6 +314,12 @@ public enum AMQType
throw new IllegalArgumentException("Unable to read field table from buffer.", e);
}
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ EncodingUtils.skipFieldTable(buffer);
+ }
},
/**
* Implements the field table type. The native value of a field table type will be an instance of
@@ -346,6 +381,12 @@ public enum AMQType
return FieldArray.readFromBuffer(buffer);
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ FieldArray.skipFieldArray(buffer);
+ }
},
VOID('V')
{
@@ -378,6 +419,12 @@ public enum AMQType
{
return null;
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ // no-op
+ }
},
BINARY('x')
@@ -413,6 +460,12 @@ public enum AMQType
{
return EncodingUtils.readLongstr(buffer);
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ EncodingUtils.skipLongString(buffer);
+ }
},
ASCII_STRING('c')
@@ -447,6 +500,12 @@ public enum AMQType
{
return EncodingUtils.readLongString(buffer);
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ EncodingUtils.skipLongString(buffer);
+ }
},
WIDE_STRING('C')
@@ -482,6 +541,12 @@ public enum AMQType
{
return EncodingUtils.readLongString(buffer);
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ EncodingUtils.skipLongString(buffer);
+ }
},
BOOLEAN('t')
@@ -521,6 +586,12 @@ public enum AMQType
{
return buffer.get() == 1;
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ buffer.position(buffer.position() + Byte.BYTES);
+ }
},
ASCII_CHARACTER('k')
@@ -561,6 +632,12 @@ public enum AMQType
{
return (char) buffer.get();
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ buffer.position(buffer.position() + Byte.BYTES);
+ }
},
BYTE('b')
@@ -600,6 +677,12 @@ public enum AMQType
{
return buffer.get();
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ buffer.position(buffer.position() + Byte.BYTES);
+ }
},
UNSIGNED_BYTE('B')
@@ -647,6 +730,12 @@ public enum AMQType
{
return buffer.getUnsignedByte();
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ buffer.position(buffer.position() + Byte.BYTES);
+ }
},
SHORT('s')
@@ -690,6 +779,12 @@ public enum AMQType
{
return buffer.getShort();
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ buffer.position(buffer.position() + Short.BYTES);
+ }
},
UNSIGNED_SHORT('u')
@@ -737,6 +832,12 @@ public enum AMQType
{
return buffer.getUnsignedShort();
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ buffer.position(buffer.position() + Short.BYTES);
+ }
},
INT('I')
@@ -782,6 +883,12 @@ public enum AMQType
{
return buffer.getInt();
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ buffer.position(buffer.position() + Integer.BYTES);
+ }
},
LONG('l')
@@ -833,6 +940,12 @@ public enum AMQType
{
return buffer.getLong();
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ buffer.position(buffer.position() + Long.BYTES);
+ }
},
FLOAT('f')
@@ -872,6 +985,12 @@ public enum AMQType
{
return buffer.getFloat();
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ buffer.position(buffer.position() + Float.BYTES);
+ }
},
DOUBLE('d')
@@ -915,6 +1034,12 @@ public enum AMQType
{
return buffer.getDouble();
}
+
+ @Override
+ void skip(final QpidByteBuffer buffer)
+ {
+ buffer.position(buffer.position() + Double.BYTES);
+ }
};
/** Holds the defined one byte identifier for the type. */
@@ -987,4 +1112,6 @@ public enum AMQType
* @return An instance of the type.
*/
abstract Object readValueFromBuffer(QpidByteBuffer buffer);
+
+ abstract void skip(QpidByteBuffer buffer);
}
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/ae14be5d/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQTypedValue.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQTypedValue.java b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQTypedValue.java
index 89fdc8d..6836c3e 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQTypedValue.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQTypedValue.java
@@ -282,6 +282,10 @@ public abstract class AMQTypedValue
{
return AMQType.ASCII_CHARACTER.asTypedValue(val);
}
+ else if (klass == Short.class)
+ {
+ return AMQType.SHORT.asTypedValue(val);
+ }
else if(klass == Integer.class)
{
return AMQType.INT.asTypedValue(val);
@@ -322,7 +326,7 @@ public abstract class AMQTypedValue
{
return AMQType.FIELD_TABLE.asTypedValue(FieldTable.convertToFieldTable((Map<String,Object>)val));
}
- else if(klass == FieldTable.class)
+ else if(val instanceof FieldTable)
{
return AMQType.FIELD_TABLE.asTypedValue(val);
}
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/ae14be5d/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/EncodingUtils.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/EncodingUtils.java b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/EncodingUtils.java
index 653d12c..5039552 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/EncodingUtils.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/EncodingUtils.java
@@ -213,7 +213,16 @@ public class EncodingUtils
}
else
{
- return new FieldTable(input, (int) length);
+ return FieldTableFactory.createFieldTable(input, (int) length);
+ }
+ }
+
+ public static void skipFieldTable(QpidByteBuffer buffer)
+ {
+ long length = buffer.getUnsignedInt();
+ if (length > 0)
+ {
+ buffer.position(buffer.position() + (int)length);
}
}
@@ -234,6 +243,16 @@ public class EncodingUtils
}
}
+
+ public static void skipLongString(final QpidByteBuffer buffer)
+ {
+ long length = buffer.getUnsignedInt();
+ if (length > 0)
+ {
+ buffer.position(buffer.position() + (int)length);
+ }
+ }
+
public static byte[] readLongstr(QpidByteBuffer buffer)
{
long length = ((long)(buffer.getInt())) & 0xFFFFFFFFL;
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/ae14be5d/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldArray.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldArray.java b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldArray.java
index 9e5222b..8b55a5c 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldArray.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldArray.java
@@ -127,4 +127,14 @@ public class FieldArray<T> extends AbstractCollection<T>
}
return new FieldArray<>(result);
}
+
+ public static void skipFieldArray(final QpidByteBuffer buffer)
+ {
+ int size = buffer.getInt();
+ if (size > 0)
+ {
+ buffer.position(buffer.position() + size);
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/ae14be5d/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldTable.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldTable.java b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldTable.java
index 561a24e..1f5e8cb 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldTable.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldTable.java
@@ -21,18 +21,17 @@
package org.apache.qpid.server.protocol.v0_8;
import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
-import java.util.Enumeration;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
-import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -44,820 +43,205 @@ public class FieldTable
private static final Logger LOGGER = LoggerFactory.getLogger(FieldTable.class);
private static final String STRICT_AMQP_NAME = "STRICT_AMQP";
private static final boolean STRICT_AMQP = Boolean.valueOf(System.getProperty(STRICT_AMQP_NAME, "false"));
+ private static final AMQTypedValue NOT_PRESENT = AMQType.VOID.asTypedValue(null);
- private QpidByteBuffer _encodedForm;
- private Map<String, AMQTypedValue> _properties = null;
- private long _encodedSize;
- private static final int INITIAL_HASHMAP_CAPACITY = 16;
- private final boolean _strictAMQP;
-
- public FieldTable()
- {
- this(STRICT_AMQP);
- }
-
-
- public FieldTable(boolean strictAMQP)
- {
- super();
- _strictAMQP = strictAMQP;
- }
-
- public FieldTable(FieldTable other)
- {
- _encodedForm = other._encodedForm;
- _encodedSize = other._encodedSize;
- _strictAMQP = other._strictAMQP;
- if(other._properties != null)
- {
- _properties = new LinkedHashMap<>(other._properties);
- }
- }
-
- public FieldTable(QpidByteBuffer input, int len)
- {
- this();
- _encodedForm = input.view(0,len);
- input.position(input.position()+len);
- _encodedSize = len;
- }
-
- public FieldTable(QpidByteBuffer buffer)
- {
- this();
- _encodedForm = buffer.duplicate();
- _encodedSize = buffer.remaining();
- }
-
- public synchronized boolean isClean()
- {
- return _encodedForm != null;
- }
-
- @Deprecated
- public AMQTypedValue getProperty(AMQShortString string)
- {
- return getProperty(AMQShortString.toString(string));
- }
-
- private AMQTypedValue getProperty(String string)
- {
- checkPropertyName(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()
- {
- if (_encodedSize > 0)
- {
- _properties = new LinkedHashMap<>(INITIAL_HASHMAP_CAPACITY);
-
- _encodedForm.mark();
- try
- {
- do
- {
- final String key = AMQShortString.readAMQShortStringAsString(_encodedForm);
- AMQTypedValue value = AMQTypedValue.readFromBuffer(_encodedForm);
- _properties.put(key, value);
- }
- while (_encodedForm.hasRemaining());
- }
- finally
- {
- _encodedForm.reset();
- }
- }
- }
-
- private AMQTypedValue setProperty(String key, AMQTypedValue val)
- {
- checkPropertyName(key);
-
- synchronized (this)
- {
- initMapIfNecessary();
- if (_properties.containsKey(key))
- {
- _encodedForm = null;
-
- if (val == null)
- {
- return removeKey(key);
- }
- }
- else if ((_encodedForm != null) && (val != null))
- {
- // We have updated data to store in the buffer
- // So clear the _encodedForm to allow it to be rebuilt later
- // this is safer than simply appending to any existing buffer.
- _encodedForm = null;
- }
- else if (val == null)
- {
- return null;
- }
- }
-
- 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) || (_encodedSize == 0))
- {
- _properties = new LinkedHashMap<>();
- }
- else
- {
- populateFromBuffer();
- }
- }
-
- }
- }
-
- @Deprecated
- public Boolean getBoolean(AMQShortString string)
- {
- return getBoolean(AMQShortString.toString(string));
- }
-
- public Boolean getBoolean(String string)
- {
- AMQTypedValue value = getProperty(string);
- if ((value != null) && (value.getType() == AMQType.BOOLEAN))
- {
- return (Boolean) value.getValue();
- }
- else
- {
- return null;
- }
- }
-
- @Deprecated
- public Byte getByte(AMQShortString string)
- {
- return getByte(AMQShortString.toString(string));
- }
-
- public Byte getByte(String string)
- {
- AMQTypedValue value = getProperty(string);
- if ((value != null) && (value.getType() == AMQType.BYTE))
- {
- return (Byte) value.getValue();
- }
- else
- {
- return null;
- }
- }
+ public static final FieldTable EMPTY = FieldTable.convertToFieldTable(Collections.emptyMap());
- @Deprecated
- public Short getShort(AMQShortString string)
- {
- return getShort(AMQShortString.toString(string));
- }
-
- public Short getShort(String string)
- {
- AMQTypedValue value = getProperty(string);
- if ((value != null) && (value.getType() == AMQType.SHORT))
- {
- return (Short) value.getValue();
- }
- else
- {
- return null;
- }
- }
-
- @Deprecated
- public Integer getInteger(AMQShortString string)
- {
- return getInteger(AMQShortString.toString(string));
- }
-
- public Integer getInteger(String string)
- {
- AMQTypedValue value = getProperty(string);
- if ((value != null) && (value.getType() == AMQType.INT))
- {
- return (Integer) value.getValue();
- }
- else
- {
- return null;
- }
- }
-
- @Deprecated
- public Long getLong(AMQShortString string)
- {
- return getLong(AMQShortString.toString(string));
- }
-
- public Long getLong(String string)
- {
- AMQTypedValue value = getProperty(string);
- if ((value != null) && (value.getType() == AMQType.LONG))
- {
- return (Long) value.getValue();
- }
- else
- {
- return null;
- }
- }
-
- @Deprecated
- public Float getFloat(AMQShortString string)
- {
- return getFloat(AMQShortString.toString(string));
- }
-
- public Float getFloat(String string)
- {
- AMQTypedValue value = getProperty(string);
- if ((value != null) && (value.getType() == AMQType.FLOAT))
- {
- return (Float) value.getValue();
- }
- else
- {
- return null;
- }
- }
-
- @Deprecated
- public Double getDouble(AMQShortString string)
- {
- return getDouble(AMQShortString.toString(string));
- }
-
- public Double getDouble(String string)
- {
- AMQTypedValue value = getProperty(string);
- if ((value != null) && (value.getType() == AMQType.DOUBLE))
- {
- return (Double) value.getValue();
- }
- else
- {
- return null;
- }
- }
-
- @Deprecated
- public String getString(AMQShortString string)
- {
- return getString(AMQShortString.toString(string));
- }
-
- public String getString(String string)
- {
- AMQTypedValue value = getProperty(string);
- if ((value != null) && ((value.getType() == AMQType.WIDE_STRING) || (value.getType() == AMQType.ASCII_STRING)))
- {
- return (String) value.getValue();
- }
- else if ((value != null) && (value.getValue() != null) && !(value.getValue() instanceof byte[]))
- {
- return String.valueOf(value.getValue());
- }
- else
- {
- return null;
- }
-
- }
-
- @Deprecated
- public Character getCharacter(AMQShortString string)
- {
- return getCharacter(AMQShortString.toString(string));
- }
-
- public Character getCharacter(String string)
- {
- AMQTypedValue value = getProperty(string);
- if ((value != null) && (value.getType() == AMQType.ASCII_CHARACTER))
- {
- return (Character) value.getValue();
- }
- else
- {
- return null;
- }
- }
-
- @Deprecated
- public byte[] getBytes(AMQShortString string)
- {
- return getBytes(AMQShortString.toString(string));
- }
-
- public byte[] getBytes(String string)
- {
- AMQTypedValue value = getProperty(string);
- if ((value != null) && (value.getType() == AMQType.BINARY))
- {
- return (byte[]) value.getValue();
- }
- else
- {
- return null;
- }
- }
-
- /**
- * Extracts a value from the field table that is itself a FieldTable associated with the specified parameter name.
- *
- * @param string The name of the parameter to get the associated FieldTable value for.
- *
- * @return The associated FieldTable value, or <tt>null</tt> if the associated value is not of FieldTable type or
- * not present in the field table at all.
- */
- @Deprecated
- public FieldTable getFieldTable(AMQShortString string)
- {
- return getFieldTable(AMQShortString.toString(string));
- }
-
- /**
- * Extracts a value from the field table that is itself a FieldTable associated with the specified parameter name.
- *
- * @param string The name of the parameter to get the associated FieldTable value for.
- *
- * @return The associated FieldTable value, or <tt>null</tt> if the associated value is not of FieldTable type or
- * not present in the field table at all.
- */
- public FieldTable getFieldTable(String string)
- {
- AMQTypedValue value = getProperty(string);
-
- if ((value != null) && (value.getType() == AMQType.FIELD_TABLE))
- {
- return (FieldTable) value.getValue();
- }
- else
- {
- return null;
- }
- }
-
- @Deprecated
- public Object getObject(AMQShortString string)
- {
- return getObject(AMQShortString.toString(string));
- }
-
- public Object getObject(String string)
- {
- AMQTypedValue value = getProperty(string);
- if (value != null)
- {
- return value.getValue();
- }
- else
- {
- return null;
- }
-
- }
-
- @Deprecated
- public Long getTimestamp(AMQShortString name)
- {
- return getTimestamp(AMQShortString.toString(name));
- }
-
- public Long getTimestamp(String name)
- {
- AMQTypedValue value = getProperty(name);
- if ((value != null) && (value.getType() == AMQType.TIMESTAMP))
- {
- return (Long) value.getValue();
- }
- else
- {
- return null;
- }
- }
-
- @Deprecated
- public BigDecimal getDecimal(AMQShortString propertyName)
- {
- return getDecimal(AMQShortString.toString(propertyName));
- }
-
- public BigDecimal getDecimal(String propertyName)
- {
- AMQTypedValue value = getProperty(propertyName);
- if ((value != null) && (value.getType() == AMQType.DECIMAL))
- {
- return (BigDecimal) value.getValue();
- }
- else
- {
- return null;
- }
- }
-
- // ************ Setters
-
- @Deprecated
- public Object setBoolean(AMQShortString string, Boolean b)
- {
- return setBoolean(AMQShortString.toString(string), b);
- }
-
- public Object setBoolean(String string, Boolean b)
- {
- return setProperty(string, AMQType.BOOLEAN.asTypedValue(b));
- }
-
- @Deprecated
- public Object setByte(AMQShortString string, Byte b)
- {
- return setByte(AMQShortString.toString(string), b);
- }
-
- public Object setByte(String string, Byte b)
- {
- return setProperty(string, AMQType.BYTE.asTypedValue(b));
- }
-
- @Deprecated
- public Object setShort(AMQShortString string, Short i)
- {
- return setShort(AMQShortString.toString(string), i);
- }
-
- public Object setShort(String string, Short i)
- {
- return setProperty(string, AMQType.SHORT.asTypedValue(i));
- }
-
- @Deprecated
- public Object setInteger(AMQShortString string, int i)
- {
- return setInteger(AMQShortString.toString(string), i);
- }
-
- public Object setInteger(String string, int i)
- {
- return setProperty(string, AMQTypedValue.createAMQTypedValue(i));
- }
-
- @Deprecated
- public Object setLong(AMQShortString string, long l)
- {
- return setLong(AMQShortString.toString(string), l);
- }
-
- public Object setLong(String string, long l)
- {
- return setProperty(string, AMQTypedValue.createAMQTypedValue(l));
- }
-
- @Deprecated
- public Object setFloat(AMQShortString string, Float v)
- {
- return setFloat(AMQShortString.toString(string), v);
- }
-
- public Object setFloat(String string, Float f)
- {
- return setProperty(string, AMQType.FLOAT.asTypedValue(f));
- }
-
- @Deprecated
- public Object setDouble(AMQShortString string, Double d)
- {
- return setDouble(AMQShortString.toString(string), d);
- }
-
- public Object setDouble(String string, Double v)
- {
- return setProperty(string, AMQType.DOUBLE.asTypedValue(v));
- }
+ private QpidByteBuffer _encodedForm;
+ private boolean _decoded;
+ private final Map<String, AMQTypedValue> _properties;
+ private final long _encodedSize;
+ private final boolean _strictAMQP;
- @Deprecated
- public Object setString(AMQShortString string, String value)
+ FieldTable(QpidByteBuffer input, int len)
{
- return setString(AMQShortString.toString(string), value);
+ _strictAMQP = STRICT_AMQP;
+ _encodedForm = input.view(0,len);
+ input.position(input.position()+len);
+ _encodedSize = len;
+ _properties = new LinkedHashMap<>();
}
- public Object setString(String string, String value)
+ FieldTable(QpidByteBuffer buffer)
{
- if (value == null)
- {
- return setProperty(string, AMQType.VOID.asTypedValue(null));
- }
- else
- {
- return setProperty(string, AMQType.LONG_STRING.asTypedValue(value));
- }
+ _strictAMQP = STRICT_AMQP;
+ _encodedForm = buffer.duplicate();
+ _encodedSize = buffer.remaining();
+ _properties = new LinkedHashMap<>();
}
- @Deprecated
- public Object setAsciiString(AMQShortString string, String value)
+ FieldTable(Map<String, Object> properties)
{
- return setAsciiString(AMQShortString.toString(string), value);
+ this(properties, STRICT_AMQP);
}
- public Object setAsciiString(String string, String value)
+ FieldTable(Map<String, Object> properties, boolean strictAMQP)
{
- if (value == null)
- {
- return setProperty(string, AMQType.VOID.asTypedValue(null));
- }
- else
+ _strictAMQP = strictAMQP;
+ long size = 0;
+ Map<String, AMQTypedValue> m = new LinkedHashMap<>();
+ if (properties != null && !properties.isEmpty())
{
- return setProperty(string, AMQType.ASCII_STRING.asTypedValue(value));
+ m = new LinkedHashMap<>();
+ for (Map.Entry<String, Object> e : properties.entrySet())
+ {
+ String key = e.getKey();
+ Object val = e.getValue();
+ checkPropertyName(key);
+ AMQTypedValue value = getAMQTypeValue(val);
+ size += EncodingUtils.encodedShortStringLength(e.getKey()) + 1 + value.getEncodingSize();
+ m.put(e.getKey(), value);
+ }
}
+ _properties = m;
+ _encodedSize = size;
+ _decoded = true;
}
- @Deprecated
- public Object setChar(AMQShortString string, char c)
- {
- return setChar(AMQShortString.toString(string), c);
- }
-
- public Object setChar(String string, char c)
- {
- return setProperty(string, AMQType.ASCII_CHARACTER.asTypedValue(c));
- }
-
- @Deprecated
- public Object setFieldArray(AMQShortString string, Collection<?> collection)
- {
- return setFieldArray(AMQShortString.toString(string), collection);
- }
-
- public Object setFieldArray(String string, Collection<?> collection)
- {
- return setProperty(string, AMQType.FIELD_ARRAY.asTypedValue(collection));
- }
-
- @Deprecated
- public Object setBytes(AMQShortString string, byte[] bytes)
- {
- return setBytes(AMQShortString.toString(string), bytes);
- }
-
- public Object setBytes(String string, byte[] bytes)
+ private synchronized AMQTypedValue getProperty(String key)
{
- return setProperty(string, AMQType.BINARY.asTypedValue(bytes));
- }
-
- @Deprecated
- public Object setBytes(AMQShortString string, byte[] bytes, int start, int length)
- {
- return setBytes(AMQShortString.toString(string), bytes, start, length);
- }
-
- public Object setBytes(String string, byte[] bytes, int start, int length)
- {
- byte[] newBytes = new byte[length];
- System.arraycopy(bytes, start, newBytes, 0, length);
-
- return setBytes(string, newBytes);
- }
-
- @Deprecated
- public Object setTimestamp(AMQShortString string, long datetime)
- {
- return setTimestamp(AMQShortString.toString(string), datetime);
- }
-
- public Object setTimestamp(String string, long datetime)
- {
- return setProperty(string, AMQType.TIMESTAMP.asTypedValue(datetime));
- }
-
- @Deprecated
- public Object setDecimal(AMQShortString string, BigDecimal decimal)
- {
- return setDecimal(AMQShortString.toString(string), decimal);
- }
-
- public Object setDecimal(String string, BigDecimal decimal)
- {
- if (decimal.longValue() > Integer.MAX_VALUE)
- {
- throw new UnsupportedOperationException("AMQP does not support decimals larger than " + Integer.MAX_VALUE);
- }
-
- if (decimal.scale() > Byte.MAX_VALUE)
+ AMQTypedValue value = _properties.get(key);
+ if (value == null && !_decoded)
{
- throw new UnsupportedOperationException("AMQP does not support decimal scales larger than " + Byte.MAX_VALUE);
+ value = findValueForKey(key);
+ _properties.put(key, value);
}
-
- return setProperty(string, AMQType.DECIMAL.asTypedValue(decimal));
- }
-
- @Deprecated
- public Object setVoid(AMQShortString string)
- {
- return setVoid(AMQShortString.toString(string));
- }
-
- public Object setVoid(String string)
- {
- return setProperty(string, AMQType.VOID.asTypedValue(null));
+ return value;
}
- /**
- * Associates a nested field table with the specified parameter name.
- *
- * @param string The name of the parameter to store in the table.
- * @param ftValue The field table value to associate with the parameter name.
- *
- * @return The stored value.
- */
- @Deprecated
- public Object setFieldTable(AMQShortString string, FieldTable ftValue)
+ private void decode()
{
- return setFieldTable(AMQShortString.toString(string), ftValue);
- }
+ if (_encodedSize > 0 && _encodedForm != null)
+ {
+ if (!_properties.isEmpty())
+ {
+ _properties.clear();
+ }
+ _encodedForm.mark();
+ try
+ {
+ do
+ {
+ final String key = AMQShortString.readAMQShortStringAsString(_encodedForm);
- /**
- * Associates a nested field table with the specified parameter name.
- *
- * @param string The name of the parameter to store in the table.
- * @param ftValue The field table value to associate with the parameter name.
- *
- * @return The stored value.
- */
- public Object setFieldTable(String string, FieldTable ftValue)
- {
- return setProperty(string, AMQType.FIELD_TABLE.asTypedValue(ftValue));
+ checkPropertyName(key);
+ AMQTypedValue value = AMQTypedValue.readFromBuffer(_encodedForm);
+ _properties.put(key, value);
+ }
+ while (_encodedForm.hasRemaining());
+ }
+ finally
+ {
+ _encodedForm.reset();
+ }
+ }
}
- @Deprecated
- public Object setObject(AMQShortString string, Object object)
+ private void decodeIfNecessary()
{
- return setObject(AMQShortString.toString(string), object);
+ if (!_decoded)
+ {
+ decode();
+ _decoded = true;
+ }
}
- public Object setObject(String string, Object object)
+ private AMQTypedValue getAMQTypeValue(final Object object) throws AMQPInvalidClassException
{
- if (object instanceof Boolean)
+ if (object == null)
{
- return setBoolean(string, (Boolean) object);
+ return AMQType.VOID.asTypedValue(null);
+ }
+ else if (object instanceof Boolean)
+ {
+ return AMQType.BOOLEAN.asTypedValue(object);
}
else if (object instanceof Byte)
{
- return setByte(string, (Byte) object);
+ return AMQType.BYTE.asTypedValue(object);
}
else if (object instanceof Short)
{
- return setShort(string, (Short) object);
+ return AMQType.SHORT.asTypedValue(object);
}
else if (object instanceof Integer)
{
- return setInteger(string, (Integer) object);
+ return AMQTypedValue.createAMQTypedValue((int) object);
}
else if (object instanceof Long)
{
- return setLong(string, (Long) object);
+ return AMQTypedValue.createAMQTypedValue((long) object);
}
else if (object instanceof Float)
{
- return setFloat(string, (Float) object);
+ return AMQType.FLOAT.asTypedValue(object);
}
else if (object instanceof Double)
{
- return setDouble(string, (Double) object);
+ return AMQType.DOUBLE.asTypedValue(object);
}
else if (object instanceof String)
{
- return setString(string, (String) object);
+ return AMQType.LONG_STRING.asTypedValue(object);
}
else if (object instanceof Character)
{
- return setChar(string, (Character) object);
+ return AMQType.ASCII_CHARACTER.asTypedValue(object);
}
else if (object instanceof FieldTable)
{
- return setFieldTable(string, (FieldTable) object);
+ return AMQType.FIELD_TABLE.asTypedValue(object);
}
else if (object instanceof Map)
{
- return setFieldTable(string, FieldTable.convertToFieldTable((Map<String,Object>) object));
+ @SuppressWarnings("unchecked")
+ Map<String, Object> map = (Map<String, Object>) object;
+ return AMQType.FIELD_TABLE.asTypedValue(FieldTable.convertToFieldTable(map));
}
else if (object instanceof Collection)
{
- return setFieldArray(string, (Collection)object);
+ return AMQType.FIELD_ARRAY.asTypedValue(object);
}
else if (object instanceof Date)
{
- return setTimestamp(string, ((Date) object).getTime());
+ return AMQType.TIMESTAMP.asTypedValue(((Date) object).getTime());
}
else if (object instanceof BigDecimal)
{
- return setDecimal(string, (BigDecimal) object);
+ final BigDecimal decimal = (BigDecimal) object;
+ if (decimal.longValue() > Integer.MAX_VALUE)
+ {
+ throw new UnsupportedOperationException(String.format("AMQP does not support decimals larger than %d",
+ Integer.MAX_VALUE));
+ }
+
+ if (decimal.scale() > Byte.MAX_VALUE)
+ {
+ throw new UnsupportedOperationException(String.format(
+ "AMQP does not support decimal scales larger than %d",
+ Byte.MAX_VALUE));
+ }
+
+ return AMQType.DECIMAL.asTypedValue(decimal);
}
else if (object instanceof byte[])
{
- return setBytes(string, (byte[]) object);
+ return AMQType.BINARY.asTypedValue(object);
}
else if (object instanceof UUID)
{
- return setString(string, object.toString());
+ return AMQType.LONG_STRING.asTypedValue(object.toString());
}
- throw new AMQPInvalidClassException(AMQPInvalidClassException.INVALID_OBJECT_MSG + (object == null ? "null" : object.getClass()));
- }
-
- public boolean isNullStringValue(String name)
- {
- AMQTypedValue value = getProperty(name);
-
- return (value != null) && (value.getType() == AMQType.VOID);
+ throw new AMQPInvalidClassException(AMQPInvalidClassException.INVALID_OBJECT_MSG + object.getClass());
}
// ***** Methods
- private Enumeration getPropertyNames()
- {
- return Collections.enumeration(keys());
- }
-
- @Deprecated
- public boolean propertyExists(AMQShortString propertyName)
- {
- return itemExists(AMQShortString.toString(propertyName));
- }
-
- public boolean propertyExists(String propertyName)
- {
- return itemExists(propertyName);
- }
-
- @Deprecated
- public boolean itemExists(AMQShortString propertyName)
- {
- return itemExists(AMQShortString.toString(propertyName));
- }
-
- private boolean itemExists(String propertyName)
- {
- checkPropertyName(propertyName);
- initMapIfNecessary();
-
- return _properties.containsKey(propertyName);
- }
-
@Override
public String toString()
{
- initMapIfNecessary();
-
- return _properties.toString();
+ return getProperties().toString();
}
private void checkPropertyName(String propertyName)
@@ -877,12 +261,6 @@ public class FieldTable
}
}
- @Deprecated
- protected static void checkIdentiferFormat(AMQShortString propertyName)
- {
- checkIdentiferFormat(AMQShortString.toString(propertyName));
- }
-
private static void checkIdentiferFormat(String propertyName)
{
// AMQP Spec: 4.2.5.5 Field Tables
@@ -903,25 +281,24 @@ public class FieldTable
// AMQ start character
if (!(Character.isLetter(propertyName.charAt(0)) || (propertyName.charAt(0) == '$')
- || (propertyName.charAt(0) == '#') || (propertyName.charAt(0) == '_'))) // Not official AMQP added for JMS.
+ || (propertyName.charAt(0) == '#') || (propertyName.charAt(0)
+ == '_'))) // Not official AMQP added for JMS.
{
throw new IllegalArgumentException("Identifier '" + propertyName
- + "' does not start with a valid AMQP start character");
+ + "' does not start with a valid AMQP start character");
}
}
// ************************* Byte Buffer Processing
- public void writeToBuffer(QpidByteBuffer buffer)
+ public synchronized void writeToBuffer(QpidByteBuffer buffer)
{
- final boolean trace = LOGGER.isDebugEnabled();
-
- if (trace)
+ if (LOGGER.isDebugEnabled())
{
LOGGER.debug("FieldTable::writeToBuffer: Writing encoded length of " + getEncodedSize() + "...");
- if (_properties != null)
+ if (_decoded)
{
- LOGGER.debug(_properties.toString());
+ LOGGER.debug(getProperties().toString());
}
}
@@ -930,10 +307,9 @@ public class FieldTable
putDataInBuffer(buffer);
}
-
public synchronized byte[] getDataAsBytes()
{
- if(_encodedForm == null)
+ if (_encodedForm == null)
{
byte[] data = new byte[(int) getEncodedSize()];
QpidByteBuffer buf = QpidByteBuffer.wrap(data);
@@ -946,7 +322,6 @@ public class FieldTable
_encodedForm.copyTo(encodedCopy);
return encodedCopy;
}
-
}
public long getEncodedSize()
@@ -954,151 +329,57 @@ public class FieldTable
return _encodedSize;
}
- private void recalculateEncodedSize()
- {
-
- int encodedSize = 0;
- if (_properties != null)
- {
- for (Map.Entry<String, AMQTypedValue> e : _properties.entrySet())
- {
- encodedSize += EncodingUtils.encodedShortStringLength(e.getKey());
- encodedSize++; // the byte for the encoding Type
- encodedSize += e.getValue().getEncodingSize();
-
- }
- }
-
- _encodedSize = encodedSize;
- }
-
- public synchronized void addAll(FieldTable fieldTable)
- {
- initMapIfNecessary();
- fieldTable.initMapIfNecessary();
- if (fieldTable._properties != null)
- {
- _encodedForm = null;
- _properties.putAll(fieldTable._properties);
- recalculateEncodedSize();
- }
- }
-
public static Map<String, Object> convertToMap(final FieldTable fieldTable)
{
final Map<String, Object> map = new HashMap<>();
- if(fieldTable != null)
- {
- fieldTable.processOverElements(
- new FieldTableElementProcessor()
- {
-
- @Override
- public boolean processElement(String propertyName, AMQTypedValue value)
- {
- Object val = value.getValue();
- if (val instanceof AMQShortString)
- {
- val = val.toString();
- }
- else if (val instanceof FieldTable)
- {
- val = FieldTable.convertToMap((FieldTable) val);
- }
- map.put(propertyName, val);
- return true;
- }
-
- @Override
- public Object getResult()
- {
- return map;
- }
- });
- }
- return map;
- }
-
- public void clearEncodedForm()
- {
- synchronized (this)
+ if (fieldTable != null)
{
- if (_properties == null)
+ Map<String, AMQTypedValue> properties = fieldTable.getProperties();
+ if (properties != null)
{
- if (_encodedForm != null)
+ for (Map.Entry<String, AMQTypedValue> e : properties.entrySet())
{
- populateFromBuffer();
+ Object val = e.getValue().getValue();
+ if (val instanceof AMQShortString)
+ {
+ val = val.toString();
+ }
+ else if (val instanceof FieldTable)
+ {
+ val = FieldTable.convertToMap((FieldTable) val);
+ }
+ map.put(e.getKey(), val);
}
}
-
- if (_encodedForm != null)
- {
- _encodedForm.dispose();
- _encodedForm = null;
- }
}
+ return map;
}
- public void dispose()
+ public synchronized void clearEncodedForm()
{
- synchronized (this)
- {
- if (_properties == null)
- {
- if (_encodedForm != null)
- {
- _properties = Collections.emptyMap();
- }
- }
+ decodeIfNecessary();
- if (_encodedForm != null)
- {
- _encodedForm.dispose();
- _encodedForm = null;
- }
+ if (_encodedForm != null)
+ {
+ _encodedForm.dispose();
+ _encodedForm = null;
}
}
- public synchronized void reallocate()
- {
- _encodedForm = QpidByteBuffer.reallocateIfNecessary(_encodedForm);
- }
-
-
- public static interface FieldTableElementProcessor
- {
- public boolean processElement(String propertyName, AMQTypedValue value);
-
- public Object getResult();
- }
-
- @Deprecated // make it private
- public Object processOverElements(FieldTableElementProcessor processor)
+ public synchronized void dispose()
{
- initMapIfNecessary();
- if (_properties != null)
+ if (_encodedForm != null)
{
- for (Map.Entry<String, AMQTypedValue> e : _properties.entrySet())
- {
- boolean result = processor.processElement(e.getKey(), e.getValue());
- if (!result)
- {
- break;
- }
- }
+ _encodedForm.dispose();
+ _encodedForm = null;
}
-
- return processor.getResult();
-
+ _properties.clear();
}
public int size()
{
- initMapIfNecessary();
-
- return _properties.size();
-
+ return getProperties().size();
}
public boolean isEmpty()
@@ -1106,112 +387,31 @@ public class FieldTable
return size() == 0;
}
- @Deprecated
- public boolean containsKey(AMQShortString key)
- {
- return containsKey(AMQShortString.toString(key));
- }
-
public boolean containsKey(String key)
{
- initMapIfNecessary();
-
- return _properties.containsKey(key);
+ return getProperties().containsKey(key);
}
public Set<String> keys()
{
- initMapIfNecessary();
- return new LinkedHashSet<>(_properties.keySet());
- }
-
- @Deprecated
- public Iterator<Map.Entry<AMQShortString, AMQTypedValue>> iterator()
- {
- initMapIfNecessary();
- return _properties.entrySet()
- .stream()
- .collect(Collectors.toMap(e-> AMQShortString.valueOf(e.getKey()), Map.Entry::getValue))
- .entrySet()
- .iterator();
+ return new LinkedHashSet<>(getProperties().keySet());
}
public Object get(String key)
{
- return getObject(key);
- }
-
- @Deprecated
- public Object put(AMQShortString key, Object value)
- {
- return setObject(AMQShortString.toString(key), value);
- }
-
- public Object remove(String key)
- {
- AMQTypedValue val = removeKey(key);
-
- return (val == null) ? null : val.getValue();
-
- }
-
- @Deprecated
- public Object remove(AMQShortString key)
- {
- return remove(AMQShortString.toString(key));
- }
-
- @Deprecated
- public AMQTypedValue removeKey(AMQShortString key)
- {
- return removeKey(AMQShortString.toString(key));
- }
-
- private AMQTypedValue removeKey(String key)
- {
- synchronized (this)
- {
- initMapIfNecessary();
- _encodedForm = null;
- }
- AMQTypedValue value = _properties.remove(key);
- if (value == null)
+ checkPropertyName(key);
+ AMQTypedValue value = getProperty(key);
+ if (value != null && value != NOT_PRESENT)
{
- return null;
+ return value.getValue();
}
else
{
- _encodedSize -= EncodingUtils.encodedShortStringLength(key);
- _encodedSize--;
- _encodedSize -= value.getEncodingSize();
-
- return value;
- }
-
- }
-
- public synchronized void clear()
- {
- initMapIfNecessary();
- if (_encodedForm != null)
- {
- _encodedForm.dispose();
- _encodedForm = null;
+ return null;
}
- _properties.clear();
- _encodedSize = 0;
- }
-
-
- @Deprecated
- public Set<AMQShortString> keySet()
- {
- initMapIfNecessary();
-
- return _properties.keySet().stream().map(k->AMQShortString.valueOf(k)).collect(Collectors.toSet());
}
- private synchronized void putDataInBuffer(QpidByteBuffer buffer)
+ private void putDataInBuffer(QpidByteBuffer buffer)
{
if (_encodedForm != null)
{
@@ -1220,26 +420,12 @@ public class FieldTable
buffer.put(encodedCopy);
}
- else if (_properties != null)
+ else if (!_properties.isEmpty())
{
- final Iterator<Map.Entry<String, 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
-
- while (it.hasNext())
+ for (final Map.Entry<String, AMQTypedValue> me : _properties.entrySet())
{
- final Map.Entry<String, AMQTypedValue> me = it.next();
- try
- {
- // Write the actual parameter name
- EncodingUtils.writeShortStringBytes(buffer, me.getKey());
- me.getValue().writeToBuffer(buffer);
- }
- catch (Exception e)
- {
- throw new RuntimeException(e);
- }
+ EncodingUtils.writeShortStringBytes(buffer, me.getKey());
+ me.getValue().writeToBuffer(buffer);
}
}
}
@@ -1248,9 +434,7 @@ public class FieldTable
@Override
public int hashCode()
{
- initMapIfNecessary();
-
- return _properties.hashCode();
+ return getProperties().hashCode();
}
@Override
@@ -1266,32 +450,52 @@ public class FieldTable
return false;
}
- initMapIfNecessary();
-
FieldTable f = (FieldTable) o;
- f.initMapIfNecessary();
-
- return _properties.equals(f._properties);
+ return getProperties().equals(f.getProperties());
}
+ private synchronized Map<String, AMQTypedValue> getProperties()
+ {
+ decodeIfNecessary();
+ return _properties;
+ }
- public static FieldTable convertToFieldTable(Map<String, Object> map)
+ private AMQTypedValue findValueForKey(String key)
{
- if (map != null)
+ byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
+ _encodedForm.mark();
+ try
{
- FieldTable table = new FieldTable();
- for(Map.Entry<String,Object> entry : map.entrySet())
+ while (_encodedForm.hasRemaining())
{
- table.setObject(entry.getKey(), entry.getValue());
+ final byte[] bytes = AMQShortString.readAMQShortStringAsBytes(_encodedForm);
+ if (Arrays.equals(keyBytes, bytes))
+ {
+ return AMQTypedValue.readFromBuffer(_encodedForm);
+ }
+ else
+ {
+ AMQType type = AMQTypeMap.getType(_encodedForm.get());
+ type.skip(_encodedForm);
+ }
}
+ }
+ finally
+ {
+ _encodedForm.reset();
+ }
+ return NOT_PRESENT;
+ }
- return table;
+ public static FieldTable convertToFieldTable(Map<String, Object> map)
+ {
+ if (map != null)
+ {
+ return new FieldTable(map);
}
else
{
return null;
}
}
-
-
}
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/ae14be5d/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldTableFactory.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldTableFactory.java b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldTableFactory.java
index fc5f97c..bc2ab8b 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldTableFactory.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldTableFactory.java
@@ -20,16 +20,28 @@
*/
package org.apache.qpid.server.protocol.v0_8;
+import java.util.Map;
+
+import org.apache.qpid.server.bytebuffer.QpidByteBuffer;
+
public class FieldTableFactory
{
private FieldTableFactory()
{
}
- public static FieldTable newFieldTable()
+ public static FieldTable createFieldTable(QpidByteBuffer fieldTableBuffer)
{
- return new FieldTable();
+ return new FieldTable(fieldTableBuffer);
}
+ public static FieldTable createFieldTable(QpidByteBuffer qpidByteBuffer, int length)
+ {
+ return new FieldTable(qpidByteBuffer, length);
+ }
+ public static FieldTable createFieldTable(final Map<String, Object> map)
+ {
+ return new FieldTable(map);
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org