using System;
|
using System.Collections.Generic;
|
using System.IO;
|
using System.Text;
|
using System.Text.RegularExpressions;
|
using System.Threading;
|
using System.Xml.Serialization;
|
|
namespace Top.Api.Parser
|
{
|
/// <summary>
|
/// TOP XML响应通用解释器。
|
/// </summary>
|
public class TopXmlParser<T> : ITopParser<T> where T : TopResponse
|
{
|
private static readonly Regex regex = new Regex("<(\\w+?)[ >]", RegexOptions.Compiled);
|
private static readonly ReaderWriterLock rwLock = new ReaderWriterLock();
|
private static readonly Dictionary<string, XmlSerializer> parsers = new Dictionary<string, XmlSerializer>();
|
|
#region ITopParser Members
|
|
public T Parse(string body, Type type)
|
{
|
return DoParse(body, type);
|
}
|
|
public T Parse(string body)
|
{
|
Type type = typeof(T);
|
return DoParse(body, type);
|
}
|
|
#endregion
|
|
private T DoParse(string body, Type type)
|
{
|
string rootTagName = GetRootElement(body);
|
|
string key = type.FullName;
|
if (Constants.ERROR_RESPONSE.Equals(rootTagName))
|
{
|
key += ("_" + Constants.ERROR_RESPONSE);
|
}
|
|
XmlSerializer serializer = null;
|
bool incl = false;
|
|
rwLock.AcquireReaderLock(50);
|
try
|
{
|
if (rwLock.IsReaderLockHeld)
|
{
|
incl = parsers.TryGetValue(key, out serializer);
|
}
|
}
|
finally
|
{
|
if (rwLock.IsReaderLockHeld)
|
{
|
rwLock.ReleaseReaderLock();
|
}
|
}
|
|
if (!incl || serializer == null)
|
{
|
XmlAttributes rootAttrs = new XmlAttributes();
|
rootAttrs.XmlRoot = new XmlRootAttribute(rootTagName);
|
|
XmlAttributeOverrides attrOvrs = new XmlAttributeOverrides();
|
attrOvrs.Add(type, rootAttrs);
|
|
serializer = new XmlSerializer(type, attrOvrs);
|
|
rwLock.AcquireWriterLock(50);
|
try
|
{
|
if (rwLock.IsWriterLockHeld)
|
{
|
parsers[key] = serializer;
|
}
|
}
|
finally
|
{
|
if (rwLock.IsWriterLockHeld)
|
{
|
rwLock.ReleaseWriterLock();
|
}
|
}
|
}
|
|
object obj = null;
|
using (System.IO.Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(body)))
|
{
|
obj = serializer.Deserialize(stream);
|
}
|
|
T rsp = (T)obj;
|
if (rsp != null)
|
{
|
rsp.Body = body;
|
}
|
return rsp;
|
}
|
|
/// <summary>
|
/// 获取XML响应的根节点名称
|
/// </summary>
|
private string GetRootElement(string body)
|
{
|
Match match = regex.Match(body);
|
if (match.Success)
|
{
|
return match.Groups[1].ToString();
|
}
|
else
|
{
|
throw new TopException("Invalid XML response format!");
|
}
|
}
|
}
|
}
|