PageRenderTime 9ms CodeModel.GetById 2ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 1ms

/Source/ResourceManagement.ObjectModel/RmResourceChanges.cs

#
C# | 190 lines | 149 code | 13 blank | 28 comment | 18 complexity | 39e0346e34d45588ccec340b0759daac MD5 | raw file
  1using System;
  2using System.Collections;
  3using System.Collections.Generic;
  4using System.Linq;
  5using System.Text;
  6
  7namespace Microsoft.ResourceManagement.ObjectModel
  8{
  9    /// <summary>
 10    /// A transaction object monitors the changes made to an RmResource object.
 11    /// 
 12    /// Use this class to check for changes when updating the Resource Management Service.
 13    /// </summary>
 14    public class RmResourceChanges : IDisposable
 15    {
 16        private RmResource rmObject;
 17        private Dictionary<RmAttributeName, RmAttributeValue> originalAttributes;
 18
 19        public RmResource RmObject
 20        {
 21            get
 22            {
 23                return this.rmObject;
 24            }
 25        }
 26
 27        /// <summary>
 28        /// Begins a transaction on the provided RmResource object.
 29        /// </summary>
 30        /// <param name="rmObject">The object to watch during the transaction.</param>
 31        public RmResourceChanges(RmResource rmObject)
 32        {
 33            if (rmObject == null)
 34            {
 35                throw new ArgumentNullException("rmObject");
 36            }
 37            this.rmObject = rmObject;
 38        }
 39
 40        /// <summary>
 41        /// Returns a list of changes made to this object since the transaction began or the last call to AcceptChanges.
 42        /// </summary>
 43        /// <returns></returns>
 44        public IList<RmAttributeChange> GetChanges()
 45        {
 46            EnsureNotDisposed();
 47            lock (rmObject.Attributes)
 48            {
 49                // there was no original, so we just return an empty list
 50                if (originalAttributes == null)
 51                {
 52                    return new List<RmAttributeChange>();
 53                }
 54                else
 55                {
 56                    return RmResourceChanges.GetDifference(rmObject.Attributes, this.originalAttributes);
 57                }
 58            }
 59        }
 60
 61        public void BeginChanges()
 62        {
 63            EnsureNotDisposed();
 64            lock (rmObject.attributes)
 65            {
 66                this.originalAttributes = new Dictionary<RmAttributeName, RmAttributeValue>();
 67                foreach (RmAttributeName key in rmObject.attributes.Keys)
 68                {
 69                    this.originalAttributes[key] = new RmAttributeValue();
 70                    RmAttributeValue value = rmObject.attributes[key];
 71                    this.originalAttributes[key] = value.Clone() as RmAttributeValue;
 72                }
 73            }
 74        }
 75
 76        /// <summary>
 77        /// Commits all of the changes made the RmResource object.
 78        /// 
 79        /// GetChanges() will return an empty list immediately after this call.
 80        /// </summary>
 81        public void AcceptChanges()
 82        {
 83            EnsureNotDisposed();
 84            lock (rmObject.attributes)
 85            {
 86                this.originalAttributes = null;
 87            }
 88        }
 89
 90        /// <summary>
 91        /// Discards all of the changes made ot the RmResource object since the transaction began or a call to AcceptChanges()
 92        /// </summary>
 93        public void DiscardChanges()
 94        {
 95            EnsureNotDisposed();
 96            lock (rmObject.attributes)
 97            {
 98                rmObject.attributes = this.originalAttributes;
 99            }
100        }
101
102        #region IDisposable Members
103
104        public void Dispose()
105        {
106            EnsureNotDisposed();
107            lock (rmObject.attributes)
108            {
109                this.originalAttributes = null;
110                GC.SuppressFinalize(this);
111                this.rmObject = null;
112            }
113        }
114
115        private void EnsureNotDisposed()
116        {
117            if (this.rmObject == null)
118            {
119                throw new ObjectDisposedException("RmObjectTransaction", "The RmObjectTransaction object has already been disposed");
120            }
121        }
122
123        #endregion
124
125        #region difference calculation
126        /// <summary>
127        /// Returns a list of changes to make to obj1 in order for it to look like obj2.
128        /// </summary>
129        /// <param name="obj1">The starting object state.</param>
130        /// <param name="obj2">The ending object state.</param>
131        /// <returns>A list of RmAttributeChanges to apply to obj1 for it to look like obj2</returns>
132        public static IList<RmAttributeChange> GetDifference(RmResource obj1, RmResource obj2)
133        {
134            if (obj1 == null)
135            {
136                throw new ArgumentNullException("obj1");
137            }
138            if (obj2 == null)
139            {
140                throw new ArgumentNullException("obj2");
141            }
142            return GetDifference(obj1.attributes, obj2.attributes);
143        }
144
145        private static IList<RmAttributeChange> GetDifference(Dictionary<RmAttributeName, RmAttributeValue> attributes1, Dictionary<RmAttributeName, RmAttributeValue> attributes2)
146        {
147            IList<RmAttributeChange> changedAttributes = new List<RmAttributeChange>();
148            foreach (KeyValuePair<RmAttributeName, RmAttributeValue> item1 in attributes1)
149            {
150                if (attributes2.ContainsKey(item1.Key) == false)
151                {
152                    foreach (IComparable value1 in item1.Value.Values)
153                    {
154                        changedAttributes.Add(new RmAttributeChange(item1.Key, value1, RmAttributeChangeOperation.Add));
155                    }
156                }
157                else
158                {
159                    RmAttributeValue rmValue2 = attributes2[item1.Key];
160                    foreach (IComparable value1 in item1.Value.Values)
161                    {
162                        if (rmValue2.Values.Contains(value1) == false)
163                        {
164                            changedAttributes.Add(new RmAttributeChange(item1.Key, value1, RmAttributeChangeOperation.Add));
165                        }
166                    }
167                    foreach (IComparable value2 in rmValue2.Values)
168                    {
169                        if (item1.Value.Values.Contains(value2) == false)
170                        {
171                            changedAttributes.Add(new RmAttributeChange(item1.Key, value2, RmAttributeChangeOperation.Delete));
172                        }
173                    }
174                }
175            }
176            foreach (KeyValuePair<RmAttributeName, RmAttributeValue> item2 in attributes2)
177            {
178                if (attributes1.ContainsKey(item2.Key) == false)
179                {
180                    foreach (IComparable value2 in item2.Value.Values)
181                    {
182                        changedAttributes.Add(new RmAttributeChange(item2.Key, value2, RmAttributeChangeOperation.Delete));
183                    }
184                }
185            }
186            return changedAttributes;
187        }
188        #endregion
189    }
190}