Clover coverage report - PMD - 3.9 Coverage timestamp: Tue Dec 19 2006 09:38:44 EST FRAMES NO FRAMES |
file stats: | LOC: | 116 |  | Methods: | 6
| NCLOC: | 89 |  | Classes: | 1
Source file | Conditionals | Statements | Methods | TOTAL
BeanMembersShouldSerializeRule.java | 95.5% | 97.6% | 83.3% | 95.7% |

1 |  | /**
2 |  | * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 |  | */
4 |  | package net.sourceforge.pmd.rules;
5 |  |
6 |  | import java.util.ArrayList;
7 |  | import java.util.Arrays;
8 |  | import java.util.Iterator;
9 |  | import java.util.List;
10 |  | import java.util.Map;
11 |  |
12 |  | import net.sourceforge.pmd.AbstractRule;
13 |  | import net.sourceforge.pmd.PropertyDescriptor;
14 |  | import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
15 |  | import net.sourceforge.pmd.ast.ASTCompilationUnit;
16 |  | import net.sourceforge.pmd.ast.ASTMethodDeclarator;
17 |  | import net.sourceforge.pmd.ast.ASTPrimitiveType;
18 |  | import net.sourceforge.pmd.ast.ASTResultType;
19 |  | import net.sourceforge.pmd.ast.SimpleNode;
20 |  | import net.sourceforge.pmd.properties.StringProperty;
21 |  | import net.sourceforge.pmd.symboltable.MethodNameDeclaration;
22 |  | import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
23 |  |
24 |  | public class BeanMembersShouldSerializeRule extends AbstractRule {
25 |  |
26 |  | private String prefixProperty;
27 |  |
28 |  | private static final PropertyDescriptor prefixDescriptor = new StringProperty(
29 |  | "prefix", "Prefix somethingorother?", "", 1.0f
30 |  | );
31 |  |
32 |  | private static final Map propertyDescriptorsByName = asFixedMap(prefixDescriptor);
33 |  |
34 |  |
35 | 12 | public Object visit(ASTCompilationUnit node, Object data) {
36 | 12 | prefixProperty = getStringProperty(prefixDescriptor);
37 | 12 | super.visit(node, data);
38 | 12 | return data;
39 |  | }
40 |  |
41 | 11 | private static String[] imagesOf(List simpleNodes) {
42 |  |
43 | 11 | String[] imageArray = new String[simpleNodes.size()];
44 |  |
45 | 11 | for (int i = 0; i < simpleNodes.size(); i++) {
46 | 13 | imageArray[i] = ((SimpleNode) simpleNodes.get(i)).getImage();
47 |  | }
48 | 11 | return imageArray;
49 |  | }
50 |  |
51 | 12 | public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
52 | 12 | if (node.isInterface()) {
53 | 1 | return data;
54 |  | }
55 |  |
56 | 11 | Map methods = node.getScope().getEnclosingClassScope().getMethodDeclarations();
57 | 11 | List getSetMethList = new ArrayList(methods.size());
58 | 11 | for (Iterator i = methods.keySet().iterator(); i.hasNext();) {
59 | 14 | ASTMethodDeclarator mnd = ((MethodNameDeclaration) i.next()).getMethodNameDeclaratorNode();
60 | 14 | if (isBeanAccessor(mnd)) {
61 | 13 | getSetMethList.add(mnd);
62 |  | }
63 |  | }
64 |  |
65 | 11 | String[] methNameArray = imagesOf(getSetMethList);
66 |  |
67 | 11 | Arrays.sort(methNameArray);
68 |  |
69 | 11 | Map vars = node.getScope().getVariableDeclarations();
70 | 11 | for (Iterator i = vars.keySet().iterator(); i.hasNext();) {
71 | 17 | VariableNameDeclaration decl = (VariableNameDeclaration) i.next();
72 | 17 | if (((List) vars.get(decl)).isEmpty() || decl.getAccessNodeParent().isTransient() || decl.getAccessNodeParent().isStatic()) {
73 | 8 | continue;
74 |  | }
75 | 9 | String varName = trimIfPrefix(decl.getImage());
76 | 9 | varName = varName.substring(0, 1).toUpperCase() + varName.substring(1, varName.length());
77 | 9 | boolean hasGetMethod = Arrays.binarySearch(methNameArray, "get" + varName) >= 0 || Arrays.binarySearch(methNameArray, "is" + varName) >= 0;
78 | 9 | boolean hasSetMethod = Arrays.binarySearch(methNameArray, "set" + varName) >= 0;
79 | 9 | if (!hasGetMethod || !hasSetMethod) {
80 | 6 | addViolation(data, decl.getNode(), decl.getImage());
81 |  | }
82 |  | }
83 | 11 | return super.visit(node, data);
84 |  | }
85 |  |
86 | 9 | private String trimIfPrefix(String img) {
87 | 9 | if (prefixProperty != null && img.startsWith(prefixProperty)) {
88 | 8 | return img.substring(prefixProperty.length());
89 |  | }
90 | 1 | return img;
91 |  | }
92 |  |
93 | 14 | private boolean isBeanAccessor(ASTMethodDeclarator meth) {
94 |  |
95 | 14 | String methodName = meth.getImage();
96 |  |
97 | 14 | if (methodName.startsWith("get") || methodName.startsWith("set")) {
98 | 12 | return true;
99 |  | }
100 | 2 | if (methodName.startsWith("is")) {
101 | 2 | ASTResultType ret = (ASTResultType) meth.jjtGetParent().jjtGetChild(0);
102 | 2 | List primitives = ret.findChildrenOfType(ASTPrimitiveType.class);
103 | 2 | if (!primitives.isEmpty() && ((ASTPrimitiveType) primitives.get(0)).isBoolean()) {
104 | 1 | return true;
105 |  | }
106 |  | }
107 | 1 | return false;
108 |  | }
109 |  |
110 |  | /**
111 |  | * @return Map
112 |  | */
113 | 0 | protected Map propertiesByName() {
114 | 0 | return propertyDescriptorsByName;
115 |  | }
116 |  | }