Ejemplo n.º 1
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// This is the heart of CopyObject Pass 2.
        /// Sets the references recursively. Needs to go down recursively into
        /// all of the source object's owned properties looking for Reference
        /// properties, since those owned properties will have just been copied too.
        /// </summary>
        /// <param name="source">The source.</param>
        /// ------------------------------------------------------------------------------------
        private void SetReferencesRecursively(ICmObject source)
        {
            // Get the copy of our source object in which to set references.
            ICmObject newObj;
            int       hvoSrc = source.Hvo;

            if (!m_sourceToCopyMap.TryGetValue(hvoSrc, out newObj))
            {
                throw new ArgumentOutOfRangeException("source", "Can't find copy of original object in copy map.");
            }

            if (source is ICloneableCmObject)
            {
                return;                 // Assume that the object handled this itself
            }
            // TODO: Copy references from source object to copied object unless reference is to something in the sourceToCopyMap
            // in that case replace it with a reference to the copied version.
            // We'll need to go down inside of all owned objects to do this too, since they were just copied.
            int srcClsID = source.ClassID;
            int hvoCopy  = newObj.Hvo;

            int[] srcFlids = GetAllFieldsFromClassId(srcClsID);

            // Clone each owned flid and copy basic properties
            for (int i = 0; i < srcFlids.Length; i++)
            {
                int thisFlid = srcFlids[i];
                // If thisFlid is part of CmObject, this Flid of copied object has
                //   already been correctly set on creation.
                // Also skip virtual fields; let the object handle its own virtuals.
                if (thisFlid < 200 || m_mdc.get_IsVirtual(thisFlid))
                {
                    continue;
                }

                // Skip basic/string properties this pass
                int flidType = m_mdc.GetFieldType(thisFlid);
                if (flidType < (int)CellarPropertyType.MinObj)
                {
                    continue;
                }

                // Only have reference and owned props left
                if (m_cache.IsReferenceProperty(thisFlid))
                {
                    SetReferencesForReferenceFlid(thisFlid, flidType, hvoSrc, hvoCopy);
                }
                else
                {
                    SetReferencesForOwnedFlid(thisFlid, flidType, hvoSrc);
                }
            }
        }