Ejemplo n.º 1
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Creates a new top-level owned object.
        /// </summary>
        /// <param name="srcFactory">The factory for creating the object.</param>
        /// <returns>The created object</returns>
        /// ------------------------------------------------------------------------------------
        private TTopLevel CreateTopLevelOwnedObj(ILcmFactoryInternal srcFactory)
        {
            // This is the top-level object we are copying so we need to add it to its
            // correct owner.
            TTopLevel newObj = (TTopLevel)srcFactory.CreateInternal();

            m_topLevelOwnerFunct(newObj);
            return(newObj);
        }
Ejemplo n.º 2
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Creates a new unowned object
        /// </summary>
        /// <typeparam name="TObj">The type of object</typeparam>
        /// <param name="srcFactory">The factory used to create the object</param>
        /// <param name="classId">The class id of the object</param>
        /// <returns>The created object</returns>
        /// ------------------------------------------------------------------------------------
        private TObj CreateUnownedObj <TObj>(ILcmFactoryInternal srcFactory, int classId)
            where TObj : ICmObject
        {
            TObj obj = (TObj)srcFactory.CreateInternal();

            if (!obj.IsValidObject)
            {
                throw new ArgumentException("Factory failed to create a valid object", "srcFactory");
            }

            return(obj);
        }
Ejemplo n.º 3
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// This is the heart of CopyObject Pass 1.
        /// Clones all owned objects (OA, OS, OC) and the source LCM object.
        /// Does nothing with reference objects (RA, RS, RC), these are in 2nd pass.
        /// Basic properties are just copied straight across. Returns the new object.
        /// </summary>
        /// <typeparam name="TObj">The type of object</typeparam>
        /// <param name="srcObj">LCM object to clone</param>
        /// <returns>The cloned object</returns>
        /// ------------------------------------------------------------------------------------
        private TObj CloneLcmObjectsRecursively <TObj>(TObj srcObj) where TObj : ICmObject
        {
            if (srcObj == null)
            {
                return(srcObj);
            }

            int srcClsID = srcObj.ClassID;

            // Review: Is this necessary? How could this ever be true?
            if (m_mdc.GetAbstract(srcClsID))
            {
                throw new ArgumentNullException("source", "Source object is Abstract; not copyable!");
            }
            ILcmFactoryInternal srcFactory = (ILcmFactoryInternal)m_servLoc.GetInstance(
                GetServicesFromFWClass.GetFactoryTypeFromFWClassID(m_mdc, srcClsID));

            if (srcFactory == null)
            {
                throw new LcmObjectUninitializedException(String.Format("Failed to find a Factory to create {0}.", srcObj));
            }

            bool fIsTopLevel = ((ICmObject)srcObj == (ICmObject)m_topLevelObj);
            bool fUnOwned    = (srcObj.Owner == null);

            ICmObject newObj;

            if (fUnOwned)
            {
                newObj = CreateUnownedObj <TObj>(srcFactory, srcClsID);
            }
            else
            {
                Debug.Assert(!fIsTopLevel || m_topLevelOwnerFunct != null, "An owned top-level object must have a owner function passed in");
                newObj = (fIsTopLevel && m_topLevelOwnerFunct != kAddToSourceOwner) ?
                         (ICmObject)CreateTopLevelOwnedObj(srcFactory) :
                         CreateOwnedObj(m_servLoc.ObjectRepository, srcObj);
            }
            if (newObj == null)
            {
                throw new LcmObjectUninitializedException(String.Format("Failed to create a healthy LCM Object as a copy of {0}.", srcObj));
            }

            // Record copy in sourceToCopyMap
            int hvoSrc = srcObj.Hvo;
            int hvoNew = newObj.Hvo;

            // Review: This should work okay even if we modify the contents of newObj later, right?
            m_sourceToCopyMap.Add(hvoSrc, newObj);

            if (srcObj is ICloneableCmObject)
            {
                Debug.Assert(newObj is ICloneableCmObject);
                ((ICloneableCmObject)srcObj).SetCloneProperties(newObj);
                return((TObj)newObj);
            }

            int[] srcFlids = GetAllFieldsFromClassId(srcClsID);

            // Clone each owned flid and copy basic properties
            var owningInfo = new List <KeyValuePair <int, int> >();

            for (int i = 0; i < srcFlids.Length; i++)
            {
                int thisFlid = srcFlids[i];
                // If thisFlid is part of CmObject, this Flid's already been set on creation
                // Skip reference properties this pass
                // If Flid is Virtual, skip (let the new object determine its own virtual stuff)
                if (thisFlid < 200 || m_cache.IsReferenceProperty(thisFlid) ||
                    m_mdc.get_IsVirtual(thisFlid))
                {
                    continue;
                }

                int flidType = m_mdc.GetFieldType(thisFlid);
                if (flidType < (int)CellarPropertyType.MinObj)
                {
                    HandleBasicOrStringFlid(thisFlid, flidType, hvoSrc, hvoNew);
                }
                else
                {
                    // No. Just store the owned stuff, for now.
                    // The master xml file now has all props in numerical order,
                    // so all basic props has to be copied first.
                    //HandleObjFlid(thisFlid, flidType, hvoSrc);
                    owningInfo.Add(new KeyValuePair <int, int>(thisFlid, flidType));
                }
            }
            // Now process the owned stuff.
            foreach (var kvp in owningInfo)
            {
                HandleObjFlid(kvp.Key, kvp.Value, hvoSrc);
            }

            return((TObj)newObj);
        }