Skip to content
Permalink
Browse files
Change underlying buffer for serializing Xml text to a StringBuilder …
…type. This will serialize the Xml message as a Unicode string without a Byte Order Mark.

Fixes [AMQNET-230]. (See https://issues.apache.org/activemq/browse/AMQNET-230)
  • Loading branch information
Jim Gomes committed Feb 9, 2010
1 parent f18e5b7 commit 23858cbaa0bc6cf2e38e18ee07774b0c91bb368b
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 131 deletions.
@@ -35,29 +35,13 @@ public static object ToObject(this IMessage message)
/// <summary>
/// Deserializes the object from Xml, and returns it.
/// </summary>
public static object ToObject(this IMessage message, Encoding encoding)
{
return ToObject<object>(message, encoding);
}

/// <summary>
/// Deserializes the object from Xml, and returns it.
/// </summary>
public static T ToObject<T>(this IMessage message) where T : class
{
return ToObject<T>(message, Encoding.Unicode);
}

/// <summary>
/// Deserializes the object from Xml, and returns it.
/// </summary>
public static T ToObject<T>(this IMessage message, Encoding encoding) where T : class
public static T ToObject<T>(this IMessage message) where T : class
{
try
{
if(null != message)
{
return (T) NMSConvert.DeserializeObjFromMessage(message, encoding);
return (T) NMSConvert.DeserializeObjFromMessage(message);
}
}
catch(Exception ex)
@@ -29,15 +29,7 @@ public static class MessageProducerExtensions
/// </summary>
public static ITextMessage CreateXmlMessage(this IMessageProducer producer, object obj)
{
return CreateXmlMessage(producer, obj, Encoding.Unicode);
}

/// <summary>
/// Extension function to create a text message from an object. The object must be serializable to XML.
/// </summary>
public static ITextMessage CreateXmlMessage(this IMessageProducer producer, object obj, Encoding encoding)
{
return NMSConvert.SerializeObjToMessage(producer.CreateTextMessage(), obj, encoding);
return NMSConvert.SerializeObjToMessage(producer.CreateTextMessage(), obj);
}

/// <summary>
@@ -48,14 +40,6 @@ public static void Send(this IMessageProducer producer, object objMessage)
producer.Send(producer.CreateXmlMessage(objMessage));
}

/// <summary>
/// Sends the message to the default destination for this producer. The object must be serializable to XML.
/// </summary>
public static void Send(this IMessageProducer producer, object objMessage, Encoding encoding)
{
producer.Send(producer.CreateXmlMessage(objMessage, encoding));
}

/// <summary>
/// Sends the message to the default destination with the explicit QoS configuration. The object must be serializable to XML.
/// </summary>
@@ -64,14 +48,6 @@ public static void Send(this IMessageProducer producer, object objMessage, MsgDe
producer.Send(producer.CreateXmlMessage(objMessage), deliveryMode, priority, timeToLive);
}

/// <summary>
/// Sends the message to the default destination with the explicit QoS configuration. The object must be serializable to XML.
/// </summary>
public static void Send(this IMessageProducer producer, object objMessage, Encoding encoding, MsgDeliveryMode deliveryMode, MsgPriority priority, TimeSpan timeToLive)
{
producer.Send(producer.CreateXmlMessage(objMessage, encoding), deliveryMode, priority, timeToLive);
}

/// <summary>
/// Sends the message to the given destination
/// </summary>
@@ -80,29 +56,13 @@ public static void Send(this IMessageProducer producer, IDestination destination
producer.Send(destination, producer.CreateXmlMessage(objMessage));
}

/// <summary>
/// Sends the message to the given destination
/// </summary>
public static void Send(this IMessageProducer producer, IDestination destination, object objMessage, Encoding encoding)
{
producer.Send(destination, producer.CreateXmlMessage(objMessage, encoding));
}

/// <summary>
/// Sends the message to the given destination with the explicit QoS configuration. The object must be serializable to XML.
/// </summary>
public static void Send(this IMessageProducer producer, IDestination destination, object objMessage, MsgDeliveryMode deliveryMode, MsgPriority priority, TimeSpan timeToLive)
{
producer.Send(destination, producer.CreateXmlMessage(objMessage), deliveryMode, priority, timeToLive);
}

/// <summary>
/// Sends the message to the given destination with the explicit QoS configuration. The object must be serializable to XML.
/// </summary>
public static void Send(this IMessageProducer producer, IDestination destination, object objMessage, Encoding encoding, MsgDeliveryMode deliveryMode, MsgPriority priority, TimeSpan timeToLive)
{
producer.Send(destination, producer.CreateXmlMessage(objMessage, encoding), deliveryMode, priority, timeToLive);
}
}
#endif
}
@@ -16,6 +16,7 @@
*/

