/********************************************************************
* FulcrumWeb RAD Framework - Fulcrum of your business *
* Copyright (c) 2002-2009 FulcrumWeb, ALL RIGHTS RESERVED *
* *
* THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED *
* FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE *
* COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE *
* AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT *
* AND PERMISSION FROM FULCRUMWEB. CONSULT THE END USER LICENSE *
* AGREEMENT FOR INFORMATION ON ADDITIONAL RESTRICTIONS. *
********************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using Framework.Silverlight.Client.AppServer;
namespace Framework.Silverlight.Client
{
/// <summary>
/// Represents collection of Entities.
/// </summary>
public class CxEntityList : IEnumerable, IxDataObject
{
private bool m_IsDisposed;
private int m_ChangesCounter;
//----------------------------------------------------------------------------
/// <summary>
/// Occurs when Attribute with depended attributes had changed.
/// </summary>
public event DxDependencyAttributeChanged DependencyAttributeChanged;
//----------------------------------------------------------------------------
/// <summary>
/// Occurs when data had change.
/// </summary>
public event EventHandler DataChanged;
//----------------------------------------------------------------------------
/// <summary>
/// Occurs when changes of data was commited.
/// </summary>
public event EventHandler DataCommited;
//----------------------------------------------------------------------------
/// <summary>
/// Occurs when changes of data was reverted.
/// </summary>
public event EventHandler DataReverted;
//----------------------------------------------------------------------------
/// <summary>
/// Gets list of CxBaseEntity.
/// </summary>
public ObservableCollection<CxBaseEntity> Entities { get; private set; }
//----------------------------------------------------------------------------
/// <summary>
/// Initializes a new instance of the CxEntityList class.
/// </summary>
public CxEntityList()
{
Entities = new ObservableCollection<CxBaseEntity>();
Entities.CollectionChanged += Entities_CollectionChanged;
}
//----------------------------------------------------------------------------
/// <summary>
/// Raises the DependencyAttributeChanged event.
/// </summary>
protected virtual void OnDependencyAttributeChanged(CxDependencyAttributeChangedEventArgs e)
{
if (DependencyAttributeChanged != null)
{
DependencyAttributeChanged(this, e);
}
}
//----------------------------------------------------------------------------
/// <summary>
/// Handles CollectionChanged event.
/// </summary>
void Entities_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (CxBaseEntity baseEntity in e.NewItems)
{
baseEntity.DataChanged += baseEntity_DataChanged;
baseEntity.DataReverted += baseEntity_DataReverted;
baseEntity.DataCommited += baseEntity_DataCommited;
baseEntity.DependencyAttributeChanged += baseEntity_DependencyAttributeChanged;
}
}
if (e.Action == NotifyCollectionChangedAction.Remove)
{
foreach (CxBaseEntity baseEntity in e.OldItems)
{
baseEntity.DataChanged -= baseEntity_DataChanged;
baseEntity.DataReverted -= baseEntity_DataReverted;
baseEntity.DataCommited -= baseEntity_DataCommited;
baseEntity.DependencyAttributeChanged -= baseEntity_DependencyAttributeChanged;
baseEntity.Dispose();
}
}
}
//----------------------------------------------------------------------------
/// <summary>
/// Handles CxBaseEntity.DependencyAttributeChanged
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void baseEntity_DependencyAttributeChanged(object sender, CxDependencyAttributeChangedEventArgs e)
{
OnDependencyAttributeChanged(new CxDependencyAttributeChangedEventArgs(e.ChangedAttributeId));
}
//----------------------------------------------------------------------------
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.
/// </returns>
public IEnumerator GetEnumerator()
{
return Entities.GetEnumerator();
}
//----------------------------------------------------------------------------
/// <summary>
/// Handles the CxBaseEntity.DataChanged event.
/// </summary>
void baseEntity_DataChanged(object sender, EventArgs e)
{
m_ChangesCounter++;
OnDataChanged();
}
//----------------------------------------------------------------------------
/// <summary>
/// Raises the DataCommited event.
/// </summary>
void baseEntity_DataCommited(object sender, EventArgs e)
{
m_ChangesCounter--;
if (m_ChangesCounter == 0)
{
OnDataCommited();
}
}
//----------------------------------------------------------------------------
/// <summary>
/// Raises the DataReverted event.
/// </summary>
void baseEntity_DataReverted(object sender, EventArgs e)
{
m_ChangesCounter--;
if (m_ChangesCounter == 0)
{
OnDataReverted();
}
}
//----------------------------------------------------------------------------
/// <summary>
/// Raises the DataChanged event.
/// </summary>
protected virtual void OnDataChanged()
{
if (DataChanged != null)
{
DataChanged(this, EventArgs.Empty);
}
}
//----------------------------------------------------------------------------
/// <summary>
/// Raises the DataReverted event.
/// </summary>
protected virtual void OnDataReverted()
{
if (DataReverted != null)
{
DataReverted(this, EventArgs.Empty);
}
}
//----------------------------------------------------------------------------
/// <summary>
/// Raises the DataCommited event.
/// </summary>
protected virtual void OnDataCommited()
{
if (DataCommited != null)
{
DataCommited(this, EventArgs.Empty);
}
}
//----------------------------------------------------------------------------
/// <summary>
/// Commits all the changes made to this DataObject since
/// the last time AcceptChanges() was called.
/// <param name="validate">True - validate befor accepting.</param>
/// </summary>
public void AcceptChanges(bool validate)
{
foreach (IxDataObject entity in Entities)
{
entity.AcceptChanges(validate);
}
m_ChangesCounter = 0;
}
//----------------------------------------------------------------------------
/// <summary>
/// Commits all the changes made to this DataObject since
/// the last time AcceptChanges() was called.
/// </summary>
public void AcceptChanges()
{
AcceptChanges(true);
}
//----------------------------------------------------------------------------
/// <summary>
/// Rolls back all changes that have been made to the
/// DataObject since the last time AcceptChanges() was called.
/// </summary>
public void RejectChanges()
{
foreach (IxDataObject entity in Entities)
{
entity.RejectChanges();
}
m_ChangesCounter = 0;
}
//----------------------------------------------------------------------------
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing,
/// or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (!m_IsDisposed)
{
foreach (CxBaseEntity entity in Entities)
{
Entities.CollectionChanged -= Entities_CollectionChanged;
entity.DataChanged -= baseEntity_DataChanged;
entity.DataReverted -= baseEntity_DataReverted;
entity.DataCommited -= baseEntity_DataCommited;
entity.DependencyAttributeChanged -= baseEntity_DependencyAttributeChanged;
entity.Dispose();
}
Entities.Clear();
m_IsDisposed = true;
}
}
//----------------------------------------------------------------------------
/// <summary>
/// Finds Entity with defined primary key(s).
/// </summary>
/// <param name="pkList">List of primary key(s) which need to find.</param>
/// <returns>Found Entity or null.</returns>
public CxBaseEntity FindEntityByPk(IList<CxAttributeSnapShot> pkList)
{
foreach (CxBaseEntity entity in Entities)
{
if (entity.ComparePk(pkList))
{
return entity;
}
}
return null;
}
//----------------------------------------------------------------------------
/// <summary>
/// Gets value that defines, has this entity uncommitted changes or not.
/// </summary>
public bool HasChanges
{
get { return m_ChangesCounter > 0; }
}
//----------------------------------------------------------------------------
/// <summary>
/// Gets or sets value that defines there was DataObject is commited.
/// </summary>
public bool IsCommited { get; set; }
//----------------------------------------------------------------------------
/// <summary>
/// Returns true if the data list contains one, newly created entity
/// and this entity is newer commited.
/// </summary>
public bool IsNewEntity { get; internal set; }
//----------------------------------------------------------------------------
/// <summary>
/// Refreshes entity by given CxExpressionResult.
/// </summary>
/// <param name="exprResult"></param>
public void RefreshEntity(
CxExpressionResult exprResult)
{
Dictionary<string, object> pkList = new Dictionary<string, object>();
foreach (KeyValuePair<CxClientAttributeMetadata, object> pair in exprResult.Entity)
{
if (pair.Key.PrimaryKey)
{
pkList.Add(pair.Key.Id, pair.Value);
}
}
List<CxBaseEntity> entities = (from baseEntity in Entities
where baseEntity.ComparePk(pkList)
select baseEntity).ToList();
if (entities.Count == 0)
throw new ExApplicationException("Entity with given PK list does not exists.");
entities[0].Refresh(exprResult);
}
}
}