1
2
3
4 package net.sourceforge.pmd.lang.java.rule.imports;
5
6 import java.util.HashSet;
7 import java.util.Set;
8
9 import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
10 import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
11 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
12 import net.sourceforge.pmd.lang.java.rule.ImportWrapper;
13
14 public class DuplicateImportsRule extends AbstractJavaRule {
15
16 private Set<ImportWrapper> singleTypeImports;
17 private Set<ImportWrapper> importOnDemandImports;
18
19 public Object visit(ASTCompilationUnit node, Object data) {
20 singleTypeImports = new HashSet<ImportWrapper>();
21 importOnDemandImports = new HashSet<ImportWrapper>();
22 super.visit(node, data);
23
24
25
26
27 for (ImportWrapper thisImportOnDemand : importOnDemandImports) {
28 for (ImportWrapper thisSingleTypeImport : singleTypeImports) {
29 String singleTypeFullName = thisSingleTypeImport.getName();
30
31 int lastDot = singleTypeFullName.lastIndexOf('.');
32 String singleTypePkg = singleTypeFullName.substring(0, lastDot);
33 String singleTypeName = singleTypeFullName.substring(lastDot + 1);
34
35 if (thisImportOnDemand.getName().equals(singleTypePkg) &&
36 !isDisambiguationImport(node, singleTypePkg, singleTypeName)) {
37 addViolation(data, thisSingleTypeImport.getNode(), singleTypeFullName);
38 }
39 }
40 }
41 singleTypeImports.clear();
42 importOnDemandImports.clear();
43 return data;
44 }
45
46
47
48
49
50
51
52
53
54 private boolean isDisambiguationImport(ASTCompilationUnit node, String singleTypePkg, String singleTypeName) {
55 for (ImportWrapper thisImportOnDemand : importOnDemandImports) {
56 if (!thisImportOnDemand.getName().equals(singleTypePkg)) {
57 String fullyQualifiedClassName = thisImportOnDemand.getName() + "." + singleTypeName;
58 if (node.getClassTypeResolver().classNameExists(fullyQualifiedClassName)) {
59 return true;
60 }
61 }
62 }
63
64 String fullyQualifiedClassName = "java.lang." + singleTypeName;
65 if (node.getClassTypeResolver().classNameExists(fullyQualifiedClassName)) {
66 return true;
67 }
68
69 return false;
70 }
71
72 public Object visit(ASTImportDeclaration node, Object data) {
73 ImportWrapper wrapper = new ImportWrapper(node.getImportedName(), node.getImportedName(), node.getImportedNameNode());
74
75
76 if (node.isImportOnDemand()) {
77 if (importOnDemandImports.contains(wrapper)) {
78 addViolation(data, node.getImportedNameNode(), node.getImportedNameNode().getImage());
79 } else {
80 importOnDemandImports.add(wrapper);
81 }
82 } else {
83 if (singleTypeImports.contains(wrapper)) {
84 addViolation(data, node.getImportedNameNode(), node.getImportedNameNode().getImage());
85 } else {
86 singleTypeImports.add(wrapper);
87 }
88 }
89 return data;
90 }
91
92 }