diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/xpath/XpathQueryGenerator.java b/src/main/java/com/puppycrawl/tools/checkstyle/xpath/XpathQueryGenerator.java
new file mode 100644
index 000000000000..85f01d23402f
--- /dev/null
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/xpath/XpathQueryGenerator.java
@@ -0,0 +1,233 @@
+////////////////////////////////////////////////////////////////////////////////
+// checkstyle: Checks Java source code for adherence to a set of rules.
+// Copyright (C) 2001-2017 the original author or authors.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+////////////////////////////////////////////////////////////////////////////////
+
+package com.puppycrawl.tools.checkstyle.xpath;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+import com.puppycrawl.tools.checkstyle.utils.TokenUtils;
+
+/**
+ * Generates xpath queries. Xpath queries are generated based on received
+ * {@code DetailAst} element, line number and column number.
+ *
+ *
+ * Example class
+ *
+ *
+ * public class Main {
+ *
+ * public String sayHello(String name) {
+ * return "Hello, " + name;
+ * }
+ * }
+ *
+ *
+ *
+ * Following expression returns list of queries. Each query is the string representing full
+ * path to the node inside Xpath tree, whose line number is 3 and column number is 4.
+ *
+ *
+ * new XpathQueryGenerator(rootAst, 3, 4).generate();
+ *
+ *
+ *
+ * Result list
+ *
+ *
+ * -
+ * /CLASS_DEF[@text='Main']/OBJBLOCK/METHOD_DEF[@text='sayHello']
+ *
+ * -
+ * /CLASS_DEF[@text='Main']/OBJBLOCK/METHOD_DEF[@text='sayHello']/MODIFIERS
+ *
+ * -
+ * /CLASS_DEF[@text='Main']/OBJBLOCK/METHOD_DEF[@text='sayHello']/MODIFIERS/LITERAL_PUBLIC
+ *
+ *
+ *
+ * @author Timur Tibeyev.
+ */
+public class XpathQueryGenerator {
+ /** The root ast. */
+ private final DetailAST rootAst;
+ /** The line number of the element for which the query should be generated. */
+ private final int lineNumber;
+ /** The column number of the element for which the query should be generated. */
+ private final int columnNumber;
+
+ /**
+ * Creates a new {@code XpathQueryGenerator} instance.
+ *
+ * @param rootAst root ast
+ * @param lineNumber line number of the element for which the query should be generated
+ * @param columnNumber column number of the element for which the query should be generated
+ */
+ public XpathQueryGenerator(DetailAST rootAst, int lineNumber, int columnNumber) {
+ this.rootAst = rootAst;
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ }
+
+ /**
+ * Returns list of xpath queries of nodes, matching line and column number.
+ * This approach uses DetailAST traversal. DetailAST means detail abstract syntax tree.
+ * @return list of xpath queries of nodes, matching line and column number
+ */
+ public List generate() {
+ return getMatchingAstElements(rootAst, lineNumber, columnNumber)
+ .stream()
+ .map(XpathQueryGenerator::generateXpathQuery)
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Returns child {@code DetailAst} element of the given root,
+ * which has child element with token type equals to {@link TokenTypes#IDENT}.
+ * @param root {@code DetailAST} root ast
+ * @return child {@code DetailAst} element of the given root
+ */
+ private static DetailAST findChildWithIdent(DetailAST root) {
+ return TokenUtils.findFirstTokenByPredicate(root,
+ cur -> {
+ return cur.findFirstToken(TokenTypes.IDENT) != null;
+ }).orElse(null);
+ }
+
+ /**
+ * Returns full xpath query for given ast element.
+ * @param ast {@code DetailAST} ast element
+ * @return full xpath query for given ast element
+ */
+ private static String generateXpathQuery(DetailAST ast) {
+ String xpathQuery = getXpathQuery(null, ast);
+ if (!isUniqueAst(ast)) {
+ final DetailAST child = findChildWithIdent(ast);
+ if (child != null) {
+ xpathQuery += "[." + getXpathQuery(ast, child) + ']';
+ }
+ }
+ return xpathQuery;
+ }
+
+ /**
+ * Returns list of nodes matching defined line and column number.
+ * @param root {@code DetailAST} root ast
+ * @param lineNumber line number
+ * @param columnNumber column number
+ * @return list of nodes matching defined line and column number
+ */
+ private static List getMatchingAstElements(DetailAST root, int lineNumber,
+ int columnNumber) {
+ final List result = new ArrayList<>();
+ DetailAST curNode = root;
+ while (curNode != null && curNode.getLineNo() <= lineNumber) {
+ if (curNode.getLineNo() == lineNumber
+ && curNode.getColumnNo() == columnNumber
+ && curNode.getType() != TokenTypes.IDENT) {
+ result.add(curNode);
+ }
+ DetailAST toVisit = curNode.getFirstChild();
+ while (curNode != null && toVisit == null) {
+ toVisit = curNode.getNextSibling();
+ if (toVisit == null) {
+ curNode = curNode.getParent();
+ }
+ }
+
+ curNode = toVisit;
+ }
+ return result;
+ }
+
+ /**
+ * Returns relative xpath query for given ast element from root.
+ * @param root {@code DetailAST} root element
+ * @param ast {@code DetailAST} ast element
+ * @return relative xpath query for given ast element from root
+ */
+ private static String getXpathQuery(DetailAST root, DetailAST ast) {
+ final StringBuilder resultBuilder = new StringBuilder(1024);
+ DetailAST cur = ast;
+ while (cur != root) {
+ final StringBuilder curNodeQueryBuilder = new StringBuilder(256);
+ curNodeQueryBuilder.append('/')
+ .append(TokenUtils.getTokenName(cur.getType()));
+ final DetailAST identAst = cur.findFirstToken(TokenTypes.IDENT);
+ if (identAst != null) {
+ curNodeQueryBuilder.append("[@text='")
+ .append(identAst.getText())
+ .append("']");
+ }
+ resultBuilder.insert(0, curNodeQueryBuilder);
+ cur = cur.getParent();
+ }
+ return resultBuilder.toString();
+ }
+
+ /**
+ * Checks if the given ast element has unique {@code TokenTypes} among siblings.
+ * @param ast {@code DetailAST} ast element
+ * @return if the given ast element has unique {@code TokenTypes} among siblings
+ */
+ private static boolean hasAtLeastOneSiblingWithSameTokenType(DetailAST ast) {
+ boolean result = false;
+ if (ast.getParent() == null) {
+ DetailAST prev = ast.getPreviousSibling();
+ while (prev != null) {
+ if (prev.getType() == ast.getType()) {
+ result = true;
+ break;
+ }
+ prev = prev.getPreviousSibling();
+ }
+ if (!result) {
+ DetailAST next = ast.getNextSibling();
+ while (next != null) {
+ if (next.getType() == ast.getType()) {
+ result = true;
+ break;
+ }
+ next = next.getNextSibling();
+ }
+ }
+ }
+ else {
+ result = ast.getParent().getChildCount(ast.getType()) > 1;
+ }
+ return result;
+ }
+
+ /**
+ * To be sure that generated xpath query will return exactly required ast element, the element
+ * should be checked for uniqueness. If ast element has {@link TokenTypes#IDENT} as the child
+ * or there is no sibling with the same {@code TokenTypes} then element is supposed to be
+ * unique. This method finds if {@code DetailAst} element is unique.
+ * @param ast {@code DetailAST} ast element
+ * @return if {@code DetailAst} element is unique
+ */
+ private static boolean isUniqueAst(DetailAST ast) {
+ return ast.findFirstToken(TokenTypes.IDENT) != null
+ || !hasAtLeastOneSiblingWithSameTokenType(ast);
+ }
+}
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/xpath/package-info.java b/src/main/java/com/puppycrawl/tools/checkstyle/xpath/package-info.java
index 6a7b75863932..e14213951f96 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/xpath/package-info.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/xpath/package-info.java
@@ -18,6 +18,6 @@
////////////////////////////////////////////////////////////////////////////////
/**
- * Contains the nodes implementations for XPATH queries.
+ * Contains the nodes implementations for XPATH queries and query generator.
*/
package com.puppycrawl.tools.checkstyle.xpath;
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/xpath/XpathQueryGeneratorTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/xpath/XpathQueryGeneratorTest.java
new file mode 100644
index 000000000000..548ab5ef04d0
--- /dev/null
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/xpath/XpathQueryGeneratorTest.java
@@ -0,0 +1,306 @@
+////////////////////////////////////////////////////////////////////////////////
+// checkstyle: Checks Java source code for adherence to a set of rules.
+// Copyright (C) 2001-2017 the original author or authors.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+////////////////////////////////////////////////////////////////////////////////
+
+package com.puppycrawl.tools.checkstyle.xpath;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.internal.TestUtils;
+
+public class XpathQueryGeneratorTest {
+
+ private static DetailAST rootAst;
+
+ @Before
+ public void init() throws Exception {
+ final File file = new File("src/test/resources/com/puppycrawl/tools/"
+ + "checkstyle/xpath/InputXpathQueryGenerator.java");
+ rootAst = TestUtils.parseFile(file);
+ }
+
+ @Test
+ public void testClassDef() {
+ final int lineNumber = 11;
+ final int columnNumber = 0;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Arrays.asList(
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']",
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/MODIFIERS",
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/MODIFIERS/LITERAL_PUBLIC");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testMethodDef() {
+ final int lineNumber = 44;
+ final int columnNumber = 4;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Arrays.asList(
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']"
+ + "/OBJBLOCK/METHOD_DEF[@text='callSomeMethod']",
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']"
+ + "/OBJBLOCK/METHOD_DEF[@text='callSomeMethod']/MODIFIERS",
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']"
+ + "/OBJBLOCK/METHOD_DEF[@text='callSomeMethod']/MODIFIERS/LITERAL_PUBLIC");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testVariableDef() {
+ final int lineNumber = 52;
+ final int columnNumber = 12;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Arrays.asList(
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/METHOD_DEF[@text='callSomeMethod']/SLIST/LITERAL_FOR"
+ + "/SLIST/VARIABLE_DEF[@text='d']",
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/METHOD_DEF[@text='callSomeMethod']/SLIST/LITERAL_FOR"
+ + "/SLIST/VARIABLE_DEF[@text='d']/MODIFIERS",
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/METHOD_DEF[@text='callSomeMethod']/SLIST/LITERAL_FOR"
+ + "/SLIST/VARIABLE_DEF[@text='d']/TYPE",
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/METHOD_DEF[@text='callSomeMethod']/SLIST/LITERAL_FOR"
+ + "/SLIST/VARIABLE_DEF[@text='d']/TYPE/LITERAL_SHORT");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testLcurly() {
+ final int lineNumber = 36;
+ final int columnNumber = 19;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Collections.singletonList(
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK/METHOD_DEF[@text='Label']"
+ + "/SLIST/LITERAL_SWITCH/LCURLY");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testRcurly() {
+ final int lineNumber = 24;
+ final int columnNumber = 4;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Collections.singletonList(
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK/INSTANCE_INIT"
+ + "/SLIST/RCURLY");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testExpr() {
+ final int lineNumber = 16;
+ final int columnNumber = 49;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Arrays.asList(
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/VARIABLE_DEF[@text='mUse4']/ASSIGN/EXPR",
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/VARIABLE_DEF[@text='mUse4']/ASSIGN/EXPR/DOT");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testLparen() {
+ final int lineNumber = 44;
+ final int columnNumber = 30;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Collections.singletonList(
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/METHOD_DEF[@text='callSomeMethod']/LPAREN");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testEmpty() {
+ final int lineNumber = 300;
+ final int columnNumber = 300;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ assertTrue("Result should be empty", actual.isEmpty());
+ }
+
+ @Test
+ public void testPackage() {
+ final int lineNumber = 1;
+ final int columnNumber = 0;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Collections.singletonList(
+ "/PACKAGE_DEF");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testImport() {
+ final int lineNumber = 4;
+ final int columnNumber = 0;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Collections.singletonList(
+ "/IMPORT[./DOT[@text='File']]");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testMethodParams() {
+ final int lineNumber = 71;
+ final int columnNumber = 29;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Arrays.asList(
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/METHOD_DEF[@text='saveUser']/PARAMETERS",
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/METHOD_DEF[@text='saveUser']/PARAMETERS/PARAMETER_DEF[@text='name']",
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/METHOD_DEF[@text='saveUser']/PARAMETERS/PARAMETER_DEF[@text='name']"
+ + "/MODIFIERS",
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/METHOD_DEF[@text='saveUser']/PARAMETERS/PARAMETER_DEF[@text='name']"
+ + "/TYPE[@text='String']");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testSwitch() {
+ final int lineNumber = 36;
+ final int columnNumber = 8;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Collections.singletonList(
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/METHOD_DEF[@text='Label']/SLIST/LITERAL_SWITCH");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testSwitchCase() {
+ final int lineNumber = 37;
+ final int columnNumber = 12;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Arrays.asList(
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK/METHOD_DEF[@text='Label']"
+ + "/SLIST/LITERAL_SWITCH/CASE_GROUP",
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK/METHOD_DEF[@text='Label']"
+ + "/SLIST/LITERAL_SWITCH/CASE_GROUP/LITERAL_DEFAULT");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testVariableStringLiteral() {
+ final int lineNumber = 46;
+ final int columnNumber = 25;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Arrays.asList(
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/METHOD_DEF[@text='callSomeMethod']/SLIST/VARIABLE_DEF[@text='another']"
+ + "/ASSIGN/EXPR",
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/METHOD_DEF[@text='callSomeMethod']/SLIST/VARIABLE_DEF[@text='another']"
+ + "/ASSIGN/EXPR/STRING_LITERAL");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testComma() {
+ final int lineNumber = 65;
+ final int columnNumber = 35;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Collections.singletonList(
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK/METHOD_DEF[@text='foo']"
+ + "/SLIST/LITERAL_FOR/FOR_ITERATOR/ELIST/COMMA");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testLiteralVoid() {
+ final int lineNumber = 64;
+ final int columnNumber = 11;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Arrays.asList(
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/METHOD_DEF[@text='foo']/TYPE",
+ "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK"
+ + "/METHOD_DEF[@text='foo']/TYPE/LITERAL_VOID");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testFirstImport() {
+ final int lineNumber = 3;
+ final int columnNumber = 0;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Collections.singletonList(
+ "/IMPORT[./DOT[@text='JToolBar']]");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+
+ @Test
+ public void testLastImport() {
+ final int lineNumber = 7;
+ final int columnNumber = 0;
+ final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber,
+ columnNumber);
+ final List actual = queryGenerator.generate();
+ final List expected = Collections.singletonList(
+ "/IMPORT[./DOT[@text='Iterator']]");
+ assertEquals("Generated queries do not match expected ones", expected, actual);
+ }
+}
diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/xpath/InputXpathQueryGenerator.java b/src/test/resources/com/puppycrawl/tools/checkstyle/xpath/InputXpathQueryGenerator.java
new file mode 100644
index 000000000000..7dbcc8cb3824
--- /dev/null
+++ b/src/test/resources/com/puppycrawl/tools/checkstyle/xpath/InputXpathQueryGenerator.java
@@ -0,0 +1,74 @@
+package com.puppycrawl.tools.checkstyle.xpath;
+
+import javax.swing.JToolBar;
+import java.io.File;
+import java.sql.Connection;
+import java.util.Arrays;
+import java.util.Iterator;
+
+import static java.io.File.listRoots;
+
+public class InputXpathQueryGenerator {
+
+ private Class mUse1 = Connection.class;
+ private Class mUse2 = java.io.File.class;
+ private Class mUse3 = Iterator[].class;
+ private Class mUse4 = java.util.Enumeration[].class;
+ private String ftpClient = null;
+
+ {
+ int[] x = {};
+ Arrays.sort(x);
+ Object obj = javax.swing.BorderFactory.createEmptyBorder();
+ File[] files = listRoots();
+ }
+
+ private JToolBar.Separator mSep = null;
+
+ private Object mUse5 = new Object();
+
+ private Object mUse6 = new javax.swing.JToggleButton.ToggleButtonModel();
+
+ private int Component;
+
+ public void Label() {
+ int i = 23;
+ switch (i) {
+ default:
+ break;
+ case 1:
+ break;
+ }
+ }
+
+ public void callSomeMethod() {
+ int variable = 123;
+ String another = "HelloWorld";
+ String[] array = new String[3];
+ for (String cycle : array) {
+ char a = 'b';
+ char b = a;
+ byte c = 1;
+ short d = 1;
+ }
+ }
+
+ /**
+ * Returns if current node has children.
+ * @return if current node has children
+ */
+ public String getSomeMethod() {
+ return "HelloWorld";
+ }
+
+ static void foo() {
+ for (int i = 0; i < 10; i++, i+=2) {
+
+ }
+ return;
+ }
+
+ private boolean saveUser(String name, String surname, int age) {
+ return true;
+ }
+}