View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2017 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ////////////////////////////////////////////////////////////////////////////////
19  
20  package com.puppycrawl.tools.checkstyle.xpath;
21  
22  import com.puppycrawl.tools.checkstyle.api.DetailAST;
23  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
24  import net.sf.saxon.om.AxisInfo;
25  import net.sf.saxon.om.NodeInfo;
26  import net.sf.saxon.tree.iter.ArrayIterator;
27  import net.sf.saxon.tree.iter.AxisIterator;
28  import net.sf.saxon.tree.iter.EmptyIterator;
29  import net.sf.saxon.tree.iter.SingleNodeIterator;
30  import net.sf.saxon.tree.util.Navigator;
31  import net.sf.saxon.type.Type;
32  
33  /**
34   * Represents root node of Xpath-tree.
35   *
36   * @author Timur Tibeyev
37   */
38  public class RootNode extends AbstractNode {
39      /** Name of the root element. */
40      private static final String ROOT_NAME = "ROOT";
41  
42      /** The ast node. */
43      private final DetailAST detailAst;
44  
45      /**
46       * Creates a new {@code RootNode} instance.
47       *
48       * @param detailAst reference to {@code DetailAST}
49       */
50      public RootNode(DetailAST detailAst) {
51          this.detailAst = detailAst;
52          if (detailAst != null) {
53              createChildren();
54          }
55      }
56  
57      /**
58       * Iterates siblings of the current node and
59       * recursively creates new Xpath-nodes.
60       */
61      private void createChildren() {
62          DetailAST currentChild = detailAst;
63          while (currentChild != null) {
64              final ElementNode child = new ElementNode(this, this, currentChild);
65              addChild(child);
66              currentChild = currentChild.getNextSibling();
67          }
68      }
69  
70      /**
71       * Returns attribute value. Throws {@code UnsupportedOperationException} because root node
72       * has no attributes.
73       * @param namespace namespace
74       * @param localPart actual name of the attribute
75       * @return attribute value
76       */
77      @Override
78      public String getAttributeValue(String namespace, String localPart) {
79          throw throwUnsupportedOperationException();
80      }
81  
82      /**
83       * Returns local part.
84       * @return local part
85       */
86      // -@cs[SimpleAccessorNameNotation] Overrides method from the base class.
87      // Issue: https://github.com/sevntu-checkstyle/sevntu.checkstyle/issues/166
88      @Override
89      public String getLocalPart() {
90          return ROOT_NAME;
91      }
92  
93      /**
94       * Returns type of the node.
95       * @return node kind
96       */
97      @Override
98      public int getNodeKind() {
99          return Type.DOCUMENT;
100     }
101 
102     /**
103      * Returns parent.
104      * @return parent
105      */
106     @Override
107     public NodeInfo getParent() {
108         return null;
109     }
110 
111     /**
112      * Returns root of the tree.
113      * @return root of the tree
114      */
115     @Override
116     public NodeInfo getRoot() {
117         return this;
118     }
119 
120     /**
121      * Returns string value.
122      * @return string value
123      */
124     // -@cs[SimpleAccessorNameNotation] Overrides method from the base class.
125     // Issue: https://github.com/sevntu-checkstyle/sevntu.checkstyle/issues/166
126     @Override
127     public String getStringValue() {
128         return ROOT_NAME;
129     }
130 
131     /**
132      * Determines axis iteration algorithm. Throws {@code UnsupportedOperationException} in case,
133      * when there is no axis iterator for given axisNumber.
134      * @param axisNumber element from {@code AxisInfo}
135      * @return {@code AxisIterator} object
136      */
137     @Override
138     public AxisIterator iterateAxis(byte axisNumber) {
139         final AxisIterator result;
140         switch (axisNumber) {
141             case AxisInfo.ANCESTOR:
142             case AxisInfo.ATTRIBUTE:
143             case AxisInfo.PARENT:
144                 result = EmptyIterator.OfNodes.THE_INSTANCE;
145                 break;
146             case AxisInfo.ANCESTOR_OR_SELF:
147             case AxisInfo.SELF:
148                 result = SingleNodeIterator.makeIterator(this);
149                 break;
150             case AxisInfo.CHILD:
151                 if (hasChildNodes()) {
152                     result = new ArrayIterator.OfNodes(
153                             getChildren().toArray(new AbstractNode[getChildren().size()]));
154                 }
155                 else {
156                     result = EmptyIterator.OfNodes.THE_INSTANCE;
157                 }
158                 break;
159             case AxisInfo.DESCENDANT:
160                 if (hasChildNodes()) {
161                     result = new Navigator.DescendantEnumeration(this, false, true);
162                 }
163                 else {
164                     result = EmptyIterator.OfNodes.THE_INSTANCE;
165                 }
166                 break;
167             case AxisInfo.DESCENDANT_OR_SELF:
168                 result = new Navigator.DescendantEnumeration(this, true, true);
169                 break;
170             default:
171                 throw throwUnsupportedOperationException();
172         }
173         return result;
174     }
175 
176     /**
177      * Returns line number.
178      * @return line number
179      */
180     @Override
181     public int getLineNumber() {
182         return detailAst.getLineNo();
183     }
184 
185     /**
186      * Returns column number.
187      * @return column number
188      */
189     @Override
190     public int getColumnNumber() {
191         return detailAst.getColumnNo();
192     }
193 
194     /**
195      * Getter method for token type.
196      * @return token type
197      */
198     @Override
199     public int getTokenType() {
200         return TokenTypes.EOF;
201     }
202 
203     /**
204      * Returns underlying node.
205      * @return underlying node
206      */
207     // -@cs[SimpleAccessorNameNotation] Overrides method from the base class.
208     // Issue: https://github.com/sevntu-checkstyle/sevntu.checkstyle/issues/166
209     @Override
210     public DetailAST getUnderlyingNode() {
211         return detailAst;
212     }
213 
214     /**
215      * Returns UnsupportedOperationException exception.
216      * @return UnsupportedOperationException exception
217      */
218     private static UnsupportedOperationException throwUnsupportedOperationException() {
219         return new UnsupportedOperationException("Operation is not supported");
220     }
221 }