PageRenderTime 22ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/Externals/log4net/ObjectRenderer/DefaultRenderer.cs

http://netgore.googlecode.com/
C# | 294 lines | 104 code | 23 blank | 167 comment | 26 complexity | 85d67f91c275a8ca997124d07a9ca81d MD5 | raw file
Possible License(s): MIT
  1. #region Copyright & License
  2. //
  3. // Copyright 2001-2006 The Apache Software Foundation
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. #endregion
  18. using System;
  19. using System.Collections;
  20. using System.IO;
  21. using System.Linq;
  22. using log4net.Util;
  23. namespace log4net.ObjectRenderer
  24. {
  25. /// <summary>
  26. /// The default object Renderer.
  27. /// </summary>
  28. /// <remarks>
  29. /// <para>
  30. /// The default renderer supports rendering objects and collections to strings.
  31. /// </para>
  32. /// <para>
  33. /// See the <see cref="RenderObject"/> method for details of the output.
  34. /// </para>
  35. /// </remarks>
  36. /// <author>Nicko Cadell</author>
  37. /// <author>Gert Driesen</author>
  38. public sealed class DefaultRenderer : IObjectRenderer
  39. {
  40. #region Constructors
  41. #endregion
  42. #region Implementation of IObjectRenderer
  43. /// <summary>
  44. /// Render the object <paramref name="obj"/> to a string
  45. /// </summary>
  46. /// <param name="rendererMap">The map used to lookup renderers</param>
  47. /// <param name="obj">The object to render</param>
  48. /// <param name="writer">The writer to render to</param>
  49. /// <remarks>
  50. /// <para>
  51. /// Render the object <paramref name="obj"/> to a string.
  52. /// </para>
  53. /// <para>
  54. /// The <paramref name="rendererMap"/> parameter is
  55. /// provided to lookup and render other objects. This is
  56. /// very useful where <paramref name="obj"/> contains
  57. /// nested objects of unknown type. The <see cref="RendererMap.FindAndRender(object)"/>
  58. /// method can be used to render these objects.
  59. /// </para>
  60. /// <para>
  61. /// The default renderer supports rendering objects to strings as follows:
  62. /// </para>
  63. /// <list type="table">
  64. /// <listheader>
  65. /// <term>Value</term>
  66. /// <description>Rendered String</description>
  67. /// </listheader>
  68. /// <item>
  69. /// <term><c>null</c></term>
  70. /// <description>
  71. /// <para>"(null)"</para>
  72. /// </description>
  73. /// </item>
  74. /// <item>
  75. /// <term><see cref="Array"/></term>
  76. /// <description>
  77. /// <para>
  78. /// For a one dimensional array this is the
  79. /// array type name, an open brace, followed by a comma
  80. /// separated list of the elements (using the appropriate
  81. /// renderer), followed by a close brace.
  82. /// </para>
  83. /// <para>
  84. /// For example: <c>int[] {1, 2, 3}</c>.
  85. /// </para>
  86. /// <para>
  87. /// If the array is not one dimensional the
  88. /// <c>Array.ToString()</c> is returned.
  89. /// </para>
  90. /// </description>
  91. /// </item>
  92. /// <item>
  93. /// <term><see cref="IEnumerable"/>, <see cref="ICollection"/> &amp; <see cref="IEnumerator"/></term>
  94. /// <description>
  95. /// <para>
  96. /// Rendered as an open brace, followed by a comma
  97. /// separated list of the elements (using the appropriate
  98. /// renderer), followed by a close brace.
  99. /// </para>
  100. /// <para>
  101. /// For example: <c>{a, b, c}</c>.
  102. /// </para>
  103. /// <para>
  104. /// All collection classes that implement <see cref="ICollection"/> its subclasses,
  105. /// or generic equivalents all implement the <see cref="IEnumerable"/> interface.
  106. /// </para>
  107. /// </description>
  108. /// </item>
  109. /// <item>
  110. /// <term><see cref="DictionaryEntry"/></term>
  111. /// <description>
  112. /// <para>
  113. /// Rendered as the key, an equals sign ('='), and the value (using the appropriate
  114. /// renderer).
  115. /// </para>
  116. /// <para>
  117. /// For example: <c>key=value</c>.
  118. /// </para>
  119. /// </description>
  120. /// </item>
  121. /// <item>
  122. /// <term>other</term>
  123. /// <description>
  124. /// <para><c>Object.ToString()</c></para>
  125. /// </description>
  126. /// </item>
  127. /// </list>
  128. /// </remarks>
  129. public void RenderObject(RendererMap rendererMap, object obj, TextWriter writer)
  130. {
  131. if (rendererMap == null)
  132. throw new ArgumentNullException("rendererMap");
  133. if (obj == null)
  134. {
  135. writer.Write(SystemInfo.NullText);
  136. return;
  137. }
  138. var objArray = obj as Array;
  139. if (objArray != null)
  140. {
  141. RenderArray(rendererMap, objArray, writer);
  142. return;
  143. }
  144. // Test if we are dealing with some form of collection object
  145. var objEnumerable = obj as IEnumerable;
  146. if (objEnumerable != null)
  147. {
  148. // Get a collection interface if we can as its .Count property may be more
  149. // performant than getting the IEnumerator object and trying to advance it.
  150. var objCollection = obj as ICollection;
  151. if (objCollection != null && objCollection.Count == 0)
  152. {
  153. writer.Write("{}");
  154. return;
  155. }
  156. // This is a special check to allow us to get the enumerator from the IDictionary
  157. // interface as this guarantees us DictionaryEntry objects. Note that in .NET 2.0
  158. // the generic IDictionary<> interface enumerates KeyValuePair objects rather than
  159. // DictionaryEntry ones. However the implementation of the plain IDictionary
  160. // interface on the generic Dictionary<> still returns DictionaryEntry objects.
  161. var objDictionary = obj as IDictionary;
  162. if (objDictionary != null)
  163. {
  164. RenderEnumerator(rendererMap, objDictionary.GetEnumerator(), writer);
  165. return;
  166. }
  167. RenderEnumerator(rendererMap, objEnumerable.GetEnumerator(), writer);
  168. return;
  169. }
  170. var objEnumerator = obj as IEnumerator;
  171. if (objEnumerator != null)
  172. {
  173. RenderEnumerator(rendererMap, objEnumerator, writer);
  174. return;
  175. }
  176. if (obj is DictionaryEntry)
  177. {
  178. RenderDictionaryEntry(rendererMap, (DictionaryEntry)obj, writer);
  179. return;
  180. }
  181. var str = obj.ToString();
  182. writer.Write((str == null) ? SystemInfo.NullText : str);
  183. }
  184. #endregion
  185. /// <summary>
  186. /// Render the array argument into a string
  187. /// </summary>
  188. /// <param name="rendererMap">The map used to lookup renderers</param>
  189. /// <param name="array">the array to render</param>
  190. /// <param name="writer">The writer to render to</param>
  191. /// <remarks>
  192. /// <para>
  193. /// For a one dimensional array this is the
  194. /// array type name, an open brace, followed by a comma
  195. /// separated list of the elements (using the appropriate
  196. /// renderer), followed by a close brace. For example:
  197. /// <c>int[] {1, 2, 3}</c>.
  198. /// </para>
  199. /// <para>
  200. /// If the array is not one dimensional the
  201. /// <c>Array.ToString()</c> is returned.
  202. /// </para>
  203. /// </remarks>
  204. void RenderArray(RendererMap rendererMap, Array array, TextWriter writer)
  205. {
  206. if (array.Rank != 1)
  207. writer.Write(array.ToString());
  208. else
  209. {
  210. writer.Write(array.GetType().Name + " {");
  211. var len = array.Length;
  212. if (len > 0)
  213. {
  214. rendererMap.FindAndRender(array.GetValue(0), writer);
  215. for (var i = 1; i < len; i++)
  216. {
  217. writer.Write(", ");
  218. rendererMap.FindAndRender(array.GetValue(i), writer);
  219. }
  220. }
  221. writer.Write("}");
  222. }
  223. }
  224. /// <summary>
  225. /// Render the DictionaryEntry argument into a string
  226. /// </summary>
  227. /// <param name="rendererMap">The map used to lookup renderers</param>
  228. /// <param name="entry">the DictionaryEntry to render</param>
  229. /// <param name="writer">The writer to render to</param>
  230. /// <remarks>
  231. /// <para>
  232. /// Render the key, an equals sign ('='), and the value (using the appropriate
  233. /// renderer). For example: <c>key=value</c>.
  234. /// </para>
  235. /// </remarks>
  236. void RenderDictionaryEntry(RendererMap rendererMap, DictionaryEntry entry, TextWriter writer)
  237. {
  238. rendererMap.FindAndRender(entry.Key, writer);
  239. writer.Write("=");
  240. rendererMap.FindAndRender(entry.Value, writer);
  241. }
  242. /// <summary>
  243. /// Render the enumerator argument into a string
  244. /// </summary>
  245. /// <param name="rendererMap">The map used to lookup renderers</param>
  246. /// <param name="enumerator">the enumerator to render</param>
  247. /// <param name="writer">The writer to render to</param>
  248. /// <remarks>
  249. /// <para>
  250. /// Rendered as an open brace, followed by a comma
  251. /// separated list of the elements (using the appropriate
  252. /// renderer), followed by a close brace. For example:
  253. /// <c>{a, b, c}</c>.
  254. /// </para>
  255. /// </remarks>
  256. void RenderEnumerator(RendererMap rendererMap, IEnumerator enumerator, TextWriter writer)
  257. {
  258. writer.Write("{");
  259. if (enumerator != null && enumerator.MoveNext())
  260. {
  261. rendererMap.FindAndRender(enumerator.Current, writer);
  262. while (enumerator.MoveNext())
  263. {
  264. writer.Write(", ");
  265. rendererMap.FindAndRender(enumerator.Current, writer);
  266. }
  267. }
  268. writer.Write("}");
  269. }
  270. }
  271. }