using System;
using System.Text;

namespace Apache.NMS
{
@@ -28,15 +28,7 @@ public static class SessionExtensions
/// </summary>
public static ITextMessage CreateXmlMessage(this ISession session, object obj)
{
return CreateXmlMessage(session, obj, Encoding.Unicode);
}

/// <summary>
/// Extension function to create a text message from an object. The object must be serializable to XML.
/// </summary>
public static ITextMessage CreateXmlMessage(this ISession session, object obj, Encoding encoding)
{
return NMSConvert.SerializeObjToMessage(session.CreateTextMessage(), obj, encoding);
return NMSConvert.SerializeObjToMessage(session.CreateTextMessage(), obj);
}

/// <summary>
@@ -64,18 +64,7 @@ public static AcknowledgementMode ToAcknowledgementMode(string ackText)
#endif
public static ITextMessage ToXmlMessage(IMessageProducer producer, object obj)
{
return ToXmlMessage(producer, obj, Encoding.Unicode);
}

/// <summary>
/// Convert an object into a text message. The object must be serializable to XML.
/// </summary>
#if NET_3_5 || MONO
[Obsolete]
#endif
public static ITextMessage ToXmlMessage(IMessageProducer producer, object obj, Encoding encoding)
{
return SerializeObjToMessage(producer.CreateTextMessage(), obj, encoding);
return SerializeObjToMessage(producer.CreateTextMessage(), obj);
}

/// <summary>
@@ -86,18 +75,7 @@ public static ITextMessage ToXmlMessage(IMessageProducer producer, object obj, E
#endif
public static ITextMessage ToXmlMessage(ISession session, object obj)
{
return ToXmlMessage(session, obj, Encoding.Unicode);
}

/// <summary>
/// Convert an object into a text message. The object must be serializable to XML.
/// </summary>
#if NET_3_5 || MONO
[Obsolete]
#endif
public static ITextMessage ToXmlMessage(ISession session, object obj, Encoding encoding)
{
return SerializeObjToMessage(session.CreateTextMessage(), obj, encoding);
return SerializeObjToMessage(session.CreateTextMessage(), obj);
}

/// <summary>
@@ -108,7 +86,7 @@ public static ITextMessage ToXmlMessage(ISession session, object obj, Encoding e
#endif
public static object FromXmlMessage(IMessage message)
{
return DeserializeObjFromMessage(message, Encoding.Unicode);
return DeserializeObjFromMessage(message);
}

/// <summary>
@@ -117,23 +95,21 @@ public static object FromXmlMessage(IMessage message)
/// </summary>
/// <param name="message"></param>
/// <param name="obj"></param>
/// <param name="encoding"></param>
/// <returns></returns>
internal static ITextMessage SerializeObjToMessage(ITextMessage message, object obj, Encoding encoding)
internal static ITextMessage SerializeObjToMessage(ITextMessage message, object obj)
{
// Embed the type into the message
message.NMSType = obj.GetType().FullName;
message.Text = XmlUtil.Serialize(obj, encoding);
message.Text = XmlUtil.Serialize(obj);
return message;
}

/// <summary>
/// Deserialize the object from the text message. The object must be serializable from XML.
/// </summary>
/// <param name="message"></param>
/// <param name="encoding"></param>
/// <returns></returns>
internal static object DeserializeObjFromMessage(IMessage message, Encoding encoding)
internal static object DeserializeObjFromMessage(IMessage message)
{
ITextMessage textMessage = message as ITextMessage;

@@ -155,7 +131,7 @@ internal static object DeserializeObjFromMessage(IMessage message, Encoding enco
return null;
}

return XmlUtil.Deserialize(objType, textMessage.Text, encoding);
return XmlUtil.Deserialize(objType, textMessage.Text);
}

/// <summary>
@@ -20,6 +20,7 @@
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Text.RegularExpressions;

namespace Apache.NMS.Util
{
@@ -29,29 +30,19 @@ namespace Apache.NMS.Util
public class XmlUtil
{
public static string Serialize(object obj)
{
return Serialize(obj, Encoding.Unicode);
}

public static string Serialize(object obj, Encoding encoding)
{
try
{
MemoryStream memoryStream = new MemoryStream();
StringBuilder outputStringBuilder = new StringBuilder();
XmlSerializer serializer = new XmlSerializer(obj.GetType());
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, encoding);
XmlWriter xmlWriter = XmlWriter.Create(outputStringBuilder);

/*
* If the XML document has been altered with unknown
* nodes or attributes, handle them with the
* UnknownNode and UnknownAttribute events.
*/
serializer.UnknownNode += new XmlNodeEventHandler(serializer_UnknownNode);
serializer.UnknownAttribute += new XmlAttributeEventHandler(serializer_UnknownAttribute);
serializer.Serialize(xmlTextWriter, obj);
memoryStream = (MemoryStream) xmlTextWriter.BaseStream;
byte[] encodedBytes = memoryStream.ToArray();
return encoding.GetString(encodedBytes, 0, encodedBytes.Length);
// Set the error handlers.
serializer.UnknownNode += serializer_UnknownNode;
serializer.UnknownElement += serializer_UnknownElement;
serializer.UnknownAttribute += serializer_UnknownAttribute;
serializer.Serialize(xmlWriter, obj);
return outputStringBuilder.ToString();
}
catch(Exception ex)
{
@@ -61,11 +52,6 @@ public static string Serialize(object obj, Encoding encoding)
}

public static object Deserialize(Type objType, string text)
{
return Deserialize(objType, text, Encoding.Unicode);
}

public static object Deserialize(Type objType, string text, Encoding encoding)
{
if(null == text)
{
@@ -75,16 +61,12 @@ public static object Deserialize(Type objType, string text, Encoding encoding)
try
{
XmlSerializer serializer = new XmlSerializer(objType);
MemoryStream memoryStream = new MemoryStream(encoding.GetBytes(text));

/*
* If the XML document has been altered with unknown
* nodes or attributes, handle them with the
* UnknownNode and UnknownAttribute events.
*/
serializer.UnknownNode += new XmlNodeEventHandler(serializer_UnknownNode);
serializer.UnknownAttribute += new XmlAttributeEventHandler(serializer_UnknownAttribute);
return serializer.Deserialize(memoryStream);
// Set the error handlers.
serializer.UnknownNode += serializer_UnknownNode;
serializer.UnknownElement += serializer_UnknownElement;
serializer.UnknownAttribute += serializer_UnknownAttribute;
return serializer.Deserialize(new StringReader(text));
}
catch(Exception ex)
{
@@ -93,11 +75,34 @@ public static object Deserialize(Type objType, string text, Encoding encoding)
}
}

/// <summary>
/// From xml spec valid chars:
/// #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
/// any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
/// </summary>
private static string invalidXMLMatch = @"[^\x09\x0A\x0D\x20-\xD7FF\xE000-\xFFFD\x10000-x10FFFF]";
private static Regex regexInvalidXMLChars = new Regex(invalidXMLMatch);

/// <summary>
/// This removes characters that are invalid for xml encoding
/// </summary>
/// <param name="text">Text to be encoded.</param>
/// <returns>Text with invalid xml characters removed.</returns>
public static string CleanInvalidXmlChars(string text)
{
return regexInvalidXMLChars.Replace(text, "");
}

private static void serializer_UnknownNode(object sender, XmlNodeEventArgs e)
{
Tracer.ErrorFormat("Unknown Node: {0}\t{1}", e.Name, e.Text);
}

private static void serializer_UnknownElement(object sender, XmlElementEventArgs e)
{
Tracer.ErrorFormat("Unknown Element: {0}\t{1}", e.Element.Name, e.Element.Value);
}

private static void serializer_UnknownAttribute(object sender, XmlAttributeEventArgs e)
{
Tracer.ErrorFormat("Unknown attribute: {0}='{1}'", e.Attr.Name, e.Attr.Value);

0 comments on commit 23858cb

Please sign in to comment.