Author: gbayon
Date: Sat Apr 29 02:39:42 2006
New Revision: 398108

URL: http://svn.apache.org/viewcvs?rev=398108&view=rev
Log:
- First iteration to fix IBATISNET-105 Lazy load support for Strong typed 
collections and single Items
Need more tests for 1:1 relationships

Added:
    ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/
    ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadInterceptor.cs
    ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadProxyFactory.cs
Modified:
    
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Proxy/CachedProxyGenerator.cs
    
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/LineItemCollection.cs
    ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/Order.cs
    
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/NUnit/SqlMapTests/CacheController/CacheModelTest.cs
    
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/bin/Debug/IBatisNet.DataMapper.Test.dll.config
    ibatis/trunk/cs/mapper/IBatisNet.DataMapper/IBatisNet.DataMapper.csproj
    
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/MappedStatement.cs

Modified: 
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Proxy/CachedProxyGenerator.cs
URL: 
http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Proxy/CachedProxyGenerator.cs?rev=398108&r1=398107&r2=398108&view=diff
==============================================================================
--- 
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Proxy/CachedProxyGenerator.cs 
(original)
+++ 
ibatis/trunk/cs/mapper/IBatisNet.Common/Utilities/Proxy/CachedProxyGenerator.cs 
Sat Apr 29 02:39:42 2006
@@ -63,7 +63,7 @@
                /// </summary>
                /// <param name="theInterface">Interface to be 
implemented</param>
                /// <param name="interceptor">instance of <see 
cref="IInterceptor"/></param>
-               /// <param name="target"></param>
+               /// <param name="target">The target object.</param>
                /// <returns>Proxy instance</returns>
                public override object CreateProxy(Type theInterface, 
IInterceptor interceptor, object target)
                {
@@ -76,7 +76,7 @@
                /// </summary>
                /// <param name="interfaces">Array of interfaces to be 
implemented</param>
                /// <param name="interceptor">instance of <see 
cref="IInterceptor"/></param>
-               /// <param name="target"></param>
+               /// <param name="target">The target object.</param>
                /// <returns>Proxy instance</returns>
                public override object CreateProxy(Type[] interfaces, 
IInterceptor interceptor, object target)
                {
@@ -102,10 +102,43 @@
                                _log.Error( "Castle Dynamic Proxy Generator 
failed", e );
                                throw new IBatisNetException( "Castle Proxy 
Generator failed", e );
                        }
+               }
 
 
-               }
+               
+               /// <summary>
+               /// Generates a proxy implementing all the specified interfaces 
and
+               /// redirecting method invocations to the specifed interceptor.
+               /// This proxy is for object different from IList or ICollection
+               /// </summary>
+               /// <param name="targetType">The target type</param>
+               /// <param name="interceptor">The interceptor.</param>
+               /// <param name="argumentsForConstructor">The arguments for 
constructor.</param>
+               /// <returns></returns>
+               public override object CreateClassProxy(Type targetType, 
IInterceptor interceptor, params object[] argumentsForConstructor)
+               {
+                       try
+                       {
+                               System.Type proxyType = null;
 
+                               lock( _cachedProxyTypes.SyncRoot )
+                               {
+                                       proxyType = _cachedProxyTypes[ 
targetType ] as System.Type;
 
+                                       if( proxyType == null )
+                                       {
+                                               proxyType = 
ProxyBuilder.CreateClassProxy(targetType);
+                                               _cachedProxyTypes[ targetType ] 
= proxyType;
+                                       }
+                               }
+                               return CreateClassProxyInstance( proxyType, 
interceptor, argumentsForConstructor ); 
+                       }
+                       catch( Exception e )
+                       {
+                               _log.Error( "Castle Dynamic Class-Proxy 
Generator failed", e );
+                               throw new IBatisNetException( "Castle Proxy 
Generator failed", e );
+                       }
+       
+               }
        }
 }

Modified: 
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/LineItemCollection.cs
URL: 
http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/LineItemCollection.cs?rev=398108&r1=398107&r2=398108&view=diff
==============================================================================
--- 
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/LineItemCollection.cs 
(original)
+++ 
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/LineItemCollection.cs 
Sat Apr 29 02:39:42 2006
@@ -4,23 +4,27 @@
 
 namespace IBatisNet.DataMapper.Test.Domain 
 {
+       /// <summary>
+       /// In order to make this class strongly-proxified you have to mark 
virtual 
+       /// each property/method you want be proxified.
+       /// </summary>
        [Serializable]
        public class LineItemCollection : CollectionBase 
        {
                public LineItemCollection() {}
 
-               public LineItem this[int index] 
+               public virtual LineItem this[int index] 
                {
                        get     { return (LineItem)List[index]; }
                        set { List[index] = value; }
                }
 
-               public int Add(LineItem value) 
+               public virtual int Add(LineItem value) 
                {
                        return List.Add(value);
                }
 
-               public void AddRange(LineItem[] value) 
+               public virtual void AddRange(LineItem[] value) 
                {
                        for (int i = 0; i < value.Length; i++) 
                        {
@@ -28,7 +32,7 @@
                        }
                }
 
-               public void AddRange(LineItemCollection value) 
+               public virtual void AddRange(LineItemCollection value) 
                {
                        for (int i = 0; i < value.Count; i++) 
                        {
@@ -36,29 +40,34 @@
                        }
                }
 
-               public bool Contains(LineItem value) 
+               public virtual bool Contains(LineItem value) 
                {
                        return List.Contains(value);
                }
 
-               public void CopyTo(LineItem[] array, int index) 
+               public virtual void CopyTo(LineItem[] array, int index) 
                {
                        List.CopyTo(array, index);
                }
 
-               public int IndexOf(LineItem value) 
+               public virtual int IndexOf(LineItem value) 
                {
                        return List.IndexOf(value);
                }
                
-               public void Insert(int index, LineItem value) 
+               public virtual void Insert(int index, LineItem value) 
                {
                        List.Insert(index, value);
                }
                
-               public void Remove(LineItem value) 
+               public virtual void Remove(LineItem value) 
                {
                        List.Remove(value);
+               }
+
+               public new virtual int Count
+               {
+                       get {return this.List.Count;}
                }
        }
 }

Modified: ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/Order.cs
URL: 
http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/Order.cs?rev=398108&r1=398107&r2=398108&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/Order.cs (original)
+++ ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/Domain/Order.cs Sat Apr 29 
02:39:42 2006
@@ -23,7 +23,7 @@
                private string _province;
                private string _postalCode;
                private IList _lineItemsIList;
-               private IList _lineItems;//LineItemCollection
+               private LineItemCollection _lineItems;//LineItemCollection
                private LineItem[] _lineItemsArray;
                private LineItem _favouriteLineItem;
 
@@ -121,7 +121,7 @@
                }
 
 
