Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/Netron.Diagramming.Core-3.0.2672.12446/Collections/CollectionBase.cs @ 2768

Last change on this file since 2768 was 2768, checked in by mkommend, 14 years ago

added solution folders and sources for the netron library (ticket #867)

File size: 24.7 KB
Line 
1
2using System;
3using System.IO;
4using System.Runtime.Serialization;
5using System.Runtime.Serialization.Formatters.Binary;
6using System.Collections;
7using System.Collections.Generic;
8using System.Diagnostics;
9using Netron.NetronLight;
10namespace Netron.Diagramming.Core
11{
12    /// <summary>
13    /// CollectionBase is a base class that can be used to more easily implement the
14    /// generic ICollection&lt;T&gt; and non-generic ICollection interfaces.
15    /// </summary>
16    /// <remarks>
17    /// <para>To use CollectionBase as a base class, the derived class must override
18    /// the Count, GetEnumerator, Add, Clear, and Remove methods. </para>
19    /// <para>ICollection&lt;T&gt;.Contains need not be implemented by the
20    /// derived class, but it should be strongly considered, because the CollectionBase implementation
21    /// may not be very efficient.</para>
22    /// </remarks>
23    /// <typeparam name="T">The item type of the collection.</typeparam>
24
25    [DebuggerDisplay("{DebuggerDisplayString()}")]
26    public partial class CollectionBase<T> : ICollection<T>, ICollection, IList<T>, ICollectionBase<T>, IShowable
27    {
28        #region Events
29        /// <summary>
30        /// Occurs when an item is added to the collection.
31        /// </summary>
32        public event EventHandler<CollectionEventArgs<T>> OnItemAdded;
33        /// <summary>
34        /// Occurs when an item is removed from the collection.
35        /// </summary>
36        public event EventHandler<CollectionEventArgs<T>> OnItemRemoved;
37        /// <summary>
38        /// Occurs when the collection is cleared.
39        /// </summary>
40        public event EventHandler OnClear;
41        #endregion
42
43        #region Fields
44        /// <summary>
45        /// the internal generic list on which this collection is based
46        /// </summary>                                                                   
47        protected List<T> innerList;
48        /// <summary>
49        /// whether this collection is readonly
50        /// </summary>
51        bool mReadOnly = false;
52        #endregion
53
54        #region Properties
55        /// <summary>
56        /// Indicates whether the collection is read-only.
57        /// </summary>
58        bool ICollection<T>.IsReadOnly
59        {
60            get
61            {
62                return mReadOnly;
63            }
64        }
65
66        /// <summary>
67        /// Gets a value indicating whether this instance is empty.
68        /// </summary>
69        /// <value><c>true</c> if this instance is empty; otherwise, <c>false</c>.</value>
70        public virtual bool IsEmpty
71        {
72            get { return this.innerList.Count == 0; }
73        }
74        #endregion
75
76       
77
78        #region Constructor
79       
80        /// <summary>
81        /// Creates a new CollectionBase.
82        /// </summary>
83        public  CollectionBase()
84        {
85            innerList = new List<T>();
86        }
87
88        /// <summary>
89        /// Initializes a new instance of the <see cref="T:CollectionBase&lt;T&gt;"/> class.
90        /// </summary>
91        /// <param name="baseCollection">The base collection.</param>
92        public CollectionBase(ICollectionBase<T> baseCollection) : this()
93        {
94            innerList.AddRange(baseCollection);   
95        }
96
97        /// <summary>
98        /// Initializes a new instance of the <see cref="T:CollectionBase&lt;T&gt;"/> class.
99        /// </summary>
100        /// <param name="baseCollection">The base collection.</param>
101        /// <param name="readOnly">if set to <c>true</c> [read only].</param>
102        public CollectionBase(ICollectionBase<T> baseCollection, bool readOnly)
103            : this()
104        {
105            mReadOnly = readOnly;
106            //innerList = new System.Collections.ObjectModel.ReadOnlyCollection<T>(baseCollection);
107            innerList.AddRange(baseCollection);
108        }
109
110       
111       
112
113        #endregion
114
115        /// <summary>
116        /// Shows the string representation of the collection. The string representation contains
117        /// a list of the items in the collection. Contained collections (except string) are expanded
118        /// recursively.
119        /// </summary>
120        /// <returns>The string representation of the collection.</returns>
121        public override string ToString()
122        {
123            return Algorithms.ToString(this);
124        }
125        /// <summary>
126        /// Returns a string representation of this collection.
127        /// </summary>
128        /// <param name="format">The format.</param>
129        /// <param name="formatProvider">The format provider.</param>
130        /// <returns></returns>
131        public virtual string ToString(string format, IFormatProvider formatProvider)
132        {
133            return Showing.ShowString(this, format, formatProvider);
134        }
135
136        #region ICollection<T> Members
137
138        /// <summary>
139        /// Must be overridden to allow adding items to this collection.
140        /// </summary>
141        /// <remarks><p>This method is not abstract, although derived classes should always
142        /// override it. It is not abstract because some derived classes may wish to reimplement
143        /// Add with a different return type (typically bool). In C#, this can be accomplished
144        /// with code like the following:</p>
145        /// <code>
146        ///     public class MyCollection&lt;T&gt;: CollectionBase&lt;T&gt;, ICollection&lt;T&gt;
147        ///     {
148        ///         public new bool Add(T item) {
149        ///             /* Add the item */
150        ///         }
151        /// 
152        ///         void ICollection&lt;T&gt;.Add(T item) {
153        ///             Add(item);
154        ///         }
155        ///     }
156        /// </code>
157        /// </remarks>
158        /// <param name="item">Item to be added to the collection.</param>
159        /// <exception cref="NotImplementedException">Always throws this exception to indicated
160        /// that the method must be overridden or re-implemented in the derived class.</exception>
161        public virtual void Add(T item)
162        {
163            if(item==null) throw new InconsistencyException("Adding 'null' to the collection is not allowed.");
164            if (mReadOnly)
165                throw new InconsistencyException("The collection is read only");
166            this.innerList.Add(item);
167            RaiseOnItemAdded(item);
168
169        }
170        /// <summary>
171        /// Determines the index of a specific item in the <see cref="T:System.Collections.Generic.IList`1"></see>.
172        /// </summary>
173        /// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.IList`1"></see>.</param>
174        /// <returns>
175        /// The index of item if found in the list; otherwise, -1.
176        /// </returns>
177        public int IndexOf(T item)
178        {
179            return this.innerList.IndexOf(item);
180        }
181
182        /// <summary>
183        /// Inserts the specified item at the specified index.
184        /// </summary>
185        /// <param name="index">The index.</param>
186        /// <param name="item">A parameter of the generics Type T</param>
187        public virtual void Insert(int index, T item)
188        {
189            if (mReadOnly)
190                throw new InconsistencyException("The collection is read only");
191            if(item.Equals(default(T)))
192                return;
193            this.innerList.Insert(index, item);
194            RaiseOnItemAdded(item);
195        }
196
197        /// <summary>
198        /// Adds a collection range to this collection.
199        /// </summary>
200        /// <param name="items">The items.</param>
201        public virtual void AddRange(CollectionBase<T> items)
202        {
203            if (mReadOnly)
204                throw new InconsistencyException("The collection is read only");
205            this.innerList.AddRange(items);
206            foreach (T item in items)
207            {
208                RaiseOnItemAdded(item);
209            }
210        }
211
212        private void RaiseOnItemAdded(T item)
213        {
214            if (OnItemAdded != null)
215                OnItemAdded(this, new CollectionEventArgs<T>(item));
216        }
217
218        private void RaiseOnItemRemoved(T item)
219        {
220            if (OnItemRemoved != null)
221                OnItemRemoved(this, new CollectionEventArgs<T>(item));
222        }
223        private void RaiseOnClear()
224        {
225            if (OnClear != null)
226                OnClear(this, EventArgs.Empty);
227        }
228
229
230
231        /// <summary>
232        /// Must be overridden to allow clearing this collection.
233        /// </summary>
234        public virtual void Clear()
235        {
236            RaiseOnClear();
237            innerList.Clear();
238        }
239
240        /// <summary>
241        /// Must be overridden to allow removing items from this collection.
242        /// </summary>
243        /// <returns>True if <paramref name="item"/> existed in the collection and
244        /// was removed. False if <paramref name="item"/> did not exist in the collection.</returns>
245        public virtual bool Remove(T item)
246        {
247           
248            bool result =  this.innerList.Remove(item);
249            if (result)
250            {
251                RaiseOnItemRemoved(item);
252            }
253            return result;
254        }
255
256        /// <summary>
257        /// Determines if the collection contains a particular item. This default implementation
258        /// iterates all of the items in the collection via GetEnumerator, testing each item
259        /// against <paramref name="item"/> using IComparable&lt;T&gt;.Equals or
260        /// Object.Equals.
261        /// </summary>
262        /// <remarks>You should strongly consider overriding this method to provide
263        /// a more efficient implementation, or if the default equality comparison
264        /// is inappropriate.</remarks>
265        /// <param name="item">The item to check for in the collection.</param>
266        /// <returns>True if the collection contains <paramref name="item"/>, false otherwise.</returns>
267        public virtual bool Contains(T item)
268        {
269            return this.innerList.Contains(item);
270
271        }
272
273        /// <summary>
274        /// Copies all the items in the collection into an array. Implemented by
275        /// using the enumerator returned from GetEnumerator to get all the items
276        /// and copy them to the provided array.
277        /// </summary>
278        /// <param name="array">Array to copy to.</param>
279        /// <param name="arrayIndex">Starting index in <paramref name="array"/> to copy to.</param>
280        public virtual void CopyTo(T[] array, int arrayIndex)
281        {
282            int count = this.Count;
283
284            if (count == 0)
285                return;
286
287            if (array == null)
288                throw new ArgumentNullException("array");
289            if (count < 0)
290                throw new ArgumentOutOfRangeException("count", count, Resource1.ArgumentOutOfRange);
291            if (arrayIndex < 0)
292                throw new ArgumentOutOfRangeException("arrayIndex", arrayIndex, Resource1.ArgumentOutOfRange);
293            if (arrayIndex >= array.Length || count > array.Length - arrayIndex)
294                throw new ArgumentException("arrayIndex", Resource1.ArrayTooSmall);
295
296            int index = arrayIndex, i = 0;
297            foreach (T item in (ICollection<T>)this)
298            {
299                if (i >= count)
300                    break;
301
302                array[index] = item;
303                ++index;
304                ++i;
305            }
306        }
307
308        /// <summary>
309        /// Creates an array of the correct size, and copies all the items in the
310        /// collection into the array, by calling CopyTo.
311        /// </summary>
312        /// <returns>An array containing all the elements in the collection, in order.</returns>
313        public virtual T[] ToArray()
314        {
315            int count = this.Count;
316
317            T[] array = new T[count];
318            CopyTo(array, 0);
319            return array;
320        }
321
322        /// <summary>
323        /// Must be overridden to provide the number of items in the collection.
324        /// </summary>
325        /// <value>The number of items in the collection.</value>
326        public virtual int Count { get { return innerList.Count; } }
327
328
329
330        #endregion
331
332        #region Delegate operations
333
334        /// <summary>
335        /// Determines if the collection contains any item that satisfies the condition
336        /// defined by <paramref name="predicate"/>.
337        /// </summary>
338        /// <param name="predicate">A delegate that defines the condition to check for.</param>
339        /// <returns>True if the collection contains one or more items that satisfy the condition
340        /// defined by <paramref name="predicate"/>. False if the collection does not contain
341        /// an item that satisfies <paramref name="predicate"/>.</returns>
342        public virtual bool Exists(Predicate<T> predicate)
343        {
344            if (predicate == null)
345                throw new ArgumentNullException("predicate");
346
347            return Algorithms.Exists(this, predicate);
348        }
349
350        /// <summary>
351        /// Determines if all of the items in the collection satisfy the condition
352        /// defined by <paramref name="predicate"/>.
353        /// </summary>
354        /// <param name="predicate">A delegate that defines the condition to check for.</param>
355        /// <returns>True if all of the items in the collection satisfy the condition
356        /// defined by <paramref name="predicate"/>, or if the collection is empty. False if one or more items
357        /// in the collection do not satisfy <paramref name="predicate"/>.</returns>
358        public virtual bool TrueForAll(Predicate<T> predicate)
359        {
360            if (predicate == null)
361                throw new ArgumentNullException("predicate");
362
363            return Algorithms.TrueForAll(this, predicate);
364        }
365         /*
366        /// <summary>
367        /// Counts the number of items in the collection that satisfy the condition
368        /// defined by <paramref name="predicate"/>.
369        /// </summary>
370        /// <param name="predicate">A delegate that defines the condition to check for.</param>
371        /// <returns>The number of items in the collection that satisfy <paramref name="predicate"/>.</returns>
372        public virtual int CountWhere(Predicate<T> predicate)
373        {
374            if (predicate == null)
375                throw new ArgumentNullException("predicate");
376
377            return Algorithms.CountWhere(this, predicate);
378        }
379          */
380        /// <summary>
381        /// Finds the first item in the collection satisfying the given predicate
382        /// </summary>
383        /// <param name="predicate">a searching predictae</param>
384        /// <returns>an item satisfying the criteria (if any)</returns>
385        public virtual T Find(Predicate<T> predicate)
386        {
387            foreach (T item in this.innerList)
388            {
389                if (predicate(item))
390                    return item;
391            }
392            return default(T);
393        }
394
395
396        /// <summary>
397        /// Removes all the items in the collection that satisfy the condition
398        /// defined by <paramref name="predicate"/>.
399        /// </summary>
400        /// <param name="predicate">A delegate that defines the condition to check for.</param>
401        /// <returns>Returns a collection of the items that were removed, in sorted order.</returns>
402        public virtual ICollection<T> RemoveAll(Predicate<T> predicate)
403        {
404            if (predicate == null)
405                throw new ArgumentNullException("predicate");
406
407            return Algorithms.RemoveWhere(this, predicate);
408        }
409
410        /// <summary>
411        /// Performs the specified action on each item in this collection.
412        /// </summary>
413        /// <param name="action">An Action delegate which is invoked for each item in this collection.</param>
414        public virtual void ForEach(Action<T> action)
415        {
416            if (action == null)
417                throw new ArgumentNullException("action");
418
419            Algorithms.ForEach(this, action);
420        }
421
422
423
424        #endregion
425
426        #region IEnumerable<T> Members
427
428        /// <summary>
429        /// Must be overridden to enumerate all the members of the collection.
430        /// </summary>
431        /// <returns>A generic IEnumerator&lt;T&gt; that can be used
432        /// to enumerate all the items in the collection.</returns>
433        public virtual IEnumerator<T> GetEnumerator()
434        {
435            return this.innerList.GetEnumerator();
436        }
437
438
439        #endregion
440
441        #region ICollection Members
442
443        /// <summary>
444        /// Copies all the items in the collection into an array. Implemented by
445        /// using the enumerator returned from GetEnumerator to get all the items
446        /// and copy them to the provided array.
447        /// </summary>
448        /// <param name="array">Array to copy to.</param>
449        /// <param name="index">Starting index in <paramref name="array"/> to copy to.</param>
450        void ICollection.CopyTo(Array array, int index)
451        {
452            int count = this.Count;
453
454            if (count == 0)
455                return;
456
457            if (array == null)
458                throw new ArgumentNullException("array");
459            if (index < 0)
460                throw new ArgumentOutOfRangeException("index", index, Resource1.ArgumentOutOfRange);
461            if (index >= array.Length || count > array.Length - index)
462                throw new ArgumentException("index", Resource1.ArrayTooSmall);
463
464            int i = 0;
465            foreach (object o in (ICollection)this)
466            {
467                if (i >= count)
468                    break;
469
470                array.SetValue(o, index);
471                ++index;
472                ++i;
473            }
474        }
475
476        /// <summary>
477        /// Indicates whether the collection is synchronized.
478        /// </summary>
479        /// <value>Always returns false, indicating that the collection is not synchronized.</value>
480        bool ICollection.IsSynchronized
481        {
482            get { return IsSynchronized; }
483        }
484
485        /// <summary>
486        /// See code analysis CA1033
487        /// </summary>
488        protected bool IsSynchronized
489        {
490            get { return false; }
491        }
492        /// <summary>
493        /// Indicates the synchronization object for this collection.
494        /// </summary>
495        /// <value>Always returns this.</value>
496        object ICollection.SyncRoot
497        {
498            get { return SyncRoot; }
499        }
500
501        /// <summary>
502        /// See code analysis CA1033
503        /// </summary>
504        protected object SyncRoot
505        {
506            get { return this; }
507        }
508
509        #endregion
510
511        #region IEnumerable Members
512
513        /// <summary>
514        /// Provides an IEnumerator that can be used to iterate all the members of the
515        /// collection. This implementation uses the IEnumerator&lt;T&gt; that was overridden
516        /// by the derived classes to enumerate the members of the collection.
517        /// </summary>
518        /// <returns>An IEnumerator that can be used to iterate the collection.</returns>
519        IEnumerator IEnumerable.GetEnumerator()
520        {
521            foreach (T item in this)
522            {
523                yield return item;
524            }
525        }
526
527        #endregion
528
529        /// <summary>
530        /// Display the contents of the collection in the debugger. This is intentionally private, it is called
531        /// only from the debugger due to the presence of the DebuggerDisplay attribute. It is similar
532        /// format to ToString(), but is limited to 250-300 characters or so, so as not to overload the debugger.
533        /// </summary>
534        /// <returns>The string representation of the items in the collection, similar in format to ToString().</returns>
535        internal string DebuggerDisplayString()
536        {
537            const int MAXLENGTH = 250;
538
539            System.Text.StringBuilder builder = new System.Text.StringBuilder();
540
541            builder.Append('{');
542
543            // Call ToString on each item and put it in.
544            bool firstItem = true;
545            foreach (T item in this)
546            {
547                if (builder.Length >= MAXLENGTH)
548                {
549                    builder.Append(",...");
550                    break;
551                }
552
553                if (!firstItem)
554                    builder.Append(',');
555
556                if (item == null)
557                    builder.Append("null");
558                else
559                    builder.Append(item.ToString());
560
561                firstItem = false;
562            }
563
564            builder.Append('}');
565            return builder.ToString();
566        }
567        /// <summary>
568        /// Removes an item at the given index
569        /// </summary>
570        /// <param name="index"></param>
571        public void RemoveAt(int index)
572        {
573            this.innerList.RemoveAt(index);
574        }
575        /// <summary>
576        /// Integer indexer
577        /// </summary>
578        /// <param name="index"></param>
579        /// <returns></returns>
580        public T this[int index]
581        {
582            get
583            {
584                return this.innerList[index];
585            }
586            set
587            {
588                this.innerList[index] = value;
589            }
590        }
591
592        /// <summary>
593        /// Returns a deep copy of this collection.
594        /// <remarks>The returned collection is not attached to the <see cref="Model"/>
595        /// and is as such on an in-memory collection of instances. You need to 'unwrap' the collection
596        /// in the model and, to make it visible, deploy it in the paintables collection of the model.
597        /// </remarks>
598        /// </summary>
599        /// <returns></returns>
600        public CollectionBase<T> DeepCopy()
601        {
602            /* This doesn't work seemingly....
603            if (!typeof(T).IsSerializable)
604                throw new InconsistencyException("The generic type on which the collection is based is not serializable, the collection cannot generate a deep copy.");
605            */
606
607            try
608            {
609               
610                CollectionBase<T> newobj = null;
611                MemoryStream stream = new MemoryStream();
612                GenericFormatter<BinaryFormatter> f = new GenericFormatter<BinaryFormatter>();
613                f.Serialize(stream, this);
614                stream.Seek(0, SeekOrigin.Begin);
615                newobj = f.Deserialize<CollectionBase<T>>(stream);
616                stream.Close();
617                return newobj;
618            }
619            catch (Exception exc)
620            {
621                throw new InconsistencyException("The copy operation failed.", exc);
622            }
623
624        }
625        /// <summary>
626        /// Returns a copy of this instance.
627        /// </summary>
628        /// <returns></returns>
629        public CollectionBase<T> Copy()
630        {
631            CollectionBase<T> copy = new CollectionBase<T>();
632            foreach (T item in this.innerList)
633            {
634                copy.Add(item);
635            }
636            return copy; 
637        }
638        /// <summary>
639        /// This method creates first a deep copy of the collection and puts
640        /// the result in a <see cref="MemoryStream"/>.
641        /// See the <see cref="CopyTool"/> for details.
642        /// </summary>
643        /// <returns></returns>
644        public MemoryStream ToStream()
645        {
646            try
647            {
648
649                MemoryStream stream = new MemoryStream();
650                GenericFormatter<BinaryFormatter> f =
651                    new GenericFormatter<BinaryFormatter>();
652                f.Serialize(stream, this);
653                return stream;
654            }
655            catch (Exception exc)
656            {
657                throw new InconsistencyException(
658                    "The ToStream() operation failed.",
659                    exc);
660            }
661
662        }
663
664        /// <summary>
665        /// Format <code>this</code> using at most approximately <code>rest</code> chars and
666        /// append the result, possibly truncated, to stringbuilder.
667        /// Subtract the actual number of used chars from <code>rest</code>.
668        /// </summary>
669        /// <param name="stringbuilder"></param>
670        /// <param name="rest"></param>
671        /// <param name="formatProvider"></param>
672        /// <returns>
673        /// True if the appended formatted string was complete (not truncated).
674        /// </returns>
675        public virtual bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
676        {
677            return true;
678        }
679     
680    }
681
682   
683   
684
685
686   
687}
Note: See TracBrowser for help on using the repository browser.