2 // XsltCompiledContext.cs
5 // Ben Maurer (bmaurer@users.sourceforge.net)
6 // Atsushi Enomoto (atsushi@ximian.com)
8 // (C) 2004 Novell Inc.
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System
.Collections
;
34 using System
.Collections
.Specialized
;
36 using System
.Xml
.Schema
;
37 using System
.Xml
.XPath
;
41 using Mono
.Xml
.Xsl
.Operations
;
42 using System
.Reflection
;
44 using BF
= System
.Reflection
.BindingFlags
;
45 using QName
= System
.Xml
.XmlQualifiedName
;
48 namespace Mono
.Xml
.Xsl
50 internal class XsltCompiledContext
: XsltContext
52 XslTransformProcessor p
;
54 public XslTransformProcessor Processor { get { return p; }}
56 public XsltCompiledContext (XslTransformProcessor p
) : base (new NameTable ())
61 public override string DefaultNamespace { get { return String.Empty; }}
64 public override string LookupNamespace (string prefix
)
66 throw new InvalidOperationException ("we should never get here");
69 internal override IXsltContextFunction
ResolveFunction (XmlQualifiedName name
, XPathResultType
[] argTypes
)
71 string ns
= name
.Namespace
;
73 if (ns
== null) return null;
75 object extension
= null;
77 if (p
.Arguments
!= null)
78 extension
= p
.Arguments
.GetExtensionObject (ns
);
80 bool isScript
= false;
81 if (extension
== null) {
82 extension
= p
.ScriptManager
.GetExtensionObject (ns
);
83 if (extension
== null)
90 MethodInfo method
= FindBestMethod (extension
.GetType (), name
.Name
, argTypes
, isScript
);
93 return new XsltExtensionFunction (extension
, method
, p
.CurrentNode
);
97 MethodInfo
FindBestMethod (Type t
, string name
, XPathResultType
[] argTypes
, bool isScript
)
101 MethodInfo
[] mi
= t
.GetMethods ((isScript
? BF
.Public
| BF
.NonPublic
: BF
.Public
) | BF
.Instance
| BF
.Static
);
105 if (argTypes
== null)
106 return mi
[0]; // if we dont have info on the arg types, nothing we can do
110 // filter on name + num args
111 int numArgs
= argTypes
.Length
;
112 for (int i
= 0; i
< mi
.Length
; i
++) {
113 if (mi
[i
].Name
== name
&& mi
[i
].GetParameters ().Length
== numArgs
)
114 mi
[free
++] = mi
[i
];
127 for (int i
= 0; i
< length
; i
++) {
129 ParameterInfo
[] pi
= mi
[i
].GetParameters ();
131 for (int par
= 0; par
< pi
.Length
; par
++) {
132 XPathResultType required
= argTypes
[par
];
133 if (required
== XPathResultType
.Any
)
134 continue; // dunno what it is
136 XPathResultType actual
= XPFuncImpl
.GetXPathType (pi
[par
].ParameterType
, p
.CurrentNode
);
137 if (actual
!= required
&& actual
!= XPathResultType
.Any
) {
142 if (actual
== XPathResultType
.Any
) {
143 // try to get a stronger gind
144 if (required
!= XPathResultType
.NodeSet
&& !(pi
[par
].ParameterType
== typeof (object)))
151 if (match
) return mi
[i
]; // TODO look for exact match
156 public override IXsltContextVariable
ResolveVariable (string prefix
, string name
)
158 throw new InvalidOperationException ("shouldn't get here");
161 public override IXsltContextFunction
ResolveFunction (string prefix
, string name
, XPathResultType
[] ArgTypes
)
163 throw new InvalidOperationException ("XsltCompiledContext exception: shouldn't get here.");
166 internal override System
.Xml
.Xsl
.IXsltContextVariable
ResolveVariable(QName q
)
168 return p
.CompiledStyle
.ResolveVariable (q
);
171 public override int CompareDocument (string baseUri
, string nextBaseUri
)
173 // it is implementation specific
174 return baseUri
.GetHashCode ().CompareTo (nextBaseUri
.GetHashCode ());
177 public override bool PreserveWhitespace (XPathNavigator nav
)
179 return p
.CompiledStyle
.Style
.GetPreserveWhitespace (nav
.LocalName
, nav
.NamespaceURI
);
182 public override bool Whitespace { get { return WhitespaceHandling; }
}
184 // Below are mimicking XmlNamespaceManager ;-)
185 public bool IsCData
{
186 get { return scopes [scopeAt].IsCData; }
187 set { scopes [scopeAt].IsCData = value; }
189 public bool WhitespaceHandling
{
190 get { return scopes [scopeAt].PreserveWhitespace; }
191 set { scopes [scopeAt].PreserveWhitespace = value; }
194 struct XsltContextInfo
197 public bool PreserveWhitespace
;
200 XsltContextInfo
[] scopes
= new XsltContextInfo
[40];
203 // precondition scopeAt == scopes.Length
206 XsltContextInfo
[] old
= scopes
;
207 scopes
= new XsltContextInfo
[scopeAt
* 2 + 1];
209 Array
.Copy (old
, 0, scopes
, 0, scopeAt
);
212 public override bool PopScope ()
222 public override void PushScope ()
227 if (scopeAt
== scopes
.Length
)