1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host.dom;
16
17 import org.htmlunit.corejs.javascript.Context;
18 import org.htmlunit.corejs.javascript.Function;
19 import org.htmlunit.corejs.javascript.NativeFunction;
20 import org.htmlunit.corejs.javascript.Scriptable;
21 import org.htmlunit.html.DomNode;
22 import org.htmlunit.javascript.HtmlUnitScriptable;
23 import org.htmlunit.javascript.JavaScriptEngine;
24 import org.htmlunit.javascript.configuration.JsxClass;
25 import org.htmlunit.javascript.configuration.JsxConstructor;
26 import org.htmlunit.javascript.configuration.JsxFunction;
27 import org.htmlunit.javascript.host.NativeFunctionPrefixResolver;
28 import org.htmlunit.javascript.host.Window;
29 import org.htmlunit.xpath.xml.utils.PrefixResolver;
30
31
32
33
34
35
36
37
38 @JsxClass
39 public class XPathEvaluator extends HtmlUnitScriptable {
40
41
42
43
44 @JsxConstructor
45 public void jsConstructor() {
46
47 }
48
49
50
51
52
53
54
55
56 @JsxFunction
57 public XPathNSResolver createNSResolver(final Node nodeResolver) {
58 final XPathNSResolver resolver = new XPathNSResolver();
59 resolver.setElement(nodeResolver);
60 resolver.setParentScope(getWindow());
61 resolver.setPrototype(getPrototype(resolver.getClass()));
62 return resolver;
63 }
64
65
66
67
68
69
70
71
72
73
74
75 @JsxFunction
76 public XPathResult evaluate(final String expression, final Object contextNodeObj,
77 final Object resolver, final int type, final Object result) {
78 try {
79
80 if (!(contextNodeObj instanceof Node)) {
81 throw JavaScriptEngine.typeError("Illegal value for parameter 'context'");
82 }
83
84 final Node contextNode = (Node) contextNodeObj;
85 PrefixResolver prefixResolver = null;
86 if (resolver instanceof PrefixResolver) {
87 prefixResolver = (PrefixResolver) resolver;
88 }
89 else if (resolver instanceof NativeFunction) {
90 prefixResolver = new NativeFunctionPrefixResolver(
91 (NativeFunction) resolver, contextNode.getParentScope());
92 }
93
94 final XPathResult xPathResult;
95 if (result instanceof XPathResult) {
96 xPathResult = (XPathResult) result;
97 }
98 else {
99 xPathResult = new XPathResult();
100 xPathResult.setParentScope(getParentScope());
101 xPathResult.setPrototype(getPrototype(xPathResult.getClass()));
102 }
103
104 xPathResult.init(contextNode.getDomNodeOrDie().getByXPath(expression, prefixResolver), type);
105 return xPathResult;
106 }
107 catch (final Exception e) {
108 throw JavaScriptEngine.typeError("Failed to execute 'evaluate': " + e.getMessage());
109 }
110 }
111
112
113
114
115
116
117
118
119
120
121 @JsxFunction
122 public static XPathExpression createExpression(final Context context, final Scriptable scope,
123 final Scriptable thisObj, final Object[] args, final Function function) {
124 if (args.length < 1) {
125 throw JavaScriptEngine.reportRuntimeError("Missing 'expression' parameter");
126 }
127
128 PrefixResolver prefixResolver = null;
129 if (args.length > 1) {
130 final Object resolver = args[1];
131 if (resolver instanceof PrefixResolver) {
132 prefixResolver = (PrefixResolver) resolver;
133 }
134 else if (resolver instanceof NativeFunction) {
135 prefixResolver = new NativeFunctionPrefixResolver(
136 (NativeFunction) resolver, scope.getParentScope());
137 }
138 }
139
140 final XPathEvaluator evaluator = (XPathEvaluator) thisObj;
141
142 try {
143 final String xpath = JavaScriptEngine.toString(args[0]);
144 final DomNode doc = ((Window) scope).getDocument().getDocumentElement().getDomNodeOrDie();
145 final XPathExpression xPathExpression = new XPathExpression(xpath, prefixResolver, doc);
146 xPathExpression.setParentScope(evaluator.getParentScope());
147 xPathExpression.setPrototype(evaluator.getPrototype(xPathExpression.getClass()));
148
149 return xPathExpression;
150 }
151 catch (final Exception e) {
152 throw JavaScriptEngine.syntaxError(
153 "Failed to compile xpath '" + args[0] + "' (" + e.getMessage() + ")");
154 }
155 }
156 }