author | joehw |
Wed, 18 Oct 2017 13:25:49 -0700 | |
changeset 47359 | e1a6c0168741 |
parent 47216 | 71c04702a3d5 |
child 48409 | 5ab69533994b |
permissions | -rw-r--r-- |
6 | 1 |
/* |
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
2 |
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. |
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
3 |
* @LastModified: Oct 2017 |
6 | 4 |
*/ |
5 |
/* |
|
44797
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
6 |
* Licensed to the Apache Software Foundation (ASF) under one or more |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
7 |
* contributor license agreements. See the NOTICE file distributed with |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
8 |
* this work for additional information regarding copyright ownership. |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
9 |
* The ASF licenses this file to You under the Apache License, Version 2.0 |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
10 |
* (the "License"); you may not use this file except in compliance with |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
11 |
* the License. You may obtain a copy of the License at |
6 | 12 |
* |
44797
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
13 |
* http://www.apache.org/licenses/LICENSE-2.0 |
6 | 14 |
* |
15 |
* Unless required by applicable law or agreed to in writing, software |
|
16 |
* distributed under the License is distributed on an "AS IS" BASIS, |
|
17 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
18 |
* See the License for the specific language governing permissions and |
|
19 |
* limitations under the License. |
|
20 |
*/ |
|
44797
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
21 |
|
6 | 22 |
package com.sun.org.apache.xpath.internal.axes; |
23 |
||
24 |
import com.sun.org.apache.xml.internal.dtm.Axis; |
|
25 |
import com.sun.org.apache.xml.internal.dtm.DTM; |
|
26 |
import com.sun.org.apache.xml.internal.dtm.DTMIterator; |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
27 |
import com.sun.org.apache.xml.internal.utils.QName; |
6 | 28 |
import com.sun.org.apache.xpath.internal.Expression; |
29 |
import com.sun.org.apache.xpath.internal.ExpressionOwner; |
|
30 |
import com.sun.org.apache.xpath.internal.XPathVisitor; |
|
31 |
import com.sun.org.apache.xpath.internal.compiler.Compiler; |
|
32 |
import com.sun.org.apache.xpath.internal.compiler.OpCodes; |
|
12458 | 33 |
import com.sun.org.apache.xpath.internal.compiler.OpMap; |
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
34 |
import java.util.List; |
6 | 35 |
|
36 |
/** |
|
37 |
* This class extends NodeSetDTM, which implements DTMIterator, |
|
38 |
* and fetches nodes one at a time in document order based on a XPath |
|
39 |
* <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>. |
|
40 |
* As each node is iterated via nextNode(), the node is also stored |
|
41 |
* in the NodeVector, so that previousNode() can easily be done. |
|
42 |
* @xsl.usage advanced |
|
43 |
*/ |
|
44 |
public class UnionPathIterator extends LocPathIterator |
|
45 |
implements Cloneable, DTMIterator, java.io.Serializable, PathComponent |
|
46 |
{ |
|
47 |
static final long serialVersionUID = -3910351546843826781L; |
|
48 |
||
49 |
/** |
|
50 |
* Constructor to create an instance which you can add location paths to. |
|
51 |
*/ |
|
52 |
public UnionPathIterator() |
|
53 |
{ |
|
54 |
||
55 |
super(); |
|
56 |
||
57 |
// m_mutable = false; |
|
58 |
// m_cacheNodes = false; |
|
59 |
m_iterators = null; |
|
60 |
m_exprs = null; |
|
61 |
} |
|
62 |
||
63 |
/** |
|
64 |
* Initialize the context values for this expression |
|
65 |
* after it is cloned. |
|
66 |
* |
|
67 |
* @param context The XPath runtime context for this |
|
68 |
* transformation. |
|
69 |
*/ |
|
70 |
public void setRoot(int context, Object environment) |
|
71 |
{ |
|
72 |
super.setRoot(context, environment); |
|
73 |
||
74 |
try |
|
75 |
{ |
|
76 |
if (null != m_exprs) |
|
77 |
{ |
|
78 |
int n = m_exprs.length; |
|
79 |
DTMIterator newIters[] = new DTMIterator[n]; |
|
80 |
||
81 |
for (int i = 0; i < n; i++) |
|
82 |
{ |
|
83 |
DTMIterator iter = m_exprs[i].asIterator(m_execContext, context); |
|
84 |
newIters[i] = iter; |
|
85 |
iter.nextNode(); |
|
86 |
} |
|
87 |
m_iterators = newIters; |
|
88 |
} |
|
89 |
} |
|
90 |
catch(Exception e) |
|
91 |
{ |
|
92 |
throw new com.sun.org.apache.xml.internal.utils.WrappedRuntimeException(e); |
|
93 |
} |
|
94 |
} |
|
95 |
||
96 |
/** |
|
97 |
* Add an iterator to the union list. |
|
98 |
* |
|
99 |
* @param expr non-null reference to a location path iterator. |
|
100 |
*/ |
|
101 |
public void addIterator(DTMIterator expr) |
|
102 |
{ |
|
103 |
||
104 |
// Increase array size by only 1 at a time. Fix this |
|
105 |
// if it looks to be a problem. |
|
106 |
if (null == m_iterators) |
|
107 |
{ |
|
108 |
m_iterators = new DTMIterator[1]; |
|
109 |
m_iterators[0] = expr; |
|
110 |
} |
|
111 |
else |
|
112 |
{ |
|
113 |
DTMIterator[] exprs = m_iterators; |
|
114 |
int len = m_iterators.length; |
|
115 |
||
116 |
m_iterators = new DTMIterator[len + 1]; |
|
117 |
||
118 |
System.arraycopy(exprs, 0, m_iterators, 0, len); |
|
119 |
||
120 |
m_iterators[len] = expr; |
|
121 |
} |
|
122 |
expr.nextNode(); |
|
123 |
if(expr instanceof Expression) |
|
124 |
((Expression)expr).exprSetParent(this); |
|
125 |
} |
|
126 |
||
127 |
/** |
|
128 |
* Detaches the iterator from the set which it iterated over, releasing |
|
129 |
* any computational resources and placing the iterator in the INVALID |
|
130 |
* state. After<code>detach</code> has been invoked, calls to |
|
131 |
* <code>nextNode</code> or<code>previousNode</code> will raise the |
|
132 |
* exception INVALID_STATE_ERR. |
|
133 |
*/ |
|
134 |
public void detach() |
|
135 |
{ |
|
136 |
if(m_allowDetach && null != m_iterators){ |
|
137 |
int n = m_iterators.length; |
|
138 |
for(int i = 0; i < n; i++) |
|
139 |
{ |
|
140 |
m_iterators[i].detach(); |
|
141 |
} |
|
142 |
m_iterators = null; |
|
143 |
} |
|
144 |
} |
|
145 |
||
146 |
||
147 |
/** |
|
148 |
* Create a UnionPathIterator object, including creation |
|
149 |
* of location path iterators from the opcode list, and call back |
|
150 |
* into the Compiler to create predicate expressions. |
|
151 |
* |
|
152 |
* @param compiler The Compiler which is creating |
|
153 |
* this expression. |
|
154 |
* @param opPos The position of this iterator in the |
|
155 |
* opcode list from the compiler. |
|
156 |
* |
|
157 |
* @throws javax.xml.transform.TransformerException |
|
158 |
*/ |
|
159 |
public UnionPathIterator(Compiler compiler, int opPos) |
|
160 |
throws javax.xml.transform.TransformerException |
|
161 |
{ |
|
162 |
||
163 |
super(); |
|
164 |
||
12458 | 165 |
opPos = OpMap.getFirstChildPos(opPos); |
6 | 166 |
|
167 |
loadLocationPaths(compiler, opPos, 0); |
|
168 |
} |
|
169 |
||
170 |
/** |
|
171 |
* This will return an iterator capable of handling the union of paths given. |
|
172 |
* |
|
173 |
* @param compiler The Compiler which is creating |
|
174 |
* this expression. |
|
175 |
* @param opPos The position of this iterator in the |
|
176 |
* opcode list from the compiler. |
|
177 |
* |
|
178 |
* @return Object that is derived from LocPathIterator. |
|
179 |
* |
|
180 |
* @throws javax.xml.transform.TransformerException |
|
181 |
*/ |
|
182 |
public static LocPathIterator createUnionIterator(Compiler compiler, int opPos) |
|
183 |
throws javax.xml.transform.TransformerException |
|
184 |
{ |
|
185 |
// For the moment, I'm going to first create a full UnionPathIterator, and |
|
186 |
// then see if I can reduce it to a UnionChildIterator. It would obviously |
|
187 |
// be more effecient to just test for the conditions for a UnionChildIterator, |
|
188 |
// and then create that directly. |
|
189 |
UnionPathIterator upi = new UnionPathIterator(compiler, opPos); |
|
190 |
int nPaths = upi.m_exprs.length; |
|
191 |
boolean isAllChildIterators = true; |
|
192 |
for(int i = 0; i < nPaths; i++) |
|
193 |
{ |
|
194 |
LocPathIterator lpi = upi.m_exprs[i]; |
|
195 |
||
196 |
if(lpi.getAxis() != Axis.CHILD) |
|
197 |
{ |
|
198 |
isAllChildIterators = false; |
|
199 |
break; |
|
200 |
} |
|
201 |
else |
|
202 |
{ |
|
203 |
// check for positional predicates or position function, which won't work. |
|
204 |
if(HasPositionalPredChecker.check(lpi)) |
|
205 |
{ |
|
206 |
isAllChildIterators = false; |
|
207 |
break; |
|
208 |
} |
|
209 |
} |
|
210 |
} |
|
211 |
if(isAllChildIterators) |
|
212 |
{ |
|
213 |
UnionChildIterator uci = new UnionChildIterator(); |
|
214 |
||
215 |
for(int i = 0; i < nPaths; i++) |
|
216 |
{ |
|
217 |
PredicatedNodeTest lpi = upi.m_exprs[i]; |
|
218 |
// I could strip the lpi down to a pure PredicatedNodeTest, but |
|
219 |
// I don't think it's worth it. Note that the test can be used |
|
220 |
// as a static object... so it doesn't have to be cloned. |
|
221 |
uci.addNodeTest(lpi); |
|
222 |
} |
|
223 |
return uci; |
|
224 |
||
225 |
} |
|
226 |
else |
|
227 |
return upi; |
|
228 |
} |
|
229 |
||
230 |
/** |
|
231 |
* Get the analysis bits for this walker, as defined in the WalkerFactory. |
|
232 |
* @return One of WalkerFactory#BIT_DESCENDANT, etc. |
|
233 |
*/ |
|
234 |
public int getAnalysisBits() |
|
235 |
{ |
|
236 |
int bits = 0; |
|
237 |
||
238 |
if (m_exprs != null) |
|
239 |
{ |
|
240 |
int n = m_exprs.length; |
|
241 |
||
242 |
for (int i = 0; i < n; i++) |
|
243 |
{ |
|
244 |
int bit = m_exprs[i].getAnalysisBits(); |
|
245 |
bits |= bit; |
|
246 |
} |
|
247 |
} |
|
248 |
||
249 |
return bits; |
|
250 |
} |
|
251 |
||
252 |
/** |
|
253 |
* Read the object from a serialization stream. |
|
254 |
* |
|
255 |
* @param stream Input stream to read from |
|
256 |
* |
|
257 |
* @throws java.io.IOException |
|
258 |
* @throws javax.xml.transform.TransformerException |
|
259 |
*/ |
|
260 |
private void readObject(java.io.ObjectInputStream stream) |
|
261 |
throws java.io.IOException, javax.xml.transform.TransformerException |
|
262 |
{ |
|
263 |
try |
|
264 |
{ |
|
265 |
stream.defaultReadObject(); |
|
266 |
m_clones = new IteratorPool(this); |
|
267 |
} |
|
268 |
catch (ClassNotFoundException cnfe) |
|
269 |
{ |
|
270 |
throw new javax.xml.transform.TransformerException(cnfe); |
|
271 |
} |
|
272 |
} |
|
273 |
||
274 |
/** |
|
275 |
* Get a cloned LocPathIterator that holds the same |
|
276 |
* position as this iterator. |
|
277 |
* |
|
278 |
* @return A clone of this iterator that holds the same node position. |
|
279 |
* |
|
280 |
* @throws CloneNotSupportedException |
|
281 |
*/ |
|
282 |
public Object clone() throws CloneNotSupportedException |
|
283 |
{ |
|
284 |
||
285 |
UnionPathIterator clone = (UnionPathIterator) super.clone(); |
|
286 |
if (m_iterators != null) |
|
287 |
{ |
|
288 |
int n = m_iterators.length; |
|
289 |
||
290 |
clone.m_iterators = new DTMIterator[n]; |
|
291 |
||
292 |
for (int i = 0; i < n; i++) |
|
293 |
{ |
|
294 |
clone.m_iterators[i] = (DTMIterator)m_iterators[i].clone(); |
|
295 |
} |
|
296 |
} |
|
297 |
||
298 |
return clone; |
|
299 |
} |
|
300 |
||
301 |
||
302 |
/** |
|
303 |
* Create a new location path iterator. |
|
304 |
* |
|
305 |
* @param compiler The Compiler which is creating |
|
306 |
* this expression. |
|
307 |
* @param opPos The position of this iterator in the |
|
308 |
* |
|
309 |
* @return New location path iterator. |
|
310 |
* |
|
311 |
* @throws javax.xml.transform.TransformerException |
|
312 |
*/ |
|
313 |
protected LocPathIterator createDTMIterator( |
|
314 |
Compiler compiler, int opPos) throws javax.xml.transform.TransformerException |
|
315 |
{ |
|
316 |
LocPathIterator lpi = (LocPathIterator)WalkerFactory.newDTMIterator(compiler, opPos, |
|
317 |
(compiler.getLocationPathDepth() <= 0)); |
|
318 |
return lpi; |
|
319 |
} |
|
320 |
||
321 |
/** |
|
322 |
* Initialize the location path iterators. Recursive. |
|
323 |
* |
|
324 |
* @param compiler The Compiler which is creating |
|
325 |
* this expression. |
|
326 |
* @param opPos The position of this iterator in the |
|
327 |
* opcode list from the compiler. |
|
328 |
* @param count The insert position of the iterator. |
|
329 |
* |
|
330 |
* @throws javax.xml.transform.TransformerException |
|
331 |
*/ |
|
332 |
protected void loadLocationPaths(Compiler compiler, int opPos, int count) |
|
333 |
throws javax.xml.transform.TransformerException |
|
334 |
{ |
|
335 |
||
336 |
// TODO: Handle unwrapped FilterExpr |
|
337 |
int steptype = compiler.getOp(opPos); |
|
338 |
||
339 |
if (steptype == OpCodes.OP_LOCATIONPATH) |
|
340 |
{ |
|
341 |
loadLocationPaths(compiler, compiler.getNextOpPos(opPos), count + 1); |
|
342 |
||
343 |
m_exprs[count] = createDTMIterator(compiler, opPos); |
|
344 |
m_exprs[count].exprSetParent(this); |
|
345 |
} |
|
346 |
else |
|
347 |
{ |
|
348 |
||
349 |
// Have to check for unwrapped functions, which the LocPathIterator |
|
350 |
// doesn't handle. |
|
351 |
switch (steptype) |
|
352 |
{ |
|
353 |
case OpCodes.OP_VARIABLE : |
|
354 |
case OpCodes.OP_EXTFUNCTION : |
|
355 |
case OpCodes.OP_FUNCTION : |
|
356 |
case OpCodes.OP_GROUP : |
|
357 |
loadLocationPaths(compiler, compiler.getNextOpPos(opPos), count + 1); |
|
358 |
||
359 |
WalkingIterator iter = |
|
360 |
new WalkingIterator(compiler.getNamespaceContext()); |
|
361 |
iter.exprSetParent(this); |
|
362 |
||
363 |
if(compiler.getLocationPathDepth() <= 0) |
|
364 |
iter.setIsTopLevel(true); |
|
365 |
||
366 |
iter.m_firstWalker = new com.sun.org.apache.xpath.internal.axes.FilterExprWalker(iter); |
|
367 |
||
368 |
iter.m_firstWalker.init(compiler, opPos, steptype); |
|
369 |
||
370 |
m_exprs[count] = iter; |
|
371 |
break; |
|
372 |
default : |
|
373 |
m_exprs = new LocPathIterator[count]; |
|
374 |
} |
|
375 |
} |
|
376 |
} |
|
377 |
||
378 |
/** |
|
379 |
* Returns the next node in the set and advances the position of the |
|
380 |
* iterator in the set. After a DTMIterator is created, the first call |
|
381 |
* to nextNode() returns the first node in the set. |
|
382 |
* @return The next <code>Node</code> in the set being iterated over, or |
|
383 |
* <code>null</code> if there are no more members in that set. |
|
384 |
*/ |
|
385 |
public int nextNode() |
|
386 |
{ |
|
387 |
if(m_foundLast) |
|
388 |
return DTM.NULL; |
|
389 |
||
390 |
// Loop through the iterators getting the current fetched |
|
391 |
// node, and get the earliest occuring in document order |
|
392 |
int earliestNode = DTM.NULL; |
|
393 |
||
394 |
if (null != m_iterators) |
|
395 |
{ |
|
396 |
int n = m_iterators.length; |
|
397 |
int iteratorUsed = -1; |
|
398 |
||
399 |
for (int i = 0; i < n; i++) |
|
400 |
{ |
|
401 |
int node = m_iterators[i].getCurrentNode(); |
|
402 |
||
403 |
if (DTM.NULL == node) |
|
404 |
continue; |
|
405 |
else if (DTM.NULL == earliestNode) |
|
406 |
{ |
|
407 |
iteratorUsed = i; |
|
408 |
earliestNode = node; |
|
409 |
} |
|
410 |
else |
|
411 |
{ |
|
412 |
if (node == earliestNode) |
|
413 |
{ |
|
414 |
||
415 |
// Found a duplicate, so skip past it. |
|
416 |
m_iterators[i].nextNode(); |
|
417 |
} |
|
418 |
else |
|
419 |
{ |
|
420 |
DTM dtm = getDTM(node); |
|
421 |
||
422 |
if (dtm.isNodeAfter(node, earliestNode)) |
|
423 |
{ |
|
424 |
iteratorUsed = i; |
|
425 |
earliestNode = node; |
|
426 |
} |
|
427 |
} |
|
428 |
} |
|
429 |
} |
|
430 |
||
431 |
if (DTM.NULL != earliestNode) |
|
432 |
{ |
|
433 |
m_iterators[iteratorUsed].nextNode(); |
|
434 |
||
435 |
incrementCurrentPos(); |
|
436 |
} |
|
437 |
else |
|
438 |
m_foundLast = true; |
|
439 |
} |
|
440 |
||
441 |
m_lastFetched = earliestNode; |
|
442 |
||
443 |
return earliestNode; |
|
444 |
} |
|
445 |
||
446 |
/** |
|
447 |
* This function is used to fixup variables from QNames to stack frame |
|
448 |
* indexes at stylesheet build time. |
|
449 |
* @param vars List of QNames that correspond to variables. This list |
|
450 |
* should be searched backwards for the first qualified name that |
|
451 |
* corresponds to the variable reference qname. The position of the |
|
452 |
* QName in the vector from the start of the vector will be its position |
|
453 |
* in the stack frame (but variables above the globalsTop value will need |
|
454 |
* to be offset to the current stack frame). |
|
455 |
*/ |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
456 |
public void fixupVariables(List<QName> vars, int globalsSize) |
6 | 457 |
{ |
458 |
for (int i = 0; i < m_exprs.length; i++) |
|
459 |
{ |
|
460 |
m_exprs[i].fixupVariables(vars, globalsSize); |
|
461 |
} |
|
462 |
||
463 |
} |
|
464 |
||
465 |
/** |
|
466 |
* The location path iterators, one for each |
|
467 |
* <a href="http://www.w3.org/TR/xpath#NT-LocationPath">location |
|
468 |
* path</a> contained in the union expression. |
|
469 |
* @serial |
|
470 |
*/ |
|
471 |
protected LocPathIterator[] m_exprs; |
|
472 |
||
473 |
||
474 |
/** |
|
475 |
* The location path iterators, one for each |
|
476 |
* <a href="http://www.w3.org/TR/xpath#NT-LocationPath">location |
|
477 |
* path</a> contained in the union expression. |
|
478 |
* @serial |
|
479 |
*/ |
|
480 |
protected DTMIterator[] m_iterators; |
|
481 |
||
482 |
/** |
|
483 |
* Returns the axis being iterated, if it is known. |
|
484 |
* |
|
485 |
* @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple |
|
486 |
* types. |
|
487 |
*/ |
|
488 |
public int getAxis() |
|
489 |
{ |
|
490 |
// Could be smarter. |
|
491 |
return -1; |
|
492 |
} |
|
493 |
||
494 |
class iterOwner implements ExpressionOwner |
|
495 |
{ |
|
496 |
int m_index; |
|
497 |
||
498 |
iterOwner(int index) |
|
499 |
{ |
|
500 |
m_index = index; |
|
501 |
} |
|
502 |
||
503 |
/** |
|
504 |
* @see ExpressionOwner#getExpression() |
|
505 |
*/ |
|
506 |
public Expression getExpression() |
|
507 |
{ |
|
508 |
return m_exprs[m_index]; |
|
509 |
} |
|
510 |
||
511 |
/** |
|
512 |
* @see ExpressionOwner#setExpression(Expression) |
|
513 |
*/ |
|
514 |
public void setExpression(Expression exp) |
|
515 |
{ |
|
516 |
||
517 |
if(!(exp instanceof LocPathIterator)) |
|
518 |
{ |
|
519 |
// Yuck. Need FilterExprIter. Or make it so m_exprs can be just |
|
520 |
// plain expressions? |
|
521 |
WalkingIterator wi = new WalkingIterator(getPrefixResolver()); |
|
522 |
FilterExprWalker few = new FilterExprWalker(wi); |
|
523 |
wi.setFirstWalker(few); |
|
524 |
few.setInnerExpression(exp); |
|
525 |
wi.exprSetParent(UnionPathIterator.this); |
|
526 |
few.exprSetParent(wi); |
|
527 |
exp.exprSetParent(few); |
|
528 |
exp = wi; |
|
529 |
} |
|
530 |
else |
|
531 |
exp.exprSetParent(UnionPathIterator.this); |
|
532 |
m_exprs[m_index] = (LocPathIterator)exp; |
|
533 |
} |
|
534 |
||
535 |
} |
|
536 |
||
537 |
/** |
|
538 |
* @see com.sun.org.apache.xpath.internal.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor) |
|
539 |
*/ |
|
540 |
public void callVisitors(ExpressionOwner owner, XPathVisitor visitor) |
|
541 |
{ |
|
542 |
if(visitor.visitUnionPath(owner, this)) |
|
543 |
{ |
|
544 |
if(null != m_exprs) |
|
545 |
{ |
|
546 |
int n = m_exprs.length; |
|
547 |
for(int i = 0; i < n; i++) |
|
548 |
{ |
|
549 |
m_exprs[i].callVisitors(new iterOwner(i), visitor); |
|
550 |
} |
|
551 |
} |
|
552 |
} |
|
553 |
} |
|
554 |
||
555 |
/** |
|
556 |
* @see Expression#deepEquals(Expression) |
|
557 |
*/ |
|
558 |
public boolean deepEquals(Expression expr) |
|
559 |
{ |
|
560 |
if (!super.deepEquals(expr)) |
|
561 |
return false; |
|
562 |
||
563 |
UnionPathIterator upi = (UnionPathIterator) expr; |
|
564 |
||
565 |
if (null != m_exprs) |
|
566 |
{ |
|
567 |
int n = m_exprs.length; |
|
568 |
||
569 |
if((null == upi.m_exprs) || (upi.m_exprs.length != n)) |
|
570 |
return false; |
|
571 |
||
572 |
for (int i = 0; i < n; i++) |
|
573 |
{ |
|
574 |
if(!m_exprs[i].deepEquals(upi.m_exprs[i])) |
|
575 |
return false; |
|
576 |
} |
|
577 |
} |
|
578 |
else if (null != upi.m_exprs) |
|
579 |
{ |
|
580 |
return false; |
|
581 |
} |
|
582 |
||
583 |
return true; |
|
584 |
} |
|
585 |
||
586 |
||
587 |
} |