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/22 21:32:44 UTC
svn commit: r489748 [1/2] - in /incubator/qpid/trunk/qpid/java:
broker/src/main/java/org/apache/qpid/server/exchange/
broker/src/test/java/org/apache/qpid/server/exchange/
client/src/main/java/org/apache/qpid/client/
client/src/main/java/org/apache/qpi...
Author: rgreig
Date: Fri Dec 22 12:32:43 2006
New Revision: 489748
URL: http://svn.apache.org/viewvc?view=rev&rev=489748
Log:
QPID-229 : Patch supplied by Rob Godfrey - Change implementation of FieldTable
Added:
incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQType.java
incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQTypeMap.java
incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQTypedValue.java
Removed:
incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/PropertyFieldTable.java
Modified:
incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersBinding.java
incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
incubator/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java
incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java
incubator/qpid/trunk/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/StreamMessageTest.java
incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java
incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java
incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/JMSPropertyFieldTable.java
incubator/qpid/trunk/qpid/java/common/src/test/java/org/apache/qpid/framing/BasicContentHeaderPropertiesTest.java
incubator/qpid/trunk/qpid/java/common/src/test/java/org/apache/qpid/framing/JMSPropertyFieldTableTest.java
incubator/qpid/trunk/qpid/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java
incubator/qpid/trunk/qpid/java/systests/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
incubator/qpid/trunk/qpid/java/systests/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java
incubator/qpid/trunk/qpid/java/systests/src/test/java/org/apache/qpid/server/exchange/ReturnUnroutableMandatoryMessageTest.java
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersBinding.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersBinding.java?view=diff&rev=489748&r1=489747&r2=489748
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersBinding.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersBinding.java Fri Dec 22 12:32:43 2006
@@ -21,12 +21,11 @@
package org.apache.qpid.server.exchange;
import org.apache.log4j.Logger;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.AMQTypedValue;
-import java.util.Collections;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.*;
/**
* Defines binding and matching based on a set of headers.
@@ -35,11 +34,53 @@
{
private static final Logger _logger = Logger.getLogger(HeadersBinding.class);
- private final Map _mappings = new HashMap();
- private final Set<Object> required = new HashSet<Object>();
- private final Set<Map.Entry> matches = new HashSet<Map.Entry>();
+ private final FieldTable _mappings = new FieldTable();
+ private final Set<String> required = new HashSet<String>();
+ private final Map<String,Object> matches = new HashMap<String,Object>();
private boolean matchAny;
+ private final class MatchesOrProcessor implements FieldTable.FieldTableElementProcessor
+ {
+ private Boolean _result = Boolean.FALSE;
+
+ public boolean processElement(String propertyName, AMQTypedValue value)
+ {
+ if((value != null) && (value.getValue() != null) && value.getValue().equals(matches.get(propertyName)))
+ {
+ _result = Boolean.TRUE;
+ return false;
+ }
+ return true;
+ }
+
+ public Object getResult()
+ {
+ return _result;
+ }
+ }
+
+ private final class RequiredOrProcessor implements FieldTable.FieldTableElementProcessor
+ {
+ Boolean _result = Boolean.FALSE;
+
+ public boolean processElement(String propertyName, AMQTypedValue value)
+ {
+ if(required.contains(propertyName))
+ {
+ _result = Boolean.TRUE;
+ return false;
+ }
+ return true;
+ }
+
+ public Object getResult()
+ {
+ return _result;
+ }
+ }
+
+
+
/**
* Creates a binding for a set of mappings. Those mappings whose value is
* null or the empty string are assumed only to be required headers, with
@@ -47,33 +88,50 @@
* define a required match of value.
* @param mappings the defined mappings this binding should use
*/
- HeadersBinding(Map mappings)
+
+ HeadersBinding(FieldTable mappings)
{
- //noinspection unchecked
- this(mappings == null ? new HashSet<Map.Entry>() : mappings.entrySet());
- _mappings.putAll(mappings);
+ Enumeration propertyNames = mappings.getPropertyNames();
+ while(propertyNames.hasMoreElements())
+ {
+ String propName = (String) propertyNames.nextElement();
+ _mappings.put(propName, mappings.getObject(propName));
+ }
+ initMappings();
}
- private HeadersBinding(Set<Map.Entry> entries)
+ private void initMappings()
{
- for (Map.Entry e : entries)
+
+ _mappings.processOverElements(new FieldTable.FieldTableElementProcessor()
{
- if (isSpecial(e.getKey()))
- {
- processSpecial((String) e.getKey(), e.getValue());
- }
- else if (e.getValue() == null || e.getValue().equals(""))
+
+ public boolean processElement(String propertyName, AMQTypedValue value)
{
- required.add(e.getKey());
+ if (isSpecial(propertyName))
+ {
+ processSpecial(propertyName, value.getValue());
+ }
+ else if (value.getValue() == null || value.getValue().equals(""))
+ {
+ required.add(propertyName);
+ }
+ else
+ {
+ matches.put(propertyName,value.getValue());
+ }
+
+ return true;
}
- else
+
+ public Object getResult()
{
- matches.add(e);
+ return null;
}
- }
+ });
}
- protected Map getMappings()
+ protected FieldTable getMappings()
{
return _mappings;
}
@@ -84,7 +142,7 @@
* @return true if the headers define any required keys and match any required
* values
*/
- public boolean matches(Map headers)
+ public boolean matches(FieldTable headers)
{
if(headers == null)
{
@@ -96,18 +154,37 @@
}
}
- private boolean and(Map headers)
+ private boolean and(FieldTable headers)
{
- //need to match all the defined mapping rules:
- return headers.keySet().containsAll(required)
- && headers.entrySet().containsAll(matches);
+ if(headers.keys().containsAll(required))
+ {
+ for(Map.Entry<String, Object> e : matches.entrySet())
+ {
+ if(!e.getValue().equals(headers.getObject(e.getKey())))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
- private boolean or(Map headers)
+
+ private boolean or(final FieldTable headers)
{
- //only need to match one mapping rule:
- return !Collections.disjoint(headers.keySet(), required)
- || !Collections.disjoint(headers.entrySet(), matches);
+ if(required.isEmpty() || !(Boolean) headers.processOverElements(new RequiredOrProcessor()))
+ {
+ return ((!matches.isEmpty()) && (Boolean) headers.processOverElements(new MatchesOrProcessor()))
+ || (required.isEmpty() && matches.isEmpty());
+ }
+ else
+ {
+ return true;
+ }
}
private void processSpecial(String key, Object value)
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java?view=diff&rev=489748&r1=489747&r2=489748
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java Fri Dec 22 12:32:43 2006
@@ -22,10 +22,7 @@
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.BasicContentHeaderProperties;
-import org.apache.qpid.framing.ContentHeaderBody;
-import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.framing.FieldTableFactory;
+import org.apache.qpid.framing.*;
import org.apache.qpid.server.management.MBeanConstructor;
import org.apache.qpid.server.management.MBeanDescription;
import org.apache.qpid.server.queue.AMQMessage;
@@ -34,10 +31,7 @@
import javax.management.JMException;
import javax.management.openmbean.*;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
/**
@@ -119,16 +113,24 @@
String queueName = registration.queue.getName();
HeadersBinding headers = registration.binding;
- Map<Object, Object> headerMappings = headers.getMappings();
- List<String> mappingList = new ArrayList<String>();
+ FieldTable headerMappings = headers.getMappings();
+ final List<String> mappingList = new ArrayList<String>();
- for (Map.Entry<Object, Object> en : headerMappings.entrySet())
+ headerMappings.processOverElements(new FieldTable.FieldTableElementProcessor()
{
- String key = en.getKey().toString();
- String value = en.getValue().toString();
- mappingList.add(key + "=" + value);
- }
+ public boolean processElement(String propertyName, AMQTypedValue value)
+ {
+ mappingList.add(propertyName + "=" + value.getValue());
+ return true;
+ }
+
+ public Object getResult()
+ {
+ return mappingList;
+ }
+ });
+
Object[] bindingItemValues = {count++, queueName, mappingList.toArray(new String[0])};
CompositeData bindingData = new CompositeDataSupport(_bindingDataType, _bindingItemNames, bindingItemValues);
@@ -155,7 +157,7 @@
}
String[] bindings = binding.split(",");
- FieldTable fieldTable = FieldTableFactory.newFieldTable();
+ FieldTable bindingMap = new FieldTable();
for (int i = 0; i < bindings.length; i++)
{
String[] keyAndValue = bindings[i].split("=");
@@ -163,10 +165,10 @@
{
throw new JMException("Format for headers binding should be \"<attribute1>=<value1>,<attribute2>=<value2>\" ");
}
- fieldTable.put(keyAndValue[0], keyAndValue[1]);
+ bindingMap.setString(keyAndValue[0], keyAndValue[1]);
}
- _bindings.add(new Registration(new HeadersBinding(fieldTable), queue));
+ _bindings.add(new Registration(new HeadersBinding(bindingMap), queue));
}
} // End of MBean class
@@ -185,7 +187,7 @@
public void route(AMQMessage payload) throws AMQException
{
- Map headers = getHeaders(payload.getContentHeaderBody());
+ FieldTable headers = getHeaders(payload.getContentHeaderBody());
if (_logger.isDebugEnabled())
{
_logger.debug("Exchange " + getName() + ": routing message with headers " + headers);
@@ -248,7 +250,7 @@
return !_bindings.isEmpty();
}
- protected Map getHeaders(ContentHeaderBody contentHeaderFrame)
+ protected FieldTable getHeaders(ContentHeaderBody contentHeaderFrame)
{
//what if the content type is not 'basic'? 'file' and 'stream' content classes also define headers,
//but these are not yet implemented.
Modified: incubator/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java?view=diff&rev=489748&r1=489747&r2=489748
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java Fri Dec 22 12:32:43 2006
@@ -24,17 +24,18 @@
import java.util.HashMap;
import junit.framework.TestCase;
+import org.apache.qpid.framing.FieldTable;
/**
*/
public class HeadersBindingTest extends TestCase
{
- private Map<String, String> bindHeaders = new HashMap<String, String>();
- private Map<String, String> matchHeaders = new HashMap<String, String>();
+ private FieldTable bindHeaders = new FieldTable();
+ private FieldTable matchHeaders = new FieldTable();
public void testDefault_1()
{
- bindHeaders.put("A", "Value of A");
+ bindHeaders.setString("A", "Value of A");
matchHeaders.put("A", "Value of A");
Modified: incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java?view=diff&rev=489748&r1=489747&r2=489748
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java (original)
+++ incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java Fri Dec 22 12:32:43 2006
@@ -986,7 +986,7 @@
// ft.put("headers", rawSelector.getDataAsBytes());
if (rawSelector != null)
{
- ft.putAll(rawSelector);
+ ft.addAll(rawSelector);
}
BasicMessageConsumer consumer = new BasicMessageConsumer(_channelId, _connection, amqd, selector, noLocal,
_messageFactoryRegistry, AMQSession.this,
Modified: incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java?view=diff&rev=489748&r1=489747&r2=489748
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java (original)
+++ incubator/qpid/trunk/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java Fri Dec 22 12:32:43 2006
@@ -452,10 +452,6 @@
}
}
- public Map getUnderlyingMessagePropertiesMap()
- {
- return getJmsContentHeaderProperties().getHeaders();
- }
public void setUnderlyingMessagePropertiesMap(FieldTable messageProperties)
{
Modified: incubator/qpid/trunk/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/StreamMessageTest.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/StreamMessageTest.java?view=diff&rev=489748&r1=489747&r2=489748
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/StreamMessageTest.java (original)
+++ incubator/qpid/trunk/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/StreamMessageTest.java Fri Dec 22 12:32:43 2006
@@ -17,7 +17,6 @@
import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.framing.PropertyFieldTable;
import org.apache.qpid.url.AMQBindingURL;
import org.apache.qpid.url.BindingURL;
@@ -53,7 +52,7 @@
AMQHeadersExchange queue = new AMQHeadersExchange(new AMQBindingURL(ExchangeDefaults.HEADERS_EXCHANGE_CLASS+"://"+ExchangeDefaults.HEADERS_EXCHANGE_NAME+"/test/queue1?"+ BindingURL.OPTION_ROUTING_KEY+"='F0000=1'"));
- FieldTable ft = new PropertyFieldTable();
+ FieldTable ft = new FieldTable();
ft.setString("F1000","1");
MessageConsumer consumer = consumerSession.createConsumer(queue, AMQSession.DEFAULT_PREFETCH_LOW_MARK, AMQSession.DEFAULT_PREFETCH_HIGH_MARK, false, false, (String)null, ft);
Added: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQType.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQType.java?view=auto&rev=489748
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQType.java (added)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQType.java Fri Dec 22 12:32:43 2006
@@ -0,0 +1,688 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.framing;
+
+import org.apache.mina.common.ByteBuffer;
+
+public enum AMQType
+{
+
+
+ //AMQP FieldTable Wire Types
+
+ DECIMAL('D')
+ {
+
+ public int getEncodingSize(Object value)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+ public Object toNativeValue(Object value)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+ },
+
+ UNSIGNED_SHORT('S')
+ {
+
+ public int getEncodingSize(Object value)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+ public Object toNativeValue(Object value)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+ },
+
+ UNSIGNED_INT('I')
+ {
+
+ public int getEncodingSize(Object value)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+
+ public Object toNativeValue(Object value)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+ },
+
+ UNSIGNED_LONG('L')
+ {
+
+ public int getEncodingSize(Object value)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+
+ public Long toNativeValue(Object value)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+ },
+
+ EXTTENDED('D')
+ {
+
+ public int getEncodingSize(Object value)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+
+ public Object toNativeValue(Object value)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+ },
+
+ TIMESTAMP('T')
+ {
+
+ public int getEncodingSize(Object value)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+
+ public Object toNativeValue(Object value)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ // TODO : fixme
+ throw new UnsupportedOperationException();
+ }
+ },
+
+ BINARY('x')
+ {
+ public int getEncodingSize(Object value)
+ {
+ return 1 + (value == null ? 0 : ((byte[]) value).length);
+ }
+
+
+ public Object toNativeValue(Object value)
+ {
+ if((value instanceof byte[]) || (value == null))
+ {
+ return value;
+ }
+ else
+ {
+ throw new IllegalArgumentException("Value: " + value + " (" + value.getClass().getName() +
+ ") cannot be converted to byte[]");
+ }
+ }
+
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ EncodingUtils.writeBytes(buffer, (byte[]) value);
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.readBytes(buffer);
+ }
+
+ },
+
+ ASCII_STRING('c')
+ {
+ public int getEncodingSize(Object value)
+ {
+ return EncodingUtils.encodedLongStringLength((String) value);
+ }
+
+
+ public String toNativeValue(Object value)
+ {
+ if (value != null)
+ {
+ return value.toString();
+ }
+ else
+ {
+ throw new NullPointerException("Cannot convert: null to String.");
+ }
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ EncodingUtils.writeLongStringBytes(buffer, (String) value);
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.readLongString(buffer);
+ }
+
+ },
+
+ WIDE_STRING('C')
+ {
+ public int getEncodingSize(Object value)
+ {
+ // FIXME: use proper charset encoder
+ return EncodingUtils.encodedLongStringLength((String) value);
+ }
+
+
+ public String toNativeValue(Object value)
+ {
+ if (value != null)
+ {
+ return value.toString();
+ }
+ else
+ {
+ throw new NullPointerException("Cannot convert: null to String.");
+ }
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ EncodingUtils.writeLongStringBytes(buffer, (String) value);
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.readLongString(buffer);
+ }
+ },
+
+ NULL_STRING('n')
+ {
+
+ public int getEncodingSize(Object value)
+ {
+ return 0;
+ }
+
+
+ public String toNativeValue(Object value)
+ {
+ if (value == null)
+ {
+ return null;
+ }
+ else
+ {
+ throw new NumberFormatException("Cannot convert: " + value + "(" +
+ value.getClass().getName() + ") to null String.");
+ }
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ return null;
+ }
+ },
+
+ BOOLEAN('t')
+ {
+ public int getEncodingSize(Object value)
+ {
+ return EncodingUtils.encodedBooleanLength();
+ }
+
+
+ public Object toNativeValue(Object value)
+ {
+ if (value instanceof Boolean)
+ {
+ return (Boolean) value;
+ }
+ else if ((value instanceof String) || (value == null))
+ {
+ return Boolean.valueOf((String)value);
+ }
+ else
+ {
+ throw new NumberFormatException("Cannot convert: " + value + "(" +
+ value.getClass().getName() + ") to boolean.");
+ }
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ EncodingUtils.writeBoolean(buffer, (Boolean) value);
+ }
+
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.readBoolean(buffer);
+ }
+ },
+
+ BYTE('b')
+ {
+ public int getEncodingSize(Object value)
+ {
+ return EncodingUtils.encodedByteLength();
+ }
+
+
+ public Byte toNativeValue(Object value)
+ {
+ if (value instanceof Byte)
+ {
+ return (Byte) value;
+ }
+ else if ((value instanceof String) || (value == null))
+ {
+ return Byte.valueOf((String)value);
+ }
+ else
+ {
+ throw new NumberFormatException("Cannot convert: " + value + "(" +
+ value.getClass().getName() + ") to byte.");
+ }
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ EncodingUtils.writeByte(buffer, (Byte) value);
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.readByte(buffer);
+ }
+ },
+
+ ASCII_CHARACTER('k')
+ {
+ public int getEncodingSize(Object value)
+ {
+ return EncodingUtils.encodedCharLength();
+ }
+
+
+ public Character toNativeValue(Object value)
+ {
+ if (value instanceof Character)
+ {
+ return (Character) value;
+ }
+ else if (value == null)
+ {
+ throw new NullPointerException("Cannot convert null into char");
+ }
+ else
+ {
+ throw new NumberFormatException("Cannot convert: " + value + "(" +
+ value.getClass().getName() + ") to char.");
+ }
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ EncodingUtils.writeChar(buffer, (Character) value);
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.readChar(buffer);
+ }
+
+ },
+
+ SHORT('s')
+ {
+
+ public int getEncodingSize(Object value)
+ {
+ return EncodingUtils.encodedShortLength();
+ }
+
+
+ public Short toNativeValue(Object value)
+ {
+ if (value instanceof Short)
+ {
+ return (Short) value;
+ }
+ else if (value instanceof Byte)
+ {
+ return ((Byte) value).shortValue();
+ }
+ else if ((value instanceof String) || (value == null))
+ {
+ return Short.valueOf((String)value);
+ }
+
+ else
+ {
+ throw new NumberFormatException("Cannot convert: " + value + "(" +
+ value.getClass().getName() + ") to short.");
+ }
+
+
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ EncodingUtils.writeShort(buffer, (Short) value);
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.readShort(buffer);
+ }
+ },
+
+ INT('i')
+ {
+ public int getEncodingSize(Object value)
+ {
+ return EncodingUtils.encodedIntegerLength();
+ }
+
+ public Integer toNativeValue(Object value)
+ {
+ if (value instanceof Integer)
+ {
+ return (Integer) value;
+ }
+ else if (value instanceof Short)
+ {
+ return ((Short) value).intValue();
+ }
+ else if (value instanceof Byte)
+ {
+ return ((Byte) value).intValue();
+ }
+ else if ((value instanceof String) || (value == null))
+ {
+ return Integer.valueOf((String)value);
+ }
+ else
+ {
+ throw new NumberFormatException("Cannot convert: " + value + "(" +
+ value.getClass().getName() + ") to int.");
+ }
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ EncodingUtils.writeInteger(buffer, (Integer) value);
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.readInteger(buffer);
+ }
+ },
+
+ LONG('l')
+ {
+
+ public int getEncodingSize(Object value)
+ {
+ return EncodingUtils.encodedLongLength();
+ }
+
+ public Object toNativeValue(Object value)
+ {
+ if(value instanceof Long)
+ {
+ return (Long) value;
+ }
+ else if (value instanceof Integer)
+ {
+ return ((Integer) value).longValue();
+ }
+ else if (value instanceof Short)
+ {
+ return ((Short) value).longValue();
+ }
+ else if (value instanceof Byte)
+ {
+ return ((Byte) value).longValue();
+ }
+ else if ((value instanceof String) || (value == null))
+ {
+ return Long.valueOf((String)value);
+ }
+ else
+ {
+ throw new NumberFormatException("Cannot convert: " + value + "(" +
+ value.getClass().getName() + ") to long.");
+ }
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ EncodingUtils.writeLong(buffer, (Long) value);
+ }
+
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.readLong(buffer);
+ }
+ },
+
+ FLOAT('f')
+ {
+ public int getEncodingSize(Object value)
+ {
+ return EncodingUtils.encodedFloatLength();
+ }
+
+
+ public Float toNativeValue(Object value)
+ {
+ if (value instanceof Float)
+ {
+ return (Float) value;
+ }
+ else if ((value instanceof String) || (value == null))
+ {
+ return Float.valueOf((String)value);
+ }
+ else
+ {
+ throw new NumberFormatException("Cannot convert: " + value + "(" +
+ value.getClass().getName() + ") to float.");
+ }
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ EncodingUtils.writeFloat(buffer, (Float) value);
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.readFloat(buffer);
+ }
+ },
+
+ DOUBLE('d')
+ {
+
+ public int getEncodingSize(Object value)
+ {
+ return EncodingUtils.encodedDoubleLength();
+ }
+
+
+ public Double toNativeValue(Object value)
+ {
+ if (value instanceof Double)
+ {
+ return (Double) value;
+ }
+ else if (value instanceof Float)
+ {
+ return ((Float) value).doubleValue();
+ }
+ else if ((value instanceof String) || (value == null))
+ {
+ return Double.valueOf((String)value);
+ }
+ else
+ {
+ throw new NumberFormatException("Cannot convert: " + value + "(" +
+ value.getClass().getName() + ") to double.");
+ }
+ }
+
+ public void writeValueImpl(Object value, ByteBuffer buffer)
+ {
+ EncodingUtils.writeDouble(buffer, (Double) value);
+ }
+
+ public Object readValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.readDouble(buffer);
+ }
+ };
+
+ private final byte _identifier;
+
+ AMQType(char identifier)
+ {
+ _identifier = (byte) identifier;
+ }
+
+ public final byte identifier()
+ {
+ return _identifier;
+ }
+
+
+ public abstract int getEncodingSize(Object value);
+
+ public abstract Object toNativeValue(Object value);
+
+ public AMQTypedValue asTypedValue(Object value)
+ {
+ return new AMQTypedValue(this, toNativeValue(value));
+ }
+
+ public void writeToBuffer(Object value, ByteBuffer buffer)
+ {
+ buffer.put((byte)identifier());
+ writeValueImpl(value, buffer);
+ }
+
+ abstract void writeValueImpl(Object value, ByteBuffer buffer);
+
+ abstract Object readValueFromBuffer(ByteBuffer buffer);
+}
Added: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQTypeMap.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQTypeMap.java?view=auto&rev=489748
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQTypeMap.java (added)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQTypeMap.java Fri Dec 22 12:32:43 2006
@@ -0,0 +1,43 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.framing;
+
+import java.util.Map;
+import java.util.HashMap;
+
+public class AMQTypeMap
+{
+ public static Map<Byte, AMQType> _reverseTypeMap = new HashMap<Byte, AMQType>();
+
+ static
+ {
+ for(AMQType type : AMQType.values())
+ {
+ _reverseTypeMap.put(type.identifier(), type);
+ }
+ }
+
+ public static AMQType getType(Byte identifier)
+ {
+ return _reverseTypeMap.get(identifier);
+ }
+
+}
Added: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQTypedValue.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQTypedValue.java?view=auto&rev=489748
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQTypedValue.java (added)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQTypedValue.java Fri Dec 22 12:32:43 2006
@@ -0,0 +1,54 @@
+package org.apache.qpid.framing;
+
+import org.apache.mina.common.ByteBuffer;
+
+public class AMQTypedValue
+{
+ private final AMQType _type;
+ private final Object _value;
+
+
+ public AMQTypedValue(AMQType type, Object value)
+ {
+ if(type == null)
+ {
+ throw new NullPointerException("Cannot create a typed value with null type");
+ }
+ _type = type;
+ _value = type.toNativeValue(value);
+ }
+
+ private AMQTypedValue(AMQType type, ByteBuffer buffer)
+ {
+ _type = type;
+ _value = type.readValueFromBuffer( buffer );
+ }
+
+
+ public AMQType getType()
+ {
+ return _type;
+ }
+
+ public Object getValue()
+ {
+ return _value;
+ }
+
+
+ public void writeToBuffer(ByteBuffer buffer)
+ {
+ _type.writeToBuffer(_value,buffer);
+ }
+
+ public int getEncodingSize()
+ {
+ return _type.getEncodingSize(_value);
+ }
+
+ public static AMQTypedValue readFromBuffer(ByteBuffer buffer)
+ {
+ AMQType type = AMQTypeMap.getType(buffer.get());
+ return new AMQTypedValue(type, buffer);
+ }
+}
Modified: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java?view=diff&rev=489748&r1=489747&r2=489748
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java Fri Dec 22 12:32:43 2006
@@ -48,6 +48,19 @@
}
}
+ public static int encodedShortStringLength(AMQShortString s)
+ {
+ if (s == null)
+ {
+ return 1;
+ }
+ else
+ {
+ return (short) (1 + s.length());
+ }
+ }
+
+
public static int encodedLongStringLength(String s)
{
if (s == null)
@@ -88,12 +101,12 @@
{
if (table == null)
{
- // size is encoded as 4 octets
+ // length is encoded as 4 octets
return 4;
}
else
{
- // size of the table plus 4 octets for the size
+ // length of the table plus 4 octets for the length
return (int) table.getEncodedSize() + 4;
}
}
@@ -104,6 +117,20 @@
return 0;
}
+ public static void writeShortStringBytes(ByteBuffer buffer, AMQShortString s)
+ {
+
+ if (s != null)
+ {
+ writeBytes(buffer, s.getBytes());
+ }
+ else
+ {
+ // really writing out unsigned byte
+ buffer.put((byte) 0);
+ }
+ }
+
public static void writeShortStringBytes(ByteBuffer buffer, String s)
{
if (s != null)
@@ -312,6 +339,24 @@
return null;
}
+ public static AMQShortString readShortStringAsAMQShortString(ByteBuffer buffer)
+ {
+ short length = buffer.getUnsigned();
+ if (length == 0)
+ {
+ return null;
+ }
+ else
+ {
+ byte[] stringBytes = new byte[length];
+ buffer.get(stringBytes, 0, length);
+
+ return new AMQShortString(stringBytes);
+ }
+ }
+
+
+
public static String readShortString(ByteBuffer buffer)
{
short length = buffer.getUnsigned();
@@ -448,7 +493,7 @@
byte[] from = new byte[size];
// Is this not the same.
- //bb.get(from, 0, size);
+ //bb.get(from, 0, length);
for (int i = 0; i < size; i++)
{
from[i] = bb.get(i);
Modified: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java?view=diff&rev=489748&r1=489747&r2=489748
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java Fri Dec 22 12:32:43 2006
@@ -1,98 +1,612 @@
/*
- * 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
+ * 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
*
- * 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 org.apache.qpid.AMQPInvalidClassException;
-import java.util.Map;
-import java.util.Enumeration;
+import java.util.*;
-public interface FieldTable extends Map
+//extends FieldTable
+public class FieldTable
{
- 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);
+ private static final Logger _logger = Logger.getLogger(FieldTable.class);
- public Object setObject(String string, Object object);
+ private LinkedHashMap<String, AMQTypedValue> _properties;
- public boolean isNullStringValue(String name);
+ public FieldTable()
+ {
+ super();
+ _properties = new LinkedHashMap<String, AMQTypedValue>();
+
+ }
+
+
+
+ /**
+ * 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
+ {
+ this();
+ setFromBuffer(buffer, length);
+ }
+
+
+
+ public Boolean getBoolean(String string)
+ {
+ AMQTypedValue value = _properties.get(string);
+ if (value != null && (value.getType() == AMQType.BOOLEAN))
+ {
+ return (Boolean) value.getValue();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public Byte getByte(String string)
+ {
+ AMQTypedValue value = _properties.get(string);
+ if (value != null && (value.getType() == AMQType.BYTE))
+ {
+ return (Byte) value.getValue();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public Short getShort(String string)
+ {
+ AMQTypedValue value = _properties.get(string);
+ if (value != null && (value.getType() == AMQType.SHORT))
+ {
+ return (Short) value.getValue();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public Integer getInteger(String string)
+ {
+ AMQTypedValue value = _properties.get(string);
+ if (value != null && (value.getType() == AMQType.INT))
+ {
+ return (Integer) value.getValue();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public Long getLong(String string)
+ {
+ AMQTypedValue value = _properties.get(string);
+ if (value != null && (value.getType() == AMQType.LONG))
+ {
+ return (Long) value.getValue();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public Float getFloat(String string)
+ {
+ AMQTypedValue value = _properties.get(string);
+ if (value != null && (value.getType() == AMQType.FLOAT))
+ {
+ return (Float) value.getValue();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public Double getDouble(String string)
+ {
+ AMQTypedValue value = _properties.get(string);
+ if (value != null && (value.getType() == AMQType.DOUBLE))
+ {
+ return (Double) value.getValue();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public String getString(String string)
+ {
+ AMQTypedValue value = _properties.get(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;
+ }
+
+ }
+
+ public Character getCharacter(String string)
+ {
+ AMQTypedValue value = _properties.get(string);
+ if (value != null && (value.getType() == AMQType.ASCII_CHARACTER))
+ {
+ return (Character) value.getValue();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public byte[] getBytes(String string)
+ {
+ AMQTypedValue value = _properties.get(string);
+ if (value != null && (value.getType() == AMQType.BINARY))
+ {
+ return (byte[]) value.getValue();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public Object getObject(String string)
+ {
+ AMQTypedValue value = _properties.get(string);
+ if(value != null)
+ {
+ return value.getValue();
+ }
+ else
+ {
+ return value;
+ }
+
+ }
+
+ // ************ Setters
+
+ public Object setBoolean(String string, boolean b)
+ {
+ checkPropertyName(string);
+ return _properties.put(string, AMQType.BOOLEAN.asTypedValue(b));
+ }
+
+ public Object setByte(String string, byte b)
+ {
+ checkPropertyName(string);
+ return _properties.put(string, AMQType.BYTE.asTypedValue(b));
+ }
+
+ public Object setShort(String string, short i)
+ {
+ checkPropertyName(string);
+ return _properties.put(string, AMQType.SHORT.asTypedValue(i));
+ }
+
+ public Object setInteger(String string, int i)
+ {
+ checkPropertyName(string);
+ return _properties.put(string, AMQType.INT.asTypedValue(i));
+ }
+
+ public Object setLong(String string, long l)
+ {
+ checkPropertyName(string);
+ return _properties.put(string, AMQType.LONG.asTypedValue(l));
+ }
+
+ public Object setFloat(String string, float v)
+ {
+ checkPropertyName(string);
+ return _properties.put(string, AMQType.FLOAT.asTypedValue(v));
+ }
+
+ public Object setDouble(String string, double v)
+ {
+ checkPropertyName(string);
+ return _properties.put(string, AMQType.DOUBLE.asTypedValue(v));
+ }
+
+ public Object setString(String string, String value)
+ {
+ checkPropertyName(string);
+ if (value == null)
+ {
+ return _properties.put(string, AMQType.NULL_STRING.asTypedValue(null));
+ }
+ else
+ {
+ //FIXME: determine string encoding and set either WIDE or ASCII string
+// if ()
+ {
+ return _properties.put(string, AMQType.WIDE_STRING.asTypedValue(value));
+ }
+// else
+// {
+// return _properties.put(string, AMQType.ASCII_STRING.asTypedValue(value));
+// }
+ }
+ }
+
+ public Object setChar(String string, char c)
+ {
+ checkPropertyName(string);
+ return _properties.put(string, AMQType.ASCII_CHARACTER.asTypedValue(c));
+ }
+
+ public Object setBytes(String string, byte[] bytes)
+ {
+ checkPropertyName(string);
+ return _properties.put(string, AMQType.BINARY.asTypedValue(bytes));
+ }
+
+ public Object setBytes(String string, byte[] bytes, int start, int length)
+ {
+ checkPropertyName(string);
+ byte[] newBytes = new byte[length];
+ System.arraycopy(bytes,start,newBytes,0,length);
+ return setBytes(string, bytes);
+ }
+
+
+ public Object setObject(String string, Object object)
+ {
+ if (object instanceof Boolean)
+ {
+ return setBoolean(string, (Boolean) object);
+ }
+ else if (object instanceof Byte)
+ {
+ return setByte(string, (Byte) object);
+ }
+ else if (object instanceof Short)
+ {
+ return setShort(string, (Short) object);
+ }
+ else if (object instanceof Integer)
+ {
+ return setInteger(string, (Integer) object);
+ }
+ else if (object instanceof Long)
+ {
+ return setLong(string, (Long) object);
+ }
+ else if (object instanceof Float)
+ {
+ return setFloat(string, (Float) object);
+ }
+ else if (object instanceof Double)
+ {
+ return setDouble(string, (Double) object);
+ }
+ else if (object instanceof String)
+ {
+ return setString(string, (String) object);
+ }
+ else if (object instanceof Character)
+ {
+ return setChar(string, (Character) object);
+ }
+ else if (object instanceof byte[])
+ {
+ return setBytes(string, (byte[]) object);
+ }
+
+ throw new AMQPInvalidClassException("Only Primatives objects allowed Object is:" + object.getClass());
+ }
+
+
+ public boolean isNullStringValue(String name)
+ {
+ AMQTypedValue value = _properties.get(name);
+ return (value != null) && (value.getType() == AMQType.NULL_STRING);
+ }
+
+ // ***** Methods
+
+ public Enumeration getPropertyNames()
+ {
+ return Collections.enumeration(_properties.keySet());
+ }
+
+ public boolean propertyExists(String propertyName)
+ {
+ return itemExists(propertyName);
+ }
+
+ public boolean itemExists(String string)
+ {
+ return _properties.containsKey(string);
+ }
+
+ public String toString()
+ {
+ return _properties.toString();
+ }
+
+
+
+ private void checkPropertyName(String propertyName)
+ {
+ if (propertyName == null)
+ {
+ throw new IllegalArgumentException("Property name must not be null");
+ }
+ else if ("".equals(propertyName))
+ {
+ throw new IllegalArgumentException("Property name must not be the empty string");
+ }
+
+ checkIdentiferFormat(propertyName);
+ }
+
+
+ protected static void checkIdentiferFormat(String propertyName)
+ {
+// 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.
+
+
+ // 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) == '#'
+ || propertyName.charAt(0) == '_')) // Not official AMQP added for JMS.
+ {
+ throw new IllegalArgumentException("Identifier '" + propertyName + "' does not start with a valid AMQP start character");
+ }
+ }
+
+
+ // ************************* Byte Buffer Processing
+
+ public void writeToBuffer(ByteBuffer buffer)
+ {
+ final boolean trace = _logger.isTraceEnabled();
+
+ if (trace)
+ {
+ _logger.trace("FieldTable::writeToBuffer: Writing encoded length of " + getEncodedSize() + "...");
+ }
+
+ EncodingUtils.writeUnsignedInteger(buffer, getEncodedSize());
+
+ putDataInBuffer(buffer);
+ }
+
+ public byte[] getDataAsBytes()
+ {
+ final int encodedSize = (int) getEncodedSize();
+ final ByteBuffer buffer = ByteBuffer.allocate(encodedSize); // FIXME XXX: Is cast a problem?
+
+ putDataInBuffer(buffer);
+
+ final byte[] result = new byte[encodedSize];
+ buffer.flip();
+ buffer.get(result);
+ buffer.release();
+ return result;
+ }
+
+ public long getEncodedSize()
+ {
+ int encodedSize = 0;
+ for(Map.Entry<String,AMQTypedValue> e : _properties.entrySet())
+ {
+ encodedSize += EncodingUtils.encodedShortStringLength(e.getKey());
+ encodedSize++; // the byte for the encoding Type
+ encodedSize += e.getValue().getEncodingSize();
+
+ }
+ return encodedSize;
+ }
+
+ public void addAll(FieldTable fieldTable)
+ {
+ _properties.putAll(fieldTable._properties);
+ }
+
+
+ public static interface FieldTableElementProcessor
+ {
+ public boolean processElement(String propertyName, AMQTypedValue value);
+ public Object getResult();
+ }
+
+ public Object processOverElements(FieldTableElementProcessor processor)
+ {
+ for(Map.Entry<String,AMQTypedValue> e : _properties.entrySet())
+ {
+ boolean result = processor.processElement(e.getKey(), e.getValue());
+ if(!result)
+ {
+ break;
+ }
+ }
+ return processor.getResult();
+ }
+
+
+ public int size()
+ {
+ return _properties.size();
+ }
+
+ public boolean isEmpty()
+ {
+ return _properties.isEmpty();
+ }
+
+ public boolean containsKey(String key)
+ {
+ return _properties.containsKey(key);
+ }
+
+ public Set<String> keys()
+ {
+ return _properties.keySet();
+ }
+
+
+ public Object get(Object key)
+ {
+
+ return getObject((String)key);
+ }
+
+
+ public Object put(Object key, Object value)
+ {
+ return setObject(key.toString(), value);
+ }
+
+
+ public Object remove(String key)
+ {
+ AMQTypedValue value = _properties.remove(key);
+ return value == null ? null : value.getValue();
+ }
+
+
+
+ public void clear()
+ {
+ _properties.clear();
+ }
+
+ public Set keySet()
+ {
+ return _properties.keySet();
+ }
+
+ private void putDataInBuffer(ByteBuffer buffer)
+ {
+
+ 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())
+ {
+ final Map.Entry<String,AMQTypedValue> me = it.next();
+ try
+ {
+ if (_logger.isTraceEnabled())
+ {
+ _logger.trace("Writing Property:" + me.getKey() +
+ " Type:" + me.getValue().getType() +
+ " Value:" + me.getValue().getValue());
+ _logger.trace("Buffer Position:" + buffer.position() +
+ " Remaining:" + buffer.remaining());
+ }
+
+
+
+ //Write the actual parameter name
+ EncodingUtils.writeShortStringBytes(buffer, me.getKey());
+ me.getValue().writeToBuffer(buffer);
+ }
+ catch (Exception e)
+ {
+ if (_logger.isTraceEnabled())
+ {
+ _logger.trace("Exception thrown:" + e);
+ _logger.trace("Writing Property:" + me.getKey() +
+ " Type:" + me.getValue().getType() +
+ " Value:" + me.getValue().getValue());
+ _logger.trace("Buffer Position:" + buffer.position() +
+ " Remaining:" + buffer.remaining());
+ }
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+
+ public void setFromBuffer(ByteBuffer buffer, long length) throws AMQFrameDecodingException
+ {
+ final boolean trace = _logger.isTraceEnabled();
+
+ int sizeRead = 0;
+ while (sizeRead < length)
+ {
+ int sizeRemaining = buffer.remaining();
+ final String key = EncodingUtils.readShortString(buffer);
+ AMQTypedValue value = AMQTypedValue.readFromBuffer(buffer);
+ sizeRead += (sizeRemaining - buffer.remaining());
+
+ if (trace)
+ {
+ _logger.trace("FieldTable::PropFieldTable(buffer," + length + "): Read type '" + value.getType() + "', key '" + key + "', value '" + value.getValue() + "' (now read " + sizeRead + " of " + length + " encoded bytes)...");
+ }
+
+ _properties.put(key,value);
+ }
+
+ if (trace)
+ {
+ _logger.trace("FieldTable::FieldTable(buffer," + length + "): Done.");
+ }
+ }
}
Modified: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java?view=diff&rev=489748&r1=489747&r2=489748
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTableFactory.java Fri Dec 22 12:32:43 2006
@@ -26,16 +26,13 @@
{
public static FieldTable newFieldTable()
{
- return new PropertyFieldTable();
+ return new FieldTable();
}
public static FieldTable newFieldTable(ByteBuffer byteBuffer, long length) throws AMQFrameDecodingException
{
- return new PropertyFieldTable(byteBuffer, length);
+ return new FieldTable(byteBuffer, length);
}
- public static FieldTable newFieldTable(String text)
- {
- return new PropertyFieldTable(text);
- }
+
}
Modified: incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/JMSPropertyFieldTable.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/JMSPropertyFieldTable.java?view=diff&rev=489748&r1=489747&r2=489748
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/JMSPropertyFieldTable.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/main/java/org/apache/qpid/framing/JMSPropertyFieldTable.java Fri Dec 22 12:32:43 2006
@@ -32,29 +32,11 @@
{
private FieldTable _fieldtable;
- public JMSPropertyFieldTable()
- {
- _fieldtable = new PropertyFieldTable();
- }
-
public JMSPropertyFieldTable(FieldTable table)
{
_fieldtable = table;
}
- public JMSPropertyFieldTable(ByteBuffer buffer, long length) throws JMSException
- {
- try
- {
- _fieldtable = new PropertyFieldTable(buffer, length);
- }
- catch (AMQFrameDecodingException e)
- {
- JMSException error = new JMSException(e.getMessage());
- error.setLinkedException(e);
- throw error;
- }
- }
private void checkPropertyName(String propertyName)
{
Modified: incubator/qpid/trunk/qpid/java/common/src/test/java/org/apache/qpid/framing/BasicContentHeaderPropertiesTest.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/test/java/org/apache/qpid/framing/BasicContentHeaderPropertiesTest.java?view=diff&rev=489748&r1=489747&r2=489748
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/test/java/org/apache/qpid/framing/BasicContentHeaderPropertiesTest.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/test/java/org/apache/qpid/framing/BasicContentHeaderPropertiesTest.java Fri Dec 22 12:32:43 2006
@@ -31,7 +31,7 @@
{
BasicContentHeaderProperties _testProperties;
- PropertyFieldTable _testTable;
+ FieldTable _testTable;
String _testString = "This is a test string";
int _testint = 666;
@@ -45,11 +45,9 @@
public void setUp()
{
- HashMap _testMap = new HashMap(10);
- _testMap.put("TestString", _testString);
- _testMap.put("Testint", _testint);
- _testTable = new PropertyFieldTable();
- _testTable.putAll(_testMap);
+ _testTable = new FieldTable();
+ _testTable.setString("TestString", _testString);
+ _testTable.setInteger("Testint", _testint);
_testProperties = new BasicContentHeaderProperties();
_testProperties.setHeaders(_testTable);
}
@@ -57,7 +55,7 @@
public void testGetPropertyListSize()
{
//needs a better test but at least we're exercising the code !
- // FT size is encoded in an int
+ // FT length is encoded in an int
int expectedSize = EncodingUtils.encodedIntegerLength();
expectedSize += EncodingUtils.encodedShortStringLength("TestInt");
Modified: incubator/qpid/trunk/qpid/java/common/src/test/java/org/apache/qpid/framing/JMSPropertyFieldTableTest.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/common/src/test/java/org/apache/qpid/framing/JMSPropertyFieldTableTest.java?view=diff&rev=489748&r1=489747&r2=489748
==============================================================================
--- incubator/qpid/trunk/qpid/java/common/src/test/java/org/apache/qpid/framing/JMSPropertyFieldTableTest.java (original)
+++ incubator/qpid/trunk/qpid/java/common/src/test/java/org/apache/qpid/framing/JMSPropertyFieldTableTest.java Fri Dec 22 12:32:43 2006
@@ -51,7 +51,7 @@
*/
public void testReplacement() throws JMSException
{
- JMSPropertyFieldTable table1 = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table1 = new JMSPropertyFieldTable(new FieldTable());
//Set a boolean value
table1.setBoolean("value", true);
@@ -73,7 +73,7 @@
public void testRemoval() throws JMSException
{
- JMSPropertyFieldTable table1 = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table1 = new JMSPropertyFieldTable(new FieldTable());
//Set a boolean value
table1.setBoolean("value", true);
@@ -99,7 +99,7 @@
*/
public void testBoolean() throws JMSException
{
- JMSPropertyFieldTable table1 = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table1 = new JMSPropertyFieldTable(new FieldTable());
table1.setBoolean("value", true);
Assert.assertTrue(table1.propertyExists("value"));
@@ -184,7 +184,7 @@
//but after a remove it doesn't
Assert.assertFalse(table1.propertyExists("value"));
- // Table should now have zero size for encoding
+ // Table should now have zero length for encoding
checkEmpty(table1);
//Looking up an invalid value will return false
@@ -197,7 +197,7 @@
*/
public void testByte() throws JMSException
{
- JMSPropertyFieldTable table1 = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table1 = new JMSPropertyFieldTable(new FieldTable());
table1.setByte("value", Byte.MAX_VALUE);
Assert.assertTrue(table1.propertyExists("value"));
@@ -243,7 +243,7 @@
//but after a remove it doesn't
Assert.assertFalse(table1.propertyExists("value"));
- // Table should now have zero size for encoding
+ // Table should now have zero length for encoding
checkEmpty(table1);
//Looking up an invalid value returns null
@@ -266,7 +266,7 @@
*/
public void testShort() throws JMSException
{
- JMSPropertyFieldTable table1 = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table1 = new JMSPropertyFieldTable(new FieldTable());
table1.setShort("value", Short.MAX_VALUE);
Assert.assertTrue(table1.propertyExists("value"));
@@ -323,7 +323,7 @@
//but after a remove it doesn't
Assert.assertFalse(table1.propertyExists("value"));
- // Table should now have zero size for encoding
+ // Table should now have zero length for encoding
checkEmpty(table1);
//Looking up an invalid value returns null
@@ -345,7 +345,7 @@
*/
public void testDouble() throws JMSException
{
- JMSPropertyFieldTable table1 = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table1 = new JMSPropertyFieldTable(new FieldTable());
table1.setDouble("value", Double.MAX_VALUE);
Assert.assertTrue(table1.propertyExists("value"));
@@ -414,7 +414,7 @@
//but after a remove it doesn't
Assert.assertFalse(table1.propertyExists("value"));
- // Table should now have zero size for encoding
+ // Table should now have zero length for encoding
checkEmpty(table1);
//Looking up an invalid value returns null
@@ -437,7 +437,7 @@
*/
public void testFloat() throws JMSException
{
- JMSPropertyFieldTable table1 = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table1 = new JMSPropertyFieldTable(new FieldTable());
table1.setFloat("value", Float.MAX_VALUE);
Assert.assertTrue(table1.propertyExists("value"));
@@ -500,7 +500,7 @@
//but after a remove it doesn't
Assert.assertFalse(table1.propertyExists("value"));
- // Table should now have zero size for encoding
+ // Table should now have zero length for encoding
checkEmpty(table1);
//Looking up an invalid value returns null
@@ -522,7 +522,7 @@
*/
public void testInt() throws JMSException
{
- JMSPropertyFieldTable table1 = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table1 = new JMSPropertyFieldTable(new FieldTable());
table1.setInteger("value", Integer.MAX_VALUE);
Assert.assertTrue(table1.propertyExists("value"));
@@ -586,7 +586,7 @@
//but after a remove it doesn't
Assert.assertFalse(table1.propertyExists("value"));
- // Table should now have zero size for encoding
+ // Table should now have zero length for encoding
checkEmpty(table1);
//Looking up an invalid value returns null
@@ -608,7 +608,7 @@
*/
public void testLong() throws JMSException
{
- JMSPropertyFieldTable table1 = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table1 = new JMSPropertyFieldTable(new FieldTable());
table1.setLong("value", Long.MAX_VALUE);
Assert.assertTrue(table1.propertyExists("value"));
@@ -679,7 +679,7 @@
//but after a remove it doesn't
Assert.assertFalse(table1.propertyExists("value"));
- // Table should now have zero size for encoding
+ // Table should now have zero length for encoding
checkEmpty(table1);
//Looking up an invalid value
@@ -700,7 +700,7 @@
* Calls all methods that can be used to check the table is empty
* - getEncodedSize
* - isEmpty
- * - size
+ * - length
*
* @param table to check is empty
*/
@@ -716,7 +716,7 @@
*/
public void testString() throws JMSException
{
- JMSPropertyFieldTable table1 = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table1 = new JMSPropertyFieldTable(new FieldTable());
table1.setString("value", "Hello");
Assert.assertTrue(table1.propertyExists("value"));
@@ -799,7 +799,7 @@
public void testValues() throws JMSException
{
- JMSPropertyFieldTable table = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table = new JMSPropertyFieldTable(new FieldTable());
table.setBoolean("bool", true);
table.setDouble("double", Double.MAX_VALUE);
table.setFloat("float", Float.MAX_VALUE);
@@ -842,7 +842,7 @@
*/
public void testCheckPropertyNameasNull() throws JMSException
{
- JMSPropertyFieldTable table = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table = new JMSPropertyFieldTable(new FieldTable());
try
{
@@ -862,7 +862,7 @@
*/
public void testCheckPropertyNameasEmptyString() throws JMSException
{
- JMSPropertyFieldTable table = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table = new JMSPropertyFieldTable(new FieldTable());
try
{
@@ -882,7 +882,7 @@
*/
public void testCheckPropertyNamehasMaxLength() throws JMSException
{
- JMSPropertyFieldTable table = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table = new JMSPropertyFieldTable(new FieldTable());
StringBuffer longPropertyName = new StringBuffer(129);
@@ -910,7 +910,7 @@
*/
public void testCheckPropertyNameStartCharacterIsLetter() throws JMSException
{
- JMSPropertyFieldTable table = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table = new JMSPropertyFieldTable(new FieldTable());
//Try a name that starts with a number
try
@@ -931,7 +931,7 @@
*/
public void testCheckPropertyNameContainsInvalidCharacter() throws JMSException
{
- JMSPropertyFieldTable table = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table = new JMSPropertyFieldTable(new FieldTable());
//Try a name that starts with a number
try
@@ -953,7 +953,7 @@
*/
public void testCheckPropertyNameIsInvalid() throws JMSException
{
- JMSPropertyFieldTable table = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table = new JMSPropertyFieldTable(new FieldTable());
//Try a name that starts with a number
try
@@ -995,7 +995,7 @@
public void testSets()
{
- JMSPropertyFieldTable table = new JMSPropertyFieldTable();
+ JMSPropertyFieldTable table = new JMSPropertyFieldTable(new FieldTable());
table.put("n1", "1");
table.put("n2", "2");