View Javadoc

1   /*
2    * Copyright 1999-2004 The Apache Software Foundation
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.jxpath.ri.axes;
17  
18  import org.apache.commons.jxpath.ri.EvalContext;
19  import org.apache.commons.jxpath.ri.compiler.NodeTest;
20  import org.apache.commons.jxpath.ri.model.NodePointer;
21  
22  /***
23   * EvalContext that walks the "ancestor::" and "ancestor-or-self::" axes.
24   *
25   * @author Dmitri Plotnikov
26   * @version $Revision: 1.15 $ $Date: 2004/03/25 03:49:50 $
27   */
28  public class AncestorContext extends EvalContext {
29      private NodeTest nodeTest;
30      private boolean setStarted = false;
31      private NodePointer currentNodePointer;
32      private boolean includeSelf;
33  
34      /***
35       * @param parentContext represents the previous step on the path
36       * @param  includeSelf differentiates between "ancestor::" and "ancestor-
37       * or-self::" axes
38       * @param nameTest is the name of the element(s) we are looking for
39       */
40      public AncestorContext(
41          EvalContext parentContext,
42          boolean includeSelf,
43          NodeTest nodeTest) 
44      {
45          super(parentContext);
46          this.includeSelf = includeSelf;
47          this.nodeTest = nodeTest;
48      }
49  
50      public NodePointer getCurrentNodePointer() {
51          return currentNodePointer;
52      }
53  
54      public int getDocumentOrder() {
55          return -1;
56      }
57  
58      public void reset() {
59          super.reset();
60          setStarted = false;
61      }
62  
63      public boolean setPosition(int position) {
64          if (position < getCurrentPosition()) {
65              reset();
66          }
67  
68          while (getCurrentPosition() < position) {
69              if (!nextNode()) {
70                  return false;
71              }
72          }
73          return true;
74      }
75  
76      public boolean nextNode() {
77          if (!setStarted) {
78              setStarted = true;
79              currentNodePointer = parentContext.getCurrentNodePointer();
80              if (includeSelf) {
81                  if (currentNodePointer.testNode(nodeTest)) {
82                      position++;
83                      return true;
84                  }
85              }
86          }
87  
88          while (true) {
89              currentNodePointer = currentNodePointer.getImmediateParentPointer();
90  
91              if (currentNodePointer == null) {
92                  return false;
93              }
94  
95              if (currentNodePointer.testNode(nodeTest)) {
96                  position++;
97                  return true;
98              }
99          }
100     }
101 }