1
2
3
4 package net.sourceforge.pmd.lang.java.rule.design;
5
6 import java.util.Set;
7
8 import net.sourceforge.pmd.lang.ast.Node;
9 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
10 import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
11 import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
12 import net.sourceforge.pmd.lang.java.ast.ASTSynchronizedStatement;
13 import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
14 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
15 import net.sourceforge.pmd.lang.java.symboltable.NameOccurrence;
16 import net.sourceforge.pmd.util.CollectionUtil;
17
18
19
20
21
22
23
24
25
26
27
28
29
30 public class UnsynchronizedStaticDateFormatterRule extends AbstractJavaRule {
31
32 private static Set<String> targets = CollectionUtil.asSet(new String[] {
33 "DateFormat", "SimpleDateFormat", "java.text.DateFormat","java.text.SimpleDateFormat"
34 });
35
36 @Override
37 public Object visit(ASTFieldDeclaration node, Object data) {
38 if (!node.isStatic()) {
39 return data;
40 }
41 ASTClassOrInterfaceType cit = node.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
42 if (cit == null || !targets.contains(cit.getImage())) {
43 return data;
44 }
45 ASTVariableDeclaratorId var = node.getFirstDescendantOfType(ASTVariableDeclaratorId.class);
46 for (NameOccurrence occ: var.getUsages()) {
47 Node n = occ.getLocation();
48 if (n.getFirstParentOfType(ASTSynchronizedStatement.class) != null) {
49 continue;
50 }
51
52 if (!n.getImage().contains(".")) {
53 continue;
54 }
55
56 ASTMethodDeclaration method = n.getFirstParentOfType(ASTMethodDeclaration.class);
57 if (method != null && !method.isSynchronized()) {
58 addViolation(data, n);
59 }
60 }
61 return data;
62 }
63 }