Esempio n. 1
0
        /// <summary> Copies an element using ADoc to provide the context of the copy. </summary>
        /// <param name="doc"> XDocument used to create/host the new node </param>
        /// <param name="ANode"> XElement to copy </param>
        /// <param name="deep"> Whether to copy the node's elements as well as attributes </param>
        /// <returns> A copy of ANode in the context of ADoc </returns>
        protected static XElement CopyNode(XDocument doc, XElement element, bool deep)
        {
            XElement tempElement = null;

            foreach (XAttribute copyAttr in element.Attributes())
            {
                if (!Persistence.XNamesEqual(copyAttr.Name, XmlIBOPOrder))                 // don't copy the ibop:order attribute in the merged doc
                {
                    AddAttr
                    (
                        doc,
                        ref tempElement,
                        element.Name,
                        copyAttr.Name,
                        copyAttr.Value
                    );
                }
            }

            if (tempElement == null)
            {
                tempElement = new XElement(element.Name);
            }

            if (deep && element.HasElements)
            {
                foreach (XElement childNode in element.Elements())
                {
                    tempElement.Add(CopyNode(doc, childNode, true));
                }
            }

            return(tempElement);
        }
Esempio n. 2
0
        /// <summary>
        ///		Applies the differences from the diff document to transform the Original document to
        ///		the Modified document it was compared against.
        /// </summary>
        /// <param name="doc"> the Original document, used to provide contex for created attributes </param>
        /// <param name="modifiedNode"> the node resulting from a diff operation </param>
        /// <param name="originalNode"> the node to be transformed in the merge </param>
        /// <param name="ignoreName"> whether to ignore the name difference in the merge operation </param>
        protected static void MergeAttrs
        (
            XDocument doc,
            XElement modifiedNode,
            ref XElement originalNode,
            bool ignoreName
        )
        {
            // assumes the nodes are "matched" in in the document by FindNode()

            if (!ignoreName && !Persistence.XNamesEqual(modifiedNode.Name, originalNode.Name))
            {
                XElement newNode = new XElement(modifiedNode.Name);
                MergeAttrs(doc, originalNode, ref newNode, true);
                foreach (XElement node in originalNode.Elements())
                {
                    newNode.Add(CopyNode(doc, node, true));
                }
                originalNode.ReplaceWith(newNode);
                originalNode = newNode;
                newNode      = null;
            }

            // merge the attributes
            foreach (XAttribute modifiedAttr in modifiedNode.Attributes())
            {
                if (!(modifiedAttr.Name == (XNamespace.Xmlns + IBOPNamespacePrefix)) && !Persistence.XNamesEqual(modifiedAttr.Name, XmlIBOPOrder))                 // don't put the ibop:order in the merged doc
                {
                    // if the attribute name is default-<attribute name> and it's value is true then remove the appropriate attribute from the original node.
                    if (modifiedAttr.Name.NamespaceName == Persistence.BOPNamespaceURI && modifiedAttr.Name.LocalName.StartsWith(Persistence.BOPDefault))
                    {
                        string attributeName = modifiedAttr.Name.LocalName.Substring(Persistence.BOPDefault.Length);
                        originalNode.SetAttributeValue(attributeName, null);
                    }
                    else
                    {
                        // assumed each node has a name and never delete the name attr
                        XAttribute originalAttr = originalNode.Attribute(modifiedAttr.Name);
                        if (originalAttr == null)                         // add attr
                        {
                            AddAttr
                            (
                                doc,
                                ref originalNode,
                                modifiedNode.Name,
                                modifiedAttr.Name,
                                modifiedAttr.Value
                            );
                        }
                        else                         // change attr value
                        {
                            originalAttr.Value = modifiedAttr.Value;
                        }
                    }
                }
            }
        }
