2004-02-11 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mcs / class / System.Security / System.Security.Cryptography.Xml / XmlDsigXPathTransform.cs
1 //
2 // XmlDsigXPathTransform.cs - 
3 //      XmlDsigXPathTransform implementation for XML Signature
4 // http://www.w3.org/TR/1999/REC-xpath-19991116 
5 //
6 // Author:
7 //      Sebastien Pouliot <sebastien@ximian.com>
8 //
9 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
10 // (C) 2004 Novell (http://www.novell.com)
11 //
12
13 using System.IO;
14 using System.Text;
15 using System.Xml;
16
17 namespace System.Security.Cryptography.Xml {
18
19         // www.w3.org/TR/xmldsig-core/
20         // see Section 6.6.3 of the XMLDSIG specification
21         [MonoTODO]
22         public class XmlDsigXPathTransform : Transform {
23
24                 private Type[] input;
25                 private Type[] output;
26                 private XmlNodeList xpath;
27                 private XmlDocument doc;
28
29                 public XmlDsigXPathTransform () 
30                 {
31                         Algorithm = "http://www.w3.org/TR/1999/REC-xpath-19991116";
32                 }
33
34                 public override Type[] InputTypes {
35                         get {
36                                 if (input == null) {
37                                         lock (this) {
38                                                 // this way the result is cached if called multiple time
39                                                 input = new Type [3];
40                                                 input[0] = typeof (System.IO.Stream);
41                                                 input[1] = typeof (System.Xml.XmlDocument);
42                                                 input[2] = typeof (System.Xml.XmlNodeList);
43                                         }
44                                 }
45                                 return input;
46                         }
47                 }
48
49                 public override Type[] OutputTypes {
50                         get {
51                                 if (output == null) {
52                                         lock (this) {
53                                                 // this way the result is cached if called multiple time
54                                                 output = new Type [1];
55                                                 output[0] = typeof (System.Xml.XmlNodeList);
56                                         }
57                                 }
58                                 return output;
59                         }
60                 }
61
62                 protected override XmlNodeList GetInnerXml () 
63                 {
64                         if (xpath == null) {
65                                 // default value
66                                 XmlDocument doc = new XmlDocument ();
67                                 doc.LoadXml ("<XPath xmlns=\"" + XmlSignature.NamespaceURI + "\"></XPath>");
68                                 xpath = doc.ChildNodes;
69                         }
70                         return xpath;
71                 }
72                 
73                 public override object GetOutput () 
74                 {
75                         // note: this will throw a NullReferenceException if 
76                         // doc is null - just like MS implementation does
77                         if ((xpath == null) || (xpath.Count < 1)) {
78                                 // can't create an XmlNodeList
79                                 XmlDocument xd = new XmlDocument ();
80                                 return xd.ChildNodes;
81                         }
82                         return doc.ChildNodes;
83 //* I know it doesn't make a lot of sense - but this is what the MS framework
84 //* returns - I must miss something really bad
85 //*                     return doc.DocumentElement.SelectNodes (xpath [0].InnerXml);
86                 }
87
88                 public override object GetOutput (Type type) 
89                 {
90                         if (type != typeof (XmlNodeList))
91                                 throw new ArgumentException ("type");
92                         return GetOutput ();
93                 }
94
95                 public override void LoadInnerXml (XmlNodeList nodeList) 
96                 {
97                         if (nodeList == null)
98                                 throw new CryptographicException ("nodeList");
99                         xpath = nodeList;
100                 }
101
102                 public override void LoadInput (object obj) 
103                 {
104                         // possible input: Stream, XmlDocument, and XmlNodeList
105                         if (obj is Stream) {
106                                 doc = new XmlDocument ();
107                                 doc.Load (obj as Stream);
108                         }
109                         else if (obj is XmlDocument) {
110                                 doc = (obj as XmlDocument);
111                         }
112                         else if (obj is XmlNodeList) {
113                                 doc = new XmlDocument ();
114                                 foreach (XmlNode xn in (obj as XmlNodeList))  {
115                                         XmlNode importedNode = doc.ImportNode (xn, true);
116                                         doc.AppendChild (importedNode);
117                                 }
118                         }
119                 }
120         }
121 }