1 package net.sourceforge.pmd;
2
3 import net.sourceforge.pmd.ast.Node;
4 import net.sourceforge.pmd.ast.SimpleNode;
5
6 import java.text.MessageFormat;
7 import java.util.Properties;
8
9 /***
10 * Basic abstract implementation of all parser-independent methods of the
11 * Rule interface.
12 *
13 * @author pieter_van_raemdonck - Application Engineers NV/SA - www.ae.be
14 */
15 public abstract class CommonAbstractRule implements Rule {
16
17 protected String name = getClass().getName();
18 protected Properties properties = new Properties();
19 protected String message;
20 protected String description;
21 protected String example;
22 protected String ruleSetName;
23 protected boolean include;
24 protected boolean usesDFA;
25 protected int priority = LOWEST_PRIORITY;
26 protected String externalInfoUrl;
27
28 public String getRuleSetName() {
29 return ruleSetName;
30 }
31
32 public void setRuleSetName(String ruleSetName) {
33 this.ruleSetName = ruleSetName;
34 }
35
36 public String getDescription() {
37 return description;
38 }
39
40 public void setDescription(String description) {
41 this.description = description;
42 }
43
44 public String getExample() {
45 return example;
46 }
47
48 public void setExample(String example) {
49 this.example = example;
50 }
51
52 public boolean hasProperty(String name) {
53 return properties.containsKey(name);
54 }
55
56 public void addProperty(String name, String value) {
57 properties.setProperty(name, value);
58 }
59
60 public void addProperties(Properties properties) {
61 this.properties.putAll(properties);
62 }
63
64 public double getDoubleProperty(String name) {
65 return Double.parseDouble(properties.getProperty(name));
66 }
67
68 public int getIntProperty(String name) {
69 return Integer.parseInt(properties.getProperty(name));
70 }
71
72 public boolean getBooleanProperty(String name) {
73 return Boolean.valueOf(properties.getProperty(name)).booleanValue();
74 }
75
76 public String getStringProperty(String name) {
77 return properties.getProperty(name);
78 }
79
80 public String getName() {
81 return name;
82 }
83
84 public void setName(String name) {
85 this.name = name;
86 }
87
88 public String getMessage() {
89 return message;
90 }
91
92 public void setMessage(String message) {
93 this.message = message;
94 }
95
96 public String getExternalInfoUrl() {
97 return externalInfoUrl;
98 }
99
100 public void setExternalInfoUrl(String url) {
101 this.externalInfoUrl = url;
102 }
103
104 /***
105 * Test if rules are equals. Rules are equals if
106 * 1. they have the same implementation class
107 * 2. they have the same name
108 * 3. they have the same priority
109 * 4. they share the same properties/values
110 */
111 public boolean equals(Object o) {
112 if (o == null) {
113 return false;
114 }
115
116 if (this == o) {
117 return true;
118 }
119
120 Rule rule = null;
121 boolean equality = this.getClass().getName().equals(o.getClass().getName());
122
123 if (equality) {
124 rule = (Rule) o;
125 equality = this.getName().equals(rule.getName())
126 && this.getPriority() == rule.getPriority()
127 && this.getProperties().equals(rule.getProperties());
128 }
129
130 return equality;
131 }
132
133 /***
134 * Return a hash code to conform to equality. Try with a string.
135 */
136 public int hashCode() {
137 String s = this.getClass().getName() + this.getName() + String.valueOf(this.getPriority()) + this.getProperties().toString();
138 return s.hashCode();
139 }
140
141
142 public Properties getProperties() {
143 return properties;
144 }
145
146 public boolean include() {
147 return include;
148 }
149
150 public void setInclude(boolean include) {
151 this.include = include;
152 }
153
154 public int getPriority() {
155 return priority;
156 }
157
158 public String getPriorityName() {
159 return PRIORITIES[getPriority() - 1];
160 }
161
162 public void setPriority(int priority) {
163 this.priority = priority;
164 }
165
166 public void setUsesDFA() {
167 this.usesDFA = true;
168 }
169
170 public boolean usesDFA() {
171 return this.usesDFA;
172 }
173
174
175 /***
176 * Adds a violation to the report.
177 *
178 * @param ctx the RuleContext
179 * @param node the node that produces the violation
180 */
181 protected final void addViolation(Object data, SimpleNode node) {
182 RuleContext ctx = (RuleContext) data;
183 ctx.getReport().addRuleViolation(new RuleViolation(this, ctx, node));
184 }
185
186 /***
187 * Adds a violation to the report.
188 *
189 * @param ctx the RuleContext
190 * @param node the node that produces the violation
191 * @param msg specific message to put in the report
192 */
193 protected final void addViolationWithMessage(Object data, SimpleNode node, String msg) {
194 RuleContext ctx = (RuleContext) data;
195 ctx.getReport().addRuleViolation(new RuleViolation(this, ctx, node, msg));
196 }
197
198 /***
199 * Adds a violation to the report.
200 *
201 * @param ctx the RuleContext
202 * @param node the node that produces the violation
203 * @param embed a variable to embed in the rule violation message
204 */
205 protected final void addViolation(Object data, SimpleNode node, String embed) {
206 RuleContext ctx = (RuleContext) data;
207 ctx.getReport().addRuleViolation(new RuleViolation(this, ctx, node, MessageFormat.format(getMessage(), new Object[]{embed})));
208 }
209
210 /***
211 * Adds a violation to the report.
212 *
213 * @param ctx the RuleContext
214 * @param node the node that produces the violation, may be null, in which case all line and column info will be set to zero
215 * @param args objects to embed in the rule violation message
216 */
217 protected final void addViolation(Object data, Node node, Object[] args) {
218 RuleContext ctx = (RuleContext) data;
219 ctx.getReport().addRuleViolation(new RuleViolation(this, ctx, (SimpleNode) node, MessageFormat.format(getMessage(), args)));
220 }
221
222 }