Author: jgomes Date: Tue Feb 9 01:11:33 2010 New Revision: 907867 URL: http://svn.apache.org/viewvc?rev=907867&view=rev Log: 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) Modified: activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/MessageExtensions.cs activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/MessageProducerExtensions.cs activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/NMSConstants.cs activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/SessionExtensions.cs activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/Util/Convert.cs activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/Util/XmlUtils.cs Modified: activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/MessageExtensions.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/MessageExtensions.cs?rev=907867&r1=907866&r2=907867&view=diff ============================================================================== --- activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/MessageExtensions.cs (original) +++ activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/MessageExtensions.cs Tue Feb 9 01:11:33 2010 @@ -35,29 +35,13 @@ /// <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) Modified: activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/MessageProducerExtensions.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/MessageProducerExtensions.cs?rev=907867&r1=907866&r2=907867&view=diff ============================================================================== --- activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/MessageProducerExtensions.cs (original) +++ activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/MessageProducerExtensions.cs Tue Feb 9 01:11:33 2010 @@ -29,15 +29,7 @@ /// </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> @@ -49,14 +41,6 @@ } /// <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> public static void Send(this IMessageProducer producer, object objMessage, MsgDeliveryMode deliveryMode, MsgPriority priority, TimeSpan timeToLive) @@ -65,14 +49,6 @@ } /// <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> public static void Send(this IMessageProducer producer, IDestination destination, object objMessage) @@ -81,28 +57,12 @@ } /// <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 } Modified: activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/NMSConstants.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/NMSConstants.cs?rev=907867&r1=907866&r2=907867&view=diff ============================================================================== --- activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/NMSConstants.cs (original) +++ activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/NMSConstants.cs Tue Feb 9 01:11:33 2010 @@ -16,6 +16,7 @@ */ using System; +using System.Text; namespace Apache.NMS { Modified: activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/SessionExtensions.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/SessionExtensions.cs?rev=907867&r1=907866&r2=907867&view=diff ============================================================================== --- activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/SessionExtensions.cs (original) +++ activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/SessionExtensions.cs Tue Feb 9 01:11:33 2010 @@ -28,15 +28,7 @@ /// </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> Modified: activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/Util/Convert.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/Util/Convert.cs?rev=907867&r1=907866&r2=907867&view=diff ============================================================================== --- activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/Util/Convert.cs (original) +++ activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/Util/Convert.cs Tue Feb 9 01:11:33 2010 @@ -64,18 +64,7 @@ #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 @@ #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 @@ #endif public static object FromXmlMessage(IMessage message) { - return DeserializeObjFromMessage(message, Encoding.Unicode); + return DeserializeObjFromMessage(message); } /// <summary> @@ -117,13 +95,12 @@ /// </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; } @@ -131,9 +108,8 @@ /// 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 @@ return null; } - return XmlUtil.Deserialize(objType, textMessage.Text, encoding); + return XmlUtil.Deserialize(objType, textMessage.Text); } /// <summary> Modified: activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/Util/XmlUtils.cs URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/Util/XmlUtils.cs?rev=907867&r1=907866&r2=907867&view=diff ============================================================================== --- activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/Util/XmlUtils.cs (original) +++ activemq/activemq-dotnet/Apache.NMS/trunk/src/main/csharp/Util/XmlUtils.cs Tue Feb 9 01:11:33 2010 @@ -20,6 +20,7 @@ using System.Text; using System.Xml; using System.Xml.Serialization; +using System.Text.RegularExpressions; namespace Apache.NMS.Util { @@ -30,28 +31,18 @@ { 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) { @@ -62,11 +53,6 @@ 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) { return null; @@ -75,16 +61,12 @@ 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 @@ } } + /// <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);
