/// ---------------------------------------------------------------------------------------- /// <summary> /// Gives the CSharp interface type for the factory that creates objects of the specified class. /// </summary> /// ---------------------------------------------------------------------------------------- internal static Type GetFactoryTypeFromFWClassID(IFwMetaDataCacheManaged mdc, int classId) { // Abstract classes have no factory. if (mdc.GetAbstract(classId)) { throw new ArgumentException("No factory for abstract classes", "classId"); } // if the class ID is cached then return the type now. Type result; if (s_classIdToFactType.TryGetValue(classId, out result)) { return(result); } // Find the class name of this object var sClassName = mdc.GetClassName(classId); // find the Type for the factory for this class. var fullTypeName = string.Format("SIL.FieldWorks.FDO.I{0}Factory", sClassName); result = Assembly.GetExecutingAssembly().GetType(fullTypeName, true); s_classIdToFactType.Add(classId, result); // Store for next time. return(result); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Adds the node. /// </summary> /// <param name="parentNodeCollection">The parent node collection.</param> /// <param name="classname">The classname.</param> /// <param name="clid">The clid.</param> /// ------------------------------------------------------------------------------------ private void AddNode(TreeNodeCollection parentNodeCollection, string classname, int clid) { bool isAbstract = m_mdc.GetAbstract(clid); string label = classname + ": (" + clid + ")" + (isAbstract ? " abstract class" : ""); TreeNode node = new TreeNode(label) { Tag = clid }; bool fAdded = false; for (int i = 0; i < parentNodeCollection.Count; i++) { if (node.Text.CompareTo(parentNodeCollection[i].Text) < 0) { parentNodeCollection.Insert(i, node); fAdded = true; break; } } if (!fAdded) { parentNodeCollection.Add(node); } AddSubNodes(node.Nodes, clid); }
/// ---------------------------------------------------------------------------------------- /// <summary> /// Gives the CSharp interface type for the factory that creates objects of the specified class. /// </summary> /// ---------------------------------------------------------------------------------------- internal static Type GetFactoryTypeFromFWClassID(IFwMetaDataCacheManaged mdc, int classId) { // Abstract classes have no factory. if (mdc.GetAbstract(classId)) throw new ArgumentException("No factory for abstract classes", "classId"); // if the class ID is cached then return the type now. Type result; if (s_classIdToFactType.TryGetValue(classId, out result)) return result; // Find the class name of this object var sClassName = mdc.GetClassName(classId); // find the Type for the factory for this class. var fullTypeName = string.Format("SIL.FieldWorks.FDO.I{0}Factory", sClassName); result = Assembly.GetExecutingAssembly().GetType(fullTypeName, true); s_classIdToFactType.Add(classId, result); // Store for next time. return result; }
/// <summary> Indicates whether a class is abstract or concrete. </summary> /// <param name='luClid'>Class identification number. In the database, this corresponds to "Id" /// column in the Class$ table. </param> /// <returns>Points to the output boolean set to "true" if abstract, or set to /// "false" for concrete.</returns> public virtual bool GetAbstract(int luClid) { return(m_metaDataCache.GetAbstract(luClid)); }
/// ------------------------------------------------------------------------------------ /// <summary> /// This is the heart of CopyObject Pass 1. /// Clones all owned objects (OA, OS, OC) and the source FDO 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">FDO object to clone</param> /// <returns>The cloned object</returns> /// ------------------------------------------------------------------------------------ private TObj CloneFdoObjectsRecursively <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!"); } IFdoFactoryInternal srcFactory = (IFdoFactoryInternal)m_servLoc.GetInstance( GetServicesFromFWClass.GetFactoryTypeFromFWClassID(m_mdc, srcClsID)); if (srcFactory == null) { throw new FDOObjectUninitializedException(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 FDOObjectUninitializedException(String.Format("Failed to create a healthy FDO 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); }