#region Apache Notice /***************************************************************************** * $Header: $ * $Revision: $ * $Date: $ * * iBATIS.NET Data Mapper * Copyright (C) 2004 - Gilles Bayon * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ********************************************************************************/ #endregion #region Using using System; using System.Collections.Specialized; using System.Reflection; using IBatisNet.Common.Logging; #endregion namespace IBatisNet.DataMapper.TypeHandlers { /// /// Not much of a suprise, this is a factory class for TypeHandler objects. /// public class TypeHandlerFactory { #region Fields private static readonly ILog _logger = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType ); private HybridDictionary _typeHandlerMap = new HybridDictionary(); private ITypeHandler _unknownTypeHandler = null; private const string NULL = "_NULL_TYPE_"; #endregion #region Constructor /// /// Constructor /// public TypeHandlerFactory() { ITypeHandler handler = null; handler = new BooleanTypeHandler(); this.Register(typeof(bool), handler); // key= "System.Boolean" handler = new ByteTypeHandler(); this.Register(typeof(Byte), handler); handler = new CharTypeHandler(); this.Register(typeof(Char), handler); handler = new DateTimeTypeHandler(); this.Register(typeof(DateTime), handler); handler = new DecimalTypeHandler(); this.Register(typeof(Decimal), handler); handler = new DoubleTypeHandler(); this.Register(typeof(Double), handler); handler = new Int16TypeHandler(); this.Register(typeof(Int16), handler); handler = new Int32TypeHandler(); this.Register(typeof(Int32), handler); handler = new Int64TypeHandler(); this.Register(typeof(Int64), handler); handler = new SingleTypeHandler(); this.Register(typeof(Single), handler); handler = new StringTypeHandler(); this.Register(typeof(String), handler); handler = new GuidTypeHandler(); this.Register(typeof(Guid), handler); handler = new TimeSpanTypeHandler(); this.Register(typeof(TimeSpan), handler); handler = new ByteArrayTypeHandler(); this.Register(typeof(Byte[]), handler); handler = new ObjectTypeHandler(); this.Register(typeof(object), handler); handler = new EnumTypeHandler(); this.Register( typeof(System.Enum), handler); _unknownTypeHandler = new UnknownTypeHandler(this); } #endregion #region Methods /// /// Get a TypeHandler for a Type /// /// the Type you want a TypeHandler for /// the handler public ITypeHandler GetTypeHandler(Type type) { return GetTypeHandler(type, null); } /// /// Get a TypeHandler for a type /// /// the type you want a TypeHandler for /// the database type /// the handler public ITypeHandler GetTypeHandler(Type type, string dbType) { if (type.IsEnum) { return this.GetPrivateTypeHandler(typeof(System.Enum), dbType); } else { return this.GetPrivateTypeHandler(type, dbType); } } /// /// Get a TypeHandler for a type and a dbType type /// /// the type /// the dbType type /// the handler private ITypeHandler GetPrivateTypeHandler(Type type, string dbType) { HybridDictionary dbTypeHandlerMap = (HybridDictionary) _typeHandlerMap[ type ]; ITypeHandler handler = null; if (dbTypeHandlerMap != null) { if (dbType==null) { handler = (ITypeHandler) dbTypeHandlerMap[ NULL ]; } else { handler = (ITypeHandler) dbTypeHandlerMap[ dbType ]; if (handler == null) { handler = (ITypeHandler) dbTypeHandlerMap[ NULL ]; } } } return handler; } /// /// Register (add) a type handler for a type /// /// the type /// the handler instance public void Register(Type type, ITypeHandler handler) { this.Register(type, null, handler); } /// /// Register (add) a type handler for a type and dbType /// /// the type /// the dbType (optional, if dbType is null the handler will be used for all dbTypes) /// the handler instance public void Register(Type type, string dbType, ITypeHandler handler) { HybridDictionary map = (HybridDictionary) _typeHandlerMap[ type ]; if (map == null) { map = new HybridDictionary(); _typeHandlerMap.Add(type, map) ; } if (dbType==null) { if (_logger.IsInfoEnabled) { // notify the user that they are no longer using one of the built-in type handlers ITypeHandler oldTypeHandler = (ITypeHandler)map[NULL]; if (oldTypeHandler != null) { // the replacement will always(?) be a CustomTypeHandler CustomTypeHandler customTypeHandler = handler as CustomTypeHandler; string replacement = string.Empty; if (customTypeHandler != null) { // report the underlying type replacement = customTypeHandler.Callback.ToString(); } else { replacement = handler.ToString(); } // should oldTypeHandler be checked if its a CustomTypeHandler and if so report the Callback property ??? _logger.Info("Replacing type handler [" + oldTypeHandler.ToString() + "] with [" + replacement + "]."); } } map[NULL] = handler; } else { map.Add(dbType, handler); } } /// /// When in doubt, get the "unknown" type handler /// /// if I told you, it would not be unknown, would it? public ITypeHandler GetUnkownTypeHandler() { return _unknownTypeHandler; } /// /// /// /// /// public bool IsSimpleType(Type type) { bool result = false; if (type != null) { ITypeHandler handler = this.GetTypeHandler(type, null); if (handler != null) { result = handler.IsSimpleType; } } return result; } #endregion } }