/// <summary> /// Flatten an owned object and add an appropriate objsur to the specified property of the owning object. /// </summary> internal static void FlattenOwnedObject(string pathname, SortedDictionary <string, XElement> sortedData, XElement element, string ownerguid, XContainer owningElement, string propertyName) { FlattenObjectCore(pathname, sortedData, element, ownerguid); // We MUST create the objsur AFTER flattening the object, which may pathologically change its guid. var guid = element.Attribute(SharedConstants.GuidStr).Value.ToLowerInvariant(); BaseDomainServices.RestoreObjsurElement(owningElement, propertyName, BaseDomainServices.CreateObjSurElement(guid)); }
private static void FlattenObjectCore( string pathname, SortedDictionary <string, XElement> sortedData, XElement element, string ownerguid) { if (string.IsNullOrEmpty(pathname)) { throw new ArgumentNullException("pathname"); } if (sortedData == null) { throw new ArgumentNullException("sortedData"); } if (element == null) { throw new ArgumentNullException("element"); } // No, since unowned stuff will feed a null. //if (string.IsNullOrEmpty(ownerguid)) throw new ArgumentNullException(SharedConstants.OwnerGuid); if (ownerguid != null && ownerguid == string.Empty) { throw new ArgumentException(Resources.kOwnerGuidEmpty, SharedConstants.OwnerGuid); } string className; bool isOwnSeqNode; var elementGuid = CheckForDuplicateElementMethod.CheckForDuplicateGuid(pathname, sortedData, element, out isOwnSeqNode, out className); sortedData.Add(elementGuid, element); // The name of 'element' is the class of CmObject, or 'ownseq', or.... element.Name = SharedConstants.RtTag; if (!isOwnSeqNode) { element.Add(new XAttribute(SharedConstants.Class, className)); } //if (element.Attribute(SharedConstants.OwnerGuid) == null) if (ownerguid != null) // && element.Attribute(SharedConstants.OwnerGuid) == null) { element.Add(new XAttribute(SharedConstants.OwnerGuid, ownerguid)); } // Re-sort those attributes. var sortedAttrs = new SortedDictionary <string, XAttribute>(); foreach (var attribute in element.Attributes()) { sortedAttrs.Add(attribute.Name.LocalName, attribute); } element.Attributes().Remove(); element.Add(sortedAttrs.Values); // Restore any ref seq props to have 'objsur' elements. var mdc = MetadataCache.MdCache; var propCache = mdc.PropertyCache[className]; var refSeqPropNames = propCache["AllReferenceSequence"]; // Restore any ref col props to have 'objsur' elements. var refColPropNames = propCache["AllReferenceCollection"]; var owningPropsForClass = propCache["AllOwning"]; if (owningPropsForClass.Count == 0 && refSeqPropNames.Count == 0 && refColPropNames.Count == 0) { return; // Nothing special to be done for normal properties. } foreach (var propertyElement in element.Elements().ToArray()) { var isCustomProperty = propertyElement.Name.LocalName == SharedConstants.Custom; var propName = isCustomProperty ? propertyElement.Attribute(SharedConstants.Name).Value : propertyElement.Name.LocalName; if (!owningPropsForClass.Contains(propName)) { if (refSeqPropNames.Contains(propName)) { foreach (var refSeqNode in propertyElement.Elements(SharedConstants.Refseq)) { refSeqNode.Name = SharedConstants.Objsur; } } else if (refColPropNames.Contains(propName)) { foreach (var refColNode in propertyElement.Elements(SharedConstants.Refcol)) { refColNode.Name = SharedConstants.Objsur; } } continue; } if (!propertyElement.HasElements) { continue; } foreach (var ownedElement in propertyElement.Elements().ToArray()) { if (ownedElement.Name.LocalName == SharedConstants.Objsur) { break; } // Do before the removal call, so we know the parent, and thus, the property name. if (isCustomProperty) { var owningPropertyElement = (element.Elements().Where(customNode => customNode.Name.LocalName == SharedConstants.Custom && customNode.Attribute(SharedConstants.Name) != null && customNode.Attribute(SharedConstants.Name).Value == propertyElement.Attribute(SharedConstants.Name).Value)).First(); ownedElement.Remove(); FlattenObjectCore(pathname, sortedData, ownedElement, elementGuid); // BEFORE we make the objsur! BaseDomainServices.RestoreObjsurElement(owningPropertyElement, ownedElement); } else { var propertyName = ownedElement.Parent.Name.LocalName; ownedElement.Remove(); // Move down the nested set of owned objects, and do the same. FlattenOwnedObject(pathname, sortedData, ownedElement, elementGuid, element, propertyName); } } } }