JavaRuleViolation.java
01 /**
02  * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
03  */
04 package net.sourceforge.pmd.lang.java.rule;
05 
06 import net.sourceforge.pmd.Rule;
07 import net.sourceforge.pmd.RuleContext;
08 import net.sourceforge.pmd.lang.ast.Node;
09 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
10 import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
11 import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
12 import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration;
13 import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
14 import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator;
15 import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
16 import net.sourceforge.pmd.lang.java.ast.CanSuppressWarnings;
17 import net.sourceforge.pmd.lang.java.ast.JavaNode;
18 import net.sourceforge.pmd.lang.java.symboltable.Scope;
19 import net.sourceforge.pmd.lang.java.symboltable.SourceFileScope;
20 import net.sourceforge.pmd.lang.rule.AbstractRuleViolation;
21 
22 /**
23  * This is a Java RuleViolation.  It knows how to try to extract the following
24  * extra information from the violation node:
25  <ul>
26  *    <li>Package name</li>
27  *    <li>Class name</li>
28  *    <li>Method name</li>
29  *    <li>Variable name</li>
30  *    <li>Suppression indicator</li>
31  </ul>
32  */
33 public class JavaRuleViolation extends AbstractRuleViolation {
34     public JavaRuleViolation(Rule rule, RuleContext ctx, JavaNode node, String message) {
35   super(rule, ctx, node, message);
36 
37   if (node != null) {
38       final Scope scope = node.getScope();
39       final SourceFileScope sourceFileScope = scope.getEnclosingSourceFileScope();
40 
41       // Package name is on SourceFileScope
42       packageName = sourceFileScope.getPackageName() == null "" : sourceFileScope.getPackageName();
43 
44       // Class name is built from enclosing ClassScopes
45       String qualifiedName = null;
46       for (ASTClassOrInterfaceDeclaration parent : node.getParentsOfType(ASTClassOrInterfaceDeclaration.class)) {
47     if (qualifiedName == null) {
48         qualifiedName = parent.getScope().getEnclosingClassScope().getClassName();
49     else {
50         qualifiedName = parent.getScope().getEnclosingClassScope().getClassName() "$" + qualifiedName;
51     }
52       }
53       if (qualifiedName != null) {
54     className = qualifiedName;
55       }
56       // Method name comes from 1st enclosing MethodScope
57       if (node.getFirstParentOfType(ASTMethodDeclaration.class!= null) {
58     methodName = scope.getEnclosingMethodScope().getName();
59       }
60       // Variable name node specific
61       setVariableNameIfExists(node);
62 
63       // Check for suppression on this node, on parents, and on contained types for ASTCompilationUnit
64       if (!suppressed) {
65     suppressed = suppresses(node);
66       }
67       if (!suppressed && node instanceof ASTCompilationUnit) {
68     for (int i = 0; !suppressed && i < node.jjtGetNumChildren(); i++) {
69         suppressed = suppresses(node.jjtGetChild(i));
70     }
71       }
72       if (!suppressed) {
73     Node parent = node.jjtGetParent();
74     while (!suppressed && parent != null) {
75         suppressed = suppresses(parent);
76         parent = parent.jjtGetParent();
77     }
78       }
79   }
80     }
81 
82     private boolean suppresses(final Node node) {
83   return node instanceof CanSuppressWarnings
84     && ((CanSuppressWarningsnode).hasSuppressWarningsAnnotationFor(getRule());
85     }
86 
87     private void setVariableNameIfExists(Node node) {
88   variableName = "";
89   if (node instanceof ASTFieldDeclaration) {
90       variableName = ((ASTFieldDeclarationnode).getVariableName();
91   else if (node instanceof ASTLocalVariableDeclaration) {
92       variableName = ((ASTLocalVariableDeclarationnode).getVariableName();
93   else if (node instanceof ASTVariableDeclarator) {
94       variableName = node.jjtGetChild(0).getImage();
95   else if (node instanceof ASTVariableDeclaratorId) {
96       variableName = node.getImage();
97   }
98     }
99 }