1 /*** 2 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html 3 */ 4 package net.sourceforge.pmd; 5 6 import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration; 7 import net.sourceforge.pmd.ast.ASTCompilationUnit; 8 import net.sourceforge.pmd.ast.ASTMethodDeclarator; 9 import net.sourceforge.pmd.ast.ASTName; 10 import net.sourceforge.pmd.ast.ASTPackageDeclaration; 11 import net.sourceforge.pmd.ast.JavaParserVisitorAdapter; 12 import net.sourceforge.pmd.ast.SimpleNode; 13 14 import java.util.Iterator; 15 import java.util.List; 16 import java.util.Properties; 17 18 public abstract class AbstractRule extends JavaParserVisitorAdapter implements Rule { 19 20 protected String name = getClass().getName(); 21 protected Properties properties = new Properties(); 22 protected String message; 23 protected String description; 24 protected String example; 25 protected String ruleSetName; 26 protected boolean include; 27 protected boolean usesDFA; 28 protected boolean usesSymbolTable; 29 protected int priority = LOWEST_PRIORITY; 30 private String packageName/package-summary.html">ong> String packageName; 31 private String className; 32 private String methodName; 33 34 public String getRuleSetName() { 35 return ruleSetName; 36 } 37 38 public void setRuleSetName(String ruleSetName) { 39 this.ruleSetName = ruleSetName; 40 } 41 42 public String getDescription() { 43 return description; 44 } 45 46 public void setDescription(String description) { 47 this.description = description; 48 } 49 50 public String getExample() { 51 return example; 52 } 53 54 public void setExample(String example) { 55 this.example = example; 56 } 57 58 public boolean hasProperty(String name) { 59 return properties.containsKey(name); 60 } 61 62 public void addProperty(String name, String value) { 63 properties.setProperty(name, value); 64 } 65 66 public void addProperties(Properties properties) { 67 this.properties.putAll(properties); 68 } 69 70 public double getDoubleProperty(String name) { 71 return Double.parseDouble(properties.getProperty(name)); 72 } 73 74 public int getIntProperty(String name) { 75 return Integer.parseInt(properties.getProperty(name)); 76 } 77 78 public boolean getBooleanProperty(String name) { 79 return Boolean.valueOf(properties.getProperty(name)).booleanValue(); 80 } 81 82 public String getStringProperty(String name) { 83 return properties.getProperty(name); 84 } 85 86 public String getName() { 87 return name; 88 } 89 90 public void setName(String name) { 91 this.name = name; 92 } 93 94 public String getMessage() { 95 return message; 96 } 97 98 public void setMessage(String message) { 99 this.message = message; 100 } 101 102 public void setPackageName(String name) { 103 this.packageName = name; 104 } 105 106 public boolean equals(Object o) { 107 if (!(o instanceof Rule)) { 108 return false; 109 } 110 return ((Rule) o).getName().equals(getName()); 111 } 112 113 public int hashCode() { 114 return getName().hashCode(); 115 } 116 117 protected void visitAll(List acus, RuleContext ctx) { 118 for (Iterator i = acus.iterator(); i.hasNext();) { 119 ASTCompilationUnit node = (ASTCompilationUnit) i.next(); 120 visit(node, ctx); 121 } 122 } 123 124 public void apply(List acus, RuleContext ctx) { 125 visitAll(acus, ctx); 126 } 127 128 /*** 129 * @deprecated use @link #createRuleViolation(RuleContext, IPositionProvider) instead 130 */ 131 public RuleViolation createRuleViolation(RuleContext ctx, int lineNumber) { 132 return<RuleViolation(this, lineNumber, ctx, packageName, className, methodName)/package-summary.html">/strong> new RuleViolation(this, lineNumber, ctx, packageName, className, methodName); 133 } 134 135 public RuleViolation createRuleViolation(RuleContext ctx, IPositionProvider pp) { 136 RuleViolation v = new RuleViolation(this, ctx, packageName, className, methodName)/package-summary.html">RuleViolation v = new RuleViolation(this, ctx, packageName, className, methodName); 137 extractNodeInfo(v, pp); 138 return v; 139 } 140 141 /*** 142 * @deprecated use @link #createRuleViolation(RuleContext, IPositionProvider, String) instead 143 */ 144 public RuleViolation createRuleViolation(RuleContext ctx, int lineNumber, String specificDescription) { 145 return<RuleViolation(this, lineNumber, specificDescription, ctx, packageName, className, methodName)/package-summary.html">/strong> new RuleViolation(this, lineNumber, specificDescription, ctx, packageName, className, methodName); 146 } 147 148 public RuleViolation createRuleViolation(RuleContext ctx, IPositionProvider pp, String specificDescription) { 149 RuleViolation rv = new RuleViolation(this, 0, specificDescription, ctx, packageName, className, methodName)/package-summary.html">RuleViolation rv = new RuleViolation(this, 0, specificDescription, ctx, packageName, className, methodName); 150 extractNodeInfo(rv, pp); 151 return rv; 152 } 153 154 public RuleViolation createRuleViolation(RuleContext ctx, int lineNumber, int lineNumber2, String variableName, String specificDescription) { 155 return<RuleViolation(this, lineNumber, lineNumber2, variableName, specificDescription, ctx, packageName, className, methodName)/package-summary.html">/strong> new RuleViolation(this, lineNumber, lineNumber2, variableName, specificDescription, ctx, packageName, className, methodName); 156 } 157 158 public Properties getProperties() { 159 return properties; 160 } 161 162 public boolean include() { 163 return include; 164 } 165 166 public void setInclude(boolean include) { 167 this.include = include; 168 } 169 170 public int getPriority() { 171 return priority; 172 } 173 174 public String getPriorityName() { 175 return PRIORITIES[getPriority() - 1]; 176 } 177 178 public void setPriority(int priority) { 179 this.priority = priority; 180 } 181 182 public Object visit(ASTPackageDeclaration node, Object data) { 183 packageName = ((ASTName) node.jjtGetChild(0)).getImage(); 184 return super.visit(node, data); 185 } 186 187 public Object visit(ASTClassOrInterfaceDeclaration node, Object data) { 188 className = node.getImage(); 189 return super.visit(node, data); 190 } 191 192 public Object visit(ASTMethodDeclarator node, Object data) { 193 methodName = node.getImage(); 194 return super.visit(node, data); 195 } 196 197 public void setUsesSymbolTable() { 198 this.usesSymbolTable = true; 199 } 200 201 public boolean usesSymbolTable() { 202 return this.usesSymbolTable; 203 } 204 205 public void setUsesDFA() { 206 this.usesDFA = true; 207 } 208 209 public boolean usesDFA() { 210 return this.usesDFA; 211 } 212 213 /*** 214 * Adds a violation to the report. 215 * It is an utility method that simply does: 216 * <code>context.getReport().addRuleViolation(createRuleViolation(context, beginLine));</code> 217 * 218 * @param context the RuleContext 219 * @param beginLine begin line of the violation 220 * @deprecated use @link #addViolation(RuleContext, IPositionProvider) 221 */ 222 protected final void addViolation(RuleContext context, int beginLine) { 223 context.getReport().addRuleViolation(createRuleViolation(context, beginLine)); 224 } 225 226 /*** 227 * Adds a violation to the report. 228 * 229 * @param context the RuleContext 230 * @param pp the node that produces the violation, may be null, in which case all line and column info will be set to zero 231 */ 232 protected final void addViolation(RuleContext context, IPositionProvider pp) { 233 context.getReport().addRuleViolation(createRuleViolation(context, pp)); 234 } 235 236 /*** 237 * Gets the Image of the first parent node of type ASTClassOrInterfaceDeclaration or <code>null</code> 238 * 239 * @param node the node which will be searched 240 * @return 241 */ 242 protected final String getDeclaringType(SimpleNode node) { 243 ASTClassOrInterfaceDeclaration c = (ASTClassOrInterfaceDeclaration) node.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class); 244 if (c!=null) 245 return c.getImage(); 246 return null; 247 } 248 249 private final void extractNodeInfo(RuleViolation v, IPositionProvider pp) { 250 if (pp==null) { 251 v.setLine(0); 252 v.setColumnInfo(0, 0); 253 } else { 254 v.setLine(pp.getBeginLine()); 255 v.setColumnInfo(pp.getBeginColumn(), pp.getEndColumn()); 256 } 257 } 258 259 }