001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2009 SonarSource SA
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020 package org.sonar.api.rules;
021
022 import org.apache.commons.lang.StringUtils;
023 import org.apache.commons.lang.builder.EqualsBuilder;
024 import org.apache.commons.lang.builder.HashCodeBuilder;
025 import org.apache.commons.lang.builder.ToStringBuilder;
026 import org.sonar.api.database.DatabaseProperties;
027 import org.sonar.check.Cardinality;
028
029 import java.util.ArrayList;
030 import java.util.List;
031
032 import javax.persistence.*;
033
034 @Entity
035 @Table(name = "rules")
036 public final class Rule {
037
038 private final static RulesCategory NONE = new RulesCategory("none");
039
040 @Id
041 @Column(name = "id")
042 @GeneratedValue
043 private Integer id;
044
045 /**
046 * The default priority given to a rule if not explicitly set
047 */
048 public static final RulePriority DEFAULT_PRIORITY = RulePriority.MAJOR;
049
050 @Column(name = "name", updatable = true, nullable = false)
051 private String name;
052
053 @Column(name = "plugin_rule_key", updatable = false, nullable = true, length = 200)
054 private String key;
055
056 @Column(name = "enabled", updatable = true, nullable = true)
057 private Boolean enabled = Boolean.TRUE;
058
059 @Column(name = "plugin_config_key", updatable = true, nullable = true, length = 500)
060 private String configKey;
061
062 // Godin: This field should be named priority, otherwise StandardRulesXmlParserTest fails
063 @Column(name = "priority", updatable = true, nullable = true)
064 @Enumerated(EnumType.ORDINAL)
065 private RulePriority priority = DEFAULT_PRIORITY;
066
067 @Column(name = "description", updatable = true, nullable = true, length = DatabaseProperties.MAX_TEXT_SIZE)
068 private String description;
069
070 @Column(name = "plugin_name", updatable = true, nullable = false)
071 private String pluginName;
072
073 @Enumerated(EnumType.STRING)
074 @Column(name = "cardinality", updatable = true, nullable = false)
075 private Cardinality cardinality = Cardinality.SINGLE;
076
077 @ManyToOne(fetch = FetchType.EAGER)
078 @JoinColumn(name = "parent_id", updatable = true, nullable = true)
079 private Rule parent = null;
080
081 @org.hibernate.annotations.Cascade({ org.hibernate.annotations.CascadeType.ALL, org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
082 @OneToMany(mappedBy = "rule")
083 private List<RuleParam> params = new ArrayList<RuleParam>();
084
085 /**
086 * @deprecated since 2.3. Use the factory method {@link #create()}
087 */
088 @Deprecated
089 public Rule() {
090 // TODO reduce visibility to package
091 }
092
093 /**
094 * Creates rule with minimum set of info
095 *
096 * @param pluginName the plugin name indicates which plugin the rule belongs to
097 * @param key the key should be unique within a plugin, but it is even more careful for the time being that it is unique across the
098 * application
099 * @deprecated since 2.3. Use the factory method {@link #create()}
100 */
101 @Deprecated
102 public Rule(String pluginName, String key) {
103 this.pluginName = pluginName;
104 this.key = key;
105 this.configKey = key;
106 }
107
108 /**
109 * Creates a fully qualified rule
110 *
111 * @param pluginKey the plugin the rule belongs to
112 * @param key the key should be unique within a plugin, but it is even more careful for the time being that it is unique across the
113 * application
114 * @param name the name displayed in the UI
115 * @param rulesCategory the ISO category the rule belongs to
116 * @param severity this is the severity associated to the rule
117 * @deprecated since 2.3. Use the factory method {@link #create()}
118 */
119 @Deprecated
120 public Rule(String pluginKey, String key, String name, RulesCategory rulesCategory, RulePriority severity) {
121 setName(name);
122 this.key = key;
123 this.configKey = key;
124 this.priority = severity;
125 this.pluginName = pluginKey;
126 }
127
128 /**
129 * @deprecated since 2.3. Use the factory method {@link #create()}
130 */
131 @Deprecated
132 public Rule(String name, String key, RulesCategory rulesCategory, String pluginName, String description) {
133 this();
134 setName(name);
135 this.key = key;
136 this.configKey = key;
137 this.pluginName = pluginName;
138 this.description = description;
139 }
140
141 /**
142 * @deprecated since 2.3. Use the factory method {@link #create()}
143 */
144 @Deprecated
145 public Rule(String name, String key, String configKey, RulesCategory rulesCategory, String pluginName, String description) {
146 this();
147 setName(name);
148 this.key = key;
149 this.configKey = configKey;
150 this.pluginName = pluginName;
151 this.description = description;
152 }
153
154 public Integer getId() {
155 return id;
156 }
157
158 /**
159 * @deprecated since 2.3. visibility should be decreased to protected or package
160 */
161 @Deprecated
162 public void setId(Integer id) {
163 this.id = id;
164 }
165
166 public String getName() {
167 return name;
168 }
169
170 /**
171 * Sets the rule name
172 */
173 public Rule setName(String name) {
174 this.name = removeNewLineCharacters(name);
175 return this;
176 }
177
178 public String getKey() {
179 return key;
180 }
181
182 /**
183 * Sets the rule key
184 */
185 public Rule setKey(String key) {
186 this.key = key;
187 return this;
188 }
189
190 /**
191 * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
192 */
193 @Deprecated
194 public RulesCategory getRulesCategory() {
195 return NONE;
196 }
197
198 /**
199 * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
200 */
201 @Deprecated
202 public Rule setRulesCategory(RulesCategory rulesCategory) {
203 return this;
204 }
205
206 /**
207 * @deprecated since 2.5 use {@link #getRepositoryKey()} instead
208 */
209 @Deprecated
210 public String getPluginName() {
211 return pluginName;
212 }
213
214 /**
215 * @deprecated since 2.5 use {@link #setRepositoryKey(String)} instead
216 */
217 @Deprecated
218 public Rule setPluginName(String pluginName) {
219 this.pluginName = pluginName;
220 return this;
221 }
222
223 public String getConfigKey() {
224 return configKey;
225 }
226
227 /**
228 * Sets the configuration key
229 */
230 public Rule setConfigKey(String configKey) {
231 this.configKey = configKey;
232 return this;
233 }
234
235 public String getDescription() {
236 return description;
237 }
238
239 /**
240 * Sets the rule description
241 */
242 public Rule setDescription(String description) {
243 this.description = StringUtils.strip(description);
244 return this;
245 }
246
247 public Boolean isEnabled() {
248 return enabled;
249 }
250
251 /**
252 * Do not call. Used only by sonar.
253 */
254 public Rule setEnabled(Boolean b) {
255 this.enabled = b;
256 return this;
257 }
258
259 public List<RuleParam> getParams() {
260 return params;
261 }
262
263 public RuleParam getParam(String key) {
264 for (RuleParam param : params) {
265 if (StringUtils.equals(key, param.getKey())) {
266 return param;
267 }
268 }
269 return null;
270 }
271
272 /**
273 * Sets the rule parameters
274 */
275 public Rule setParams(List<RuleParam> params) {
276 this.params.clear();
277 for (RuleParam param : params) {
278 param.setRule(this);
279 this.params.add(param);
280 }
281 return this;
282 }
283
284 public RuleParam createParameter() {
285 RuleParam parameter = new RuleParam()
286 .setRule(this);
287 params.add(parameter);
288 return parameter;
289 }
290
291 public RuleParam createParameter(String key) {
292 RuleParam parameter = new RuleParam()
293 .setKey(key)
294 .setRule(this);
295 params.add(parameter);
296 return parameter;
297 }
298
299 /**
300 * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007
301 */
302 @Deprecated
303 public Integer getCategoryId() {
304 return null;
305 }
306
307 /**
308 * @since 2.5
309 */
310 public RulePriority getSeverity() {
311 return priority;
312 }
313
314 /**
315 * @param severity severity to set, if null, uses the default priority.
316 * @since 2.5
317 */
318 public Rule setSeverity(RulePriority severity) {
319 if (severity == null) {
320 this.priority = DEFAULT_PRIORITY;
321 } else {
322 this.priority = severity;
323 }
324 return this;
325 }
326
327 /**
328 * @deprecated since 2.5 use {@link #getSeverity()} instead. See http://jira.codehaus.org/browse/SONAR-1829
329 */
330 @Deprecated
331 public RulePriority getPriority() {
332 return priority;
333 }
334
335 /**
336 * Sets the rule priority. If null, uses the default priority
337 *
338 * @deprecated since 2.5 use {@link #setSeverity(RulePriority)} instead. See http://jira.codehaus.org/browse/SONAR-1829
339 */
340 @Deprecated
341 public Rule setPriority(RulePriority priority) {
342 return setSeverity(priority);
343 }
344
345 public String getRepositoryKey() {
346 return pluginName;
347 }
348
349 public Rule setRepositoryKey(String s) {
350 this.pluginName = s;
351 return this;
352 }
353
354 public Rule setUniqueKey(String repositoryKey, String key) {
355 return setRepositoryKey(repositoryKey).setKey(key).setConfigKey(key);
356 }
357
358 public Cardinality getCardinality() {
359 return cardinality;
360 }
361
362 public Rule setCardinality(Cardinality c) {
363 this.cardinality = c;
364 return this;
365 }
366
367 public Rule getParent() {
368 return parent;
369 }
370
371 public Rule setParent(Rule parent) {
372 this.parent = parent;
373 return this;
374 }
375
376 @Override
377 public boolean equals(Object obj) {
378 if (!(obj instanceof Rule)) {
379 return false;
380 }
381 if (this == obj) {
382 return true;
383 }
384 Rule other = (Rule) obj;
385 return new EqualsBuilder()
386 .append(pluginName, other.getRepositoryKey())
387 .append(key, other.getKey())
388 .isEquals();
389 }
390
391 @Override
392 public int hashCode() {
393 return new HashCodeBuilder(17, 37)
394 .append(pluginName)
395 .append(key)
396 .toHashCode();
397 }
398
399 @Override
400 public String toString() {
401 return new ToStringBuilder(this)
402 .append("id", getId())
403 .append("name", name)
404 .append("key", key)
405 .append("configKey", configKey)
406 .append("plugin", pluginName)
407 .toString();
408 }
409
410 private String removeNewLineCharacters(String text) {
411 String removedCRLF = StringUtils.remove(text, "\n");
412 removedCRLF = StringUtils.remove(removedCRLF, "\r");
413 removedCRLF = StringUtils.remove(removedCRLF, "\n\r");
414 removedCRLF = StringUtils.remove(removedCRLF, "\r\n");
415 return removedCRLF;
416 }
417
418 public static Rule create() {
419 return new Rule();
420 }
421
422 /**
423 * Create with all required fields
424 */
425 public static Rule create(String repositoryKey, String key, String name) {
426 return new Rule().setUniqueKey(repositoryKey, key).setName(name);
427 }
428
429 }