SPRNET-936 - Add message converter to/from XML (NMS)
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
|
||||
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace Spring.Messaging.Nms.Support.Converter
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a layer of indirection when adding the 'type' of the object as a message property.
|
||||
/// </summary>
|
||||
/// <author>Mark Pollack</author>
|
||||
public interface ITypeMapper
|
||||
{
|
||||
string TypeIdFieldName
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
string FromType(Type typeOfObjectToConvert);
|
||||
|
||||
Type ToType(string typeId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Spring.Core.TypeResolution;
|
||||
|
||||
namespace Spring.Messaging.Nms.Support.Converter
|
||||
{
|
||||
public class TypeMapper : ITypeMapper
|
||||
{
|
||||
private string defaultNamespace;
|
||||
private string defaultAssemblyName;
|
||||
|
||||
//Generics not used to support both 1.1 and 2.0
|
||||
private IDictionary idTypeMapping;
|
||||
private IDictionary typeIdMapping;
|
||||
|
||||
|
||||
//TODO generalize?
|
||||
private string defaultHashtableTypeId = "Hashtable";
|
||||
|
||||
private Type defaultHashtableClass = typeof(Hashtable);
|
||||
|
||||
public TypeMapper()
|
||||
{
|
||||
idTypeMapping = new Hashtable();
|
||||
typeIdMapping = new Hashtable();
|
||||
}
|
||||
|
||||
|
||||
public IDictionary IdTypeMapping
|
||||
{
|
||||
get { return idTypeMapping; }
|
||||
set { idTypeMapping = value; }
|
||||
}
|
||||
|
||||
public string TypeIdFieldName
|
||||
{
|
||||
get { return "__TypeId__"; }
|
||||
}
|
||||
|
||||
|
||||
public Type DefaultHashtableClass
|
||||
{
|
||||
set { defaultHashtableClass = value; }
|
||||
}
|
||||
|
||||
public string FromType(Type typeOfObjectToConvert)
|
||||
{
|
||||
|
||||
if (typeIdMapping.Contains(typeOfObjectToConvert))
|
||||
{
|
||||
return typeIdMapping[typeOfObjectToConvert] as string;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( typeof (IDictionary).IsAssignableFrom(typeOfObjectToConvert))
|
||||
{
|
||||
return defaultHashtableTypeId;
|
||||
}
|
||||
return typeOfObjectToConvert.Name;
|
||||
}
|
||||
}
|
||||
|
||||
public Type ToType(string typeId)
|
||||
{
|
||||
if (idTypeMapping.Contains(typeId))
|
||||
{
|
||||
return idTypeMapping[typeId] as Type;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (typeId.Equals(defaultHashtableTypeId))
|
||||
{
|
||||
return defaultHashtableClass;
|
||||
}
|
||||
string fullyQualifiedTypeName = defaultNamespace + "." +
|
||||
typeId + ", " +
|
||||
DefaultAssemblyName;
|
||||
return TypeResolutionUtils.ResolveType(fullyQualifiedTypeName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string DefaultNamespace
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultNamespace;
|
||||
}
|
||||
set
|
||||
{
|
||||
defaultNamespace = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string DefaultAssemblyName
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultAssemblyName;
|
||||
}
|
||||
set
|
||||
{
|
||||
defaultAssemblyName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void AfterPropertiesSet()
|
||||
{
|
||||
ValidateIdTypeMapping();
|
||||
if (DefaultAssemblyName != null && DefaultNamespace == null)
|
||||
{
|
||||
throw new ArgumentException("Default Namespace required when DefaultAssemblyName is set.");
|
||||
}
|
||||
if (DefaultNamespace != null && DefaultAssemblyName == null)
|
||||
{
|
||||
throw new ArgumentException("Default Assembly Name required when DefaultNamespace is set.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ValidateIdTypeMapping()
|
||||
{
|
||||
IDictionary finalIdTypeMapping = new Hashtable();
|
||||
foreach (DictionaryEntry entry in idTypeMapping)
|
||||
{
|
||||
string id = entry.Key.ToString();
|
||||
Type t = entry.Value as Type;
|
||||
if (t == null)
|
||||
{
|
||||
//convert from string value.
|
||||
string typeName = entry.Value.ToString();
|
||||
t = TypeResolutionUtils.ResolveType(typeName);
|
||||
}
|
||||
finalIdTypeMapping.Add(id,t);
|
||||
typeIdMapping.Add(t,id);
|
||||
|
||||
}
|
||||
idTypeMapping = finalIdTypeMapping;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using Apache.NMS;
|
||||
using Spring.Messaging.Nms.Support.Converter;
|
||||
|
||||
namespace Spring.Messaging.Nms.Support.Converter
|
||||
{
|
||||
public class XmlMessageConverter : IMessageConverter
|
||||
{
|
||||
private IMessageConverter defaultMessageConverter = new SimpleMessageConverter();
|
||||
|
||||
|
||||
private ITypeMapper typeMapper;
|
||||
|
||||
|
||||
public ITypeMapper TypeMapper
|
||||
{
|
||||
set { typeMapper = value; }
|
||||
}
|
||||
|
||||
public IMessage ToMessage(object objectToConvert, ISession session)
|
||||
{
|
||||
if (objectToConvert == null)
|
||||
{
|
||||
throw new MessageConversionException("Can't convert null object");
|
||||
}
|
||||
try
|
||||
{
|
||||
if (objectToConvert.GetType().Equals(typeof (string)) ||
|
||||
typeof (IDictionary).IsAssignableFrom(objectToConvert.GetType()) ||
|
||||
objectToConvert.GetType().Equals(typeof (Byte[])))
|
||||
{
|
||||
return defaultMessageConverter.ToMessage(objectToConvert, session);
|
||||
}
|
||||
else
|
||||
{
|
||||
string xmlString = GetXmlString(objectToConvert);
|
||||
IMessage msg = session.CreateTextMessage(xmlString);
|
||||
msg.Properties.SetString(typeMapper.TypeIdFieldName, typeMapper.FromType(objectToConvert.GetType()));
|
||||
return msg;
|
||||
}
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw new MessageConversionException("Can't convert object of type " + objectToConvert.GetType(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetXmlString(object objectToConvert)
|
||||
{
|
||||
string xmlString;
|
||||
XmlTextWriter xmlTextWriter = null;
|
||||
MemoryStream memoryStream = null;
|
||||
try
|
||||
{
|
||||
memoryStream = new MemoryStream();
|
||||
xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
|
||||
XmlSerializer xs = new XmlSerializer(objectToConvert.GetType());
|
||||
xs.Serialize(xmlTextWriter, objectToConvert);
|
||||
xmlString = UTF8ByteArrayToString(((MemoryStream) xmlTextWriter.BaseStream).ToArray());
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw new MessageConversionException("Can't convert object of type " + objectToConvert.GetType(), e);
|
||||
} finally
|
||||
{
|
||||
if (memoryStream != null) memoryStream.Close();
|
||||
if (xmlTextWriter != null) xmlTextWriter.Close();
|
||||
}
|
||||
return xmlString;
|
||||
}
|
||||
|
||||
public object FromMessage(IMessage messageToConvert)
|
||||
{
|
||||
if (messageToConvert == null)
|
||||
{
|
||||
throw new MessageConversionException("Can't convert null message");
|
||||
}
|
||||
try
|
||||
{
|
||||
string converterId = messageToConvert.Properties.GetString(typeMapper.TypeIdFieldName);
|
||||
if (converterId == null)
|
||||
{
|
||||
return defaultMessageConverter.FromMessage(messageToConvert);
|
||||
}
|
||||
else
|
||||
{
|
||||
ITextMessage textMessage = messageToConvert as ITextMessage;
|
||||
if (textMessage == null)
|
||||
{
|
||||
throw new MessageConversionException("Can't convert message of type " +
|
||||
messageToConvert.GetType());
|
||||
}
|
||||
|
||||
using (MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(textMessage.Text)))
|
||||
{
|
||||
|
||||
XmlSerializer xs = new XmlSerializer(GetTargetType(textMessage));
|
||||
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
|
||||
return xs.Deserialize(memoryStream);
|
||||
}
|
||||
}
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw new MessageConversionException("Can't convert message of type " + messageToConvert.GetType(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private Type GetTargetType(ITextMessage message)
|
||||
{
|
||||
return typeMapper.ToType(message.Properties.GetString(typeMapper.TypeIdFieldName));
|
||||
}
|
||||
|
||||
|
||||
private String UTF8ByteArrayToString(Byte[] characters)
|
||||
{
|
||||
UTF8Encoding encoding = new UTF8Encoding();
|
||||
|
||||
String constructedString = encoding.GetString(characters);
|
||||
|
||||
return (constructedString);
|
||||
}
|
||||
|
||||
|
||||
private Byte[] StringToUTF8ByteArray(String pXmlString)
|
||||
{
|
||||
UTF8Encoding encoding = new UTF8Encoding();
|
||||
|
||||
Byte[] byteArray = encoding.GetBytes(pXmlString);
|
||||
|
||||
return byteArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,8 +84,11 @@
|
||||
<Compile Include="Messaging\Nms\Listener\RecoveryTimeExceededException.cs" />
|
||||
<Compile Include="Messaging\Nms\Listener\SimpleMessageListenerContainer.cs" />
|
||||
<Compile Include="Messaging\Nms\Support\Converter\IMessageConverter.cs" />
|
||||
<Compile Include="Messaging\Nms\Support\Converter\ITypeMapper.cs" />
|
||||
<Compile Include="Messaging\Nms\Support\Converter\MessageConversionException.cs" />
|
||||
<Compile Include="Messaging\Nms\Support\Converter\SimpleMessageConverter.cs" />
|
||||
<Compile Include="Messaging\Nms\Support\Converter\TypeMapper.cs" />
|
||||
<Compile Include="Messaging\Nms\Support\Converter\XmlMessageConverter.cs" />
|
||||
<Compile Include="Messaging\Nms\Support\Destinations\DynamicDestinationResolver.cs" />
|
||||
<Compile Include="Messaging\Nms\Support\Destinations\IDestinationResolver.cs" />
|
||||
<Compile Include="Messaging\Nms\Support\Destinations\NmsDestinationAccessor.cs" />
|
||||
|
||||
Reference in New Issue
Block a user