#region Apache Notice /***************************************************************************** * $Revision: 374175 $ * $LastChangedDate$ * $LastChangedBy$ * * 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 using System; using System.Collections; using IBatisNet.DataMapper.MappedStatements; using IBatisNet.Common.Utilities.Objects.Members; using IBatisNet.Common.Logging; using System.Reflection; namespace IBatisNet.DataMapper.Proxy { /// /// A lazy list /// [Serializable] public class LazyList : IList { #region Fields private object _param = null; private object _target = null; private ISetAccessor _setAccessor = null; private ISqlMapper _sqlMap = null; private string _statementId = string.Empty; private bool _loaded = false; private object _loadLock = new object(); private IList _list = null; private static readonly ILog _logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); #endregion /// /// Resolve the lazy loading. /// /// Name of the method. private void Load(string methodName) { if (_logger.IsDebugEnabled) { _logger.Debug("Proxyfying call to " + methodName); } lock (_loadLock) { if (_loaded == false) { if (_logger.IsDebugEnabled) { _logger.Debug("Proxyfying call, query statement " + _statementId); } _list = _sqlMap.QueryForList(_statementId, _param); _loaded = true; _setAccessor.Set(_target, _list); } } if (_logger.IsDebugEnabled) { _logger.Debug("End of proxyfied call to " + methodName); } } /// /// Initializes a new instance of the class. /// /// The mapped satement. /// The param. /// The target. /// The set accessor. public LazyList(IMappedStatement mappedSatement, object param, object target, ISetAccessor setAccessor) { _list = new ArrayList(); _param = param; _statementId = mappedSatement.Id; _sqlMap = mappedSatement.SqlMap; _target = target; _setAccessor = setAccessor; } #region IList Members /// /// Adds an item to the . /// /// The to add to the . /// /// The position into which the new element was inserted. /// /// The is read-only.-or- The has a fixed size. public int Add(object value) { Load("Add"); return _list.Add(value); } /// /// Removes all items from the . /// /// The is read-only. public void Clear() { Load("Clear"); _list.Clear(); } /// /// Determines whether the contains a specific value. /// /// The to locate in the . /// /// true if the is found in the ; otherwise, false. /// public bool Contains(object value) { Load("Contains"); return _list.Contains(value); } /// /// Determines the index of a specific item in the . /// /// The to locate in the . /// /// The index of value if found in the list; otherwise, -1. /// public int IndexOf(object value) { Load("IndexOf"); return _list.IndexOf(value); } /// /// Inserts an item to the at the specified index. /// /// The zero-based index at which value should be inserted. /// The to insert into the . /// index is not a valid index in the . /// The is read-only.-or- The has a fixed size. /// value is null reference in the . public void Insert(int index, object value) { Load("Insert"); _list.Insert(index, value); } /// /// Gets a value indicating whether the has a fixed size. /// /// /// true if the has a fixed size; otherwise, false. public bool IsFixedSize { get { return false; } } /// /// Gets a value indicating whether the is read-only. /// /// /// true if the is read-only; otherwise, false. public bool IsReadOnly { get { return false; } } /// /// Removes the first occurrence of a specific object from the . /// /// The to remove from the . /// The is read-only.-or- The has a fixed size. public void Remove(object value) { Load("Remove"); _list.Remove(value); } /// /// Removes the item at the specified index. /// /// The zero-based index of the item to remove. /// index is not a valid index in the . /// The is read-only.-or- The has a fixed size. public void RemoveAt(int index) { Load("RemoveAt"); _list.RemoveAt(index); } /// /// Gets or sets the at the specified index. /// /// public object this[int index] { get { Load("this"); return _list[index]; } set { Load("this"); _list[index] = value; } } #endregion #region ICollection Members /// /// Copies the elements of the to an , starting at a particular index. /// /// The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. /// The zero-based index in array at which copying begins. /// array is null. /// index is less than zero. /// array is multidimensional.-or- index is equal to or greater than the length of array.-or- The number of elements in the source is greater than the available space from index to the end of the destination array. /// The type of the source cannot be cast automatically to the type of the destination array. public void CopyTo(Array array, int index) { Load("CopyTo"); _list.CopyTo(array, index); } /// /// Gets the number of elements contained in the . /// /// /// The number of elements contained in the . public int Count { get { Load("Count"); return _list.Count; } } /// /// Gets a value indicating whether access to the is synchronized (thread safe). /// /// /// true if access to the is synchronized (thread safe); otherwise, false. public bool IsSynchronized { get { return false; } } /// /// Gets an object that can be used to synchronize access to the . /// /// /// An object that can be used to synchronize access to the . public object SyncRoot { get { return this; } } #endregion #region IEnumerable Members /// /// Returns an enumerator that iterates through a collection. /// /// /// An object that can be used to iterate through the collection. /// public IEnumerator GetEnumerator() { Load("Add"); return _list.GetEnumerator(); } #endregion } }