Esempio n. 3
0
        /// <summary> Deserializes an instance from a node. </summary>
        /// <param name="node"> The XML node.  This node will not be affected by this method. </param>
        /// <param name="instance"> An optional instance to deserialize "into". </param>
        /// <returns> The instance that was passed by AInstance or was constructed if null was passed. </returns>
        private object ReadObject(XElement node, object instance)
        {
            string elementName = node.Name.LocalName.Substring(node.Name.LocalName.LastIndexOf('.') + 1).ToLower();             // simple type name

            Type type;

            if (instance != null)               // instance provided
            {
                type = instance.GetType();
                string typeName = GetElementName(type);                 // result is lower case
                if (elementName != typeName)
                {
                    Errors.Add(new BOPException(BOPException.Codes.TypeNameMismatch, elementName, typeName));
                }
            }
            else                // construct instance
            {
                type = GetClassType(elementName, node.Name.NamespaceName);

                try
                {
                    if (!IsValueType(type))
                    {
                        PublishDefaultConstructorAttribute constructorAttribute = (PublishDefaultConstructorAttribute)ReflectionUtility.GetAttribute(type, typeof(PublishDefaultConstructorAttribute));
                        if ((constructorAttribute == null) || (constructorAttribute.ConstructorSignature == String.Empty))
                        {
                            instance = Activator.CreateInstance(type, new object[] { });
                        }
                        else
                        {
                            // create a copy of the node to work with
                            // so that the original is not corrupted by disappearing attributes
                            node     = new XElement(node);
                            instance = ConstructInstance(constructorAttribute.ConstructorSignature, type, node);
                        }
                    }
                    else
                    {
                        return(ReflectionUtility.StringToValue(node.Attribute("value").Value, type));
                    }
                }
                catch (Exception E)
                {
                    throw new BOPException(BOPException.Codes.UnableToConstruct, E, type.FullName);
                }
            }

            MemberInfo member;
            object     memberInstance;
            string     memberName;
            Type       memberType;

            // Have Type and Instance, now read the properties
            try
            {
                // Read attributes
                foreach (XAttribute attribute in node.Attributes())
                {
                    try
                    {
                        memberName = attribute.Name.LocalName.ToLower();
                        if
                        (
                            (!attribute.IsNamespaceDeclaration)
                            &&
                            !(
                                IsBOPNode(attribute.Name) &&
                                (memberName.StartsWith(BOPType) || memberName.StartsWith(BOPDefault))
                                )
                        )
                        {
                            if (IsBOPNode(attribute.Name))
                            {
                                memberInstance = instance;
                                if (Persistence.XNamesEqual(attribute.Name, XmlBOPName))
                                {
                                    member = GetNameMemberInfo(type);
                                    if (member == null)
                                    {
                                        throw new BOPException(BOPException.Codes.InvalidElementName, type.Name);
                                    }
                                }
                                else
                                {
                                    throw new BOPException(BOPException.Codes.InvalidAttribute, attribute.Name);
                                }
                            }
                            else
                            {
                                memberInstance = FindMemberInstance(instance, ref memberName);
                                member         = ReflectionUtility.FindSimpleMember(memberInstance.GetType(), memberName);
                            }
                            memberType = GetMemberType(node, member);

                            ReflectionUtility.SetMemberValue
                            (
                                member,
                                memberInstance,
                                (
                                    AttributeToValue
                                    (
                                        attribute.Value,
                                        memberType,
                                        memberInstance,
                                        member
                                    )
                                )
                            );
                        }
                    }
                    catch (Exception exception)
                    {
                        Errors.Add(exception);
                    }
                }

                // Add this instance to the list of read instances if it has a name
                member = GetNameMemberInfo(instance.GetType());
                if (member != null)
                {
                    memberName = (string)ReflectionUtility.GetMemberValue(member, instance);
                    if (memberName != String.Empty)
                    {
                        InstancesByName.Add(memberName, instance);
                    }
                }

                // read child nodes
                IList list;
                foreach (XElement localNode in node.Elements())
                {
                    try
                    {
                        memberName     = localNode.Name.LocalName.ToLower();
                        memberInstance = FindMemberInstance(instance, ref memberName);

                        // First see if the member instance has a default list attribute and use it if it does
                        string defaultListName = GetDefaultListMemberName(memberInstance.GetType());
                        if (defaultListName == String.Empty)
                        {
                            list = memberInstance as IList;
                        }
                        else                         // if no default list, assume the member instance IS the list
                        {
                            list = ReflectionUtility.GetMemberValue
                                   (
                                ReflectionUtility.FindSimpleMember(memberInstance.GetType(), defaultListName),
                                memberInstance
                                   ) as IList;
                        }
                        if (list == null)
                        {
                            throw new BOPException(BOPException.Codes.DefaultListNotFound, memberInstance.GetType().Name);
                        }
                        list.Add(ReadObject(localNode, null));
                    }
                    catch (Exception exception)
                    {
                        Errors.Add(exception);
                    }
                }

                // call AfterDeserialize
                if (instance is IBOPSerializationEvents)
                {
                    ((IBOPSerializationEvents)instance).AfterDeserialize(this);
                }

                if (AfterDeserialized != null)
                {
                    AfterDeserialized(instance);
                }
            }
            catch
            {
                if ((instance != null) && (instance is IDisposable))
                {
                    ((IDisposable)instance).Dispose();
                }
                throw;
            }

            return(instance);
        }
