PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Externals/log4net/Util/TypeConverters/ConverterRegistry.cs

http://netgore.googlecode.com/
C# | 289 lines | 120 code | 31 blank | 138 comment | 21 complexity | 527334a1fd31a074387907b3c11b8460 MD5 | raw file
Possible License(s): MIT
  1. #region Copyright & License
  2. //
  3. // Copyright 2001-2005 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.Linq;
  21. using System.Net;
  22. using System.Text;
  23. using log4net.Layout;
  24. namespace log4net.Util.TypeConverters
  25. {
  26. /// <summary>
  27. /// Register of type converters for specific types.
  28. /// </summary>
  29. /// <remarks>
  30. /// <para>
  31. /// Maintains a registry of type converters used to convert between
  32. /// types.
  33. /// </para>
  34. /// <para>
  35. /// Use the <see cref="AddConverter(Type, object)"/> and
  36. /// <see cref="AddConverter(Type, Type)"/> methods to register new converters.
  37. /// The <see cref="GetConvertTo"/> and <see cref="GetConvertFrom"/> methods
  38. /// lookup appropriate converters to use.
  39. /// </para>
  40. /// </remarks>
  41. /// <seealso cref="IConvertFrom"/>
  42. /// <seealso cref="IConvertTo"/>
  43. /// <author>Nicko Cadell</author>
  44. /// <author>Gert Driesen</author>
  45. public sealed class ConverterRegistry
  46. {
  47. #region Private Constructors
  48. /// <summary>
  49. /// Private constructor
  50. /// </summary>
  51. /// <remarks>
  52. /// Initializes a new instance of the <see cref="ConverterRegistry" /> class.
  53. /// </remarks>
  54. ConverterRegistry()
  55. {
  56. }
  57. #endregion Private Constructors
  58. #region Static Constructor
  59. /// <summary>
  60. /// Static constructor.
  61. /// </summary>
  62. /// <remarks>
  63. /// <para>
  64. /// This constructor defines the intrinsic type converters.
  65. /// </para>
  66. /// </remarks>
  67. static ConverterRegistry()
  68. {
  69. // Add predefined converters here
  70. AddConverter(typeof(bool), typeof(BooleanConverter));
  71. AddConverter(typeof(Encoding), typeof(EncodingConverter));
  72. AddConverter(typeof(Type), typeof(TypeConverter));
  73. AddConverter(typeof(PatternLayout), typeof(PatternLayoutConverter));
  74. AddConverter(typeof(PatternString), typeof(PatternStringConverter));
  75. AddConverter(typeof(IPAddress), typeof(IPAddressConverter));
  76. }
  77. #endregion Static Constructor
  78. #region Public Static Methods
  79. /// <summary>
  80. /// Adds a converter for a specific type.
  81. /// </summary>
  82. /// <param name="destinationType">The type being converted to.</param>
  83. /// <param name="converter">The type converter to use to convert to the destination type.</param>
  84. /// <remarks>
  85. /// <para>
  86. /// Adds a converter instance for a specific type.
  87. /// </para>
  88. /// </remarks>
  89. public static void AddConverter(Type destinationType, object converter)
  90. {
  91. if (destinationType != null && converter != null)
  92. {
  93. lock (s_type2converter)
  94. {
  95. s_type2converter[destinationType] = converter;
  96. }
  97. }
  98. }
  99. /// <summary>
  100. /// Adds a converter for a specific type.
  101. /// </summary>
  102. /// <param name="destinationType">The type being converted to.</param>
  103. /// <param name="converterType">The type of the type converter to use to convert to the destination type.</param>
  104. /// <remarks>
  105. /// <para>
  106. /// Adds a converter <see cref="Type"/> for a specific type.
  107. /// </para>
  108. /// </remarks>
  109. public static void AddConverter(Type destinationType, Type converterType)
  110. {
  111. AddConverter(destinationType, CreateConverterInstance(converterType));
  112. }
  113. /// <summary>
  114. /// Creates the instance of the type converter.
  115. /// </summary>
  116. /// <param name="converterType">The type of the type converter.</param>
  117. /// <returns>
  118. /// The type converter instance to use for type conversions or <c>null</c>
  119. /// if no type converter is found.
  120. /// </returns>
  121. /// <remarks>
  122. /// <para>
  123. /// The type specified for the type converter must implement
  124. /// the <see cref="IConvertFrom"/> or <see cref="IConvertTo"/> interfaces
  125. /// and must have a public default (no argument) constructor.
  126. /// </para>
  127. /// </remarks>
  128. static object CreateConverterInstance(Type converterType)
  129. {
  130. if (converterType == null)
  131. throw new ArgumentNullException("converterType",
  132. "CreateConverterInstance cannot create instance, converterType is null");
  133. // Check type is a converter
  134. if (typeof(IConvertFrom).IsAssignableFrom(converterType) || typeof(IConvertTo).IsAssignableFrom(converterType))
  135. {
  136. try
  137. {
  138. // Create the type converter
  139. return Activator.CreateInstance(converterType);
  140. }
  141. catch (Exception ex)
  142. {
  143. LogLog.Error(
  144. "ConverterRegistry: Cannot CreateConverterInstance of type [" + converterType.FullName +
  145. "], Exception in call to Activator.CreateInstance", ex);
  146. }
  147. }
  148. else
  149. {
  150. LogLog.Error("ConverterRegistry: Cannot CreateConverterInstance of type [" + converterType.FullName +
  151. "], type does not implement IConvertFrom or IConvertTo");
  152. }
  153. return null;
  154. }
  155. /// <summary>
  156. /// Gets the type converter to use to convert values to the destination type.
  157. /// </summary>
  158. /// <param name="destinationType">The type being converted to.</param>
  159. /// <returns>
  160. /// The type converter instance to use for type conversions or <c>null</c>
  161. /// if no type converter is found.
  162. /// </returns>
  163. /// <remarks>
  164. /// <para>
  165. /// Gets the type converter to use to convert values to the destination type.
  166. /// </para>
  167. /// </remarks>
  168. public static IConvertFrom GetConvertFrom(Type destinationType)
  169. {
  170. // TODO: Support inheriting type converters.
  171. // i.e. getting a type converter for a base of destinationType
  172. lock (s_type2converter)
  173. {
  174. // Lookup in the static registry
  175. var converter = s_type2converter[destinationType] as IConvertFrom;
  176. if (converter == null)
  177. {
  178. // Lookup using attributes
  179. converter = GetConverterFromAttribute(destinationType) as IConvertFrom;
  180. if (converter != null)
  181. {
  182. // Store in registry
  183. s_type2converter[destinationType] = converter;
  184. }
  185. }
  186. return converter;
  187. }
  188. }
  189. /// <summary>
  190. /// Gets the type converter to use to convert values to the destination type.
  191. /// </summary>
  192. /// <param name="sourceType">The type being converted from.</param>
  193. /// <param name="destinationType">The type being converted to.</param>
  194. /// <returns>
  195. /// The type converter instance to use for type conversions or <c>null</c>
  196. /// if no type converter is found.
  197. /// </returns>
  198. /// <remarks>
  199. /// <para>
  200. /// Gets the type converter to use to convert values to the destination type.
  201. /// </para>
  202. /// </remarks>
  203. public static IConvertTo GetConvertTo(Type sourceType, Type destinationType)
  204. {
  205. // TODO: Support inheriting type converters.
  206. // i.e. getting a type converter for a base of sourceType
  207. // TODO: Is destinationType required? We don't use it for anything.
  208. lock (s_type2converter)
  209. {
  210. // Lookup in the static registry
  211. var converter = s_type2converter[sourceType] as IConvertTo;
  212. if (converter == null)
  213. {
  214. // Lookup using attributes
  215. converter = GetConverterFromAttribute(sourceType) as IConvertTo;
  216. if (converter != null)
  217. {
  218. // Store in registry
  219. s_type2converter[sourceType] = converter;
  220. }
  221. }
  222. return converter;
  223. }
  224. }
  225. /// <summary>
  226. /// Lookups the type converter to use as specified by the attributes on the
  227. /// destination type.
  228. /// </summary>
  229. /// <param name="destinationType">The type being converted to.</param>
  230. /// <returns>
  231. /// The type converter instance to use for type conversions or <c>null</c>
  232. /// if no type converter is found.
  233. /// </returns>
  234. static object GetConverterFromAttribute(Type destinationType)
  235. {
  236. // Look for an attribute on the destination type
  237. var attributes = destinationType.GetCustomAttributes(typeof(TypeConverterAttribute), true);
  238. if (attributes != null && attributes.Length > 0)
  239. {
  240. var tcAttr = attributes[0] as TypeConverterAttribute;
  241. if (tcAttr != null)
  242. {
  243. var converterType = SystemInfo.GetTypeFromString(destinationType, tcAttr.ConverterTypeName, false, true);
  244. return CreateConverterInstance(converterType);
  245. }
  246. }
  247. // Not found converter using attributes
  248. return null;
  249. }
  250. #endregion Public Static Methods
  251. #region Private Static Fields
  252. /// <summary>
  253. /// Mapping from <see cref="Type" /> to type converter.
  254. /// </summary>
  255. static readonly Hashtable s_type2converter = new Hashtable();
  256. #endregion
  257. }
  258. }