1 /*
2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3 */
4 /*
5 * Licensed to the Apache Software Foundation (ASF) under one or more
6 * contributor license agreements. See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 package com.sun.org.apache.xpath.internal.patterns;
22
23 import com.sun.org.apache.xml.internal.dtm.DTM;
24 import com.sun.org.apache.xml.internal.dtm.DTMIterator;
25 import com.sun.org.apache.xml.internal.utils.QName;
26 import com.sun.org.apache.xpath.internal.Expression;
27 import com.sun.org.apache.xpath.internal.ExpressionOwner;
28 import com.sun.org.apache.xpath.internal.XPathContext;
29 import com.sun.org.apache.xpath.internal.XPathVisitor;
30 import com.sun.org.apache.xpath.internal.objects.XNumber;
31 import com.sun.org.apache.xpath.internal.objects.XObject;
32 import java.util.List;
33
34 /**
35 * Match pattern step that contains a function.
36 * @xsl.usage advanced
37 * @LastModified: Oct 2017
38 */
39 public class FunctionPattern extends StepPattern
40 {
41 static final long serialVersionUID = -5426793413091209944L;
42
43 /**
44 * Construct a FunctionPattern from a
45 * {@link com.sun.org.apache.xpath.internal.functions.Function expression}.
46 *
47 * NEEDSDOC @param expr
48 */
49 public FunctionPattern(Expression expr, int axis, int predaxis)
50 {
51
52 super(0, null, null, axis, predaxis);
53
54 m_functionExpr = expr;
55 }
56
57 /**
58 * Static calc of match score.
59 */
60 public final void calcScore()
61 {
62
63 m_score = SCORE_OTHER;
64
65 if (null == m_targetString)
66 calcTargetString();
67 }
68
69 /**
70 * Should be a {@link com.sun.org.apache.xpath.internal.functions.Function expression}.
71 * @serial
72 */
73 Expression m_functionExpr;
74
75 /**
76 * This function is used to fixup variables from QNames to stack frame
77 * indexes at stylesheet build time.
78 * @param vars List of QNames that correspond to variables. This list
79 * should be searched backwards for the first qualified name that
80 * corresponds to the variable reference qname. The position of the
81 * QName in the vector from the start of the vector will be its position
82 * in the stack frame (but variables above the globalsTop value will need
83 * to be offset to the current stack frame).
84 */
85 public void fixupVariables(List<QName> vars, int globalsSize)
86 {
87 super.fixupVariables(vars, globalsSize);
88 m_functionExpr.fixupVariables(vars, globalsSize);
89 }
90
91
92 /**
93 * Test a node to see if it matches the given node test.
94 *
95 * @param xctxt XPath runtime context.
96 *
97 * @return {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NODETEST},
98 * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NONE},
99 * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NSWILD},
100 * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_QNAME}, or
101 * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_OTHER}.
102 *
103 * @throws javax.xml.transform.TransformerException
104 */
105 public XObject execute(XPathContext xctxt, int context)
106 throws javax.xml.transform.TransformerException
107 {
108
109 DTMIterator nl = m_functionExpr.asIterator(xctxt, context);
110 XNumber score = SCORE_NONE;
111
112 if (null != nl)
113 {
114 int n;
115
116 while (DTM.NULL != (n = nl.nextNode()))
117 {
118 score = (n == context) ? SCORE_OTHER : SCORE_NONE;
119
120 if (score == SCORE_OTHER)
121 {
122 context = n;
123
124 break;
125 }
126 }
127
128 // nl.detach();
129 }
130 nl.detach();
131
132 return score;
133 }
134
135 /**
136 * Test a node to see if it matches the given node test.
137 *
138 * @param xctxt XPath runtime context.
139 *
140 * @return {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NODETEST},
141 * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NONE},
142 * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NSWILD},
143 * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_QNAME}, or
144 * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_OTHER}.
145 *
146 * @throws javax.xml.transform.TransformerException
147 */
148 public XObject execute(XPathContext xctxt, int context,
149 DTM dtm, int expType)
150 throws javax.xml.transform.TransformerException
151 {
152
153 DTMIterator nl = m_functionExpr.asIterator(xctxt, context);
154 XNumber score = SCORE_NONE;
155
156 if (null != nl)
157 {
158 int n;
159
160 while (DTM.NULL != (n = nl.nextNode()))
161 {
162 score = (n == context) ? SCORE_OTHER : SCORE_NONE;
163
164 if (score == SCORE_OTHER)
165 {
166 context = n;
167
168 break;
169 }
170 }
171
172 nl.detach();
173 }
174
175 return score;
176 }
177
178 /**
179 * Test a node to see if it matches the given node test.
180 *
181 * @param xctxt XPath runtime context.
182 *
183 * @return {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NODETEST},
184 * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NONE},
185 * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NSWILD},
186 * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_QNAME}, or
187 * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_OTHER}.
188 *
189 * @throws javax.xml.transform.TransformerException
190 */
191 public XObject execute(XPathContext xctxt)
192 throws javax.xml.transform.TransformerException
193 {
194
195 int context = xctxt.getCurrentNode();
196 DTMIterator nl = m_functionExpr.asIterator(xctxt, context);
197 XNumber score = SCORE_NONE;
198
199 if (null != nl)
200 {
201 int n;
202
203 while (DTM.NULL != (n = nl.nextNode()))
204 {
205 score = (n == context) ? SCORE_OTHER : SCORE_NONE;
206
207 if (score == SCORE_OTHER)
208 {
209 context = n;
210
211 break;
212 }
213 }
214
215 nl.detach();
216 }
217
218 return score;
219 }
220
221 class FunctionOwner implements ExpressionOwner
222 {
223 /**
224 * @see ExpressionOwner#getExpression()
225 */
226 public Expression getExpression()
227 {
228 return m_functionExpr;
229 }
230
231
232 /**
233 * @see ExpressionOwner#setExpression(Expression)
234 */
235 public void setExpression(Expression exp)
236 {
237 exp.exprSetParent(FunctionPattern.this);
238 m_functionExpr = exp;
239 }
240 }
241
242 /**
243 * Call the visitor for the function.
244 */
245 protected void callSubtreeVisitors(XPathVisitor visitor)
246 {
247 m_functionExpr.callVisitors(new FunctionOwner(), visitor);
248 super.callSubtreeVisitors(visitor);
249 }
250
251 }
--- EOF ---