KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > pmd > typeresolution > rules > CloneMethodMustImplementCloneable


1 /**
2  * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3  */

4 package net.sourceforge.pmd.typeresolution.rules;
5
6 import net.sourceforge.pmd.AbstractRule;
7 import net.sourceforge.pmd.ast.ASTBlock;
8 import net.sourceforge.pmd.ast.ASTBlockStatement;
9 import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
10 import net.sourceforge.pmd.ast.ASTClassOrInterfaceType;
11 import net.sourceforge.pmd.ast.ASTExtendsList;
12 import net.sourceforge.pmd.ast.ASTFormalParameters;
13 import net.sourceforge.pmd.ast.ASTImplementsList;
14 import net.sourceforge.pmd.ast.ASTMethodDeclaration;
15 import net.sourceforge.pmd.ast.ASTMethodDeclarator;
16 import net.sourceforge.pmd.ast.SimpleNode;
17
18 import java.util.Arrays JavaDoc;
19 import java.util.List JavaDoc;
20
21 /**
22  * The method clone() should only be implemented if the class implements the
23  * Cloneable interface with the exception of a final method that only throws
24  * CloneNotSupportedException. This version uses PMD's type resolution
25  * facilities, and can detect if the class implements or extends a Cloneable
26  * class
27  *
28  * @author acaplan
29  *
30  */

31 public class CloneMethodMustImplementCloneable extends AbstractRule {
32
33     public Object JavaDoc visit(ASTClassOrInterfaceDeclaration node, Object JavaDoc data) {
34         ASTImplementsList impl = (ASTImplementsList) node.getFirstChildOfType(ASTImplementsList.class);
35         if (impl != null && impl.jjtGetParent().equals(node)) {
36             for (int ix = 0; ix < impl.jjtGetNumChildren(); ix++) {
37                 ASTClassOrInterfaceType type = (ASTClassOrInterfaceType) impl.jjtGetChild(ix);
38                 if (type.getType() == null) {
39                     if ("Cloneable".equals(type.getImage())) {
40                         return data;
41                     }
42                 } else if (type.getType().equals(Cloneable JavaDoc.class)) {
43                     return data;
44                 } else {
45                     List implementors = Arrays.asList(type.getType().getInterfaces());
46                     if (implementors.contains(Cloneable JavaDoc.class)) {
47                         return data;
48                     }
49                 }
50             }
51         }
52         if (node.jjtGetNumChildren() != 0 && node.jjtGetChild(0).getClass().equals(ASTExtendsList.class)) {
53             ASTClassOrInterfaceType type = (ASTClassOrInterfaceType) ((SimpleNode) node.jjtGetChild(0)).jjtGetChild(0);
54             Class JavaDoc clazz = type.getType();
55             if (clazz != null && clazz.equals(Cloneable JavaDoc.class)) {
56                 return data;
57             }
58             while (clazz != null && !Object JavaDoc.class.equals(clazz)) {
59                 if (Arrays.asList(clazz.getInterfaces()).contains(Cloneable JavaDoc.class)) {
60                     return data;
61                 }
62                 clazz = clazz.getSuperclass();
63             }
64         }
65
66         return super.visit(node, data);
67     }
68
69     public Object JavaDoc visit(ASTMethodDeclaration node, Object JavaDoc data) {
70
71         if (node.isFinal()) {
72             List blocks = node.findChildrenOfType(ASTBlock.class);
73             if (blocks.size() == 1) {
74                 blocks = node.findChildrenOfType(ASTBlockStatement.class);
75                 if (blocks.size() == 1) {
76                     ASTBlockStatement block = (ASTBlockStatement) blocks.get(0);
77                     ASTClassOrInterfaceType type = (ASTClassOrInterfaceType) block.getFirstChildOfType(ASTClassOrInterfaceType.class);
78                     if (type != null && type.getType() != null && type.getNthParent(9).equals(node) && type.getType().equals(CloneNotSupportedException JavaDoc.class)) {
79                         return data;
80                     } else if (type != null && type.getType() == null && "CloneNotSupportedException".equals(type.getImage())) {
81                         return data;
82                     }
83                 }
84             }
85         }
86         return super.visit(node, data);
87     }
88
89     public Object JavaDoc visit(ASTMethodDeclarator node, Object JavaDoc data) {
90         if (!"clone".equals(node.getImage())) {
91             return data;
92         }
93         int countParams = ((ASTFormalParameters) node.jjtGetChild(0)).jjtGetNumChildren();
94         if (countParams != 0) {
95             return data;
96         }
97         addViolation(data, node);
98         return data;
99     }
100 }
Popular Tags