1 4 package net.sourceforge.pmd; 5 6 import java.text.MessageFormat ; 7 import java.util.Collections ; 8 import java.util.HashMap ; 9 import java.util.Iterator ; 10 import java.util.List ; 11 import java.util.Map ; 12 import java.util.Properties ; 13 14 import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration; 15 import net.sourceforge.pmd.ast.ASTCompilationUnit; 16 import net.sourceforge.pmd.ast.ASTImportDeclaration; 17 import net.sourceforge.pmd.ast.JavaParserVisitorAdapter; 18 import net.sourceforge.pmd.ast.Node; 19 import net.sourceforge.pmd.ast.SimpleNode; 20 21 public abstract class AbstractRule extends JavaParserVisitorAdapter implements Rule { 22 23 protected String name = getClass().getName(); 24 protected Properties properties = new Properties (); protected String message; 26 protected String description; 27 protected String example; 28 protected String ruleSetName; 29 protected boolean include; 30 protected boolean usesDFA; 31 protected boolean usesTypeResolution; 32 protected int priority = LOWEST_PRIORITY; 33 protected String externalInfoUrl; 34 35 private static final boolean inOldPropertyMode = true; 37 protected static Map asFixedMap(PropertyDescriptor[] descriptors) { 38 39 Map descsById = new HashMap (descriptors.length); 40 41 for (int i=0; i<descriptors.length; i++) { 42 descsById.put(descriptors[i].name(), descriptors[i]); 43 } 44 return Collections.unmodifiableMap(descsById); 45 } 46 47 protected static Map asFixedMap(PropertyDescriptor descriptor) { 48 return asFixedMap(new PropertyDescriptor[] {descriptor}); 49 } 50 51 public String getRuleSetName() { 52 return ruleSetName; 53 } 54 55 public void setRuleSetName(String ruleSetName) { 56 this.ruleSetName = ruleSetName; 57 } 58 59 public String getDescription() { 60 return description; 61 } 62 63 public void setDescription(String description) { 64 this.description = description; 65 } 66 67 public String getExample() { 68 return example; 69 } 70 71 public void setExample(String example) { 72 this.example = example; 73 } 74 75 78 public boolean hasProperty(String name) { 79 80 return inOldPropertyMode ? properties.containsKey(name) : 82 propertiesByName().containsKey(name); 83 } 84 85 88 public void addProperty(String name, String value) { 89 properties.setProperty(name, value); 90 } 91 92 95 public void addProperties(Properties properties) { 96 this.properties.putAll(properties); 97 } 98 99 public double[] getDoubleProperties(PropertyDescriptor descriptor) { 100 101 Number [] values = (Number [])getProperties(descriptor); 102 103 double[] doubles = new double[values.length]; 104 for (int i=0; i<doubles.length; i++) doubles[i] = values[i].doubleValue(); 105 return doubles; 106 } 107 108 111 public double getDoubleProperty(String name) { 112 113 return Double.parseDouble(properties.getProperty(name)); 114 } 115 116 public double getDoubleProperty(PropertyDescriptor descriptor) { 117 118 return ((Number )getProperty(descriptor)).doubleValue(); 119 } 120 121 public int[] getIntProperties(PropertyDescriptor descriptor) { 122 123 Number [] values = (Number [])getProperties(descriptor); 124 125 int[] ints = new int[values.length]; 126 for (int i=0; i<ints.length; i++) ints[i] = values[i].intValue(); 127 return ints; 128 } 129 130 133 public int getIntProperty(String name) { 134 135 return Integer.parseInt(properties.getProperty(name)); 136 } 137 138 public int getIntProperty(PropertyDescriptor descriptor) { 139 140 return ((Number )getProperty(descriptor)).intValue(); 141 } 142 143 public Class [] getTypeProperties(PropertyDescriptor descriptor) { 144 145 return (Class [])getProperties(descriptor); 146 } 147 148 public Class getTypeProperty(PropertyDescriptor descriptor) { 149 150 return (Class )getProperty(descriptor); 151 } 152 153 public boolean[] getBooleanProperties(PropertyDescriptor descriptor) { 154 155 Boolean [] values = (Boolean [])getProperties(descriptor); 156 157 boolean[] bools = new boolean[values.length]; 158 for (int i=0; i<bools.length; i++) bools[i] = values[i].booleanValue(); 159 return bools; 160 } 161 162 public boolean getBooleanProperty(PropertyDescriptor descriptor) { 163 164 return ((Boolean )getProperty(descriptor)).booleanValue(); 165 } 166 167 170 public boolean getBooleanProperty(String name) { 171 172 return Boolean.valueOf(properties.getProperty(name)).booleanValue(); 173 } 174 175 181 public void setBooleanProperty(String name, boolean flag) { 182 183 properties.setProperty(name, Boolean.toString(flag)); 184 } 185 186 public String [] getStringProperties(PropertyDescriptor descriptor) { 187 188 return (String [])getProperties(descriptor); 189 } 190 191 192 196 public String getStringProperty(String name) { 197 return properties.getProperty(name); 198 } 199 200 public String getStringProperty(PropertyDescriptor descriptor) { 201 return (String )getProperty(descriptor); 202 } 203 204 private Object getProperty(PropertyDescriptor descriptor) { 205 206 if (descriptor.maxValueCount() > 1) propertyGetError(descriptor, true); 207 208 String rawValue = properties.getProperty(descriptor.name()); 209 210 return rawValue == null || rawValue.length() == 0 ? 211 descriptor.defaultValue() : 212 descriptor.valueFrom(rawValue); 213 } 214 215 public void setProperty(PropertyDescriptor descriptor, Object value) { 216 217 if (descriptor.maxValueCount() > 1) propertySetError(descriptor, true); 218 219 properties.setProperty(descriptor.name(), descriptor.asDelimitedString(value)); 220 } 221 222 private Object [] getProperties(PropertyDescriptor descriptor) { 223 224 if (descriptor.maxValueCount() == 1) propertyGetError(descriptor, false); 225 226 String rawValue = properties.getProperty(descriptor.name()); 227 228 return rawValue == null || rawValue.length() == 0 ? 229 (Object [])descriptor.defaultValue() : 230 (Object [])descriptor.valueFrom(rawValue); 231 } 232 233 public void setProperties(PropertyDescriptor descriptor, Object [] values) { 234 235 if (descriptor.maxValueCount() == 1) propertySetError(descriptor, false); 236 237 properties.setProperty(descriptor.name(), descriptor.asDelimitedString(values)); 238 } 239 240 private void propertyGetError(PropertyDescriptor descriptor, boolean requestedSingleValue) { 241 242 if (requestedSingleValue) { 243 throw new RuntimeException ("Cannot retrieve a single value from a multi-value property field"); 244 } 245 throw new RuntimeException ("Cannot retrieve multiple values from a single-value property field"); 246 } 247 248 private void propertySetError(PropertyDescriptor descriptor, boolean setSingleValue) { 249 250 if (setSingleValue) { 251 throw new RuntimeException ("Cannot set a single value within a multi-value property field"); 252 } 253 throw new RuntimeException ("Cannot set multiple values within a single-value property field"); 254 } 255 256 public String getName() { 257 return name; 258 } 259 260 public void setName(String name) { 261 this.name = name; 262 } 263 264 public String getMessage() { 265 return message; 266 } 267 268 public void setMessage(String message) { 269 this.message = message; 270 } 271 272 public String getExternalInfoUrl() { 273 return externalInfoUrl; 274 } 275 276 public void setExternalInfoUrl(String url) { 277 this.externalInfoUrl = url; 278 } 279 280 287 public boolean equals(Object o) { 288 if (o == null) { 289 return false; } 291 292 if (this == o) { 293 return true; } 295 296 Rule rule = null; 297 boolean equality = this.getClass().getName().equals(o.getClass().getName()); 298 299 if (equality) { 300 rule = (Rule) o; 301 equality = this.getName().equals(rule.getName()) 302 && this.getPriority() == rule.getPriority() 303 && this.getProperties().equals(rule.getProperties()); 304 } 305 306 return equality; 307 } 308 309 312 public int hashCode() { 313 String s = getClass().getName() + getName() + getPriority() + getProperties().toString(); 314 return s.hashCode(); 315 } 316 317 public void apply(List acus, RuleContext ctx) { 318 visitAll(acus, ctx); 319 } 320 321 324 public Properties getProperties() { 325 return properties; 326 } 327 328 public boolean include() { 329 return include; 330 } 331 332 public void setInclude(boolean include) { 333 this.include = include; 334 } 335 336 public int getPriority() { 337 return priority; 338 } 339 340 public String getPriorityName() { 341 return PRIORITIES[getPriority() - 1]; 342 } 343 344 public void setPriority(int priority) { 345 this.priority = priority; 346 } 347 348 public void setUsesDFA() { 349 this.usesDFA = true; 350 } 351 352 public boolean usesDFA() { 353 return this.usesDFA; 354 } 355 356 public void setUsesTypeResolution() { 357 this.usesTypeResolution = true; 358 } 359 360 public boolean usesTypeResolution() { 361 return this.usesTypeResolution; 362 } 363 364 protected void visitAll(List acus, RuleContext ctx) { 365 for (Iterator i = acus.iterator(); i.hasNext();) { 366 ASTCompilationUnit node = (ASTCompilationUnit) i.next(); 367 visit(node, ctx); 368 } 369 } 370 371 377 protected final void addViolation(Object data, SimpleNode node) { 378 RuleContext ctx = (RuleContext) data; 379 ctx.getReport().addRuleViolation(new RuleViolation(this, ctx, node)); 380 } 381 382 389 protected final void addViolationWithMessage(Object data, SimpleNode node, String msg) { 390 RuleContext ctx = (RuleContext) data; 391 ctx.getReport().addRuleViolation(new RuleViolation(this, ctx, node, msg)); 392 } 393 394 401 protected final void addViolation(Object data, SimpleNode node, String embed) { 402 RuleContext ctx = (RuleContext) data; 403 ctx.getReport().addRuleViolation(new RuleViolation(this, ctx, node, MessageFormat.format(getMessage(), new Object []{embed}))); 404 } 405 406 413 protected final void addViolation(Object data, Node node, Object [] args) { 414 RuleContext ctx = (RuleContext) data; 415 ctx.getReport().addRuleViolation(new RuleViolation(this, ctx, (SimpleNode) node, MessageFormat.format(getMessage(), args))); 416 } 417 418 423 protected final String getDeclaringType(SimpleNode node) { 424 ASTClassOrInterfaceDeclaration c = (ASTClassOrInterfaceDeclaration) node.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class); 425 if (c != null) 426 return c.getImage(); 427 return null; 428 } 429 430 public static boolean isQualifiedName(SimpleNode node) { 431 return node.getImage().indexOf('.') != -1; 432 } 433 434 public static boolean importsPackage(ASTCompilationUnit node, String packageName) { 435 436 List nodes = node.findChildrenOfType(ASTImportDeclaration.class); 437 for (Iterator i = nodes.iterator(); i.hasNext();) { 438 ASTImportDeclaration n = (ASTImportDeclaration) i.next(); 439 if (n.getPackageName().startsWith(packageName)) { 440 return true; 441 } 442 } 443 return false; 444 } 445 446 452 protected Map propertiesByName() { 453 return Collections.EMPTY_MAP; 454 } 455 456 462 public PropertyDescriptor propertyDescriptorFor(String propertyName) { 463 PropertyDescriptor desc = (PropertyDescriptor)propertiesByName().get(propertyName); 464 if (desc == null) throw new IllegalArgumentException ("unknown property: " + propertyName); 465 return desc; 466 } 467 } 468 | Popular Tags |