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