Esempio n. 4
0
        /// <summary> Compares the Modified node's atributes to those of the Original node. </summary>
        /// <remarks> Copies the differences, using AModifiedNode, into ADiffNode. </remarks>
        /// <param name="diffDoc"> document used to provide context for the DiffNode </param>
        /// <param name="AModifiedNode"> node that the Original should look like after a merge operation </param>
        /// <param name="AOriginalNode"> node describing the initial state of the node</param>
        /// <param name="ADiffNode"> node describing the operations required to make the Original node into the Modified </param>
        /// <returns> ADiffNode </returns>
        protected static XElement DiffAttrs
        (
            XDocument diffDoc,
            XElement modifiedElement,
            XElement originalElement,
            ref XElement diffElement
        )
        {
            // assumes both nodes exist!
            bool diffFound = false;

            // assumes the nodes are "matched" in the document by the name attribute, see FindNode()
            foreach (XAttribute modifiedAttr in modifiedElement.Attributes())
            {
                XAttribute originalAttr = originalElement.Attribute(modifiedAttr.Name);

                if (originalAttr == null)                 // add attr
                {
                    diffFound = true;
                    if (!Persistence.XNamesEqual(modifiedAttr.Name, XmlIBOPDiffFound))
                    {
                        AddAttr(diffDoc, ref diffElement, originalElement.Name, modifiedAttr.Name, modifiedAttr.Value);
                    }
                }
                else                 // compare attr value
                {
                    if (!String.Equals(modifiedAttr.Value, originalAttr.Value))
                    {
                        diffFound = true;
                        AddAttr(diffDoc, ref diffElement, originalElement.Name, modifiedAttr.Name, modifiedAttr.Value);
                    }
                    else
                    {
                        if
                        (
                            String.Equals(modifiedAttr.Name.NamespaceName, Serializer.BOPNamespaceURI, StringComparison.OrdinalIgnoreCase) ||
                            String.Equals(modifiedAttr.Name.NamespaceName, IBOPNamespaceURI, StringComparison.OrdinalIgnoreCase)
                        )
                        {
                            AddAttr(diffDoc, ref diffElement, originalElement.Name, modifiedAttr.Name, modifiedAttr.Value);
                        }
                    }
                    // delete the original attribute so we know which ones do not appear in the modified node
                    originalElement.SetAttributeValue(originalAttr.Name, null);
                }
            }

            foreach (XAttribute defaultAttr in originalElement.Attributes())
            {
                // If the attr is in the orig but not in modified, then explicitly mark the attr as "default" (it has changed from something to the default value)
                diffFound = true;
                AddAttr
                (
                    diffDoc,
                    ref diffElement,
                    originalElement.Name,
                    XName.Get(Persistence.BOPDefault + defaultAttr.Name, Persistence.BOPNamespaceURI),
                    "True"
                );
            }

            if (diffFound)
            {
                AddAttr
                (
                    diffDoc,
                    ref diffElement,
                    originalElement.Name,
                    XmlIBOPDiffFound,
                    "yes"
                );
            }
            else
            {
                AddAttr
                (
                    diffDoc,
                    ref diffElement,
                    originalElement.Name,
                    XmlIBOPDiffFound,
                    "no"
                );
            }

            return(diffElement);
        }