using System; using System.Collections; using System.Collections.Generic; namespace Be.Timvw.Framework.Domain { public class EffectivityManager : IEffectivityManager where T : IComparable { #region Private Fields private readonly List> effectivities; #endregion #region Public Constructors public EffectivityManager() { this.effectivities = new List>(); } #endregion #region IEffectivityManager Members public IEffectivity Add(T t, DateTime begin) { if (this.effectivities.Count == 0) { Range validityPeriod = new Range(begin, DateTime.MaxValue); Effectivity effectivity = new Effectivity(t, validityPeriod); this.effectivities.Add(effectivity); return effectivity; } IEffectivity snapshot; if (!this.TryGetSnapshot(begin, out snapshot)) { IEffectivity effectivityFirstAfter = this.effectivities[0]; Range validityPeriod = new Range(begin, effectivityFirstAfter.ValidityPeriod.Begin.AddTicks(-1)); Effectivity effectivity = new Effectivity(t, validityPeriod); this.effectivities.Insert(0, effectivity); return effectivity; } else { Range validityPeriod = new Range(begin, snapshot.ValidityPeriod.End); Effectivity effectivity = new Effectivity(t, validityPeriod); this.effectivities.Insert(this.effectivities.IndexOf(snapshot) + 1, effectivity); if (snapshot.ValidityPeriod.Begin < effectivity.ValidityPeriod.Begin.AddTicks(-1)) { snapshot.ValidityPeriod.End = effectivity.ValidityPeriod.Begin.AddTicks(-1); } else { this.effectivities.Remove(snapshot); } return effectivity; } } public IEffectivity GetSnapshot(DateTime validityDate) { IEffectivity effectivity; if (this.TryGetSnapshot(validityDate, out effectivity)) { return effectivity; } throw new ArgumentOutOfRangeException(string.Format("No element is effective on {0}", validityDate)); } public bool TryGetSnapshot(DateTime validityDate, out IEffectivity effectivity) { foreach (IEffectivity anEffectivity in this.effectivities) { if (anEffectivity.IsEffectiveOn(validityDate)) { effectivity = anEffectivity; return true; } } effectivity = default(IEffectivity); return false; } #endregion #region IList> Members public int IndexOf(IEffectivity item) { return this.effectivities.IndexOf(item); } public void Insert(int index, IEffectivity item) { throw new NotSupportedException(); } public void RemoveAt(int index) { this.Remove(this.effectivities[index]); } public IEffectivity this[int index] { get { return this.effectivities[index]; } set { throw new NotSupportedException(); } } #endregion #region ICollection> Members public void Add(IEffectivity item) { throw new NotSupportedException(); } public void Clear() { this.effectivities.Clear(); } public bool Contains(IEffectivity item) { return this.effectivities.Contains(item); } public void CopyTo(IEffectivity[] array, int arrayIndex) { this.effectivities.CopyTo(array, arrayIndex); } public int Count { get { return this.effectivities.Count; } } public bool IsReadOnly { get { return false; } } public bool Remove(IEffectivity item) { int indexOfEffectivity = this.effectivities.IndexOf(item); if (indexOfEffectivity > 0) { IEffectivity effectivityFirstBefore = this.effectivities[indexOfEffectivity - 1]; effectivityFirstBefore.ValidityPeriod.End = item.ValidityPeriod.End; } return this.effectivities.Remove(item); } #endregion #region IEnumerable> Members public IEnumerator> GetEnumerator() { return this.effectivities.GetEnumerator(); } #endregion #region IEnumerable Members IEnumerator IEnumerable.GetEnumerator() { return this.effectivities.GetEnumerator(); } #endregion } }