ResultMap.cs :  » Persistence-Frameworks » iBATIS.NET » IBatisNet » DataMapper » Configuration » ResultMapping » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Persistence Frameworks » iBATIS.NET 
iBATIS.NET » IBatisNet » DataMapper » Configuration » ResultMapping » ResultMap.cs

#region Apache Notice
/*****************************************************************************
 * $Revision: 638539 $
 * $LastChangedDate: 2008-03-18 20:53:02 +0100 (mar., 18 mars 2008) $
 * $LastChangedBy: gbayon $
 * 
 * iBATIS.NET Data Mapper
 * Copyright (C) 2006/2005 - The Apache Software Foundation
 *  
 * 
 * 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.Data;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;
using IBatisNet.Common.Exceptions;
using IBatisNet.Common.Utilities.Objects;
using IBatisNet.DataMapper.Configuration.Serializers;
using IBatisNet.DataMapper.DataExchange;
using IBatisNet.DataMapper.Exceptions;
using IBatisNet.DataMapper.Scope;
using IBatisNet.Common.Utilities;

#endregion

namespace IBatisNet.DataMapper.Configuration.ResultMapping{
  /// <summary>
    /// Main implementation of ResultMap interface
  /// </summary>
  [Serializable]
  [XmlRoot("resultMap", Namespace="http://ibatis.apache.org/mapping")]
  public class ResultMap : IResultMap
  {
    /// <summary>
    /// Token for xml path to argument constructor elements.
    /// </summary>
    public static BindingFlags ANY_VISIBILITY_INSTANCE = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

    /// <summary>
    /// Token for xml path to result elements.
    /// </summary>
    private const string XML_RESULT = "result";

    /// <summary>
    /// Token for xml path to result elements.
    /// </summary>
    private const string XML_CONSTRUCTOR_ARGUMENT = "constructor/argument";

    /// <summary>
    /// Token for xml path to discriminator elements.
    /// </summary>
    private const string XML_DISCRIMNATOR = "discriminator";

    /// <summary>
    /// Token for xml path to subMap elements.
    /// </summary>
    private const string XML_SUBMAP = "subMap";

        private static IResultMap _nullResultMap = null;

    #region Fields
        [NonSerialized]
        private bool _isInitalized = true;
    [NonSerialized]
    private string _id = string.Empty;
    [NonSerialized]
    private string _className = string.Empty;
    [NonSerialized]
    private string _extendMap = string.Empty;
    [NonSerialized]
    private Type _class = null;
        [NonSerialized]
        private StringCollection _groupByPropertyNames = new StringCollection();
      
    [NonSerialized]
    private ResultPropertyCollection _properties = new ResultPropertyCollection();
        [NonSerialized]
        private ResultPropertyCollection _groupByProperties = new ResultPropertyCollection();

    [NonSerialized]
    private ResultPropertyCollection _parameters = new ResultPropertyCollection();

    [NonSerialized]
    private Discriminator _discriminator = null;
    [NonSerialized]
    private string _sqlMapNameSpace = string.Empty;
    [NonSerialized]
    private IFactory _objectFactory = null;
    [NonSerialized]
    private DataExchangeFactory _dataExchangeFactory = null;
    [NonSerialized]
    private IDataExchange _dataExchange = null;
    #endregion

    #region Properties

        /// <summary>
        /// The GroupBy Properties.
        /// </summary>
        [XmlIgnore]
        public StringCollection GroupByPropertyNames
        {
            get { return _groupByPropertyNames; }
        }
      
        /// <summary>
        /// Gets or sets a value indicating whether this instance is initalized.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is initalized; otherwise, <c>false</c>.
        /// </value>
        public bool IsInitalized
        {
            get { return true; }
            set { _isInitalized = value; }
        }
      
    /// <summary>
    /// The discriminator used to choose the good SubMap
    /// </summary>
    [XmlIgnore]
    public Discriminator Discriminator
    {
      get { return _discriminator; }  
      set { _discriminator = value; }  
    }

    /// <summary>
    /// The collection of ResultProperty.
    /// </summary>
    [XmlIgnore]
    public ResultPropertyCollection Properties
    {
      get { return _properties; }
    }

        /// <summary>
        /// The GroupBy Properties.
        /// </summary>
        [XmlIgnore]
        public ResultPropertyCollection GroupByProperties
        {
            get { return _groupByProperties; }
        }

    /// <summary>
    /// The collection of constructor parameters.
    /// </summary>
    [XmlIgnore]
    public ResultPropertyCollection Parameters
    {
      get { return _parameters; }
    }

    /// <summary>
    /// Identifier used to identify the resultMap amongst the others.
    /// </summary>
    /// <example>GetProduct</example>
    [XmlAttribute("id")]
    public string Id
    {
      get { return _id; }
    }

    /// <summary>
    /// Extend ResultMap attribute
    /// </summary>
    [XmlAttribute("extends")]
    public string ExtendMap
    {
      get { return _extendMap; }
            set { _extendMap = value; }
    }

    /// <summary>
    /// The output type class of the resultMap.
    /// </summary>
    [XmlIgnore]
    public Type Class
    {
      get { return _class; }
    }


    /// <summary>
    /// Sets the IDataExchange
    /// </summary>
    [XmlIgnore]
    public IDataExchange DataExchange
    {
      set { _dataExchange = value; }
    }
    #endregion

    #region Constructor (s) / Destructor

        /// <summary>
        /// Initializes a new instance of the <see cref="ResultMap"/> class.
        /// </summary>
        /// <param name="configScope">The config scope.</param>
        /// <param name="className">The output class name of the resultMap.</param>
        /// <param name="extendMap">The extend result map bame.</param>
        /// <param name="id">Identifier used to identify the resultMap amongst the others.</param>
        /// <param name="groupBy">The groupBy properties</param>
        public ResultMap(ConfigurationScope configScope, string id, string className, string extendMap, string groupBy)
    {
            _nullResultMap = new NullResultMap();

            _dataExchangeFactory = configScope.DataExchangeFactory;
            _sqlMapNameSpace = configScope.SqlMapNamespace;
            if ((id == null) || (id.Length < 1))
            {
                 throw new ArgumentNullException("The id attribute is mandatory in a ResultMap tag.");
            }
            _id = configScope.ApplyNamespace(id);
            if ((className == null) || (className.Length < 1))
            {
                throw new ArgumentNullException("The class attribute is mandatory in the ResultMap tag id:"+_id);
            }
            _className = className;
            _extendMap = extendMap;
             if (groupBy != null && groupBy.Length>0)
             {
                 string[] groupByProperties = groupBy.Split(',');
                 for (int i = 0; i < groupByProperties.Length; i++)
                 {
                     string memberName = groupByProperties[i].Trim();
                     _groupByPropertyNames.Add(memberName);
                 }
             }
            
    }
    #endregion

    #region Methods

    #region Configuration
      
    /// <summary>
    /// Initialize the resultMap from an xmlNode..
    /// </summary>
    /// <param name="configScope"></param>
    public void Initialize( ConfigurationScope configScope )
    {
      try
      {
        _class = configScope.SqlMapper.TypeHandlerFactory.GetType(_className);
        _dataExchange = _dataExchangeFactory.GetDataExchangeForClass(_class);

        // Load the child node
        GetChildNode(configScope);

                 // Verify that that each groupBy element correspond to a class member
                 // of one of result property
                for (int i = 0; i < _groupByProperties.Count; i++)
                {
                    string memberName = GroupByPropertyNames[i];
                    if (!_properties.Contains(memberName))
                    {
                         throw new ConfigurationException(
                             string.Format(
                                 "Could not configure ResultMap named \"{0}\". Check the groupBy attribute. Cause: there's no result property named \"{1}\".",
                                 _id, memberName));
                    }
                }
            }
      catch(Exception e)
      {
        throw new ConfigurationException(
          string.Format("Could not configure ResultMap named \"{0}\", Cause: {1}", _id, e.Message)
          , e);
      }
    }

        /// <summary>
        /// Initializes the groupBy properties.
        /// </summary>
        public void InitializeGroupByProperties()
        {
            for (int i = 0; i < GroupByPropertyNames.Count; i++)
            {
                ResultProperty resultProperty = Properties.FindByPropertyName(this.GroupByPropertyNames[i]);
                this.GroupByProperties.Add(resultProperty);
            }
        }


    /// <summary>
    /// Get the result properties and the subMap properties.
    /// </summary>
    /// <param name="configScope"></param>
    private void GetChildNode(ConfigurationScope configScope)
    {
      ResultProperty mapping = null;
      SubMap subMap = null;

      #region Load the parameters constructor
      XmlNodeList nodeList = configScope.NodeContext.SelectNodes( DomSqlMapBuilder.ApplyMappingNamespacePrefix(XML_CONSTRUCTOR_ARGUMENT), configScope.XmlNamespaceManager);
      if (nodeList.Count>0)
      {
        Type[] parametersType= new Type[nodeList.Count];
        string[] parametersName = new string[nodeList.Count];
        for( int i =0; i<nodeList.Count; i++)
        {
          ArgumentProperty argumentMapping = ArgumentPropertyDeSerializer.Deserialize( nodeList[i], configScope );
          _parameters.Add( argumentMapping  );
          parametersName[i] = argumentMapping.ArgumentName;
        }
        ConstructorInfo constructorInfo = this.GetConstructor( _class, parametersName );
        for(int i=0;i<_parameters.Count;i++)
        {
          ArgumentProperty argumentMapping = (ArgumentProperty)_parameters[i];

          configScope.ErrorContext.MoreInfo = "initialize argument property : " + argumentMapping.ArgumentName;
          argumentMapping.Initialize( configScope, constructorInfo);
          parametersType[i] = argumentMapping.MemberType;
        }    
        // Init the object factory
        _objectFactory = configScope.SqlMapper.ObjectFactory.CreateFactory(_class, parametersType);
      }
      else
      {
        if (Type.GetTypeCode(_class) == TypeCode.Object)
        {
          _objectFactory = configScope.SqlMapper.ObjectFactory.CreateFactory(_class, Type.EmptyTypes);
        }
      }

      #endregion

      #region Load the Result Properties

      foreach ( XmlNode resultNode in configScope.NodeContext.SelectNodes( DomSqlMapBuilder.ApplyMappingNamespacePrefix(XML_RESULT), configScope.XmlNamespaceManager) )
      {
        mapping = ResultPropertyDeSerializer.Deserialize( resultNode, configScope );
          
        configScope.ErrorContext.MoreInfo = "initialize result property: "+mapping.PropertyName;

        mapping.Initialize( configScope, _class );

          _properties.Add( mapping  );
      }
      #endregion 

      #region Load the Discriminator Property

      XmlNode discriminatorNode = configScope.NodeContext.SelectSingleNode(DomSqlMapBuilder.ApplyMappingNamespacePrefix(XML_DISCRIMNATOR), configScope.XmlNamespaceManager);
      if (discriminatorNode != null)
      {
        configScope.ErrorContext.MoreInfo = "initialize discriminator";

        this.Discriminator = DiscriminatorDeSerializer.Deserialize(discriminatorNode, configScope); 
        this.Discriminator.SetMapping( configScope, _class );
      }
      #endregion 

      #region Load the SubMap Properties

      if (configScope.NodeContext.SelectNodes(DomSqlMapBuilder.ApplyMappingNamespacePrefix(XML_SUBMAP), configScope.XmlNamespaceManager).Count>0 && this.Discriminator==null)
      {
        throw new ConfigurationException("The discriminator is null, but somehow a subMap was reached.  This is a bug.");
      }
      foreach ( XmlNode resultNode in configScope.NodeContext.SelectNodes(DomSqlMapBuilder.ApplyMappingNamespacePrefix(XML_SUBMAP), configScope.XmlNamespaceManager) )
      {
        configScope.ErrorContext.MoreInfo = "initialize subMap";
        subMap = SubMapDeSerializer.Deserialize(resultNode, configScope);

        this.Discriminator.Add( subMap );
      }
      #endregion 
    }

        /// <summary>
        /// Sets the object factory.
        /// </summary>
        public void SetObjectFactory(ConfigurationScope configScope)
        {
            Type[] parametersType = new Type[_parameters.Count];
            for (int i = 0; i < _parameters.Count; i++)
            {
                ArgumentProperty argumentMapping = (ArgumentProperty)_parameters[i];
                parametersType[i] = argumentMapping.MemberType;
            }
            // Init the object factory
            _objectFactory = configScope.SqlMapper.ObjectFactory.CreateFactory(_class, parametersType);
        }

      /// <summary>
    /// Finds the constructor that takes the parameters.
    /// </summary>
    /// <param name="type">The <see cref="System.Type"/> to find the constructor in.</param> 
    /// <param name="parametersName">The parameters name to use to find the appropriate constructor.</param>
    /// <returns>
    /// An <see cref="ConstructorInfo"/> that can be used to create the type with 
    /// the specified parameters.
    /// </returns>
    /// <exception cref="DataMapperException">
    /// Thrown when no constructor with the correct signature can be found.
    /// </exception> 
    private ConstructorInfo GetConstructor(Type type, string[] parametersName )
    {
      ConstructorInfo[] candidates = type.GetConstructors(ANY_VISIBILITY_INSTANCE);
      foreach( ConstructorInfo constructor in candidates )
      {
        ParameterInfo[] parameters = constructor.GetParameters();

        if( parameters.Length == parametersName.Length )
        {
          bool found = true;

          for( int j = 0; j < parameters.Length; j++ )
          {
            bool ok = (parameters[ j ].Name == parametersName[ j ]);
            if( !ok )
            {
              found = false;
              break;
            }
          }

          if( found )
          {
            return constructor;
          }
        }
      }
      throw new DataMapperException( "Cannot find an appropriate constructor which map parameters in class: "+ type.Name );
    }

    #endregion

    /// <summary>
    /// Create an instance Of result.
    /// </summary>
    /// <param name="parameters">
    /// An array of values that matches the number, order and type 
    /// of the parameters for this constructor. 
    /// </param>
    /// <returns>An object.</returns>
    public object CreateInstanceOfResult(object[] parameters)
    {
      TypeCode typeCode = Type.GetTypeCode(_class);

      if (typeCode == TypeCode.Object)
      {
        return _objectFactory.CreateInstance(parameters);
      }
      else
      {
                return TypeUtils.InstantiatePrimitiveType(typeCode);
      }
    }

    /// <summary>
    /// Set the value of an object property.
    /// </summary>
    /// <param name="target">The object to set the property.</param>
    /// <param name="property">The result property to use.</param>
    /// <param name="dataBaseValue">The database value to set.</param>
    public void SetValueOfProperty( ref object target, ResultProperty property, object dataBaseValue )
    {
      _dataExchange.SetData(ref target, property, dataBaseValue);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="dataReader"></param>
    /// <returns></returns>
    public IResultMap ResolveSubMap(IDataReader dataReader)
    {
      IResultMap subMap = this;
      if (_discriminator != null)
      {  
        ResultProperty mapping = _discriminator.ResultProperty;
        object dataBaseValue = mapping.GetDataBaseValue( dataReader );

                if (dataBaseValue!=null)
                {
            subMap = _discriminator.GetSubMap( dataBaseValue.ToString() );

            if (subMap == null) 
            {
              subMap = this;
            } 
            else if (subMap != this) 
            {
              subMap = subMap.ResolveSubMap(dataReader);
            }                    
                }
                else
                {
                    subMap = _nullResultMap;
                }
      }
      return subMap;
    }

    
    #endregion
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.