1
#region Copyright & License
3
// Copyright 2001-2005 The Apache Software Foundation
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
9
// http://www.apache.org/licenses/LICENSE-2.0
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.
23
namespace log4net.ObjectRenderer
26
/// Map class objects to an <see cref="IObjectRenderer"/>.
30
/// Maintains a mapping between types that require special
31
/// rendering and the <see cref="IObjectRenderer"/> that
32
/// is used to render them.
35
/// The <see cref="FindAndRender(object)"/> method is used to render an
36
/// <c>object</c> using the appropriate renderers defined in this map.
39
/// <author>Nicko Cadell</author>
40
/// <author>Gert Driesen</author>
41
public class RendererMap
43
#region Member Variables
45
private System.Collections.Hashtable m_map;
46
private System.Collections.Hashtable m_cache = new System.Collections.Hashtable();
48
private static IObjectRenderer s_defaultRenderer = new DefaultRenderer();
55
/// Default Constructor
59
/// Default constructor.
64
m_map = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable());
70
/// Render <paramref name="obj"/> using the appropriate renderer.
72
/// <param name="obj">the object to render to a string</param>
73
/// <returns>the object rendered as a string</returns>
76
/// This is a convenience method used to render an object to a string.
77
/// The alternative method <see cref="FindAndRender(object,TextWriter)"/>
78
/// should be used when streaming output to a <see cref="TextWriter"/>.
81
public string FindAndRender(object obj)
83
// Optimisation for strings
84
string strData = obj as String;
90
StringWriter stringWriter = new StringWriter(System.Globalization.CultureInfo.InvariantCulture);
91
FindAndRender(obj, stringWriter);
92
return stringWriter.ToString();
96
/// Render <paramref name="obj"/> using the appropriate renderer.
98
/// <param name="obj">the object to render to a string</param>
99
/// <param name="writer">The writer to render to</param>
102
/// Find the appropriate renderer for the type of the
103
/// <paramref name="obj"/> parameter. This is accomplished by calling the
104
/// <see cref="Get(Type)"/> method. Once a renderer is found, it is
105
/// applied on the object <paramref name="obj"/> and the result is returned
106
/// as a <see cref="string"/>.
109
public void FindAndRender(object obj, TextWriter writer)
113
writer.Write(SystemInfo.NullText);
117
// Optimisation for strings
118
string str = obj as string;
125
// Lookup the renderer for the specific type
128
Get(obj.GetType()).RenderObject(this, obj, writer);
132
// Exception rendering the object
133
log4net.Util.LogLog.Error("RendererMap: Exception while rendering object of type ["+obj.GetType().FullName+"]", ex);
135
// return default message
136
string objectTypeName = "";
137
if (obj != null && obj.GetType() != null)
139
objectTypeName = obj.GetType().FullName;
142
writer.Write("<log4net.Error>Exception rendering object type ["+objectTypeName+"]");
145
string exceptionText = null;
149
exceptionText = ex.ToString();
156
writer.Write("<stackTrace>" + exceptionText + "</stackTrace>");
158
writer.Write("</log4net.Error>");
165
/// Gets the renderer for the specified object type
167
/// <param name="obj">the object to lookup the renderer for</param>
168
/// <returns>the renderer for <paramref name="obj"/></returns>
171
/// Gets the renderer for the specified object type.
174
/// Syntactic sugar method that calls <see cref="Get(Type)"/>
175
/// with the type of the object parameter.
178
public IObjectRenderer Get(Object obj)
186
return Get(obj.GetType());
191
/// Gets the renderer for the specified type
193
/// <param name="type">the type to lookup the renderer for</param>
194
/// <returns>the renderer for the specified type</returns>
197
/// Returns the renderer for the specified type.
198
/// If no specific renderer has been defined the
199
/// <see cref="DefaultRenderer"/> will be returned.
202
public IObjectRenderer Get(Type type)
206
throw new ArgumentNullException("type");
209
IObjectRenderer result = null;
212
result = (IObjectRenderer)m_cache[type];
216
for(Type cur = type; cur != null; cur = cur.BaseType)
218
// Search the type's interfaces
219
result = SearchTypeAndInterfaces(cur);
226
// if not set then use the default renderer
229
result = s_defaultRenderer;
233
m_cache[type] = result;
240
/// Internal function to recursively search interfaces
242
/// <param name="type">the type to lookup the renderer for</param>
243
/// <returns>the renderer for the specified type</returns>
244
private IObjectRenderer SearchTypeAndInterfaces(Type type)
246
IObjectRenderer r = (IObjectRenderer)m_map[type];
253
foreach(Type t in type.GetInterfaces())
255
r = SearchTypeAndInterfaces(t);
266
/// Get the default renderer instance
268
/// <value>the default renderer</value>
271
/// Get the default renderer
274
public IObjectRenderer DefaultRenderer
276
get { return s_defaultRenderer; }
280
/// Clear the map of renderers
284
/// Clear the custom renderers defined by using
285
/// <see cref="Put"/>. The <see cref="DefaultRenderer"/>
286
/// cannot be removed.
296
/// Register an <see cref="IObjectRenderer"/> for <paramref name="typeToRender"/>.
298
/// <param name="typeToRender">the type that will be rendered by <paramref name="renderer"/></param>
299
/// <param name="renderer">the renderer for <paramref name="typeToRender"/></param>
302
/// Register an object renderer for a specific source type.
303
/// This renderer will be returned from a call to <see cref="Get(Type)"/>
304
/// specifying the same <paramref name="typeToRender"/> as an argument.
307
public void Put(Type typeToRender, IObjectRenderer renderer)
311
if (typeToRender == null)
313
throw new ArgumentNullException("typeToRender");
315
if (renderer == null)
317
throw new ArgumentNullException("renderer");
320
m_map[typeToRender] = renderer;