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.Compiler;
20  import org.apache.commons.jxpath.ri.EvalContext;
21  import org.apache.commons.jxpath.ri.QName;
22  import org.apache.commons.jxpath.ri.compiler.NodeNameTest;
23  import org.apache.commons.jxpath.ri.compiler.NodeTest;
24  import org.apache.commons.jxpath.ri.compiler.NodeTypeTest;
25  import org.apache.commons.jxpath.ri.model.NodeIterator;
26  import org.apache.commons.jxpath.ri.model.NodePointer;
27  
28  /**
29   * EvalContext that walks the "attribute::" axis.
30   *
31   * @author Dmitri Plotnikov
32   * @version $Revision: 652845 $ $Date: 2008-05-02 19:46:46 +0200 (Fr, 02 Mai 2008) $
33   */
34  public class AttributeContext extends EvalContext {
35      private static final QName WILDCARD = new QName(null, "*");
36  
37      private NodeTest nodeTest;
38      private boolean setStarted = false;
39      private NodeIterator iterator;
40      private NodePointer currentNodePointer;
41  
42      /**
43       * Create a new AttributeContext.
44       * @param parentContext represents the previous step on the path
45       * @param nodeTest is the name of the attribute we are looking for
46       */
47      public AttributeContext(EvalContext parentContext, NodeTest nodeTest) {
48          super(parentContext);
49          this.nodeTest = nodeTest;
50      }
51  
52      public NodePointer getCurrentNodePointer() {
53          return currentNodePointer;
54      }
55  
56      public void reset() {
57          setStarted = false;
58          iterator = null;
59          super.reset();
60      }
61  
62      public boolean setPosition(int position) {
63          if (position < getCurrentPosition()) {
64              reset();
65          }
66  
67          while (getCurrentPosition() < position) {
68              if (!nextNode()) {
69                  return false;
70              }
71          }
72          return true;
73      }
74  
75      public boolean nextNode() {
76          super.setPosition(getCurrentPosition() + 1);
77          if (!setStarted) {
78              setStarted = true;
79              QName name;
80              if (nodeTest instanceof NodeNameTest) {
81                  name = ((NodeNameTest) nodeTest).getNodeName();
82              }
83              else {
84                  if (nodeTest instanceof NodeTypeTest
85                          && ((NodeTypeTest) nodeTest).getNodeType() == Compiler.NODE_TYPE_NODE) {
86                      name = WILDCARD;
87                  }
88                  else {
89                      iterator = null;
90                      return false;
91                  }
92              }
93              iterator = parentContext.getCurrentNodePointer().attributeIterator(
94                      name);
95          }
96          if (iterator == null) {
97              return false;
98          }
99          if (!iterator.setPosition(iterator.getPosition() + 1)) {
100             return false;
101         }
102         currentNodePointer = iterator.getNodePointer();
103         return true;
104     }
105 }