Example #1
0
        /// <summary>
        /// Decodes the given XML node. The optional "into" argument specifies an
        /// existing object to be used. If no object is given, then a new
        /// instance is created using the constructor from the codec.
        /// The function returns the passed in object or the new instance if no
        /// object was given.
        /// </summary>
        /// <param name="node">XML node to be decoded.</param>
        /// <param name="into">Optional object to be decodec into.</param>
        /// <returns>Returns an object that represents the given node.</returns>
        public Object Decode(XmlNode node, Object into)
        {
            Object obj = null;

            if (node != null && node.NodeType == XmlNodeType.Element)
            {
                mxObjectCodec codec = mxCodecRegistry.GetCodec(node.Name);

                try
                {
                    if (codec != null)
                    {
                        obj = codec.Decode(this, node, into);
                    }
                    else
                    {
                        obj = node.CloneNode(true);
                        ((XmlElement)obj).RemoveAttribute("as");
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Cannot decode " + node.Name + ": "
                                      + e.Message);
                }
            }

            return(obj);
        }
Example #2
0
        /// <summary>
        /// Decodes cells that have been encoded using inversion, ie. where the
        /// user object is the enclosing node in the XML, and restores the group
        /// and graph structure in the cells. Returns a new mxCell instance
        /// that represents the given node.
        /// </summary>
        /// <param name="node">XML node that contains the cell data.</param>
        /// <param name="restoreStructures">Boolean indicating whether the graph
        /// structure should be restored by calling insert and insertEdge on the
        /// parent and terminals, respectively.
        /// </param>
        /// <returns>Graph cell that represents the given node.</returns>
        public mxICell DecodeCell(XmlNode node, bool restoreStructures)
        {
            mxICell cell = null;

            if (node != null &&
                node.NodeType == XmlNodeType.Element)
            {
                // Tries to find a codec for the given node name. If that does
                // not return a codec then the node is the user object (an XML node
                // that contains the mxCell, aka inversion).
                mxObjectCodec decoder = mxCodecRegistry.GetCodec(node.Name);

                // Tries to find the codec for the cell inside the user object.
                // This assumes all node names inside the user object are either
                // not registered or they correspond to a class for cells.
                if (decoder == null)
                {
                    XmlNode child = node.FirstChild;

                    while (child != null &&
                           !(decoder is mxCellCodec))
                    {
                        decoder = mxCodecRegistry.GetCodec(child.Name);
                        child   = child.NextSibling;
                    }
                }

                if (!(decoder is mxCellCodec))
                {
                    decoder = mxCodecRegistry.GetCodec("mxCell");
                }

                cell = (mxICell)decoder.Decode(this, node);

                if (restoreStructures)
                {
                    InsertIntoGraph(cell);
                }
            }

            return(cell);
        }
Example #3
0
        /// <summary>
        /// Decodes an mxCell and uses the enclosing XML node as
        /// the user object for the cell (inversion).
        /// </summary>
        public override XmlNode BeforeDecode(mxCodec dec, XmlNode node, Object obj)
        {
            XmlElement inner = (XmlElement)node;

            if (obj is mxCell)
            {
                mxCell cell      = (mxCell)obj;
                String classname = GetName();

                if (!node.Name.Equals(classname))
                {
                    // Passes the inner graphical annotation node to the
                    // object codec for further processing of the cell.
                    XmlNode tmp = inner.GetElementsByTagName(classname)[0];

                    if (tmp != null && tmp.ParentNode == node)
                    {
                        inner = (XmlElement)tmp;

                        // Removes annotation and whitespace from node
                        XmlNode tmp2 = tmp.PreviousSibling;

                        while (tmp2 != null && tmp2.NodeType == XmlNodeType.Text)
                        {
                            XmlNode tmp3 = tmp2.PreviousSibling;

                            if (tmp2.Value.Trim().Length == 0)
                            {
                                tmp2.ParentNode.RemoveChild(tmp2);
                            }

                            tmp2 = tmp3;
                        }

                        // Removes more whitespace
                        tmp2 = tmp.NextSibling;

                        while (tmp2 != null && tmp2.NodeType == XmlNodeType.Text)
                        {
                            XmlNode tmp3 = tmp2.PreviousSibling;

                            if (tmp2.Value.Trim().Length == 0)
                            {
                                tmp2.ParentNode.RemoveChild(tmp2);
                            }

                            tmp2 = tmp3;
                        }

                        tmp.ParentNode.RemoveChild(tmp);
                    }
                    else
                    {
                        inner = null;
                    }

                    // Creates the user object out of the XML node
                    XmlElement value = (XmlElement)node.CloneNode(true);
                    cell.Value = value;
                    String id = value.GetAttribute("id");

                    if (id != null)
                    {
                        cell.Id = id;
                        value.RemoveAttribute("id");
                    }
                }
                else
                {
                    cell.Id = ((XmlElement)node).GetAttribute("id");
                }

                // Preprocesses and removes all Id-references
                // in order to use the correct encoder (this)
                // for the known references to cells (all).
                if (inner != null && idrefs != null)
                {
                    foreach (string attr in idrefs)
                    {
                        string rf = inner.GetAttribute(attr);

                        if (rf != null && rf.Length > 0)
                        {
                            inner.RemoveAttribute(attr);
                            Object tmp = (dec.Objects.ContainsKey(rf)) ? dec.Objects[rf] : null;

                            if (tmp == null)
                            {
                                tmp = dec.Lookup(rf);
                            }

                            if (tmp == null)
                            {
                                // Needs to decode forward reference
                                XmlNode element = dec.GetElementById(rf);

                                if (element != null)
                                {
                                    mxObjectCodec decoder = mxCodecRegistry
                                                            .GetCodec(element.Name);

                                    if (decoder == null)
                                    {
                                        decoder = this;
                                    }

                                    tmp = decoder.Decode(dec, element);
                                }
                            }

                            SetFieldValue(obj, attr, tmp);
                        }
                    }
                }
            }

            return(inner);
        }