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