From: <jul...@us...> - 2010-11-07 15:52:15
|
Revision: 5262 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5262&view=rev Author: julian-maughan Date: 2010-11-07 15:52:07 +0000 (Sun, 07 Nov 2010) Log Message: ----------- Refactor: Moved methods from TypeFactory to new class, TypeHelper (as-per Hibernate). Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Action/EntityUpdateAction.cs trunk/nhibernate/src/NHibernate/Cache/Entry/CacheEntry.cs trunk/nhibernate/src/NHibernate/Cache/StandardQueryCache.cs trunk/nhibernate/src/NHibernate/Engine/TwoPhaseLoad.cs trunk/nhibernate/src/NHibernate/Event/Default/AbstractReassociateEventListener.cs trunk/nhibernate/src/NHibernate/Event/Default/AbstractSaveEventListener.cs trunk/nhibernate/src/NHibernate/Event/Default/DefaultDeleteEventListener.cs trunk/nhibernate/src/NHibernate/Event/Default/DefaultLoadEventListener.cs trunk/nhibernate/src/NHibernate/Event/Default/DefaultMergeEventListener.cs trunk/nhibernate/src/NHibernate/Impl/MultipleQueriesCacheAssembler.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs trunk/nhibernate/src/NHibernate/Type/ComponentType.cs trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate/Type/TypeHelper.cs Modified: trunk/nhibernate/src/NHibernate/Action/EntityUpdateAction.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Action/EntityUpdateAction.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Action/EntityUpdateAction.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -90,7 +90,7 @@ // get the updated snapshot of the entity state by cloning current state; // it is safe to copy in place, since by this time no-one else (should have) // has a reference to the array - TypeFactory.DeepCopy(state, persister.PropertyTypes, persister.PropertyCheckability, state, Session); + TypeHelper.DeepCopy(state, persister.PropertyTypes, persister.PropertyCheckability, state, Session); if (persister.HasUpdateGeneratedProperties) { // this entity defines property generation, so process those generated Modified: trunk/nhibernate/src/NHibernate/Cache/Entry/CacheEntry.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cache/Entry/CacheEntry.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Cache/Entry/CacheEntry.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -21,7 +21,7 @@ public CacheEntry(object[] state, IEntityPersister persister, bool unfetched, object version, ISessionImplementor session, object owner) { //disassembled state gets put in a new array (we write to cache by value!) - disassembledState = TypeFactory.Disassemble(state, persister.PropertyTypes, null, session, owner); + disassembledState = TypeHelper.Disassemble(state, persister.PropertyTypes, null, session, owner); subclass = persister.EntityName; lazyPropertiesAreUnfetched = unfetched || !persister.IsLazyPropertiesCacheable; this.version = version; @@ -76,7 +76,7 @@ IInterceptor interceptor, ISessionImplementor session) { //assembled state gets put in a new array (we read from cache by value!) - object[] assembledProps = TypeFactory.Assemble(values, persister.PropertyTypes, session, result); + object[] assembledProps = TypeHelper.Assemble(values, persister.PropertyTypes, session, result); //from h3.2 TODO: reuse the PreLoadEvent PreLoadEvent preLoadEvent = new PreLoadEvent((IEventSource) session); Modified: trunk/nhibernate/src/NHibernate/Cache/StandardQueryCache.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cache/StandardQueryCache.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Cache/StandardQueryCache.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -83,7 +83,7 @@ } else { - cacheable.Add(TypeFactory.Disassemble((object[]) result[i], returnTypes, null, session, null)); + cacheable.Add(TypeHelper.Disassemble((object[]) result[i], returnTypes, null, session, null)); } } queryCache.Put(key, cacheable); @@ -123,7 +123,7 @@ } else { - TypeFactory.BeforeAssemble((object[])cacheable[i], returnTypes, session); + TypeHelper.BeforeAssemble((object[])cacheable[i], returnTypes, session); } } IList result = new List<object>(cacheable.Count - 1); @@ -137,7 +137,7 @@ } else { - result.Add(TypeFactory.Assemble((object[])cacheable[i], returnTypes, session, null)); + result.Add(TypeHelper.Assemble((object[])cacheable[i], returnTypes, session, null)); } } catch (UnresolvableObjectException) Modified: trunk/nhibernate/src/NHibernate/Engine/TwoPhaseLoad.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/TwoPhaseLoad.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Engine/TwoPhaseLoad.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -128,7 +128,7 @@ else { //take a snapshot - TypeFactory.DeepCopy(hydratedState, persister.PropertyTypes, persister.PropertyUpdateability, hydratedState, session); + TypeHelper.DeepCopy(hydratedState, persister.PropertyTypes, persister.PropertyUpdateability, hydratedState, session); persistenceContext.SetEntryStatus(entityEntry, Status.Loaded); } Modified: trunk/nhibernate/src/NHibernate/Event/Default/AbstractReassociateEventListener.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/AbstractReassociateEventListener.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Event/Default/AbstractReassociateEventListener.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -40,7 +40,7 @@ //get a snapshot object[] values = persister.GetPropertyValues(entity, source.EntityMode); - TypeFactory.DeepCopy(values, persister.PropertyTypes, persister.PropertyUpdateability, values, source); + TypeHelper.DeepCopy(values, persister.PropertyTypes, persister.PropertyUpdateability, values, source); object version = Versioning.GetVersion(values, persister); EntityEntry newEntry = source.PersistenceContext.AddEntity(entity, Status.Loaded, values, key, version, LockMode.None, true, persister, false, true); Modified: trunk/nhibernate/src/NHibernate/Event/Default/AbstractSaveEventListener.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/AbstractSaveEventListener.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Event/Default/AbstractSaveEventListener.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -245,7 +245,7 @@ persister.SetPropertyValues(entity, values, source.EntityMode); } - TypeFactory.DeepCopy(values, types, persister.PropertyUpdateability, values, source); + TypeHelper.DeepCopy(values, types, persister.PropertyUpdateability, values, source); new ForeignKeys.Nullifier(entity, false, useIdentityColumn, source).NullifyTransientReferences(values, types); new Nullability(source).CheckNullability(values, persister, false); Modified: trunk/nhibernate/src/NHibernate/Event/Default/DefaultDeleteEventListener.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/DefaultDeleteEventListener.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Event/Default/DefaultDeleteEventListener.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -221,7 +221,7 @@ // TypeFactory.deepCopy( currentState, propTypes, persister.getPropertyUpdateability(), deletedState, session ); bool[] copyability = new bool[propTypes.Length]; ArrayHelper.Fill(copyability, true); - TypeFactory.DeepCopy(currentState, propTypes, copyability, deletedState, session); + TypeHelper.DeepCopy(currentState, propTypes, copyability, deletedState, session); return deletedState; } Modified: trunk/nhibernate/src/NHibernate/Event/Default/DefaultLoadEventListener.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/DefaultLoadEventListener.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Event/Default/DefaultLoadEventListener.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -463,7 +463,7 @@ IType[] types = subclassPersister.PropertyTypes; object[] values = entry.Assemble(result, id, subclassPersister, session.Interceptor, session); // intializes result by side-effect - TypeFactory.DeepCopy(values, types, subclassPersister.PropertyUpdateability, values, session); + TypeHelper.DeepCopy(values, types, subclassPersister.PropertyUpdateability, values, session); object version = Versioning.GetVersion(values, subclassPersister); if (log.IsDebugEnabled) Modified: trunk/nhibernate/src/NHibernate/Event/Default/DefaultMergeEventListener.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/DefaultMergeEventListener.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Event/Default/DefaultMergeEventListener.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -350,7 +350,7 @@ protected virtual void CopyValues(IEntityPersister persister, object entity, object target, ISessionImplementor source, IDictionary copyCache) { object[] copiedValues = - TypeFactory.Replace(persister.GetPropertyValues(entity, source.EntityMode), + TypeHelper.Replace(persister.GetPropertyValues(entity, source.EntityMode), persister.GetPropertyValues(target, source.EntityMode), persister.PropertyTypes, source, target, copyCache); @@ -368,14 +368,14 @@ // replacement to associations types (value types were already replaced // during the first pass) copiedValues = - TypeFactory.ReplaceAssociations(persister.GetPropertyValues(entity, source.EntityMode), + TypeHelper.ReplaceAssociations(persister.GetPropertyValues(entity, source.EntityMode), persister.GetPropertyValues(target, source.EntityMode), persister.PropertyTypes, source, target, copyCache, foreignKeyDirection); } else { copiedValues = - TypeFactory.Replace(persister.GetPropertyValues(entity, source.EntityMode), + TypeHelper.Replace(persister.GetPropertyValues(entity, source.EntityMode), persister.GetPropertyValues(target, source.EntityMode), persister.PropertyTypes, source, target, copyCache, foreignKeyDirection); } Modified: trunk/nhibernate/src/NHibernate/Impl/MultipleQueriesCacheAssembler.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultipleQueriesCacheAssembler.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Impl/MultipleQueriesCacheAssembler.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -34,7 +34,7 @@ } else { - singleQueryCached.Add(TypeFactory.Disassemble((object[]) objToCache, assemblers, null, session, null)); + singleQueryCached.Add(TypeHelper.Disassemble((object[]) objToCache, assemblers, null, session, null)); } } cacheable.Add(singleQueryCached); @@ -59,7 +59,7 @@ } else { - queryResults.Add(TypeFactory.Assemble((object[]) fromCache, assemblers, session, owner)); + queryResults.Add(TypeHelper.Assemble((object[]) fromCache, assemblers, session, owner)); } } result.Add(queryResults); Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-11-07 15:52:07 UTC (rev 5262) @@ -412,6 +412,7 @@ <Compile Include="Type\TimeType.cs" /> <Compile Include="Type\TrueFalseType.cs" /> <Compile Include="Type\TypeFactory.cs" /> + <Compile Include="Type\TypeHelper.cs" /> <Compile Include="Type\TypeType.cs" /> <Compile Include="Type\UInt16Type.cs" /> <Compile Include="Type\UInt32Type.cs" /> Modified: trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -3515,7 +3515,7 @@ public virtual int[] FindDirty(object[] currentState, object[] previousState, object entity, ISessionImplementor session) { - int[] props = TypeFactory.FindDirty( + int[] props = TypeHelper.FindDirty( entityMetamodel.Properties, currentState, previousState, propertyColumnUpdateable, HasUninitializedLazyProperties(entity, session.EntityMode), session); if (props == null) @@ -3531,7 +3531,7 @@ public virtual int[] FindModified(object[] old, object[] current, object entity, ISessionImplementor session) { - int[] props = TypeFactory.FindModified( + int[] props = TypeHelper.FindModified( entityMetamodel.Properties, current, old, propertyColumnUpdateable, HasUninitializedLazyProperties(entity, session.EntityMode), session); if (props == null) { Modified: trunk/nhibernate/src/NHibernate/Type/ComponentType.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Type/ComponentType.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Type/ComponentType.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -376,7 +376,7 @@ object result = target ?? Instantiate(owner, session); EntityMode entityMode = session.EntityMode; - object[] values = TypeFactory.Replace(GetPropertyValues(original, entityMode), GetPropertyValues(result, entityMode), propertyTypes, session, owner, copiedAlready); + object[] values = TypeHelper.Replace(GetPropertyValues(original, entityMode), GetPropertyValues(result, entityMode), propertyTypes, session, owner, copiedAlready); SetPropertyValues(result, values, entityMode); return result; @@ -390,7 +390,7 @@ object result = target ?? Instantiate(owner, session); EntityMode entityMode = session.EntityMode; - object[] values = TypeFactory.Replace(GetPropertyValues(original, entityMode), GetPropertyValues(result, entityMode), propertyTypes, session, owner, copyCache, foreignKeyDirection); + object[] values = TypeHelper.Replace(GetPropertyValues(original, entityMode), GetPropertyValues(result, entityMode), propertyTypes, session, owner, copyCache, foreignKeyDirection); SetPropertyValues(result, values, entityMode); return result; Modified: trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs 2010-11-07 15:51:01 UTC (rev 5261) +++ trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -8,10 +8,7 @@ using NHibernate.Bytecode; using NHibernate.Classic; using NHibernate.Engine; -using NHibernate.Intercept; -using NHibernate.Properties; using NHibernate.SqlTypes; -using NHibernate.Tuple; using NHibernate.UserTypes; using NHibernate.Util; using System.Runtime.CompilerServices; @@ -24,7 +21,7 @@ /// <remarks> /// Applications should use static methods and constants on NHibernate.NHibernateUtil if the default /// IType is good enough. For example, the TypeFactory should only be used when the String needs - /// to have a length of 300 instead of 255. At this point NHibernate.String does not get you the + /// to have a length of 300 instead of 255. At this point NHibernate.String does not get you the /// correct IType. Instead use TypeFactory.GetString(300) and keep a local variable that holds /// a reference to the IType. /// </remarks> @@ -44,11 +41,11 @@ private static readonly System.Type[] GenericCollectionSimpleSignature = new[] { typeof(string), typeof(string), typeof(bool) }; /* - * Maps the string representation of the type to the IType. The string + * Maps the string representation of the type to the IType. The string * representation is how the type will appear in the mapping file and in * name of the IType.Name. The list below provides a few examples of how * the Key/Value pair will be. - * + * * key -> value * "System.DateTime" -> instance of DateTimeType * "System.DateTime, fully assembly name" -> instance of DateTimeType @@ -86,7 +83,7 @@ RegisterType(nhibernateType, typeAliases); } - private static void RegisterType(System.Type systemType, IType nhibernateType, + private static void RegisterType(System.Type systemType, IType nhibernateType, IEnumerable<string> aliases, GetNullableTypeWithLength ctorLength) { var typeAliases = new List<string>(aliases); @@ -108,7 +105,7 @@ { var typeAliases = new List<string> { - systemType.FullName, + systemType.FullName, systemType.AssemblyQualifiedName, }; if (systemType.IsValueType) @@ -276,15 +273,15 @@ /// <returns>The Type of Classification</returns> /// <remarks> /// This parses through the string and makes the assumption that no class - /// name and no assembly name will contain the <c>"("</c>. + /// name and no assembly name will contain the <c>"("</c>. /// <para> - /// If it finds - /// the <c>"("</c> and then finds a <c>","</c> afterwards then it is a - /// <c>TypeClassification.PrecisionScale</c>. + /// If it finds + /// the <c>"("</c> and then finds a <c>","</c> afterwards then it is a + /// <c>TypeClassification.PrecisionScale</c>. /// </para> /// <para> /// If it finds the <c>"("</c> - /// and doesn't find a <c>","</c> afterwards, then it is a + /// and doesn't find a <c>","</c> afterwards, then it is a /// <c>TypeClassification.Length</c>. /// </para> /// <para> @@ -320,7 +317,7 @@ /// <summary> /// Given the name of a Hibernate type such as Decimal, Decimal(19,0) - /// , Int32, or even NHibernate.Type.DecimalType, NHibernate.Type.DecimalType(19,0), + /// , Int32, or even NHibernate.Type.DecimalType, NHibernate.Type.DecimalType(19,0), /// NHibernate.Type.Int32Type, then return an instance of NHibernate.Type.IType /// </summary> /// <param name="name">The name of the type.</param> @@ -341,7 +338,7 @@ } // if we get to here then the basic type with the length or precision/scale - // combination doesn't exists - so lets figure out which one we have and + // combination doesn't exists - so lets figure out which one we have and // invoke the appropriate delegate TypeClassification typeClassification = GetTypeClassification(name); @@ -430,8 +427,8 @@ } /// <summary> - /// Uses heuristics to deduce a NHibernate type given a string naming the - /// type. + /// Uses heuristics to deduce a NHibernate type given a string naming the + /// type. /// </summary> /// <param name="typeName"></param> /// <returns>An instance of <c>NHibernate.Type.IType</c></returns> @@ -439,9 +436,9 @@ /// When looking for the NHibernate type it will look in the cache of the Basic types first. /// If it doesn't find it in the cache then it uses the typeName to get a reference to the /// Class (Type in .NET). Once we get the reference to the .NET class we check to see if it - /// implements IType, ICompositeUserType, IUserType, ILifecycle (Association), or + /// implements IType, ICompositeUserType, IUserType, ILifecycle (Association), or /// IPersistentEnum. If none of those are implemented then we will serialize the Type to the - /// database using NHibernate.Type.SerializableType(typeName) + /// database using NHibernate.Type.SerializableType(typeName) /// </remarks> public static IType HeuristicType(string typeName) { @@ -449,8 +446,8 @@ } /// <summary> - /// Uses heuristics to deduce a NHibernate type given a string naming the - /// type. + /// Uses heuristics to deduce a NHibernate type given a string naming the + /// type. /// </summary> /// <param name="typeName">the type name</param> /// <param name="parameters">parameters for the type</param> @@ -563,7 +560,7 @@ /// <returns>A BinaryType</returns> /// <remarks> /// In addition to returning the BinaryType it will also ensure that it has - /// been added to the basicNameMap with the keys <c>Byte[](length)</c> and + /// been added to the basicNameMap with the keys <c>Byte[](length)</c> and /// <c>NHibernate.Type.BinaryType(length)</c>. /// </remarks> [MethodImpl(MethodImplOptions.Synchronized)] @@ -621,7 +618,7 @@ /// <para> /// In addition to returning the SerializableType it will also ensure that it has /// been added to the basicNameMap with the keys <c>Type.FullName</c> (the result - /// of <c>IType.Name</c> and <c>Type.AssemblyQualifiedName</c>. This is different + /// of <c>IType.Name</c> and <c>Type.AssemblyQualifiedName</c>. This is different /// from the other items put in the basicNameMap because it is uses the AQN and the /// FQN as opposed to the short name used in the maps and the FQN. /// </para> @@ -876,284 +873,6 @@ return (CollectionType)mi.Invoke(Instance.CollectionTypeFactory, new object[] { role, propertyRef, false }); } - /// <summary> Deep copy a series of values from one array to another... </summary> - /// <param name="values">The values to copy (the source) </param> - /// <param name="types">The value types </param> - /// <param name="copy">an array indicating which values to include in the copy </param> - /// <param name="target">The array into which to copy the values </param> - /// <param name="session">The originating session </param> - public static void DeepCopy(object[] values, IType[] types, bool[] copy, object[] target, ISessionImplementor session) - { - for (int i = 0; i < types.Length; i++) - { - if (copy[i]) - { - if (values[i] == LazyPropertyInitializer.UnfetchedProperty || values[i] == BackrefPropertyAccessor.Unknown) - { - target[i] = values[i]; - } - else - { - target[i] = types[i].DeepCopy(values[i], session.EntityMode, session.Factory); - } - } - } - } - - /// <summary> Apply the <see cref="ICacheAssembler.BeforeAssemble"/> operation across a series of values. </summary> - /// <param name="row">The values </param> - /// <param name="types">The value types </param> - /// <param name="session">The originating session </param> - public static void BeforeAssemble(object[] row, ICacheAssembler[] types, ISessionImplementor session) - { - for (int i = 0; i < types.Length; i++) - { - if (row[i] != LazyPropertyInitializer.UnfetchedProperty && row[i] != BackrefPropertyAccessor.Unknown) - { - types[i].BeforeAssemble(row[i], session); - } - } - } - /// <summary> - /// Determine if any of the given field values are dirty, - /// returning an array containing indexes of - /// the dirty fields or null if no fields are dirty. - /// </summary> - public static int[] FindDirty( - StandardProperty[] properties, - object[] x, - object[] y, - bool[][] includeColumns, - bool anyUninitializedProperties, - ISessionImplementor session) - { - int[] results = null; - int count = 0; - int span = properties.Length; - - for (int i = 0; i < span; i++) - { - bool dirty = - // TODO H3: x[ i ] != LazyPropertyInitializer.UnfetchedProperty && //x is the "current" state - properties[i].IsDirtyCheckable(anyUninitializedProperties) - && properties[i].Type.IsDirty(y[i], x[i], includeColumns[i], session); - - if (dirty) - { - if (results == null) - { - results = new int[span]; - } - results[count++] = i; - } - } - if (count == 0) - { - return null; - } - else - { - int[] trimmed = new int[count]; - System.Array.Copy(results, 0, trimmed, 0, count); - return trimmed; - } - } - - /// <summary> - /// Determine if any of the given field values are modified, - /// returning an array containing indexes of - /// the dirty fields or null if no fields are modified. - /// </summary> - public static int[] FindModified( - StandardProperty[] properties, - object[] x, - object[] y, - bool[][] includeColumns, - bool anyUninitializedProperties, - ISessionImplementor session) - { - int[] results = null; - int count = 0; - int span = properties.Length; - - for (int i = 0; i < span; i++) - { - bool dirty = - // TODO H3: x[ i ] != LazyPropertyInitializer.UnfetchedProperty && //x is the "current" state - properties[i].IsDirtyCheckable(anyUninitializedProperties) - && properties[i].Type.IsModified(y[i], x[i], includeColumns[i], session); - - if (dirty) - { - if (results == null) - { - results = new int[span]; - } - results[count++] = i; - } - } - if (count == 0) - { - return null; - } - else - { - int[] trimmed = new int[count]; - System.Array.Copy(results, 0, trimmed, 0, count); - return trimmed; - } - } - - /// <summary> - /// - /// </summary> - /// <param name="row"></param> - /// <param name="types"></param> - /// <param name="session"></param> - /// <param name="owner"></param> - /// <returns></returns> - public static object[] Assemble(object[] row, ICacheAssembler[] types, ISessionImplementor session, object owner) - { - object[] assembled = new object[row.Length]; - for (int i = 0; i < row.Length; i++) - { - assembled[i] = types[i].Assemble(row[i], session, owner); - } - return assembled; - } - - /// <summary> Apply the {@link Type#disassemble} operation across a series of values. </summary> - /// <param name="row">The values </param> - /// <param name="types">The value types </param> - /// <param name="nonCacheable">An array indicating which values to include in the disassembled state </param> - /// <param name="session">The originating session </param> - /// <param name="owner">The entity "owning" the values </param> - /// <returns> The disassembled state </returns> - public static object[] Disassemble(object[] row, ICacheAssembler[] types, bool[] nonCacheable, ISessionImplementor session, object owner) - { - object[] disassembled = new object[row.Length]; - for (int i = 0; i < row.Length; i++) - { - if (nonCacheable != null && nonCacheable[i]) - { - disassembled[i] = LazyPropertyInitializer.UnfetchedProperty; - } - else if (row[i] == LazyPropertyInitializer.UnfetchedProperty || row[i] == BackrefPropertyAccessor.Unknown) - { - disassembled[i] = row[i]; - } - else - { - disassembled[i] = types[i].Disassemble(row[i], session, owner); - } - } - return disassembled; - } - - - /// <summary> - /// Apply the <see cref="IType.Replace(object, object, ISessionImplementor, object, IDictionary)"/> operation across a series of values. - /// </summary> - /// <param name="original">The source of the state </param> - /// <param name="target">The target into which to replace the source values. </param> - /// <param name="types">The value types </param> - /// <param name="session">The originating session </param> - /// <param name="owner">The entity "owning" the values </param> - /// <param name="copiedAlready">Represent a cache of already replaced state </param> - /// <returns> The replaced state </returns> - public static object[] Replace(object[] original, object[] target, IType[] types, ISessionImplementor session, - object owner, IDictionary copiedAlready) - { - object[] copied = new object[original.Length]; - for (int i = 0; i < original.Length; i++) - { - copied[i] = types[i].Replace(original[i], target[i], session, owner, copiedAlready); - } - return copied; - } - - /// <summary> - /// Apply the <see cref="IType.Replace(object, object, ISessionImplementor, object, IDictionary, ForeignKeyDirection)"/> - /// operation across a series of values. - /// </summary> - /// <param name="original">The source of the state </param> - /// <param name="target">The target into which to replace the source values. </param> - /// <param name="types">The value types </param> - /// <param name="session">The originating session </param> - /// <param name="owner">The entity "owning" the values </param> - /// <param name="copyCache">A map representing a cache of already replaced state </param> - /// <param name="foreignKeyDirection">FK directionality to be applied to the replacement </param> - /// <returns> The replaced state </returns> - public static object[] Replace(object[] original, object[] target, IType[] types, - ISessionImplementor session, object owner, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection) - { - object[] copied = new object[original.Length]; - for (int i = 0; i < types.Length; i++) - { - if (original[i] == LazyPropertyInitializer.UnfetchedProperty || original[i] == BackrefPropertyAccessor.Unknown) - { - copied[i] = target[i]; - } - else - copied[i] = types[i].Replace(original[i], target[i], session, owner, copyCache, foreignKeyDirection); - } - return copied; - } - - /// <summary> - /// Apply the <see cref="IType.Replace(object, object, ISessionImplementor, object, IDictionary, ForeignKeyDirection)"/> - /// operation across a series of values, as - /// long as the corresponding <see cref="IType"/> is an association. - /// </summary> - /// <param name="original">The source of the state </param> - /// <param name="target">The target into which to replace the source values. </param> - /// <param name="types">The value types </param> - /// <param name="session">The originating session </param> - /// <param name="owner">The entity "owning" the values </param> - /// <param name="copyCache">A map representing a cache of already replaced state </param> - /// <param name="foreignKeyDirection">FK directionality to be applied to the replacement </param> - /// <returns> The replaced state </returns> - /// <remarks> - /// If the corresponding type is a component type, then apply <see cref="ReplaceAssociations"/> - /// across the component subtypes but do not replace the component value itself. - /// </remarks> - public static object[] ReplaceAssociations(object[] original, object[] target, IType[] types, - ISessionImplementor session, object owner, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection) - { - object[] copied = new object[original.Length]; - for (int i = 0; i < types.Length; i++) - { - if (original[i] == LazyPropertyInitializer.UnfetchedProperty || original[i] == BackrefPropertyAccessor.Unknown) - { - copied[i] = target[i]; - } - else if (types[i].IsComponentType) - { - // need to extract the component values and check for subtype replacements... - IAbstractComponentType componentType = (IAbstractComponentType)types[i]; - IType[] subtypes = componentType.Subtypes; - object[] origComponentValues = original[i] == null ? new object[subtypes.Length] : componentType.GetPropertyValues(original[i], session); - object[] targetComponentValues = target[i] == null ? new object[subtypes.Length] : componentType.GetPropertyValues(target[i], session); - - object[] componentCopy = ReplaceAssociations(origComponentValues, targetComponentValues, subtypes, session, null, copyCache, foreignKeyDirection); - - if (!componentType.IsAnyType && target[i] != null) - componentType.SetPropertyValues(target[i], componentCopy, session.EntityMode); - - copied[i] = target[i]; - } - else if (!types[i].IsAssociationType) - { - copied[i] = target[i]; - } - else - { - copied[i] = types[i].Replace(original[i], target[i], session, owner, copyCache, foreignKeyDirection); - } - } - return copied; - } - public static CollectionType CustomCollection(string typeName, IDictionary<string, string> typeParameters, string role, string propertyRef, bool embedded) { Added: trunk/nhibernate/src/NHibernate/Type/TypeHelper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Type/TypeHelper.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Type/TypeHelper.cs 2010-11-07 15:52:07 UTC (rev 5262) @@ -0,0 +1,304 @@ +using System; +using System.Collections; +using NHibernate.Engine; +using NHibernate.Intercept; +using NHibernate.Properties; +using NHibernate.Tuple; + +namespace NHibernate.Type +{ + /// <summary> + /// Collection of convenience methods relating to operations across arrays of types... + /// </summary> + public static class TypeHelper + { + /// <summary>Deep copy a series of values from one array to another</summary> + /// <param name="values">The values to copy (the source)</param> + /// <param name="types">The value types</param> + /// <param name="copy">An array indicating which values to include in the copy</param> + /// <param name="target">The array into which to copy the values</param> + /// <param name="session">The originating session</param> + public static void DeepCopy(object[] values, IType[] types, bool[] copy, object[] target, ISessionImplementor session) + { + for (int i = 0; i < types.Length; i++) + { + if (copy[i]) + { + if (values[i] == LazyPropertyInitializer.UnfetchedProperty || values[i] == BackrefPropertyAccessor.Unknown) + { + target[i] = values[i]; + } + else + { + target[i] = types[i].DeepCopy(values[i], session.EntityMode, session.Factory); + } + } + } + } + + /// <summary>Apply the <see cref="ICacheAssembler.BeforeAssemble" /> operation across a series of values.</summary> + /// <param name="row">The values</param> + /// <param name="types">The value types</param> + /// <param name="session">The originating session</param> + public static void BeforeAssemble(object[] row, ICacheAssembler[] types, ISessionImplementor session) + { + for (int i = 0; i < types.Length; i++) + { + if (row[i] != LazyPropertyInitializer.UnfetchedProperty && row[i] != BackrefPropertyAccessor.Unknown) + { + types[i].BeforeAssemble(row[i], session); + } + } + } + + /// <summary> + /// Apply the <see cref="ICacheAssembler.Assemble" /> operation across a series of values. + /// </summary> + /// <param name="row">The values</param> + /// <param name="types">The value types</param> + /// <param name="session">The originating session</param> + /// <param name="owner">The entity "owning" the values</param> + /// <returns></returns> + public static object[] Assemble(object[] row, ICacheAssembler[] types, ISessionImplementor session, object owner) + { + object[] assembled = new object[row.Length]; + for (int i = 0; i < row.Length; i++) + { + assembled[i] = types[i].Assemble(row[i], session, owner); + } + return assembled; + } + + /// <summary>Apply the <see cref="ICacheAssembler.Disassemble" /> operation across a series of values.</summary> + /// <param name="row">The values</param> + /// <param name="types">The value types</param> + /// <param name="nonCacheable">An array indicating which values to include in the disassembled state</param> + /// <param name="session">The originating session</param> + /// <param name="owner">The entity "owning" the values</param> + /// <returns> The disassembled state</returns> + public static object[] Disassemble(object[] row, ICacheAssembler[] types, bool[] nonCacheable, ISessionImplementor session, object owner) + { + object[] disassembled = new object[row.Length]; + for (int i = 0; i < row.Length; i++) + { + if (nonCacheable != null && nonCacheable[i]) + { + disassembled[i] = LazyPropertyInitializer.UnfetchedProperty; + } + else if (row[i] == LazyPropertyInitializer.UnfetchedProperty || row[i] == BackrefPropertyAccessor.Unknown) + { + disassembled[i] = row[i]; + } + else + { + disassembled[i] = types[i].Disassemble(row[i], session, owner); + } + } + return disassembled; + } + + /// <summary> + /// Apply the <see cref="IType.Replace(object, object, ISessionImplementor, object, IDictionary)" /> operation across a series of values. + /// </summary> + /// <param name="original">The source of the state</param> + /// <param name="target">The target into which to replace the source values.</param> + /// <param name="types">The value types</param> + /// <param name="session">The originating session</param> + /// <param name="owner">The entity "owning" the values</param> + /// <param name="copiedAlready">Represent a cache of already replaced state</param> + /// <returns> The replaced state</returns> + public static object[] Replace(object[] original, object[] target, IType[] types, ISessionImplementor session, + object owner, IDictionary copiedAlready) + { + object[] copied = new object[original.Length]; + for (int i = 0; i < original.Length; i++) + { + copied[i] = types[i].Replace(original[i], target[i], session, owner, copiedAlready); + } + return copied; + } + + /// <summary> + /// Apply the <see cref="IType.Replace(object, object, ISessionImplementor, object, IDictionary, ForeignKeyDirection)" /> + /// operation across a series of values. + /// </summary> + /// <param name="original">The source of the state</param> + /// <param name="target">The target into which to replace the source values.</param> + /// <param name="types">The value types</param> + /// <param name="session">The originating session</param> + /// <param name="owner">The entity "owning" the values</param> + /// <param name="copyCache">A map representing a cache of already replaced state</param> + /// <param name="foreignKeyDirection">FK directionality to be applied to the replacement</param> + /// <returns> The replaced state</returns> + public static object[] Replace(object[] original, object[] target, IType[] types, + ISessionImplementor session, object owner, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection) + { + object[] copied = new object[original.Length]; + for (int i = 0; i < types.Length; i++) + { + if (original[i] == LazyPropertyInitializer.UnfetchedProperty || original[i] == BackrefPropertyAccessor.Unknown) + { + copied[i] = target[i]; + } + else + copied[i] = types[i].Replace(original[i], target[i], session, owner, copyCache, foreignKeyDirection); + } + return copied; + } + + /// <summary> + /// Apply the <see cref="IType.Replace(object, object, ISessionImplementor, object, IDictionary, ForeignKeyDirection)" /> + /// operation across a series of values, as long as the corresponding <see cref="IType"/> is an association. + /// </summary> + /// <param name="original">The source of the state</param> + /// <param name="target">The target into which to replace the source values.</param> + /// <param name="types">The value types</param> + /// <param name="session">The originating session</param> + /// <param name="owner">The entity "owning" the values</param> + /// <param name="copyCache">A map representing a cache of already replaced state</param> + /// <param name="foreignKeyDirection">FK directionality to be applied to the replacement</param> + /// <returns> The replaced state</returns> + /// <remarks> + /// If the corresponding type is a component type, then apply <see cref="ReplaceAssociations" /> + /// across the component subtypes but do not replace the component value itself. + /// </remarks> + public static object[] ReplaceAssociations(object[] original, object[] target, IType[] types, + ISessionImplementor session, object owner, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection) + { + object[] copied = new object[original.Length]; + for (int i = 0; i < types.Length; i++) + { + if (original[i] == LazyPropertyInitializer.UnfetchedProperty || original[i] == BackrefPropertyAccessor.Unknown) + { + copied[i] = target[i]; + } + else if (types[i].IsComponentType) + { + // need to extract the component values and check for subtype replacements... + IAbstractComponentType componentType = (IAbstractComponentType)types[i]; + IType[] subtypes = componentType.Subtypes; + object[] origComponentValues = original[i] == null ? new object[subtypes.Length] : componentType.GetPropertyValues(original[i], session); + object[] targetComponentValues = target[i] == null ? new object[subtypes.Length] : componentType.GetPropertyValues(target[i], session); + + object[] componentCopy = ReplaceAssociations(origComponentValues, targetComponentValues, subtypes, session, null, copyCache, foreignKeyDirection); + + if (!componentType.IsAnyType && target[i] != null) + componentType.SetPropertyValues(target[i], componentCopy, session.EntityMode); + + copied[i] = target[i]; + } + else if (!types[i].IsAssociationType) + { + copied[i] = target[i]; + } + else + { + copied[i] = types[i].Replace(original[i], target[i], session, owner, copyCache, foreignKeyDirection); + } + } + return copied; + } + + /// <summary> + /// <para>Determine if any of the given field values are dirty, returning an array containing + /// indices of the dirty fields.</para> + /// <para>If it is determined that no fields are dirty, null is returned.</para> + /// </summary> + /// <param name="properties">The property definitions</param> + /// <param name="x">The current state of the entity</param> + /// <param name="y">The baseline state of the entity</param> + /// <param name="includeColumns">Columns to be included in the dirty checking, per property</param> + /// <param name="anyUninitializedProperties">Does the entity currently hold any uninitialized property values?</param> + /// <param name="session">The session from which the dirty check request originated.</param> + /// <returns>Array containing indices of the dirty properties, or null if no properties considered dirty.</returns> + public static int[] FindDirty(StandardProperty[] properties, + object[] currentState, + object[] previousState, + bool[][] includeColumns, + bool anyUninitializedProperties, + ISessionImplementor session) + { + int[] results = null; + int count = 0; + int span = properties.Length; + + for (int i = 0; i < span; i++) + { + bool dirty = + // TODO H3: x[ i ] != LazyPropertyInitializer.UnfetchedProperty && //x is the "current" state + properties[i].IsDirtyCheckable(anyUninitializedProperties) + && properties[i].Type.IsDirty(previousState[i], currentState[i], includeColumns[i], session); + + if (dirty) + { + if (results == null) + { + results = new int[span]; + } + results[count++] = i; + } + } + if (count == 0) + { + return null; + } + else + { + int[] trimmed = new int[count]; + System.Array.Copy(results, 0, trimmed, 0, count); + return trimmed; + } + } + + /// <summary> + /// <para>Determine if any of the given field values are modified, returning an array containing + /// indices of the modified fields.</para> + /// <para>If it is determined that no fields are dirty, null is returned.</para> + /// </summary> + /// <param name="properties">The property definitions</param> + /// <param name="x">The current state of the entity</param> + /// <param name="y">The baseline state of the entity</param> + /// <param name="includeColumns">Columns to be included in the mod checking, per property</param> + /// <param name="anyUninitializedProperties">Does the entity currently hold any uninitialized property values?</param> + /// <param name="session">The session from which the dirty check request originated.</param> + /// <returns>Array containing indices of the modified properties, or null if no properties considered modified.</returns> + public static int[] FindModified(StandardProperty[] properties, + object[] currentState, + object[] previousState, + bool[][] includeColumns, + bool anyUninitializedProperties, + ISessionImplementor session) + { + int[] results = null; + int count = 0; + int span = properties.Length; + + for (int i = 0; i < span; i++) + { + bool dirty = + // TODO H3: x[ i ] != LazyPropertyInitializer.UnfetchedProperty && //x is the "current" state + properties[i].IsDirtyCheckable(anyUninitializedProperties) + && properties[i].Type.IsModified(previousState[i], currentState[i], includeColumns[i], session); + + if (dirty) + { + if (results == null) + { + results = new int[span]; + } + results[count++] = i; + } + } + if (count == 0) + { + return null; + } + else + { + int[] trimmed = new int[count]; + System.Array.Copy(results, 0, trimmed, 0, count); + return trimmed; + } + } + } +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |