View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2024 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.internal.utils;
21  
22  import java.util.HashMap;
23  import java.util.Map;
24  
25  import com.puppycrawl.tools.checkstyle.DetailAstImpl;
26  import com.puppycrawl.tools.checkstyle.api.DetailAST;
27  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
28  import com.puppycrawl.tools.checkstyle.xpath.RootNode;
29  import net.sf.saxon.om.NodeInfo;
30  
31  /**
32   * XpathIteratorUtil.
33   *
34   * @noinspection ClassOnlyUsedInOnePackage
35   * @noinspectionreason ClassOnlyUsedInOnePackage - class is internal tool, and only used in testing
36   */
37  public final class XpathIteratorUtil {
38  
39      /**
40       * Map from {@link NodeInfo#getLocalPart()} to {@link NodeInfo}.
41       */
42      private static final Map<String, NodeInfo> NODES_BY_LOCAL_PART = new HashMap<>();
43  
44      static {
45          fillMap(new RootNode(createTree()));
46      }
47  
48      private XpathIteratorUtil() {
49      }
50  
51      /**
52       * Finds node by its {@link NodeInfo#getLocalPart()} value.
53       *
54       * @param localPart text to be searched
55       *
56       * @return corresponding node
57       */
58      public static NodeInfo findNode(String localPart) {
59          return NODES_BY_LOCAL_PART.get(localPart);
60      }
61  
62      /**
63       * Iterates Xpath tree nodes and fills the map.
64       *
65       * @param cur current {@link NodeInfo} node
66       */
67      private static void fillMap(NodeInfo cur) {
68          NODES_BY_LOCAL_PART.put(cur.getLocalPart(), cur);
69          for (NodeInfo node : cur.children()) {
70              fillMap(node);
71          }
72      }
73  
74      /**
75       * Creates AST tree for iteration tests and returns root.
76       * <p>
77       * PACKAGE_DEF -> package [1:0]
78       * |--ANNOTATIONS -> ANNOTATIONS [1:8]
79       *     `--ANNOTATION_DEF -> ANNOTATIONS [1:8]
80       * `--CLASS_DEF -> CLASS_DEF [3:0]
81       *     `--OBJBLOCK -> OBJBLOCK [3:19]
82       *         |--LCURLY -> { [3:19]
83       *         |--METHOD_DEF -> METHOD_DEF [4:4]
84       *         |   |--PARAMETERS -> PARAMETERS [4:31]
85       *         |   `--SLIST -> { [4:33]
86       *         `--RCURLY -> } [8:0]
87       * </p>
88       *
89       * @return {@link DetailAST} object.
90       */
91      private static DetailAST createTree() {
92          final DetailAstImpl rootNode = createNode(TokenTypes.PACKAGE_DEF, 1, 0);
93  
94          final DetailAstImpl annotationsNode = createNode(rootNode, TokenTypes.ANNOTATIONS, 1, 8);
95          createNode(annotationsNode, TokenTypes.ANNOTATION_DEF, 1, 8);
96  
97          final DetailAstImpl classDefNode = createNode(rootNode, TokenTypes.CLASS_DEF, 3, 0);
98          final DetailAstImpl objblockNode = createNode(classDefNode, TokenTypes.OBJBLOCK, 3, 19);
99          createNode(objblockNode, TokenTypes.LCURLY, 3, 19);
100         final DetailAstImpl methodDefNode = createNode(objblockNode, TokenTypes.METHOD_DEF, 4, 4);
101         createNode(objblockNode, TokenTypes.RCURLY, 8, 0);
102 
103         createNode(methodDefNode, TokenTypes.PARAMETERS, 4, 31);
104         createNode(methodDefNode, TokenTypes.SLIST, 4, 33);
105 
106         return rootNode;
107     }
108 
109     /**
110      * Creates {@link DetailAstImpl} node with predefined parent.
111      *
112      * @param parent parent node
113      * @param tokenType token type, see {@link TokenTypes}
114      * @param lineNo line number
115      * @param columnNo column number
116      *
117      * @return {@link DetailAstImpl} object.
118      */
119     private static DetailAstImpl createNode(DetailAstImpl parent, int tokenType, int lineNo,
120                                             int columnNo) {
121         final DetailAstImpl result = createNode(tokenType, lineNo, columnNo);
122         parent.addChild(result);
123         return result;
124     }
125 
126     /**
127      * Creates {@link DetailAstImpl} node.
128      *
129      * @param tokenType token type, see {@link TokenTypes}
130      * @param lineNo line number
131      * @param columnNo column number
132      *
133      * @return {@link DetailAstImpl} object.
134      */
135     private static DetailAstImpl createNode(int tokenType, int lineNo, int columnNo) {
136         final DetailAstImpl result = new DetailAstImpl();
137         result.setType(tokenType);
138         result.setLineNo(lineNo);
139         result.setColumnNo(columnNo);
140         return result;
141     }
142 }