X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Security%2FSystem.Security.Cryptography.Xml%2FDataObject.cs;h=bd7c529f137bc5e3138abfe4dea4d64b819e3783;hb=097409cdab4f046189c17d4bd9490c8aecbc5ef4;hp=9266d85fb09e76ece86319cddb5ba1c77d8096f9;hpb=355327100c95708808045804b65225ef9cf4de56;p=mono.git diff --git a/mcs/class/System.Security/System.Security.Cryptography.Xml/DataObject.cs b/mcs/class/System.Security/System.Security.Cryptography.Xml/DataObject.cs index 9266d85fb09..bd7c529f137 100644 --- a/mcs/class/System.Security/System.Security.Cryptography.Xml/DataObject.cs +++ b/mcs/class/System.Security/System.Security.Cryptography.Xml/DataObject.cs @@ -3,12 +3,32 @@ // http://www.w3.org/2000/09/xmldsig#Object // // Author: -// Sebastien Pouliot (spouliot@motus.com) +// Sebastien Pouliot +// Atsushi Enomoto (atsushi@ximian.com) // // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) +// Copyright (C) 2005 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -using System.Text; using System.Xml; namespace System.Security.Cryptography.Xml { @@ -18,14 +38,10 @@ namespace System.Security.Cryptography.Xml { // required for "enveloping signatures" public class DataObject { - private string id; - private string mimeType; - private string encoding; - private XmlDocument doc; - - static private string xmldsig = "http://www.w3.org/2000/09/xmldsig#"; + private XmlElement element; + private bool propertyModified; - public DataObject () + public DataObject () { Build (null, null, null, null); } @@ -38,122 +54,115 @@ namespace System.Security.Cryptography.Xml { Build (id, mimeType, encoding, data); } + // this one accept a null "data" parameter private void Build (string id, string mimeType, string encoding, XmlElement data) { - StringBuilder sb = new StringBuilder (); - sb.Append (""); - - doc = new XmlDocument (); - doc.LoadXml (sb.ToString ()); if (data != null) { - XmlNodeList xnl = doc.GetElementsByTagName ("Object"); - XmlNode newNode = doc.ImportNode (data, true); - xnl[0].AppendChild (newNode); + XmlNode newNode = document.ImportNode (data, true); + xel.AppendChild (newNode); } + element = xel; } // why is data a XmlNodeList instead of a XmlElement ? public XmlNodeList Data { get { - XmlNodeList xnl = doc.GetElementsByTagName ("Object"); - return xnl[0].ChildNodes; + return element.ChildNodes; } set { if (value == null) throw new ArgumentNullException ("value"); - - Build (id, mimeType, encoding, null); - XmlNodeList xnl = doc.GetElementsByTagName ("Object"); - if ((xnl != null) && (xnl.Count > 0)) { - foreach (XmlNode xn in value) { - XmlNode newNode = doc.ImportNode (xn, true); - xnl[0].AppendChild (newNode); - } - } + XmlDocument doc = new XmlDocument (); + XmlElement el = (XmlElement) doc.ImportNode (element, true); + while (el.LastChild != null) + el.RemoveChild (el.LastChild); + foreach (XmlNode n in value) + el.AppendChild (doc.ImportNode (n, true)); + element = el; + propertyModified = true; } } // default to null - no encoding public string Encoding { - get { return encoding; } - set { encoding = value; } + get { return GetField (XmlSignature.AttributeNames.Encoding); } + set { SetField (XmlSignature.AttributeNames.Encoding, value); } } // default to null public string Id { - get { return id; } - set { id = value; } + get { return GetField (XmlSignature.AttributeNames.Id); } + set { SetField (XmlSignature.AttributeNames.Id, value); } } // default to null public string MimeType { - get { return mimeType; } - set { mimeType = value; } + get { return GetField (XmlSignature.AttributeNames.MimeType); } + set { SetField (XmlSignature.AttributeNames.MimeType, value); } + } + + private string GetField (string attribute) + { + XmlNode attr = element.Attributes [attribute]; + return attr != null ? attr.Value : null; + } + + private void SetField (string attribute, string value) + { + // MS-BUGS: it never cleans attribute value up. + if (value == null) + return; + + if (propertyModified) + element.SetAttribute (attribute, value); + else { + XmlDocument document = new XmlDocument (); + XmlElement el = document.ImportNode (element, true) as XmlElement; + el.SetAttribute (attribute, value); + element = el; + propertyModified = true; + } } public XmlElement GetXml () { - if ((doc.DocumentElement.LocalName == "Object") && (doc.DocumentElement.NamespaceURI == xmldsig)) { - // recreate all attributes in order - XmlAttribute xa = null; - doc.DocumentElement.Attributes.RemoveAll (); - if (id != null) { - xa = doc.CreateAttribute ("Id"); - xa.Value = id; - doc.DocumentElement.Attributes.Append (xa); - } - if (mimeType != null) { - xa = doc.CreateAttribute ("MimeType"); - xa.Value = mimeType; - doc.DocumentElement.Attributes.Append (xa); - } - if (encoding != null) { - xa = doc.CreateAttribute ("Encoding"); - xa.Value = encoding; - doc.DocumentElement.Attributes.Append (xa); + if (propertyModified) { + // It looks MS.NET returns element which comes from new XmlDocument every time + XmlElement oldElement = element; + XmlDocument doc = new XmlDocument (); + element = doc.CreateElement (XmlSignature.ElementNames.Object, XmlSignature.NamespaceURI); + foreach (XmlAttribute attribute in oldElement.Attributes) { + switch (attribute.Name) { + case XmlSignature.AttributeNames.Id: + case XmlSignature.AttributeNames.Encoding: + case XmlSignature.AttributeNames.MimeType: + element.SetAttribute (attribute.Name, attribute.Value); + break; + } } - xa = doc.CreateAttribute ("xmlns"); - xa.Value = xmldsig; - doc.DocumentElement.Attributes.Append (xa); + foreach (XmlNode n in oldElement.ChildNodes) + element.AppendChild (doc.ImportNode (n, true)); } - return doc.DocumentElement; + return element; } public void LoadXml (XmlElement value) { if (value == null) throw new ArgumentNullException ("value"); - - if ((value.LocalName == "Object") && (value.NamespaceURI == xmldsig)) { - doc.LoadXml (value.OuterXml); - XmlAttribute xa = value.Attributes ["Id"]; - id = ((xa != null) ? xa.InnerText : null); - xa = value.Attributes ["MimeType"]; - mimeType = ((xa != null) ? xa.InnerText : null); - xa = value.Attributes ["Encoding"]; - encoding = ((xa != null) ? xa.InnerText : null); - } - else - doc.LoadXml (value.OuterXml); + element = value; + propertyModified = false; } } -} \ No newline at end of file +}