KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > pmd > AbstractRule


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 JavaDoc;
7 import java.util.Collections JavaDoc;
8 import java.util.HashMap JavaDoc;
9 import java.util.Iterator JavaDoc;
10 import java.util.List JavaDoc;
11 import java.util.Map JavaDoc;
12 import java.util.Properties JavaDoc;
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 JavaDoc name = getClass().getName();
24     protected Properties JavaDoc properties = new Properties JavaDoc(); // TODO - remove when ready
25
protected String JavaDoc message;
26     protected String JavaDoc description;
27     protected String JavaDoc example;
28     protected String JavaDoc ruleSetName;
29     protected boolean include;
30     protected boolean usesDFA;
31     protected boolean usesTypeResolution;
32     protected int priority = LOWEST_PRIORITY;
33     protected String JavaDoc externalInfoUrl;
34
35     private static final boolean inOldPropertyMode = true; // temporary flag during conversion
36

37     protected static Map JavaDoc asFixedMap(PropertyDescriptor[] descriptors) {
38         
39         Map JavaDoc descsById = new HashMap JavaDoc(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 JavaDoc asFixedMap(PropertyDescriptor descriptor) {
48         return asFixedMap(new PropertyDescriptor[] {descriptor});
49     }
50     
51     public String JavaDoc getRuleSetName() {
52         return ruleSetName;
53     }
54
55     public void setRuleSetName(String JavaDoc ruleSetName) {
56         this.ruleSetName = ruleSetName;
57     }
58
59     public String JavaDoc getDescription() {
60         return description;
61     }
62
63     public void setDescription(String JavaDoc description) {
64         this.description = description;
65     }
66
67     public String JavaDoc getExample() {
68         return example;
69     }
70
71     public void setExample(String JavaDoc example) {
72         this.example = example;
73     }
74
75     /**
76      * @deprecated - property values will be guaranteed available via default values
77      */

78     public boolean hasProperty(String JavaDoc name) {
79         
80         return inOldPropertyMode ? // TODO -remove
81
properties.containsKey(name) :
82             propertiesByName().containsKey(name);
83     }
84     
85     /**
86      * @deprecated
87      */

88     public void addProperty(String JavaDoc name, String JavaDoc value) {
89         properties.setProperty(name, value);
90     }
91
92     /**
93      * @deprecated
94      */

95     public void addProperties(Properties JavaDoc properties) {
96         this.properties.putAll(properties);
97     }
98     
99     public double[] getDoubleProperties(PropertyDescriptor descriptor) {
100         
101         Number JavaDoc[] values = (Number JavaDoc[])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     /**
109      * @deprecated - use getDoubleProperty(PropertyDescriptor) instead
110      */

111     public double getDoubleProperty(String JavaDoc name) {
112         
113         return Double.parseDouble(properties.getProperty(name));
114     }
115
116     public double getDoubleProperty(PropertyDescriptor descriptor) {
117         
118         return ((Number JavaDoc)getProperty(descriptor)).doubleValue();
119     }
120     
121     public int[] getIntProperties(PropertyDescriptor descriptor) {
122         
123         Number JavaDoc[] values = (Number JavaDoc[])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     /**
131      * @deprecated - use getIntProperty(PropertyDescriptor) instead
132      */

133     public int getIntProperty(String JavaDoc name) {
134         
135         return Integer.parseInt(properties.getProperty(name));
136     }
137
138     public int getIntProperty(PropertyDescriptor descriptor) {
139         
140         return ((Number JavaDoc)getProperty(descriptor)).intValue();
141     }
142     
143     public Class JavaDoc[] getTypeProperties(PropertyDescriptor descriptor) {
144         
145         return (Class JavaDoc[])getProperties(descriptor);
146     }
147     
148     public Class JavaDoc getTypeProperty(PropertyDescriptor descriptor) {
149         
150         return (Class JavaDoc)getProperty(descriptor);
151     }
152     
153     public boolean[] getBooleanProperties(PropertyDescriptor descriptor) {
154         
155         Boolean JavaDoc[] values = (Boolean JavaDoc[])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 JavaDoc)getProperty(descriptor)).booleanValue();
165     }
166     
167     /**
168      * @deprecated - use getBooleanProperty(PropertyDescriptor) instead
169      */

170     public boolean getBooleanProperty(String JavaDoc name) {
171         
172         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     public void setBooleanProperty(String JavaDoc name, boolean flag) {
182         
183         properties.setProperty(name, Boolean.toString(flag));
184     }
185     
186     public String JavaDoc[] getStringProperties(PropertyDescriptor descriptor) {
187         
188         return (String JavaDoc[])getProperties(descriptor);
189     }
190     
191
192     /**
193      * @deprecated - use getStringProperty(PropertyDescriptor) instead
194      *
195      */

196     public String JavaDoc getStringProperty(String JavaDoc name) {
197         return properties.getProperty(name);
198     }
199     
200     public String JavaDoc getStringProperty(PropertyDescriptor descriptor) {
201         return (String JavaDoc)getProperty(descriptor);
202     }
203     
204     private Object JavaDoc getProperty(PropertyDescriptor descriptor) {
205                 
206         if (descriptor.maxValueCount() > 1) propertyGetError(descriptor, true);
207         
208         String JavaDoc 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 JavaDoc value) {
216                 
217         if (descriptor.maxValueCount() > 1) propertySetError(descriptor, true);
218         
219         properties.setProperty(descriptor.name(), descriptor.asDelimitedString(value));
220     }
221     
222     private Object JavaDoc[] getProperties(PropertyDescriptor descriptor) {
223                 
224         if (descriptor.maxValueCount() == 1) propertyGetError(descriptor, false);
225         
226         String JavaDoc rawValue = properties.getProperty(descriptor.name());
227         
228         return rawValue == null || rawValue.length() == 0 ?
229             (Object JavaDoc[])descriptor.defaultValue() :
230             (Object JavaDoc[])descriptor.valueFrom(rawValue);
231     }
232     
233     public void setProperties(PropertyDescriptor descriptor, Object JavaDoc[] 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 JavaDoc("Cannot retrieve a single value from a multi-value property field");
244             }
245         throw new RuntimeException JavaDoc("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 JavaDoc("Cannot set a single value within a multi-value property field");
252             }
253         throw new RuntimeException JavaDoc("Cannot set multiple values within a single-value property field");
254     }
255     
256     public String JavaDoc getName() {
257         return name;
258     }
259
260     public void setName(String JavaDoc name) {
261         this.name = name;
262     }
263
264     public String JavaDoc getMessage() {
265         return message;
266     }
267
268     public void setMessage(String JavaDoc message) {
269         this.message = message;
270     }
271
272     public String JavaDoc getExternalInfoUrl() {
273         return externalInfoUrl;
274     }
275
276     public void setExternalInfoUrl(String JavaDoc url) {
277         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     public boolean equals(Object JavaDoc o) {
288         if (o == null) {
289             return false; // trivial
290
}
291
292         if (this == o) {
293             return true; // trivial
294
}
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     /**
310      * Return a hash code to conform to equality. Try with a string.
311      */

312     public int hashCode() {
313         String JavaDoc s = getClass().getName() + getName() + getPriority() + getProperties().toString();
314         return s.hashCode();
315     }
316
317     public void apply(List JavaDoc acus, RuleContext ctx) {
318         visitAll(acus, ctx);
319     }
320
321     /**
322      * @deprecated - retrieve by name using get<type>Property or get<type>Properties
323      */

324     public Properties JavaDoc 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 JavaDoc 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 JavaDoc acus, RuleContext ctx) {
365         for (Iterator JavaDoc i = acus.iterator(); i.hasNext();) {
366             ASTCompilationUnit node = (ASTCompilationUnit) i.next();
367             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     protected final void addViolation(Object JavaDoc data, SimpleNode node) {
378         RuleContext ctx = (RuleContext) data;
379         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     protected final void addViolationWithMessage(Object JavaDoc data, SimpleNode node, String JavaDoc msg) {
390         RuleContext ctx = (RuleContext) data;
391         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     protected final void addViolation(Object JavaDoc data, SimpleNode node, String JavaDoc embed) {
402         RuleContext ctx = (RuleContext) data;
403         ctx.getReport().addRuleViolation(new RuleViolation(this, ctx, node, MessageFormat.format(getMessage(), new Object JavaDoc[]{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     protected final void addViolation(Object JavaDoc data, Node node, Object JavaDoc[] args) {
414         RuleContext ctx = (RuleContext) data;
415         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     protected final String JavaDoc 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 JavaDoc packageName) {
435         
436         List JavaDoc nodes = node.findChildrenOfType(ASTImportDeclaration.class);
437         for (Iterator JavaDoc 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     /**
447      * Return all the relevant properties for the receiver by
448      * overriding in subclasses as necessary.
449      *
450      * @return Map
451      */

452     protected Map JavaDoc propertiesByName() {
453         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     public PropertyDescriptor propertyDescriptorFor(String JavaDoc propertyName) {
463         PropertyDescriptor desc = (PropertyDescriptor)propertiesByName().get(propertyName);
464         if (desc == null) throw new IllegalArgumentException JavaDoc("unknown property: " + propertyName);
465         return desc;
466     }
467 }
468
Popular Tags