#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;
using System.Reflection;
using Castle.DynamicProxy;
using IBatisNet.Common.Logging;
using IBatisNet.Common.Utilities.Objects;
using IBatisNet.Common.Utilities.Proxy;
using IBatisNet.DataMapper.MappedStatements;
#endregion
namespace IBatisNet.DataMapper
{
///
/// Summary description for LazyLoadList.
///
[Serializable]
internal class LazyLoadList : IInterceptor
{
#region Fields
private object _param = null;
private object _target = null;
private string _propertyName= string.Empty;
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
///
/// Constructor for a lazy list loader
///
static LazyLoadList()
{
_passthroughMethods.Add("GetType");
_passthroughMethods.Add("ToString");
}
///
/// Constructor for a lazy list loader
///
/// The mapped statement used to build the list
/// The parameter object used to build the list
/// The property's name which been proxified.
/// The target object which contains the property proxydied.
internal LazyLoadList(IMappedStatement mappedSatement, object param, object target,string propertyName)
{
_param = param;
_statementName = mappedSatement.Name;
_sqlMap = mappedSatement.SqlMap;
_target = target;
_propertyName = propertyName;
}
#endregion
#region Methods
///
/// Static constructor
///
/// The statement used to build the list
/// The parameter object used to build the list
/// The property's name which been proxified.
/// The target object which contains the property proxydied.
/// A proxy
internal static IList NewInstance(IMappedStatement mappedSatement, object param, object target,string propertyName)
{
object proxList = null;
IInterceptor handler = new LazyLoadList(mappedSatement, param, target, propertyName);
if (mappedSatement.Statement.ListClass != null)
{
proxList = ProxyGeneratorFactory.GetProxyGenerator().CreateProxy(typeof(IList), handler, mappedSatement.Statement.CreateInstanceOfListClass());
}
else
{
proxList = ProxyGeneratorFactory.GetProxyGenerator().CreateProxy(typeof(IList), handler, new ArrayList());
}
return (IList) proxList;
}
#region IInterceptor members
///
///
///
///
///
///
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;
}
}
object returnValue = invocation.Method.Invoke( _innerList, arguments);
ObjectProbe.SetPropertyValue( _target, _propertyName, _innerList);
if (_logger.IsDebugEnabled)
{
_logger.Debug("End of proxyfied call to " + invocation.Method.Name);
}
return returnValue;
}
#endregion
#endregion
}
}