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