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 2014/09/06 18:49:22 UTC
svn commit: r1622888 - in
/qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms:
./ impl/ impl/util/
Author: rgodfrey
Date: Sat Sep 6 16:49:22 2014
New Revision: 1622888
URL: http://svn.apache.org/r1622888
Log:
QPID-6078 : [JMS AMQP 1.0 Client] Allow Message and Delivery annotations to be read and modified through the JMS API
Added:
qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/
qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/AnnotationDecoder.java
qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/AnnotationEncoder.java
qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/JsonDecoder.java
qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/JsonEncoder.java
Modified:
qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Message.java
qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/AmqpMessageImpl.java
qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/BytesMessageImpl.java
qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MapMessageImpl.java
qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageFactory.java
qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageImpl.java
qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java
qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/StreamMessageImpl.java
qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TextMessageImpl.java
Modified: qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Message.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Message.java?rev=1622888&r1=1622887&r2=1622888&view=diff
==============================================================================
--- qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Message.java (original)
+++ qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Message.java Sat Sep 6 16:49:22 2014
@@ -21,7 +21,12 @@
package org.apache.qpid.amqp_1_0.jms;
-import org.apache.qpid.amqp_1_0.messaging.MessageAttributes;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.jms.JMSException;
+
import org.apache.qpid.amqp_1_0.type.Binary;
import org.apache.qpid.amqp_1_0.type.Symbol;
import org.apache.qpid.amqp_1_0.type.UnsignedByte;
@@ -29,11 +34,6 @@ import org.apache.qpid.amqp_1_0.type.Uns
import org.apache.qpid.amqp_1_0.type.UnsignedLong;
import org.apache.qpid.amqp_1_0.type.UnsignedShort;
-import javax.jms.JMSException;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
public interface Message extends javax.jms.Message
{
@@ -118,14 +118,6 @@ public interface Message extends javax.j
void setDeliveryFailures(UnsignedInteger failures);
- MessageAttributes getHeaderMessageAttrs();
-
- void setHeaderMessageAttrs(MessageAttributes messageAttrs);
-
- MessageAttributes getHeaderDeliveryAttrs();
-
- void setHeaderDeliveryAttrs(MessageAttributes deliveryAttrs);
-
Boolean getDurable();
void setDurable(Boolean durable);
Modified: qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/AmqpMessageImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/AmqpMessageImpl.java?rev=1622888&r1=1622887&r2=1622888&view=diff
==============================================================================
--- qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/AmqpMessageImpl.java (original)
+++ qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/AmqpMessageImpl.java Sat Sep 6 16:49:22 2014
@@ -18,30 +18,44 @@
*/
package org.apache.qpid.amqp_1_0.jms.impl;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListIterator;
+
import org.apache.qpid.amqp_1_0.jms.AmqpMessage;
import org.apache.qpid.amqp_1_0.type.Section;
import org.apache.qpid.amqp_1_0.type.messaging.ApplicationProperties;
+import org.apache.qpid.amqp_1_0.type.messaging.DeliveryAnnotations;
import org.apache.qpid.amqp_1_0.type.messaging.Footer;
import org.apache.qpid.amqp_1_0.type.messaging.Header;
import org.apache.qpid.amqp_1_0.type.messaging.MessageAnnotations;
import org.apache.qpid.amqp_1_0.type.messaging.Properties;
-import java.util.*;
-
public class AmqpMessageImpl extends MessageImpl implements AmqpMessage
{
private List<Section> _sections;
- protected AmqpMessageImpl(Header header, MessageAnnotations messageAnnotations, Properties properties, ApplicationProperties appProperties, List<Section> sections,
- Footer footer, SessionImpl session)
+ protected AmqpMessageImpl(Header header,
+ DeliveryAnnotations deliveryAnnotations,
+ MessageAnnotations messageAnnotations,
+ Properties properties,
+ ApplicationProperties appProperties,
+ List<Section> sections,
+ Footer footer,
+ SessionImpl session)
{
- super(header, messageAnnotations, properties, appProperties, footer, session);
+ super(header, deliveryAnnotations, messageAnnotations, properties, appProperties, footer, session);
_sections = sections;
}
protected AmqpMessageImpl(final SessionImpl session)
{
- super(new Header(), new MessageAnnotations(new HashMap()), new Properties(), new ApplicationProperties(new HashMap()), new Footer(Collections.EMPTY_MAP),
+ super(new Header(),
+ new DeliveryAnnotations(new HashMap()),
+ new MessageAnnotations(new HashMap()), new Properties(), new ApplicationProperties(new HashMap()), new Footer(Collections.EMPTY_MAP),
session);
_sections = new ArrayList<Section>();
}
@@ -65,6 +79,10 @@ public class AmqpMessageImpl extends Mes
{
List<Section> sections = new ArrayList<Section>();
sections.add(getHeader());
+ if(getDeliveryAnnotations() != null && getDeliveryAnnotations().getValue() != null && !getDeliveryAnnotations().getValue().isEmpty())
+ {
+ sections.add(getDeliveryAnnotations());
+ }
if(getMessageAnnotations() != null && getMessageAnnotations().getValue() != null && !getMessageAnnotations().getValue().isEmpty())
{
sections.add(getMessageAnnotations());
Modified: qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/BytesMessageImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/BytesMessageImpl.java?rev=1622888&r1=1622887&r2=1622888&view=diff
==============================================================================
--- qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/BytesMessageImpl.java (original)
+++ qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/BytesMessageImpl.java Sat Sep 6 16:49:22 2014
@@ -19,17 +19,32 @@
package org.apache.qpid.amqp_1_0.jms.impl;
-import org.apache.qpid.amqp_1_0.jms.BytesMessage;
-import org.apache.qpid.amqp_1_0.type.Binary;
-import org.apache.qpid.amqp_1_0.type.Section;
-import org.apache.qpid.amqp_1_0.type.messaging.*;
-import org.apache.qpid.amqp_1_0.type.messaging.Properties;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
import javax.jms.JMSException;
import javax.jms.MessageEOFException;
import javax.jms.MessageFormatException;
-import java.io.*;
-import java.util.*;
+
+import org.apache.qpid.amqp_1_0.jms.BytesMessage;
+import org.apache.qpid.amqp_1_0.type.Binary;
+import org.apache.qpid.amqp_1_0.type.Section;
+import org.apache.qpid.amqp_1_0.type.messaging.ApplicationProperties;
+import org.apache.qpid.amqp_1_0.type.messaging.Data;
+import org.apache.qpid.amqp_1_0.type.messaging.DeliveryAnnotations;
+import org.apache.qpid.amqp_1_0.type.messaging.Footer;
+import org.apache.qpid.amqp_1_0.type.messaging.Header;
+import org.apache.qpid.amqp_1_0.type.messaging.MessageAnnotations;
+import org.apache.qpid.amqp_1_0.type.messaging.Properties;
public class BytesMessageImpl extends MessageImpl implements BytesMessage
{
@@ -39,10 +54,16 @@ public class BytesMessageImpl extends Me
private Data _dataIn;
// message created for reading
- protected BytesMessageImpl(Header header, MessageAnnotations messageAnnotations, Properties properties, ApplicationProperties appProperties, Data data,
- Footer footer, SessionImpl session)
+ protected BytesMessageImpl(Header header,
+ DeliveryAnnotations deliveryAnnotations,
+ MessageAnnotations messageAnnotations,
+ Properties properties,
+ ApplicationProperties appProperties,
+ Data data,
+ Footer footer,
+ SessionImpl session)
{
- super(header, messageAnnotations, properties, appProperties, footer, session);
+ super(header, deliveryAnnotations, messageAnnotations, properties, appProperties, footer, session);
_dataIn = data;
final Binary dataBuffer = data.getValue();
_dataAsInput = new DataInputStream(new ByteArrayInputStream(dataBuffer.getArray(),dataBuffer.getArrayOffset(),dataBuffer.getLength()));
@@ -53,7 +74,7 @@ public class BytesMessageImpl extends Me
protected BytesMessageImpl(final SessionImpl session)
{
super(new Header(),
- new MessageAnnotations(new HashMap()),
+ new DeliveryAnnotations(new HashMap()), new MessageAnnotations(new HashMap()),
new Properties(),
new ApplicationProperties(new HashMap()),
new Footer(Collections.EMPTY_MAP),
@@ -524,6 +545,10 @@ public class BytesMessageImpl extends Me
{
List<Section> sections = new ArrayList<Section>();
sections.add(getHeader());
+ if(getDeliveryAnnotations() != null && getDeliveryAnnotations().getValue() != null && !getDeliveryAnnotations().getValue().isEmpty())
+ {
+ sections.add(getDeliveryAnnotations());
+ }
if(getMessageAnnotations() != null && getMessageAnnotations().getValue() != null && !getMessageAnnotations().getValue().isEmpty())
{
sections.add(getMessageAnnotations());
Modified: qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MapMessageImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MapMessageImpl.java?rev=1622888&r1=1622887&r2=1622888&view=diff
==============================================================================
--- qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MapMessageImpl.java (original)
+++ qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MapMessageImpl.java Sat Sep 6 16:49:22 2014
@@ -19,31 +19,49 @@
package org.apache.qpid.amqp_1_0.jms.impl;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jms.JMSException;
+import javax.jms.MessageFormatException;
+
import org.apache.qpid.amqp_1_0.jms.MapMessage;
import org.apache.qpid.amqp_1_0.type.Binary;
import org.apache.qpid.amqp_1_0.type.Section;
-import org.apache.qpid.amqp_1_0.type.messaging.*;
+import org.apache.qpid.amqp_1_0.type.messaging.AmqpValue;
+import org.apache.qpid.amqp_1_0.type.messaging.ApplicationProperties;
+import org.apache.qpid.amqp_1_0.type.messaging.DeliveryAnnotations;
+import org.apache.qpid.amqp_1_0.type.messaging.Footer;
+import org.apache.qpid.amqp_1_0.type.messaging.Header;
+import org.apache.qpid.amqp_1_0.type.messaging.MessageAnnotations;
import org.apache.qpid.amqp_1_0.type.messaging.Properties;
-import javax.jms.JMSException;
-import javax.jms.MessageFormatException;
-import java.util.*;
-
public class MapMessageImpl extends MessageImpl implements MapMessage
{
private Map _map;
- public MapMessageImpl(Header header, MessageAnnotations messageAnnotations, Properties properties, ApplicationProperties appProperties, Map map,
+ public MapMessageImpl(Header header,
+ DeliveryAnnotations deliveryAnnotations,
+ MessageAnnotations messageAnnotations,
+ Properties properties,
+ ApplicationProperties appProperties,
+ Map map,
Footer footer,
SessionImpl session)
{
- super(header, messageAnnotations, properties, appProperties, footer, session);
+ super(header, deliveryAnnotations, messageAnnotations, properties, appProperties, footer, session);
_map = map;
}
MapMessageImpl(final SessionImpl session)
{
- super(new Header(), new MessageAnnotations(new HashMap()),
+ super(new Header(), new DeliveryAnnotations(new HashMap()), new MessageAnnotations(new HashMap()),
new Properties(), new ApplicationProperties(new HashMap()), new Footer(Collections.EMPTY_MAP),
session);
_map = new HashMap();
@@ -431,6 +449,10 @@ public class MapMessageImpl extends Mess
{
List<Section> sections = new ArrayList<Section>();
sections.add(getHeader());
+ if(getDeliveryAnnotations() != null && getDeliveryAnnotations().getValue() != null && !getDeliveryAnnotations().getValue().isEmpty())
+ {
+ sections.add(getDeliveryAnnotations());
+ }
if(getMessageAnnotations() != null && getMessageAnnotations().getValue() != null && !getMessageAnnotations().getValue().isEmpty())
{
sections.add(getMessageAnnotations());
Modified: qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageFactory.java?rev=1622888&r1=1622887&r2=1622888&view=diff
==============================================================================
--- qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageFactory.java (original)
+++ qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageFactory.java Sat Sep 6 16:49:22 2014
@@ -19,18 +19,24 @@
package org.apache.qpid.amqp_1_0.jms.impl;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
import org.apache.qpid.amqp_1_0.client.Message;
import org.apache.qpid.amqp_1_0.type.Binary;
import org.apache.qpid.amqp_1_0.type.Section;
-import org.apache.qpid.amqp_1_0.type.messaging.*;
+import org.apache.qpid.amqp_1_0.type.messaging.AmqpSequence;
+import org.apache.qpid.amqp_1_0.type.messaging.AmqpValue;
+import org.apache.qpid.amqp_1_0.type.messaging.ApplicationProperties;
+import org.apache.qpid.amqp_1_0.type.messaging.Data;
+import org.apache.qpid.amqp_1_0.type.messaging.DeliveryAnnotations;
+import org.apache.qpid.amqp_1_0.type.messaging.Footer;
+import org.apache.qpid.amqp_1_0.type.messaging.Header;
+import org.apache.qpid.amqp_1_0.type.messaging.MessageAnnotations;
import org.apache.qpid.amqp_1_0.type.messaging.Properties;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-import java.util.*;
-
class MessageFactory
{
private final SessionImpl _session;
@@ -47,6 +53,7 @@ class MessageFactory
List<Section> payload = msg.getPayload();
Header header = null;
MessageAnnotations messageAnnotations = null;
+ DeliveryAnnotations deliveryAnnotations = null;
Properties properties = null;
ApplicationProperties appProperties = null;
@@ -65,6 +72,7 @@ class MessageFactory
if(section instanceof DeliveryAnnotations)
{
+ deliveryAnnotations = (DeliveryAnnotations) section;
section = iter.hasNext() ? iter.next() : null;
}
@@ -99,23 +107,28 @@ class MessageFactory
Section bodySection = body.get(0);
if(bodySection instanceof AmqpValue && ((AmqpValue)bodySection).getValue() instanceof Map)
{
- message = new MapMessageImpl(header, messageAnnotations, properties, appProperties, (Map) ((AmqpValue)bodySection).getValue(), footer, _session);
+ message = new MapMessageImpl(header, deliveryAnnotations, messageAnnotations, properties, appProperties, (Map) ((AmqpValue)bodySection).getValue(), footer, _session);
}
else if(bodySection instanceof AmqpValue && ((AmqpValue)bodySection).getValue() instanceof List)
{
- message = new StreamMessageImpl(header, messageAnnotations, properties, appProperties,
- (List) ((AmqpValue)bodySection).getValue(), footer, _session);
+ message = new StreamMessageImpl(header,
+ deliveryAnnotations,
+ messageAnnotations, properties, appProperties,
+ (List) ((AmqpValue)bodySection).getValue(), footer, _session
+ );
}
else if(bodySection instanceof AmqpValue && ((AmqpValue)bodySection).getValue() instanceof String)
{
- message = new TextMessageImpl(header, messageAnnotations, properties, appProperties,
+ message = new TextMessageImpl(header, deliveryAnnotations, messageAnnotations, properties, appProperties,
(String) ((AmqpValue)bodySection).getValue(), footer, _session);
}
else if(bodySection instanceof AmqpValue && ((AmqpValue)bodySection).getValue() instanceof Binary)
{
Binary value = (Binary) ((AmqpValue) bodySection).getValue();
- message = new BytesMessageImpl(header, messageAnnotations, properties, appProperties,
+ message = new BytesMessageImpl(header,
+ deliveryAnnotations,
+ messageAnnotations, properties, appProperties,
new Data(value), footer, _session);
}
else if(bodySection instanceof Data)
@@ -124,19 +137,26 @@ class MessageFactory
{
- message = new ObjectMessageImpl(header, messageAnnotations, properties, appProperties,
+ message = new ObjectMessageImpl(header,
+ deliveryAnnotations,
+ messageAnnotations, properties, appProperties,
(Data) bodySection,
footer,
_session);
}
else
{
- message = new BytesMessageImpl(header, messageAnnotations, properties, appProperties, (Data) bodySection, footer, _session);
+ message = new BytesMessageImpl(header,
+ deliveryAnnotations,
+ messageAnnotations, properties, appProperties, (Data) bodySection, footer, _session);
}
}
else if(bodySection instanceof AmqpSequence)
{
- message = new StreamMessageImpl(header, messageAnnotations, properties, appProperties, ((AmqpSequence) bodySection).getValue(), footer, _session);
+ message = new StreamMessageImpl(header,
+ deliveryAnnotations,
+ messageAnnotations, properties, appProperties, ((AmqpSequence) bodySection).getValue(), footer, _session
+ );
}
/*else if(bodySection instanceof AmqpDataSection)
@@ -181,12 +201,16 @@ class MessageFactory
}*/
else
{
- message = new AmqpMessageImpl(header,messageAnnotations, properties,appProperties,body,footer, _session);
+ message = new AmqpMessageImpl(header,
+ deliveryAnnotations,
+ messageAnnotations, properties,appProperties,body,footer, _session);
}
}
else
{
- message = new AmqpMessageImpl(header,messageAnnotations, properties,appProperties,body,footer, _session);
+ message = new AmqpMessageImpl(header,
+ deliveryAnnotations,
+ messageAnnotations, properties,appProperties,body,footer, _session);
}
message.setReadOnly();
Modified: qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageImpl.java?rev=1622888&r1=1622887&r2=1622888&view=diff
==============================================================================
--- qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageImpl.java (original)
+++ qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageImpl.java Sat Sep 6 16:49:22 2014
@@ -21,8 +21,30 @@
package org.apache.qpid.amqp_1_0.jms.impl;
+import java.io.IOException;
+import java.util.ArrayList;
+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.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jms.DeliveryMode;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.MessageFormatException;
+import javax.jms.MessageNotReadableException;
+import javax.jms.MessageNotWriteableException;
+
import org.apache.qpid.amqp_1_0.jms.Message;
-import org.apache.qpid.amqp_1_0.messaging.MessageAttributes;
+import org.apache.qpid.amqp_1_0.jms.impl.util.AnnotationDecoder;
+import org.apache.qpid.amqp_1_0.jms.impl.util.AnnotationEncoder;
import org.apache.qpid.amqp_1_0.type.Binary;
import org.apache.qpid.amqp_1_0.type.Section;
import org.apache.qpid.amqp_1_0.type.Symbol;
@@ -31,28 +53,24 @@ import org.apache.qpid.amqp_1_0.type.Uns
import org.apache.qpid.amqp_1_0.type.UnsignedLong;
import org.apache.qpid.amqp_1_0.type.UnsignedShort;
import org.apache.qpid.amqp_1_0.type.messaging.ApplicationProperties;
+import org.apache.qpid.amqp_1_0.type.messaging.DeliveryAnnotations;
import org.apache.qpid.amqp_1_0.type.messaging.Footer;
import org.apache.qpid.amqp_1_0.type.messaging.Header;
import org.apache.qpid.amqp_1_0.type.messaging.MessageAnnotations;
import org.apache.qpid.amqp_1_0.type.messaging.Properties;
-import javax.jms.DeliveryMode;
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.MessageFormatException;
-import javax.jms.MessageNotReadableException;
-import javax.jms.MessageNotWriteableException;
-import java.util.*;
-
public abstract class MessageImpl implements Message
{
static final Set<Class> _supportedClasses =
new HashSet<Class>(Arrays.asList(Boolean.class, Byte.class, Short.class, Integer.class, Long.class,
Float.class, Double.class, Character.class, String.class, byte[].class));
+
static final Symbol JMS_TYPE = Symbol.valueOf("x-opt-jms-type");
static final Symbol TO_TYPE = Symbol.valueOf("x-opt-to-type");
static final Symbol REPLY_TO_TYPE = Symbol.valueOf("x-opt-reply-type");
+ static final Collection<Symbol> SYSTEM_MESSAGE_ANNOTATIONS = Arrays.asList(JMS_TYPE, TO_TYPE, REPLY_TO_TYPE);
+
static final String QUEUE_ATTRIBUTE = "queue";
static final String TOPIC_ATTRIBUTE = "topic";
static final String TEMPORARY_ATTRIBUTE = "temporary";
@@ -63,6 +81,8 @@ public abstract class MessageImpl implem
static final Set<String> JMS_TEMP_TOPIC_ATTRIBUTES = set(TOPIC_ATTRIBUTE, TEMPORARY_ATTRIBUTE);
private static final String JMSXGROUP_ID = "JMSXGroupID";
+ public static final String JMS_AMQP_MESSAGE_ANNOTATIONS = "JMS_AMQP_MESSAGE_ANNOTATIONS";
+ public static final String JMS_AMQP_DELIVERY_ANNOTATIONS = "JMS_AMQP_DELIVERY_ANNOTATIONS";
private Header _header;
private Properties _properties;
@@ -70,6 +90,7 @@ public abstract class MessageImpl implem
private Footer _footer;
private final SessionImpl _sessionImpl;
private boolean _readOnly;
+ private DeliveryAnnotations _deliveryAnnotations;
private MessageAnnotations _messageAnnotations;
private boolean _isFromQueue;
@@ -78,6 +99,7 @@ public abstract class MessageImpl implem
private DestinationImpl _replyTo;
protected MessageImpl(Header header,
+ DeliveryAnnotations deliveryAnnotations,
MessageAnnotations messageAnnotations,
Properties properties,
ApplicationProperties appProperties,
@@ -87,6 +109,8 @@ public abstract class MessageImpl implem
_header = header == null ? new Header() : header;
_properties = properties == null ? new Properties() : properties;
_messageAnnotations = messageAnnotations == null ? new MessageAnnotations(new HashMap()) : messageAnnotations;
+ _deliveryAnnotations = deliveryAnnotations == null ? new DeliveryAnnotations(new HashMap()) : deliveryAnnotations;
+
_footer = footer == null ? new Footer(Collections.EMPTY_MAP) : footer;
_applicationProperties = appProperties == null ? new ApplicationProperties(new HashMap()) : appProperties;
_sessionImpl = session;
@@ -470,6 +494,49 @@ public abstract class MessageImpl implem
{
return _properties.getGroupId();
}
+ else if(JMS_AMQP_DELIVERY_ANNOTATIONS.equals(name))
+ {
+ Map annotationsMap = deliveryAnnotationsMap();
+ if(annotationsMap.isEmpty())
+ {
+ return null;
+ }
+ else
+ {
+ try
+ {
+ return new AnnotationEncoder().encode(annotationsMap);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+ }
+ }
+ else if(JMS_AMQP_MESSAGE_ANNOTATIONS.equals(name))
+ {
+ Map annotationsMap = new LinkedHashMap(messageAnnotationMap());
+ for(Symbol s : SYSTEM_MESSAGE_ANNOTATIONS)
+ {
+ annotationsMap.remove(s);
+ }
+
+ if(annotationsMap.isEmpty())
+ {
+ return null;
+ }
+ else
+ {
+ try
+ {
+ return new AnnotationEncoder().encode(annotationsMap);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+ }
+ }
return _applicationProperties.getValue().get(name);
}
@@ -740,6 +807,27 @@ public abstract class MessageImpl implem
{
names.add(JMSXGROUP_ID);
}
+ if(!deliveryAnnotationsMap().isEmpty())
+ {
+ names.add(JMS_AMQP_DELIVERY_ANNOTATIONS);
+ }
+ if(!messageAnnotationMap().isEmpty())
+ {
+ boolean nonDefaultAnnotation = false;
+ for(Object key : messageAnnotationMap().keySet())
+ {
+ if(!SYSTEM_MESSAGE_ANNOTATIONS.contains(key))
+ {
+ nonDefaultAnnotation = true;
+ break;
+ }
+ }
+
+ if(nonDefaultAnnotation)
+ {
+ names.add(JMS_AMQP_MESSAGE_ANNOTATIONS);
+ }
+ }
return Collections.enumeration(names);
}
@@ -952,6 +1040,44 @@ public abstract class MessageImpl implem
{
_properties.setGroupId(value == null ? null : value.toString());
}
+ else if(JMS_AMQP_MESSAGE_ANNOTATIONS.equals(name))
+ {
+ try
+ {
+ Map<Symbol, Object> annotationMap = new AnnotationDecoder().decode((String) value);
+ Map messageAnnotations = messageAnnotationMap();
+ Map tmp = new LinkedHashMap();
+ for(Symbol key : SYSTEM_MESSAGE_ANNOTATIONS)
+ {
+ if(messageAnnotations.containsKey(key))
+ {
+ tmp.put(key, messageAnnotations.get(key));
+ }
+ }
+ messageAnnotations.clear();
+ messageAnnotations.putAll(annotationMap);
+ messageAnnotations.putAll(tmp);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+
+ }
+ else if(JMS_AMQP_DELIVERY_ANNOTATIONS.equals(name))
+ {
+ try
+ {
+ Map<Symbol, Object> annotationMap = new AnnotationDecoder().decode((String) value);
+ Map deliveryAnnotations = deliveryAnnotationsMap();
+ deliveryAnnotations.clear();
+ deliveryAnnotations.putAll(annotationMap);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+ }
else
{
_applicationProperties.getValue().put(name, value);
@@ -998,28 +1124,6 @@ public abstract class MessageImpl implem
_header.setDeliveryCount(failures);
}
- public MessageAttributes getHeaderMessageAttrs()
- {
- // TODO
- return null ; // _header.getMessageAttrs();
- }
-
- public void setHeaderMessageAttrs(final MessageAttributes messageAttrs)
- {
- // TODO
- }
-
- public MessageAttributes getHeaderDeliveryAttrs()
- {
- // TODO
- return null ; //_header.getDeliveryAttrs();
- }
-
- public void setHeaderDeliveryAttrs(final MessageAttributes deliveryAttrs)
- {
- //TODO
- }
-
public Boolean getDurable()
{
return _header.getDurable();
@@ -1224,6 +1328,12 @@ public abstract class MessageImpl implem
return _messageAnnotations;
}
+
+ DeliveryAnnotations getDeliveryAnnotations()
+ {
+ return _deliveryAnnotations;
+ }
+
public ApplicationProperties getApplicationProperties()
{
return _applicationProperties;
@@ -1319,6 +1429,17 @@ public abstract class MessageImpl implem
return messageAttrs;
}
+ private Map deliveryAnnotationsMap()
+ {
+ Map deliveryAttrs = _deliveryAnnotations == null ? null : _deliveryAnnotations.getValue();
+ if(deliveryAttrs == null)
+ {
+ deliveryAttrs = new HashMap();
+ _deliveryAnnotations = new DeliveryAnnotations(deliveryAttrs);
+ }
+ return deliveryAttrs;
+ }
+
Set<String> splitCommaSeparateSet(String value)
{
if( value == null )
Modified: qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java?rev=1622888&r1=1622887&r2=1622888&view=diff
==============================================================================
--- qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java (original)
+++ qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java Sat Sep 6 16:49:22 2014
@@ -19,22 +19,32 @@
package org.apache.qpid.amqp_1_0.jms.impl;
-import org.apache.qpid.amqp_1_0.jms.ObjectMessage;
-import org.apache.qpid.amqp_1_0.type.Binary;
-import org.apache.qpid.amqp_1_0.type.Section;
-import org.apache.qpid.amqp_1_0.type.Symbol;
-import org.apache.qpid.amqp_1_0.type.messaging.*;
-import org.apache.qpid.amqp_1_0.type.messaging.Properties;
-
-import javax.jms.JMSException;
-import javax.jms.MessageNotWriteableException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.jms.JMSException;
+import javax.jms.MessageNotWriteableException;
+
+import org.apache.qpid.amqp_1_0.jms.ObjectMessage;
+import org.apache.qpid.amqp_1_0.type.Binary;
+import org.apache.qpid.amqp_1_0.type.Section;
+import org.apache.qpid.amqp_1_0.type.Symbol;
+import org.apache.qpid.amqp_1_0.type.messaging.ApplicationProperties;
+import org.apache.qpid.amqp_1_0.type.messaging.Data;
+import org.apache.qpid.amqp_1_0.type.messaging.DeliveryAnnotations;
+import org.apache.qpid.amqp_1_0.type.messaging.Footer;
+import org.apache.qpid.amqp_1_0.type.messaging.Header;
+import org.apache.qpid.amqp_1_0.type.messaging.MessageAnnotations;
+import org.apache.qpid.amqp_1_0.type.messaging.Properties;
public class ObjectMessageImpl extends MessageImpl implements ObjectMessage
{
@@ -61,6 +71,7 @@ public class ObjectMessageImpl extends M
private Data _objectData = NULL_OBJECT_DATA;
protected ObjectMessageImpl(Header header,
+ DeliveryAnnotations deliveryAnnotations,
MessageAnnotations messageAnnotations,
Properties properties,
ApplicationProperties appProperties,
@@ -68,7 +79,7 @@ public class ObjectMessageImpl extends M
Footer footer,
SessionImpl session)
{
- super(header, messageAnnotations, properties, appProperties, footer, session);
+ super(header, deliveryAnnotations, messageAnnotations, properties, appProperties, footer, session);
getProperties().setContentType(CONTENT_TYPE);
Serializable serializable = null;
_objectData = dataSection;
@@ -77,7 +88,7 @@ public class ObjectMessageImpl extends M
protected ObjectMessageImpl(final SessionImpl session)
{
- super(new Header(), new MessageAnnotations(new HashMap()),
+ super(new Header(), new DeliveryAnnotations(new HashMap()), new MessageAnnotations(new HashMap()),
new Properties(), new ApplicationProperties(new HashMap()), new Footer(Collections.EMPTY_MAP),
session);
getProperties().setContentType(CONTENT_TYPE);
@@ -146,6 +157,10 @@ public class ObjectMessageImpl extends M
{
List<Section> sections = new ArrayList<Section>();
sections.add(getHeader());
+ if(getDeliveryAnnotations() != null && getDeliveryAnnotations().getValue() != null && !getDeliveryAnnotations().getValue().isEmpty())
+ {
+ sections.add(getDeliveryAnnotations());
+ }
if(getMessageAnnotations() != null && getMessageAnnotations().getValue() != null && !getMessageAnnotations().getValue().isEmpty())
{
sections.add(getMessageAnnotations());
Modified: qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/StreamMessageImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/StreamMessageImpl.java?rev=1622888&r1=1622887&r2=1622888&view=diff
==============================================================================
--- qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/StreamMessageImpl.java (original)
+++ qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/StreamMessageImpl.java Sat Sep 6 16:49:22 2014
@@ -19,17 +19,26 @@
package org.apache.qpid.amqp_1_0.jms.impl;
-import org.apache.qpid.amqp_1_0.jms.StreamMessage;
-import org.apache.qpid.amqp_1_0.type.Binary;
-import org.apache.qpid.amqp_1_0.type.Section;
-import org.apache.qpid.amqp_1_0.type.messaging.*;
-import org.apache.qpid.amqp_1_0.type.messaging.Properties;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
import javax.jms.JMSException;
import javax.jms.MessageEOFException;
import javax.jms.MessageFormatException;
-import java.io.EOFException;
-import java.util.*;
+
+import org.apache.qpid.amqp_1_0.jms.StreamMessage;
+import org.apache.qpid.amqp_1_0.type.Binary;
+import org.apache.qpid.amqp_1_0.type.Section;
+import org.apache.qpid.amqp_1_0.type.messaging.AmqpValue;
+import org.apache.qpid.amqp_1_0.type.messaging.ApplicationProperties;
+import org.apache.qpid.amqp_1_0.type.messaging.DeliveryAnnotations;
+import org.apache.qpid.amqp_1_0.type.messaging.Footer;
+import org.apache.qpid.amqp_1_0.type.messaging.Header;
+import org.apache.qpid.amqp_1_0.type.messaging.MessageAnnotations;
+import org.apache.qpid.amqp_1_0.type.messaging.Properties;
public class StreamMessageImpl extends MessageImpl implements StreamMessage
{
@@ -40,31 +49,27 @@ public class StreamMessageImpl extends M
- protected StreamMessageImpl(Header header, MessageAnnotations messageAnnotations, Properties properties, ApplicationProperties appProperties, List list,
- Footer footer, SessionImpl session)
+ protected StreamMessageImpl(Header header,
+ DeliveryAnnotations deliveryAnnotations,
+ MessageAnnotations messageAnnotations,
+ Properties properties,
+ ApplicationProperties appProperties,
+ List list,
+ Footer footer,
+ SessionImpl session)
{
- super(header, messageAnnotations, properties, appProperties, footer, session);
+ super(header, deliveryAnnotations, messageAnnotations, properties, appProperties, footer, session);
_list = list;
}
StreamMessageImpl(final SessionImpl session)
{
- super(new Header(), new MessageAnnotations(new HashMap()), new Properties(),
+ super(new Header(), new DeliveryAnnotations(new HashMap()), new MessageAnnotations(new HashMap()), new Properties(),
new ApplicationProperties(new HashMap()), new Footer(Collections.EMPTY_MAP),
session);
_list = new ArrayList();
}
- public StreamMessageImpl(final Header header,
- final MessageAnnotations messageAnnotations,
- final Properties properties,
- final ApplicationProperties appProperties,
- final List amqpListSection, final Footer footer)
- {
- super(header, messageAnnotations, properties, appProperties, footer, null);
- _list = amqpListSection;
- }
-
public boolean readBoolean() throws JMSException
{
Object obj = readObject();
@@ -453,6 +458,10 @@ public class StreamMessageImpl extends M
{
List<Section> sections = new ArrayList<Section>();
sections.add(getHeader());
+ if(getDeliveryAnnotations() != null && getDeliveryAnnotations().getValue() != null && !getDeliveryAnnotations().getValue().isEmpty())
+ {
+ sections.add(getDeliveryAnnotations());
+ }
if(getMessageAnnotations() != null && getMessageAnnotations().getValue() != null && !getMessageAnnotations().getValue().isEmpty())
{
sections.add(getMessageAnnotations());
Modified: qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TextMessageImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TextMessageImpl.java?rev=1622888&r1=1622887&r2=1622888&view=diff
==============================================================================
--- qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TextMessageImpl.java (original)
+++ qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TextMessageImpl.java Sat Sep 6 16:49:22 2014
@@ -19,20 +19,31 @@
package org.apache.qpid.amqp_1_0.jms.impl;
-import org.apache.qpid.amqp_1_0.jms.TextMessage;
-import org.apache.qpid.amqp_1_0.type.Section;
-import org.apache.qpid.amqp_1_0.type.messaging.*;
-import org.apache.qpid.amqp_1_0.type.messaging.Properties;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
import javax.jms.JMSException;
import javax.jms.MessageNotWriteableException;
-import java.util.*;
+
+import org.apache.qpid.amqp_1_0.jms.TextMessage;
+import org.apache.qpid.amqp_1_0.type.Section;
+import org.apache.qpid.amqp_1_0.type.messaging.AmqpValue;
+import org.apache.qpid.amqp_1_0.type.messaging.ApplicationProperties;
+import org.apache.qpid.amqp_1_0.type.messaging.DeliveryAnnotations;
+import org.apache.qpid.amqp_1_0.type.messaging.Footer;
+import org.apache.qpid.amqp_1_0.type.messaging.Header;
+import org.apache.qpid.amqp_1_0.type.messaging.MessageAnnotations;
+import org.apache.qpid.amqp_1_0.type.messaging.Properties;
public class TextMessageImpl extends MessageImpl implements TextMessage
{
private String _text;
protected TextMessageImpl(Header header,
+ DeliveryAnnotations deliveryAnnotations,
MessageAnnotations messageAnnotations,
Properties properties,
ApplicationProperties appProperties,
@@ -40,13 +51,13 @@ public class TextMessageImpl extends Mes
Footer footer,
SessionImpl session)
{
- super(header, messageAnnotations, properties, appProperties, footer, session);
+ super(header, deliveryAnnotations, messageAnnotations, properties, appProperties, footer, session);
_text = text;
}
protected TextMessageImpl(final SessionImpl session)
{
- super(new Header(), new MessageAnnotations(new HashMap()),
+ super(new Header(), new DeliveryAnnotations(new HashMap()), new MessageAnnotations(new HashMap()),
new Properties(), new ApplicationProperties(new HashMap()), new Footer(Collections.EMPTY_MAP),
session);
}
@@ -77,6 +88,10 @@ public class TextMessageImpl extends Mes
{
List<Section> sections = new ArrayList<Section>();
sections.add(getHeader());
+ if(getDeliveryAnnotations() != null && getDeliveryAnnotations().getValue() != null && !getDeliveryAnnotations().getValue().isEmpty())
+ {
+ sections.add(getDeliveryAnnotations());
+ }
if(getMessageAnnotations() != null && getMessageAnnotations().getValue() != null && !getMessageAnnotations().getValue().isEmpty())
{
sections.add(getMessageAnnotations());
Added: qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/AnnotationDecoder.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/AnnotationDecoder.java?rev=1622888&view=auto
==============================================================================
--- qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/AnnotationDecoder.java (added)
+++ qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/AnnotationDecoder.java Sat Sep 6 16:49:22 2014
@@ -0,0 +1,395 @@
+/*
+ *
+ * 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.amqp_1_0.jms.impl.util;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.qpid.amqp_1_0.codec.DescribedType;
+import org.apache.qpid.amqp_1_0.type.Binary;
+import org.apache.qpid.amqp_1_0.type.Symbol;
+import org.apache.qpid.amqp_1_0.type.UnsignedByte;
+import org.apache.qpid.amqp_1_0.type.UnsignedInteger;
+import org.apache.qpid.amqp_1_0.type.UnsignedLong;
+import org.apache.qpid.amqp_1_0.type.UnsignedShort;
+
+public class AnnotationDecoder
+{
+ private static final Map<String,Converter> CONVERTERS = new HashMap<>();
+
+
+ private final JsonDecoder _decoder = new JsonDecoder();
+
+ public Map<Symbol,Object> decode(String value) throws IOException
+ {
+ Map<String,Object> map = (Map<String,Object>) _decoder.decode(new StringReader(value));
+ Map<Symbol,Object> convertedMap = new LinkedHashMap<>();
+ for(Map.Entry<String,Object> entry : map.entrySet())
+ {
+ convertedMap.put(Symbol.valueOf(entry.getKey()), convertObject(entry.getValue()));
+ }
+ return convertedMap;
+ }
+
+ private Object convertObject(final Object value)
+ {
+ if(value == null || value instanceof String || value instanceof Boolean)
+ {
+ return value;
+ }
+ else if(value instanceof Number)
+ {
+ return ((Number)value).intValue();
+ }
+ else if(value instanceof Collection)
+ {
+ Collection<?> list = (Collection<?>)value;
+ List<Object> convertedList = new ArrayList<>(list.size());
+ for(Object o : list)
+ {
+ convertedList.add(convertObject(o));
+ }
+ return convertedList;
+ }
+ else if(value instanceof Map)
+ {
+ Map<String,Object> map = (Map<String,Object>)value;
+ if(map.size() != 1)
+ {
+ throw new IllegalArgumentException("Cannot parse map " + map + " as a value");
+ }
+ Converter converter = CONVERTERS.get(map.keySet().iterator().next());
+ return converter.convert(map.values().iterator().next(), this);
+ }
+ return null;
+ }
+
+ private static abstract class Converter
+ {
+ Converter(String name)
+ {
+ CONVERTERS.put(name, this);
+ }
+
+ abstract Object convert(Object value, final AnnotationDecoder decoder);
+ }
+
+ private static Converter LONG_CONVERTER = new Converter("long")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ return ((Number)value).longValue();
+ }
+ };
+
+ private static Converter SHORT_CONVERTER = new Converter("short")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ return ((Number)value).shortValue();
+ }
+ };
+
+ private static Converter BYTE_CONVERTER = new Converter("byte")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ return ((Number)value).byteValue();
+ }
+ };
+
+ private static Converter ULONG_CONVERTER = new Converter("ulong")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ Number number = (Number) value;
+ return UnsignedLong.valueOf(number.toString());
+ }
+ };
+
+ private static Converter UINT_CONVERTER = new Converter("uint")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ return UnsignedInteger.valueOf(((Number) value).longValue());
+ }
+ };
+
+ private static Converter USHORT_CONVERTER = new Converter("ushort")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ Number number = (Number) value;
+ return UnsignedShort.valueOf(number.toString());
+ }
+ };
+
+ private static Converter UBYTE_CONVERTER = new Converter("ubyte")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ Number number = (Number) value;
+
+ return UnsignedByte.valueOf(value.toString());
+ }
+ };
+
+ private static Converter FLOAT_CONVERTER = new Converter("float")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ return ((Number) value).floatValue();
+ }
+ };
+
+ private static Converter DOUBLE_CONVERTER = new Converter("double")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ return ((Number) value).doubleValue();
+ }
+ };
+
+
+ private static Converter SYMBOL_CONVERTER = new Converter("symbol")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ return Symbol.valueOf((String) value);
+ }
+ };
+
+
+ private static Converter CHAR_CONVERTER = new Converter("char")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ String stringValue = (String) value;
+ if(stringValue.length() != 1)
+ {
+ throw new IllegalArgumentException("Cannot decode '"+stringValue+"' as a char");
+ }
+ return stringValue.charAt(0);
+ }
+ };
+
+
+ private static Converter TIMESTAMP_CONVERTER = new Converter("timestamp")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ return new Date(((Number) value).longValue());
+ }
+ };
+
+
+ private static Converter MAP_CONVERTER = new Converter("map")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ Map<?,?> map = (Map<?,?>) value;
+ Map<Object,Object> convertedMap = new LinkedHashMap<>();
+ for(Map.Entry<?,?> entry : map.entrySet())
+ {
+ convertedMap.put(decoder.convertObject(entry.getKey()), decoder.convertObject(entry.getValue()));
+ }
+ return convertedMap;
+ }
+ };
+
+
+ private static Converter DESCRIBED_CONVERTER = new Converter("described")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ Map<?,?> map = (Map<?,?>) value;
+ if(map.size() != 1)
+ {
+ throw new IllegalArgumentException("Cannot convert described type from: " + map);
+ }
+ Object descriptor = decoder.convertObject(map.keySet().iterator().next());
+ Object described = decoder.convertObject(map.values().iterator().next());
+ return new DescribedType(descriptor, described);
+ }
+ };
+
+ private static Converter BINARY_CONVERTER = new Converter("binary")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ String valueString = (String)value;
+ byte[] bytes = DatatypeConverter.parseBase64Binary(valueString);
+ return new Binary(bytes);
+ }
+ };
+
+ private static Converter ARRAY_CONVERTER = new Converter("array")
+ {
+ @Override
+ Object convert(final Object value, final AnnotationDecoder decoder)
+ {
+ Collection<?> list = (Collection<?>)value;
+ List<Object> convertedList = new ArrayList<>(list.size());
+ Set<Class> objClasses = new HashSet<>();
+ for(Object o : list)
+ {
+ Object convertObject = decoder.convertObject(o);
+ objClasses.add(convertObject == null ? Void.class : convertObject.getClass());
+ convertedList.add(convertObject);
+ }
+ if(objClasses.size() != 1)
+ {
+ throw new IllegalArgumentException("Cannot convert object to an array: " + value);
+ }
+ Class objClass = objClasses.iterator().next();
+ if(objClass == Void.class)
+ {
+ return new Void[convertedList.size()];
+ }
+ else if(objClass == Boolean.class)
+ {
+ boolean[] array = new boolean[convertedList.size()];
+ for(int i = 0; i < convertedList.size(); i++)
+ {
+ array[i] = (Boolean) convertedList.get(i);
+ }
+ return array;
+ }
+ else if(objClass == Byte.class)
+ {
+ byte[] array = new byte[convertedList.size()];
+ for(int i = 0; i < convertedList.size(); i++)
+ {
+ array[i] = (Byte) convertedList.get(i);
+ }
+ return array;
+ }
+ else if(objClass == Character.class)
+ {
+ char[] array = new char[convertedList.size()];
+ for(int i = 0; i < convertedList.size(); i++)
+ {
+ array[i] = (Character) convertedList.get(i);
+ }
+ return array;
+ }
+ else if(objClass == Short.class)
+ {
+ short[] array = new short[convertedList.size()];
+ for(int i = 0; i < convertedList.size(); i++)
+ {
+ array[i] = (Short) convertedList.get(i);
+ }
+ return array;
+ }
+ else if(objClass == Integer.class)
+ {
+ int[] array = new int[convertedList.size()];
+ for(int i = 0; i < convertedList.size(); i++)
+ {
+ array[i] = (Integer) convertedList.get(i);
+ }
+ return array;
+ }
+ else if(objClass == Long.class)
+ {
+ long[] array = new long[convertedList.size()];
+ for(int i = 0; i < convertedList.size(); i++)
+ {
+ array[i] = (Long) convertedList.get(i);
+ }
+ return array;
+ }
+ else if(objClass == Float.class)
+ {
+ float[] array = new float[convertedList.size()];
+ for(int i = 0; i < convertedList.size(); i++)
+ {
+ array[i] = (Float) convertedList.get(i);
+ }
+ return array;
+ }
+ else if(objClass == Double.class)
+ {
+ double[] array = new double[convertedList.size()];
+ for(int i = 0; i < convertedList.size(); i++)
+ {
+ array[i] = (Double) convertedList.get(i);
+ }
+ return array;
+ }
+ else
+ {
+ return convertedList.toArray((Object[])Array.newInstance(objClass, convertedList.size()));
+ }
+ }
+ };
+
+
+ public static void main(String[] args) throws Exception
+ {
+ Map<Symbol, Object> foo = new LinkedHashMap<>();
+ foo.put(Symbol.valueOf("ARG_1"), 2);
+ foo.put(Symbol.valueOf("ARG_2"), true);
+ foo.put(Symbol.valueOf("ARG_3"), "wibble");
+ foo.put(Symbol.valueOf("ARG_4"), Arrays.asList("this", "is", "a", "test"));
+ foo.put(Symbol.valueOf("ARG_5"), Arrays.asList((Object)"this", 2l, Symbol.valueOf("a"), "test"));
+ foo.put(Symbol.valueOf("ARG_6"), Collections.singletonMap("wibble",0.3));
+
+
+
+ String encoded = new AnnotationEncoder().encode(foo);
+ System.err.println(encoded);
+ Object foo2 = new AnnotationDecoder().decode(encoded);
+
+ System.out.println(foo2.equals(foo));
+ }
+
+}
Added: qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/AnnotationEncoder.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/AnnotationEncoder.java?rev=1622888&view=auto
==============================================================================
--- qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/AnnotationEncoder.java (added)
+++ qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/AnnotationEncoder.java Sat Sep 6 16:49:22 2014
@@ -0,0 +1,175 @@
+/*
+ *
+ * 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.amqp_1_0.jms.impl.util;
+
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.qpid.amqp_1_0.codec.DescribedType;
+import org.apache.qpid.amqp_1_0.type.Binary;
+import org.apache.qpid.amqp_1_0.type.Symbol;
+import org.apache.qpid.amqp_1_0.type.UnsignedByte;
+import org.apache.qpid.amqp_1_0.type.UnsignedInteger;
+import org.apache.qpid.amqp_1_0.type.UnsignedLong;
+import org.apache.qpid.amqp_1_0.type.UnsignedShort;
+
+public class AnnotationEncoder
+{
+ private final JsonEncoder _encoder = new JsonEncoder();
+
+ public String encode(Map<Symbol,Object> annotations) throws IOException
+ {
+ Map<String,Object> convertedMap = convertMap(annotations);
+ return _encoder.encode(convertedMap);
+ }
+
+
+ private Map<String, Object> convertMap(final Map<Symbol,Object> value)
+ {
+ Map<String,Object> converted = new LinkedHashMap<>();
+ for(Map.Entry<Symbol,Object> entry : value.entrySet())
+ {
+ converted.put(entry.getKey().toString(), convert(entry.getValue()));
+ }
+ return converted;
+ }
+
+ private Object convert(final Object value)
+ {
+ if(value == null || value instanceof String || value instanceof Boolean || value instanceof Integer)
+ {
+ return value;
+ }
+ else if(value instanceof Long)
+ {
+ return Collections.singletonMap("long", value);
+ }
+ else if(value instanceof Short)
+ {
+ return Collections.singletonMap("short", value);
+ }
+ else if(value instanceof Byte)
+ {
+ return Collections.singletonMap("byte", value);
+ }
+ else if(value instanceof UnsignedLong)
+ {
+ return Collections.singletonMap("ulong", ((UnsignedLong)value).bigIntegerValue());
+ }
+ else if(value instanceof UnsignedInteger)
+ {
+ return Collections.singletonMap("uint", ((UnsignedInteger)value).longValue());
+ }
+ else if(value instanceof UnsignedShort)
+ {
+ return Collections.singletonMap("ushort", ((UnsignedShort)value).intValue());
+ }
+ else if(value instanceof UnsignedByte)
+ {
+ return Collections.singletonMap("ubyte", ((UnsignedByte)value).shortValue());
+ }
+ else if(value instanceof Character)
+ {
+ return Collections.singletonMap("char", value.toString());
+ }
+ else if(value instanceof Symbol)
+ {
+ return Collections.singletonMap("symbol", value.toString());
+ }
+ else if(value instanceof Date)
+ {
+ return Collections.singletonMap("timestamp", ((Date)value).getTime());
+ }
+ else if(value instanceof Float)
+ {
+ return Collections.singletonMap("float", value);
+ }
+ else if(value instanceof Double)
+ {
+ return Collections.singletonMap("double", value);
+ }
+ else if(value instanceof Binary)
+ {
+ Binary bin = (Binary) value;
+ byte[] bytes;
+ if(bin.getArrayOffset() != 0 || bin.getLength() != bin.getArray().length)
+ {
+ bytes = new byte[bin.getLength()];
+ System.arraycopy(bin.getArray(), bin.getArrayOffset(),bytes, 0, bin.getLength());
+ }
+ else
+ {
+ bytes = bin.getArray();
+ }
+ return Collections.singletonMap("binary", DatatypeConverter.printBase64Binary(bytes));
+ }
+ else if(value instanceof List)
+ {
+ List<?> list = (List) value;
+ List<Object> convertedList = new ArrayList<>(list.size());
+ for(Object o : list)
+ {
+ convertedList.add(convert(o));
+ }
+ return convertedList;
+ }
+ else if(value instanceof Map)
+ {
+ Map<?,?> map = (Map<?,?>) value;
+ Map<Object,Object> convertedMap = new LinkedHashMap<>();
+ for(Map.Entry<?,?> entry : map.entrySet())
+ {
+ convertedMap.put(convert(entry.getKey()), convert(entry.getValue()));
+ }
+ return Collections.singletonMap("map", convertedMap);
+ }
+ else if(value instanceof Object[])
+ {
+ return Collections.singletonMap("array", convert(Arrays.asList((Object[])value)));
+ }
+ else if(value.getClass().isArray())
+ {
+ int length = Array.getLength(value);
+ List<Object> list = new ArrayList<>(length);
+ for(int i = 0; i < length; i++)
+ {
+ list.add(Array.get(value, i));
+ }
+ return Collections.singletonMap("array", convert(list));
+ }
+ else if(value instanceof DescribedType)
+ {
+ DescribedType type = (DescribedType) value;
+ return Collections.singletonMap("described", Collections.singletonMap(convert(type.getDescriptor()),
+ convert(type.getDescribed())));
+ }
+ throw new IllegalArgumentException("Cannot convert object of class: " + value.getClass().getName());
+ }
+}
Added: qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/JsonDecoder.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/JsonDecoder.java?rev=1622888&view=auto
==============================================================================
--- qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/JsonDecoder.java (added)
+++ qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/JsonDecoder.java Sat Sep 6 16:49:22 2014
@@ -0,0 +1,379 @@
+/*
+ *
+ * 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.amqp_1_0.jms.impl.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+public class JsonDecoder
+{
+ static enum TokenType
+ {
+ BEGIN_MAP,
+ END_MAP,
+ BEGIN_ARRAY,
+ END_ARRAY,
+ COMMA,
+ COLON,
+ STRING,
+ BOOLEAN,
+ NUMBER,
+ NULL
+ }
+
+ static private class Token
+ {
+ private final TokenType _type;
+ private final Object _value;
+
+
+ private Token(final TokenType type, final Object value)
+ {
+ _type = type;
+ _value = value;
+ }
+
+ public TokenType getType()
+ {
+ return _type;
+ }
+
+ public Object getValue()
+ {
+ return _value;
+ }
+ }
+
+ public Object decode(Reader reader) throws IOException
+ {
+ if(!reader.markSupported())
+ {
+ return decode(new BufferedReader(reader));
+ }
+ else
+ {
+ return readValue(reader, new Stack<Token>());
+ }
+ }
+
+ private Object readValue(final Reader reader, final Stack<Token> tokenStack) throws IOException
+ {
+ Token token = readToken(reader, tokenStack);
+ switch(token.getType())
+ {
+ case BOOLEAN:
+ case NUMBER:
+ case STRING:
+ case NULL:
+ return token.getValue();
+ case BEGIN_MAP:
+ Map<Object,Object> map = new LinkedHashMap<>();
+ token = readToken(reader, tokenStack);
+ if(token.getType() != TokenType.END_MAP)
+ {
+ tokenStack.push(token);
+ do
+ {
+ Object key = readValue(reader, tokenStack);
+ token = readToken(reader, tokenStack);
+ if(token.getType() != TokenType.COLON)
+ {
+ throw new IllegalArgumentException("Cannot parse Json string");
+ }
+ Object value = readValue(reader, tokenStack);
+ map.put(key, value);
+ token = readToken(reader, tokenStack);
+ if(!(token.getType() == TokenType.END_MAP
+ || token.getType() == TokenType.COMMA))
+ {
+ throw new IllegalArgumentException("Cannot parse Json string");
+ }
+ }
+ while(token.getType() != TokenType.END_MAP);
+
+ }
+ return map;
+ case BEGIN_ARRAY:
+ List<Object> list = new ArrayList<>();
+ token = readToken(reader, tokenStack);
+ if(token.getType() != TokenType.END_MAP)
+ {
+ tokenStack.push(token);
+ do
+ {
+ Object element = readValue(reader, tokenStack);
+ list.add(element);
+ token = readToken(reader, tokenStack);
+ if(!(token.getType() == TokenType.END_ARRAY
+ || token.getType() == TokenType.COMMA))
+ {
+ throw new IllegalArgumentException("Cannot parse Json string");
+ }
+ }
+ while(token.getType() != TokenType.END_ARRAY);
+
+ }
+
+ return list;
+ default:
+ throw new IllegalArgumentException("Could not parse Json String");
+
+ }
+ }
+
+ static final Map<Character, Token> PUNCTUATION_TOKENS;
+ static
+ {
+ final Map<Character, Token> tokenMap = new HashMap<>();
+ tokenMap.put('{', new Token(TokenType.BEGIN_MAP, null));
+ tokenMap.put('}', new Token(TokenType.END_MAP, null));
+ tokenMap.put('[', new Token(TokenType.BEGIN_ARRAY, null));
+ tokenMap.put(']', new Token(TokenType.END_ARRAY, null));
+ tokenMap.put(':', new Token(TokenType.COLON, null));
+ tokenMap.put(',', new Token(TokenType.COMMA, null));
+ PUNCTUATION_TOKENS = Collections.unmodifiableMap(tokenMap);
+ }
+
+ private Token readToken(final Reader reader, final Stack<Token> tokenStack) throws IOException
+ {
+ if(!tokenStack.isEmpty())
+ {
+ return tokenStack.pop();
+ }
+ ignoreWhitespace(reader);
+
+
+ char[] cb = new char[1];
+ reader.mark(2);
+ if(reader.read(cb) == 1)
+ {
+ final char c = cb[0];
+ Token token = PUNCTUATION_TOKENS.get(c);
+ if(token != null)
+ {
+ return token;
+ }
+ if(c == '"')
+ {
+ reader.reset();
+ return readString(reader);
+ }
+ else if(c == '-' || (c >= '0' && c <= '9'))
+ {
+ reader.reset();
+ return readNumber(reader);
+ }
+ else if(c == 't')
+ {
+ reader.reset();
+ readLiteral(reader, "true");
+ return new Token(TokenType.BOOLEAN, true);
+ }
+ else if(c == 'f')
+ {
+ reader.reset();
+ readLiteral(reader, "false");
+ return new Token(TokenType.BOOLEAN, false);
+ }
+ else if(c == 'n')
+ {
+ reader.reset();
+ readLiteral(reader, "null");
+ return new Token(TokenType.NULL, null);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Could not parse json string");
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("Insufficient data");
+ }
+
+ }
+
+ private Token readNumber(final Reader reader) throws IOException
+ {
+ StringBuilder buffer = new StringBuilder();
+ reader.mark(1);
+ char[] cb = new char[1];
+ int read;
+ while((read = reader.read(cb)) == 1 && (Character.isDigit(cb[0]) || cb[0] == '-' || Character.isAlphabetic(cb[0]) || cb[0] == '.'))
+ {
+ buffer.append(cb[0]);
+ reader.mark(1);
+ }
+ if(read == 1)
+ {
+ reader.reset();
+ }
+
+ // todo - here
+ String numberString = buffer.toString();
+ if(!numberString.matches("-?\\d+(\\.\\d+)?([eE][+\\-]?\\d+)?"))
+ {
+ throw new IllegalArgumentException("Cannot parse number from " + numberString);
+ }
+ BigDecimal number = new BigDecimal(numberString.toUpperCase());
+ try
+ {
+ // TODO - doesn't cope with unsigned longs > Long.MAX_VALUE
+ BigInteger bigInteger = number.toBigIntegerExact();
+ if(bigInteger.longValue() > Integer.MAX_VALUE
+ || bigInteger.longValue() < Integer.MIN_VALUE)
+ {
+ return new Token(TokenType.NUMBER, bigInteger.longValue());
+ }
+ else
+ {
+ return new Token(TokenType.NUMBER, bigInteger.intValue());
+ }
+ }
+ catch(ArithmeticException e)
+ {
+ return new Token(TokenType.NUMBER, number.doubleValue());
+ }
+ }
+
+ private Token readString(final Reader reader) throws IOException
+ {
+ StringBuilder builder = new StringBuilder();
+ // ignore starting quote
+ reader.read();
+
+
+ do
+ {
+ char c = readChar(reader);
+ if(c == '\\')
+ {
+ c = readChar(reader);
+ if(c == '\\' || c == '/' || c == '"')
+ {
+ builder.append(c);
+ }
+ else if(c == 't')
+ {
+ builder.append('\t');
+ }
+ else if(c == 'n')
+ {
+ builder.append('\n');
+ }
+ else if(c == 'r')
+ {
+ builder.append('\r');
+ }
+ else if(c == 'f')
+ {
+ builder.append('\f');
+ }
+ else if(c == 'b')
+ {
+ builder.append('\b');
+ }
+ else if(c == 'u')
+ {
+ char[] point = new char[4];
+ if(reader.read(point) != 4)
+ {
+ throw new IllegalArgumentException("Insufficient data");
+ }
+ char codePoint = (char)(Integer.parseInt((new String(point)).toUpperCase(), 16) & 0xffff);
+ builder.append(codePoint);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Invalid escaped character");
+ }
+ }
+ else if(c == '"')
+ {
+ break;
+ }
+ else
+ {
+ builder.append(c);
+ }
+ }
+ while(true);
+
+
+ return new Token(TokenType.STRING, builder.toString());
+ }
+
+ private char readChar(final Reader reader) throws IOException
+ {
+ char[] cb = new char[1];
+ if(reader.read(cb) != 1)
+ {
+ throw new IllegalArgumentException("Insufficient data");
+ }
+ return cb[0];
+ }
+
+
+ private void readLiteral(final Reader reader, CharSequence expected) throws IOException
+ {
+ char[] cbuf = new char[expected.length()];
+ int read = reader.read(cbuf);
+ if(read != expected.length())
+ {
+ throw new IllegalArgumentException("Could not parse literal");
+ }
+ for(int i = 0; i < expected.length(); i++)
+ {
+ if(cbuf[i] != expected.charAt(i))
+ {
+ throw new IllegalArgumentException("Could not parse literal");
+ }
+ }
+ }
+
+ private void ignoreWhitespace(Reader reader) throws IOException
+ {
+ char[] cb = new char[1];
+ reader.mark(1);
+ while(reader.read(cb) == 1)
+ {
+ if(!Character.isWhitespace(cb[0]))
+ {
+ reader.reset();
+ break;
+ }
+ else
+ {
+ reader.mark(1);
+ }
+ }
+ }
+}
Added: qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/JsonEncoder.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/JsonEncoder.java?rev=1622888&view=auto
==============================================================================
--- qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/JsonEncoder.java (added)
+++ qpid/trunk/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/util/JsonEncoder.java Sat Sep 6 16:49:22 2014
@@ -0,0 +1,140 @@
+/*
+ *
+ * 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.amqp_1_0.jms.impl.util;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+
+public class JsonEncoder
+{
+ public void encode(Object object, Writer writer) throws IOException
+ {
+ if(object == null)
+ {
+ writer.append("null");
+ }
+ else if(object instanceof Boolean)
+ {
+ writer.append(((Boolean)object)? "true" : "false");
+ }
+ else if(object instanceof Number)
+ {
+ writer.append(object.toString());
+ }
+ else if(object instanceof Object[])
+ {
+ writer.append("[ ");
+ boolean first = true;
+ for(Object element : ((Object[])object))
+ {
+ if(first)
+ {
+ first = false;
+ }
+ else
+ {
+ writer.append(',');
+ }
+ encode(element, writer);
+ writer.append(" ]");
+ }
+ }
+ else if(object instanceof Iterable)
+ {
+ writer.append("[ ");
+ boolean first = true;
+ for(Object element : ((Iterable)object))
+ {
+ if(first)
+ {
+ first = false;
+ }
+ else
+ {
+ writer.append(", ");
+ }
+ encode(element, writer);
+ }
+ writer.append(" ]");
+ }
+ else if(object instanceof Map)
+ {
+ writer.append("{ ");
+ boolean first = true;
+ for(Map.Entry element : ((Map<?,?>)object).entrySet())
+ {
+ if(first)
+ {
+ first = false;
+ }
+ else
+ {
+ writer.append(", ");
+ }
+ encode(element.getKey(), writer);
+ writer.append(" : ");
+ encode(element.getValue(), writer);
+ }
+ writer.append(" }");
+ }
+ else if(object instanceof CharSequence)
+ {
+ CharSequence string = (CharSequence)object;
+ writer.append('"');
+ for(int i = 0; i < string.length(); i++)
+ {
+ char c = string.charAt(i);
+ if(c == '"' || c=='\\')
+ {
+ writer.append('\\');
+ }
+ writer.append(c);
+ }
+ writer.append('"');
+ }
+ else
+ {
+ throw new IllegalArgumentException("Don't know how to encode class " + object.getClass().getName());
+ }
+ }
+
+ public String encode(Object object) throws IOException
+ {
+ StringWriter writer = new StringWriter();
+ encode(object, writer);
+ return writer.toString();
+ }
+
+
+ public static void main(String[] args) throws Exception
+ {
+ JsonEncoder encoder = new JsonEncoder();
+ String encoded =
+ encoder.encode(Collections.singletonMap("hello \\\" world", Arrays.asList(3, 7.2, false, null, 4)));
+ Object decoded = new JsonDecoder().decode(new StringReader(encoded));
+ System.err.println(encoded);
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org