/// <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); }
/// <summary> /// Returns a codec that handles the given object, which can be an object /// instance or an XML node. /// </summary> /// <param name="name">C# type name.</param> /// <returns></returns> public static mxObjectCodec GetCodec(String name) { if (aliases.ContainsKey(name)) { name = aliases[name]; } mxObjectCodec codec = (codecs.ContainsKey(name)) ? codecs[name] : null; if (codec == null) { Object instance = GetInstanceForName(name); if (instance != null) { try { codec = new mxObjectCodec(instance); Register(codec); } catch (Exception e) { Trace.WriteLine("mxCodecRegistry.GetCodec(" + name + "): " + e.Message); } } } return(codec); }
/// <summary> /// Encodes the specified object and returns the resulting XML node. /// </summary> /// <param name="obj">Object to be encoded.</param> /// <returns>Returns an XML node that represents the given object.</returns> public XmlNode Encode(Object obj) { XmlNode node = null; if (obj != null) { string name = mxCodecRegistry.GetName(obj); mxObjectCodec enc = mxCodecRegistry.GetCodec(name); if (enc != null) { node = enc.Encode(this, obj); } else { if (obj is XmlNode) { node = ((XmlNode)obj).CloneNode(true); } else { Console.WriteLine("No codec for " + name); } } } return(node); }
/// <summary> /// Registers a new codec and associates the name of the template constructor /// in the codec with the codec object. Automatically creates an alias if the /// codename and the classname are not equal. /// </summary> public static mxObjectCodec Register(mxObjectCodec codec) { if (codec != null) { string name = codec.GetName(); codecs[name] = codec; string classname = GetName(codec.Template); if (!classname.Equals(name)) { AddAlias(classname, name); } } return(codec); }
/// <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); }
/// <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); }
/// <summary> /// Returns a codec that handles the given object, which can be an object /// instance or an XML node. /// </summary> /// <param name="name">C# type name.</param> /// <returns></returns> public static mxObjectCodec GetCodec(String name) { if (aliases.ContainsKey(name)) { name = aliases[name]; } mxObjectCodec codec = (codecs.ContainsKey(name)) ? codecs[name] : null; if (codec == null) { Object instance = GetInstanceForName(name); if (instance != null) { try { codec = new mxObjectCodec(instance); Register(codec); } catch (Exception e) { Trace.WriteLine("mxCodecRegistry.GetCodec(" + name + "): " + e.Message); } } } return codec; }
/// <summary> /// Registers a new codec and associates the name of the template constructor /// in the codec with the codec object. Automatically creates an alias if the /// codename and the classname are not equal. /// </summary> public static mxObjectCodec Register(mxObjectCodec codec) { if (codec != null) { string name = codec.GetName(); codecs[name] = codec; string classname = GetName(codec.Template); if (!classname.Equals(name)) { AddAlias(classname, name); } } return codec; }