| using FastJSON; | 
| using System; | 
| using System.Collections; | 
| using System.Collections.Generic; | 
| using System.Reflection; | 
| using System.Threading; | 
| using System.Xml.Serialization; | 
|   | 
| namespace Top.Api.Parser | 
| { | 
|     /// <summary> | 
|     /// TOP JSON响应通用解释器。 | 
|     /// </summary> | 
|     public class DingTalkJsonParser<T> : ITopParser<T> where T : TopResponse | 
|     { | 
|         private static readonly ReaderWriterLock rwLock = new ReaderWriterLock(); | 
|         private static readonly Dictionary<string, Dictionary<string, TopAttribute>> attrs = new Dictionary<string, Dictionary<string, TopAttribute>>(); | 
|   | 
|         #region ITopParser Members | 
|   | 
|         public virtual T Parse(string body) | 
|         { | 
|             return Parse(body, typeof(T)); | 
|         } | 
|   | 
|         public T Parse(string body, Type type) | 
|         { | 
|             T rsp = null; | 
|   | 
|             IDictionary json = JSON.Parse(body) as IDictionary; | 
|             if (json != null) | 
|             { | 
|                 IDictionary data = json; | 
|   | 
|                 if (data != null) | 
|                 { | 
|                     ITopReader reader = new TopSimplifyJsonReader(data); | 
|                     rsp = (T)FromJson(reader, type); | 
|                 } | 
|             } | 
|   | 
|             if (rsp == null) | 
|             { | 
|                 rsp = Activator.CreateInstance(type) as T; | 
|             } | 
|   | 
|             if (rsp != null) | 
|             { | 
|                 rsp.Body = body; | 
|             } | 
|   | 
|             return rsp; | 
|         } | 
|   | 
|         #endregion | 
|   | 
|         private Dictionary<string, TopAttribute> GetTopAttributes(Type type) | 
|         { | 
|             Dictionary<string, TopAttribute> tas = null; | 
|             bool inc = false; | 
|   | 
|             rwLock.AcquireReaderLock(50); | 
|             try | 
|             { | 
|                 if (rwLock.IsReaderLockHeld) | 
|                 { | 
|                     inc = attrs.TryGetValue(type.FullName, out tas); | 
|                 } | 
|             } | 
|             finally | 
|             { | 
|                 if (rwLock.IsReaderLockHeld) | 
|                 { | 
|                     rwLock.ReleaseReaderLock(); | 
|                 } | 
|             } | 
|   | 
|             if (inc && tas != null) // 从缓存中获取类属性元数据 | 
|             { | 
|                 return tas; | 
|             } | 
|             else // 创建新的类属性元数据缓存 | 
|             { | 
|                 tas = new Dictionary<string, TopAttribute>(); | 
|             } | 
|   | 
|             PropertyInfo[] pis = type.GetProperties(); | 
|             foreach (PropertyInfo pi in pis) | 
|             { | 
|                 TopAttribute ta = new TopAttribute(); | 
|                 ta.Method = pi.GetSetMethod(); | 
|   | 
|                 // 获取对象属性名称 | 
|                 XmlElementAttribute[] xeas = pi.GetCustomAttributes(typeof(XmlElementAttribute), true) as XmlElementAttribute[]; | 
|                 if (xeas != null && xeas.Length > 0) | 
|                 { | 
|                     ta.ItemName = xeas[0].ElementName; | 
|                 } | 
|   | 
|                 // 获取列表属性名称 | 
|                 if (ta.ItemName == null) | 
|                 { | 
|                     XmlArrayItemAttribute[] xaias = pi.GetCustomAttributes(typeof(XmlArrayItemAttribute), true) as XmlArrayItemAttribute[]; | 
|                     if (xaias != null && xaias.Length > 0) | 
|                     { | 
|                         ta.ItemName = xaias[0].ElementName; | 
|                     } | 
|                     XmlArrayAttribute[] xaas = pi.GetCustomAttributes(typeof(XmlArrayAttribute), true) as XmlArrayAttribute[]; | 
|                     if (xaas != null && xaas.Length > 0) | 
|                     { | 
|                         ta.ListName = xaas[0].ElementName; | 
|                     } | 
|                     if (ta.ListName == null) | 
|                     { | 
|                         continue; | 
|                     } | 
|                 } | 
|   | 
|                 // 获取属性类型 | 
|                 if (pi.PropertyType.IsGenericType) | 
|                 { | 
|                     Type[] types = pi.PropertyType.GetGenericArguments(); | 
|                     ta.ListType = types[0]; | 
|                 } | 
|                 else | 
|                 { | 
|                     ta.ItemType = pi.PropertyType; | 
|                 } | 
|   | 
|                 tas.Add(pi.Name, ta); | 
|             } | 
|   | 
|             rwLock.AcquireWriterLock(50); | 
|             try | 
|             { | 
|                 if (rwLock.IsWriterLockHeld) | 
|                 { | 
|                     attrs[type.FullName] = tas; | 
|                 } | 
|             } | 
|             finally | 
|             { | 
|                 if (rwLock.IsWriterLockHeld) | 
|                 { | 
|                     rwLock.ReleaseWriterLock(); | 
|                 } | 
|             } | 
|             return tas; | 
|         } | 
|   | 
|         public object FromJson(ITopReader reader, Type type) | 
|         { | 
|             object rsp = null; | 
|             Dictionary<string, TopAttribute> pas = GetTopAttributes(type); | 
|   | 
|             Dictionary<string, TopAttribute>.Enumerator em = pas.GetEnumerator(); | 
|             while (em.MoveNext()) | 
|             { | 
|                 KeyValuePair<string, TopAttribute> kvp = em.Current; | 
|                 TopAttribute ta = kvp.Value; | 
|                 string itemName = ta.ItemName; | 
|                 string listName = ta.ListName; | 
|   | 
|                 if (!reader.HasReturnField(itemName) && (string.IsNullOrEmpty(listName) || !reader.HasReturnField(listName))) | 
|                 { | 
|                     continue; | 
|                 } | 
|   | 
|                 object value = null; | 
|                 if (ta.ListType != null) | 
|                 { | 
|                     value = reader.GetListObjects(listName, itemName, ta.ListType, FromJson); | 
|                 } | 
|                 else | 
|                 { | 
|                     if (typeof(string) == ta.ItemType) | 
|                     { | 
|                         object tmp = reader.GetPrimitiveObject(itemName); | 
|                         if (typeof(string) == tmp.GetType()) | 
|                         { | 
|                             value = tmp; | 
|                         } | 
|                         else | 
|                         { | 
|                             if (tmp != null) | 
|                             { | 
|                                 value = JSON.ToJSON(tmp); | 
|                             } | 
|                         } | 
|                     } | 
|                     else if (typeof(long) == ta.ItemType) | 
|                     { | 
|                         object tmp = reader.GetPrimitiveObject(itemName); | 
|                         if (typeof(long) == tmp.GetType()) | 
|                         { | 
|                             value = tmp; | 
|                         } | 
|                         else | 
|                         { | 
|                             if (tmp != null) | 
|                             { | 
|                                 value = long.Parse(tmp.ToString()); | 
|                             } | 
|                         } | 
|                     } | 
|                     else if (typeof(bool) == ta.ItemType) | 
|                     { | 
|                         object tmp = reader.GetPrimitiveObject(itemName); | 
|                         if (typeof(bool) == tmp.GetType()) | 
|                         { | 
|                             value = tmp; | 
|                         } | 
|                         else | 
|                         { | 
|                             if (tmp != null) | 
|                             { | 
|                                 value = bool.Parse(tmp.ToString()); | 
|                             } | 
|                         } | 
|                     } | 
|                     else | 
|                     { | 
|                         value = reader.GetReferenceObject(itemName, ta.ItemType, FromJson); | 
|                     } | 
|                 } | 
|   | 
|                 if (value != null) | 
|                 { | 
|                     if (rsp == null) | 
|                     { | 
|                         rsp = Activator.CreateInstance(type); | 
|                     } | 
|                     ta.Method.Invoke(rsp, new object[] { value }); | 
|                 } | 
|             } | 
|   | 
|             return rsp; | 
|         } | 
|     } | 
| } |