Esempio n. 1
0
        /// <summary>
        /// Merge the changed members (recursively) from one object into another.
        ///
        /// <para/>
        /// This function will recurse through the members of the "from" object and
        /// take all the members that have a change flag set and copy them into the "into"
        /// object.
        /// </summary>
        /// <param name="into">Object to merge into.</param>
        /// <param name="from">Object whose changes shall be merged into "into".</param>
        public static void MergeChanges(Object into, Object from)
        {
            if (from == null || into == null)
            {
                throw new SoftwareViolationException("Objects must not be null in call to MergeChanges");
            }

            if (from.GetTypeId() != into.GetTypeId())
            {
                throw new SoftwareViolationException("Objects must have same TypeId for MergeChanges");
            }

            try
            {
                System.Int32 numMembers = Members.GetNumberOfMembers(into.GetTypeId());
                for (System.Int32 member = 0; member < numMembers; ++member)
                {
                    System.Int32 arraySize = Members.GetArraySize(into.GetTypeId(), member);
                    for (System.Int32 index = 0; index < arraySize; ++index)
                    {
                        ContainerBase fromContainerB = from.GetMember(member, index);
                        ContainerBase intoContainerB = into.GetMember(member, index);

                        //is it an object member?
                        if (fromContainerB is ObjectContainerBase)
                        {
                            ObjectContainerBase fromContainerOB = fromContainerB as ObjectContainerBase;
                            ObjectContainerBase intoContainerOB = intoContainerB as ObjectContainerBase;

                            if (fromContainerOB.IsChangedHere()) //this specific member has changed
                            {
                                if (fromContainerOB.IsNull())
                                {
                                    intoContainerOB.SetNull();
                                }
                                else
                                {
                                    intoContainerOB.InternalObj = fromContainerOB.InternalObj.Clone();
                                    intoContainerOB.SetChangedHere(true);
                                }
                            }
                            else if (fromContainerOB.IsChanged()) //some child has changed we need to recurse
                            {
                                //unless the type has changed or the into-member is null
                                if (intoContainerOB.IsNull() || intoContainerOB.InternalObj.GetTypeId() != fromContainerOB.InternalObj.GetTypeId())
                                {
                                    //If the type is changing we write a warning
                                    if (!intoContainerOB.IsNull())
                                    {
                                        System.Console.WriteLine("Warning (Contact a DOB developer if you do not understand it):");
                                        System.Console.WriteLine("The type of a member has changed without the change flag being set in 'from'.");
                                    }

                                    //if it was null we don't warn (even if it is a little bit suspicious to do that...)

                                    intoContainerOB.InternalObj = fromContainerOB.InternalObj.Clone();
                                    intoContainerOB.SetChangedHere(true);
                                }
                                else
                                {
                                    //recurse
                                    MergeChanges(intoContainerOB.InternalObj, fromContainerOB.InternalObj);
                                }
                            }
                        }
                        else //no, normal member
                        {
                            if (fromContainerB.IsChanged())
                            {
                                intoContainerB.Copy(fromContainerB);
                            }
                        }
                    }
                }
            }
            catch (System.InvalidCastException exc)
            {
                throw new SoftwareViolationException("Cast failed inside MergeChanges" + exc.Message);
            }
        }
 /// <summary>
 /// Copy constructor.
 /// </summary>
 /// <param name="other">ObjectContainerBase.</param>
 protected ObjectContainerBase(ObjectContainerBase other) : base(other)
 {
 }