1 package net.sourceforge.pmd.lang.java.rule.imports;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
7 import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
8 import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
9 import net.sourceforge.pmd.lang.java.ast.ASTName;
10 import net.sourceforge.pmd.lang.java.ast.JavaNode;
11 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
12
13 public class UnnecessaryFullyQualifiedNameRule extends AbstractJavaRule {
14
15 private List<ASTImportDeclaration> imports = new ArrayList<ASTImportDeclaration>();
16 private List<ASTImportDeclaration> matches = new ArrayList<ASTImportDeclaration>();
17
18 public UnnecessaryFullyQualifiedNameRule() {
19 super.addRuleChainVisit(ASTCompilationUnit.class);
20 super.addRuleChainVisit(ASTImportDeclaration.class);
21 super.addRuleChainVisit(ASTClassOrInterfaceType.class);
22 super.addRuleChainVisit(ASTName.class);
23 }
24
25 @Override
26 public Object visit(ASTCompilationUnit node, Object data) {
27 imports.clear();
28 return data;
29 }
30
31 @Override
32 public Object visit(ASTImportDeclaration node, Object data) {
33 imports.add(node);
34 return data;
35 }
36
37 @Override
38 public Object visit(ASTClassOrInterfaceType node, Object data) {
39 checkImports(node, data, false);
40 return data;
41 }
42
43 @Override
44 public Object visit(ASTName node, Object data) {
45 if (!(node.jjtGetParent() instanceof ASTImportDeclaration)) {
46 checkImports(node, data, true);
47 }
48 return data;
49 }
50
51 private void checkImports(JavaNode node, Object data, boolean checkStatic) {
52 String name = node.getImage();
53 matches.clear();
54
55
56 for (ASTImportDeclaration importDeclaration : imports) {
57 if (importDeclaration.isImportOnDemand()) {
58
59 if (name.startsWith(importDeclaration.getImportedName())) {
60 if (name.lastIndexOf('.') == importDeclaration.getImportedName().length()) {
61 matches.add(importDeclaration);
62 continue;
63 }
64 }
65 } else {
66
67 if (name.equals(importDeclaration.getImportedName())) {
68 matches.add(importDeclaration);
69 continue;
70 }
71
72 if (name.startsWith(importDeclaration.getImportedName())) {
73 if (name.lastIndexOf('.') == importDeclaration.getImportedName().length()) {
74 matches.add(importDeclaration);
75 continue;
76 }
77 }
78 }
79 }
80
81
82
83
84
85
86
87
88
89
90
91 if (matches.isEmpty() && name.indexOf('.') >= 0) {
92 for (ASTImportDeclaration importDeclaration : imports) {
93 if (importDeclaration.isStatic()) {
94 String[] importParts = importDeclaration.getImportedName().split("\\.");
95 String[] nameParts = name.split("\\.");
96 boolean checkClassImport = false;
97 if (importDeclaration.isImportOnDemand()) {
98
99 if (nameParts[nameParts.length - 2].equals(importParts[importParts.length - 1])) {
100 checkClassImport = true;
101 }
102 } else {
103
104 if (nameParts[nameParts.length - 1].equals(importParts[importParts.length - 1])
105 && nameParts[nameParts.length - 2].equals(importParts[importParts.length - 2])) {
106 checkClassImport = true;
107 }
108 }
109 if (checkClassImport) {
110
111 String nameEnd = "." + nameParts[nameParts.length - 2];
112 for (ASTImportDeclaration importDeclaration2 : imports) {
113 if (!importDeclaration2.isStatic() && !importDeclaration2.isImportOnDemand()
114 && importDeclaration2.getImportedName().endsWith(nameEnd)) {
115 matches.add(importDeclaration2);
116 }
117 }
118 }
119 }
120 }
121 }
122
123 if (!matches.isEmpty()) {
124 String importStr = matches.get(0).getImportedName() + (matches.get(0).isImportOnDemand() ? ".*" : "");
125 addViolation(data, node, new Object[] { node.getImage(), importStr });
126 }
127
128 matches.clear();
129 }
130 }