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