PageRenderTime 44ms CodeModel.GetById 33ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/Libraries/Source/NHibernate/Collection/PersistentArrayHolder.cs

https://github.com/enjoii/WCell
C# | 353 lines | 255 code | 42 blank | 56 comment | 26 complexity | 3e4ec508763d2ab04718ee122acc1cde MD5 | raw file
  1using System;
  2using System.Collections;
  3using System.Data;
  4using System.Diagnostics;
  5using log4net;
  6using NHibernate.DebugHelpers;
  7using NHibernate.Engine;
  8using NHibernate.Loader;
  9using NHibernate.Persister.Collection;
 10using NHibernate.Type;
 11
 12namespace NHibernate.Collection
 13{
 14	/// <summary>
 15	/// A persistent wrapper for an array. lazy initialization is NOT supported
 16	/// </summary>
 17	[Serializable]
 18	[DebuggerTypeProxy(typeof(CollectionProxy))]
 19	public class PersistentArrayHolder : AbstractPersistentCollection
 20	{
 21		private static readonly ILog log = LogManager.GetLogger(typeof(PersistentArrayHolder));
 22
 23		/// <summary>
 24		/// The <see cref="Array"/> that NHibernate is wrapping.
 25		/// </summary>
 26		private Array array;
 27
 28		[NonSerialized]
 29		private System.Type elementClass;
 30
 31		/// <summary>
 32		/// A temporary list that holds the objects while the PersistentArrayHolder is being
 33		/// populated from the database.
 34		/// </summary>
 35		[NonSerialized]
 36		private ArrayList tempList;
 37
 38
 39		public PersistentArrayHolder(ISessionImplementor session, object array) : base(session)
 40		{
 41			this.array = (Array) array;
 42			SetInitialized();
 43		}
 44
 45		/// <summary>
 46		/// 
 47		/// </summary>
 48		/// <param name="persister"></param>
 49		/// <returns></returns>
 50		protected override ICollection Snapshot(ICollectionPersister persister)
 51		{
 52			EntityMode entityMode = Session.EntityMode;
 53
 54			int length = /*(array==null) ? temp.Count :*/ array.Length;
 55			Array result = System.Array.CreateInstance(persister.ElementClass, length);
 56			for (int i = 0; i < length; i++)
 57			{
 58				object elt = /*(array==null) ? temp[i] :*/ array.GetValue(i);
 59				try
 60				{
 61					result.SetValue(persister.ElementType.DeepCopy(elt, entityMode, persister.Factory), i);
 62				}
 63				catch (Exception e)
 64				{
 65					log.Error("Array element type error", e);
 66					throw new HibernateException("Array element type error", e);
 67				}
 68			}
 69			return result;
 70		}
 71
 72		public override ICollection GetOrphans(object snapshot, string entityName)
 73		{
 74			object[] sn = (object[]) snapshot;
 75			object[] arr = (object[]) array;
 76			ArrayList result = new ArrayList(sn.Length);
 77			for (int i = 0; i < sn.Length; i++)
 78			{
 79				result.Add(sn[i]);
 80			}
 81			for (int i = 0; i < sn.Length; i++)
 82			{
 83				IdentityRemove(result, arr[i], entityName, Session);
 84			}
 85			return result;
 86		}
 87
 88
 89		public PersistentArrayHolder(ISessionImplementor session, ICollectionPersister persister)
 90			: base(session)
 91		{
 92			elementClass = persister.ElementClass;
 93		}
 94
 95		/// <summary>
 96		/// 
 97		/// </summary>
 98		public object Array
 99		{
100			get { return array; }
101		}
102
103		/// <summary>
104		/// 
105		/// </summary>
106		/// <param name="collection"></param>
107		/// <returns></returns>
108		public override bool IsWrapper(object collection)
109		{
110			return array == collection;
111		}
112
113		public override bool EqualsSnapshot(ICollectionPersister persister)
114		{
115			IType elementType = persister.ElementType;
116			Array snapshot = GetSnapshot() as Array;
117
118			int xlen = snapshot.Length;
119			if (xlen != array.Length)
120			{
121				return false;
122			}
123			for (int i = 0; i < xlen; i++)
124			{
125				if (elementType.IsDirty(snapshot.GetValue(i), array.GetValue(i), Session))
126				{
127					return false;
128				}
129			}
130			return true;
131		}
132
133		/// <summary>
134		/// 
135		/// </summary>
136		/// <returns></returns>
137		public ICollection Elements()
138		{
139			//if (array==null) return tempList;
140			int length = array.Length;
141			IList list = new ArrayList(length);
142			for (int i = 0; i < length; i++)
143			{
144				list.Add(array.GetValue(i));
145			}
146			return list;
147		}
148
149		/// <summary>
150		/// 
151		/// </summary>
152		public override bool Empty
153		{
154			get { return false; }
155		}
156
157		public override object ReadFrom(IDataReader rs, ICollectionPersister role, ICollectionAliases descriptor, object owner)
158		{
159			object element = role.ReadElement(rs, owner, descriptor.SuffixedElementAliases, Session);
160			int index = (int) role.ReadIndex(rs, descriptor.SuffixedIndexAliases, Session);
161			for (int i = tempList.Count; i <= index; i++)
162			{
163				tempList.Add(null);
164			}
165			tempList[index] = element;
166			return element;
167		}
168
169		/// <summary>
170		/// 
171		/// </summary>
172		/// <returns></returns>
173		public override IEnumerable Entries()
174		{
175			return Elements();
176		}
177
178		/// <summary>
179		/// Before <see cref="ReadFrom" /> is called the PersistentArrayHolder needs to setup 
180		/// a temporary list to hold the objects.
181		/// </summary>
182		public override void BeginRead()
183		{
184			base.BeginRead();
185			tempList = new ArrayList();
186		}
187
188		/// <summary>
189		/// Takes the contents stored in the temporary list created during <see cref="BeginRead" />
190		/// that was populated during <see cref="ReadFrom" /> and write it to the underlying 
191		/// array.
192		/// </summary>
193		public override bool EndRead(ICollectionPersister persister)
194		{
195			SetInitialized();
196			array = System.Array.CreateInstance(elementClass, tempList.Count);
197			int index = 0;
198			foreach (object element in tempList)
199			{
200				array.SetValue(element, index);
201				index++;
202			}
203			tempList = null;
204
205			return true;
206		}
207
208		public override void BeforeInitialize(ICollectionPersister persister)
209		{
210		}
211
212		public override bool IsDirectlyAccessible
213		{
214			get { return true; }
215		}
216
217		/// <summary>
218		/// Initializes this array holder from the cached values.
219		/// </summary>
220		/// <param name="persister">The CollectionPersister to use to reassemble the Array.</param>
221		/// <param name="disassembled">The disassembled Array.</param>
222		/// <param name="owner">The owner object.</param>
223		public override void InitializeFromCache(ICollectionPersister persister, object disassembled, object owner)
224		{
225			object[] cached = (object[]) disassembled;
226
227			array = System.Array.CreateInstance(persister.ElementClass, cached.Length);
228
229			for (int i = 0; i < cached.Length; i++)
230			{
231				array.SetValue(persister.ElementType.Assemble(cached[i], Session, owner), i);
232			}
233			SetInitialized();
234		}
235
236		public override object Disassemble(ICollectionPersister persister)
237		{
238			int length = array.Length;
239			object[] result = new object[length];
240			for (int i = 0; i < length; i++)
241			{
242				result[i] = persister.ElementType.Disassemble(array.GetValue(i), Session, null);
243			}
244			return result;
245		}
246
247		/// <summary>
248		/// Returns the user-visible portion of the NHibernate PersistentArrayHolder.
249		/// </summary>
250		/// <returns>
251		/// The array that contains the data, not the NHibernate wrapper.
252		/// </returns>
253		public override object GetValue()
254		{
255			return array;
256		}
257
258		public override IEnumerable GetDeletes(IType elemType, bool indexIsFormula)
259		{
260			IList deletes = new ArrayList();
261			Array sn = GetSnapshot() as Array;
262			int snSize = sn.Length;
263			int arraySize = array.Length;
264			int end;
265			if (snSize > arraySize)
266			{
267				for (int i = arraySize; i < snSize; i++)
268				{
269					deletes.Add(i);
270				}
271				end = arraySize;
272			}
273			else
274			{
275				end = snSize;
276			}
277			for (int i = 0; i < end; i++)
278			{
279				if (array.GetValue(i) == null && sn.GetValue(i) != null)
280				{
281					deletes.Add(i);
282				}
283			}
284			return deletes;
285		}
286
287		public override bool NeedsInserting(object entry, int i, IType elemType)
288		{
289			Array sn = GetSnapshot() as Array;
290			return array.GetValue(i) != null && (i >= sn.Length || sn.GetValue(i) == null);
291		}
292
293		public override bool NeedsUpdating(object entry, int i, IType elemType)
294		{
295			Array sn = GetSnapshot() as Array;
296			return i < sn.Length &&
297			       sn.GetValue(i) != null &&
298			       array.GetValue(i) != null &&
299			       elemType.IsDirty(array.GetValue(i), sn.GetValue(i), Session);
300		}
301
302		public override object GetIndex(object entry, int i)
303		{
304			return i;
305		}
306
307		public override object GetElement(object entry)
308		{
309			return entry;
310		}
311
312		public override object GetSnapshotElement(object entry, int i)
313		{
314			Array sn = (Array) GetSnapshot();
315			return sn.GetValue(i);
316		}
317
318		public override bool EntryExists(object entry, int i)
319		{
320			return entry != null;
321		}
322
323		public void CopyTo(Array array, int index)
324		{
325			this.array.CopyTo(array, index);
326		}
327
328		public int Count
329		{
330			get { return array.Length; }
331		}
332
333		public IEnumerator GetEnumerator()
334		{
335			return array.GetEnumerator();
336		}
337
338		public bool IsSynchronized
339		{
340			get { return false; }
341		}
342
343		public object SyncRoot
344		{
345			get { return this; }
346		}
347
348		public override IEnumerable Entries(ICollectionPersister persister)
349		{
350			return Elements();
351		}
352	}
353}