Source code: com/puppycrawl/tools/checkstyle/checks/imports/RedundantImportCheck.java
1 ////////////////////////////////////////////////////////////////////////////////
2 // checkstyle: Checks Java source code for adherence to a set of rules.
3 // Copyright (C) 2001-2003 Oliver Burn
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.checks.imports;
21
22 import com.puppycrawl.tools.checkstyle.api.Check;
23 import com.puppycrawl.tools.checkstyle.api.DetailAST;
24 import com.puppycrawl.tools.checkstyle.api.FullIdent;
25 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
26 import java.util.HashSet;
27 import java.util.Iterator;
28 import java.util.Set;
29
30 /**
31 * <p>
32 * Checks for imports that are redundant. An import statement is
33 * considered redundant if:
34 * </p>
35 *<ul>
36 * <li>It is a duplicate of another import. This is, when a class is imported
37 * more than once.</li>
38 * <li>The class imported is from the <code>java.lang</code> package.
39 * For example importing <code>java.lang.String</code>.</li>
40 * <li>The class imported is from the same package.</li>
41 *</ul>
42 * <p>
43 * An example of how to configure the check is:
44 * </p>
45 * <pre>
46 * <module name="RedundantImport"/>
47 * </pre>
48 * @author Oliver Burn
49 * @version 1.0
50 */
51 public class RedundantImportCheck
52 extends Check
53 {
54 /** name of package in file */
55 private String mPkgName;
56 /** set of the imports */
57 private final Set mImports = new HashSet();
58
59 /** @see com.puppycrawl.tools.checkstyle.api.Check */
60 public void beginTree(DetailAST aRootAST)
61 {
62 mPkgName = null;
63 mImports.clear();
64 }
65
66 /** @see com.puppycrawl.tools.checkstyle.api.Check */
67 public int[] getDefaultTokens()
68 {
69 return new int[] {TokenTypes.IMPORT, TokenTypes.PACKAGE_DEF};
70 }
71
72 /** @see com.puppycrawl.tools.checkstyle.api.Check */
73 public void visitToken(DetailAST aAST)
74 {
75 if (aAST.getType() == TokenTypes.PACKAGE_DEF) {
76 final DetailAST nameAST = (DetailAST) aAST.getFirstChild();
77 mPkgName = FullIdent.createFullIdent(nameAST).getText();
78 }
79 else {
80 final FullIdent imp = FullIdent.createFullIdentBelow(aAST);
81 if (fromPackage(imp.getText(), "java.lang")) {
82 log(aAST.getLineNo(), aAST.getColumnNo(), "import.lang",
83 imp.getText());
84 }
85 else if (fromPackage(imp.getText(), mPkgName)) {
86 log(aAST.getLineNo(), aAST.getColumnNo(), "import.same",
87 imp.getText());
88 }
89 // Check for a duplicate import
90 final Iterator it = mImports.iterator();
91 while (it.hasNext()) {
92 final FullIdent full = (FullIdent) it.next();
93 if (imp.getText().equals(full.getText())) {
94 log(aAST.getLineNo(),
95 aAST.getColumnNo(),
96 "import.duplicate",
97 new Integer(full.getLineNo()),
98 imp.getText());
99 }
100 }
101
102 mImports.add(imp);
103 }
104 }
105
106 /**
107 * Determines if an import statement is for types from a specified package.
108 * @param aImport the import name
109 * @param aPkg the package name
110 * @return whether from the package
111 */
112 private static boolean fromPackage(String aImport, String aPkg)
113 {
114 boolean retVal = false;
115 if (aPkg == null) {
116 // If not package, then check for no package in the import.
117 retVal = (aImport.indexOf('.') == -1);
118 }
119 else {
120 final int index = aImport.lastIndexOf('.');
121 if (index != -1) {
122 final String front = aImport.substring(0, index);
123 retVal = front.equals(aPkg);
124 }
125 }
126 return retVal;
127 }
128 }