Clover coverage report - PMD - 3.9
Coverage timestamp: Tue Dec 19 2006 09:38:44 EST
file stats: LOC: 467   Methods: 61
NCLOC: 276   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
AbstractRule.java 66.7% 76.1% 82% 75.9%
coverage coverage
 1    /**
 2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
 3    */
 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(); // TODO - remove when ready
 25    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; // temporary flag during conversion
 36   
 37  251 protected static Map asFixedMap(PropertyDescriptor[] descriptors) {
 38   
 39  251 Map descsById = new HashMap(descriptors.length);
 40   
 41  251 for (int i=0; i<descriptors.length; i++) {
 42  533 descsById.put(descriptors[i].name(), descriptors[i]);
 43    }
 44  251 return Collections.unmodifiableMap(descsById);
 45    }
 46   
 47  72 protected static Map asFixedMap(PropertyDescriptor descriptor) {
 48  72 return asFixedMap(new PropertyDescriptor[] {descriptor});
 49    }
 50   
 51  12 public String getRuleSetName() {
 52  12 return ruleSetName;
 53    }
 54   
 55  4599 public void setRuleSetName(String ruleSetName) {
 56  4599 this.ruleSetName = ruleSetName;
 57    }
 58   
 59  2 public String getDescription() {
 60  2 return description;
 61    }
 62   
 63  4346 public void setDescription(String description) {
 64  4346 this.description = description;
 65    }
 66   
 67  1 public String getExample() {
 68  1 return example;
 69    }
 70   
 71  4434 public void setExample(String example) {
 72  4434 this.example = example;
 73    }
 74   
 75    /**
 76    * @deprecated - property values will be guaranteed available via default values
 77    */
 78  603 public boolean hasProperty(String name) {
 79   
 80  603 return inOldPropertyMode ? // TODO -remove
 81    properties.containsKey(name) :
 82    propertiesByName().containsKey(name);
 83    }
 84   
 85    /**
 86    * @deprecated
 87    */
 88  3455 public void addProperty(String name, String value) {
 89  3455 properties.setProperty(name, value);
 90    }
 91   
 92    /**
 93    * @deprecated
 94    */
 95  2 public void addProperties(Properties properties) {
 96  2 this.properties.putAll(properties);
 97    }
 98   
 99  0 public double[] getDoubleProperties(PropertyDescriptor descriptor) {
 100   
 101  0 Number[] values = (Number[])getProperties(descriptor);
 102   
 103  0 double[] doubles = new double[values.length];
 104  0 for (int i=0; i<doubles.length; i++) doubles[i] = values[i].doubleValue();
 105  0 return doubles;
 106    }
 107   
 108    /**
 109    * @deprecated - use getDoubleProperty(PropertyDescriptor) instead
 110    */
 111  1 public double getDoubleProperty(String name) {
 112   
 113  1 return Double.parseDouble(properties.getProperty(name));
 114    }
 115   
 116  253 public double getDoubleProperty(PropertyDescriptor descriptor) {
 117   
 118  253 return ((Number)getProperty(descriptor)).doubleValue();
 119    }
 120   
 121  1 public int[] getIntProperties(PropertyDescriptor descriptor) {
 122   
 123  1 Number[] values = (Number[])getProperties(descriptor);
 124   
 125  1 int[] ints = new int[values.length];
 126  2 for (int i=0; i<ints.length; i++) ints[i] = values[i].intValue();
 127  1 return ints;
 128    }
 129   
 130    /**
 131    * @deprecated - use getIntProperty(PropertyDescriptor) instead
 132    */
 133  8 public int getIntProperty(String name) {
 134   
 135  8 return Integer.parseInt(properties.getProperty(name));
 136    }
 137   
 138  176 public int getIntProperty(PropertyDescriptor descriptor) {
 139   
 140  176 return ((Number)getProperty(descriptor)).intValue();
 141    }
 142   
 143  0 public Class[] getTypeProperties(PropertyDescriptor descriptor) {
 144   
 145  0 return (Class[])getProperties(descriptor);
 146    }
 147   
 148  0 public Class getTypeProperty(PropertyDescriptor descriptor) {
 149   
 150  0 return (Class)getProperty(descriptor);
 151    }
 152   
 153  1 public boolean[] getBooleanProperties(PropertyDescriptor descriptor) {
 154   
 155  1 Boolean[] values = (Boolean[])getProperties(descriptor);
 156   
 157  1 boolean[] bools = new boolean[values.length];
 158  2 for (int i=0; i<bools.length; i++) bools[i] = values[i].booleanValue();
 159  1 return bools;
 160    }
 161   
 162  25 public boolean getBooleanProperty(PropertyDescriptor descriptor) {
 163   
 164  25 return ((Boolean)getProperty(descriptor)).booleanValue();
 165    }
 166   
 167    /**
 168    * @deprecated - use getBooleanProperty(PropertyDescriptor) instead
 169    */
 170  16 public boolean getBooleanProperty(String name) {
 171   
 172  16 return Boolean.valueOf(properties.getProperty(name)).booleanValue();
 173    }
 174   
 175    /**
 176    * @deprecated - use setProperty(PropertyDescriptor, Object) instead
 177    *
 178    * @param name
 179    * @param flag
 180    */
 181  0 public void setBooleanProperty(String name, boolean flag) {
 182   
 183  0 properties.setProperty(name, Boolean.toString(flag));
 184    }
 185   
 186  41 public String[] getStringProperties(PropertyDescriptor descriptor) {
 187   
 188  41 return (String[])getProperties(descriptor);
 189    }
 190   
 191   
 192    /**
 193    * @deprecated - use getStringProperty(PropertyDescriptor) instead
 194    *
 195    */
 196  109 public String getStringProperty(String name) {
 197  109 return properties.getProperty(name);
 198    }
 199   
 200  37 public String getStringProperty(PropertyDescriptor descriptor) {
 201  37 return (String)getProperty(descriptor);
 202    }
 203   
 204  491 private Object getProperty(PropertyDescriptor descriptor) {
 205   
 206  0 if (descriptor.maxValueCount() > 1) propertyGetError(descriptor, true);
 207   
 208  491 String rawValue = properties.getProperty(descriptor.name());
 209   
 210  491 return rawValue == null || rawValue.length() == 0 ?
 211    descriptor.defaultValue() :
 212    descriptor.valueFrom(rawValue);
 213    }
 214   
 215  29 public void setProperty(PropertyDescriptor descriptor, Object value) {
 216   
 217  3 if (descriptor.maxValueCount() > 1) propertySetError(descriptor, true);
 218   
 219  26 properties.setProperty(descriptor.name(), descriptor.asDelimitedString(value));
 220    }
 221   
 222  43 private Object[] getProperties(PropertyDescriptor descriptor) {
 223   
 224  0 if (descriptor.maxValueCount() == 1) propertyGetError(descriptor, false);
 225   
 226  43 String rawValue = properties.getProperty(descriptor.name());
 227   
 228  43 return rawValue == null || rawValue.length() == 0 ?
 229    (Object[])descriptor.defaultValue() :
 230    (Object[])descriptor.valueFrom(rawValue);
 231    }
 232   
 233  6 public void setProperties(PropertyDescriptor descriptor, Object[] values) {
 234   
 235  3 if (descriptor.maxValueCount() == 1) propertySetError(descriptor, false);
 236   
 237  3 properties.setProperty(descriptor.name(), descriptor.asDelimitedString(values));
 238    }
 239   
 240  0 private void propertyGetError(PropertyDescriptor descriptor, boolean requestedSingleValue) {
 241   
 242  0 if (requestedSingleValue) {
 243  0 throw new RuntimeException("Cannot retrieve a single value from a multi-value property field");
 244    }
 245  0 throw new RuntimeException("Cannot retrieve multiple values from a single-value property field");
 246    }
 247   
 248  6 private void propertySetError(PropertyDescriptor descriptor, boolean setSingleValue) {
 249   
 250  6 if (setSingleValue) {
 251  3 throw new RuntimeException("Cannot set a single value within a multi-value property field");
 252    }
 253  3 throw new RuntimeException("Cannot set multiple values within a single-value property field");
 254    }
 255   
 256  2846 public String getName() {
 257  2846 return name;
 258    }
 259   
 260  4413 public void setName(String name) {
 261  4413 this.name = name;
 262    }
 263   
 264  849 public String getMessage() {
 265  849 return message;
 266    }
 267   
 268  4417 public void setMessage(String message) {
 269  4417 this.message = message;
 270    }
 271   
 272  15 public String getExternalInfoUrl() {
 273  15 return externalInfoUrl;
 274    }
 275   
 276  4391 public void setExternalInfoUrl(String url) {
 277  4391 this.externalInfoUrl = url;
 278    }
 279   
 280    /**
 281    * Test if rules are equals. Rules are equals if
 282    * 1. they have the same implementation class
 283    * 2. they have the same name
 284    * 3. they have the same priority
 285    * 4. they share the same properties/values
 286    */
 287  16 public boolean equals(Object o) {
 288  16 if (o == null) {
 289  1 return false; // trivial
 290    }
 291   
 292  15 if (this == o) {
 293  5 return true; // trivial
 294    }
 295   
 296  10 Rule rule = null;
 297  10 boolean equality = this.getClass().getName().equals(o.getClass().getName());
 298   
 299  10 if (equality) {
 300  8 rule = (Rule) o;
 301  8 equality = this.getName().equals(rule.getName())
 302    && this.getPriority() == rule.getPriority()
 303    && this.getProperties().equals(rule.getProperties());
 304    }
 305   
 306  10 return equality;
 307    }
 308   
 309    /**
 310    * Return a hash code to conform to equality. Try with a string.
 311    */
 312  20 public int hashCode() {
 313  20 String s = getClass().getName() + getName() + getPriority() + getProperties().toString();
 314  20 return s.hashCode();
 315    }
 316   
 317  1189 public void apply(List acus, RuleContext ctx) {
 318  1189 visitAll(acus, ctx);
 319    }
 320   
 321    /**
 322    * @deprecated - retrieve by name using get<type>Property or get<type>Properties
 323    */
 324  1200 public Properties getProperties() {
 325  1200 return properties;
 326    }
 327   
 328  0 public boolean include() {
 329  0 return include;
 330    }
 331   
 332  0 public void setInclude(boolean include) {
 333  0 this.include = include;
 334    }
 335   
 336  4483 public int getPriority() {
 337  4483 return priority;
 338    }
 339   
 340  0 public String getPriorityName() {
 341  0 return PRIORITIES[getPriority() - 1];
 342    }
 343   
 344  4356 public void setPriority(int priority) {
 345  4356 this.priority = priority;
 346    }
 347   
 348  19 public void setUsesDFA() {
 349  19 this.usesDFA = true;
 350    }
 351   
 352  1229 public boolean usesDFA() {
 353  1229 return this.usesDFA;
 354    }
 355   
 356  4 public void setUsesTypeResolution() {
 357  4 this.usesTypeResolution = true;
 358    }
 359   
 360  1225 public boolean usesTypeResolution() {
 361  1225 return this.usesTypeResolution;
 362    }
 363   
 364  1383 protected void visitAll(List acus, RuleContext ctx) {
 365  1383 for (Iterator i = acus.iterator(); i.hasNext();) {
 366  1225 ASTCompilationUnit node = (ASTCompilationUnit) i.next();
 367  1225 visit(node, ctx);
 368    }
 369    }
 370   
 371    /**
 372    * Adds a violation to the report.
 373    *
 374    * @param ctx the RuleContext
 375    * @param node the node that produces the violation
 376    */
 377  224 protected final void addViolation(Object data, SimpleNode node) {
 378  224 RuleContext ctx = (RuleContext) data;
 379  224 ctx.getReport().addRuleViolation(new RuleViolation(this, ctx, node));
 380    }
 381   
 382    /**
 383    * Adds a violation to the report.
 384    *
 385    * @param ctx the RuleContext
 386    * @param node the node that produces the violation
 387    * @param msg specific message to put in the report
 388    */
 389  2239 protected final void addViolationWithMessage(Object data, SimpleNode node, String msg) {
 390  2239 RuleContext ctx = (RuleContext) data;
 391  2239 ctx.getReport().addRuleViolation(new RuleViolation(this, ctx, node, msg));
 392    }
 393   
 394    /**
 395    * Adds a violation to the report.
 396    *
 397    * @param ctx the RuleContext
 398    * @param node the node that produces the violation
 399    * @param embed a variable to embed in the rule violation message
 400    */
 401  326 protected final void addViolation(Object data, SimpleNode node, String embed) {
 402  326 RuleContext ctx = (RuleContext) data;
 403  326 ctx.getReport().addRuleViolation(new RuleViolation(this, ctx, node, MessageFormat.format(getMessage(), new Object[]{embed})));
 404    }
 405   
 406    /**
 407    * Adds a violation to the report.
 408    *
 409    * @param ctx the RuleContext
 410    * @param node the node that produces the violation, may be null, in which case all line and column info will be set to zero
 411    * @param args objects to embed in the rule violation message
 412    */
 413  62 protected final void addViolation(Object data, Node node, Object[] args) {
 414  62 RuleContext ctx = (RuleContext) data;
 415  62 ctx.getReport().addRuleViolation(new RuleViolation(this, ctx, (SimpleNode) node, MessageFormat.format(getMessage(), args)));
 416    }
 417   
 418    /**
 419    * Gets the Image of the first parent node of type ASTClassOrInterfaceDeclaration or <code>null</code>
 420    *
 421    * @param node the node which will be searched
 422    */
 423  12 protected final String getDeclaringType(SimpleNode node) {
 424  12 ASTClassOrInterfaceDeclaration c = (ASTClassOrInterfaceDeclaration) node.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class);
 425  12 if (c != null)
 426  12 return c.getImage();
 427  0 return null;
 428    }
 429   
 430  46 public static boolean isQualifiedName(SimpleNode node) {
 431  46 return node.getImage().indexOf('.') != -1;
 432    }
 433   
 434  0 public static boolean importsPackage(ASTCompilationUnit node, String packageName) {
 435   
 436  0 List nodes = node.findChildrenOfType(ASTImportDeclaration.class);
 437  0 for (Iterator i = nodes.iterator(); i.hasNext();) {
 438  0 ASTImportDeclaration n = (ASTImportDeclaration) i.next();
 439  0 if (n.getPackageName().startsWith(packageName)) {
 440  0 return true;
 441    }
 442    }
 443  0 return false;
 444    }
 445   
 446    /**
 447    * Return all the relevant properties for the receiver by
 448    * overriding in subclasses as necessary.
 449    *
 450    * @return Map
 451    */
 452  0 protected Map propertiesByName() {
 453  0 return Collections.EMPTY_MAP;
 454    }
 455   
 456    /**
 457    * Return the indicated property descriptor or null if not found.
 458    *
 459    * @param propertyName String
 460    * @return PropertyDescriptor
 461    */
 462  0 public PropertyDescriptor propertyDescriptorFor(String propertyName) {
 463  0 PropertyDescriptor desc = (PropertyDescriptor)propertiesByName().get(propertyName);
 464  0 if (desc == null) throw new IllegalArgumentException("unknown property: " + propertyName);
 465  0 return desc;
 466    }
 467    }