Clover coverage report - PMD - 3.9 Coverage timestamp: Tue Dec 19 2006 09:38:44 EST FRAMES NO FRAMES |
file stats: | LOC: | 63 |  | Methods: | 1
| NCLOC: | 42 |  | Classes: | 1
Source file | Conditionals | Statements | Methods | TOTAL
UnsynchronizedStaticDateFormatter.java | 90% | 94.7% | 100% | 93.3% |

1 |  | /**
2 |  | * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 |  | */
4 |  | package net.sourceforge.pmd.rules.design;
5 |  |
6 |  | import net.sourceforge.pmd.AbstractRule;
7 |  | import net.sourceforge.pmd.ast.ASTClassOrInterfaceType;
8 |  | import net.sourceforge.pmd.ast.ASTFieldDeclaration;
9 |  | import net.sourceforge.pmd.ast.ASTMethodDeclaration;
10 |  | import net.sourceforge.pmd.ast.ASTSynchronizedStatement;
11 |  | import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
12 |  | import net.sourceforge.pmd.ast.SimpleNode;
13 |  | import net.sourceforge.pmd.symboltable.NameOccurrence;
14 |  |
15 |  | import java.util.HashSet;
16 |  | import java.util.Iterator;
17 |  | import java.util.Set;
18 |  |
19 |  | /**
20 |  | * Using a DateFormatter (SimpleDateFormatter) which is static can cause
21 |  | * unexpected results when used in a multi threaded environment. This rule will
22 |  | * find static (Simple)DateFormatters which are used in an unsynchronized
23 |  | * manner.
24 |  | * Refer to these Bug Parade issues:
25 |  | * <a href="http://developer.java.sun.com/developer/bugParade/bugs/4093418.html">4093418</a>
26 |  | * <a href="http://developer.java.sun.com/developer/bugParade/bugs/4228335.html">4228335</a>
27 |  | * <a href="http://developer.java.sun.com/developer/bugParade/bugs/4261469.html">4261469</a>
28 |  | * see RFE1020790 - Check for SimpleDateFormat as singleton http://sourceforge.net/tracker/index.php?func=detail&aid=1020790&group_id=56262&atid=479924
29 |  | * @author Allan Caplan
30 |  | */
31 |  | public class UnsynchronizedStaticDateFormatter extends AbstractRule {
32 |  |
33 |  | private static Set targets = new HashSet();
34 |  | static {
35 | 43 | targets.add("DateFormat");
36 | 43 | targets.add("SimpleDateFormat");
37 | 43 | targets.add("java.text.DateFormat");
38 | 43 | targets.add("java.text.SimpleDateFormat");
39 |  | }
40 |  |
41 | 6 | public Object visit(ASTFieldDeclaration node, Object data) {
42 | 6 | if (!node.isStatic()) {
43 | 1 | return data;
44 |  | }
45 | 5 | ASTClassOrInterfaceType cit = (ASTClassOrInterfaceType) node.getFirstChildOfType(ASTClassOrInterfaceType.class);
46 | 5 | if (cit == null || !targets.contains(cit.getImage())) {
47 | 0 | return data;
48 |  | }
49 | 5 | ASTVariableDeclaratorId var = (ASTVariableDeclaratorId) node.getFirstChildOfType(ASTVariableDeclaratorId.class);
50 | 5 | for (Iterator i = var.getUsages().iterator(); i.hasNext();) {
51 | 6 | NameOccurrence occ = (NameOccurrence) i.next();
52 | 6 | SimpleNode n = occ.getLocation();
53 | 6 | if ((ASTSynchronizedStatement) n.getFirstParentOfType(ASTSynchronizedStatement.class) != null) {
54 | 2 | continue;
55 |  | }
56 | 4 | ASTMethodDeclaration method = (ASTMethodDeclaration) n.getFirstParentOfType(ASTMethodDeclaration.class);
57 | 4 | if (method != null && !method.isSynchronized()) {
58 | 2 | addViolation(data, n);
59 |  | }
60 |  | }
61 | 5 | return data;
62 |  | }
63 |  | }