-               public IList LineItems
+               public LineItemCollection LineItems
                {
                        get { return _lineItems; }
                        set { _lineItems = value; }

Modified: 
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/NUnit/SqlMapTests/CacheController/CacheModelTest.cs
URL: 
http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/NUnit/SqlMapTests/CacheController/CacheModelTest.cs?rev=398108&r1=398107&r2=398108&view=diff
==============================================================================
--- 
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/NUnit/SqlMapTests/CacheController/CacheModelTest.cs
 (original)
+++ 
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/NUnit/SqlMapTests/CacheController/CacheModelTest.cs
 Sat Apr 29 02:39:42 2006
@@ -40,7 +40,7 @@
                        Order order = new Order(); 
                        order.CardNumber = "CardNumber";
                        order.Date = DateTime.Now;
-                       order.LineItems = new ArrayList();
+                       order.LineItems = new LineItemCollection();
                        LineItem item = new LineItem();
                        item.Code = "Code1";
                        order.LineItems.Add( item );
@@ -83,7 +83,7 @@
                        Order order = new Order(); 
                        order.CardNumber = "CardNumber";
                        order.Date = DateTime.Now;
-                       order.LineItems = new ArrayList();
+                       order.LineItems = new LineItemCollection();
                        LineItem item = new LineItem();
                        item.Code = "Code1";
                        order.LineItems.Add( item );

Modified: 
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/bin/Debug/IBatisNet.DataMapper.Test.dll.config
URL: 
http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/bin/Debug/IBatisNet.DataMapper.Test.dll.config?rev=398108&r1=398107&r2=398108&view=diff
==============================================================================
--- 
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/bin/Debug/IBatisNet.DataMapper.Test.dll.config
 (original)
+++ 
ibatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/bin/Debug/IBatisNet.DataMapper.Test.dll.config
 Sat Apr 29 02:39:42 2006
@@ -37,12 +37,12 @@
                                <arg key="dateTimeFormat" value="yyyy/MM/dd 
HH:mm:ss:SSS" />
                        </logFactoryAdapter>    -->
 
-<!--       <logFactoryAdapter 
type="IBatisNet.Common.Logging.Impl.Log4NetLoggerFA, 
IBatisNet.Common.Logging.Log4Net">
+       <logFactoryAdapter type="IBatisNet.Common.Logging.Impl.Log4NetLoggerFA, 
IBatisNet.Common.Logging.Log4Net">
         <arg key="configType" value="inline" />
       </logFactoryAdapter>
--->
-      
+<!--      
      <logFactoryAdapter type="IBatisNet.Common.Logging.Impl.NoOpLoggerFA, 
IBatisNet.Common" />
+-->
       
                </logging>
        </iBATIS>
@@ -88,9 +88,12 @@
                <logger name="IBatisNet.DataMapper.Commands.IPreparedCommand">
                        <level value="OFF" />
                </logger>               
-               <logger name="IBatisNet.DataMapper.LazyLoadList">
+               <logger name="IBatisNet.DataMapper.LazyLoadInterceptor">
                        <level value="DEBUG" />
                </logger>
+               <logger name="IBatisNet.DataMapper.LazyLoadProxyFactory">
+                       <level value="DEBUG" />
+               </logger>               
                <logger name="IBatisNet.DataAccess.DaoSession">
                        <level value="DEBUG" />
                </logger>

Modified: 
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/IBatisNet.DataMapper.csproj
URL: 
http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.DataMapper/IBatisNet.DataMapper.csproj?rev=398108&r1=398107&r2=398108&view=diff
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.DataMapper/IBatisNet.DataMapper.csproj 
(original)
+++ ibatis/trunk/cs/mapper/IBatisNet.DataMapper/IBatisNet.DataMapper.csproj Sat 
Apr 29 02:39:42 2006
@@ -868,6 +868,16 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "Proxy\LazyLoadInterceptor.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Proxy\LazyLoadProxyFactory.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "Scope\ConfigurationScope.cs"
                     SubType = "Code"
                     BuildAction = "Compile"

Modified: 
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/MappedStatement.cs
URL: 
http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/MappedStatement.cs?rev=398108&r1=398107&r2=398108&view=diff
==============================================================================
--- 
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/MappedStatement.cs 
(original)
+++ 
ibatis/trunk/cs/mapper/IBatisNet.DataMapper/MappedStatements/MappedStatement.cs 
Sat Apr 29 02:39:42 2006
@@ -2,7 +2,7 @@
 #region Apache Notice
 /*****************************************************************************
  * $Header: $
- * $Revision$
+ * $Revision: 397590 $
  * $Date$
  * 
  * iBATIS.NET Data Mapper
@@ -34,18 +34,21 @@
 using System.Data;
 using System.Reflection;
 using System.Text;
+
 using IBatisNet.Common;
 using IBatisNet.Common.Logging;
 using IBatisNet.Common.Utilities.Objects;
+using IBatisNet.Common.Utilities.Objects.Members;
+
 using IBatisNet.DataMapper.Commands;
 using IBatisNet.DataMapper.Configuration.ParameterMapping;
 using IBatisNet.DataMapper.Configuration.ResultMapping;
 using IBatisNet.DataMapper.Configuration.Statements;
-using IBatisNet.DataMapper.Exceptions;
 using IBatisNet.DataMapper.Scope;
+using IBatisNet.DataMapper.Exceptions;
 using IBatisNet.DataMapper.TypeHandlers;
-using IBatisNet.Common.Utilities.Objects.Members;
 using IBatisNet.DataMapper.DataExchange;
+using IBatisNet.DataMapper.Proxy;
 
 #endregion
 
@@ -1328,6 +1331,10 @@
                                        
                     if (mapping.MemberAccessor.MemberType.BaseType == 
typeof(Array))
                                        {
+                                               if (mapping.IsLazyLoad)
+                                               {
+                                                       throw new 
NotImplementedException("Lazy load no supported for System.Array property:" + 
mapping.MemberAccessor.Name);
+                                               }
                                                postSelect.Method = 
ExecuteMethod.ExecuteQueryForArrayList;
                                        }
                                        // Check if the object to Map implement 
'IList' or is IList type
@@ -1336,7 +1343,7 @@
                                        {
                                                if (mapping.IsLazyLoad)
                                                {
-                                                       object values = 
LazyLoadList.NewInstance(queryStatement, keys, target, mapping.PropertyName);
+                                                       object values = 
LazyLoadProxyFactory.Build(queryStatement, keys, target, 
mapping.MemberAccessor);
                                                        
mapping.MemberAccessor.Set(target, values);
                                                }
                                                else
@@ -1357,7 +1364,7 @@
                     {
                         if (mapping.IsLazyLoad)
                         {
-                            object values = 
LazyLoadList.NewInstance(queryStatement, keys, target, mapping.PropertyName);
+                                                       object values = 
LazyLoadProxyFactory.Build(queryStatement, keys, target, 
mapping.MemberAccessor);
                                                        
mapping.MemberAccessor.Set(target, values);
                         }
                         else

Added: ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadInterceptor.cs
URL: 
http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadInterceptor.cs?rev=398108&view=auto
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadInterceptor.cs 
(added)
+++ ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadInterceptor.cs 
Sat Apr 29 02:39:42 2006
@@ -0,0 +1,136 @@
+
+#region Apache Notice
+/*****************************************************************************
+ * $Revision: 374175 $
+ * $LastChangedDate: 2006-03-22 22:39:21 +0100 (mer., 22 mars 2006) $
+ * $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;
+using System.Reflection;
+using Castle.DynamicProxy;
+using IBatisNet.Common.Logging;
+using IBatisNet.Common.Utilities.Objects;
+using IBatisNet.Common.Utilities.Objects.Members;
+using IBatisNet.Common.Utilities.Proxy;
+using IBatisNet.DataMapper.MappedStatements;
+#if dotnet2
+using System.Collections.Generic;
+#endif
+#endregion
+
+namespace IBatisNet.DataMapper.Proxy
+{
+       /// <summary>
+       /// Default implementation of the interceptor reponsible of load the 
lazy element
+       /// Could load collections and single objects
+       /// </summary>
+       [Serializable]
+       internal class LazyLoadInterceptor : IInterceptor
+       {
+               #region Fields
+               private object _param = null;
+               private object _target = null;
+               private IMemberAccessor _memberAccessor= null;
+               private SqlMapper _sqlMap = null;
+               private string _statementName = string.Empty;
+               private bool _loaded = false;
+               private IList _innerList = null;
+               private object _loadLock = new object();
+               private static ArrayList _passthroughMethods = new ArrayList();
+
+               private static readonly ILog _logger = LogManager.GetLogger( 
MethodBase.GetCurrentMethod().DeclaringType );
+               #endregion
+
+               #region  Constructor (s) / Destructor
+
+               /// <summary>
+               /// Static Constructor for a lazy list loader
+               /// </summary>
+               static LazyLoadInterceptor()
+               {
+                       _passthroughMethods.Add("GetType");
+                       _passthroughMethods.Add("ToString");
+               }
+
+               /// <summary>
+               /// Constructor for a lazy list loader
+               /// </summary>
+               /// <param name="mappedSatement">The mapped statement used to 
build the list</param>
+               /// <param name="param">The parameter object used to build the 
list</param>
+               /// <param name="memberAccessor">The proxified member 
accessor.</param>
+               /// <param name="target">The target object which contains the 
property proxydied.</param>
+               internal LazyLoadInterceptor(IMappedStatement mappedSatement, 
object param, 
+                       object target, IMemberAccessor memberAccessor)
+               {
+                       _param = param;
+                       _statementName = mappedSatement.Id;
+                       _sqlMap = mappedSatement.SqlMap;
+                       _target = target; 
+                       _memberAccessor = memberAccessor;
+               }               
+               #endregion
+
+               #region IInterceptor member
+
+               /// <summary>
+               /// Intercepts the specified invocation.
+               /// </summary>
+               /// <param name="invocation">The invocation.</param>
+               /// <param name="arguments">The target arguments.</param>
+               /// <returns></returns>
+               public object Intercept(IInvocation invocation, params object[] 
arguments)
+               {
+                       if (_logger.IsDebugEnabled) 
+                       {
+                               _logger.Debug("Proxyfying call to " + 
invocation.Method.Name);
+                       }
+
+                       lock(_loadLock)
+                       {
+                               if ((_loaded == false) && 
(!_passthroughMethods.Contains(invocation.Method.Name)))
+                               {
+                                       if (_logger.IsDebugEnabled) 
+                                       {
+                                               _logger.Debug("Proxyfying call, 
query statement " + _statementName);
+                                       }
+                                       _innerList = 
_sqlMap.QueryForList(_statementName, _param);
+                                       _loaded = true;
+                                       _memberAccessor.Set(_target, 
_innerList);
+                               }
+                       }
+
+                       object returnValue = invocation.Method.Invoke( 
_innerList, arguments);          
+
+                       if (_logger.IsDebugEnabled) 
+                       {
+                               _logger.Debug("End of proxyfied call to " + 
invocation.Method.Name);
+                       }
+
+                       return returnValue;
+               }
+
+               #endregion
+       }
+}

Added: ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadProxyFactory.cs
URL: 
http://svn.apache.org/viewcvs/ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadProxyFactory.cs?rev=398108&view=auto
==============================================================================
--- ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadProxyFactory.cs 
(added)
+++ ibatis/trunk/cs/mapper/IBatisNet.DataMapper/Proxy/LazyLoadProxyFactory.cs 
Sat Apr 29 02:39:42 2006
@@ -0,0 +1,200 @@
+#region Apache Notice
+/*****************************************************************************
+ * $Header: $
+ * $Revision: 391784 $
+ * $Date: 2006-04-05 22:23:27 +0200 (mer., 05 avr. 2006) $
+ * 
+ * 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
+
+using System;
+using System.Collections;
+using System.Reflection;
+using Castle.DynamicProxy;
+using IBatisNet.Common.Logging;
+using IBatisNet.Common.Utilities.Objects.Members;
+using IBatisNet.Common.Utilities.Proxy;
+using IBatisNet.DataMapper.Exceptions;
+using IBatisNet.DataMapper.MappedStatements;
+
+namespace IBatisNet.DataMapper.Proxy
+{
+       /// <summary>
+       /// This class is responsible of create all lazy load proxies.
+       /// </summary>
+       public class LazyLoadProxyFactory
+       {
+               #region Fields
+               private static readonly ILog _logger = LogManager.GetLogger( 
MethodBase.GetCurrentMethod().DeclaringType );
+               #endregion
+
+               #region Constructor
+               /// <summary>
+               /// Private constructor
+               /// </summary>
+               private LazyLoadProxyFactory()
+               {
+               }
+               #endregion
+               
+               /// <summary>
+               /// Builds the specified lazy load proxy.
+               /// </summary>
+               /// <param name="mappedStatement">The mapped statement used to 
build the lazy loaded object.</param>
+               /// <param name="param">The parameter object used to build lazy 
loaded object.</param>
+               /// <param name="target">The target object which contains the 
property proxydied..</param>
+               /// <param name="memberAccessor">The proxified member 
accessor.</param>
+               /// <returns></returns>
+               public static object Build(IMappedStatement mappedStatement, 
object param, 
+                       object target, IMemberAccessor memberAccessor)
+               {
+                       object proxy = null;
+                       Type typeProxified = memberAccessor.MemberType; 
+       
+                       bool isIList = 
typeof(IList).IsAssignableFrom(memberAccessor.MemberType);
+                       Type returnedTypeByStatement = 
LazyLoadProxyFactory.GetTypeReturnedByStatemet(mappedStatement, isIList); 
+       
+                       //Test if the result of the lazy load is assigable to 
property, test now load time instead
+                       //wait to error when the method of proxy are called
+                       if 
(typeProxified.IsAssignableFrom(returnedTypeByStatement) == false)
+                       {
+                               throw new DataMapperException("Error building 
LazyLoad proxy for " + target.GetType() + "." + memberAccessor.Name + " can not 
assing " + typeProxified + " to " + returnedTypeByStatement);
+                       }
+
+                       //Build the proxy
+                       IInterceptor handler = new 
LazyLoadInterceptor(mappedStatement, param, target, memberAccessor);
+                       if (isIList)
+                       {
+                               if (_logger.IsDebugEnabled) 
+                               {
+                                       _logger.Debug(string.Format("Statement 
'{0}', create list proxy for member {1}.", mappedStatement.Id 
,memberAccessor.MemberType));
+                               }
+
+                               if (mappedStatement.Statement.ListClass == null)
+                               {
+                                        proxy = 
ProxyGeneratorFactory.GetProxyGenerator().CreateProxy(typeof(IList), handler, 
new ArrayList());
+                               }
+                               else
+                               {
+                                       proxy = 
ProxyGeneratorFactory.GetProxyGenerator().CreateClassProxy(typeProxified, 
handler, Type.EmptyTypes);
+                               }       
+                       }
+                       else if (typeProxified.IsClass)
+                       {
+                               if (_logger.IsDebugEnabled) 
+                               {
+                                       _logger.Debug(string.Format("Statement 
'{0}', create class proxy for member {1}.", mappedStatement.Id 
,memberAccessor.MemberType));
+                               }
+
+                               //TODO test if param fit with constructor 
arguments 
+                               proxy = 
ProxyGeneratorFactory.GetProxyGenerator().CreateClassProxy(typeProxified, 
handler, 
+                                       
LazyLoadProxyFactory.CreateArgumentsForConstructor(typeProxified, param));
+                       }
+                       else
+                       {
+                               throw new 
DataMapperException(string.Format("Not implemented: the type ({0}) of property 
to proxify is not and interface or class.", typeProxified) ); 
+                       }
+
+                       return proxy;
+               }
+
+
+               /// <summary>
+               /// Gets the type returned by statemet.
+               /// </summary>
+               /// <param name="mappedStatement">The mapped statement.</param>
+               /// <param name="isIList">if set to <c>true</c> [is 
Ilist].</param>
+               /// <returns>The type object return by the statement.</returns>
+               private static Type GetTypeReturnedByStatemet(IMappedStatement 
mappedStatement,
+                       bool isIList)
+               {
+                       Type returnedType = null;
+
+                       if ( isIList )
+                       {
+                               if (mappedStatement.Statement.ListClass != null)
+                               {
+                                       //Strongly type collection
+                                       returnedType = 
mappedStatement.Statement.ListClass;     
+                               }
+                               else
+                               {
+                                       //Generic List, IList is the return 
type of ExecuteQueryForList(..)
+                                       returnedType = typeof(IList);
+                               }
+                       }
+                       else 
+                       {
+                               //Property to proxified is a simple object
+                               if (mappedStatement.Statement.ResultClass != 
null)
+                               {
+                                       returnedType = 
mappedStatement.Statement.ResultClass; 
+                               }
+                               else if (mappedStatement.Statement.ParameterMap 
!= null)
+                               {
+                                       returnedType = 
mappedStatement.Statement.ParameterMap.Class;
+                               }
+                               else
+                               {
+                                       throw new DataMapperException("We must 
never get here !");
+                               }
+                       }
+               
+                       return returnedType;
+               }
+
+               
+               /// <summary>
+               /// Creates the arguments for constructor.
+               /// </summary>
+               /// <param name="type">The object type.</param>
+               /// <param name="lazyLoadParam">The lazy load param.</param>
+               /// <returns>A list of objects argument</returns>
+               private static object[] CreateArgumentsForConstructor(Type 
type,object lazyLoadParam)
+               {
+                       object[] argumentsForConstructor = null;
+
+                       if (type.GetInterface(typeof(ICollection).FullName) != 
null)
+                       {
+                               //the collection build whitout arguments
+                               argumentsForConstructor = new object[]{};
+                       }
+                       else
+                       {
+                               if (lazyLoadParam == null)
+                               {
+                                       argumentsForConstructor = new 
object[]{};
+                               }
+                               if (lazyLoadParam is object[])
+                               {
+                                       //Multiple primary key
+                                       argumentsForConstructor = 
(object[])lazyLoadParam;
+                               }
+                               else
+                               {
+                                       argumentsForConstructor = new 
object[]{lazyLoadParam};
+                               }
+                       }
+
+                       return argumentsForConstructor;
+               }
+
+
+       }
+}


Reply via email to